Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,91 @@ clean or clearly stuck → then STOP and surface to the user. The only early exi
below 3 is a pass with **zero** findings; don't manufacture findings to pad. Codex is
advisory — validate before applying; dismissed finding → one-line why.

**What a loop absorbs, and what stops it — a question of scope, not of action.** A finding
that corrects the correction you just made **and stays inside the assigned fix set** is
**inside this loop's scope**: keep it here rather than handing it back, then act on it by its
severity exactly as Mechanics already says — Blocker/Major resolve, Minor/Nit collect and
never iterate. Ancestry decides where a finding belongs; it never decides what you do with
it, and it grants no Minor or Nit a repair round it would not otherwise get. **The assigned fix set is fixed before the pass you are answering: it is the
scope the approved story or plan assigns to this cycle, plus repair obligations you already
accepted in earlier passes.** A finding is in-set when repairing it stays inside that scope —
never merely because it arrived in the current pass, which would put every new finding in the
set by definition and leave the boundary deciding nothing. Where membership is genuinely
unclear treat the finding as **outside**, which costs a question and never a silent expansion. **A correction that leaves that set stops the
loop like any other out-of-scope finding**, even when it opens no new question at all —
absorbing it would grow the assigned work without anyone agreeing to that — and it resumes
the moment the user says whether the set now includes it. A finding
that opens a **new structural or contract question** stops the loop and goes to the user —
**size is not the test, novelty of the question is**, so a structural finding that is
genuinely small still stops it, while a long correction still aimed at the last correction
does not — provided that correction, too, stays inside the set, which its ancestry never
supplies on its own. **When a finding is both** — it corrects the last correction *and* opens a new
structural or contract question — **the new question wins and the loop stops**: novelty
overrides correction ancestry, because absorbing on ancestry is exactly how a contract
decision gets made without anyone choosing it. Stopping this way is **not an exit from the gate**: the floor, the
Blocker/Major filter and the clean-final-pass rule all stand, and the loop resumes on the
revised artifact once the question is answered — what the stop prevents is a loop
committing you to a design you never chose, which is a different failure from an
unfinished review. (Field-minted in `infinite-portfolio-canvas` and carried here because
the alternative was observed there: handing back a three-line repair-of-a-repair wastes a
session, and absorbing a contract question spends a decision that was not the loop's to
make.)

**Recognizing "clearly stuck", so that exit is a reading and not a mood.** Read the
**Blocker curve across passes**, not any single pass's total — it is the better of the two
signals, the total says less than it looks like, and one low count is a snapshot rather
than a plateau. **Neither curve measures coverage:** a low Blocker count can sit beside an
entirely unreviewed subsystem. So this exit needs three things **together**, and a missing
one means keep going: a plateau visible across passes (six or more is where the field saw
one); an **affirmative judgement that coverage is sufficient**, stated — a known materially
unreviewed area forbids this exit outright, and disclosing it does not license it; and
**Blocker or Major findings that keep regenerating across genuine repair attempts**, each
round's fix producing the next. That third condition is what makes a plateau rather than a
finish, and it is why **a clean completion takes precedence over this exit**: a
Blocker/Major-free pass **at or above the floor** has satisfied the clean-final-pass rule —
collect the Minors and Nits and close — and reporting "will not converge" on a converged
loop is a false report. **Below the floor nothing closes**, and a zero-finding pass remains
the only exception, exactly as above; a Blocker/Major-free pass 1 carrying a Minor keeps
looping.
**Surfacing does not close the cycle, and that is what makes this reachable.** You surface
*with the finding still open* — the resolve rule is not waived, no pass is credited as
clean, and the loop resumes on whatever the user decides. Reading it as "stop instead of
fixing" would put the exit in competition with the rule that every Blocker and Major
resolves, and then nothing could satisfy both.
**From pass 4 onward every pass report carries three lines.** The carrier is **your own
status report to the user** — never the Codex reply, which stays exactly one line per branch,
and never the findings file, which admits no line that is not a finding or the terminator.
They are cheap because the numbers already exist: (1) the **trend** — findings and Blocker counts across the passes
so far; (2) where this pass's findings **cluster** — product behaviour, the test instrument,
or prose about either; (3) any **require↔withdraw pair** against earlier passes, meaning a
pass demanding what an earlier pass had removed.

Those three lines expose **five tells**: the finding count rising rather than falling; the
Blocker count failing to fall; findings clustering on the **instrument** rather than on
product behaviour; findings clustering on **prose about** either; and a require↔withdraw
Comment on lines +137 to +143

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Historical inputs can disappear

When a gate cycle resumes at pass 4 or later without complete prior-pass files or optional dispositions, this rule still requires trend and require↔withdraw reporting even though the mandatory findings format cannot retain all of that history. The agent must then invent or omit inputs to the two-tell decision, causing an unsupported stop or continuation.

Knowledge Base Used:

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated manually rather than by subagent triage: this PR edits CLAUDE.md and plugins/dev-workflow/commands/workflow-init.md, and /dev-workflow:process-pr-review's instruction-path precheck forbids delegating claims on a PR that changes the instruction files a subagent would itself be running under.

Split verdict: the gap is real, the stated mechanism is not.

The mechanism is false. The claim is that "the mandatory findings format cannot retain all of that history". It can, and does. §5 requires one findings file per pass per branch at a pass-numbered slot (gate-b-<spec|quality>-pass-<p>.md), one finding per line, severity as a leading field from a closed set, and a terminator carrying the count. Both inputs the three-line report needs from history are therefore mechanically derivable from the mandated artifacts alone:

  • trend — findings and Blocker counts per pass: grep -cE '^(BLOCKER|MAJOR|MINOR|NIT) \|' and grep -c '^BLOCKER' over each pass's two files.
  • require↔withdraw — a pass demanding what an earlier pass had removed: a comparison across those same per-pass files.

Run against this PR's own cycle it reproduces the reported figures exactly — findings 14, 24, 12, 3, 6, 6, 2 and Blockers 3, 4, 0, 0, 0, 0, 0. Nothing was invented or omitted, and no optional artifact was consulted. The deletion rule does not erase this history either: §5 deletes only the slot about to be written, and slots are pass-numbered, so earlier passes survive by construction.

The gap is real, but it is availability, not format. If a cycle resumes where those prior-pass files are genuinely absent — a fresh checkout, a cleared .context/, another machine — §5 defines no behaviour for the report. Its resume note is explicitly optional and cycle-stable ("Nothing depends on it existing", CLAUDE.md:224), so it is not the fallback either. That is a true defect in the rule this PR ships, and it is being escalated to the maintainer rather than fixed in this PR.

Why not fixed here. Closing it requires new normative §5 content, and this cycle has a standing maintainer decision that it does not absorb §5 surgery — the same decision already reverted two clauses drafted inside the cycle (a clean-completion precedence and a declined-expansion exit) for that exact reason, with the three contract questions they raised parked unanswered for a follow-up story. Adding a fourth clause now, after the closing pass, would reverse that decision unilaterally. Per /dev-workflow:process-pr-review item 2 this is "contrary to a settled decision" and terminates at item 4: the maintainer decides.

Thanks — the availability half is a genuine find, and it lands in the same place as the questions this cycle already parked.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Daniel, you're right. I conflated the optional resume note with the mandatory, pass-numbered findings artifacts. Those artifacts preserve the prior-pass history: trend is directly countable, and require↔withdraw can be compared across the surviving slots; deleting the current slot does not erase earlier passes. So the original “cannot retain” mechanism is incorrect.

The valid finding is narrower: if those pass files are unavailable when a cycle resumes, §5 defines no reporting behavior or fallback. That is an availability/setup gap, not a findings-format gap. I withdraw the original mechanism and agree with the disposition to escalate it rather than add §5 surgery against the settled cycle decision.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final disposition: parked, confirmed by the maintainer.

Thanks for withdrawing the mechanism — that is the right split. The availability gap is recorded as an open question alongside the three this cycle already parked: what the pass-4-onward report does when the prior-pass record is unavailable, with the candidate answers noted as genuinely unequal (report the computable lines and name the missing ones · treat unavailable history as a stop condition of its own · make the resume note mandatory across a session boundary, which would change an artifact §5 currently calls advisory · start the duty's clock at the first pass of the current record rather than of the cycle).

It is not fixed in this PR because closing it needs new normative §5 content, and this cycle has a standing decision not to absorb §5 surgery — the decision that already reverted two clauses drafted inside it.

pair. **Any two present makes stop-and-surface mandatory, not discretionary** — you report
the tells and hand the decision to the user, and the "clearly stuck" reading above is not a
precondition for it. A loop can be worth stopping long before it plateaus.

Recorded rationale, from the maintainer rather than from a measurement of this repo: in the
Bricks consumer all five signals were measurable by **day two** of a week-long loop, and the
cost was never detection — it was the absence of a duty to say so. That is why this is a
reporting obligation with a mandatory threshold and not another heuristic to weigh.

**The two rules above do not compete**, and neither overrides the other: the absorb rule
decides whether *a finding* is inside this loop's scope, this reading decides whether *the
loop* can still converge. A small correction-of-a-correction that stays inside the assigned fix
set is absorbed and is not by itself evidence of a plateau. The field measurement behind it, quoted at the
precision its own record keeps: nineteen Gate-A passes over successive revisions of one
design spec past 2800 lines (the exact size is not part of that evidence), findings from 43
into a 2–19 range after pass 6 and never zero, Blockers from 11 to 0–1 from pass 7 on — and
the late Blockers were semantic contradictions rather than wording, which is why a low
count is a signal to read and not a clearance. That a round regenerates roughly half the
findings it closes is a **hypothesis** in that record rather than a measurement; one
lineage was established (the last pass's Blocker came from the previous pass's fix). Hence
the sizing guidance: prefer **smaller specs with named interfaces** and let the plan carry
the detail — guidance, not a threshold, because where the plateau starts is unmeasured.

**Findings go to a FILE, not the response — both gates.** In the field, long finding
lists came back cut off on effectively every substantial Gate A pass, and a cut that
lands between findings is indistinguishable from a short list: silently dropped
Expand Down
Loading