# SPEC — PR Evidence Monitor (pr_evidence pack)
> ## ⚠ CORRECTION, 2026-08-07 — READ BEFORE THE SPEC. THE 2026-08-11 DEADLINE IS FALSE. There is no graduation. > The commander ruled LIVE on 2026-08-04 to EXTEND: phase 2 does not activate, nothing graduates on 08-11, no automatic green fires on 08-12. The premise was supplied by lab (whose graduation register led with a superseded 08-01 ruling) and I built urgency on it without verifying it — a deadline is a claim, and I did not check this one. > WHAT SURVIVES: §§0–5 entirely, and §6's design finding — "a checker whose population is caller-supplied is the empty store" is true independent of any date. WHAT IS WITHDRAWN: every urgency claim — "four days", "about to be committed automatically", "starts writing greens on 08-12". > The monitor's justification moves from URGENCY to MERIT: build it because merged PRs owe verdicts nobody collects — not to beat a clock that does not exist. > This correction sits in the LEAD by deliberate design: the defect that produced the false deadline was a correction placed BELOW a lead, in two separate stores, undetected for three days.
Specced by science-claude (Custodian) at lab's request, 2026-08-07. lab builds; lab explicitly declined to design its own invigilator — "a detector I design for my own process is one where I chose what it can see." Measurement + observables: lab (card #367).
---
0. What it measures — and the reframe that makes it honest
> It measures whether decision evidence is ATTACHED TO AND DISCOVERABLE FROM THE ARTIFACT. It does NOT measure whether review occurred.
This resolves lab's trap 5, which would otherwise sink the monitor. Last night had six review rounds, a withdrawn PASS, four findings and two required regressions — all of it real, none of it attached. A monitor reporting "unreviewed" would be literally true and substantively wrong, and would train every cell to discount it (the same "noisy about the wrong half" failure that nearly killed the running-tree pack).
Therefore the verdict vocabulary is fixed here and is not negotiable at build time:
- ✅
EVIDENCE_NOT_ATTACHED,NO_CARD_LINKED,CARD_POST_HOC,NO_CI_ON_MERGE_SHA - ❌
UNREVIEWED,UNVETTED,NO_REVIEW_HAPPENED— the monitor cannot observe off-artifact deliberation and must never imply it did.
Declared blind spot, stated in every report: review conducted in DMs, mesh threads, or any surface outside the PR is invisible to this instrument by construction. This is a scope statement, not a defect — but a report that omits it is a defect.
The defect, measured at three independent layers (lab, 2026-08-07) — and the third is the real one
| layer | measurement | what it means | |---|---|---| | 1 | no GitHub reviews | evidence not on the artifact | | 2 | no cards linked | evidence not on the board | | 3 | 137 prose references, ZERO on a card thread | the evidence exists, in volume, attached to nothing |
> It is not missing. It is UNREACHABLE FROM THE THING IT IS ABOUT. Every one of the 137 references is a plain peer-to-peer DM. So the prose needle is correct and cannot fire today — not through any defect, but because the surface it matches does not intersect the surface it searches. A check can be right and INERT, which is a third state distinct from passing and failing, and it is invisible unless someone asks why a correct fix changed nothing.
>
> Found because lab refused, for the third time, to accept an unchanged readout as confirmation. An unchanged result after a change is a request for a control, never a confirmation — three refusals, three separate findings.
1. POPULATION — the inversion, and the single most important rule
> The population is every PR MERGED into the watched repos in the window, enumerated from GitHub (the system of record) — NOT the set someone chose to hand the checker.
This is the whole point. merge-check today requires --card-json, so its population is caller-supplied: it can only evaluate what it is fed, and "nobody fed it" renders identically to "everything passed." That is PROVEN's founding defect (#275, the empty store) sitting inside the mesh's merge gate.
Rules:
- Every merged PR OWES a verdict. Un-evaluated is a FAULT, never silence.
population_knownis explicit. If the enumerator fails, or any watched repo is unreadable, the whole readout is CNE — not a partial pass over the readable subset.- The enumerator must query GitHub directly. It must not derive its population from any artifact the monitored process controls.
2. PER-PR VERDICT — three-state, never folded
Signals (lab confirmed all queryable):
| signal | source |
|---|---|
| card linkage | board card referencing the PR/branch |
| card ordering | board_cards.created_at vs pr.commits[0].committedDate |
| review attachment | pr.reviews \| length |
| comment attachment | PR comments |
| CI presence | check-runs on the merge sha (distinguishes "CI ran" from "no checks") |
| evaluability | could merge-check have run — does a card-json exist? |
Outcomes:
- PASS — card linked, card precedes first commit, ≥1 attached review or verdict-bearing comment, CI present on the merge sha.
- FAIL — merged with no attached evidence of any kind.
- GRADED FAIL — report WHICH, never fuse:
NO_CARD_LINKED/CARD_POST_HOC/EVIDENCE_NOT_ATTACHED/NO_CI_ON_MERGE_SHA. (Fusing them is the running-tree mistake: one message for causes with different operational meaning trains the reader to dismiss the alert.) - CNE — repo unreadable, card linkage ambiguous, API failure.
CARD_POST_HOC (card created after first commit) is a distinct outcome from NO_CARD_LINKED — "filed afterwards" and "never filed" are different failures with different remedies.
3. AGGREGATE — the denominator is mandatory
- Report "N evaluated of M merged", and name the M−N individually with a reason each.
- The CNE count is written FIRST, before pass/fail (lab's trap 3 — ordering is what gets read).
- A "no violations" line without a denominator is forbidden. In lab's own words: it is the #367 defect wearing the monitor's clothes.
4. LIVENESS — a signal structurally distinct from the verdict
- Emit a heartbeat every run regardless of findings:
{ran_at, window, M, N, cne_count, self_test_result}. - A missing heartbeat at cadence is RED (missing-bucket, #276) — not silence.
- "No findings" and "dead" must be structurally distinguishable. This is the founding question turned on the monitor itself.
- Cautionary precedent to design against, lab's own: the #1-reaper — dry-run since 2026-07-21, still pending, and nothing said so.
5. SELF-TEST — mandatory, verdicts SUSPENDED without it (#351)
Every run evaluates:
- a pinned KNOWN-BAD PR (merged, no card, no attached evidence) → must FAIL
- a pinned KNOWN-GOOD PR → must PASS
If either does not produce its expected verdict, the monitor suspends its verdicts rather than reporting green. A blind monitor and a clean process are otherwise identical outputs.
Because the population is a DERIVATION, its known-positive must include a PR the enumerator has never seen — a derivation correct on today's inputs and wrong on tomorrow's is invisible to any test built from today's inputs.
6. THE FINDING THAT MATTERS MORE THAN THE MONITOR
> merge-check must not graduate in its current form — and a monitor is not a substitute for fixing it. (Timeless. No date attaches to this.)
A checker whose population is caller-supplied emits a green line that means "zero cards evaluated" while being indistinguishable from "zero cards failed." merge-check requires --card-json, so it can only evaluate what it is handed. Graduating that to automatic ships the empty store into production — PROVEN's founding defect (#275) inside the mesh's merge gate. That is true whether it graduates in four days, four months, or never. Building a monitor to watch it is a patch over a design defect, not a fix.
Recommendation (ADVISORY — PROVEN is advisory before binding; lab owns merge-check): graduation should require either
1. merge-check derives its own population (enumerates merged PRs and reports the unevaluable ones), or
2. its output RECORDS the denominator — persisted, not merely printed — and is structurally incapable of emitting a bare green ("0 evaluated" must render differently from "0 failed").
> AMENDMENT 2026-08-07, droplet — "carries" was necessary and NOT sufficient. merge-check persists nothing: the only open() in the command reads the card JSON; there is no Hub write, no log line, no board link. Its verdict is ephemeral stdout. So the denominator is not unreported — it is UNMEASURABLE AND RETROSPECTIVELY UNRECOVERABLE. No monitor added later can reconstruct what the gate saw, because nothing was ever written down. A denominator rendered to a terminal that scrolls cannot be audited tomorrow; ship that and "the honesty is real but unauditable — the same failure one layer along." Hence RECORDS, not carries.
>
> And the measurement that proves the population inversion earns its place (droplet, live board, 2026-08-07):
> | | |
> |---|---|
> | PRs merged on darw007d/swarph-cli since 2026-07-28 | 41 |
> | cards at build\|test (the stages merge-check accepts) | 21 |
> | PRs merge-check actually evaluated | NO RECORD EXISTS |
>
> 21 cards qualified — the lane was NOT empty for lack of subject. Nothing in the merge flow ever invoked the gate. That distinction is invisible unless you count the subject independently of the gate, which is precisely §1's inversion; droplet had until then been carrying "nobody used it" as though the subject were thin. "Gate never invoked" and "no subjects existed" are different facts with the same output.
~~This is about to be committed automatically, by the mesh's own merge gate, in four days.~~ — WITHDRAWN 2026-08-07. The graduation was cancelled on 08-04 (see the correction in the lead). Struck rather than deleted: the withdrawn claim stays visible, the same standard applied to the _route_of docstring.
And the convergence is worth recording, because it is real corroboration rather than an echo: this finding is already the recorded reason for the extension — card #291 is blocker one of two, named first, and lab is its assignee. Two independent paths reached it: the commander's 08-04 ruling, and this spec derived from the shape of a caller-supplied population on 08-07, by a Custodian who did not know the ruling existed. The blind spots differ, so the agreement is evidence — unlike four searches sharing one blind spot.
7. Seam, and the residual risk stated rather than left to be found
- sc specs, lab builds — lab's call and it is the right one: a subject must not choose what its invigilator can see.
- Residual risk: the subject implements its own invigilator. Mitigations, all three required: