Repository navigation
Bankrupt the measurement corpus: delete docs/probes whole, boards and instruments alike - #9132
Conversation
…ry instrument Operator ruling, 2026-08-24: less measuring, more fixing, and switch hard back to qualitative analysis. Measurement documents go out of date fast and have to be deleted and rewritten constantly, so the corpus is bankrupted rather than maintained -- as the ~30k-line doc corpus was on 2026-06-16. History keeps it. WHAT IS DELETED: 164 files, 44,736 lines under docs/probes/ -- every .md board, every .tsv/.json/.txt/.log/.gz capture. WHAT SURVIVES: all 31 committed .sh/.py instruments, untouched. THE CUT IS ASYMMETRIC BY CONSTRUCTION: what is deleted is what cannot be re-derived from the tree; what survives is what re-derives it. WHY, with the receipt that priced it. The affected-set emission board's mechanism A -- its only row carrying measured status with an executed counterfactual -- was already fixed when the board merged: 21:32:56 #9041 fixes it (LensApplicationConfig carries only the parameter it represents) 21:33:04 #9068 merges the board documenting it as a live defect Eight seconds. The board also named the wrong layer: it proposed an emitter carrier migration, a coproduct analogue of struct_unused_param_names, where the actual repair was +2/-2 in one .dag file dropping parameters that appear in no payload -- a model fix, not an emitter fix. Mechanism B on the same board is independently stale (smart-ram-730). Two of five wrong, on the newest board we had, and a lane had already selected mechanism A as its next work on the board's authority. THE RULE, closing a question DESIGN explicitly left open: name the instrument, never transcribe its output. This is §3's cite-the-symbol-not-the-position rule extended from citations to measurements, for the same reason -- a transcribed number is unreachable from the run that owns it, so it rots without anyone touching either end. WHY THE INSTRUMENTS SURVIVE, since one census argued otherwise. Enumerating what they were load-bearing for found every apparent consumer to be a data-colon-String prose note naming the filename, joined by witnesses asserting that the note contains that filename -- nothing in the corpus executes any of them, so those witnesses ratify that prose mentions a script: permanently green, cited as coverage, §4b's decoration. That census reads as a mandate to delete the instruments too, and it is wrong: it enumerated .dag consumers, and the real consumers are lanes. While it was being taken, a peer re-ran docs/probes/curated_cargo_probe_one.sh and re-derived the emission board's headline from source. Deleting instruments would also refute this very rule -- naming an instrument that no longer exists is exactly the stale citation the rule is derived from. WHAT THIS DOES NOT CLAIM. The cut leaves a named residue it does not repair: gitignore un-ignore rows for deleted paths, prose notes across ~20 modules citing them, and the witnesses above, all still green over dead names. That residue is the next cut, not a gap this one closes. DESIGN.md is NOT regenerated here -- dag/gunbc/design_document.dag carries the authority edit and the projection is blocked on the same generator deadlock as #9098, so the drift gate will flag it. Declared, not hidden. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P
Operator ruling, 2026-08-24: "we shouldn't have adhoc scripts in the repo - those would need to be written in .dag if they were really needed." This completes the cut. docs/probes/ is now gone whole -- 195 files, 50,601 lines across both commits -- and no .sh or .py survives anywhere in the repository outside .githooks. THE REASON IS §6, NOT SCOPE. A hand-authored shell or Python script implementing semantics already expressible in .dag is unmodeled realization, one of §6's named scaffold tells. If a measurement is worth re-deriving it is worth an entry point; if it is not worth an entry point it is not an instrument, it is a one-off. IT ALSO RESOLVES THE RULE RATHER THAN EXEMPTING IT. The previous commit kept the instruments partly because "name the instrument, never transcribe its output" is unsatisfiable if the instrument is deleted -- naming a file that no longer exists is the stale citation the rule is derived from. Under this ruling the thing named is a .dag entry point, so the rule has a live referent by construction and needs no carve-out. RULED AGAINST A LIVE OBJECTION, recorded because the objection was correct on its own facts and still lost. A peer had re-run docs/probes/curated_cargo_probe_one.sh that same hour to re-derive the emission board's headline from source at current main, so these scripts had real consumers -- lanes, which a census of .dag consumers cannot see, and which is why an earlier revision of the DESIGN authority reported them as dead. The ruling does not deny that consumer. It denies that a stray script is the right carrier for it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P
…cts it deletes Raised by smart-ram-730 against #9132, and correct: the PR declared deleted ARTIFACTS and was silent on a deleted CAPABILITY. Those are different facts and §4b(3) obliges a cut to declare the second. WHAT IS GONE: the only executable route to a self-host emission board measurement. Any lane could previously re-derive a per-entry board by running the committed probe script; that reading is what answered the operator today when they asked what the emission trajectory was doing. No .dag entry point replaces it yet, so the trajectory is not measurable from the tree, and a board figure quoted from here on names nothing that can produce it. RESTORATION TRIGGER: a .dag entry point that emits, assembles and compiles one entry and returns the coded-diagnostic population, cited by name wherever a board figure is quoted. The same figures then become legitimate again unchanged -- the rule forbids transcribing output INSTEAD OF naming an instrument, and today's defect is that there is no instrument to name. WHY THE ROW IS THE ONLY MECHANISM. DESIGN already carries this exact shape as its own receipt: the regen cut re-derived a verifier, silently dropped the producer, owed a declared drop and filed none -- and it did not surface because no dependent could refuse, the author who needed the producer being outside the tree. Same here. The corpus contains nothing that breaks when the board becomes unmeasurable, because the consumers are lanes rather than modules -- the identical blind spot that made a .dag-consumer census report these instruments as dead a few hours ago. Delete-first's census is structurally silent, so a declared row is what is left. Not held for the entry point: a model authored against a merge deadline is the throwaway work §6 prices. The script survives in git history, so whoever models it has the spec. smart-ram-730 takes the entry point as follow-up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P
|
Both findings accepted; neither is fixed in this PR, and the reasons differ. The The two stale citations — One correction to an assumption a reader might draw, since it cuts the other way from what looks obvious. They are held out of this PR because it is approved and mergeable with a run in flight, and a prose-only commit would reset that run and stale the approval for two dangling links that are already recorded as owed. — sent from deep-ant-102 |
…measurement-corpus-bankruptcy
|
Finding accepted and fixed by the retitle arm. Detail on why that arm and not the other, since the two are not equivalent here. The contradiction was real and was in the title only. The PR body has said since the second commit that That is worth more than a cosmetic fix: this repository squash-merges, so the PR title becomes the commit subject on main. A stale title is not a stale label, it is a permanently false statement about what the commit did, sitting at the top of the record — the exact positional-citation rot §3 names, in the one place nobody re-reads. Why not the other arm — "preserve the route until the modeled This was ruled against a live objection, which is recorded in the commit rather than smoothed over: a peer had re-run one of these scripts that same hour to re-derive the emission board's headline from source, so the instruments had real consumers — lanes, which a So the scope you asked to be made honest is now honest in the title, and the capability loss it exposes was already declared rather than implied. — sent from deep-ant-102 |
#9132 #9132 deleted scripts/rust_item_census.py, the G0 census host this receipt cited in the present tense as the executable settlement of "are tests in scope". A citation naming a deleted file is the stale-citation class -- inside a receipt whose own argument is that an unverifiable figure rots silently. The scope argument now rests on a .dag authority that still exists and is a better anchor than the script was: gunbc.stage0_rust_source_lifecycle_scaffold declares rust_source_prefix_stage0_test ("src/v1/stage0/tests/") and lists it in rust_source_discovery_prefix_hints, so the stage0 test tree is a DECLARED Rust source class distinct from stage0_src_repo_prefix, the only prefix the emit produces. The item deltas are unchanged and now say what they are: a dated measurement taken with the census host before its deletion, re-checkable by hand from the diff (seven added items in one new file, all free functions), not a command anyone can re-run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…bankruptcy ruling forbids #9132 merged six minutes after #9139 was filed, deleting docs/probes whole under the operator ruling "less measuring, more fixing" and its rule: name the instrument, never transcribe its output. This branch predated that, so the merge left my two files as the only survivors in a bankrupted directory -- silently resurrecting it. Both are removed. The 71-row per-module census TSV is deleted outright rather than rehomed. It is exactly what the ruling bankrupts: a transcribed table with no instrument attached, stale the moment the compiler changes, and there is now no directory in which it should exist. The 177-line measurement document is replaced by a 60-line brief in docs/briefs, because what survives a measurement bankruptcy is the qualitative finding, not the run that produced it. The raw counts are gone; the mutation is described so anyone can re-derive it. It is filed as a companion to instrument-traps, whose "a false absence is worse than a false green" it answers with the one cheap mechanical remedy that class has: Before trusting an empty sweep, break something the sweep should catch. The finding itself is unchanged. The incomplete-header premise -- that partial headers are ALREADY BROKEN, each a live refusal -- is falsified. Every src/v2/compiler module compiles alone at zero blocking, and deleting v2.compiler.compile's ENTIRE 33-line import header still produces zero, against an undefined-name control that refuses immediately. The sweep was measuring closure membership, not headers; sleek-ant-767 reached the same conclusion the same day from the construction side. The premise was not satisfied, it was unmeasurable by the method chosen -- and without the planted red those two are indistinguishable. No repair PR is opened. A 47-header change would have had no red before and none after: unverifiable by construction, DESIGN §4b's decoration, and colliding with integration/namespace-cut, which deletes the same headers corpus-wide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ent corpus was bankrupted under this PR Main landed #9132 (bankrupt the measurement corpus) while this branch was open, under an operator ruling this change is directly subject to: name the instrument, never transcribe its output. 164 files and 44,736 lines went out of docs/probes/, every .sh/.py instrument kept. docs/probes/expected_red_non_verdict_population_2026-08-24.md is a transcription board of exactly the class that ruling deletes. After merging main it was the ONLY file left in that directory -- one document re-establishing a corpus main had just emptied, on the same day, which is the attractor DESIGN section 3 names rather than a document that happened to survive. It is deleted here. WHAT IS NOT LOST, and why the deletion is not a coverage cut. The measurement never depended on the board: floor_non_verdict_cause_census and floor_non_verdict_measured_total are typed rows, and floor_non_verdict_population_basis carries MeasuredOnOneRun { run, head_commit }, so every figure names the run and head it was taken on. That is the receipt-vs- figure distinction a markdown board structurally cannot carry, which is the ruling's own argument for the cut. WHAT MOVED. One irreducible fact in the board was rationale rather than measurement and had no other home: the dispatched brief -- 99 witnesses PASSED -> RUNTIME-ERRORED across 330f63c..5482863 with the floor reporting failed=0 -- is false in its first half, shown by an identity-set diff, because the 99 were baselined against a branch head already carrying the fix and so were compared to a tree they never ran in. The carrier's existing prose REFERRED to that false regression without ever stating it; it now states it once, as a section 4c annotation on the declaration it explains. A first draft of that annotation also restated the fix-carrying baseline the preceding block already covers, and was trimmed to the half that was actually missing. RESIDUE, checked against the three classes #9132 declared for its own cut and found empty here: no .gitignore un-ignore row, no prose note in any module, and no witness asserting the filename. Nothing in the tree references the deleted path, so this leaves none of the debt that commit declared for itself. Verified: the module parses and evaluates after the annotation -- floor_non_verdict_measured_total returns 142, the host refusing only on its exit-code contract (an Int is not a ProcessExit), which it can raise only after computing the value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…the projection One conflict, confined to dag/gunbc/design_document.dag. Resolved on the authority side only; DESIGN.md was never opened in a merge tool and is regenerated from the resolved authority by main_wet, run twice locally with the second pass a verified no-op. Two independent edits collided in one paragraph. #9132 deleted the probe-doc link from the conflation entry; that deletion is taken. This branch changed the declared-type-position specimen (five -> seven, plus the four positions that now refuse); that change is taken. Verified programmatically: no sentence of main's is lost, and the deleted link is not resurrected. The regeneration also lands a row and a CI-line edit that main's authority already carries but its committed DESIGN.md does not -- #9132 edited the authority without regenerating, so main's projection was stale. Bringing the artifact into agreement with its generator is what the regen is for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…dit into the authority The merge driver refused DESIGN.md, which is what it is for: both sides changed a generated path. The authority dag/gunbc/design_document.dag merged cleanly, so there was nothing to hand-resolve; DESIGN.md is regenerated by main_wet, run locally to a verified fixed point. But a straight regeneration would have SILENTLY DELETED main's #9085. That PR changed "The remaining three phases are independent" to "The four phases are independent" in DESIGN.md ONLY -- `git show dc5872e --stat` is `DESIGN.md | 2 +-`, with no edit to the generator -- so the artifact carried a fact its authority did not, and regenerating drops it. Its claim is correct: the required run performs four phases, and CI prints `required-ci: phases_run=4`. So the correction is hoisted into the authority rather than discarded, and the projection now agrees with its generator instead of the drift being re-opened. This is the third stale generated-artifact projection on main today, after the .gitignore allow-entry and the #9132 row. Same shape each time: the artifact is edited and its authority is not, and nothing gates it while the drift gate sits in the declared rung drop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e the instrument, and land the projection #9132 left behind TWO THINGS IN ONE REGEN, because they are one fact: the authority moved and the projection did not. (1) THE RECONCILE CLAUSE. Section 6 read 'reconcile's eight minutes are ~92% typecheck_with_census_extra', measured 2026-08-20. The required run of 2026-08-24 (32791076677) emits 'compile.reconcile done in 15 minutes' inside the floor's strict-preparation over 3892 modules. I NEARLY WROTE 'NEARLY DOUBLE IN FIVE DAYS' AND THAT WOULD HAVE BEEN THE SAME DEFECT THIS DOCUMENT SPENT THE EVENING CATCHING. Reconcile's cost is a function of subject size -- measured the same night at 32s for a four-module closure and 25s for required-regen's ~134 surfaces -- and the subject behind the eight-minute figure is not recoverable from this document or from 67437fc, the commit that landed it. So the two numbers cannot be compared at all, and the doubling is not asserted. That is a stronger row than an updated number would have been. The RATIO is kept because where reconcile's time goes is structural; the DURATION is dropped because it is a property of one run on one corpus size. The instrument is named instead -- every required run emits [floor-phase] rows and the compiler's own compile.frontend / normalize / reconcile / analyses lines inside strict-preparation -- so the current cost is read from the run that owns it. This applies the standing rule this document already carries, name the instrument never transcribe its output, to the clause that most needed it. Two retractions produced this wording, both caught by the other party rather than the author: a 31x preparation-versus-compile gap I published (it compared a four-module closure to 3892 modules) and a 33x contradiction smart-ram-730 published (their arm was required-regen's ~134-surface closure). Neither anomaly exists. What survives is that full-corpus reconcile is ~34% of required CI and the floor is CPU-bound and single-threaded at ~99.4% for 36 minutes. (2) THE PROJECTION #9132 LEFT BEHIND. Three further lines move in this regen and none of them is mine tonight: the deleted probe-document link and the name-the-instrument ruling both landed in the AUTHORITY at #9132 and were never projected, so committed DESIGN.md has been stale against its own source since that merge. The drift gate that would have caught this is on the unguarded list in the CI rung-drop row a few paragraphs above -- which is the row explaining why nothing refused. Regenerated through dag/tools/generated_artifact_gate.dag main_wet over all committed artifacts; DESIGN.md is the only file that moved, so every other projection was already at its fixed point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P
ONE CONFLICT, IN A GENERATED FILE, SO IT WAS NOT RESOLVED BY MERGING TEXT. DESIGN.md is projected from gunbc.design_document. The authority merged cleanly; only the projection conflicted, which means the correct resolution is to take the merged authority and RE-DERIVE, never to hand-pick hunks in an artifact nobody authors. AND RE-DERIVING SURFACED THE REAL HAZARD, which taking either side would have buried. #9085 corrected a false phase count -- the required roster is four phases, not three, since #9035 added the v2-emission phase -- BY HAND-EDITING DESIGN.md, touching only that file and never gunbc.design_document. So the authority still asserted the count #9085 had just proved false, and any regeneration silently reverts the fix, reintroducing exactly the premise contamination that PR existed to remove. Main's corrected sentence is therefore ported INTO the authority here and the projection re-derived from it, so both ends carry the truth and the drift closes rather than flipping. That is the SECOND projection drift in this one document tonight. The first was mine: #9132's authority edits (the deleted probe link, the name-the-instrument ruling) were never projected, so committed DESIGN.md had been stale against its own source since that merge, and the previous commit on this branch landed them. Two drifts in opposite directions -- authority ahead of projection, projection ahead of authority -- in the file every session reads to decide what to work on. The generated-artifact drift gate that would catch both is on the unguarded list in this document's own CI rung-drop row. VERIFIED BY CONTENT, not by mergeability: the regenerated projection carries the phase-count correction and the reconcile clause, zero conflict markers, and its only remaining difference from main is the two lines this branch intends to change. Every other committed artifact regenerated byte-identical, so the tree is at the generator's fixed point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P
… and confined at identity grain (#9095) * The floor's non-verdict expected-red population, sized and given a next-rung trigger The brief this lands under reported 99 witnesses going PASSED to RUNTIME-ERRORED across 330f63c..5482863 with the floor still green. Measured against the runs those two commits produced, nothing changed in that range: both are green, both report known_red_runtime_errored=142 over the SAME 142 identities (extracted and diffed), both roster joins read roster=177 still_red=177, and the range's diff does not touch floor_expected_red.dag. The described transition could not have occurred either -- an unenrolled runtime error is already a gating conjunct via outcome.failures, and an enrolled identity that passes reports known_red_now_passing, also gating. The real event is a HELD to RUNTIME-ERRORED reclassification, on 2026-08-23 in ec2f3c3 (#8959): known_red_held fell 208 to 36 while runtime_errored appeared at 164. That commit revealed rot rather than causing it. What survives from the brief is its second clause, and it is real: 142 enrolled identities produce no verdict on every run and the floor reports failed=0. required_floor_outcome_is_clean deliberately omits known_red_runtime_errored and known_red_observation_unreadable, and that call is not disputed here -- the arm's own comment reserves the change for an approved design. What was missing beside it is the DESIGN 4b(2) obligation: a class parked below its ceiling must name its next-rung trigger and size its population, and neither existed. gunbc.floor_non_verdict_enrollment carries both. The population is measured (119 name not in the loaded index, 13 type error, 9 undefined variable, 1 call contract mismatch) and declared through a PopulationBasis arm as a one-run snapshot rather than a bound, because nothing counts a witness that starts throwing tomorrow. The dominant cause was checked by hand rather than assumed: four unresolved names all ARE declared in the corpus, and the witnesses referencing them declare no import -- the refusal is correct and the witness is unimportable, which is why the trigger makes population repayment a precondition of the gating conjunct rather than a follow-up. The witness asserts the census sums to the measured total, that no declared cause sits at zero, and that the basis is still the snapshot arm -- so the next-rung transition cannot be asserted by editing one row. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The carrier's declaration RHS lives on the declaration's own line `data <name>: <Type> =` followed by a newline before the expression is a parse error in .dag -- "expected expression, found Newline" -- and three rows in the new carrier were wrapped that way. Measured, not guessed: the module index refused the file with that diagnostic on a remote dispatch, and with the rows unwrapped all three witness functions evaluate and return true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The 99 came from a fix-carrying baseline, not from the #8959 reclassification The dispatching session supplied the true cause and it is better than the one this probe reconstructed: the brief was differenced against gunbc#9020's BRANCH HEAD, which carries the resolution repair. Verified here rather than taken on report -- run 32680784546 (c767f4c) reads passed=10619 known_red_runtime_errored=43 against the base's 10520 / 142, exactly -99/+99, with `planned` identical at 10791 on both. That last equality is what let the mistake survive a sanity check: an equal planned population reads as an equal baseline and is not one. Section 2 previously attributed the 99 to the HELD -> RUNTIME-ERRORED reclassification in ec2f3c3 (#8959). That reclassification is real and is why this population is visible at all, but it is not where the brief's figure came from, and asserting a wrong cause in the document that exists to correct a wrong cause is the same defect one layer in. The old attribution is kept as a marked correction rather than deleted, because a reader who saw the first version needs to find out it moved. Section 1 is unchanged and was correct: there is still no regression in the named range. The carrier is deliberately NOT pre-adjusted to 43. Writing a branch's number into a row measured on main would commit the fix-carrying-baseline error a second time, inside the artifact documenting it. The PopulationBasis arm names the run and commit, so the row is re-measured when #9020 lands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Freeze the non-verdict population's growth at identity grain: the composition was below floor RULING (operator, relayed via the dispatching session): the observation arm is not the defect. known_red_runtime_errored and known_red_observation_unreadable say something TRUE -- this enrolled claim produced no Boolean verdict. What was wrong is the COMPOSITION: required_floor_outcome_is_clean consulted neither, so the floor returned CLEAN while an enrolled expected-red assertion had ceased to assert anything. A diagnostic can describe the evidence truthfully while the gate draws a false conclusion from it. Per seam: routing is mitigatable, printing the count is mitigatable, printing failed=0 without distinguishing verdict incompleteness is a misleading projection, and returning clean over an enrolled claim that produced no verdict is BELOW FLOOR. Below floor is not a rung, so this could not wait on the population being repaid, and the previous revision's 4b(2) row understated it. WHAT ENROLMENT ADMITS: a known SEMANTIC VERDICT, not permission for the subject to stop evaluating. Without a wall the expected-red arm absorbs an arbitrary regression strictly INSIDE the enrolled population -- yesterday the witness answered false, today it throws before reaching its assertion, no verdict exists, floor stays clean. An UNENROLLED witness that throws already gates through the ordinary failure path, so the absorption was never repo-wide and this commit does not claim it was. THE WALL IS A GROWTH FREEZE, NOT A GATE ON THE POPULATION. v2.workflow.floor_non_verdict carries the 142 identities; admission is that ADDED is empty. 142 -> 43 -> 0 is admitted in any order; 142 -> 143 refuses; and a swap that repairs one identity while a different one begins throwing refuses even though the count never moves. That last case is why both sides are compared as IDENTITY SETS -- a count cannot see a swap, and a repaired witness must not buy permission for an unrelated witness to lose its verdict. It has its own witness, asserting the length equality beside the refusal so the discrimination cannot be read as an artifact of differing sizes. TWO DESIGN DECISIONS THAT ARE NOT ARBITRARY. The polarity is unenrolled-blocks, so an EMPTY roster is the strictest state and a roster read failure cannot flatter a run -- the opposite polarity rebuilds the absorbing-fallback shape inside the mechanism written to close one. And repaid does NOT gate, deliberately breaking symmetry with floor_route_gap's stale-row refusal: copying it would red the floor on the merge that repairs 99 of these (gunbc#9020), which is how a repository teaches people not to repair debt. Added is walled; repaid is announced per identity with its remedy. A non-verdict row not also in floor_expected_red is REFUSED, not warned. Only enrolled identities reach these arms, so such a row can never fire -- unreachable, not empty -- and DESIGN is explicit that a check whose red cannot be authored is a decoration, worse than absent because it is cited as coverage. FloorAdmittedWithNonVerdictDebt separates unexpected_failures from verdict_incomplete on the top line. `failed=0` is a sentence a reader can finish alone and finishes wrongly; that misreading is what dispatched this whole lane against a regression that did not exist. Evidence: cargo check clean; four admission witnesses return true by execution (unchanged admitted, repayment admitted with repaid=2/added=0, growth refused with added=1, and the equal-count swap refused with added=1 and repaid=1); the roster evaluates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The admission is one pure function of two identity sets, with its red on the seed path The decision was taken INLINE IN TWO ARMS, which is two places one rule could drift from the modeled admission it mirrors. It is now taken once, after the fold, over two identity sets: the arms only RECORD what they observed. That was prompted as a way to make the seed testable and turned out to remove a real second-representation seam. THE SEED PATH NOW HAS A DISCRIMINATING RED, which the previous commit did not have -- its four witnesses exercised the MODELED admission, and a mirror can be wrong in ways its carrier cannot see. Five unit tests drive growth, repayment, the equal-count swap, and the empty roster through the Rust that actually gates. MUTATION-CONTROLLED, because five green tests establish nothing on their own: stuck-admit (always true) -> 3 of 5 FAIL count-based (added.len() <= repaid.len()) -> 4 PASS, 1 FAILS restored -> 5 pass The second mutant is the load-bearing measurement. A count-based admission passes every test except the swap, which is exactly the claim the design rests on: a count cannot see one identity repaired while a different one begins producing no verdict, and only the identity-grain comparison refuses that trade. Without that single case the mutant ships green. THE MIRROR'S RUNG IS NAMED rather than left implicit. There are now two implementations of one rule -- v2.workflow.floor_non_verdict_admission and v1_compiler.cli_run non_verdict_admission -- so the carrier records the seed half as MITIGATABLE with its next-rung trigger being derivation from the carrier, the same framing v1_compiler.required_regen_host already carries for its hand-mirrored ordering. The class rung is the minimum across paths, so it is mitigatable. RESIDUAL GAP, NAMED: none of this reaches the wiring from a real thrown witness into the observed set. That path is still unexercised. It is narrower than "the seed wall is untested" and it is not zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Repayment and roster deletion are one act; and the hand-Rust growth gets its receipt Both findings in review 55361 are correct. Neither is argued with. FINDING 1 -- THE STALE ROW WAS A LIVE EXEMPTION. stale_non_verdict shipped report-only under my argument that refusing it "punishes the fix", and the reviewer found the hole: the identity is repaired, the row stays, and if that witness later stops producing a verdict again it is ALREADY ROSTERED, so the exact regression this wall exists to refuse is admitted in silence. Repayment without deletion turns a bounded debt row into a permanent licence -- the absorbing fallback wearing the word "diagnostic". Refusing does not punish a repair; it requires the repair to be COMPLETE, the run names every row to delete, and this is the discipline stale_route_gap and the expected-red staleness join already enforce. The asymmetry was the error and consistency with them is the repair. Worth recording that the asymmetry had an argument behind it and was endorsed before a reviewer found the hole -- an endorsement is not a proof. FINDING 2 -- THE FORWARD-FREEZE ROW WAS MISSING. Verified against the tree rather than taken on report: gunbc.seed_growth_admission seed_growth_forward_freeze_policy_note requires every PR adding hand-written src/v1 Rust to enumerate exact item identity, .dag authority, why Rust is still needed, owning lane, deletion trigger, current boundary, hand-item delta and hand-LOC delta, and rules unenumerated hand growth a stop-line with no netting of deletions against additions. This change added hand Rust and authored no row. floor_non_verdict_seed_growth_justification now carries it: +8 citable items (three production, five discriminating unit tests), measured deltas of +195 cli_run.rs, +65 claim_executor.rs, +85 in the new test file, lane v1-hand-queue-drain, trigger the self-emitted claim executor, boundary named end to end. The two new RequiredFloorOutcome fields, the added conjuncts, the roster read and the report lines are deliberately NOT listed: none adds a declaration, so their disposition is ExistingSeedItemModified and listing them would net modifications into an addition census. The row is registered in the closed roster in seed_growth_admission. Evidence: build clean; 5/5 seed admission tests; the seed-growth roster well-formedness gate returns true over the extended roster (closed, well-formed, no duplicate DeclarationRef keys); the carrier witness returns true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The roster needs a reachability edge, and the note that should have prevented this did not CI refused during floor preparation: `floor_non_verdict_roster: no declaration named 'v2.workflow.floor_non_verdict.floor_non_verdict_roster' in this execution's loaded index`. The host evaluates roster functions in v2.workflow.required_floor's frame, so a roster module reaches the loaded index only via an import edge there. Mine had none. THE FIX IS ONE LINE. What is worth recording is that required_floor.dag ALREADY CARRIED TWO PARAGRAPHS documenting this exact failure happening twice before, saying precisely what would go wrong and why -- and I read that file, added a roster, and reproduced it a third time. A prose note that has now failed to prevent the thing it describes on three consecutive occasions is not a wall; it is a record of a mechanism defect. The list is a hand-maintained reachability closure that nothing derives and nothing checks, and its violation surfaces only from a full CI run. So the third paragraph says that, rather than adding a fourth warning: the structural repair is for the host's roster evaluations to derive reachability from the qualified names they call, at which point the import list and all three paragraphs delete together. THE POLARITY IS WHY THIS WAS LOUD. The roster read fails closed, so a missing edge stops the floor instead of yielding an empty roster. Under the opposite polarity this same omission would have produced a silently permissive wall -- the exact failure mode this PR exists to close, reintroduced by an oversight nobody would have seen. AND THE FAILURE IS THE DOCUMENTED CLASS, on its own author: "not in this execution's loaded index" is the same diagnostic behind 119 of the 142 identities this roster carries. The witnesses in that population reference declarations that exist while declaring no import; so did I. Evidence: required_floor's closure compiles with the edge -- exit 0, 0 blocking errors, 126 advisory. The host's own roster read is exercised by CI, which is the test that failed and is the test that has to pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Name the axis the wall does not confine: the roster itself is not compared against the base The dispatching session, relaying its second reader, asked whether R (subset of) B is enforced. Checked against the implementation rather than my description of it: it is not. non_verdict_admission takes observed and roster-at-head, and no base reference exists anywhere in that path. So a change that makes a NEW identity stop producing a verdict may add its row IN THE SAME CHANGE, satisfy both executing arms, and be admitted — the roster legalising the regression it exists to bound. That is review 55361's finding (the row becomes the permission) reached through authorship instead of through survival. NO MECHANISM CHANGES HERE. The wall does exactly what it did when CI went green. What was defective was the CLAIM: the module was named a growth freeze and the title said "frozen against growth at identity grain", from which a reader concludes growth is refused. That is rung inflation in DESIGN 4b(1)'s exact sense — worse than sitting low, because an inflated class never ranks for climbing — and it was false in the artifact independent of whether the conjunct ever lands. So the header now opens with what is confined and what is not, BEFORE it describes the admission, and the title says confines rather than freezes. TWO AXES, ONE EXECUTES. Observed-vs-roster is walled by execution every run: growth refuses, stale exemptions refuse, both at identity grain. Roster-vs-base-roster is not walled at all — mitigatable, confined by review diligence, which is strictly weaker. The class rung stays the minimum across axes and paths. NEXT-RUNG TRIGGER, and it is specified at identity grain for the same reason the executing arm is: the floor reads the roster at the merge base and refuses when the head roster is not a subset of it, established against a discriminating red. Not satisfied by counting rows — an addition and a deletion in one change leave every count unmoved. WHY THE CONJUNCT IS NOT IN THIS PR: reading the base roster means evaluating a .dag module out of a git blob in a separate resolve context. That is real machinery deserving its own discriminating red, not a paragraph bolted onto a change already at full approval with green CI. AND THE HONEST ACCOUNT OF WHY THE HOLE EXISTS, which is the reader's framing and better than mine: the admission was SPECIFIED against a base OBSERVATION, and substituting the roster for it is what makes the wall runnable in a single pass. The substitution is sound exactly to the degree the roster cannot be grown freely, so R (subset of) B is the condition that makes the cheap design safe rather than a nicety on top of it. Evidence: required_floor's closure compiles at 0 blocking errors (126 advisory); the carrier's closure at 0 blocking errors (276 advisory). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The growth trigger names the target-base tip, not the merge base A precisely-wrong trigger is worse than a vague one, because someone implements exactly what it says. The previous text named the MERGE BASE as the future authority for the roster-growth law. It is the wrong baseline, and the failure is an admission rather than a spelling. EXEMPTION RESURRECTION. M = {a} at the merge base. Main later repairs `a` and deletes its row, so the current base tip carries B = {}. A stale branch reintroduces `a` and it throws: H = {a}, O = {a}. Then O = H passes and H subset-of M PASSES — readmitting an exemption main has already paid off. H subset-of B fails, which is the law actually wanted. The mirror is a false red: a row main legitimately adds after the fork sits in B and in the composed result but not in M, so a subset-of-M rule refuses a branch that did nothing wrong. So the law is H subset-of B — the roster in the COMPOSED RESULT is a subset of the roster at that result's CURRENT TARGET-BASE PARENT — and the trigger now says so, in both the carrier and the roster header, with the counterexample beside it so the next author cannot re-derive the weaker rule from the stronger sentence. CONSEQUENCE FOR THE CUT'S SHAPE, recorded because it changes how the follow-up is scoped: a BRANCH-HEAD-ONLY RUN CANNOT ESTABLISH THIS LAW. It needs the composed result AND that result's base parent, which is strictly stronger than "read the roster at another commit". The trigger also pins the receipt the cut must carry — target_base_sha, composed_result_sha, base_roster_identity_set, result_roster_identity_set, added_exemptions = result - base — and requires the same read-failure polarity the executing arms already have. NO MECHANISM CHANGES. The two executing axes are untouched and the "confined at identity grain" claim is unaffected; only the future authority named in the trigger was wrong. Amended in this PR rather than deferred to the follow-up because the head had already moved for the main integration, so the approval cycle was already reset and the marginal cost was zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The no-import story does not cover the whole bucket: six of the eight are inside it An independent census (valiant-lynx-227, run 32743601436) partitions the erroring modules 53 declaring NO import against 8 that declare imports and error anyway. Cross-joining that against this carrier's own cause census — which neither lane had done — puts SIX of those eight inside the `no declaration named` bucket. The bucket is not homogeneous, and §5's four hand-checked names, all lacking imports, leave the impression that it is. ONE OF THE SIX READ IN FULL, so the second shape is evidence and not inference: v2.lens.vacuity_test fails on `nat_add_left_identity_input` while declaring ten imports, among them v2.test.nat_semiring.rung_5 — a module that REFERENCES that name but is not the module that DECLARES it (v2.std.algebra_laws.nat_semiring). Importing a module does not transitively supply the names its own declarations reach for. So the second shape is an INCOMPLETE import set, not an absent one. THE CONCLUSION IS UNCHANGED AND SLIGHTLY STRENGTHENED: both shapes are authored defects, both repaired by adding the import that declares the referenced name, neither is a floor scope defect. "Widen the scope" is still the wrong trigger. What moves is the repairer's expectation, which matters to the lane inheriting the backlog. The remaining five are established only as "declares imports AND lands in this bucket"; their specific missing imports are unread, and the row says so. ALSO RECORDED: the census reached me first as "142 rows but 133 distinct, 9 appearing twice" — which would have meant this roster carried nine stale exemptions. False, and instructively so: the floor COLUMN-PADS the identity, so short names are followed by spaces before `ERROR in`, and an extraction using `[^ ]*` cannot cross that padding. The pattern silently selected for long identifiers and dropped exactly nine rows. The nine were MISSED, not duplicated — sign inverted, the same shape as the brief this document exists to correct. Two independent diagnoses converged on the padding cause. The durable rule: a distinct-vs-total discrepancy is a tell about the READER before it is a tell about the population, and the control is to count with a different pattern than the one that extracts. AND THE CAUSE CENSUS IS DECLARED A CLAIM, NOT A RECEIPT. The floor log carries no cause text beside the ERROR row, so the 119/13/9/1 partition cannot be checked by anyone unwilling to re-run a floor that OOMs in a session container — unverifiable by construction. Printing the cause beside the identity is a smaller change than this wall and would have made the false alarm impossible; it is a separate subject, and until it lands the partition is a claim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * The modeled authority still said repaid never gates: one rule, two answers Review 55515, correct. When stale_non_verdict was flipped to gating after review 55361, the reversal reached the roster header, the seed's field doc and the gate conjunct — and missed the docstring on v2.workflow.floor_non_verdict_admission non_verdict_repaid, which went on saying "Reported, never gating: a repaid row must not red the run that repaid it". That left two authorities stating OPPOSITE RULES about one admission, inside the module whose whole subject is single authority, in a PR whose body cites review 55361 for exactly this class. The mechanism was never wrong — the executing code has refused stale rows since that fix — which is precisely why the sentence survived: nothing that runs reads it. FIXED IN BOTH PLACES, because the reviewer found one instance and there were two. The docstring now states the rule and records that it was reversed and why. The PR body's "repaid does not gate" paragraph carried the same stale claim and is corrected as a struck-through amendment rather than a silent rewrite — a reader of the earlier revision saw the reversed claim, and quietly replacing it would hide the drift instead of recording it. SWEPT FOR OTHERS: grepped every carrier, the seed, the probe document and the PR body for surviving assertions that repaid or stale does not gate. The only remaining hit is the verbatim quote of the original brief in the probe document, which is a quotation and stays. WHAT THIS IS AN INSTANCE OF, recorded because it is the day's recurring shape: prose asserting more or other than the mechanism does. Every defect found in this PR has been that — the failed=0 line, the diagnostic stale row, the growth-freeze title, the merge-base trigger, and now a docstring left behind by its own reversal. None was a coding error. All were caught by someone checking a claim against the tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Drop the "65 distinct signatures" figure: it counted names, not causes valiant-lynx-227 found that the floor's [floor-known-red-causes] census keys on the FIRST TWELVE WORDS OF THE MESSAGE PROSE, and that prose embeds the missing NAME. So `no declaration named 'srv3_install_hang_no_router_lease_ms'` and `no declaration named 'extdeps_cargo_build_module'` are two distinct signatures. It reports ~65 for a population with roughly four actual causes — an artifact of the key, reading as "many roots" when the truth is "one root, many names". A plan sized off it is sized wrong, toward heterogeneity, when this population is mostly one repair. The same line is SILENTLY TRUNCATED AT 20: the printed rows sum to 93 of 142 identities, with 49 identities and 45 signatures dropped and nothing saying so. WHAT THIS DOES AND DOES NOT REACH, and the boundary is the derivation rather than luck. The 119/13/9/1 partition was folded over the 142 PER-IDENTITY KNOWN-RED-RUNTIME-ERRORED lines and sums exactly to 142 — neither prose-keyed nor truncated — so it stands. The population count and the identity set stand too; the executed set match settles both. What does not survive is any DISTINCTNESS or HETEROGENEITY claim, which is precisely the one figure this document took from that line. It is deleted rather than annotated, because an artifact carried with a caveat is still cited as a count. ALSO CORRECTED, IN MY OWN FAVOUR, WHICH IS WHY IT IS WORTH WRITING DOWN: an earlier revision of this document called the partition "a claim, not a receipt" and "unverifiable by construction", on the assumption I had hand-derived it. That was too harsh and is now scoped to what is actually unverifiable — there is no per-identity cause field, so the partition cannot be JOINED BACK to identities by a reader, which is a narrower and truer statement than "unverifiable". The root — ClaimOutcome::RuntimeError carrying message: String built by format! over an already-closed 27-arm InterpError, so a typed cause is destroyed at the witness boundary and guessed back by word-slicing at the reporting site — is being repaired under its own item and is not held by this PR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Delete the probe board, keep the finding on the carrier: the measurement corpus was bankrupted under this PR Main landed #9132 (bankrupt the measurement corpus) while this branch was open, under an operator ruling this change is directly subject to: name the instrument, never transcribe its output. 164 files and 44,736 lines went out of docs/probes/, every .sh/.py instrument kept. docs/probes/expected_red_non_verdict_population_2026-08-24.md is a transcription board of exactly the class that ruling deletes. After merging main it was the ONLY file left in that directory -- one document re-establishing a corpus main had just emptied, on the same day, which is the attractor DESIGN section 3 names rather than a document that happened to survive. It is deleted here. WHAT IS NOT LOST, and why the deletion is not a coverage cut. The measurement never depended on the board: floor_non_verdict_cause_census and floor_non_verdict_measured_total are typed rows, and floor_non_verdict_population_basis carries MeasuredOnOneRun { run, head_commit }, so every figure names the run and head it was taken on. That is the receipt-vs- figure distinction a markdown board structurally cannot carry, which is the ruling's own argument for the cut. WHAT MOVED. One irreducible fact in the board was rationale rather than measurement and had no other home: the dispatched brief -- 99 witnesses PASSED -> RUNTIME-ERRORED across 330f63c..5482863 with the floor reporting failed=0 -- is false in its first half, shown by an identity-set diff, because the 99 were baselined against a branch head already carrying the fix and so were compared to a tree they never ran in. The carrier's existing prose REFERRED to that false regression without ever stating it; it now states it once, as a section 4c annotation on the declaration it explains. A first draft of that annotation also restated the fix-carrying baseline the preceding block already covers, and was trimmed to the half that was actually missing. RESIDUE, checked against the three classes #9132 declared for its own cut and found empty here: no .gitignore un-ignore row, no prose note in any module, and no witness asserting the filename. Nothing in the tree references the deleted path, so this leaves none of the debt that commit declared for itself. Verified: the module parses and evaluates after the annotation -- floor_non_verdict_measured_total returns 142, the host refusing only on its exit-code contract (an Int is not a ProcessExit), which it can raise only after computing the value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Make the modeled admission say what its consumer does, and re-measure the hand-Rust receipt (review 55577) Two findings, both verified against the code before fixing. ONE: THE MODEL DISAGREED WITH ITS ONLY CONSUMER, AND I CAUSED IT. `non_verdict_admits` -- modeled in v2.workflow.floor_non_verdict_admission and mirrored in v1_compiler.cli_run -- answered `added.is_empty()`. The executing gate `required_floor_outcome_is_clean` has nine conjuncts, two of which are `non_verdict_unenrolled.is_empty()` (the added arm) AND `stale_non_verdict.is_empty()` (the repaid arm). So the canonical model said ADMIT exactly where its consumer said REFUSE. The provenance matters because it is not an oversight in the original design: it is the divergence review 55361 opened. That review correctly argued stale rows must gate, I made the GATE gate, and I did not carry the change into the model or its tests. DESIGN section 3 is the point -- a modeled authority whose consumer disagrees is worse than no model, because it is cited as the rule while something else enforces a different one. WHAT WAS RIGHT ABOUT THE OLD RULE AND WHAT WAS WRONG. The rationale for admitting repayment was that refusing it would red the merge that repairs the population (#9020 repays 99 in one landing). Right about the goal, wrong about the subject: what refuses is not the repayment, it is the roster row LEFT BEHIND asserting a debt that no longer exists. Repaying and deleting the row are one act, which is already how the #9020 merge-order deletion was planned. So both paths now admit iff added and repaid are BOTH empty, and both suites gain a control -- repayment WITH the row deleted is admitted. Without that pair the tests cannot discriminate "stale rows refuse" from "repayment refuses", which are opposite rules; the pair fails in opposite directions if either is wrong. TWO: THE HAND-RUST RECEIPT WAS STALE. It read +195 in cli_run.rs and +65 in claim_executor.rs and omitted claim_executor's deletions entirely. Measured by git diff --numstat against origin/main at this head: +203/-0 cli_run.rs, +60/-5 claim_executor.rs, +102/-0 the test file. The forward-freeze policy exists to make hand growth checkable, and a receipt measured once and not re-measured as the change grew is a figure rather than a receipt -- the row now says so and says it must be re-measured on every push touching those files. Also removed a blank line between one annotation block and the declaration it attaches to, matching the convention every other annotation in that file follows (DESIGN section 4c attaches annotations to a declaration). This is NOT claimed as a fix for anything: a discriminating control through the actual parse sweep, with and without the blank line, produced identical output, so the form was not what any gate was refusing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Retire the prose that still states the rule the reversal replaced, and the citation naming a test that no longer exists (review 55591) The reported finding, plus two of the same class the sweep for it found. REPORTED: the `observed_repaid` fixture comment still read "Must be admitted -- refusing it would red the merge that repairs the population", directly above the test that now asserts the opposite. Fixed, and it now says WHY the refusal is not a penalty on repayment: what refuses is the roster row left standing, not the repayment, and the deleted-row form is admitted by the fixture below it. FOUND BY SWEEPING FOR THE CLASS RATHER THAN THE INSTANCE: (1) The same defect in the Rust mirror. `non_verdict_admits`'s docstring still described the retired asymmetry -- "so a caller cannot accidentally admit on `repaid` -- the asymmetry between the two is the content of this wall" -- sitting directly above a body that now refuses on both arms. Rewritten to state both refusal reasons, with the correction dated. (2) A STALE CITATION, and this one would have shipped silently. `floor_non_verdict_seed_growth_justification` cited `repayment_is_admitted_and_reported_per_identity`, which the previous commit RENAMED. That is a DESIGN section 3 fabricated symbol -- and the mechanism that used to catch it, the cited-symbol census, was removed from CI on 2026-08-23, so nothing in the repository would have refused it. Verified the whole file by hand instead: all 12 DeclarationRefs resolve to a definition in the tree. The new control test is added as a cited row, since a hand-authored seed item that is not enumerated is exactly what the forward-freeze policy refuses. Receipt re-measured, as the row itself now requires on every push touching these files: +210/-1 cli_run.rs, +60/-5 claim_executor.rs, +102/-0 the test file. THE PATTERN, recorded because it is now four for four in this PR: every defect found here has been PROSE CLAIMING SOMETHING OTHER THAN WHAT THE MECHANISM DOES -- the failed=0 headline, the "diagnostic" stale row, the growth-freeze title, the merge-base trigger, this docstring, this fixture comment, this citation. Not one was a coding error. That is the cost DESIGN section 4c prices when it calls prose commentary modeling debt: it cannot be mechanically joined to the code it describes, so a reversal updates the assertion and leaves every sentence about it standing. Verified by execution: both witnesses return true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#9151) * The forward-freeze policy said "enforceable now"; nothing enforces it Two corrections to gunbc.seed_growth_admission, both to rows that made a false claim about their own coverage. RUNG INFLATION. seed_growth_forward_freeze_policy_note led with "FORWARD-FREEZE POLICY (enforceable now)". It is contradicted by seed_growth_admission_note two rows down in the same file: what is enrolled is seed_growth_roster_well_formed_ gate_holds, which checks the roster against ITSELF -- non-empty, well-formed rows, no duplicate keys -- and never reads a diff. seed_growth_join_declarations, the join that would refuse an unenumerated addition, is NOT ENROLLED, because no changed-item population exists to join against. So nothing can refuse hand growth today, and DESIGN 4b calls a carrier named for a rung it does not occupy worse than sitting low: the class never ranks for climbing because its own row already claims the rung. It is not a scruple. Of the four PRs that added hand src/v1 Rust in the 48 hours to 2026-08-24, ZERO were caught by an unassisted reviewer; all four were caught by follow-up investigation after reaching approval. The row now states the rung (mitigatable, review diligence alone), the measurement, and a 4b(2) next-rung trigger -- rust_item_host_observation supplying a changed-item population -- with the two conditions that enrolment must satisfy: the join must be SPLIT (one candidate set cannot both find unjustified additions and declare rows stale), and an extractor that cannot attribute a changed region must REFUSE rather than report an empty delta, which would be the empty-observation narrow DESIGN 5 forbids. DEAD CITATION. seed_growth_admission_note cited scripts/rust_item_census.py as its G0 host in the present tense. That file was deleted by gunbc#9132, which left no .sh or .py outside .githooks. Five sibling modules carry the same dead citation and are deliberately NOT repaired here -- that is the residue #9132 declared, not a gap this change opens. Also recorded: hand-item delta and hand-LOC delta are functions of the diff, so authoring them is a second representation (DESIGN 2). Still required, because nothing derives them yet, and the cost is already measured -- a receipt on gunbc#9095 claimed +195/+65 against a measured +203/-0, +60/-5, +102/-0. EVIDENCE. Prose-only; no behavior changes. The two phrases seed_growth_admission_witness_test asserts ("exact item identity", "no netting") both survive. Evaluating that witness locally on this branch and on clean origin/main produces byte-identical diagnostic sets (496 lines, zero diff), so this change introduces nothing; the local gunbc shim is a Jun 26 build that cannot resolve this corpus, so it cannot show the witness passing either way. CI is the authority for that. * Repair the two rows this file's own correction left contradicting it review 55623 is right, and the finding is worse than the one I fixed: I corrected ONE row to say the G0 census host is gone while leaving TWO rows in the SAME file asserting scripts/rust_item_census.py is the current host. A module answering two ways about one fact is the DESIGN 3 violation this PR exists to remove, so the first pass made the file its own counter-example. seed_growth_g0_census_host_scaffold_note: rewritten past tense, with its dissolve-on condition split into the two clauses it always contained -- (a) script deleted, SATISFIED by gunbc#9132, and (b) rust_item_host_observation producer enrolls, OUTSTANDING. The disposition row is RETAINED, not retired: (b) is unmet and it has three consumers, so retiring it because half its trigger fired would delete a live obligation. seed_growth_admission_g0_population_note: now leads with G0 CENSUS HOST: NONE. It also carried an instruction to "run the script at HEAD for the live receipt", which named a deleted file -- an instruction is worse than a stale citation, because a reader follows it before discovering it is impossible. The mechanism description is retained, marked as describing what WOULD measure the population, because the laws survive the producer. The residue sentence is corrected too: it listed five sibling modules and omitted the two local ones, which is precisely how the contradiction survived the first pass. Siblings remain declared residue; the local pair is repaired here. EVIDENCE: prose-only. Evaluating seed_growth_admission_witness_test on this branch and on clean origin/main gives byte-identical diagnostic sets (497 lines, zero diff), so nothing is introduced. The two phrases that witness asserts are untouched. --------- Co-authored-by: Brian Searls <briansearls1@gmail.com>
…ion refusal (#9072) * Carry the span the parse phase already computed: locate every annotation refusal The required-ci parse phase rendered N annotation refusals as N byte-identical sentences with no position. The span was never missing: AnnotationAttachmentRefusal carries origin, diagnostic_to_span reads it, and run_dag_parse_sweep then formatted "{path}: {message}" and discarded it -- a typed, LOCATED diagnostic rendered as untyped prose (DESIGN section 5). The printer now builds a NewlineIndex over the same content the parse consumed and renders "{path}:{line}:{col}: {message}". A diagnostic whose span names no position in this file renders as the path alone rather than as a fabricated 1:1. One defect, three instances: all three refusal arms were unlocated for the same single reason, and the repair is arm-independent because it reads diagnostic_to_span rather than matching arms. Both consumers inherit it -- the --required-ci parse phase and the standalone v1_src_dag_parse. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Enumerate this PR's seed growth, and shrink it from 12 hand items to 7 The forward-freeze policy (gunbc.seed_growth_admission seed_growth_forward_freeze_policy_note) requires every PR that adds hand-written src/v1 Rust to enumerate item identity, authority, reason, owning lane, deletion trigger, boundary, and both deltas. Tests are not excluded, and the G0 census host agrees by execution: classify_repo_path returns "hand" for every tracked .rs outside the stage0 source root, so src/v1/stage0/tests/ is in the measured population. The scratch directory was an RAII guard -- one struct, two impl blocks, three impl methods -- and every impl method among them is UNCITABLE as a DeclarationRef, so it would have grown the class seed_growth_uncitable_item_keys reports separately. Collapsed to one free function that cleans on the way in, which is what makes the run deterministic anyway. Census diff against origin/main: 12 items -> 7, uncitable 5 -> 0, +123 LOC -> +109. Files: one justification row homed beside the obligation, one roster entry, one roster note. cli_run.rs adds zero items (the change is inside an existing fn: ExistingSeedItemModified). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Re-anchor the seed-growth scope argument on the authority that survived #9132 #9132 deleted scripts/rust_item_census.py, the G0 census host this receipt cited in the present tense as the executable settlement of "are tests in scope". A citation naming a deleted file is the stale-citation class -- inside a receipt whose own argument is that an unverifiable figure rots silently. The scope argument now rests on a .dag authority that still exists and is a better anchor than the script was: gunbc.stage0_rust_source_lifecycle_scaffold declares rust_source_prefix_stage0_test ("src/v1/stage0/tests/") and lists it in rust_source_discovery_prefix_hints, so the stage0 test tree is a DECLARED Rust source class distinct from stage0_src_repo_prefix, the only prefix the emit produces. The item deltas are unchanged and now say what they are: a dated measurement taken with the census host before its deletion, re-checkable by hand from the diff (seven added items in one new file, all free functions), not a command anyone can re-run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ct and verb axis for the emitted-tree consumer (#9154) * Single build authority + module-grain affected-set selector inverted to one reverse BFS WIP: repo_self_build.dag is the single cargo-build authority (three workflow authorities rewired onto it). module_graph.dag gains the reverse-reachability selector: build adjacency once, BFS outward from touched paths, O(1) membership per entry -- replacing entry_affected_by_touched_paths' per-entry whole-graph walk. A touched path resolving to no module on disk refuses (TouchedPathOutsideModuleGraph); it never widens to the corpus and never narrows to nothing. Compiles: 0 blocking errors on src/v2/lens/module_graph.dag. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P * The build authority gains a subject and a verb, so the emitted-tree build has a home instead of a fork crisp-crab-430 needs to cargo-check an EMITTED CANDIDATE TREE -- the one required-regen writes to disk and then compares byte-wise to the committed seed without ever asking whether either compiles. They raised it before writing rather than after, which is the only reason this is a design change and not a second authority. THE MODULE ARGUED AGAINST ITSELF. repo_self_build_authority_note pins the package as data because 'a caller free to name the package could build a different crate and still look like a conforming call'. Their subject IS a different crate, so the exact property the note relies on is what excluded them. That is not an under-served case; it is the note being right about the danger and wrong about the remedy. A closed subject coproduct keeps the guarantee and admits the second breadth: type CargoBuildSubject = RepositoryCrate | EmittedCandidateTree { manifest_path: String } No constructor names an arbitrary crate, so the property the note wanted is now structural rather than rhetorical -- and the one other legitimate subject has a name. DESIGN section 2 horizontal, one concept at two breadths, rather than a sibling module sharing an argv vocabulary, which is what a section 3 fork looks like from the inside. THE VERB IS THE SECOND AXIS AND THEY DID NOT ASK FOR IT. The base command hardcoded 'cargo build'. Establishing that an emitted tree COMPILES needs only check, and the difference is measured, not stylistic: check 59.8s / 2.5GB peak against build 155s / 4.7GB peak, warm, with the whole stage0 lib recompiled -- the candidate-install case exactly -- and every diagnostic of interest is check-visible. Left hardcoded, the next consumer writes 'cargo check' beside this module's 'cargo build' and the fork this module exists to prevent reappears one field down. repo_self_build_command keeps its signature, so the three consumers rewired onto it are untouched: it is now the RepositoryCrate/CargoBuild instance of the general form rather than the only form. Compiles: 9 files emitted, 0 diagnostics. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P * A transcribed duration with no subject was never usable evidence: name the instrument, and land the projection #9132 left behind TWO THINGS IN ONE REGEN, because they are one fact: the authority moved and the projection did not. (1) THE RECONCILE CLAUSE. Section 6 read 'reconcile's eight minutes are ~92% typecheck_with_census_extra', measured 2026-08-20. The required run of 2026-08-24 (32791076677) emits 'compile.reconcile done in 15 minutes' inside the floor's strict-preparation over 3892 modules. I NEARLY WROTE 'NEARLY DOUBLE IN FIVE DAYS' AND THAT WOULD HAVE BEEN THE SAME DEFECT THIS DOCUMENT SPENT THE EVENING CATCHING. Reconcile's cost is a function of subject size -- measured the same night at 32s for a four-module closure and 25s for required-regen's ~134 surfaces -- and the subject behind the eight-minute figure is not recoverable from this document or from 67437fc, the commit that landed it. So the two numbers cannot be compared at all, and the doubling is not asserted. That is a stronger row than an updated number would have been. The RATIO is kept because where reconcile's time goes is structural; the DURATION is dropped because it is a property of one run on one corpus size. The instrument is named instead -- every required run emits [floor-phase] rows and the compiler's own compile.frontend / normalize / reconcile / analyses lines inside strict-preparation -- so the current cost is read from the run that owns it. This applies the standing rule this document already carries, name the instrument never transcribe its output, to the clause that most needed it. Two retractions produced this wording, both caught by the other party rather than the author: a 31x preparation-versus-compile gap I published (it compared a four-module closure to 3892 modules) and a 33x contradiction smart-ram-730 published (their arm was required-regen's ~134-surface closure). Neither anomaly exists. What survives is that full-corpus reconcile is ~34% of required CI and the floor is CPU-bound and single-threaded at ~99.4% for 36 minutes. (2) THE PROJECTION #9132 LEFT BEHIND. Three further lines move in this regen and none of them is mine tonight: the deleted probe-document link and the name-the-instrument ruling both landed in the AUTHORITY at #9132 and were never projected, so committed DESIGN.md has been stale against its own source since that merge. The drift gate that would have caught this is on the unguarded list in the CI rung-drop row a few paragraphs above -- which is the row explaining why nothing refused. Regenerated through dag/tools/generated_artifact_gate.dag main_wet over all committed artifacts; DESIGN.md is the only file that moved, so every other projection was already at its fixed point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P * Move the affected-set selector to its own branch: an unwired lens does not belong in a PR that is otherwise finished Split at the operator's direction. The selector compiles clean and has no caller -- required_floor does not reference it -- so merging it here would land machinery that nothing gates on, which DESIGN section 6 names as coverage by illusion. It is not abandoned: it moves to session/deep-ant-102-affected-set-selector with its ceiling measured and stated, and it merges when it is wired to a consumer and a pruned run is measured. What remains in this PR is finished and has a waiting consumer: the single build authority with its subject and verb axes, the three consumers rewired onto it, and the DESIGN authority/projection corrections. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P * Back out the subject and verb axes: no consumer in this diff, and I had just applied the opposite standard next door Review 55633 (approve, non-blocking): CargoVerb and CargoBuildSubject add a check axis and an emitted-tree subject that nothing in this diff consumes -- the sole caller pins verb=CargoBuild and subject=RepositoryCrate -- so DESIGN section 6's new artifact with no final consumer applies and the honest landing today is bins-only. The reviewer is right on the facts. WHAT DECIDED IT IS WORSE THAN THE FINDING. Twenty minutes earlier I split the affected-set selector OUT of this same branch, on the grounds that an unwired lens does not belong in a PR that is otherwise finished, and then left unwired axes sitting in it. One principle, two neighbouring artifacts, opposite treatment. The reviewer also names the correct exception -- non-blocking if the operator greenlit the pre-plumbed axes -- and there is no such greenlight: I ruled on the requesting session's design question myself, and an author's own ruling is not the operator verdict section 6 requires for work landing ahead of its consumer. THE DESIGN IS NOT RE-OPENED BY THIS, and the module now says so in a note rather than losing it: a free package parameter remains the wrong remedy because it discards the property the authority note relies on, and a sibling authority sharing this argv vocabulary remains the section 3 fork this module exists to prevent. The subject belongs here as a CLOSED vocabulary and the verb is a real axis on a measured 59.8s check against 155s build. What changed is only WHICH DIFF carries them: the one with the consumer, not the one ahead of it. That is strictly better for the requesting session too -- axis and consumer in one reviewable change, justified on its own evidence rather than on mine. They have been told at high priority, before building against a surface about to change. 116 lines to 55. Compiles: 9 files emitted, 0 diagnostics. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P * Name why the cargo-argv fork cannot be consumed, so the next author does not discover the transport fusion alone Review 55636 is right that this module re-mints cargo argv words that extdeps.rust.cargo_build already owns, and the existing note conceded the boundary without saying what blocks it. Consuming that module is not available, and the reason is measurable rather than a matter of taste. Every cargo argv word there -- cargo, build, -p, --bin -- appears only inside a transport shell block. Measured on the live file, its entire declaration surface is one ExternalAuthority anchor, one env map, one note and two jobs-flag fns; no data or fn exposes the vocabulary at all. So there is no expression a fn here could read it from: the argv is fused to the shell transport that spells it. That is the DESIGN section 3 interface-versus-realization seam exactly. This consumer needs a workflow YAML string, which is a second realization of the same operation, so the correct repair is to de-fuse the operation shape from transport shell and bind both realizations to it -- not to have this module reach into a transport block, which the language does not admit. The follow-up is therefore de-fusion in extdeps, strictly larger than this PR and correctly outside it. Until it lands the fork stands, named rather than silent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DRMbwdtHZxTiMNZD5WLS3P --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…t moved, retire the one whose subject is gone (#9606) * Two witnesses reading deleted artifacts: repoint the one whose subject moved, retire the one whose subject is gone Both read files that earlier root cuts deleted, and both were masked until #9592 repaired the route-gap disposition. The dispositions are NOT the same, because the two deletions were not the same kind of event. REPOINTED. `regen_stage0_write_and_verify_share_compile_refusal` read `src/v1/stage0/src/bin/regen_stage0.rs`, deleted by 3b431f3 (#8406) when `claim_executor --required-regen` took over. The subject MOVED, so the witness follows it to `src/v1/stage0/src/required_regen_host.rs`, renamed off the dead binary's name. Both conjuncts survive and the positive one is tighter than at the old subject: `run_required_regen` (write) and `run_required_regen_fixed_point` (verify) do not merely share `stage0_self_compile_refusal_message`, they share the single `compile_stage0` call that consults it. The negative conjunct keeps a historically authored RED -- at 268919d^ the deleted binary carried its own forked `let hard_errors: Vec<String>`, and #6293 is the commit that removed it. A regression control with a real red is worth carrying; one without would not have been. RETIRED. The wet parser-drop witness read a receipt under `docs/probes/claude_paired_entitlement_probe/`, deleted by d3bebd0 (#9132). That commit's title, and DESIGN.md's account of the bankruptcy, say "delete every transcription, keep every instrument". FOR THIS PATH THAT IS NOT WHAT HAPPENED: `git show d3bebd0 --name-status` lists six deletions including `run-paired-probe.mjs` and `claude-wrapper-tee.mjs`. The instruments were .mjs while the surviving-instrument clause named .sh/.py, and the 2026-08-24 ruling then took the .sh/.py corpus too. Nothing in the tree re-derives this receipt, so the only route to green was authoring the JSON by hand -- fabricating exactly the measurement receipt the bankruptcy existed to end. WHAT THE RETIRE COSTS, recorded in the surviving module rather than left to be inferred from an absence: the predicate and its five discriminating controls are untouched in `test.claim.claude_sdk_parser_drop_witness`; what dies is specifically the assertion that the modeled upstream claim is grounded in a COMMITTED WET OBSERVATION rather than in a fixture transcribed from one. THE ROUTE-GAP ROWS COME OUT, AND THAT IS REQUIRED RATHER THAN TIDYING. Both identities were enrolled in `v2.workflow.floor_route_gap` on ground `NoMockResponse`, which was the wrong ground for both: the route was never missing, the FILE was. That roster is bidirectionally fail-closed by its own header -- an enrolled row whose route does not gap reds as stale, and an enrolled identity that does not execute reds too -- so after the repoint executes and the retired identity stops existing, leaving either row is a red landed on purpose. Also removed, as dead names: `claude_sdk_parser_drop_receipt_path` (a data row whose only content pointed at a deleted file), and the witness's `bin_wet` entry and `WitnessExclusionRow` in `gunbc.ci_layer_roots`. NOT TOUCHED, and it is a real gap. The retired witness's third arm, `ParserDropNotEstablished`, was built to mean REPAIR THE ARTIFACT. `eval_filesystem_read_builtin` declares `ExpectSuccess`, so a failed read raises before any record exists, and the record it returns carries only `content`. That arm is unreachable from a missing file BY ANY PATH -- the contract the witness assumed is unrepresentable, not merely unimplemented. Nothing is silently wrong today, because the TypeError is accidentally louder than the assumed contract. The fix lives in seed Rust under the v1 freeze and needs its own admission decision; it is a separate item and deliberately not taken here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Repair the citation my own deletion made stale Review finding on #9606, and it is the exact class this PR exists to remove: the hermetic sibling's note still said "The wet receipt filesystem_read witness lives in claude_sdk_parser_drop_live_witness_test.dag (ReadsLiveTree)" -- a pointer to a file this PR deletes. Leaving it would have reproduced, one file over, the dead name I removed from extdeps.llm.claude_agent_sdk_stream. It is replaced with what a reader actually needs rather than a repointed pointer, because there is nothing to repoint to: the note now records that the wet half is RETIRED rather than relocated, why (the receipt AND the instruments that produced it went with docs/probes/claude_paired_entitlement_probe/), that these controls are consequently the whole of this evidence, and where the cost of that is written down. No gate would have caught this. The citation wall re-derived in v1_compiler.declaration_index checks typed DeclarationRef literals; a prose reference inside a String is covered by nothing, before or after -- which is precisely why it took a reviewer. Swept for others: the only remaining mention of the deleted module anywhere is the srv1_residue_rehearsal captured wire blob, which is a historical capture of paths tracked at a past deploy rehearsal. That one is correctly left alone -- editing a capture to match today's tree would falsify it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…prepare or build over the live tree carry a live-corpus ignore reason and leave the required run, and the rot the first-ever `cargo test` exposed is repaired at its authorities, not hidden `cargo test -p v1-compiler --lib` had never run in CI. Its first run (33238828500) was cancelled by its own 60-minute timeout with 204 of 682 tests finished, because ~126 of the "unit" tests each build a fresh multi-entry index over `src/v2`+`dag` (4,260 modules; ~197 single-thread minutes on srv2 under nextest, 97 tests over 60 s, `self_compile_all_modules` alone 505 s), and the runner executes them serially. Those tests now carry `#[ignore = "live-corpus: ..."]` — the crate's existing `manual:` convention, one class, declared on the carrier — and the rung-drop row `required_gate_bankruptcy` names them by their instrument (`cargo test -p v1-compiler --lib -- --ignored --list`). The unit population runs in ~10 s after the compile (srv2: 537 passed / 136 ignored). Of the 44 failures the full run exposed, the 15 in the unit population are repaired where the fact lives: - REAL DEFECTS (two): `try_index_source_root_into_module_index` keyed files by their walked path, absolute since #9548 anchored the root, while the strict builder keys through `module_index_path_key` — the primary-precedence index disagreed with the strict one on every path; keyed through the same authority now. `try_build_module_index` carried `if root_idx > 0 { continue; }` before its collision refusal (from #7791), so a module declared in two roots shadowed silently in the builder named strict; the guard is gone and overlay callers have `build_module_index_primary_precedence`. - v1 TYPECHECK DEFECT: `declared_type_inhabitance` reads `params` as generic type parameters, which is exactly what a callable formal carries, so every higher-order call produced a counted advisory with a false reason (#9194); `direct_call_argument_inhabitance_diags` now excludes callable formals like its sibling `direct_call_arg_type_mismatch`. Mirror regenerated (two passes: the test blob lives inside the emitter). - STALE AUTHORITY ROWS after the #9637 reorg: 12 entry literals in `gunbc.ci_layer_roots` and 2 in `gunbc.offline_local_recipe` repointed; the two long-lane rows and one freeze row whose subjects 611fd02 and #9206 deleted are gone; the three freeze rows for relocated witnesses are DELETED rather than repointed, because the freeze gate defines relocation as growth and the roster may only shrink. `gunbc.non_fold_residue` receives the 22 sites it lacked and loses the 4 whose subjects moved or greened; its .dag twin therefore leaves floor_expected_red (it passes) and joins cost-debt chunk 12 (629 ms against the 500 ms ceiling, its whole cost the corpus scan it checks). - DELETED SUBJECTS: `cli_run::floor_witness_a_prove` (its runner, prove test and fixtures went with the FLOOR-Y cutover); the census pin tests and helpers for `docs/probes/census_extra_excludes.txt` (#9132 deleted every transcription). - EARLY ABORTS: three witness-admission tests and the roadmap jsonl-carrier test were "fast" only because they failed before their expensive step; with their inputs repaired they read the live tree for 2-4 minutes each and join the live-corpus class. - TEST ROT: the reorg rewrote a revision-addressed literal (`9ce6526c528:dag/gunbc/roadmap/...`) that must name the pre-reorg path; the method-existence witness anchored on a `Primitive()` row the frontier no longer holds. Not done here, receipts-lane rot for follow-ups: `test.claim.expectation_frontier_witness_test` names the deleted long-lane file; the affected-set kernel (`floor_diff_edits_from_diff_text`, `rerun_frontier_nodes_for_entry`, …) has no production consumer since FLOOR-Y and should go with its remaining fixture-dependent tests; the roadmap jsonl-carrier test takes 453 s and fails after its expensive step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…e prepares the roster's closure, not the tree; rust unit tests in their own job; the un-required phases declared as a rung drop (#9663) * Unbreak main: drop the JsSite artifact rows whose authority #9641 deleted, and give the six witness-bin TypeEnv initializers the unit_variant_index #9656 added Two integration collisions between independently green PRs: - #9641 deleted dag/examples/js_site but gunbc.generated_artifact and gunbc.generated_artifact_emit still imported it, so the whole-tree strict resolve refused and every floor on main has been red since. - #9656 added TypeEnv.unit_variant_index; infer_semantics_witness.rs builds six TypeEnvs by hand and none carried it, so --bins failed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The lib's own unit tests build one more TypeEnv by hand; give it unit_variant_index too Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * Required CI is the compiler floor: a static gate roster, prepared as its own import closure, with the other four phases and the product witnesses moved off the merge path Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * Drop the six duplicate unit_variant_index initializers the merge with #9648 produced * Drop the six duplicate unit_variant_index initializers the merge with #9648 produced * Regenerate .gitattributes: the six js_site rows projected from the deleted artifact registry entries go with them * Regenerate the four projections of this change: witnesses.yml (probe and all-bins steps gone, rust-unit-tests job added), DESIGN.md and design-ledgers.md (the rung-drop row), .gitattributes (js_site rows gone) * Restore the lib-test TypeEnv initializer's unit_variant_index (lost when the merge took main's cli_run.rs wholesale) * The gate closure is the loader's both-closure (imports + reference edges to a fixpoint), not the import headers: stripped modules reach their providers by reference, and the header walk left 1,190 names unresolved * Shrink the namespace transition roster: the 314 std->extdeps consolidation rows landed with #9641 and now refuse every PR as stale * Build the entry index once for both gate closures (it is the expensive part: ~75-110s per build on the corpus) * Gate closure includes containment ancestors to a fixpoint: a module importing only a child of the declaring module still binds the parent's declarations * The floor's policy module is always a closure seed: its rosters are evaluated in a frame over the prepared subject * The reference-closure index is keyed by the prepared subject's digest, bounded to the two subjects a floor process prepares by design — the gate's policy-closure preparation and the gate closure are two subjects in one process, and a once-per-process index refused the second (ReferenceIndexSubjectChanged built_for_modules=47 observed_modules=1952, CI and srv2 at 066725c) The old check keyed on module COUNT: two subjects of equal size would have shared one index silently. The new one keys on `subject_digest`, so the index a scope consults was built from the graph that scope is over, by construction. The population is bounded by FLOOR_PREPARED_SUBJECTS_PER_PROCESS = 2 (policy closure, gate closure) — a third distinct subject still refuses with the same cause, because a subject per claim is the corpus walk per row the index exists to avoid. Evidence: srv2 rerun of `claim_executor --required-ci --required-lane witnesses` at this tree builds the 47-module policy index (subject=09966adcd218af0e) and proceeds into the 1,954-module gate preparation instead of refusing at claim scope. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The floor's own runtime authorities are explicit closure seeds: the gate-bounded subject refused at output-policy install because resolve_channel_policy had only ever resolved by pool-membership coincidence — the flat bare-name channel found gunbc.output_policy because the whole corpus was loaded, not because the policy closure references it REQUIRED_FLOOR_RUNTIME_AUTHORITY_MODULES names every module the floor's Rust evaluates by name outside the gate roster: the policy module (its rosters), v2.workflow.floor_naming_hygiene (qualified evaluations), and gunbc.output_policy (bare, from install_output_policy_in). All three are seeds of the gate closure; a new by-name evaluation adds its module here or refuses at its own call site. Measured: the first gate-bounded run (srv2, at 2d5502a) got past both reference-closure indexes and refused with "no declaration named 'resolve_channel_policy' in this execution's loaded index". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * A by-name evaluation of a module's declaration runs in THAT module's scope: the floor installed the output policy and the naming-hygiene predicates from the policy module's frame, which reached gunbc.output_policy only by the accident of the whole-tree reference closure — under the gate-bounded subject the module was loaded and the name still refused floor_authority_frame(prepared, module) builds a hermetic frame over one module's exact claim scope. install_output_policy_in now receives the frame over gunbc.output_policy; floor_barren_test_sidecars the one over v2.workflow.floor_naming_hygiene. The policy module's frame keeps only the policy module's own rosters. Measured (srv2, lanes 5 and 6): with gunbc.output_policy present in the 1,954-module subject — the seeds changed the seed count 906 -> 908 and the closure not at all — resolve_channel_policy still refused as "no declaration named ... in this execution's loaded index". The scope, not the subject, was the coincidence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The floor's rosters are joined only over identities inside the required gate — an enrolled identity whose module the gate never loads is withheld with the same accounting as cost-debt withholding, not refused as stale; and two modules that reached rust_target_model_staging by bare reference now import it, because the loader follows bare references only for import-free modules while the claim scope follows all of them Measured on the first gate-bounded fold (srv2 lane 7, CI at 006b0ef): ExpectedRedIdentityDidNotExecute count=39, every row in a module outside the gate roster; and v2.test.lens_vacuity.vacuity_test x5 ERROR no-such-function `rust_target_model_staging`, reproduced standalone with `gunbc run --entry src/v2/test/lens_vacuity/vacuity_test.dag`. The loader's both-closure (build_both_closure_edge_index) skips the bare scan for any source that declares import lines, so rung_3_4_common (one import) and leaf_model_verification's bare edge to v2.extdeps.languages.rust was never followed; under the whole-tree subject the flat channel found it anyway. The import is the form 10 of the 12 sibling callers already use; the loader/scope divergence is recorded in the PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The gate closure follows bare cross-module references from EVERY module, with the loader's own scanner, to a joint fixpoint with containment ancestors — the loader's both-closure bare-scans only import-free sources, while the claim scope the fold builds over the subject follows bare references from all of them; and route-gap expectations located outside the gate are withheld like the roster rows they join Measured 2026-08-29 on srv2: with the gate subject, `gunbc run` of v2.test.lens_vacuity.vacuity_test refused no-such-function `rust_target_model_staging`, then `eval_context` after the first was imported — one absent module per run, because rung_3_4_common (one import line) and leaf_model_verification reach them by bare reference and build_both_closure_edge_index skips the bare scan for any source that declares an import. The fixpoint reuses bare_reference_pull_paths_for_source, so the relation is the loader's and not a second scanner; the count of modules pulled this way is printed on the gate-closure line. Lane 8 (srv2) then refused `floor_route_gap_expectations: located identity is absent from derived roster` for an identity whose module is outside the gate: the roster had its outside-gate rows withheld and the expectations had not. Both sides now withhold by the same predicate, counted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * Cost-debt rows outside the required gate are withheld from the staleness join, route-gap expectations honour cost-debt withholding, and emit_on_demand_classical_not_native_one_build_holds moves to the cost-debt roster — it is budget-refused before it reaches the host effect its route-gap enrollment expects, on both hosts Measured on the first complete gate-bounded fold (srv2 lane 10 and CI at e8effe8, identical): verdict=FloorRefused with unexpected_failures=0 — no claim inside the gate fails — and two bookkeeping refusals: 122 STALE-COST-DEBT rows, every one in a module the gate never loads, and one STALE-ROUTE-GAP row whose claim ran past its CPU ceiling before reaching the effect. The first is the same out-of-scope population the expected-red and route-gap joins already withhold, now counted the same way. The second is a real cost debt (floor_cost_debt already records this claim at 502 -> 2374 ms), and cost debt wins over route-gap enrollment by the roster's own rule; the expectations decode now treats a cost-debt-withheld identity as dormant rather than absent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * Two lens_module_gate_witness rows leave the expected-red roster: under the gate-bounded subject both PASS on CI and on srv2, and the floor refuses a passing enrollment as STALE-QUARANTINE Measured at 1f4bda9 (CI) and srv2 lane 12: verdict=FloorRefused with unexpected_failures=0 and exactly these two STALE-QUARANTINE rows on CI. Both are "live" claims whose question ranges over the loaded corpus; under the gate closure that corpus is 2,021 modules rather than 4,260, and the population they were red on is outside it. That is a narrowing of what the claim observes, stated here rather than hidden: the whole-corpus receipts run is where the wider question is asked again. srv2 additionally passes four emit_host_* rows that stay red on the required host; those stay enrolled — CI is the oracle for the required gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * Eleven claims interrupted before verdict on the gate-bounded subject join the cost-debt roster as proven chunk 12 — the same eleven on the GitHub runner and on srv2, run after run At 92cc92e the floor reports verdict=FloorRefused with unexpected_failures=0, no stale rows, no now-passing rows, and eleven INTERRUPTED-BEFORE-VERDICT identities (cost_coverage_witness x3, loaded_carrier_receipts x3, lens_closure_question_zero_holds_live, green_control_sanctioned_reader_body_not_flagged, same_grammar_parse_ingest_bridge_holds, kotlin_grammar_parse_accepted, nominal_distinct_control_compiles_ok). The set is identical at e8effe8 and 1f4bda9 on CI and in srv2 lane 12, so it is a property of the subject, not of host load: on the gate closure these claims first-touch artifacts the whole-tree fold had warmed before reaching them. Declared here as the roster's own containment for a cost the ceiling cannot hold; the exit is the warm, as the roster's header states. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * lens_module_gate_holds_live joins cost-debt chunk 12: it was interrupted at 1076ms the run after its sibling was withheld, because the 1.07s pool-root module_path_index fill is billed to whichever consumer runs first CI 0829ad8: verdict=FloorRefused, unexpected_failures=0, one INTERRUPTED-BEFORE-VERDICT row. The claim-cost receipt reads budget_interrupted 1076ms for it and `[floor-shared-fill] cache=module_path_index key=.../src/v2/lens fill_ms=1070 paid_by=...lens_module_gate_holds_live consumer_claims=1`; at 92cc92e the same fill was paid by lens_closure_question_zero_holds_live (consumer_claims=2) and this claim passed. The index is keyed on a pool root the decl_facts seam asks for at claim time, so preparation cannot warm it ahead; with both consumers withheld nothing pays it. The roster's own header names the warm as the exit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The pool-root module_path_index for src/v2/lens is warmed in preparation by evaluating the declared producer once in its own module's scope — the 1.07s fill was a positional bill that interrupted a different lens_module_gate_witness live claim in each of three consecutive runs — and the two fill-only rows leave cost-debt chunk 12 CI 92cc92e, 0829ad8, 154fb1f: each run's single INTERRUPTED-BEFORE-VERDICT row was the next `lens_module_gate_witness` live claim in evaluation order, at 1068–1252ms, with the claim-cost receipt and `[floor-shared-fill] cache=module_path_index key=.../src/v2/lens` naming that claim as the payer. The witness-roots warm cannot reach a per-pool-root key; this warm evaluates `v2.lens.registry.completeness.lens_registry_completeness_live_facts` in that module's frame, so the root comes from `lens_registry_completeness_pool_roots` and the key is the consumers' by construction. Adjudicated with the other preparation warms as `ModulePathIndexBuild/lens-pool-roots`; skipped (printed) when the subject does not carry the producer; a producer that fails to evaluate refuses. The two rows whose entire cost was this fill leave chunk 12, as the roster header says they must once the warm exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * lens_closure_question_zero_holds_live leaves the expected-red roster: with the src/v2/lens pool-root index warmed in preparation it passes, as its two siblings did once they stopped paying that fill srv2 lane 13 at 8ad4091: `[floor-shared-fill] cache=module_path_index key=.../src/v2/lens paid_by=<outside-fold> consumer_claims=3`, no lens claim interrupted, and STALE-QUARANTINE for this row — the same row that was red only while it paid the fill (CI 92cc92e). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The four bootstrap_footprint_anchor claims join cost-debt chunk 12: 474–505ms CPU on three consecutive CI runs with no fill billed to them, so the 500ms ceiling decides them run by run CI f462bc9: planned=executed=2834, passed=2754, known_red_held=27, failed=0, no stale rows, interrupted_before_verdict=4 — these four, at 502–505ms. At 154fb1f the same four completed at 487–504ms and at 0829ad8 at 474–485ms; the run-to-run spread is the runner slot, not the claim. The gate did not change their cost — nothing in the shared-fill attribution names them — so the disposition is the roster's, not a ceiling change: withheld as declared debt until the host-load row lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The rust-unit-tests job runs the unit population: the lib tests that prepare or build over the live tree carry a live-corpus ignore reason and leave the required run, and the rot the first-ever `cargo test` exposed is repaired at its authorities, not hidden `cargo test -p v1-compiler --lib` had never run in CI. Its first run (33238828500) was cancelled by its own 60-minute timeout with 204 of 682 tests finished, because ~126 of the "unit" tests each build a fresh multi-entry index over `src/v2`+`dag` (4,260 modules; ~197 single-thread minutes on srv2 under nextest, 97 tests over 60 s, `self_compile_all_modules` alone 505 s), and the runner executes them serially. Those tests now carry `#[ignore = "live-corpus: ..."]` — the crate's existing `manual:` convention, one class, declared on the carrier — and the rung-drop row `required_gate_bankruptcy` names them by their instrument (`cargo test -p v1-compiler --lib -- --ignored --list`). The unit population runs in ~10 s after the compile (srv2: 537 passed / 136 ignored). Of the 44 failures the full run exposed, the 15 in the unit population are repaired where the fact lives: - REAL DEFECTS (two): `try_index_source_root_into_module_index` keyed files by their walked path, absolute since #9548 anchored the root, while the strict builder keys through `module_index_path_key` — the primary-precedence index disagreed with the strict one on every path; keyed through the same authority now. `try_build_module_index` carried `if root_idx > 0 { continue; }` before its collision refusal (from #7791), so a module declared in two roots shadowed silently in the builder named strict; the guard is gone and overlay callers have `build_module_index_primary_precedence`. - v1 TYPECHECK DEFECT: `declared_type_inhabitance` reads `params` as generic type parameters, which is exactly what a callable formal carries, so every higher-order call produced a counted advisory with a false reason (#9194); `direct_call_argument_inhabitance_diags` now excludes callable formals like its sibling `direct_call_arg_type_mismatch`. Mirror regenerated (two passes: the test blob lives inside the emitter). - STALE AUTHORITY ROWS after the #9637 reorg: 12 entry literals in `gunbc.ci_layer_roots` and 2 in `gunbc.offline_local_recipe` repointed; the two long-lane rows and one freeze row whose subjects 611fd02 and #9206 deleted are gone; the three freeze rows for relocated witnesses are DELETED rather than repointed, because the freeze gate defines relocation as growth and the roster may only shrink. `gunbc.non_fold_residue` receives the 22 sites it lacked and loses the 4 whose subjects moved or greened; its .dag twin therefore leaves floor_expected_red (it passes) and joins cost-debt chunk 12 (629 ms against the 500 ms ceiling, its whole cost the corpus scan it checks). - DELETED SUBJECTS: `cli_run::floor_witness_a_prove` (its runner, prove test and fixtures went with the FLOOR-Y cutover); the census pin tests and helpers for `docs/probes/census_extra_excludes.txt` (#9132 deleted every transcription). - EARLY ABORTS: three witness-admission tests and the roadmap jsonl-carrier test were "fast" only because they failed before their expensive step; with their inputs repaired they read the live tree for 2-4 minutes each and join the live-corpus class. - TEST ROT: the reorg rewrote a revision-addressed literal (`9ce6526c528:dag/gunbc/roadmap/...`) that must name the pre-reorg path; the method-existence witness anchored on a `Primitive()` row the frontier no longer holds. Not done here, receipts-lane rot for follow-ups: `test.claim.expectation_frontier_witness_test` names the deleted long-lane file; the affected-set kernel (`floor_diff_edits_from_diff_text`, `rerun_frontier_nodes_for_entry`, …) has no production consumer since FLOOR-Y and should go with its remaining fixture-dependent tests; the roadmap jsonl-carrier test takes 453 s and fails after its expensive step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 * The host-tool probe root carries the process id: temp_dir() is the host's shared /tmp on a self-hosted runner, and a fixed directory name collided with one another runner slot's uid left behind — PermissionDenied on two tests that had never run in CI before Found by the first green-by-duration run of the unit population (dc3ca52: 533 passed, 2 failed, 9.59s). The same class as the shared-/tmp emit_on_demand collision on srv2: a test that writes a fixed path into a location the process does not own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2 --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Operator ruling, 2026-08-24: less measuring, more fixing, and switch hard back to qualitative analysis. Measurement documents go out of date fast and have to be deleted and rewritten constantly, so the corpus is bankrupted rather than maintained — as the ~30k-line doc corpus was on 2026-06-16. History keeps it.
docs/probes/is deleted whole: 195 files, 50,601 lines. Boards, captures and instruments alike. No.shor.pysurvives anywhere in the repository outside.githooks.DECLARED CAPABILITY DROP (§4b(3))
This PR deletes a capability, not only artifacts, and that is a separate fact from the deletion of transcriptions.
8ab8a8e75af,CARGO_ERROR_TOTAL=218, which is what answered the operator when they asked today what the emission trajectory was doing..dagentry point that emits, assembles and compiles one entry and returns the coded-diagnostic population, cited by name wherever a board figure is quoted. The same figures become legitimate again unchanged at that point: the rule forbids transcribing output instead of naming an instrument, and today's defect is that there is no instrument to name. smart-ram-730 takes the entry point as follow-up; this PR is not held for it, because a model authored against a merge deadline is the throwaway work §6 prices.Why a declared row is the only mechanism: no dependent can refuse. Nothing in the corpus breaks when the board becomes unmeasurable, because the consumers are lanes, not modules. DESIGN already carries this exact shape as its own receipt — the regen cut re-derived a verifier, silently dropped the producer, owed a declared drop and filed none, and it did not surface because the author who needed the producer was outside the tree. Delete-first's census is structurally silent here, so the row is what is left.
Why, with the receipt that priced it
The affected-set emission board's mechanism A — its only row carrying measured status with an executed counterfactual — was already fixed when the board merged:
Eight seconds. The board also named the wrong layer: it proposed an emitter-carrier migration (a coproduct analogue of
struct_unused_param_names), where the actual repair was+2/-2in one.dagfile dropping parameters that appear in no payload — a model fix. Mechanism B on the same board is independently stale. Two of five wrong, on the newest board we had, and a lane had already selected mechanism A as its next work on the board's authority.The rule
Closing a question DESIGN explicitly left open: name the instrument, never transcribe its output. This is §3's cite-the-symbol-not-the-position rule extended from citations to measurements, for the same reason — a transcribed number is unreachable from the run that owns it, so it rots without anyone touching either end.
Why the instruments went too
Operator ruling: "we shouldn't have adhoc scripts in the repo — those would need to be written in .dag if they were really needed." An ad-hoc script implementing semantics expressible in
.dagis §6 unmodeled realization. If a measurement is worth re-deriving it is worth an entry point; if not, it was a one-off. This also resolves the rule rather than exempting it: keeping the scripts was a carve-out around a real hole — name the instrument is unsatisfiable if the instrument is deleted — whereas naming a.dagentry point gives the rule a live referent by construction.Ruled against a live objection, recorded because it was correct on its own facts and still lost. A peer had re-run one of these scripts that same hour, so they had real consumers — lanes, which a
.dag-consumer census cannot see, and which is why an earlier revision of this PR reported them as dead. The ruling grants the consumer and denies the carrier.What this does not claim
DESIGN.mdis not regenerated.dag/gunbc/design_document.dagcarries the authority edits; the projection is blocked on the same generator deadlock as Record the declined-home narrow as a second specimen: a red assertion about main, green by non-execution #9098, so the drift gate will flag it. Declared, not hidden.