Skip to content

feat(autonomy): catalog every routine class considered, and defer the reviewer-burden term - #2694

Merged
kyle-sexton merged 6 commits into
mainfrom
feat/autonomy-routine-catalog-rows
Aug 15, 2026
Merged

feat(autonomy): catalog every routine class considered, and defer the reviewer-burden term#2694
kyle-sexton merged 6 commits into
mainfrom
feat/autonomy-routine-catalog-rows

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Closes #2682
Closes #2683

Phases 5 and 6 of the boris-routines-adoption plan, in one PR by design — one autonomy version
bump, one CHANGELOG entry. Splitting them either duplicates the bump or strands one without its
changelog line, and check-changelog-parity.sh fails on both. Independent of the detector chain
(#2690 / #2692); nothing here blocks on those merging.

Why rows for classes we are not building

A catalog that lists only what shipped cannot be reasoned from. A reader asking "why is there no
clone unifier?"
finds silence, and silence reads as an oversight rather than a decision. Nine
rows added, one existing row amended
, and every derivation run through the mapping rules
(routines.md "Mapping rules (catalog to matrix)"), never by hand — that is this phase's whole
discipline.

Existing-row sweep (first work item)

Run against routines.md itself, not the research record. Per candidate class, "no row" or the
existing row's identity:

Candidate Sweep result
dead code Row existsdead-code-sweep, DET detect | DC (review-gated PR) | repo | n/a — no agent session | not-a-routine. → amended, not duplicated.
clone work No row. The nearest row, coverage-mutation-watch, is a different observable — coverage and mutation score, not clone density — so it is no match and was not amended. → new row.
the other eight No row. → new rows.

clone-trend-gate ships a byte-identical cell signature to coverage-mutation-watch
(DET | R (digest/gate) | repo | n/a — no agent session | not-a-routine). The rows are genuinely
distinct — clone density and its trend versus coverage and mutation score — and because nothing in
the six cells says so, a class parameter now states it. Two rows that read as a copy-paste duplicate
need the difference written down somewhere.

The issue's line citations had drifted. It cites dead-code-sweep at :192 and
coverage-mutation-watch at :195; they are at :191 and :193 on main. The row identities
and their full cell text match exactly, so the sweep result stands — but the offsets are not uniform
(1 and 2), so the numbers were re-resolved rather than adjusted.

ADR-0004 incumbent gate — the search record

#2682: "ADR-0004's incumbent gate applies to rows here, not only to detectors." ADR-0004 D-1
requires the search carry path:line evidence. It is recorded here rather than in routines.md
because that contract is deployment-agnostic — an adopting org does not ship this marketplace, and a
binding parameter grounded in what this repository happens to contain is the same defect as
grounding one in this fleet's hardware. What the search changed in the contract is in the contract;
the evidence trail is here.

# Class Verdict Evidence
1 formal-logic-modeling No incumbent Searched TLA+, Alloy, model-checking, invariant-verification, design-by-contract vocabulary across plugins/. No hits that were not false positives.
2 cant-fail-test-repair Partial plugins/mutation-testing/skills/audit/SKILL.md:126 — surviving-mutant disposition surfaces tests that cannot fail a given mutant. Remediation (:201-209) authors new killing tests via /testing:write; it does not repair the existing tautological assertion, which is this class's whole content.
3 layering-enforcement Incumbent plugins/review/agents/architecture-guardian.md:3 — "Reviews code for dependency-direction violations, layer boundary breaches…"; :33 checks "inner layers must not reference outer layers; follow the project's stated layer rules." Close match, same inform-human posture. Already reflected in the row: its join trigger requires "a recurring manual pattern the incumbent reviewer does not already cover", and its parameter requires clearing the incumbent gate against the existing architecture-review surface.
4 clone-trend-gate No incumbent Searched clone-detection tool names, clone densit, copy-paste detector, code clone. plugins/review/agents/code-reviewer.md:46 flags "Duplicated Code" ad hoc during diff review — not a density trend or a gate.
5 stale-flag-removal Partial (weak) plugins/code-tidying/skills/tidy/templates/host-wiring-lane.template.md:16 lists "stale feature-flag branches" as one example under the Dead Code tidying. A bare example phrase inside a glob-scoped lane; no flag-age tracking, no staleness detector, no single-variation-everywhere trigger.
6 logic-simplification-sweep No incumbent, at either altitude Above expression level: tidyings.md has no cross-function control-flow restructuring; Beck's Guard Clauses (plugins/code-tidying/skills/tidy/reference/tidyings.md:15) restructures within one method only. At expression level: searched boolean expression, De Morgan, redundant condition, simplif.*expression across plugins/code-tidying/zero matches. plugins/code-tidying/skills/batch-simplify/SKILL.md:140 delegates to an external agent not present in this repo, with instructions naming no altitude.
7 abstraction-flattening Partial — the closest call in the set plugins/architecture/skills/improve/research/deepening/scan-briefing.md:49-51 (two-adapter rule → "speculative indirection") and research/deepening/vocabulary.md:28 (the deletion test: "If complexity vanishes, it was a pass-through") detect the same smells this class targets. But the lens's remedy is deepening, it applies no fix itself, and it routes through a human interview and planning handoff (SKILL.md:63) — there is no autonomous change path.
8 ant-only-shipper No incumbent Searched champion/challenger, canary, shadow deploy, A/B, promote-to-production, competing-implementation vocabulary. plugins/prototype/skills/explore-directions/SKILL.md is adjacent — throwaway UI variations picked by a human in-browser — not an evidence-based promotion recommender.
9 gui-crash-fuzzing No incumbent Searched fuzz, monkey-test, random-click, GUI-crash, UI-stress vocabulary. All hits false positives.
10 dead-code-sweep (amended) Partial plugins/code-tidying/skills/tidy/reference/tidyings.md:21-25 — Beck #2 Dead Code covers detection and verified deletion inside a scoped lane. It has no quarantine-then-judge staging, which is the entire normative content of the amendment.

What the search changed

  • abstraction-flattening's "no validated detector" was under-qualified. Heuristic detectors for
    exactly these smells ship — including in this marketplace. The parameter now says what is actually
    true and what the join trigger actually names: a scanner is not the join trigger; a published
    validated detector is
    , and none surveyed is validated against a fault-outcome ground truth.
  • logic-simplification-sweep's "already covered by structure-only tidying surfaces" was false,
    and the search is what established that — there is no incumbent at either altitude. The claim is
    removed rather than restated.
  • No verdict removed a row. Two partials (cant-fail-test-repair, dead-code-sweep) are
    "detection exists, the remediation shape does not", which is a capability gap rather than a
    duplicate. layering-enforcement's real incumbent was already gated in the row before this search.

Rows added

Tier 1 — join triggers

Class Judgment Output Access Derived Status
formal-logic-modeling AGT R repo C1 join: a stated invariant or specification artifact exists to model against
cant-fail-test-repair hybrid: DET detect; AGT repair judgment is the routine DC (PR) repo C3 join: proven recurring manual pattern
layering-enforcement AGT/HUM R repo C1; disposition human-gated join: layering rules stated as text, and a recurring manual pattern the incumbent reviewer does not already cover

Tier 2

Class Note
dead-code-sweep Amended. Was DET detect only; the quarantine-exit judgment makes it hybrid, and that portion derives C3 — liveness is not mechanically checkable, since reflection, dynamic dispatch, and out-of-tree callers each defeat the build that would otherwise prove it. Window floor 30–90 days with staged quarantine, never one day, and not tunable downward by an org binding.
clone-trend-gate DET | R (digest/gate) | repo | n/a | not-a-routine. Detection and trend gating only.
stale-flag-removal hybrid; removal portion derives C4 — a flag definition is a configuration surface, and the structural-blast-radius rule composes above C2/C3. Disposition human-gated.

Tier 3 — recording why not

Class Why not
logic-simplification-sweep C3; join (external): published effectiveness evidence exists.
abstraction-flattening C4 (structural surface); join (external): a validated detector is published. The fault data also runs backwards — Speculative Generality and Middle Man are in some studies associated with fewer faults.
ant-only-shipper AGT/HUM, C1, human-gated. The promotion decision is a product call.
gui-crash-fuzzing not-a-routine (DET). Reported crash-replay reproducibility is low enough that filing every crash would degrade the governed queue rather than feed it, so its WI output is replay-gated. The row also carries the isolation consequence the catalog had skipped: unattended GUI actuation requires L3.

Exclusions are exclusions, not deferrals

Recorded as such, because a deferral invites a future PR to "finish" the class:

  • clone-trend-gate — the unify decision is excluded, not a deferred posture. No surveyed
    clone-detection tool automates deciding which clones to unify, across a detection literature the
    survey found spanning two decades. On that record there is nothing to defer to, so adding a
    unify posture re-opens the class rather than extending it.
  • gui-crash-fuzzing — judging a filed crash beyond replay is excluded the same way. A filed
    crash is ordinary queue intake, owned by the issue-lifecycle classes. Without this the row's
    DET → not-a-routine exit would be skipping a judgment portion, which is precisely the misreading
    routines.md §"What a routine is" is worded to prevent.
  • stale-flag-removal / ant-only-shipper — the disposition never automates. Which branch
    survives, and whether to promote, are product calls. That is why both rows are AGT/HUM.
  • layering-enforcement — inform-human posture only; a direct-change posture derives C4 and
    no surveyed precedent supports one.

The contract is now three tiers, explicitly

The new Class parameters section carries normative detail six table cells cannot hold — stated as
binding, so a leaf contradicting one is non-conforming. That created a contradiction with three
statements in the same file saying definition depth exists only for the v1 classes, while
clone-trend-gate and gui-crash-fuzzing — neither of which will ever gain a leaf — carry
parameters.

Resolved by widening, not collapsing. The hub now declares three tiers: catalog plus mapping
rules; class parameters, binding any class leaf or not; leaf-level depth for the ten v1 classes.
Collapsing the parameters back into row cells was the alternative and was rejected — the section
exists precisely because the cells cannot carry the detail, and several parameters bind v1 and
hybrid rows generally rather than one deferred class.

Four general derivation rules now live in the mapping rules

## Mapping rules exists, in its own words, "so an adopting org can classify a novel routine
class end-to-end… without a contract change."
Three general rules were filed under
### Class parameters instead — two of them titled with a class token while generalizing in their
last sentence ("The same reading applies to every AGT/HUM row"; the structural axis "keys on
blast radius"
). An org reading the mapping rules would not have found them.

All three moved: the hybrid portion-split rule onto the hybrid bullet under Judgment and output;
the AGT/HUM clarification onto its existing bullet; the target-not-file rule onto Structural blast
radius
. A fourth was stranded the same way inside a dead-code-sweep note and is now stated
generally: a risk-raising axis evaluates per item as well as class-wide, so a class whose axis
fires on only some items derives the lower class and records the escalation rather than deriving the
higher one wholesale.

One honest limitation now stated in the rules themselves. The structural axis keys on the
change's target, and no catalog column records a target — which is why
logic-simplification-sweep and abstraction-flattening carry byte-identical axis cells
(AGT | DC (PR) | repo) and derive C3 and C4. Rather than leave a reader to conclude the three
axis columns are sufficient when they are not, the rule now says the target comes from the class's
own definition and that a row turning on it says so in its Derived row cell.

A second join semantic, separated

Every pre-existing join: trigger is a condition the adopting org can satisfy: connect a
telemetry surface, write the layering rules down, accumulate a manual pattern.
published effectiveness evidence exists and a validated detector is published are world state no
adopter can act on. One token carrying both semantics made those two rows read as backlog items.

A join (external): … legend row now separates them. Rewording the two triggers into
adopter-actionable form was the alternative and would have been dishonest — the point is that the
org cannot fire them. An excluded: status was also rejected: these classes are genuinely
deferred pending evidence, unlike the unify decision, which is excluded outright. Every other
join: row in the table was re-checked against the new definition; none belongs under the new one.

#2683 — the predicate side

  • What may never enter a predicate. An acceptance or merge rate is never a promotion input and
    is not an efficacy signal, in either role, at any cell, at any threshold.
  • Two shipped terms sit close to that line, and both are now distinguished.
    0 human-reverted merges is a correctness signal — a human asserting the change was wrong after
    it landed — not an acceptance rate. And ≥ 20 autonomous C2 merges over ≥ 14 days is a volume
    floor
    , not a rate: a ratio rises when its denominator shrinks, so attempting less — or attempting
    only what is certain to land — raises it with no change in the work. A count has no denominator to
    shrink. Selectivity leaves it flat.
  • The term inventory is now complete. It previously enumerated four term types and the table has
    seven — merge counts, advisory-review counts, and missed-blocking-finding counts were all
    missing. All three are correctness- or volume-side, so nothing in the argument moved.
  • Reviewer-burden term: deferred with an explicit trigger, not omitted. It needs a denominator,
    and a denominator needs three org-scale things this contract does not have — a population to
    divide by, a non-merge outcome signal, and a lookback window with a demotion rule. Without them the
    term moves with volume rather than trustworthiness, which rewards a cell for producing less.
    Trigger: the volume and a non-merge outcome signal; volume alone is not the trigger.
  • Standing constraint on any future tuner — its signal set stays disjoint from promotion
    evidence. Overlap is a self-dealing loop: a tuner optimizing a signal that also promotes a cell can
    raise that signal to reduce the scrutiny applied to the tuner's own output. Binds the tuner's
    inputs, not its intent, and binds whether or not the reviewer-burden term is ever activated.

Two claims in #2682 that did not verify — and one of the replacements did not either

#2682 says logic simplification above expression level is "excluded by name in tidyings.md".
It is not: plugins/code-tidying/skills/tidy/reference/tidyings.md contains zero occurrences of
simplif, case-insensitive.

The first replacement for that claim was also false. An earlier revision of this description said
expression-level simplification is "already covered by structure-only tidying surfaces" and that
simplification above that level "changes behavior in the general case". Both fail:

  • The incumbent search found no incumbent at either altitude — no cross-function control-flow
    restructuring in tidyings.md, and zero expression-simplification matches anywhere in
    plugins/code-tidying/.
  • "Changes behavior in the general case" is contradicted by
    plugins/code-tidying/skills/batch-simplify/SKILL.md:174"Simplification is
    behavior-preserving"
    — which treats behavior alteration as a regression its verification
    exists to catch. It also contradicted the row's own cell, which claims only that equivalence above
    expression level is not mechanically checkable: weaker, and correct.

A checkable-and-false claim had been replaced by an uncheckable one. The parameter now uses the row
cell's own wording and drops the coverage comparison entirely; the path:line evidence lives in the
incumbent table above, where it cannot rot a deployment-agnostic contract.

Deployment-specific fact removed from normative text

A binding parameter read: "The fleet ships no GUI to fuzz, so the class has no observable here at
all"
— inside a section declaring "A parameter here binds the class; it is not commentary", in a
contract whose own closing line is "The contract assumes no machine, org size, or budget" and whose
hosting stance makes substrate a deployment-owned binding. An adopting org that ships GUIs would read
a binding parameter grounded in this fleet's inventory.

Struck. The deployment-independent half stays, and the class's not-a-routine derivation never
depended on the inventory in the first place — it follows from Judgment DET, which holds for any
deployment.

On #2682's present-observable admission check ("Drop any candidate anchored to nothing"): the
observable here is crashes surfaced by actuating a GUI — a real, nameable artifact class, not
nothing. A deployment without a GUI simply never schedules the class, which is true of every
access-gated row in the catalog and is not an admission question. The row is admitted; what was
wrong was grounding its parameter in one deployment's inventory, not the row's presence.

Empirical claims, hedged to the register the evidence supports

The supporting research record is gitignored, so no in-tree reader can check any empirical claim in
this contract. Several were stated at a confidence the reader has no way to audit:

Was Is
"Published practice at scale runs an order of magnitude longer than a day" — ~10 days, which does not reach the 30-day floor it was offered to support The floor derives from what the window must out-last: 30 days is the shortest window spanning a monthly invocation cadence at all, 90 spans a quarterly one, and a one-day window spans nothing
"twenty years of clone-detection tooling produced no production automation" — a universal negative stated as fact "no surveyed clone-detection tool automates the choice…, across a detection literature the survey found spanning two decades"
"The flag-lifecycle tools that lead this space" "The flag-lifecycle tooling surveyed"
"No published effectiveness evidence supports automating it" — universal negative "No effectiveness evidence… surfaced in the surveyed literature"
"a direct-change posture … has no evidence behind it" "no surveyed precedent supports one"
"reproducibility around 36.6%" — two significant figures, no citation "low enough that filing every crash would degrade the queue" — and the population shift is fixed too: the figure measured replay of crashes, and was being applied to filed work items
"weakest precedent of the catalog" — a superlative over all forty-nine rows "among the weakest precedent the survey found"
"Three independent lines of evidence — peer-reviewed observational work, large-N regression, and a randomized trial", citing exactly one The rule now rests on the one finding verified at primary source (Lenarduzzi et al., quoted verbatim); the other two design families are named as survey context, explicitly not checked

The target register is the one already-well-calibrated claim in the section — "in some studies
associated with fewer faults"
— which is left as it stands.

Fresh-context verification, and the two contradictions it caught

The edits above were checked by a separate fresh-context agent with the authoring session's
reasoning withheld, briefed to judge whether each finding actually no longer holds, whether any fix
introduced a new in-tree contradiction, whether the remaining empirical claims are calibrated, and
whether every row still derives correctly. It re-derived six rows from the mapping rules and axis
cells alone before reading the Derived row column: six of six matched.

It found two real contradictions, both now closed:

  • gui-crash-fuzzing's Output cell (R + WI) contradicted its own binding parameter, which
    said filing would degrade the governed queue. The previous revision masked this — "the fleet
    ships no GUI to fuzz"
    made the whole row moot, so the Output cell never had to agree with the
    parameter. Removing that escape exposed it. The WI output is now admission-constrained: an item
    is filed only where re-running the recorded input sequence reproduces the crash, and the rest stay
    in the R half. That gate is a re-run rather than a judgment, so it adds no AGT portion and the
    DET exit stays complete.
  • work-classes.md deferred the reviewer-burden term on "the org-scale trust-path requirements
    this contract already defers"
    — a phrase with zero other occurrences anywhere in the
    repository. A back-reference leaked from the gitignored research record into normative text,
    asserting a prior decision no in-tree reader can locate. The three requirements were already
    enumerated inline, so the phantom reference is dropped rather than manufactured.

It also caught the stranded per-item rule, the missing-target-column limitation, the four
over-claimed hedges above, and one SSOT gap outside the three files in play:
guardrails/isolation-ladder.md scoped L3 to untrusted-provenance (C5) work alone, while
the catalog's access rule has always also required it for unattended GUI actuation — a demand that
reaches classes deriving no work class, so it cannot travel through the matrix's min-isolation
column. That leaf is the contract's source of truth for when a level applies, and was incomplete
against its own charter. Fixed at the root rather than papered over in routines.md.

Other corrections in this pass

  • The posture-qualified-identity mandate was unsatisfiable for seven of the nine hybrid rows.
    The new parameter made it mandatory for every hybrid row, while Routine identity says posture
    tokens are owned by the class's definition leaf — and seven hybrid rows are join:-deferred with
    no leaf. Scoped: tokens are minted with the leaf, so the obligation binds at leaf time; until then
    a deferred class records its split in its Judgment cell and binds nothing.
  • The L3 on gui-crash-fuzzing does not come from the matrix. The guardrail matrix's
    min-isolation column is indexed by work class (C1C5); a row deriving no class cannot reach
    it. The floor comes from the GUI-actuation mapping rule directly, and the row and its parameter
    now say so rather than implying a matrix lookup that would not resolve.
  • ## Precedent pointers' scope line claimed coverage it did not have. It declared itself
    pointers "for the deferred and deterministic rows"; all nine new rows are deferred or
    deterministic and none got one. Narrowed to the rows where a shipped pattern was surveyed, with
    an explicit note that absence is not a claim that no pattern exists — rather than inventing nine
    pointers this pass has no evidence for.
  • dead-code-sweep's precedent pointer was stale against the amended row. It described deletion
    pipelines with no quarantine stage while the row's whole normative content is staged quarantine —
    so it read as precedent for the unstaged form. It now says the staged quarantine is the row's own
    normative content, not a property read off those pipelines.
  • ### Reviewer-burden term sits under a preamble that did not cover it. The preamble said
    "the threshold values below are suggested defaults the org binds"; a deliberately-not-live term
    with no threshold is not a suggested default. Promoting it to a sibling ## was the alternative
    and was rejectedfeat(autonomy): record the reviewer-burden promotion term as deferred #2683 names §"Suggested default predicates" as its placement. The preamble
    was narrowed to the table instead, and now states that the two subsections after it are not
    defaults and carry no bindable threshold.
  • CHANGELOG bullets re-filed per Keep a Changelog, which the file's own header cites. The
    dead-code-sweep amendment and the derivation-rule bullet change existing content and moved to
    ### Changed. The row count is now exact: nine added, one amended — class rows go 40 → 49,
    and "ten rows added" double-counted the amendment. (Commit 21fce8eb's body carries the same
    off-by-one; history is not rewritten, the durable surface is fixed.)

Sanity checks — actual output, re-run at c0795c93

  • No two rows share a class tokenawk -F'|' '/^\| [a-z]/ {print $2}' … | sort | uniq -d
    returns empty. Verified non-vacuous: the same pipeline yields 51 distinct tokens, against
    41 on origin/main. The delta is +10, not +9: nine new class rows plus the new
    join (external): … status-legend row, which the pipeline also matches because legend rows begin
    | join…. Class rows alone go 40 → 49.
  • grep -n "388\|180 merged" plugins/autonomy/reference/routines.mdempty.
  • grep -ci "never a promotion input\|no acceptance-rate\|not an efficacy signal" …work-classes.md
    1.
  • grep -Eci "predicate .*(merge|acceptance) rate|(merge|acceptance) rate .*(threshold|>=)" …work-classes.md0.
  • scripts/check-changelog-parity.sh --check-bump origin/mainexit 0 (autonomy
    0.16.12 → 0.17.0).
  • scripts/check-changed-skills.sh origin/main → "No changed skills under plugins/*/skills/".
  • markdownlint-cli2 on all four changed files → 0 issues.

Declared human gate — evidence recorded, disposition open

#2682: "a reviewer who did not author the rows re-derives three of them from the mapping rules and
the row's own axis cells alone. No command self-clears this."

A fresh-context agent performed the re-derivation. No human re-derived these rows, and this PR
does not claim the gate is cleared.
An earlier revision of this description said CLEARED; that was
the authoring session grading its own homework, and a fresh-context same-vendor agent is the middle
rung of the independence hierarchy, not the reviewer #2682 names.

The full record — the withheld-answer protocol, the agent's unprompted provenance statement, the
three derivations, and this same caveat — is posted as a durable comment on both #2682 and this
PR, so it does not live only in a commit body and a PR description written by the session that
produced the rows.

Class Independently derived Authored Match
dead-code-sweep C3 C3 yes
stale-flag-removal C4 C4 yes
abstraction-flattening C4 C4 yes

Three of three. The run predates three subsequent commits, so it was performed against a
superseded revision — but the later verification pass re-derived all three classes against the
current text and reached the same three answers, so the result survives the edits rather than
merely predating them.

More useful than the match: the derivation showed the mapping rules imply three things they never
stated, each of which the agent had to reason out to avoid a wrong answer. All three are now
stated in ## Mapping rules itself, alongside the fourth the verification pass found stranded.

What a human still owes this gate: deciding whether an agent re-derivation satisfies it. The
record exists so that call can be made against the actual protocol rather than against a summary.

Related

Independent of #2690 / #2692. Blocks the can't-fail test detector's row amendment (#2684).

… reviewer-burden term

Two issues, one version bump: splitting them either duplicates the bump or
strands one without its changelog line, and the parity gate fails on both.

A catalog that lists only what shipped cannot be reasoned from. A reader asking
why there is no clone unifier finds silence, which reads as an oversight rather
than a decision -- so the classes deliberately not built get rows too, and the
row's own Status cell carries why. Ten rows added, one amended, every derivation
run through the mapping rules rather than by hand.

dead-code-sweep was amended rather than duplicated. It was DET detect only; the
quarantine-exit judgment makes it a hybrid whose judgment portion derives C3,
because liveness is not mechanically checkable -- reflection, dynamic dispatch,
and out-of-tree callers each defeat the build that would otherwise prove it. Its
window floor is 30-90 days with staged quarantine and is not tunable downward by
an org binding: published practice at scale runs an order of magnitude longer
than a day, and a one-day window turns a detector false positive into a deletion
before anything can contradict it.

Three exclusions are exclusions, not deferrals, and the distinction is recorded
because a deferral invites a future PR to "finish" the class. Clone work is
detection and trend gating only -- twenty years of clone tooling produced no
production automation for deciding which clones to unify, so there is nothing to
defer to. stale-flag-removal and ant-only-shipper stop at the disposition: which
branch survives and whether to promote are product calls, which is why both rows
are AGT/HUM rather than AGT. layering-enforcement admits the inform-human posture
only; a direct-change posture derives C4 by structural blast radius and has
nothing behind it.

A new Class parameters section carries the normative detail six table cells
cannot hold, and is explicitly binding rather than commentary -- a leaf that
contradicts one is non-conforming.

On the predicate side, work-classes.md now states what may never enter one. An
acceptance or merge rate is never a promotion input and is not an efficacy signal
-- three independent lines of evidence find artifact quality weakly-to-not
coupled to acceptance. The section names the nearest existing row rather than
leaving a reader to guess: `0 human-reverted merges` is a correctness signal, a
human asserting the change was wrong after it landed, not an acceptance rate,
which counts how much got merged. Without that sentence the new prohibition reads
as contradicting the predicate directly above it.

The reviewer-burden term is recorded as deferred with a trigger rather than
omitted, because a designated planning pass was asked to settle it and silence
would leave that obligation unfilled. It needs a denominator, and a denominator
needs the org-scale trust-path requirements this contract already defers at solo
volume. Without them the term moves with volume rather than trustworthiness --
which rewards a cell for producing less. The trigger is the volume AND a non-merge
outcome signal; volume alone is not it.

Finally, a standing constraint on any future tuner: its signal set stays disjoint
from promotion evidence. Overlap is a self-dealing loop, since a tuner optimising
a signal that also promotes a cell can raise that signal to reduce the scrutiny
applied to the tuner's own output. It binds the inputs, not the intent, and binds
whether or not the reviewer-burden term is ever activated.

Closes #2682
Closes #2683

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 15, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 2s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown

Warning

Automated review did not complete — this is an infrastructure failure, not a review verdict.

Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."

Re-run the job, or workflow_dispatch this workflow with the PR number, to retry the review. A new push re-triggers this lane only if the caller's pull_request triggers include synchronize (the canonical caller omits it).
An automatic retry may already have run — it is skipped when a partial review could duplicate comments, or when the failure class needs an operator (auth).

@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown

Warning

Automated security review did not complete — this is an infrastructure failure, not a review verdict.

Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."

The check is green on purpose, and it is not evidence. It certifies that a security pass ran, and this one did not complete — but the cause is outside this PR's control, so merging is deliberately left unblocked rather than locking every merge for the length of the outage. Nothing was reviewed at this head. Where this check is required, it is satisfied without that evidence; a human should review security-sensitive changes here before merging.

Re-run the job, or workflow_dispatch this workflow with the PR number, to retry the review (ci-workflows#227). A new push also retries it only if the caller's pull_request triggers include synchronize (the canonical security caller keeps it). An automatic retry may already have run — it is skipped when a partial review could duplicate comments, or when the failure class needs an operator.

Re-running does NOT help for every class:

  • rate-limit that persists across re-runs, or auth — the credential or usage budget needs an operator; retrying will not clear it.
  • a run that exhausted its turn budget ("subtype":"error_max_turns" above) will exhaust it again. As the PR author, split the change into smaller PRs; raising --max-turns is a change to the caller workflow, not something you can set on this PR.

…d were implicit

#2682 declares a human gate no command can self-clear: a reviewer who did not
author the rows re-derives three of them from the mapping rules and the row's own
axis cells alone. A fresh-context agent was given the mapping rules and the axis
cells for dead-code-sweep, stale-flag-removal, and abstraction-flattening with the
Derived column withheld, and asked to derive rather than check. It reached C3, C4,
and C4 independently -- matching all three authored rows.

What it surfaced is that the mapping rules imply three things they never state,
and it had to reason each one out to avoid a wrong answer. Left implicit, the next
person derives differently.

A hybrid row is portion-split, so it binds a posture-qualified identity rather
than the bare class token, its Derived cell carries the judgment portion's class
because that portion IS the routine, and it is never flagged not-a-routine --
that flag belongs to the pure-DET bullet, for a class with no agent portion at
all. The three new hybrid rows carried "detect n/a -- no agent session" in their
Derived cells, which put the pure-DET marker inside a hybrid row and diverges from
every existing hybrid row; the no-agent-session property is already stated in the
Judgment cell and is now stated only there.

AGT/HUM assigns a disposition, not a class. It is class-silent by construction, so
reading it as a terminal derivation produces a row with a human-gated disposition
and no verification topology, no checker floor, and no cost tier. The numeric
class comes from the remaining rules.

The structural-blast-radius axis fires on the change's target, not on the file it
lives in. A one-line fix that merely sits in a file declaring an interface is the
over-read this excludes; a mechanical single-implementation inline does not demote
the row, because the axis keys on blast radius rather than on how reliable the
editing mechanism is.

One substantive refinement to dead-code-sweep. C3 is the class-level derivation,
but deleting a symbol on a published, cross-repo-consumed surface is a contract
change, so the structural axis fires per item and escalates that item to C4. The
class does not derive C4 wholesale -- then the direct-change rule's C2/C3 branch
would be nearly unpopulated for repo-scoped deletion work. C3 versus C4 is the
difference between auto-merge ever becoming eligible and human merge always, so
the leaf owns the predicate that decides which side an item falls on.

Also recorded: a green quarantine window is inductive evidence, never proof. The
paths a bounded window under-samples worst -- disaster recovery, annual jobs,
error and fallback branches, a consumer pinned to an older version -- are exactly
the ones that make deletion dangerous, and a suite that still passes after removal
proves the suite does not cover the symbol, which is the null hypothesis rather
than the alternative.

Refs #2682

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

… rows

Six high-severity findings from a review that read the catalog against the
mapping rules rather than against the story behind them.

gui-crash-fuzzing skipped the one mapping rule that names GUI. The Access
bullet on unattended GUI actuation requires the highest isolation-ladder
tier; the row scored repo and stopped at the L2 unattended floor. The
Derived cell now applies it -- L3, because the fuzz target is built from the
repo but synthetic input actuation is not contained by a process boundary.
Its parameter also stopped modelling the reproducibility judgment it argued
about: deciding whether a filed crash reproduces is now excluded from the
class the way clone-trend-gate excludes the unify decision, since a filed
crash is ordinary queue intake. The DET exit is complete rather than
skipping a split the file elsewhere warns against skipping.

The logic-simplification parameter claimed simplification above expression
level changes behavior in the general case. batch-simplify's own skill says
simplification is behavior-preserving and treats behavior alteration as a
regression, and the row's own cell claims only that equivalence above
expression level is not mechanically checkable -- weaker and correct. The
parameter now uses the cell's wording. Its "already covered by structure-only
tidying surfaces" claim is dropped rather than restated: tidyings.md carries
no simplification content at all, so the checkable-and-false claim had been
replaced by an uncheckable one.

Class parameters contradicted three statements in its own file about
definition depth being v1-only. The contract is now three tiers explicitly:
catalog plus mapping rules, class parameters binding any class leaf or not,
and leaf-level depth for the ten v1 classes. Widened rather than collapsed --
the section exists precisely because six table cells cannot carry the detail,
and several parameters bind v1 and hybrid rows generally.

work-classes.md's defense of its own table was wrong about the table. The
C3 row opens with a merge count per window, which is in none of the four
categories the prose enumerated. Merge counts are now enumerated, and the
count-versus-rate argument is stated in the form that is actually valid: a
ratio rises when its denominator shrinks, so selectivity raises it with no
change in the work, while a count has no denominator to shrink.

A binding parameter rested on this fleet's inventory -- "the fleet ships no
GUI to fuzz" -- inside a contract that assumes no machine, org size, or
budget. Struck. The class is not-a-routine on judgment grounds independent of
any deployment's inventory, which is the deployment-agnostic half.

Three general derivation rules were filed under Class parameters, two of them
titled with a class token while generalizing in their last sentence. Mapping
rules exist so an adopting org can classify a novel class without a contract
change, and an org reading that section would not have found them. All three
moved: the hybrid portion-split rule under Judgment and output, the AGT/HUM
clarification onto its own bullet, the target-not-file rule under Structural
blast radius.

Also: a join (external) status separates deferral on world state no adopter
can act on from the org-actionable join triggers that share the column; the
posture-token mandate is scoped so it is satisfiable for deferred hybrids
with no leaf; the 30-90 day floor derives from the invocation cadences the
window must out-last rather than from an order-of-magnitude figure that did
not reach 30; unsourced universal negatives and a two-significant-figure
statistic are hedged to the surveyed record; the precedent-pointer scope line
no longer implies exhaustiveness and the dead-code pointer no longer reads as
precedent for the unstaged form; and clone-trend-gate and
coverage-mutation-watch, which carry byte-identical cells, are recorded as
distinct classes over distinct observables.

Refs #2682
Refs #2683

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

…om the matrix

The term inventory was still short by two types one row over from the one the
review named: a review count in the AI-review promotion predicate, and the
missed-blocking-finding counts in both C3 rows. Fixing only the named
instance while restating the sentence as a full inventory made the
exhaustiveness claim stronger than the list. Both missing types are
correctness-side, so nothing in the argument moves.

The gui-crash-fuzzing row asserted an isolation floor through the matrix's
min-isolation column, which is indexed by work class -- a row deriving no
class cannot reach it. The L3 comes from the GUI-actuation mapping rule
directly, and the row and its parameter now say so.

Refs #2682
Refs #2683

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

The logic-simplification parameter read "that absence is the join trigger",
which joins the class when evidence is absent -- the inverse of what its
status cell says. The absence is the reason for deferral; the trigger is its
resolution.

The changelog still carried the count-versus-rate argument in the form that
does not hold: merging a higher fraction of a fixed attempt pool DOES raise
a count. It now carries the form that does -- a ratio rises when its
denominator shrinks and a count has no denominator to shrink -- matching the
contract. The changelog also now reflects the seven-type term inventory and
the fact that L3 comes from the GUI-actuation mapping rule rather than from
a matrix column a classless row cannot index.

Scoped the term-inventory sentence to the predicate table and noted that the
demotion evidence set enumerates one of its seven types, so a reader does not
count verification divergence as an eighth the sentence missed.

Refs #2682
Refs #2683

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

…found

The gui-crash-fuzzing row said its output includes work items while its own
binding parameter said filing would degrade the governed queue. The previous
revision masked this: "the fleet ships no GUI to fuzz" made the whole row
moot, so the Output cell never had to agree with the parameter. Removing that
escape exposed it. The WI output is now admission-constrained -- an item is
filed only where re-running the recorded input sequence reproduces the crash,
and the rest stay in the R half. That gate is a re-run rather than a
judgment, so it adds no AGT portion and the DET exit stays complete.

work-classes.md deferred the reviewer-burden term on "the org-scale
trust-path requirements this contract already defers", a commitment with zero
other occurrences anywhere in the repository -- a back-reference leaked from
the gitignored research record into normative text, asserting a prior
decision no in-tree reader can locate. The three requirements were already
enumerated inline, so the phantom reference is dropped rather than
manufactured.

Also from the same pass:

A fourth general derivation rule was stranded in a dead-code-sweep note --
that a risk-raising axis evaluates per item as well as class-wide. Same
category as the three already relocated, so it joins them in the mapping
rules; the dead-code parameter now reads as that rule applied.

The structural axis keys on the change's target and no catalog column records
a target, which is why logic-simplification-sweep and abstraction-flattening
carry identical axis cells and derive C3 and C4. The rule now says so, rather
than leaving a reader to conclude the axes are sufficient when they are not.

isolation-ladder.md scoped L3 to untrusted-provenance work alone while the
catalog's access rule has always also required it for unattended GUI
actuation. That leaf is the contract's source of truth for when a level
applies, so it named one of two demands.

Four remaining claims were still stated above the confidence an in-tree
reader can audit: two decades without an appearing tool, a bare "no evidence
behind it", a superlative over all forty-nine rows, and three design families
asserted where one was verified at primary source.

Refs #2682
Refs #2683

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Declared gate — the independent re-derivation, recorded

#2682 declares a gate no command can self-clear:

a reviewer who did not author the rows re-derives three of them from routines.md:88-146 and the
row's own axis cells alone. No command self-clears this.

Stating it plainly: a fresh-context agent performed the re-derivation. No human re-derived these
rows.
This comment exists because the run was previously recorded only in a commit body and the PR
description — prose written by the authoring session about itself. It is posted on both the issue and
the PR so the record does not live on one surface only, and so the gate's disposition stays a human's
call made against the protocol rather than against a summary.

Protocol — what was withheld

  • The agent was given routines.md §"Mapping rules (catalog to matrix)" and the Judgment / Output /
    Access cells for three classes. Nothing else.
  • The Derived row column was withheld for those three classes.
  • The catalog table, the CHANGELOG, the PR body, and the diff were placed out of bounds.
  • The instruction was to derive, not to check — no authored answer was available to agree with.

Provenance statement

The agent opened, unprompted, by stating what it had read: routines.md lines 80–147 only — stopping
one line short of the catalog heading — and that no Derived row value for any of the three classes
was visible to it. Paraphrased from the run record, not quoted verbatim.

The three derivations

Class Independently derived Authored Match
dead-code-sweep C3 C3 yes
stale-flag-removal C4 C4 yes
abstraction-flattening C4 C4 yes

Three of three.

More useful than the match: three implicit rules

The derivation showed the mapping rules imply three things they never stated, each of which the
agent had to reason out to avoid a wrong answer. Left implicit, the next reader derives differently.
All three are now stated in ## Mapping rules itself — not in a per-class note — because that is the
section an adopting org reads to classify a novel class:

  1. A hybrid row is portion-split. It binds a posture-qualified identity rather than the bare class
    token, carries the judgment portion's class in Derived row, and is never flagged
    not-a-routine — that flag belongs to the pure-DET bullet. This caught a real defect: three new
    hybrid rows carried detect n/a — no agent session in their Derived cells, putting the pure-DET
    marker inside a hybrid row and diverging from every existing hybrid row.
  2. AGT/HUM assigns a disposition, not a class. It is class-silent by construction, so it never
    terminates a derivation. A row stopping there carries a human-gated disposition with no
    verification topology, no checker floor, and no cost tier.
  3. The structural axis fires on the change's target, not the file it lives in. A one-line fix in a
    file that happens to declare an interface is the over-read this excludes; a mechanical
    single-implementation inline does not demote a row whose target is the structural surface,
    because the axis keys on blast radius rather than on how reliable the editing mechanism is.

Standing caveat

A fresh-context same-vendor agent is the middle rung of the independence hierarchy, not a human
reviewer. This is evidence toward the declared gate, not a claim that the gate is cleared.
#2682's wording names a reviewer; whether an agent run satisfies it is a human judgment, and this
record exists so that judgment can be made against the actual protocol.

@github-actions github-actions Bot deleted a comment from claude Bot Aug 15, 2026
@claude

claude Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@kyle-sexton
kyle-sexton merged commit fd41866 into main Aug 15, 2026
42 checks passed
@kyle-sexton
kyle-sexton deleted the feat/autonomy-routine-catalog-rows branch August 15, 2026 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(autonomy): record the reviewer-burden promotion term as deferred feat(autonomy): catalog rows for every routine class considered

1 participant