triage(branches): 35 branches that never had a PR — commit count is the wrong instrument - #3278
Merged
Merged
Conversation
…he wrong instrument, path residue is the right one Standing operator rule: tickets, PRs and branches that are not triaged are P0. `git ls-remote --heads origin` = 112; branches with no PR in any state = 35, and none had ever been classified. The obvious measure is wrong by construction. `rev-list --count main..<b>` says 30 of the 35 carry unique commits — but this repo squash-merges from a merge queue, so a branch whose content LANDED still shows every original commit as unique. What decides is path residue: of the paths a branch changes against its merge-base, how many do not exist on main at all. 4 + 1 + 11 + 6 + 2 + 11 = 35 DELETE 4 merge-queue artifacts DELETE 1 zero commits ahead DELETE 11 zero path residue DELETE 6 residue is a fixture RENAME only DELETE 2 superseded by OPEN #3021 REVIEW 11 genuinely absent from main The prrev stack (12 branches, 2026-08-30) looked like it had dropped a discriminating test row: `row-07-honest-docs-only-all-not-triggered` is absent from main. It had not. Main carries `row-07-honest-docs-only-pmat-consulted`, plus row-16/17 renumbered to row-23/24 — every residue in that stack is a rename. Counted by ROWS rather than by directory name, main has 113 fixture rows against the stack's 24. The subsystem shipped by another route with 4.7x the coverage. That correction is the point of the method note: residue BOUNDS the question, it does not answer it. PMAT-1094 is the other worked example — 8 absent paths, 7 of them throwaway `fix_derives*.py` / `fix_dry*.py` scratch scripts. Two REVIEW rows matter to this spec: `agent/R-5` holds `.github/workflows/release-assets.yml` and `contracts/apr-publish-cascade-v1.yaml`, neither of which exists on main, and both are T-3/T-4 surface. No branch is deleted here. kind:triage is classify and link only: this diff touches docs/audits/** and docs/roadmaps/roadmap.yaml and nothing else. Pmat-Ticket: PMAT-3231 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
noahgift
added a commit
that referenced
this pull request
Sep 14, 2026
…as itself only a review comment
§11.1 states: "Every sweep PR body carries one line ... Absent is a PR-body lint
failure, not a review comment."
$ grep -rl ont-delta scripts/ .github/ Makefile
(nothing)
The rule shipped as prose in #3268 and nothing read it. A rule whose enforcement is
"not a review comment", enforced only by review comment, is this repo's anti-theater
class one level up from the guard it now sits beside in ci.yml.
WHAT A SWEEP PR IS — and only half of it may be a list.
* the prose sinks §11.1 NAMES are constants here, quoted, and printed on every
run so drift between spec and guard is visible instead of silent.
* "a known-red list anywhere" is DERIVED: the union of a working-tree `find` and
the index, the same rule check_baseline_ratchets.sh uses and for the same two
reasons — a new baseline arriving unclassified is how the class survives, and a
tracked-only universe is a free pass for a file present but not yet added.
The derived half is what makes it non-trivial, measured on real PRs:
#3268 sweep via prose sink docs/specifications/... PASS (carries none+reason)
#3277 sweep via KNOWN-RED LIST scripts/cb200_baseline.txt FAIL -> now fixed
#3278 not a sweep PASS
#3245 not a sweep PASS
#3277 touches no prose sink at all. A hand-typed sink list would have passed it, and
it is a true positive: that PR withdraws a wrong FAIL and adds an ONT-6 Unknown
reason, which is precisely §11.1 form 3. Its body now carries
`ont-delta: reason ont6-unread-window`.
Case table, 15 rows, and it DISCRIMINATES: deleting the vocabulary check turns the
table red (verified by mutation, not by reading). Rows cover kind-outside-the-
vocabulary, none-without-a-reason, id-absent, case, leading space, and empty body.
Vacuity floor: an empty changed-file list exits 2, because "not a sweep PR" is a
verdict this guard could not have reached.
Two defects found writing it, both kept as comments:
* a RETURN trap runs after bash destroys the function's locals, so `rm -rf "$tmp"`
died on an unbound variable AFTER fifteen green rows — a self-test that passed
and exited 1.
* bashrs SEC011: an unvalidated `rm -rf "$var"` is a delete-anything primitive.
Now shape-checked before the sweep. bashrs 7.4.1: 0 errors.
WORKFLOW CHANGE, stated rather than buried: this adds one step to ci.yml. §11.1
cannot exist without a caller, and guard_tree.sh runs check_*.sh BARE — which would
run only the self-test, fifteen green rows judging no PR body, the exact failure the
neighbouring step's comment documents.
ont-delta: resolves scripts/check_pr_ont_delta.sh — §11.1 was a prose claim; this
turns it into a checkable one (form 4).
Pmat-Ticket: PMAT-1098
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
noahgift
enabled auto-merge
September 14, 2026 18:38
# Conflicts: # docs/roadmaps/roadmap.yaml
…collapses it back to base bytes check_roadmap_diff_additive.sh: VIOLATION reserialised: id=PMAT-3229 (bytes differ, no field actually changed). The union resolver I hand-rolled rejoined entry blocks with a newline and left an extra blank line after PMAT-3229's `notes: null`, so the entry ABOVE my insertion re-serialised without any field changing. PMAT-980 (#2874) is exactly this rule, and the guard names its own remedy: `scripts/roadmap_trim.py` collapses a re-serialisation back to base bytes. Ran it. The entry is byte-identical to origin/main again (438 = 438 bytes). Pmat-Ticket: PMAT-3231 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… a CLOSED PR still leaves unlanded work The first pass asked "which branches never had a PR?". A branch whose PR was opened and then closed unmerged is excluded by that question — it HAS had a PR — and is exactly a branch carrying unlanded work with no path forward. 117 remote = 41 open-PR + 38 never-PR'd + 37 closed-PR + main. Classified with the same path-residue instrument: 31 DELETE (0 residue or 0 ahead), 6 REVIEW. Zero branches are merged-with-branch-left-behind, so deletion-on-merge works; all 37 are abandoned PRs — consistent with 29 of 146 PRs over 10 days (20% of production) closed unmerged. Five-whys on that rate: #3294. Batched into this PR rather than opened as a 43rd: #3294 Why 5. Pmat-Ticket: PMAT-3231
noahgift
added a commit
to guyernest/aprender
that referenced
this pull request
Sep 15, 2026
…tinuous triage, decision procedure, ontology kaizen (§11), and the chain of reasoning (§12) (paiml#3268) * docs(spec): APR-RELEASE-001 §4.1/§4.2/§5.1/§10 — the work the train did not name A day spent on T-1 surfaced five things the spec did not cover. Four are now clauses; the fifth turned out to be covered already and is only made precise. §4.1 FEATURE MATRIX — T-1 named it from the start and it was never built. Its first run (paiml#3262) measured 100 of 430 (crate, feature) pairs RED, every one unreachable from any default set — which is exactly why it could go dark: `cargo check --workspace` stays green over all of it because feature unification hands each crate whatever its siblings enabled. The section defines the universe (per-pair from `cargo metadata`, never a powerset — aprender- orchestrate alone declares 78 features), the five shapes that accounted for all 100, the known-red list and why a listed pair that PASSES must be fatal, and the `compile_error!` + private `__x-linked` form for a feature that cannot be built at all. Struct drift is listed as shape 5 because nothing else in the train watches for an upstream type growing a field. §4.2 EXAMPLES — T-1 says every `cargo run --example`, which is a different clause from building them (83 s vs ~2 h). Measured: three of five random examples ran past a 60 s cap. They are compute demos, not CLIs, so TIMEOUT IS A PASS and the assertion owed is "starts and does not crash". Asserting a duration would be a wall-clock assertion in a required check. Both clauses carry a vacuity floor: a discovery that finds nothing reports zero failures, which reads exactly like a pass. §5.1 THE DEBT TAX — the pre-commit gate refuses any commit touching a file with a function over cyclomatic 30 / cognitive 25, and `--no-verify` is banned, so a one-line fix costs the decomposition of every offender in that file. Measured in one day: 11 pre-existing violations paid down, worst cognitive 91, 73, 61, none in code that day's changes wrote. It is not a build row because it is not schedulable — it is a toll on whatever you touch. Now it is at least measured: `debt:` in §7. §10 DECISION PROCEDURE — §6 is deliberately "no judgement calls", so design forks had nowhere to go. Codifies what worked: fan out through agy not Claude subagents; the brief carries the measurements so lanes do not each measure the premise differently; plant one trap question; a verdict is a claim until the orchestrator re-runs the acceptance command; **a premise error voids the vote and the fix is another round, not the orchestrator's judgement** (paiml#3179 round 2 overturned round 1 unanimously once three facts were read out of the tree); overriding the majority is allowed once, only on a fact no lane had, and must be recorded with the losing argument quoted; prefer the reversible option when the vote is close. §6 — `untriaged` must be counted PER SURFACE. Measured 2026-09-14: issues were 319/320 triaged while PRs were 20 of 34 with no milestone at all, and one number reported the clean surface while hiding the breached one. Also states plainly that triage is not disposal: the ledger grew net +149 over ten days while ~100 % triaged, with 312 of 320 open issues opened by the agent itself. This is the same finding §6 already recorded for the 0.67 train ("filing was the work product and closing was nobody's"); it now has a stop rule. §8 — three stop conditions: a declared full-time build host at 0 % occupancy while a queue has pressure (mini, measured all of 2026-09-14) is a routing defect, not spare capacity; a stale known-red list; a design fork goes to §10. readme_contract 15/15. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(spec): §6.1/§6.2/§6.3 — triage is continuous, covers branches, and a milestone must fit its date Three gaps in §6, each measured 2026-09-14. §6.1 CADENCE. "Once per train" is what let 20 of 34 open PRs carry no milestone at all, every one opened in the preceding two days. A train is 48-72 h; a PR opened an hour after the pass is invisible for the rest of it. Triage now runs on the P0 · Pack wakeup, beside the fleet sample — same cadence, same receipt, and equally P0 per the operator ("ticket, pull requests, branches that are not triaged are P0"). The per-wakeup pass is mechanical and bounded; the once-per-train pass keeps only what needs the whole window: the §6.3 capacity check and the T-5 reconcile. §6.2 BRANCHES were the unwatched surface. 107 remote branches, 35 with an open PR, 72 without: 32 younger than 7 d, 27 in a 7-14 d band NO RULE LOOKS AT, 13 already R-3-eligible. R-3 archives a branch with no PR and a tip older than 14 d, so work that stalls on day 8 is invisible for six more days and is then deleted without ever having been seen. New test: no open PR and a tip older than 7 d must get a PR (draft is fine) or be archived now. A branch with no PR is not work in progress, it is work nobody can see. §6.3 PRIORITISATION. §4 says scope is assigned after the fact — right for what a train CONTAINS, wrong as a plan for what it PROMISES. With no capacity rule a milestone is a dumping ground with a date on it. Measured at closure = 6.1 issues/day over the trailing 7 days: 0.68.0 280 open due in 1 d needs ~46 d OVER BY 45 DAYS 0.69.0 53 open due in 4 d needs ~9 d over by 5 d 0.70.0 15 open due in 7 d needs ~2 d fits A date 45 days of arithmetic away from its content is not a commitment; it is a label, and every number computed from it is fiction. The rule is arithmetic, so it stays inside §6's no-judgement-calls design: capacity = days_remaining x measured closure_rate_p50. Over capacity is reported every wakeup, not treated as an error. At T-0 an overcommitted next milestone SPILLS lowest-priority-first until it fits — P0 never spills, then P1, then unlabelled, then oldest kept. The operator sets priority by labelling; the arithmetic sets the cut line, so no train needs a judgement call about scope. A P0 set that alone exceeds capacity is a STOP (§8): that is over-promising at the one level the operator controls, and only the operator can cut it. closure_rate is MEASURED; under 7 days of data it reports [U] and spills nothing. Arrival is the other half: 6.1/day closure against a ledger that grew net +149 in ten days means the cut line moves further out every train however it is drawn. R-5 is the control on that; capacity only decides what a date may claim. readme_contract 15/15. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(spec): §11 — a surface sweep ends in `pv`, or it did not end ONT-001 v4.3 §6 assigns aprender every ontology row but three. Measured at fa6e35f: 1 of 17 merged, 0 of 1818 contracts carry `entity:`, `shape:` or `evidence:`, no `pv census`, no `pv extract`, no `ontology/` module. Two of those measurements are the reason for this section. `pv kaizen` IS the kaizen loop and it is code-only — bindings, call sites, E0/E1/E2 assertions. The train sweeps features, examples, README, CLAUDE.md, workflows, model files and CSVs, and the loop that is supposed to improve on each sweep cannot see one of them. The upstream spec is UNTRACKED in infra. No commit, no history, unfetchable from gx10, yoga or mini — so a quorum lane cannot read the premise at all and every ontology verdict it returns is unverifiable by construction. Stop condition, fixed in infra (ONT-P), not here. §11.1 makes the rule mechanical: a surface sweep closes with one of four deltas — an entity type + extractor, a shape whose violation is the defect class just found, a new Unknown{} reason, or a `resolves:` target — or with a named `ont-delta: none <reason>`. Unnamed is P0. This spec's own §4.1 is the counter-example: 100 red pairs as an awk matcher inside night.yml, no contract, no shape, re-derived by hand before every undraft. §11.4 is why this makes the quorum more effective, which is the point. Premises cite ids, verdicts are ONT-6 lattice elements, reduce is meet=min rather than a vote count, and the planted trap becomes Unknown{PositiveControlFailed} by rule instead of by the orchestrator noticing. paiml#3179 round 1 was a 2/3 majority over verdicts that had no lattice meaning; under §11.4 it does not reduce to Pass. §11.2 ratchets five counters, §11.3 puts one row per train (16 rows, ~40 days [A]) and lands every gate unarmed, §11.5 adds the `ontology:` report line and `lattice` to `quorum:`, §11.7 gives five falsifiers. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(spec): §11 review — ids disambiguated, paiml#3179 claim corrected, stops and report lines in one place Review of the §11 draft against ONT-001 and against this spec's own conventions: - ONT-001's R-n/F-n/§n ids collided with this spec's T-5 predicates R-1..R-5. Upstream ids are now written `ONT R-n` / `ONT F-n` / `ONT §n` throughout §11. - The draft said paiml#3179 round 1 was "a 2/3 majority over lattice-invalid verdicts". It was not: the verdicts were well-formed, the PREMISE was false (a launched kernel entry point that does not exist in the tree). Corrected to what the ontology actually does about it — `resolves: symbol` on the premise returns Unknown{…} at extraction, before any lane votes. - `contracts/lint-baseline.json` and `make ont-ratchet` do not exist in aprender yet; §11.0 and §11.2 now say so instead of naming them as if present. - A "sweep PR" is now a file predicate (night.yml, docs/specifications/**, the CLI registry, README.md, CLAUDE.md, any known-red list) so FR-1 can be a `check_pr_closes_issue.sh`-class PR-body check rather than a reading. paiml#3268 itself is one and carries `ont-delta: none`. - The four stop conditions live in §8 and the two report lines in §7, once; §11.5/§11.6 point there instead of duplicating them. `ontology:` gains `deltas <n>/<sweep PRs>` so §11.1 is measurable at T-5. - ONT §0.2's push constraint (never while a release-titled run is in progress) is named as §3's one-PR rule seen from the other repo. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(spec): final review — the amendments contradicted the original text in seven places Read start to finish. Every finding is a place where a dated amendment (§3.4 merge-queue parallelism, §3.5 SSH, §6.1 continuous triage, paiml#3205 mini, the one-subagent rule) was landed beside original text that still said the opposite, so a reader could cite either. - §1 measured the fleet with `gh api …/actions/runners` — the call the operator rejected, a `busy` snapshot that cannot see ephemeral runners, and the hourly average that read 9.5 % while 15/16 workers were busy. Now the fleet-pack ledger record, instantaneous busy/online, both traps named. - §1 said "one PR in CI at a time means gate latency IS throughput"; §3.4 was amended to 3-parallel on 2026-09-12. Bound is now 3 × 72 h / p95. - `mini` is a declared full-time build host (paiml#3205) and appeared only in a §8 bullet. Added to §0 row 0, §1, §5 P0·Pack fields and Done, §7 pack:, §8. - §0 row 3 still scheduled triage once per train; §6.1 made it per-wakeup. - §2 named the required check `ci / gate`; the rules API says `gate` and `workspace-test`, and `present` is not required. - §3.4 allowed "≤ 3 read-only subagents" against the one-at-a-time rule and §10's fan-out-through-agy. - §8's last bullet stopped on "a second concurrent aprender PR in CI" and on "SSH into a host" — both allowed by the amended §3.4/§3.5. Now stops on a host CONFIG change over SSH instead of forjar. - §9 asked for the 0.67 cascade wall to be measured; it was: 70 min, attended 0. That is 3.5× the [A] line, so by §9's own rule the cascade is the next kaizen target; where the minutes go is [U]. - §7 train: line said T-0..T-4; T-5 exists. §6's tail paragraph gets a §6.4 heading. §11.3 cited the one-PR rule §3.4 no longer has; fixed. - `make build-report` does not exist on main (P0·Instrument not done) — said so where p95 is marked [U]. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(spec): §12 — the chain of reasoning: why the loop never terminates and the four things it moves The spec had eleven sections of mechanism and no argument. §12 is the argument, step by step, each with its mechanism and its falsifier: §12.1 why it runs forever — the selector is total (row 4 always matches), a stop stops the session never the loop (every §8 line names the mechanism that prevents its recurrence), every counter is a ratchet, no number is a guess and a guess that becomes measurable is replaced (§9's 70-min cascade is the worked example), the ledger is the memory, the clock cuts the train. §12.2 the four axes — the repo, the released binaries, the CRUX competitors, the fleet — on the pv/ontology substrate. Each with its dated position, its mechanism, its ratchet and its §7 line. The spec had NO competitor axis before this: the train shipped binaries and nothing in it said where they stand. CRUX monitors 9 competitors through 275 stories (✅39 🔨80 ❌156 at v2.2 intake [C]; FALSIFY-CRUX-010 declared, not found under crates/ or scripts/ on main — [U] until landed). BEATS has 16 contracts; Ollama GPU decode is PARITY with a 0.90 floor, llama.cpp c=1 a narrow loss, fail-closed WON. Approaching = ❌→🔨→✅ by demand tier, which §6.3 already schedules; surpassing = a beat threshold that is a floor first and moves above 1.0 only on three agreeing medians on the PUBLISHED binary — which is why the post-publish dogfood (paiml#3202) precedes any ratio. Hooks: `beats:` line in §7, a §8 stop on a beat RED on the published binary or a `measured-on published` claim from a dev build, a §0 pointer. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(spec): §11 — infra main tracks ONT-001 v3.1; it is v4.3 that is untracked The previous wording said the upstream spec was untracked with "no commit, no history". Measured against origin/main in a fresh worktree: main has v3.1 (414 lines, f1269d0, infra#570). The untracked file is v4.3 (972 lines, sha256 512a16d5…), the version §11 is measured against. Substance unchanged — no other host can fetch v4.3 — detail corrected in §11.0 and §8. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(spec): §4.3 — the check is `deep`, and T-1 cannot be satisfied by the lane merely EXISTING This spec named `ci / deep` in five places. No such check can exist in this repo, so T-1's already-done test was reading for a string that would never appear. GitHub prefixes a check with the job that CALLS it. `ci.yml` calls the org-wide `sovereign-ci.yml` as a job named `ci`, which is why this repo reports `ci / lint`, `ci / test`, `ci / gate` — and why `workspace-test`, `guard-tree`, `guard-cargo` and `gate`, which are top-level jobs in a workflow file, appear bare. Measured on this PR's own check list, both halves. `ci / deep` would therefore require a `deep` job inside the ORG-WIDE reusable workflow, with blast radius across every consuming repo. paiml#3260's lane is `.github/workflows/deep.yml` with a job named `deep`, emitting `deep`. Amending this document is the cheap half of that trade; amending an org-wide workflow to match a string this document happened to write is the expensive half. §4.3 also records the sequencing hazard, which is the part that would have cost a train: $ gh workflow run deep.yml --ref PMAT-1098-ci-deep-lane HTTP 404: workflow deep.yml not found on the default branch `workflow_dispatch` is honoured only on the default branch, and a deep lane deliberately has no `pull_request` trigger. So the lane cannot be exercised AT ALL before it merges — its first execution would be the cut it gates — and §4 turns a red step into SKIPPED, so a lane born red costs the train silently instead of failing loudly. T-1 is consequently not satisfied by `deep` existing. The already-done test is a green `deep` run recorded against a sha ON MAIN, and the first such run must be a deliberate `gh workflow run deep.yml --ref main` after the lane lands and before a cut is attempted. A gate whose first run is the thing it certifies is the defect class this document exists to remove. spec_conformance.sh: exit 0. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(ont): §11.1 gets a caller — "absent is a PR-body lint failure" was itself only a review comment §11.1 states: "Every sweep PR body carries one line ... Absent is a PR-body lint failure, not a review comment." $ grep -rl ont-delta scripts/ .github/ Makefile (nothing) The rule shipped as prose in paiml#3268 and nothing read it. A rule whose enforcement is "not a review comment", enforced only by review comment, is this repo's anti-theater class one level up from the guard it now sits beside in ci.yml. WHAT A SWEEP PR IS — and only half of it may be a list. * the prose sinks §11.1 NAMES are constants here, quoted, and printed on every run so drift between spec and guard is visible instead of silent. * "a known-red list anywhere" is DERIVED: the union of a working-tree `find` and the index, the same rule check_baseline_ratchets.sh uses and for the same two reasons — a new baseline arriving unclassified is how the class survives, and a tracked-only universe is a free pass for a file present but not yet added. The derived half is what makes it non-trivial, measured on real PRs: paiml#3268 sweep via prose sink docs/specifications/... PASS (carries none+reason) paiml#3277 sweep via KNOWN-RED LIST scripts/cb200_baseline.txt FAIL -> now fixed paiml#3278 not a sweep PASS paiml#3245 not a sweep PASS paiml#3277 touches no prose sink at all. A hand-typed sink list would have passed it, and it is a true positive: that PR withdraws a wrong FAIL and adds an ONT-6 Unknown reason, which is precisely §11.1 form 3. Its body now carries `ont-delta: reason ont6-unread-window`. Case table, 15 rows, and it DISCRIMINATES: deleting the vocabulary check turns the table red (verified by mutation, not by reading). Rows cover kind-outside-the- vocabulary, none-without-a-reason, id-absent, case, leading space, and empty body. Vacuity floor: an empty changed-file list exits 2, because "not a sweep PR" is a verdict this guard could not have reached. Two defects found writing it, both kept as comments: * a RETURN trap runs after bash destroys the function's locals, so `rm -rf "$tmp"` died on an unbound variable AFTER fifteen green rows — a self-test that passed and exited 1. * bashrs SEC011: an unvalidated `rm -rf "$var"` is a delete-anything primitive. Now shape-checked before the sweep. bashrs 7.4.1: 0 errors. WORKFLOW CHANGE, stated rather than buried: this adds one step to ci.yml. §11.1 cannot exist without a caller, and guard_tree.sh runs check_*.sh BARE — which would run only the self-test, fifteen green rows judging no PR body, the exact failure the neighbouring step's comment documents. ont-delta: resolves scripts/check_pr_ont_delta.sh — §11.1 was a prose claim; this turns it into a checkable one (form 4). Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(ci): the §6 R-2 PR-body gate is dark on every PR — Actions steps are fail-fast and one red guard skipped 48 of 59 Measured on run 34875945193 (PR paiml#3268), job `guard-tree`: total steps 59 ran 10 skipped after the step-8 failure 48 step 8 failure Every cargo-free guard runs, and every failure is reported step 55 skipped A PR body must close every issue it cites (§6 R-2) step 56 skipped A sweep PR closes with an ontology delta (§11.1) GitHub Actions steps are fail-fast: one red step darkens every step after it. Why this is worse than a missed run. check_pr_closes_issue.sh exists because the 0.67.0 T-5 reconcile found 48 merged PRs since the previous tag of which only NINE closed anything. Its own wiring comment, four lines above this change, records that running it bare executes only its self-test — "Nine green rows about a regex, on every PR, judging NO PR body" — and that a real caller was the remedy. It got a real caller. The caller is masked. On any PR where one cargo-free guard is red the guard is dark exactly as it was before it was wired, and step 8 is currently red on EVERY PR (the pin/advisory deadlock, paiml#3277), so §6 R-2 has been dark fleet-wide for the duration. `!cancelled()` rather than a bare event check: a step whose `if:` contains no status function is still skipped on a prior failure. These two read `github.event.pull_request.body` and nothing else, so no guard result can be their precondition — which is what makes this the narrow, defensible half of the fix. The other 46 skipped steps are mostly CASE TABLES — the mutation-verification proving the neighbouring guards can still go red. A case table that does not run is the theater this repo keeps deleting. They are NOT swept here: some (`target-watch:` markers) plausibly do depend on ordering, and a blanket always() over 48 steps would be its own kind of wrong. paiml#3282 carries the classification. Stated rather than buried: unmasking means these steps now report on PRs that are already red for another reason, so the first sweep will surface findings that have been invisible for as long as the masking has. Same class as nextest --fail-fast hiding four dark failures across seven rounds; that lesson said "sweep the CI selection" and nothing had swept the STEP surface. ont-delta: none — a CI wiring fix; this PR's delta is already recorded against scripts/check_pr_ont_delta.sh. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 15, 2026
… landed on main after this branch was cut check_roadmap_fragment_required.sh (main since 11:38Z) rejects a roadmap.yaml entry added with no docs/roadmaps/entries/<ID>.yaml; this PR sat at merge-queue position 1 and would have ejected every entry batched behind it. Adopted via scripts/lib/roadmap_fragments.py adopt PMAT-3231; roadmap.yaml regenerated, not hand-edited. Pmat-Ticket: PMAT-3231 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Sep 16, 2026
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…ad (#3292) #3278 was armed on 2026-09-16 while its guard-tree was RED. The merge queue took it, put it at POSITION 1, and when it failed there it ejected the batch queued behind it. An arming decision is not local: a PR armed on a red guard costs every PR behind it a rebuild, and the queue is deepest exactly when that hurts most. THE STALE-CHECK TRAP IS THE WHOLE POINT. "guard-tree is green on this PR" is a claim about a SHA, not about a PR, and every name-keyed surface (`gh pr checks`, `statusCheckRollup`) will show a success from two pushes ago next to the newer head. So the head sha is read FIRST, the checks come from repos/{owner}/{repo}/commits/<that sha>/check-runs -- an endpoint that cannot answer about another commit -- and every row is filtered on `head_sha == <that sha>` again anyway. A success that exists only on an older sha is the named state `stale`, not a silent `absent`: the two want different fixes. ABSENT IS A REFUSAL. No row, no failure, arm -- that is the fail-open shape this repo keeps shipping. Here it exits 3, as do in_progress, queued, skipped, and a re-run in flight beside an earlier success on the same sha. WHY NOT pr_review_quorum_arm.sh. It was searched for first and it IS an arming path, but it evaluates S13's review-quorum predicate and refuses with Q1 when there is no signed review receipt, so it cannot be the general arming entry point; and it reads statusCheckRollup, the surface this trap lives in. The two compose -- a quorum PERMIT still has to clear this precondition. 12 rows, 0 red, fixtures only, with A1 as the positive control (without it a function that always refuses satisfies every other row). Verified live in all three polarities against open PRs, --dry-run: #3366 refuse: guard-tree is failure on 179c69b... exit 3 #3361 refuse: guard-tree is in_progress on 062e471... exit 3 #3363 WOULD-ARM on e5cf234... exit 0 #99999999 (no such PR) exit 2 bashrs: 0 errors. Pmat-Ticket: PMAT-3292 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
noahgift
added a commit
that referenced
this pull request
Sep 16, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
noahgift
added a commit
that referenced
this pull request
Sep 17, 2026
…r run, apex-ca claims Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Standing operator rule: tickets, PRs and branches that are not triaged are P0.
git ls-remote --heads origin= 112 branches; branches with no PR in any state = 35,and none had ever been classified.
The obvious measure is wrong by construction
git rev-list --count origin/main..origin/<b>says 30 of the 35 carry unique commits. Thisrepo squash-merges from a merge queue, so a branch whose content landed still shows every
original commit as unique. What decides is path residue: of the paths a branch changes
against its merge-base, how many do not exist on
mainat all.The prrev stack, and the correction that is the point
Twelve branches from 2026-08-30 looked like they had dropped a discriminating test row:
tests/fixtures/pr-review/row-07-honest-docs-only-all-not-triggered/is absent frommain.It had not. Every residue in that stack is a rename or a renumber:
Counted by rows rather than by directory name:
mainhas 113 fixture rows(43
row-*+ 70q-*) against the stack's 24. The PR-review subsystem shipped by anotherroute with 4.7× the coverage the stack ever had.
So: residue bounds the question, it does not answer it.
PMAT-1094is the other workedexample — 8 absent paths, 7 of them throwaway
fix_derives*.py/fix_dry*.pyscratch scriptsthat were never meant to land.
Two REVIEW rows matter to APR-RELEASE-001
agent/R-5holds.github/workflows/release-assets.ymlandcontracts/apr-publish-cascade-v1.yaml— neither exists onmain, and both are §4T-3/T-4 surface.
prior-art/2803holdscrates/apr-cli/src/compute_latch.rsandcrates/aprender-serve/src/infer/compute_resolution.rs— the--gpu is ignoredadoptionkiller.
Scope
No branch is deleted here.
kind:triageis classify-and-link only: this diff touchesdocs/audits/**anddocs/roadmaps/roadmap.yaml, nothing else. The DELETE set of 24 is safeto execute except
agent/G-10{c,-full}, which should wait for #3021 so the supersession is afact rather than a forecast.
status: inprogress, notcompleted—check_roadmap_completion_is_cited.shcaught thepremature claim, and the fix was the status rather than the citation, which is what that guard
exists to say.
no-close: a triage pass over branches; the 35 branches are not GitHub issues, and the REVIEW
rows are recorded in the audit for a later per-branch decision rather than closed here.
🤖 Generated with Claude Code