ADR 0094: Final lifecycle checks require clean trees
Vocabulary amendment: Current pointers use
ratchets→standards,finish→done,graduate→accept,integrate→update, the retired product-category wording →discern, the gate, or the bar, the gate-pass artifact → the receipt, the shared-branch label → the trunk; the decision and reasoning are unchanged.
Status: accepted
Context
§discern's lifecycle has two kinds of feedback:
- fast iteration feedback, such as
prepare,test, and targeted project commands, which is useful while a tree is still changing; - final lifecycle feedback, such as a recorded
donepass, standards, and acceptance, whose answer only matters for the tree that will actually be handed off or landed.
Agents tended to blur those two modes. A common sequence was to run done on uncommitted work, receive a green result, commit afterward, and then ask acceptance to land the branch. The later commit changed the tree from the one done validated, so acceptance had to validate again. Standards had a similar failure mode: because they are intentionally slow and outside done, running them during ordinary dirty-tree iteration made repeat runs likely without improving confidence in the final branch.
Acceptance also had an older convenience path that WIP-committed uncommitted changes, removed the worktree, checked the branch out in the main checkout, and soft-reset the WIP commit so those changes landed staged. That preserved bytes, but it made acceptance both a final lifecycle operation and an implicit dirty-tree transport mechanism.
Decision
§Final lifecycle operations now prefer a clean, committed tree:
donestill may be run on dirty work, but a dirty green run records no gate receipt and hints that agents should useprepareortestwhile iterating, then commit and rundoneagain on the clean HEAD.statusreports the current gate receipt state and only gives the ready-for-review hint when a clean ahead branch has a receipt honored at its current HEAD.- non-dry-run
standardsrequire a clean worktree whenever standards are configured.--dry-runremains free to preview the plan, and--forceexists only for standard authoring or debugging. acceptrefuses dirty worktrees. It no longer creates WIP commits, and no longer soft-resets them into the main checkout.
update remains the canonical way to bring the trunk into a worktree. It performs its own preconditions and is idempotent, so guidance should tell agents to call it directly instead of running preliminary git checks.
Consequences
§The efficient final path is now:
- iterate with
prepare,test, or targeted commands; - commit the intended final tree;
- run
doneon the clean HEAD; - run standards as needed on the same clean tree;
- accept only when the user explicitly asks for handoff or landing.
Acceptance becomes simpler and less surprising: it lands committed branch history only. Moving uncommitted work between contexts is outside discern's acceptance lifecycle.
Standard authoring keeps an escape hatch. A person adding or debugging a standard can use --force to run the metric command before committing the standard itself, but ordinary agent guidance should treat non-dry-run standards as clean-tree checks.
Alternatives considered
§- Keep dirty acceptance and improve the prose. That would leave a feature whose existence invites agents to treat acceptance as a WIP handoff tool.
- Make standards always clean-tree-only with no override. That is simpler for agents, but awkward while designing a new metric command.
- Automatically commit before final checks. discern cannot know the user's desired commit boundary or message. The final commit is project work, not a discern side effect.