Conversation
…me question This repository's most expensive defects are all one shape: a rule written twice, drifting, with nothing comparing them. The boundary rule had three copies and only two knew `## Границы`, so seven bees were accused of straying. `can_start_another` has five. Five SR-00 rules were retyped into TypeScript and three disagreed in production. The rings audit found eleven more. Yesterday it cost 153 dispatches, and the sentence that hid it was a comment asserting the two functions could not disagree. A comment claiming two functions agree is a test that has not been written. This is that test: it does not read the comment and does not reason about the code, it runs both implementations over the rows the system actually holds. The precedent is already here - `t27-parity.mjs` does exactly this across languages, 460 cases against the deployed twin. This is the same instrument pointed at two functions in one file, which is where drift is cheapest to create and hardest to see. FIRST RUN, AND IT CORRECTED THE ROUND THAT MOTIVATED IT. 358 rows compared, 11 agree, 347 differ - and the divergence runs BOTH ways: A missed something B found on 196 rows, B missed something A found on 151. I had written that `missingVerdictSlots` was "the right answer the repository already had". It is not: 156 blocks carry no numbering at all and slot matching finds NOTHING covered on every one of them, so wiring it would have marked every criterion in 44% of the board unanswered. Corrected at the call site and on the PR. So divergence is reported with its DIRECTION. A bare "347 differ" invites picking a winner, and here neither side is the rule. AGREEMENT IS NOT CORRECTNESS - two implementations can be wrong together and this cannot see that, the same limit `rejudge` carries and states. What it rules out is the other case: a divergence sitting in the open behind a sentence saying it cannot happen. Three calibration cases, each proving the negative: a row neither side could answer is not agreement, an unreadable row accuses nobody, a one-way divergence must not claim both directions, and agreement is never reported as proof. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`tri agree` measures it; the box the operator reads is rendered by snapshot.mjs from its own list, so without this the number lived in a file nobody opens. The row does NOT fall to zero when one side is fixed. `unjudgedCriteria` and `missingVerdictSlots` will keep disagreeing on the 156 unnumbered blocks until one of them is deleted or wired properly - which is exactly the point. A rule implemented twice is a liability for as long as it exists, not only on the day it bites, and a metric that vanished on the fix would say the opposite. Read from the recorded reading rather than recomputed, the rule `provenCounts` already follows: the comparison asks production and takes about a minute, and snapshot runs on the tick path. An absent reading renders "not measured", never zero, and does not write the anchor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ns at once `tri agree` had one pair and one shape - two functions in one TypeScript file. A gate that only works on the case it was written for is not a gate. This adds the hardest shape available: one rule, three languages, three processes. "Which paths may this bee touch?" is answered in the loop's own JavaScript, in the deployed TypeScript, and in the SR-00 Swift ring. A FOURTH copy sits in `queen-brief-shape.ts`, whose comment justifies itself by saying the other TypeScript copy "is module-private" - that copy is exported now. The stated reason expired and nobody noticed, which is the argument for testing the claim rather than reading it. This rule has already cost real work: two copies knew `## Границы` and one did not, and seven bees were accused of straying outside a boundary they had honoured. The heading was added everywhere. Nothing was added that would notice the next divergence. THE ANSWER IS AGREEMENT, and that is worth reporting plainly. All three return identical path lists on all 521 issue bodies that carry a boundary section, and on 18 adversarial shapes besides - backticked paths followed by commas, nested brackets, tab-separated markers, markdown emphasis, two paths on one line. The Swift comment predicts that sequential stripping mishandles a backtick before a comma; it does not, because the TypeScript trailing class contains the backtick. So this pair is a regression guard rather than a find, and it says so. A MISSING COMPILER IS NOT AGREEMENT. With `swiftc` unavailable the run reports 521 rows unreadable, names the side that would not build, claims nothing, and exits 3 - not 0. A pair that compared zero rows no longer counts as a pair that ran, because "0 diverging rows" must never be able to mean "we could not look". The TypeScript side is EXTRACTED from the shipping ref rather than reimplemented. A reimplementation would be the fifth copy of this rule, in the file whose whole purpose is to complain about there being four. One build per script, shared by both boundary pairs: building the ring twice to answer two questions about the same rows could produce two different answers for one run, which is the confusion this tool exists to remove. Two calibration cases: every declared pair is runnable for its kind and no two share a name, and a side that could not be built classifies as unknown rather than agreement. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Second and third pairs: one rule, three languages, three processesA gate that only works on the case it was written for is not a gate. This adds the hardest shape available. "Which paths may this bee touch?" is answered in the loop's own JavaScript, in the deployed TypeScript, and in the SR-00 Swift ring. A fourth copy sits in This rule has already cost real work: two copies knew The answer is agreement, reported plainlyAll three return identical path lists on all 521 issue bodies with a boundary section, and on 18 adversarial shapes besides — backticked paths before commas, nested brackets, tab-separated markers, markdown emphasis, two paths on one line. The Swift comment predicts sequential stripping mishandles a backtick before a comma; it does not, because the TypeScript trailing class contains the backtick. So these are regression guards, not finds — and the output says so rather than letting a clean line read as a discovery. A missing compiler is not agreementWith A pair that compared zero rows no longer counts as a pair that ran — "0 diverging rows" must never be able to mean "we could not look". Notes
|
The operator's golden rule is that the bees work, and start again the moment they finish. Twenty instruments in this directory count issues, verdicts, briefs, branches and disagreements. Not one of them measured whether the swarm was WORKING, and it had been false for a long time: minutes with ZERO bees working : 356 of 721 (49%) minutes with every bee working : 268 (37%) median gap between bursts : 18.4 min against a 5-minute tick gaps under a minute : 1 of 18 WHY THE DASHBOARD COULD NOT SHOW IT. `bees running (of 4)` has been on the board for weeks. It is an INSTANT - one sample per iteration - of a quantity that turns out to be bimodal, and it read 4 as often as 0. A rate needs a window; an instant needs none, which is exactly why the instant is the one that gets measured. It also names what stopped the rounds, from the service log: 135 of 136 recent round failures were `GitHub returned 403`, and one was `deadlock detected` - the second of which nothing else in this repository has ever mentioned. IT RESTARTS NOTHING. Idleness has several causes - a failing round, an empty backlog, a full volume, a refused key - and the cure differs for each, so this names the cause and stops. Three calibration cases, and one of them caught a real defect in this file before it shipped: a twenty-minute window sampled inclusively holds twenty-ONE one-minute buckets, so a half-idle window measured 52%. The loop is `t < to` now. That is what those cases are for. The other two pin the parts that would otherwise flatter: overlapping bees are one burst so no gap is invented between them, and gaps longer than the tick are reported as "rounds are running and starting nothing" - a different fault from "rounds are rare", with a branch that refutes it when gaps are within cadence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
`make queen-core-sync` compares the eleven policy files that exist twice - the ring the app compiles and the copy the Docker build compiles for Linux - byte for byte. Its own comment states the stakes: "a policy that differs between them is two arbiters of the same rule." It appeared in no workflow, and one of the thirteen files had already drifted. Writing a check is the easy half. The half that decides whether it protects anything is whether something runs it without being reminded, and nothing in this repository was asking that question. Sixty-eight targets, eleven invoked by a workflow. A LIST OF FIFTY-SEVEN WOULD BE IGNORED BY WEEK TWO, correctly: most of them should be local. `make` builds an app, `run` launches it, `relaunch` needs a window server. So this asks two questions instead of one - does the name promise to refuse something, and could a runner execute it at all - and reports nine rather than fifty-seven. THE TOOL'S OWN OUTPUT CAUGHT A DEFECT IN IT before it shipped. `check` and `verify` appeared in the portable group, which is wrong: both have NO recipe at all - they are a list of other targets - and reading only the recipe found no `swiftc` to object to. Following prerequisites moves them where they belong, and it is why the count went from eleven to nine. Read your own report against two entries you already know the answer for. It reads the SHIPPING REF, not this checkout, which is hundreds of commits behind: a gate wired upstream would otherwise read as unwired here, an accusation produced entirely by standing in the wrong place. Three calibration cases: a target with no recipe inherits what its prerequisites reach, a cycle does not hang the audit, and a plain name is not reported as a gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two more misclassifications of the same family, both caught by reading the tool's output against targets whose answer I already knew: check-bypass came out portable. It is one line - `$(MAKE) check` - and following only prerequisites saw an empty recipe. Its own echo says 'never for CI', which is how it was caught: the tool disagreed with the target's description of itself. Sub-make calls are followed now. drift-guard came out portable and then ran for four minutes without finishing. It is `bash run_chat_sse_e2e.sh` with an env var, and the Swift compiler is inside the script. A scan of make recipes sees one layer; a script is the second. So there is a third answer now - opaque - rather than a guess. A gate that shells out is reported as unjudgeable from here, which is what it is. The portable list went 11 -> 9 -> 6 -> 3 as each layer was followed, and every step of that shrinking was a false accusation withdrawn. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A sub-make call reaches its target; a target that shells out to a script is opaque and names the script rather than guessing. Both cases fail against the version that shipped an hour ago. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The same question asked of npm scripts found the t27.ai dashboard: trios/apps/website carries a 194-check review-lifecycle contract that imports the real page module and pins the states against what the server publishes, and the string 'apps/website' appeared in NO workflow. MOST UNWIRED SCRIPTS ARE LEGITIMATELY UNWIRED, and that shaped the classes. A flat first pass listed nineteen and eighteen were fine: aggregates CI deliberately splits into per-group jobs, an alias for a wired script, a helper other scripts call, a mutating lint:fix, an interactive watch. Reported flat, the one row worth reading was buried. And the one it cannot decide, said out loud: a script whose WORK is wired under a different command. `lint` is `biome check` while CI runs `biome ci .` - the linting happens, the name never appears. Same shape as drift-guard, whose script the macOS job already runs. Named rather than silently dropped, because guessing either way has been wrong. test:* is deliberately outside the word list: including it buries the report, and that coverage already has a better guard in run-test-group.test.ts. Stated in the output so the count cannot imply completeness. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ately blind Six cases. Two of them assert not-a-gate for test:* - the word is outside the gate list on purpose - and the case that first claimed 'interactive' for test:watch was wrong, not the code. The classifier never sees a test:* script at all, and the audit says so in its own output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`make check` names its own gate suite in one line of prerequisites. Reading it corrected this file badly: of thirteen unwired gates the repository declares, ELEVEN were classified not-a-gate here, because they are named after their SUBJECT and not their function - t27-rings, type-floor, recipe-backticks, variant-fence, vendor-step, skill-frontmatter. t27-rings runs the 460-case parity between the generated ring and the policy binary, plus a Verilog simulation, and this file called it not a gate. The word list stays as the fallback for targets outside the suite, where nothing has declared anything. The report now prints the declaration first: 24 declared, 8 in a workflow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The defect class this repository keeps paying for
Every expensive failure here has been one rule written twice, drifting, with nothing comparing them:
## Границы, so seven bees were accused of strayingcan_start_anotherin fiveYesterday it cost 153 dispatches (#472). The thing that hid it was a comment asserting the two functions could not disagree.
A comment claiming two functions agree is a test that has not been written. This is that test. It does not read the comment and does not reason about the code — it runs both implementations over the rows the system actually holds.
The precedent is already in the tree:
t27-parity.mjsdoes exactly this across languages, 460 cases against the deployed twin. This is the same instrument pointed at two functions in one file, which is where drift is cheapest to create and hardest to see.The first run corrected the round that motivated it
In #472 I wrote that
missingVerdictSlotswas "the right answer the repository already had." It is not. 156 blocks carry no numbering at all, and slot matching finds nothing covered on every one of those 156 — wiring it would have marked every criterion in 44% of the board unanswered. Corrected at the call site and on that PR.That is why divergence is reported with its direction. A bare "347 differ" invites picking a winner, and here neither side is the rule.
What it does not claim
Agreement is not correctness. Two implementations can be wrong together and this cannot see that — the same limit
rejudgecarries and states in its own output. What it rules out is the other case: a divergence sitting in the open behind a sentence saying it cannot happen.It runs the deployed module, never a copy. Copying the rule into this file would make it the third implementation — the defect it was written to catch.
Calibration
Three cases, each proving a negative:
skipped, not agreement — counting it as agreement is how a gate reports health for rows it never looked atnode .trinity/loop/selftest.mjs— 260 passed, 0 failed. Report-only, in the heal chain, exit 2 on divergence.🤖 Generated with Claude Code