Skip to content

Decision 071: a phase may be offered rather than imposed — optIn, and the design critic round

  • Status: proposed
  • Date: 2026-08-10
  • Deciders: @MadaraUchiha-314 (issue #188 — the phase, its position and its default are the owner's); mechanism proposed by the harness, pending PR review
  • Work item: issue-188
  • Spec: docs/specs/issue-188/
  • Refines: decision-067 (skips are declared by humans at phase-selection) and decision-068 (every phase of the outer loop is selectable). Both settled who decides; this one adds the other default — a phase that is off until that same person asks for it.

Context

Issue #188, verbatim: "design is one of the most important artifact that's generated by the-loop as it follows it's PDLC process. We should add an optional phase (not on by default) that's selectable in the phase selection which is the critic review."

Two facts made the ask impossible to satisfy as the loop stood.

One. design.md is the artifact the whole downstream chain derives from, and it is the one artifact no critic ever reads. The review chain — self-review, critic-review, security-review — sits between implementation and human-approval. By the time a different model looks at the work, the design has already produced a testing plan, a task DAG and a diff. A design finding there is not a design finding; it is a rewrite.

Two. The selection vocabulary had exactly one default. skippable: true means on unless a human unticks it, and decision-068 widened that marker to every node the outer loop walks. There was no way for the shipped graph to offer a phase — the choice was always between imposing it on every work item or not shipping it at all.

Decision

Sub-decisionWhat was chosenWhy
D1 — a second node marker, optIn: truerendered unticked at phase-selection; runs only if an authorized human ticks itThe ticket asks for selectable and not on by default. Those are the same act by the same person at the same gate; only the default differs, so only the default is new.
D2 — optIn implies skippablean opt-in node is in the declared-skip vocabulary, declares its own on: skipped edge, and is routed around by the existing codeThe alternative is a parallel mechanism — a second filter, a second report, a second freeze — for a difference that is one boolean at render time.
D3 — an unselected opt-in node is a skip with via: not-selectednot a new check statusEvery consumer of declared_skips (routing, check, --recompute, skipped_artifacts) gets the new node right without learning a new word. The one thing that must not blur is who: _skip_provenance says "not selected — an opt-in phase", never "skipped by declaration", because nobody declared it.
D4 — the checklist keeps the two defaults in separate sectionsticked rows above, unticked opt-in rows below their own heading, each with the node's one-line descriptionA reader unticking boxes must never have to work out which way a given row leans. Mixing them would make the same gesture mean "remove work" in one row and nothing in the next.
D5 — omission means off, in every directionunticked, absent from the reply, unreadable checklist, deleted comment → not selectedThe fail-closed direction differs by class: for a gating phase, closed is "it runs"; for a phase that adds a review and gates nothing else, closed is "it does not". Nothing downstream depends on this node's output, so no gate is weakened by its absence.
D6 — a skip set may not name an opt-in nodecompile-time refusalA set declares phases away; an opt-in phase is already away. A token reading "drop these" that is a no-op for one member is a lie in the vocabulary.
D7 — the shipped opt-in phase is design-critic-review, between design and test-planningafter design.md is locked, before the testing plan and the task DAG derive from it; no phase: label; stage: critic-review; gates execution-log.md § Design critic review"After design.md is finalized" is the ticket's own placement, and it is where a structural finding still costs an edit. No label because this happens within the design phase and a new one would have to be minted in every consuming repository for a node most items never walk.
D8 — no CLI verb, and no re-selection after the gatethe-loop graph skip gets no counterpartphase-selection is required: true, so every work item passes the checklist and already has a channel. A second, shell-side channel needs its own audit comment and refusal rules for a case nothing has asked for.

Consequences

  • What a reader of the-loop check now sees. Three distinct verdicts where there were two: pass, skipped by declaration — via …, by @… and not selected — an opt-in phase. The middle one always names a person; the last one never does, and that is the point.
  • Backward compatible by construction. A work item whose graph-state.json predates this change records no selection, so the new node is skipped — an in-flight item cannot block on a phase that did not exist when it started.
  • The residual, stated plainly. An opt-in phase is one nobody has to refuse. A work item whose design deserved a second reader and whose author left the box alone gets no critic round and no warning — the loop records that the phase was offered and not taken (in the confirmation comment, in the frozen graph, and in every check), and stops there. That is the accepted cost of not imposing a review on every doc fix. If the balance proves wrong, the lever is the default on this one node, not the mechanism.
  • The vocabulary is now two markers wide, and should stay that way. skippable and optIn cover "on unless removed" and "off unless added". A third default would be a third thing a human has to reason about at the same gate; do not add one without a ticket that cannot be served by these two.

Alternatives considered

AlternativeWhy not
A config key (workflow.optIn: [...])Turns the phase on for every work item in a repository — the imposition the ticket rules out — and puts process shape back in a file, right after decision-069 deliberately moved a sibling choice out of one.
Ship the round as always-on and let people skip itInverts the ticket. It also spends a frontier-model round on every doc fix, and a phase that is usually unticked teaches people to untick without reading.
A new NOT_SELECTED status in checkEvery consumer of the skip set learns a new word, and check's output contract changes, for a case that reads perfectly as a skip with an honest reason.
Record the round in design.md itselfThe design is the subject under review; a review that writes into its subject makes the locked artifact's history unreadable. The execution log already holds every other round.
Loop the node back to design on findingsThe design is not approved yet — design-approval still reads it. Findings are applied in place under reply-first-then-fix, and no edge is needed for that.

Released under the MIT License.