pkg/fleetconfig: typed KDL fleet-config validator (core, not a guarded surface) - blocks the ward-kdl dialect-2 chain #178
Labels
No labels
burndown-2026-06
sunday-sprint
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/cli-guard#178
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Issue 1 of the ward<=>aos config architecture pass (aos#310). Two formats ratified by Kai: KDL source, agent-shaped schema in cli-guard core (decision C, literal reading). This blocks the entire ward-kdl dialect-2 chain - land it first.
Deliverable
A new
pkg/fleetconfigpackage in cli-guard core:Fleet,Agent,Defaults.Parse([]byte) (Fleet, error)over a KDL source, reusing cli-guard's existing KDL node walker.Sourceenum (Embedded|OperatorLocal):Embeddedaccepts the full fleet schema;OperatorLocalaccepts the narrower per-host node set (e.g.director.default-scope) and rejects embed-only fields. One grammar, two accepted subsets - 'one parser, two sources'.Mount, noexec, nocan runin its vocabulary. It structurally cannot express a permission. This is pure core data-typing, NOT a fourth guarded surface (cli/,http/,mcp/stay the three guarded surfaces). That package boundary IS the permission/config partition the pass requires.Schema (from the aos#310 advisor sketch)
Fields per agent:
binary,context-level,stream,auth,model,endpoint,provider,reasoning-effort,verbosity,argv{preflight,headless,interactive}. Top level:schema-version,defaults{agent, attribution{name,email}}.Docs
docs/fleetconfig.md- the schema + the two-source model.docs/architecture.mdthat config validation is a core concern (pkg/fleetconfig), deliberately NOT a guarded surface, so the three-surface least-privilege identity stays legible. This is the config-placement doctrine's landing in cli-guard (generalizes the downward-only arrow atdocs/architecture.md:17).Blocks / sequencing
Blocks aos#310 issues 2 (author fleet.kdl), 3 (repoint ward reads), 4 (ward agents list --json), 10 (axis-3 OperatorLocal). Nothing here depends on ward - land it standalone. Mode: headless.
🔒 Reserved by
ward agent --driver claude— containerengineer-claude-cli-guard-178on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-01T08:28:30Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - pkg/fleetconfig typed KDL fleet-config validator landed on main (one parser, two sources; no permission vocabulary).
Retrospective: this one went smoothly, mostly because the ground was well-prepared. The existing execverb/guardfile parsers gave me a clear house style for walking kdl-go nodes and failing closed, so the core parser was more transcription-of-a-pattern than invention. The one design judgement call was the two-source model: I read "Embedded accepts the full schema, OperatorLocal accepts the narrow per-host set" as Embedded=superset (fleet + optional director seed), OperatorLocal=director-only, rejecting the embed-only
fleetblock. That felt like the cleanest literal reading and it made the boundary testable.What fought back was entirely the doc-size and comment-discipline hooks, not the code. FEATURES.md was sitting exactly 1 char under the 4000 cap, so my one-line entry overflowed it and I had to claw back chars from unrelated bullets. The code-comments hook (2-line contiguous cap) also made me compress every doc comment. Annoying, but both are the repo keeping itself tidy, so fair enough.
Confidence is high: parser + tests are green, lint/vet/godoc/pre-commit all pass, and the sandbox test failures are pre-existing and environmental (seccomp under an unprivileged container). The structural "no mount/exec/can-run" boundary is enforced by name and covered by tests.
Rough edges / follow-ups worth filing: (1) the OperatorLocal vocabulary is currently just
director.default-scope- the real per-host axis-3 set (aos#310 issue 10) will want more nodes, and I kept it deliberately minimal; (2) schema-version is hard-pinned to 2 and fails closed on anything else, which is intentional for dialect-2 but will need a conscious bump; (3) no golden/round-trip fixture file yet - issue 2 (author fleet.kdl) is the natural place to add one and exercise Parse against the real artifact.