Metadata
| Status | done |
|---|---|
| Assigned | agent-887 |
| Agent identity | 603daf069cd2ae4a26357aa66e8c6124154b648711a0816ffd8b660ee3b23815 |
| Created | 2026-07-26T11:49:14.669233079+00:00 |
| Started | 2026-07-26T12:11:32.253429270+00:00 |
| Completed | 2026-07-26T12:25:04.953940922+00:00 |
| Tokens | 1467306 in / 27059 out |
Description
Objective
Define the implementation-ready, crash-safe candidate finalization transaction for isolated worktrees. It must refine docs/design-simplified-task-lifecycle.md, not create a parallel lifecycle: the lifecycle kernel/ledger remains the only task/attempt/status authority, and the Pi watchdog remains the only owner of Pi process-epoch stall detection and same-session continuation.
Produce docs/design-candidate-finalization-transaction.md; no production code changes.
One composed state machine
Specify one normative composite state machine, with every state mapped to the authoritative lifecycle, attempt, process, worktree-lease, evaluation, and outbox domains rather than added as ad-hoc task statuses:
Active -> Suspect/ContinuationProbe | TerminalIntent | QuiescentNoTerminal -> NeedsFinalization -> RescueCheckpointed -> CandidateCheckpointed -> Validating -> [Evaluating] -> MergePending -> Merged | RepairNeeded | FailedPreserved.
Cover these rules and all orderings explicitly:
- False stall: absence/difference of files in main, wall-clock silence, or no visible push is never progress/stall evidence for an isolated attempt. A still-current unfenced writer remains
Active; finalization cannot begin. - Pi boundary:
Suspect, meaningful-progress classification, continuation authorization, completion-probe process epochs, exact-session resume, and PID/process-group termination are inputs owned by the ratified Pi watchdog. The finalizer must neither detect Pi stalls nor launch/resume Pi. For a Pi no-terminal exit, a same-session structured completion probe is requested through that watchdog protocol: inspect the completion contract, immutable messages, diff/status, and tests; emit explicit done if complete, continue the same attempt if incomplete, explicit fail if blocked, or an operator hold if replay safety is ambiguous. Candidate code consumes the resulting quiescence/terminal-intent receipt only. - Generic no-terminal exit: the process observer records exit; no inference from prose or main. Finalization may classify/checkpoint the quiescent work, but only the lifecycle kernel may accept success/failure. Reconcile this with the authoritative
NoCompletionProtocolmapping and the Pi continuation extension; name every typed request/receipt and precedence rule. - No live terminalization: done/fail/cancel/abort are intents while the current process identity can still write. Fence and reap the exact PID + start identity/nonce and process group, then checkpoint. If quiescence is ambiguous, quarantine/hold; never reuse, checkpoint as stable, merge, or delete the tree.
- Checkpoint first: every quiescent exit, fence, cancellation, or explicit failure durably records a source-preserving rescue commit/object plus content manifest before release/terminal cleanup. A completion-ready rescue is atomically promoted to an immutable candidate version; checkpointing preserves bytes but never asserts correctness.
- First-terminal-wins: duplicate/contradictory done, fail, exit, watchdog, evaluation, merge, and restart observations are idempotent. Old process epochs/fences are evidence only. Define the exact CAS and cancellation of stale outbox actions.
- Repair and failure: rejection/conflict resumes the retained candidate worktree/session or creates an explicitly linked repair attempt under lifecycle policy. A repair produces a new immutable candidate version and new verdict binding; it never mutates the evaluated candidate. Explicit failure reaches
FailedPreservedonly after rescue retention is durable.
NeedsFinalization, CandidateCheckpointed, Validating, Evaluating, MergePending, RepairNeeded, and FailedPreserved are finalizer/worktree/evaluation projections unless the authoritative design already names a canonical task state. State exactly which canonical task/attempt transition accompanies each edge; do not add another status writer.
Immutable source-of-truth and authority
Define a CandidateDescriptor (names may vary) containing at least task, generation, attempt, fence, worktree lease epoch, parent/base, candidate commit/tree OID, canonical content-manifest digest/CID, validation policy snapshot, and creation event. It is append-only and versioned.
- Seal only after the exact writer is reaped and the lease/fence still match. Preserve explicit worker commits, then have WG create a local rescue/candidate commit for remaining dirt, including deletions/untracked files according to a documented inclusion policy.
- The worker edits, tests, communicates, and submits explicit done/fail/wait intent. The worker never needs to push. A push is optional operator publication and is not checkpoint, evaluation, acceptance, or merge evidence.
- The WG finalizer alone checkpoints/promotes candidate bytes and requests validation/evaluation/merge actions. The evaluator is read-only. The merge authority alone integrates into main. Spell out supervisor, lifecycle-kernel, process-observer, validator, evaluator, and merge-authority responsibilities.
- Deterministic validation and evaluator/FLIP must materialize/read the candidate descriptor by commit/tree/CID in a detached read-only view, never main and never a mutable source worktree. Verdicts contain the candidate commit + manifest digest + policy/route identity.
- Merge is content-bound to that same descriptor: merge/apply the exact candidate commit/tree, verify the receipt's input and resulting content against the descriptor, and reject drift. Main edits/conflicts produce
RepairNeeded/merge conflict; they must never cause validation/evaluation/merge to substitute main bytes. - Required evaluation ordering: checkpoint -> deterministic validation -> evaluate exact candidate -> accepted verdict -> merge exact candidate -> acceptance/Done. Evaluator infrastructure failure holds without rewriting source success. Advisory ordering: checkpoint -> deterministic validation -> merge exact candidate/accept as policy permits while asynchronous evaluation remains pinned to that candidate; a later advisory verdict is evidence only and cannot reopen or replace it. Define
Noneand manual policies too.
Crash, replay, retention, and operator contract
Specify an append-only event/outbox protocol with stable idempotency keys and replay behavior at every boundary: terminal intent, continuation/probe handoff, fence request, TERM/KILL, reap proof, rescue write, candidate promotion, validation start/result, evaluation start/verdict, merge start/conflict/receipt, acceptance, cleanup, and daemon restart. PID identity, attempt fence, and worktree lease epoch must prevent late writers; durable rescue/candidate refs must prevent data loss. Physical cleanup is never part of semantic acceptance.
Define status/commands and stable reason codes that expose current generation/attempt/fence/process epoch, PID identity, lease epoch, rescue/candidate IDs, validation/evaluation binding, merge receipt/conflict, retained path/ref, replay action, and safe operator next step. Define retention/GC for rescue, candidate, rejected/repair, failed, merged, and abandoned work; unknown/unmerged/source-bearing objects are fail-closed and never age-deleted.
Required incident proof and test design
Design RED-first, credential-free fixtures before implementation:
- A planted cross-repo incident with a 28KB candidate in an isolated worktree and a conflicting/substituted 6KB main version. The worker crosses the historical false-stall boundary, writes late, exits without
wg_done, and never pushes. Through the real installed binary + daemon/service + real isolated worktree (Fake-Pi only for provider behavior), prove the writer is fenced, the same-session completion probe runs where authorized, rescue/candidate bytes survive, validator/evaluator read the 28KB immutable candidate, and merge integrates exactly that candidate once or retains it for explicit repair—never the 6KB main substitute. - A daemon restart/fault barrier before and after every durable event/outbox boundary, plus PID reuse/start-identity mismatch, late write, duplicate done/fail, explicit useful-WIP failure, evaluator crash/reject, main edit/merge conflict, dirty/untracked/deleted files, and cleanup failure.
- Assertions compare candidate tree/manifest digest, evaluator binding, merge input/receipt, and resulting tree; path or branch-name equality alone is insufficient.
- Plan a permanent grow-only smoke scenario with the implementing task as owner. It must exercise the real daemon/worktree/finalizer/operator flow, not only helper/library calls, and must first fail against pre-change behavior.
Ownership/non-overlap
This design task follows design-pi-stalled; it consumes that design's typed continuation/quiescence receipts and may identify a missing seam, but must not redesign its detector, session attestation, continuation budget, progress classifier, or process-epoch launcher. implement-crash-safe is serialized after both this design and implement-pi-stalled. Lazy evaluation consumes finalized candidate events only after crash-safe finalization lands.
Validation
- One mapped state machine covers false stall, no-terminal exit/probe, candidate/rescue checkpoint, validation/evaluation, merge/repair, explicit failure, and retention without adding a status authority.
- Sequence diagrams cover normal done, no-terminal exit, false stall, explicit fail with useful WIP, evaluation accept/reject/crash, merge conflict, late write/PID reuse, duplicate terminal reports, and daemon restart at every boundary.
- Evaluator input and merge are cryptographically/content bound to one immutable candidate version; repair creates a new version and main can never be silently substituted.
- PID/start-identity/process-group fencing plus attempt fence, worktree lease epoch, durable refs, and replay-idempotent outbox actions eliminate late-writer and data-loss races.
- Worker, Pi watchdog, lifecycle kernel, finalizer, validator, evaluator, merge authority, and operator duties are unambiguous; no worker push is required.
- RED-first 28KB-worktree-vs-6KB-main fixture and permanent real installed-binary daemon/worktree smoke plan are implementation-ready and credential-free.
- Migration, diagnostics, retention/GC, stable reason codes, and file-level implementation seams are explicit.
Depends on
Required by
Log
- 2026-07-26T11:49:14.654645397+00:00 Task paused
- 2026-07-26T11:49:49.011505695+00:00 Task published
- 2026-07-26T12:11:32.336242170+00:00 Spawned by coordinator --executor pi --model openai-codex:gpt-5.6-sol --isolation required-worktree
- 2026-07-26T12:11:42.321438178+00:00 Starting design: inspecting prior WIP and authoritative lifecycle/Pi watchdog contracts before drafting the candidate finalization transaction.
- 2026-07-26T12:16:18.971645808+00:00 Research complete: authoritative lifecycle and Pi watchdog read in full; current merge/evaluation/worktree seams inventoried. Proceeding inline because this is one tightly coupled design document with one file and no safely parallel file scopes.
- 2026-07-26T12:21:43.001667397+00:00 Drafted docs/design-candidate-finalization-transaction.md: mapped composite state machine; terminal reservation and Pi/generic no-terminal precedence; immutable rescue/candidate schemas; read-only gate binding; exact merge CAS; replay, retention, diagnostics, migration, file seams, diagrams, and RED 28KB/6KB installed-daemon fixture.
- 2026-07-26T12:24:57.494186429+00:00 Validated: all seven task criteria mapped in the document; 9 Mermaid sequence diagrams cover every required flow; local links exist; code fences and git diff checks pass; cargo fmt --check and cargo build --locked pass (existing warnings only).
- 2026-07-26T12:24:57.626810810+00:00 Committed: 61b358aa — pushed to remote
- 2026-07-26T12:25:04.953943472+00:00 Task marked as done