No machine-readable success/failure contract for warded dispatch: exit codes undocumented, meta.json outcome enum names only success values #485

Closed
opened 2026-07-01 23:00:58 +00:00 by coilyco-ops · 3 comments
Member

Why

Persona the-agent-itself / angle failure-paths. Task attempted from docs alone: "you dispatched warded owner/repo#N (detached by design) — now determine programmatically whether it worked, and if not, why." That is precisely the job ward's own director role performs, so the public contract should exist. Audit of every documented affordance:

  1. Dispatch exit code — no agent-subsystem doc mentions exit codes at all (grep for exit/status across agent.md, agent-flags.md, agent-preflight.md, agent-subcommands.md, agent-observability.md, container-reap.md: zero contract statements). The project demonstrably knows how to publish this — docs/ci-watch.md documents 0/1/2/3 = passed/failed/timed-out/no-run — so its absence on the flagship surface reads as an oversight, not a policy.
  2. Pre-flight NO-GO — "a NO-GO comments and launches nothing" (agent-preflight.md via agent-engineer.md): whether that dispatch exits 0 or non-zero is unstated, so a script cannot distinguish "declined to launch" from "launched".
  3. Refusals — trust-gate and reservation-conflict refusals have error strings in Go, none quoted in any doc (companion comment on #447).
  4. After the factagent-observability.md documents meta.json's outcome as inferred from console markers and names exactly two values (pushed-to-main, ward-salvage). The failure vocabulary is unstated: what outcome does a NO-GO, a crash, an auth smoke-test abort (ward#222), or an externally-stopped run produce? An agent cannot branch on an enum whose failure half is undocumented.

Net: a harness cannot supervise warded runs from the public docs — it must reverse-engineer exit codes and console markers, which is the exact context cost this angle measures.

Deliverable

Publish the machine-readable contract in one place (agent-flags.md or agent-observability.md): dispatch exit codes per refusal class (launched / NO-GO / untrusted owner / reservation conflict / launch failure), and the complete meta.json outcome enum including all failure values, drift-tested against the code the way the roster page is.

Done condition

An agent author can write if exit == X / switch outcome handling for every dispatch ending documented above, with values taken from docs, and a drift test keeps the doc honest.


Severity: major-friction · persona: the-agent-itself · angle: failure-paths
Filed by Claude Code during a cold-read release pressure test (run 37).

## Why Persona `the-agent-itself` / angle `failure-paths`. Task attempted from docs alone: "you dispatched `warded owner/repo#N` (detached by design) — now determine programmatically whether it worked, and if not, why." That is precisely the job ward's own director role performs, so the public contract should exist. Audit of every documented affordance: 1. **Dispatch exit code** — no agent-subsystem doc mentions exit codes at all (grep for exit/status across `agent.md`, `agent-flags.md`, `agent-preflight.md`, `agent-subcommands.md`, `agent-observability.md`, `container-reap.md`: zero contract statements). The project demonstrably knows how to publish this — `docs/ci-watch.md` documents `0/1/2/3 = passed/failed/timed-out/no-run` — so its absence on the flagship surface reads as an oversight, not a policy. 2. **Pre-flight NO-GO** — "a NO-GO comments and launches nothing" (`agent-preflight.md` via `agent-engineer.md`): whether that dispatch exits 0 or non-zero is unstated, so a script cannot distinguish "declined to launch" from "launched". 3. **Refusals** — trust-gate and reservation-conflict refusals have error strings in Go, none quoted in any doc (companion comment on #447). 4. **After the fact** — `agent-observability.md` documents `meta.json`'s `outcome` as inferred from console markers and names exactly two values (`pushed-to-main`, `ward-salvage`). The failure vocabulary is unstated: what outcome does a NO-GO, a crash, an auth smoke-test abort (ward#222), or an externally-stopped run produce? An agent cannot branch on an enum whose failure half is undocumented. Net: a harness cannot supervise warded runs from the public docs — it must reverse-engineer exit codes and console markers, which is the exact context cost this angle measures. ## Deliverable Publish the machine-readable contract in one place (`agent-flags.md` or `agent-observability.md`): dispatch exit codes per refusal class (launched / NO-GO / untrusted owner / reservation conflict / launch failure), and the complete `meta.json` `outcome` enum including all failure values, drift-tested against the code the way the roster page is. ## Done condition An agent author can write `if exit == X` / `switch outcome` handling for every dispatch ending documented above, with values taken from docs, and a drift test keeps the doc honest. --- **Severity: major-friction** · persona: the-agent-itself · angle: failure-paths Filed by Claude Code during a cold-read release pressure test (run 37).
coilyco-ops added this to the ward launch milestone 2026-07-01 23:29:21 +00:00
Author
Member

DECISION - define AND implement the full machine-readable contract in one PR: documented dispatch exit codes (launched / refused / error - note the host pre-flight and its NO-GO are being REMOVED per #162, so NO-GO reporting is an in-container/meta.json concern), meta.json outcome enum covering failure values, one doc page in ci-watch's 0/1/2/3 style. Kai reviews the enum at PR review. Recorded by Claude Code (Fable) during the 2026-07-01 ward launch triage session with Kai.

DECISION - define AND implement the full machine-readable contract in one PR: documented dispatch exit codes (launched / refused / error - note the host pre-flight and its NO-GO are being REMOVED per #162, so NO-GO reporting is an in-container/meta.json concern), meta.json outcome enum covering failure values, one doc page in ci-watch's 0/1/2/3 style. Kai reviews the enum at PR review. Recorded by Claude Code (Fable) during the 2026-07-01 ward launch triage session with Kai.
Author
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-ward-485 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-07-02T02:49:03Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-ward-485` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-07-02T02:49:03Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Owner

WARD-OUTCOME: done - dispatch exit-code contract (0/1/2/3/4/5, distinct per refusal class) + full meta.json outcome enum, drift-tested, in docs/agent-dispatch-contract.md; landed on main.

Retrospective: the shape was clearer than the issue implied. The real gap wasn't just missing docs - the refusals genuinely were indistinguishable (everything exited a generic 1, NO-GO/WRONG-REPO exited 0), so this had to be an implementation change, not a doc pass. Making the trust gate and reservation conflict carry Coded exit codes was clean because cli-guard's exitcode.Coded plumbing and main.go's errors.As routing were already there; I just gave the refusals codes. The one thing that fought back was the doc-size cap: agent-observability.md sat at 3998/4000 chars and FEATURES.md at 3999/4000, both effectively full, so I split the contract into its own page and had to abandon a FEATURES entry entirely (it's in the docs index instead).

The referenced docs/ci-watch.md doesn't exist in this clone - that was a cold-read artifact - so I anchored the exit-code style on the real shared exitcode contract instead.

Two honest caveats. First, I read the live thread last, and only then hit Kai's DECISION note that the host pre-flight and its NO-GO are being removed per #162; I'd already implemented NO-GO/WRONG-REPO as dispatch codes 4/5. They're accurate for the current code, and I added a forward-note that they move to a meta.json concern once #162 lands - but if the enum should drop 4/5 pre-emptively, that's a quick follow-up. Second, the enum still wants your review at the values level. Confidence is high on the mechanics (build/vet/tests/pre-commit all green, drift test guards both enums); medium on whether the NO-GO framing matches where #162 is headed.

WARD-OUTCOME: done - dispatch exit-code contract (0/1/2/3/4/5, distinct per refusal class) + full meta.json outcome enum, drift-tested, in docs/agent-dispatch-contract.md; landed on main. Retrospective: the shape was clearer than the issue implied. The real gap wasn't just missing docs - the refusals genuinely were indistinguishable (everything exited a generic 1, NO-GO/WRONG-REPO exited 0), so this had to be an implementation change, not a doc pass. Making the trust gate and reservation conflict carry Coded exit codes was clean because cli-guard's exitcode.Coded plumbing and main.go's errors.As routing were already there; I just gave the refusals codes. The one thing that fought back was the doc-size cap: agent-observability.md sat at 3998/4000 chars and FEATURES.md at 3999/4000, both effectively full, so I split the contract into its own page and had to abandon a FEATURES entry entirely (it's in the docs index instead). The referenced docs/ci-watch.md doesn't exist in this clone - that was a cold-read artifact - so I anchored the exit-code style on the real shared exitcode contract instead. Two honest caveats. First, I read the live thread last, and only then hit Kai's DECISION note that the host pre-flight and its NO-GO are being removed per #162; I'd already implemented NO-GO/WRONG-REPO as dispatch codes 4/5. They're accurate for the current code, and I added a forward-note that they move to a meta.json concern once #162 lands - but if the enum should drop 4/5 pre-emptively, that's a quick follow-up. Second, the enum still wants your review at the values level. Confidence is high on the mechanics (build/vet/tests/pre-commit all green, drift test guards both enums); medium on whether the NO-GO framing matches where #162 is headed.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#485
No description provided.