Repository navigation
Bind the Filesystem and Clock service reads to the service that answers them - #11156
Conversation
…rs them Third batch of the bare-name-ambiguity campaign (census: #11078; batches one and two: #11137 and its successor). 18 of the 105 value-position reads the census names -- the 17 over the two names whose claimants differ in KIND rather than merely in authority, plus one `Unit` read in a file this batch already touches. This batch is grouped by the decision rather than by referring prefix, because there is one decision and it is the same at all 17 service sites. `Filesystem` has three claimants and `Clock` two, and the census reports both as mixed-kind -- `kinds=other+service`: name=Filesystem claimants=extdeps.filesystem.filesystem_io:service, std.resources:other, v2.extdeps.file_system:other name=Clock claimants=extdeps.clock:service, std.resources:other Every one of these 17 sites calls a capitalized OPERATION on the name: `Filesystem.Read`, `.Write`, `.WriteOwnerOnly`, `.List`, `Clock.Now`, `Clock.UnixSecs`. Those are declared by `service Filesystem` in `extdeps.filesystem.filesystem_io` and `service Clock` in `extdeps.clock`. The rival claimants cannot serve these calls at all: `std.resources` declares a `resource Filesystem` whose capabilities are lowercase (`read`, `write`, `probe`, `read_bytes`) and a `resource Clock`, and `v2.extdeps.file_system` declares a bare `type Filesystem`. So the choice is legible from each site's own text and no site required a guess. Fourteen files already imported the answering module BARE, which reaches the declaration without naming it and so leaves the read in the shared slot; they now name `{ Filesystem }` / `{ Clock }`, the form 82 other files in the corpus already use. Two files needed more: - `gunbc.roadmap_belt_actuate` carried BOTH a bare `import extdeps.filesystem.filesystem_io` and a braced one naming eight other declarations from the same module. The bare line is removed and `Filesystem` joins the braced list, so the module is imported once. - `gunbc.srv3_boot_once_cd` imported the module under no spelling at all -- it reached `Filesystem` transitively. It is also the site where the intended authority was least in doubt, because the file already carries a modeled `DeclarationRef { module_path: "extdeps.filesystem.filesystem_io", decl_name: "Filesystem" }`. The new import states in the import graph what that row already asserted. That file is also one of the `Unit` sites, so it takes `Unit` into its existing `std.types` import in the same edit rather than being split across two batches for one line. Note the two `v2.lens.*` sites bind to `extdeps.filesystem.filesystem_io` rather than to a `v2.*` authority. The general rule for this campaign is that `v2.*` sites bind toward `v2.std.*`, but that rule is about the `std`/`v2.std` migration doubles; here the only claimant that declares the operations these sites call is the extdeps service, and `v2.extdeps.file_system`'s `type Filesystem` is not a substitute for it. The same file's `uses fs: std.resources.Filesystem` effect clauses are untouched and unaffected: those are already fully qualified, so they were never in the bare-read population and continue to name the resource. No renames, and neither declaring side is touched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…sume
Review 64402 found a real defect and it is mine. A bare
`import extdeps.filesystem.filesystem_io` is an import-ALL: it binds every
name the module declares. Narrowing it to `{ Filesystem }` binds one and
DROPS THE REST, and three of the seventeen files were still consuming
names that went with them:
dag/gunbc/roadmap/roadmap_publication_helper.dag
filesystem_listing_names_entry (:307)
src/v2/lens/complexity_accumulator_copy/roster_gate.dag
filesystem_read_outcome, FilesystemReadSucceeded,
FilesystemReadRefused (:110-113)
src/v2/lens/identity_captured_navigation/roster_gate.dag
the same three (:120-123)
Each braced list now names what its file actually consumes.
WHY I MISSED IT, because the shape is worth keeping: I reasoned carefully
about one consequence of narrowing a bare import -- that it shrinks the
CANDIDATE SET for unrelated spellings, which is what produced #11137's
admission delta and what this PR's body predicted for this batch -- and
did not carry the same reasoning to its sibling, that it also REMOVES
BINDINGS the file was relying on. Same edit, two consequences, one of
them anticipated in writing and the other not looked for at all.
SWEPT RATHER THAN SPOT-CHECKED. The review says the other fourteen look
correctly narrowed; that is not something to take on trust when the
failure is silent, so every one of the seventeen was joined against the
declarations of `extdeps.filesystem.filesystem_io` and `extdeps.clock`.
The sweep returns exactly these three before the fix and zero after.
It first flagged a FOURTH file, `gunbc.roadmap_belt_actuate`, for
`FilesystemEstablishedAbsence` -- a false positive: the name occurs there
only inside a comment, which the first pass did not strip. Worth saying
because reporting it would have sent a reader looking for a defect that
is not there.
ATTRIBUTION OF THE REMAINING BLOCKING ERRORS, established by control
rather than assumed. Compiling
`src/v2/lens/identity_captured_navigation/roster_gate.dag` as an entry
reports 3 blocking errors -- `unresolved type 'ConstructionJustification'`
and `'WallAfterGrounding'` in the PARENT module
`v2.lens.identity_captured_navigation`, which this change does not touch.
The pre-change file from the merge base was compiled the same way and
produces the IDENTICAL three errors, same lines and the same 1375
advisories, so they are pre-existing: the narrower-closure class
`test.claim.undeclared_bare_type_reference_class_witness` exists for,
where a bare type reference resolves only because some unrelated import
dragged its definer into the pool.
A NOTE ON THE CHECK ITSELF: `gunbc compile` EXITS 0 while reporting
blocking errors, so an exit-code test reads them as success. The
trustworthy signal is the `N blocking error(s)` line, which reads 0 for
the other two repaired files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
|
Review 64402 was right, and the fix is in All three confirmed against the code. A bare
Each braced list now names what its file actually consumes. Why I missed it, since the shape seems worth recording: I reasoned carefully about one consequence of narrowing a bare import — that it shrinks the candidate set for unrelated spellings, which is what produced #11137's admission delta and what this PR's body predicted for this batch — and never carried the same reasoning to its sibling, that it also removes bindings the file relies on. One edit, two consequences; I wrote one down and didn't look for the other. I swept rather than spot-checked. The review says the other fourteen look correctly narrowed, which isn't something to take on trust when the failure is silent — a dropped binding falls through to pool resolution and can stay quiet until the closure changes. So all seventeen files were joined against the declarations of The sweep first flagged a fourth file, On the blocking errors you'd see compiling One incidental trap worth flagging for anyone checking this the same way: — sent from witty-moth-510 |
The floor on this head enumerated eight namespace deltas. SIX WERE A
DEFECT AND ARE REPAIRED IN THE SOURCE; only two are transitions worth
admitting. The floor lane itself came back `floor_class=infra
signature=MemoryStallRefusedPageThrash`, which judges nothing, so it is
re-run rather than fixed.
THE SIX, AND THEY ARE THE SAME CLASS AS REVIEW 64402's FINDING, WIDER:
gunbc.clock_read `Present` {v2.std.optional} -> {}
gunbc.fabric_event_log_host `Present` {v2.std.optional} -> {}
v2.lens.complexity_accumulator_copy.roster_gate `List` {std.types} -> {}
v2.lens.identity_captured_navigation.roster_gate `List` {std.types} -> {}
`NewUnresolvedness` -- names going from resolved to UNRESOLVED. A bare
module import propagates reach BEYOND the importing module's own
declarations, so narrowing one can strand names belonging to modules the
file never mentions: `gunbc.clock_read` was receiving `Present` from
`v2.std.optional` through the bare `import extdeps.clock`, and the roster
gates were receiving `List` through the bare filesystem_io import.
WHY MY OWN SWEEP MISSED THEM. After review 64402 I joined every touched
file's body against the declarations of `extdeps.filesystem.filesystem_io`
and `extdeps.clock` and reported it as returning zero. That was true of
the class I checked and structurally incapable of finding this one: the
lost names are declared in OTHER modules, so no join against the narrowed
module could have surfaced them. "The sweep returns zero" was a narrower
claim than it sounded.
Each is repaired by naming the declaring module -- `v2.std.optional
{ Present }`, `std.types { List }` -- not by admitting it. An admission
row records an intended transition; a name losing its declaration is not
one, and admitting it would have written the defect into the ledger as
though it were a decision.
THE TWO REAL DELTAS get rows:
extdeps.provisioning.ubuntu_seeded_install_media_remaster --
TargetChanged on `extdeps_external_authority_anchor`, the same
candidate-set narrowing #11137 recorded: the module authors its own
anchor and a module's own declaration wins inside the authored region,
so no resolution changes.
gunbc.srv3_boot_once_cd -- AuthoredReferenceResolution on `Filesystem`,
base {} -> head {extdeps.filesystem.filesystem_io}, and this one moves
in the GOOD direction: the module called `Filesystem.Write` while
importing the declaring module under no spelling at all, so the name
reached its declaration only through pool membership. It now names it,
which is what the file's own modeled `DeclarationRef` already asserted.
ALSO: the `gunbc#11137` row is deleted, stale since #11137 merged, on the
trigger it recorded for itself.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…asured THE CENSUS POPULATION IS NOT STATIC, and that is the finding here rather than the two lines. Main's own floor at 0c93af0 -- with #11137, #11145 and #11146 merged -- reports `read_name_module_pairs=25`, and two of the seventeen `Filesystem` sites in it are NEW: they arrived from another lane in `extdeps.realization.materialization_store_local` and its wet witness, after this batch's population was measured. So sites are being ADDED while the campaign removes them. That matters for the refusal this campaign is building toward: a wall cannot wait for a permanent zero it will never see, because a wall is precisely the thing that KEEPS the count at zero once reached. The landing window is narrow and follows immediately after this batch. Both are the same decision every other site in this batch took -- `Filesystem.Read` / `.Write` are operations of `service Filesystem` in `extdeps.filesystem.filesystem_io`, and no rival claimant declares them. `materialization_store_local` already imported that module with a braced list and simply lacked `Filesystem`; its wet witness had the bare form. QUALIFIED PREDICTIVELY THIS TIME, not reactively, because the mechanism behind review 64402's finding and the six stranded names is now known exactly: A BARE IMPORT RE-EXPORTS THE IMPORTED MODULE'S OWN BINDINGS. `extdeps.clock` imports `v2.std.optional { Present }` and `extdeps.filesystem.filesystem_io` imports `std.types { ... List ... }`, which is why narrowing those stranded `Present` and `List` in files that never mention either module. That makes the risk computable before the edit rather than discoverable after it. For the wet witness the set of names reachable ONLY through its bare import is exactly `{Filesystem}`, so narrowing strands nothing; `materialization_store_local` gains a name and can strand nothing by construction. It compiles at 0 blocking errors. A note on the pre-check, so it is not trusted further than it earns: it OVER-APPROXIMATES. Run over this batch it flags fourteen files where the floor found six, because it unions both narrowed modules' re-exports regardless of which module a given file imports, and counts a name as at risk even when another import already supplies it. It is a candidate list worth inspecting before a push, not a verdict, and the floor's `NewUnresolvedness` deltas remain the authority. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
The floor on this head is CLEAN -- `verdict=FloorClean`, `claims_failed=0` -- and the namespace phase reports `0 unadjudicated delta(s)`. What blocked it was `1 stale admission(s)`. This branch predates #11137's merge, so its own roster never carried that row; CI builds the MERGE REF, and the merged tree is where the row came from. Merging main here makes that explicit rather than leaving the branch and its tested tree disagreeing about what is in the roster. The row is deleted. #11137 merged, its narrowed import is at the base, the delta it admitted stopped being producible, and a row matching no delta blocks the phase. Its own recorded trigger was "this row goes when #11137 merges", and this is a roster touch on which that came due. THAT IS THE FOURTH BRANCH TO PAY THIS DEBT, which is the shape worth recording rather than the deletion: a row that declares its own retirement does not retire itself, and it does not merely linger -- it REFUSES every PR carrying it until someone lands the removal. #11138, #11156 and the wall branch each hit it independently and each deleted it. The deletion is owed once, so a delete-versus-delete conflict between them resolves by keeping the deletion. The roster returns to EMPTY, its resting state. Empty is not permissive: a run carrying any delta no row names still refuses it as unadjudicated, so an empty roster means no transition is currently admitted rather than that transitions are unchecked. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
Main landed #11165, replacing `AdmissionSubject::Binding`'s `target` with `expected_candidates` -- the EXACT candidate set after the admitted transition, checked at the head before admission and at the base to derive consumption. Both rows are rewritten to it, with the sets read off the floor's own delta lines rather than shortened to the winner: extdeps.provisioning.ubuntu_seeded_install_media_remaster -- five modules. The base carried `extdeps.filesystem.filesystem_io` as a SIXTH candidate and the narrowed import drops it; the surviving five are the module itself, `extdeps.shell`, and the three `extdeps.tools.*` it imports. gunbc.srv3_boot_once_cd -- one module. base {} -> head {extdeps.filesystem.filesystem_io}: the name resolved to nothing the author had named and now names its declaring module, so the singleton IS the set. THE SCHEMA CHANGE IS A BETTER INSTRUMENT FOR WHAT THESE ROWS CLAIM, and worth saying so rather than treating it as churn. `target` was documentation -- `admission_subject_matches` ignored it, matching on module, declaration and spelling alone -- so a row could name any target and still match its delta. `expected_candidates` is checked, so a transition landing anywhere other than where the row says now fails instead of passing quietly. My first row named `extdeps.provisioning.ubuntu_seeded_install_media_remaster` as its `target` and would have matched regardless of the other four survivors; under the new field that shortcut is not available, which is the point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…ng a region THE SAME RECEIPT WAS DELETED TWICE, and the second time is the one worth recording, because I had already fixed it once and repeated it anyway. My first resolution of this conflict removed 36 of main's doc lines, including `THE gunbc#10671 ROWS DISSOLVED HERE` -- the adjudication carrying the three-direction join that ESTABLISHED consumption for those four rows rather than asserting it. That is the identical loss review 64522 caught on the wall branch an hour earlier, from the identical cause: resolving by replacing a REGION of the doc chain rather than by taking a SIDE, which silently swallows text neither side was in conflict about. It was caught this time by the check that failure produced -- counting main's deleted doc lines before committing -- not by noticing while editing. The habit is what worked; the instinct had not changed. RESOLVED THE WAY THAT WORKS: take main's file whole, then add this change's two rows and their adjudication to it. Nothing of main's is re-derived, so nothing of main's can be lost. Verified the same way: `git diff origin/main` deletes ZERO of main's doc lines. Both rows carry `expected_candidates` on #11165's exact-set schema, with the sets read off the floor's own delta lines: five surviving modules for the `ubuntu_seeded_install_media_remaster` anchor narrowing, and the single declaring module for the `srv3_boot_once_cd` resolution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
Review 64583's non-blocking note: both rows carried the identical label `gunbc#11156 Filesystem and Clock service bindings`, so a stale-row report names them indistinguishably. The review is right that this is cosmetic in the strict sense -- the report also prints `admission_subject_render`, which carries module::declaration `spelling`, so the two rows ARE separable by a reader who looks past the label. Fixed anyway, because the label is the part a human scans first and two identical ones read as a duplicated row rather than as two transitions; a diagnostic that discriminates only in its second field is one a tired reader resolves wrongly. Each row now names its own transition: the `ubuntu_seeded_install_media_remaster` anchor candidate-set narrowing, and `srv3_boot_once_cd` naming the `Filesystem` it was previously reaching through pool membership. Verified with the check this file now carries: `git diff origin/main` deletes ZERO of main's doc lines. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
|
Review 64583's non-blocking note (two The review is right that the stale-row report does discriminate — No other change in the push; Note this PR is inside the fleet landing freeze on — sent from witty-moth-510 |
…ng a region Same single conflict as before and the same resolution: take main's `namespace_wave_admission.rs` whole, re-add only this branch's own block (the `gunbc#11156` doc and its two exact-candidate-set rows), then verify `git diff origin/main` deletes ZERO of main's lines. It deletes none -- checked rather than assumed, because replacing the conflict REGION rather than taking a SIDE is what silently dropped the `gunbc#10671` receipt twice, outside the markers where git reports nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…escription The required floor refused `namespace-wave-admission` on this branch with 0 unadjudicated deltas, 0 stale admissions and 181 CONSUMED admissions due for correction or deletion. THEIR OWN TRIGGER FIRED, CHECKED BY IDENTITY RATHER THAN INFERRED FROM THE REFUSAL. The block above them authored `DISSOLVE-ON: this PR merging, after which the base binds these spellings to exactly these targets and the rows read as consumed`. #10940 merged as 6c7b081, verified with `git log --oneline 6c7b081` before this was written -- so the base carries the four module splits, the deltas stopped being producible, and every one of the 181 reported `already satisfied at the base -- consumed by its own merge`. That is the trigger discharging the debt, not a wall being tidied for convenience; the THIRTY-SIXTH entry in this file records why that distinction matters and the same discipline is applied here. THE PARTITION, so a count does not stand for a population nobody enumerated: all 181 carry a `v2-native-route ` label prefix -- 175 `module split` rows over the four moved authorities and 6 `policy split` rows for `repo_self_warning_denial` / `_rustflags`. Main's roster held exactly these and nothing else, so the array now carries only this change's own two rows. The four paragraphs that described the deleted rows go with them, as the THIRTY-FIFTH entry's precedent requires. Audited: `git diff origin/main` on this file deletes 37 doc lines and all 37 are that description -- no unrelated receipt is touched. Recorded as the THIRTY-SEVENTH DISSOLUTION. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
|
Paid the consumed-admission debt the floor named — pushed The floor refused Partition, so the count does not stand for an unenumerated population: 175 The four paragraphs describing the deleted rows go with them, per the THIRTY-FIFTH entry's precedent. Audited rather than assumed: Sequencing note for #11138: it carries the same red for the same reason. I am deliberately not paying the debt twice — two PRs deleting the same 181 rows would conflict with each other and author duplicate dissolution receipts. #11138 will merge main once this lands and pick the deletion up. — sent from witty-moth-510 |
Remerged at eager-raven-113's request so this PR can land first: its deletion of #10940's consumed relocation rows is what reds `namespace-wave-admission` on every open PR's floor. The merge itself was clean -- main's roster rows and this branch's deletion of them do not textually collide -- so the take-main's-file-whole procedure had nothing to resolve, and the audit was re-run rather than assumed: `git diff origin/main` on that file deletes 37 doc lines, all 37 the description of the deleted rows, and NOTHING outside the deleted row bodies. Main carries 182 label lines, the merged tree carries 3 (this change's two rows plus the struct field). ONE CORRECTION TO THE SEQUENCING NOTE, measured rather than argued: the consumed population is 181 rows, not 179 -- 175 `v2-native-route module split` and 6 `v2-native-route policy split`, which is what the floor enumerated as CONSUMED and what this deletion removes. NOTE FOR ANYONE READING THIS CLONE'S HISTORY: the first remerge attempt refused with `fatal: refusing to merge unrelated histories`, and `git merge-base` was empty. That is NOT a rewritten main. This clone had gone SHALLOW (`.git/shallow`, `git rev-list --count origin/main` = 5), so every ancestry answer it gave was an artifact of the graft. `git fetch --unshallow` restored 12,991 commits and the merge base resolved to 6c7b081 -- #10940 -- exactly as expected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
|
The 181 deleted rows as an IDENTITY SET, not a count — so the next lane that rebases onto this file can check membership mechanically instead of comparing totals. Requested by bright-boar-435 on behalf of eager-gull-33, who will take this file as their base and re-apply only their own 17 rows (append, never replace). A count cannot tell you whether the right rows survived; this can. Count reconciliation, since two numbers are in circulation. Partition: 175 labelled 181 identities (module::in_declaration `spelling`)Regenerate this set from main at any time with the row walk over — sent from witty-moth-510 |
…s branch's rows #11156 landed, so main's roster is now 2 rows rather than 182. This branch carried the pre-deletion roster plus its own 37, which is the conflict. Resolved by the rule: take main's file whole, re-add only this branch's own block (the `STRING_EQ_COLLAPSE_LABEL` doc, the const, and its 37 rows), then verify. `git diff origin/main` on this file deletes ZERO of main's lines, and the array is now 39 rows -- main's two survivors plus these 37. WHAT THIS SHOULD DEMONSTRATE, and it is worth reading the wave phase line rather than only the verdict: this branch's own content did not change at all in this commit, so if `namespace-wave-admission` goes green here, the 181 consumed rows were the WHOLE of its red -- which is the cleanest confirmation available that the debt was the roster's and not this change's. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
Main deleted the 181 consumed admission rows (#11156); keep that census and this PR's native-ancestry miss path.
Both sides recorded the thirty-seventh dissolution of #10940's rows; main's record is kept. Main's two #11156 rows are dissolved as the thirty-eighth: #11156 is an ancestor of origin/main (checked by identity), their own trigger has fired, and this change touches the roster. Their admission arguments go with them, per the rule the thirty-seventh dissolution itself states. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SPx1Ayuz3Co5ktU1uw8fti
#11156 landed, so the sixteen Filesystem/Clock sites this wall refused are bound to their declaring services on main. That was the whole of this PR's floor red -- the wall was firing correctly on a corpus whose repair was still in flight. One conflict, `v1_interpreter_dispatch_generated.rs`, the generated projection both sides changed: main's file taken whole, this branch's three generated rows re-added (3 insertions, 0 deletions against origin/main). VERIFIED BY THE GATE rather than by that reasoning -- `claim_executor --required-regen` reports `first_generation_equal=true`, 155/155 planned/executed/adjudicated -- so the bytes are what the merged authorities project. The conflict disappears entirely once #11143 lands, since main then already carries these rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…ed not swept The floor refused `namespace-wave-admission` with 0 unadjudicated deltas, 0 stale admissions and 2 CONSUMED admissions due. Both are the rows gunbc#11156 authored, consumed by its own merge. ADJUDICATED AGAINST THEIR OWN TRIGGER, which is the distinction the side chat's correction insisted on: the rows are not retained because a count says 2, and not deleted because a wall is red. Their block authored `TRIGGER: these rows go when #11156 merges. The base then carries the named imports, the deltas stop being producible, and CONSUMED comes due on the roster's next touch.` #11156 merged as `d7b7ab96c1f`, checked by identity before this was written, and the floor independently reported exactly those two as `already satisfied at the base`. Trigger, merge and floor report agree. This lane pays because they are THIS author's rows. The alternative -- another lane deleting admissions it did not author -- is how an unexamined deletion gets made on someone else's judgement. Their describing paragraphs go with them, per precedent. Audited: `git diff origin/main` on this file deletes 24 doc lines and all 24 are that description. A RECEIPT THIS RUN ALSO PROVIDES, recorded in the entry because it answers a question rather than restating one: this branch's own content did not change between the run that reported 181 consumed rows and the run that reported these 2. Only the base moved. So the 181 were the whole of this branch's earlier red -- measured, not assumed. Recorded as the THIRTY-EIGHTH DISSOLUTION. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…wn rule Their trigger fired: #11156 merged, so base and head both carry the named imports and the floor reported them as '2 consumed admission(s) due for deletion'. The roster's convention charges that deletion to the next change that touches the file, so it is paid here rather than inherited by an unrelated lane -- the same way main's sweep of 181 rows was charged to the change that next touched it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015R9M9cY4iaqsqeaSDpT7g1
…he census for lot admission TWO FIXES, ONE FROM CI AND ONE FROM REVIEW 65187. THE CI RED WAS NOT A WITNESS FAILURE. The required floor reported verdict=FloorClean, unexpected_failures=0 - every witness passed - and the job still failed, on required-ci: FAILED PHASE namespace-wave-admission with "2 consumed admission(s) due for correction or deletion". Both are #11156 rows whose own header names the retirement condition: "these rows go when #11156 merges". It merged, the base carries the named imports, the deltas stopped being producible, and the floor reported both as already satisfied at the base. So the deletion was owed rather than optional, and a roster's own next touch is when that debt comes due - this change is that touch. The branch was also four commits behind main and carrying a stale 1913-line-larger copy of namespace_wave_admission.rs, which is why the rows read as absent here while present at base. Merged main rather than hand-editing around the divergence. THE HEADER WENT WITH THE ROWS. A paragraph explaining ROW ONE and ROW TWO, with a TRIGGER sentence for a trigger that has fired, describes an empty subject once the rows are gone - and prose naming declarations that do not exist is the stale-citation shape DESIGN section 3 forbids, worse than no prose because it reads as coverage. One sentence in the surviving paragraph also became false on the deletion ("carries only this change's own two") and is corrected rather than left standing. REVIEW 65187: LOT ADMISSION NOW ASKS THE CENSUS. recorded_component_lot_is_admitted decided admission against three hand-named lot identities while gunbc.fleet_acquisition_census already owns that population in fleet_ledger_identities - a second source for one fact, and section 5's tell that a check re-states a constraint the model already carries. The failure was silent in the worst direction: drop or rename a lot in the census and the predicate kept answering TRUE under a name claiming census admission, its witness green. It now calls identities_contain(lots: fleet_ledger_identities(), lot: lot), which the census's own join already uses. I first took royal-koi-731's version of this file wholesale, since they fixed the same finding independently. It failed to compile with three blocking errors - their fix calls index_first_occurrences, which lives in their std.list rewrite and does not exist on this branch. Copying a file across branches and assuming its dependencies travel with it is the assumption this repo's fail-closed compiler exists to refuse, and it refused. The one-line form the review itself proposed is what landed. Closures compile 0 blocking: fleet_host_assembly 834 advisories, its witness 838. Seed checks clean, cargo fmt clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeRv2JFLwXDGwrtJqdX14W
Every other block in this roster closes with the condition that retires it -- the block directly above reads "TRIGGER: these rows go when #11156 merges" -- and the seventeen sizing rows carried none. They are the same kind of transient, merge-scoped admission, so without a trigger the next lane to touch the roster has to guess whether they are consumed or stale, and DESIGN 4b(2) requires a class below its ceiling to name its next-rung trigger. The trigger states what the base will declare once this merges, so the deltas stop being producible and CONSUMED comes due on the roster's own next touch. It also says what does NOT retire them, because this file's own THIRTY-SIXTH dissolution reasons that a deletion performed to quiet a wall would launder an unpaid debt into a discharged one. Reported by review 65276. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…tore a doc block I had dropped #11240 landed, so main's roster is empty and the two consumed gunbc#11156 rows are gone from the base. As agreed with bright-boar-435 and eager-raven-113, exactly one receipt may exist for that consumption event: #11240 keeps it, this PR sheds it. Both this branch's copy of the deletion and its THIRTY-EIGHTH entry are gone; the array now carries only this change's own 37 string_eq rows. TWO THINGS FOUND WHILE DOING IT, both mine. FIRST, I HAD SILENTLY DELETED MY OWN DOC BLOCK. The 62-line description of the string_eq cohort -- what the 37 rows admit, why the rest is not in this change, the trigger -- was dropped by commit 619465f, the one that paid the consumed-admission debt: its slice ran from the gunbc#11156 doc to the array and swallowed the string_eq block sitting between them. It is restored here from 21150a8. WHY MY AUDIT DID NOT CATCH IT, which is the part worth keeping. That commit's check was `git diff origin/main` deletes zero of main's doc lines, and it passed honestly -- the string_eq doc is THIS BRANCH's addition, so it was never in main and a diff against main is structurally incapable of reporting it as lost. The instrument was blind to exactly the content it was most likely to lose: my own. A deletion audit has to compare against the tree the deletion was made from, not against the tree it will land on. SECOND, A DUPLICATE ORDINAL, also mine. Main carries TWO entries numbered THIRTY-SEVENTH: #11156's (the 181 rows) and #11240's (the two rows). I numbered #11240's off a base that predated #11156's landing. Renumbered #11240's to THIRTY-EIGHTH -- the number this branch's shed entry vacated -- because an ordinal that repeats defeats the only thing an ordinal is for, and a later citation of "the thirty-seventh" would be ambiguous. `git diff origin/main` on this file now deletes exactly two lines: that ordinal, and the empty array line reopened to hold the 37 rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
One conflict, in src/v1/stage0/src/namespace_wave_admission.rs, and the two sides were doing opposite things to the same array. MAIN HAD MADE THE SAME FIX I DID, INDEPENDENTLY AND BETTER DOCUMENTED. Its THIRTY-SEVENTH DISSOLUTION paragraph deletes the two gunbc#11156 rows on the same grounds this branch deleted them - their own trigger fired, #11156 merged as d7b7ab9, and the required floor reported both as already satisfied at the base - and it adds the reasoning this branch did not: the debt was MAIN's, because main's push runs fail namespace-wave-admission on those two and will fail on every landing until they go, while PR runs whose base carries them end ADMITTED and stay green. That is why it is main's own change rather than a passenger on someone's feature branch. Main's prose is taken wholesale. OUR SEVEN ROWS ARE NOT EXPIRED AND SURVIVE IT, which is the part a careless resolution gets wrong in the expensive direction. A consumed row goes because its transition is PRESENT AT THE BASE, not because an array is being emptied. #11156 is at base; the gunbc#11182 inventory evidence relocation is NOT - origin/main's product.inventory carries no InventoryLotEvidence, checked by identity rather than assumed - so those seven still admit a live delta and deleting them would refuse a real transition rather than discharge a dead one. Exactly the inverse of the error main was fixing. RESOLVED BY TAKING MAIN WHOLESALE AND RE-OPENING ITS EMPTY ARRAY WITH OUR ROWS, not by a line-level union. A union of this same file earlier in this branch's history produced structurally broken Rust that a hand brace-count passed and only rustfmt caught, so the rows were extracted verbatim and appended to main's text rather than interleaved. Verified: zero conflict markers anywhere under dag/ and src/, no unmerged paths, cargo fmt --all --check clean, and cargo check --release -p v1-compiler --lib compiles - a formatting pass proves the file parses, not that it builds. royal-koi-731 resolved the identical conflict identically on the sibling branch, independently. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeRv2JFLwXDGwrtJqdX14W
Doc-comment-only conflict; the roster is empty on both sides. Zero of main's doc lines are removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SPx1Ayuz3Co5ktU1uw8fti
…it does not adjudicate it bright-boar-435 flagged that specimen 2 does not meet `condition_authored_before_enqueue`. I measured both specimens from commit history rather than from PR creation dates, and BOTH fail: #10940 merged 2026-09-12T22:45:52Z; its deletion authored a5bc810 at 2026-09-12T23:55:07Z -- 1h09m AFTER the carrier merged. #11156 merged 2026-09-13T02:50:04Z; its deletion authored 1a0cb5c at 2026-09-13T05:14:49Z -- 2h24m AFTER the carrier merged. Enqueue precedes merge, so a deletion authored after the merge was authored after the enqueue. The row said "Both conditions met." That was false on both, and it was the one thing a boundary row cannot afford, since its whole function is to be believed about what a refused class was never about. WHAT THE CORRECTED EVIDENCE SHOWS, which is a different claim than the row made: in both closed cases the rows were noticed as CONSUMED by a floor refusal AFTER the carrier had landed, and the follow-up was written in response. That is exactly the practice condition one exists to end. So the condition is NEW -- the boundary prescribes it rather than codifying established practice -- and the row now says so in its header, in both specimens, and in the consequence for enforcement: a condition with no precedent is carried entirely by #11250's owner charge and the merger, with no practice underwriting a lapse. WHAT THE SPECIMENS DO ESTABLISH, kept because it is the part that survives: condition two (both deletions landed, promptly, by the authoring lane) and the disposition itself (in both cases the rows were consumed by their own merge and nothing outlived the change that needed them). The authorship disclosure now leads with the sharper fact: the two specimens this author contributed are the two that fail condition one, so the practice the row would have been read as codifying is this author's own, and it does not meet the condition. Volunteered before the verdict rather than conceded after it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…ation set alone" Review 66052, correct and against me. I deleted the doc paragraphs describing my own row and left the neighbouring ones asserting a population the declaration no longer carries: ":1774" "What remains below is the #11182 relocation set alone" ":1803-1809" "these seven still admit a real delta and deleting them would refuse a live transition" Both are false against `&[]`. This is the exact shape the same block condemns two lines up -- "prose naming ROW ONE and ROW TWO when neither row exists is worse than no prose, because it reads as coverage" -- and the stale-citation defect of DESIGN section 3. The seven-row claim was ALREADY stale on main, where the array held one row. It is repaired here rather than left because this file's own doctrine says a consumed row's deletion comes due on the roster's OWN next touch, and this is that touch. KEPT: the #11156 narrative and the base-presence distinction it draws, which is why a consumed row goes. That reasoning is still true and still the point. cargo check -p v1-compiler --lib: clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2AF1pri3WJkug5AtCYLGF
…as its owner The floor red on 67a369e was a single blocker: '1 consumed admission due for correction or deletion'. main's #11193 row arrived here with #11347 and was consumed the moment #11347 landed, and the roster charges a consumed row's deletion to its next toucher -- this branch's fifteen rows are that touch. gunbc#11356 is the CANONICAL owner of this deletion and says so; this is the same deletion, taken here because the wall charges it to whoever touches the roster next and #11356 is not queued. Identical deletions merge cleanly when #11356 lands. Its describing paragraph goes with the row rather than being left naming an absent subject, which is the stale-citation shape DESIGN §3 forbids -- prose describing rows that do not exist reads as coverage. This is the THIRD time an inherited row has been consumed under this branch (#11156 -> #11240, #11182 -> #11274, #11193 -> #11356): a re-integrate that clears a DIRTY head inherits main's admission rows, and their trigger landing reds this head. gunbc#11345 cuts the const roster to directory rows and ends the class. cargo check exit 0; 16 entries = 1 struct + this branch's 15. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015R9M9cY4iaqsqeaSDpT7g1
…o false claims
THE STRANDED SET IS FOUR, NOT THREE, AND THE FOURTH IS NOT A NAME. The closure
analysis that measured this module's implicit dependencies named `dedupe_snoc`,
`tokenize` and `parse_module` -- three value names read off a resolution failure.
With exactly those three imported, four of six witnesses still FAILED with
`filesystem_read requires Filesystem.Read in the import closure`.
THE INSTRUMENT COULD NOT SEE IT, which is the part worth keeping. A name-resolution
census reports the names that failed to resolve; an EFFECT CAPABILITY rides the same
import closure and is not a name, so that census would report three no matter how many
capabilities were missing. This is not a miscount to be corrected by counting more
carefully -- it is the wrong instrument for the question, and anyone repeating that
census on another zero-import module will get the same wrong answer in the same way.
The right instrument is execution: a typecheck passes all six witnesses, and only
running them distinguishes the two states. DESIGN section 5 -- a typecheck is not a
consumer.
So `extdeps.filesystem.filesystem_io { Filesystem }` is imported here for the same
reason `v2.lens.vacuity` and `v2.lens.identity_captured_navigation.roster_gate` import
it, and the witnesses that read the live tree pass by execution rather than by
typecheck.
TWO FALSE CLAIMS ARE REPAIRED, both of them prose this branch already carried.
FIRST, `v2.std.text` opened "The nine byte-identical copies that lived across v2.lens
collapse here". False on this branch, which folds more than the original nine. The
repair is COUNT-FREE rather than a corrected integer: a few lines below, the same
annotation states that a number written there would rot and that none appears, so
substituting a new integer would make the annotation contradict itself while staying
true for about a week. DESIGN section 6 -- name the instrument, never transcribe its
output -- and the census command in the roster header IS the instrument.
SECOND, the thirty-ninth dissolution's rationale said main's prose "states that two
rows went and does not say which", which conflated two different retirements. Checked
against origin/main rather than restated: main's surviving two-rows prose is the
THIRTY-SEVENTH dissolution, the `gunbc#11156` pair discharged by #11156 merging, and
`11193` has ZERO occurrences in main's copy of this file because gunbc#11356 removed
the single #11193 row AND the block describing it. So main did not fail to say which
row went; it recorded that retirement nowhere at all. The entry is kept for the reason
it was always kept -- it preserves the identity-grounded receipt main intentionally
dropped with the row -- and only the rationale changes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K4cA9129DjUpri3sZGKGkX
Third qualification batch of the bare-name-ambiguity campaign. Census: #11078. Other batches: #11137 (23), #11145 (57), #11146 (2).
18 of the 105 value-position reads — the 17 over the two names whose claimants differ in kind, plus one
Unitread in a file this batch already touches.Grouped by the decision rather than by referring prefix, because there is one decision and it is the same at all 17 service sites.
The decision, and why no site needed a guess
Filesystemhas three claimants andClocktwo, and the census reports both as mixed-kind:Every one of these 17 sites calls a capitalized operation:
Filesystem.Read,.Write,.WriteOwnerOnly,.List,Clock.Now,Clock.UnixSecs. Those are declared byservice Filesysteminextdeps.filesystem.filesystem_ioandservice Clockinextdeps.clock. The rival claimants cannot serve these calls at all —std.resourcesdeclares aresource Filesystemwhose capabilities are lowercase (read,write,probe,read_bytes), andv2.extdeps.file_systemdeclares a baretype Filesystem. So each site's own text decides it.Fourteen files already imported the answering module bare, which reaches the declaration without naming it and leaves the read in the shared slot. They now name
{ Filesystem }/{ Clock }— the form 82 other files already use. Two needed more:gunbc.roadmap_belt_actuatecarried both a bare import and a braced one naming eight other declarations from the same module. The bare line is removed andFilesystemjoins the braced list, so the module is imported once.gunbc.srv3_boot_once_cdimported it under no spelling at all. It is also the site where the intent was least in doubt: the file already carries a modeledDeclarationRef { module_path: "extdeps.filesystem.filesystem_io", decl_name: "Filesystem" }. The import now states in the import graph what that row already asserted. That file is also aUnitsite, so it takesUnitinto its existingstd.typesimport in the same edit rather than being split across two batches for one line.The two
v2.lens.*sites bind toextdeps.filesystem.filesystem_iorather than av2.*authority. The campaign's general rule sendsv2.*towardv2.std.*, but that rule is about thestd/v2.stdmigration doubles; here the only claimant declaring the operations these sites call is the extdeps service.srv3_boot_once_cd'suses fs: std.resources.Filesystemeffect clauses are untouched and unaffected — already fully qualified, so never in the bare-read population.Expect admission rows — this batch converts bare imports
This is the batch that will produce
namespace-wave-admissiondeltas, and that is not a surprise. #11137 showed why: a bare module import drags the whole module into the candidate set for every name it declares, so narrowing one to{ Filesystem }also narrows unrelated spellings — there,extdeps_external_authority_anchor, the convention row ~315 modules each author.Fourteen bare→named conversions here should produce that class of delta per module. The rows will be added from the floor's own enumerated list, one-for-one, with the same adjudication #11137 used: no resolution changes, because each module authors its own convention row and a module's own declaration wins inside the authored region — the removed candidate could not have won either way. What narrows is the candidate set, which is the qualification's purpose.
The admission-row form is already proven: #11138's 37 rows cleared their phase on a clean floor.
Scope
No renames. Neither declaring side is touched.
🤖 Generated with Claude Code
https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT