WIP: Non-committing scratch dispatch mode (ADR 0019) #308

Closed
toasterson wants to merge 0 commits from claude/wi-019f3704-non-committing-scratch-dispatch-mode-adr into main
Owner

Anima work item 019f3704-9183-7f91-b951-aed67601ad0c.

What to build

The ADR 0019 scratch dispatch mode: build-agent sessions that explore/prototype in scratch spaces and are structurally unable to commit, push, or open PRs. Deliverable of such a session is a findings Document — never a diff.

Pushed context (design grilled + accepted 2026-07-06, ADR 0019)

  • Dispatch: on-demand, bridge-style (like planning sessions) — run_prototype_phase / run_define_phase dispatch immediately, NOT via the scheduler poll. A companion may occupy a slot on ITS OWN akh without a human click (the companion pins the akh; akh capacity is separate from the implementer fleet). SessionQueue semantics when the akh is busy.
  • Assign shape: a scratch mode with NO VcsConfig; the runner preps the worktree then strips origin; session env carries a read-only token only. MCP token scopes: workitem.read + document.read/write — NO workitem.write_diff / workitem.submit_change.
  • Scratch space (see CONTEXT.md): per-PHASE, lives on the akh host, survives sessions within the phase (scratch_spaces row pins the runner/akh id). Loss on runner loss is accepted — the findings Document is the ONLY durable output; the session brief must instruct flushing findings to the Document per-turn, not at session end.
  • Lifecycle: ScratchSpaceRepo::mark_cleaned_up (currently missing) called on phase exit; runner removes the directory. TTL reaper backstop: default 7 days idle (env ANIMA_SCRATCH_TTL_SECS), covers parked/abandoned phases — cleanup tied only to lifecycle events leaks (cf. 2026-07-04 test-postgres leak).
  • Exit bar: HUMAN-only on the prototype phase — deliberately not the ADR 0018 reviewer loop; repeated empty findings Documents must surface to a human as a bug signal.
  • Files: crates/anima-server/src/scheduler.rs (assemble_and_send / Assign construction), crates/anima-server/src/services/bridge.rs (on-demand dispatch precedent), crates/anima-runner/src/slot.rs (VCS vs parity branch — add scratch arm), run_prototype_phase in crates/anima-server/src/services/artifact.rs:275-333 (currently creates a /tmp dir SERVER-side — wrong host), handle_run_define_phase in mcp/handlers.rs (~3808), crates/anima-db migrations 037 (scratch_spaces) + repo.

Acceptance criteria

  • Scratch Assign carries no VcsConfig; runner strips origin; session cannot push/PR/SetAgentDiff (verify token scopes rejected)
  • run_prototype_phase dispatches a real session on the companion's akh, on-demand, queueing when busy
  • Findings Document written with provenance during the session (not only at close); phase exit = human reads it
  • mark_cleaned_up on phase exit + TTL reaper; no orphaned scratch dirs after a parked phase
  • WI 019f13ae-95c1 (define-build) implementable against this mode

Blocked by

  • None — can start immediately (design accepted, ADR 0019).
Anima work item `019f3704-9183-7f91-b951-aed67601ad0c`. ## What to build The ADR 0019 scratch dispatch mode: build-agent sessions that explore/prototype in scratch spaces and are structurally unable to commit, push, or open PRs. Deliverable of such a session is a findings Document — never a diff. ## Pushed context (design grilled + accepted 2026-07-06, ADR 0019) - **Dispatch**: on-demand, bridge-style (like planning sessions) — `run_prototype_phase` / `run_define_phase` dispatch immediately, NOT via the scheduler poll. A companion may occupy a slot on ITS OWN akh without a human click (the companion pins the akh; akh capacity is separate from the implementer fleet). SessionQueue semantics when the akh is busy. - **Assign shape**: a scratch mode with NO VcsConfig; the runner preps the worktree then strips `origin`; session env carries a read-only token only. MCP token scopes: workitem.read + document.read/write — NO workitem.write_diff / workitem.submit_change. - **Scratch space** (see CONTEXT.md): per-PHASE, lives on the akh host, survives sessions within the phase (scratch_spaces row pins the runner/akh id). Loss on runner loss is accepted — the findings Document is the ONLY durable output; the session brief must instruct flushing findings to the Document per-turn, not at session end. - **Lifecycle**: ScratchSpaceRepo::mark_cleaned_up (currently missing) called on phase exit; runner removes the directory. TTL reaper backstop: default 7 days idle (env ANIMA_SCRATCH_TTL_SECS), covers parked/abandoned phases — cleanup tied only to lifecycle events leaks (cf. 2026-07-04 test-postgres leak). - **Exit bar**: HUMAN-only on the prototype phase — deliberately not the ADR 0018 reviewer loop; repeated empty findings Documents must surface to a human as a bug signal. - Files: crates/anima-server/src/scheduler.rs (assemble_and_send / Assign construction), crates/anima-server/src/services/bridge.rs (on-demand dispatch precedent), crates/anima-runner/src/slot.rs (VCS vs parity branch — add scratch arm), run_prototype_phase in crates/anima-server/src/services/artifact.rs:275-333 (currently creates a /tmp dir SERVER-side — wrong host), handle_run_define_phase in mcp/handlers.rs (~3808), crates/anima-db migrations 037 (scratch_spaces) + repo. ## Acceptance criteria - [ ] Scratch Assign carries no VcsConfig; runner strips origin; session cannot push/PR/SetAgentDiff (verify token scopes rejected) - [ ] run_prototype_phase dispatches a real session on the companion's akh, on-demand, queueing when busy - [ ] Findings Document written with provenance during the session (not only at close); phase exit = human reads it - [ ] mark_cleaned_up on phase exit + TTL reaper; no orphaned scratch dirs after a parked phase - [ ] WI 019f13ae-95c1 (define-build) implementable against this mode ## Blocked by - None — can start immediately (design accepted, ADR 0019).
toasterson force-pushed claude/wi-019f3704-non-committing-scratch-dispatch-mode-adr from 058b5f01a8 to 7bb9792700 2026-07-07 02:28:57 +00:00 Compare
Author
Owner

Merged to main manually (human-gated review) as merge commit fd81350, with fixup 07eb785: migration renumbered 042→043 (collided with #306's backfill migration). Noted follow-up: the TTL reaper marks scratch spaces completed in the DB but nothing removes the worktree directory on the runner host yet — runner-side FS cleanup belongs with the define-build slice. Closing.

Merged to main manually (human-gated review) as merge commit `fd81350`, with fixup `07eb785`: migration renumbered 042→043 (collided with #306's backfill migration). Noted follow-up: the TTL reaper marks scratch spaces `completed` in the DB but nothing removes the worktree directory on the runner host yet — runner-side FS cleanup belongs with the define-build slice. Closing.
toasterson closed this pull request 2026-07-07 13:16:01 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
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
toasterson/Anima!308
No description provided.