Skip to content

Agent handoff: downstream injection, waiting, attribution - #112

Merged
suprie merged 1 commit into
mainfrom
run/agent-handoff-downstream-injection-plus3-9b97e5f3a95f
Oct 30, 2026
Merged

suprie merged 1 commit into
mainfrom
run/agent-handoff-downstream-injection-plus3-9b97e5f3a95f

Conversation

@suprie

@suprie suprie commented Oct 30, 2026

Copy link
Copy Markdown
Owner

Summary

Dependent phases now receive their upstream handoff artifacts inline in a separate turn, bounded to 8 KiB per artifact and required to cite them. A phase with an unmet handoff dependency reports Waiting instead of parking. Every consumed artifact is recorded in the run report with its from-role, to-role, store path, and a coverage-only citation result.

What changed

  • Dependent phases start a new turn when a direct depends_on ancestor publishes a handoff_topic.
  • Upstream artifacts are loaded from .loopdeck/handoffs/, inlined with their store paths, and capped at 8 KiB; a missing or oversized artifact parks the batch instead of truncating.
  • RunPhaseStatus::Waiting and its transition edges are wired; the executor re-checks blocked phases after every turn, re-queues satisfied ones, parks terminal-bad ones, and parks any remainder at run end.
  • The handoff ledger records run id, from-role, to-role, artifact path, and a pass/partial/missing citation result; the run report filters the ledger by plan id.
  • Rust tests cover injection bounds, citation coverage, Waiting transitions, batch boundaries, and restart reconciliation.

PRD

docs/epics/role-based-orchestration/prd-agent-handoff.md

Decisions

  • 2026-10-10 — Use write-capable Codex policy for unattended runs (accepted): autonomous turns use workspaceWrite with approvalPolicy: on-request under the destructive-command floor.
  • 2026-10-09 — Correlate Codex turn failures across the run watchdog (accepted): Codex sessions log turn/request IDs and terminal errors; prompts and full tool arguments stay out of lifecycle logs.
  • 2026-10-08 — Separate orchestrator and worker language in run surfaces (accepted): the detail tab is "Worker activity" and the night-run card names orchestrator status and worker profile.

Test plan

  • cargo test
  • cargo clippy -- -D warnings
  • npx tsc --noEmit
  • Manual: run a two-phase plan where the first publishes a handoff and the second cites it.

Verify Verdict

PRD Verification — prd-agent-handoff.md

Verdict: PASS

# Criterion Status Evidence
1 Split to a new turn when a phase has a direct depends_on ancestor whose handoff_topic is set PASS src-tauri/src/commands/run_queue.rs:1400 stops the batch before a consumer; src-tauri/src/run_executor.rs:510 identifies consumers
2 Inject upstream artifacts into a dependent phase's prompt with bounded size and contract citation PASS src-tauri/src/handoff.rs:268 enforces the 8 KiB cap; src-tauri/src/handoff.rs:296 renders path, body, and citation rule; src-tauri/src/commands/run_queue.rs:2058 appends it to the prompt
3 Wire the unused Waiting status so phases with unmet handoff dependencies wait instead of parking PASS src-tauri/src/runplan.rs:54 adds Waiting; src-tauri/src/transition.rs:158 maps it; src-tauri/src/run_executor.rs:537 re-checks; src-tauri/src/commands/run_queue.rs:1881 invokes the re-check after each turn
4 A waiting phase parks only on a terminal-bad upstream or when the run ends PASS src-tauri/src/run_executor.rs:537 parks on terminal-bad; src-tauri/src/run_executor.rs:605 parks leftovers; src-tauri/src/commands/run_queue.rs:2506 parks at run end
5 Record every handoff (from-role, to-role, artifact path, citation check) in the run report PASS src-tauri/src/handoff.rs:64 defines the entry; src-tauri/src/commands/run_queue.rs:2221 records after a passing turn; src-tauri/src/runplan.rs:323 exposes RunReport.handoffs
6 Filter project-wide attribution to the current run PASS src-tauri/src/handoff.rs:439 filters by run id; src-tauri/src/commands/run_queue.rs:920 scopes the report to plan.id
7 Add Rust tests for store round-trips, injection bounds, and Waiting transitions; verify against the spike's contract PASS src-tauri/src/handoff.rs:1077 8 KiB bound; src-tauri/src/handoff.rs:1118 citation coverage; src-tauri/src/run_executor.rs:1607 Waiting re-check; src-tauri/src/transition.rs:304 Waiting edges; cargo test = 759 passed

Non-goals audit

  • No scope creep detected. No message bus, no parallel execution, no arbitration or artifact review, and no interactive-session writes.

Roll-up: PASS — 0 FAIL, 0 PARTIAL, 7 PASS.

Run metadata

  • Phases:
    • agent-handoff/downstream-injection — "Inject upstream artifacts into a dependent phase's prompt with bounded size and contract citation" (role-based-orchestration / prd-agent-handoff / Phase 2 — Downstream injection + waiting)
    • agent-handoff/waiting-status — "Wire the unused Waiting status so phases with unmet handoff dependencies wait instead of parking" (role-based-orchestration / prd-agent-handoff / Phase 2 — Downstream injection + waiting)
    • agent-handoff/report-attribution — "Record every handoff (from-role, to-role, artifact path, citation check) in the run report" (role-based-orchestration / prd-agent-handoff / Phase 3 — Report + audit)
    • agent-handoff/tests — "Add Rust tests for store round-trips, injection bounds, and Waiting transitions; verify against the spike's contract" (role-based-orchestration / prd-agent-handoff / Phase 4 — Tests/verification)
  • Budgets: 2000000 tokens total · 21600s wall-clock cap for this turn · 28800s total-run wall-clock cap

🤖 Generated with Claude Code

Dependent phases receive upstream handoff artifacts inline in a separate turn, bounded to 8 KiB and contract-cited. Unmet handoff dependencies now surface as Waiting instead of parking, and every consumed artifact is recorded in the run report with roles, path, and a coverage-only citation result.

Rubric: PASS — 7/7 criteria

Co-Authored-By: Claude <noreply@anthropic.com>
@suprie
suprie marked this pull request as ready for review October 30, 2026 06:01
@suprie
suprie merged commit b6f72fa into main Oct 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant