fix(gatorwalk-factory): dispatch fidelity: subagents get the rendered prompt and product contract, and results are recorded as returned (swamp-club #2776) #390

Merged
seth merged 3 commits from cue/2776-gatorwalk-factory-dispatch into main 2026-09-30 19:16:13 +00:00
Owner

Fixes swamp-club #2776. It also covers #2777 and #2779, which were closed as duplicates.

In a dispatch stage, what a subagent received and what got recorded were both whatever the driver retyped. After this change, the dispatch hands over a complete contract, ready to send, and the driver records the subagent's own output file.

1. The rendered prompt is sent verbatim. For a dispatch stage, the engine writes each subagent's whole prompt (buildSubagentPrompts). It starts with the rendered prompt, byte for byte. A fixed section follows: the skill to follow, a swamp data get read for each injected product, and a result file for each product with its schema inline. dispatch records exactly these prompts (subagentPrompts on the dispatch), so replay shows what was sent. The driver adds nothing.

2. The packet names the products. DispatchPacket.products lists every declared artifact and evidence, each with the schema its payload is checked against: the declared schema, the findings contract, both (as allOf), or the outcome contract for result evidence. A test pins that artifactContract and evidenceContract accept and reject the same payloads as recording. Schema notes (description, $comment) are stripped, following the #2804 rule.

3. Results are recorded as returned. dispatch takes an optional resultDir, which must be absolute and must exist. Without it, dispatch makes a temp directory, and removes it again if the dispatch records nothing. The driver records each result with --input payload=@<result-path> and never edits the file. When several subagents review into one artifact, their findings are joined with a documented jq -s line, and each subagent prefixes its finding ids with S<n>-.

Decisions made in planning: a ready-to-send subagentPrompt rather than a recorded addendum; schemas inline; the packet names the result path, under resultDir with a temp-directory fallback; jq for merging findings for now. Scope and severity wording in the example prompts is left to #2781. Only "Record findings" became "Report findings".

Tests:

  • dispatch_test: products for a declared artifact, a findings artifact and a workflow result evidence, and the subagent prompts.
  • payload_schema_test: contract parity and note stripping.
  • run_ops_test: the record round trip.
  • work_item_test:
    • recorded prompts equal the logged ones;
    • resultDir handling, including relative paths refused;
    • cleanup on refusal and on store failure.
  • skill_test (real engine): the worked example's reviewers write result files, which are recorded with payload=@, and the test asserts each stored review equals its file.

The work-item model version is now 2026.09.30.1. gatorwalk-factory has no manifest, so nothing publishes.

Verification: verify-build and verify-reviews both passed on f9ae98e2 (attestation e6d36b62). This was the third round; the first two rounds' review findings are fixed in the second and third commits.

🤖 Generated with Claude Code

Fixes swamp-club #2776. It also covers #2777 and #2779, which were closed as duplicates. In a dispatch stage, what a subagent received and what got recorded were both whatever the driver retyped. After this change, the dispatch hands over a complete contract, ready to send, and the driver records the subagent's own output file. **1. The rendered prompt is sent verbatim.** For a dispatch stage, the engine writes each subagent's whole prompt (`buildSubagentPrompts`). It starts with the rendered prompt, byte for byte. A fixed section follows: the skill to follow, a `swamp data get` read for each injected product, and a result file for each product with its schema inline. `dispatch` records exactly these prompts (`subagentPrompts` on the dispatch), so replay shows what was sent. The driver adds nothing. **2. The packet names the products.** `DispatchPacket.products` lists every declared artifact and evidence, each with the schema its payload is checked against: the declared schema, the findings contract, both (as `allOf`), or the outcome contract for result evidence. A test pins that `artifactContract` and `evidenceContract` accept and reject the same payloads as recording. Schema notes (`description`, `$comment`) are stripped, following the #2804 rule. **3. Results are recorded as returned.** `dispatch` takes an optional `resultDir`, which must be absolute and must exist. Without it, dispatch makes a temp directory, and removes it again if the dispatch records nothing. The driver records each result with `--input payload=@<result-path>` and never edits the file. When several subagents review into one artifact, their findings are joined with a documented `jq -s` line, and each subagent prefixes its finding ids with `S<n>-`. **Decisions made in planning:** a ready-to-send `subagentPrompt` rather than a recorded addendum; schemas inline; the packet names the result path, under `resultDir` with a temp-directory fallback; `jq` for merging findings for now. Scope and severity wording in the example prompts is left to #2781. Only "Record findings" became "Report findings". **Tests:** - `dispatch_test`: products for a declared artifact, a findings artifact and a workflow result evidence, and the subagent prompts. - `payload_schema_test`: contract parity and note stripping. - `run_ops_test`: the record round trip. - `work_item_test`: - recorded prompts equal the logged ones; - `resultDir` handling, including relative paths refused; - cleanup on refusal and on store failure. - `skill_test` (real engine): the worked example's reviewers write result files, which are recorded with `payload=@`, and the test asserts each stored review equals its file. The work-item model version is now 2026.09.30.1. gatorwalk-factory has no manifest, so nothing publishes. Verification: verify-build and verify-reviews both passed on f9ae98e2 (attestation e6d36b62). This was the third round; the first two rounds' review findings are fixed in the second and third commits. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The dispatch packet now names every product the stage declares, with the
schema its payload is checked against. For a dispatch stage, the engine
writes each subagent's whole prompt: the rendered prompt byte for byte, then
the skill, where to read injected products, and a result file per product
with its schema. dispatch records exactly those prompts and takes an
optional resultDir (a new temp directory otherwise). The skill says to send
the prompts unchanged, record each result with payload=@<path> without
editing it, and join several reviewers' findings with jq. The worked example
runs that flow on the real engine and checks each recorded review equals its
file.

Covers #2777 and #2779 (closed as duplicates).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
From the verify-reviews findings on the first commit:

- A temporary result directory made for a dispatch that is then refused
  (stale expectation, dispatch cap) is removed again.
- A given resultDir must be an existing directory.
- With several subagents on one findings artifact, each prompt has its
  subagent start finding ids with S<n>-, so the documented jq join repeats
  no id.
- The synthesized outcome contract goes through withoutNotes like the rest.
- driving.md shows the prompt markers in a text block, so formatting cannot
  split them; README and DESIGN keep main's wrapping outside this change.
- The worked-example harness removes its result directory.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fix(gatorwalk-factory): dispatch refuses a relative resultDir and removes a made one on any failure (swamp-club #2776)
All checks were successful
CI / Review Integrity (pull_request) Successful in 1m33s
CI / Validate Attestation (pull_request) Successful in 1m27s
f9ae98e2c2
From the second verify-reviews round:

- resultDir must be absolute. A relative one was checked against swamp's
  working directory but sent as written, so a subagent and the driver
  could resolve it to different places (for example under --repo-dir).
- A result directory the dispatch made is removed in a finally block, so
  a store failure no longer leaves it behind, as a refusal already didn't.
- The documented jq join keeps the first file's other top-level fields,
  so a findings artifact with a declared schema still validates.
- The worked example's sample dispatch output uses <key> and <result-dir>.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seth merged commit 0a0f205485 into main 2026-09-30 19:16:13 +00:00
seth deleted branch cue/2776-gatorwalk-factory-dispatch 2026-09-30 19:16:13 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
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
swamp-club/swamp-extensions!390
No description provided.