Repository navigation
Scope rank-view step 2: the carriers and their executing equivalence laws - #11665
Conversation
…laws Step 2 of docs/plans/scope-rank-view-design.md section 8. The model landed as #9825 with no seed consumer; this lands the carriers BESIDE the fold and the laws that make them consumed rather than dangling (DESIGN section 3c). No reader moves and no map is deleted -- section 8 forbids a leaf-first cutover, so the readers and the materialized maps go together in step 3, in one motion. WHAT THE CARRIERS ENCODE. A per-scope winner map stores the answer to "of the subject's declarers of this key, which one ranks first in this scope?". That answer is already determined by two facts held upstream: the subject-wide claimant relation, and the scope's ordered admission. There is no single winner to share across scopes -- the winner legitimately differs with order -- so DESIGN section 2's "carry the first value" applies to the CLAIMANT RELATION, and the winner is derived from its join with rank at the ask. `PreparedClaimScope` now retains `scope_order` and `authored_region`. Both were already computed here -- `scope_identity` folds over `order` and the registry fold reads `authored_region` -- and were discarded once the maps they decided were built. They are moved rather than recomputed, so nothing can derive a different order. SCOPED TO ONE SLOT. `gunbc.scope_rank_view` records six slots at three polarities; `service_ops` and `file_module_paths` resolve HIGHEST rank while `item_registry` resolves lowest. A uniform cutover is silently wrong, so the remaining slots land with their own laws rather than by generalizing this one. THE LAWS EXECUTE THE REAL FOLD via `claim_scope_for_without_memos`, and compare the winning `ItemInfo` by `Rc::ptr_eq` rather than by `module_name` -- the fold's own comment records a control catching that `module_name` is not the module-path spelling the inventory carries. Four laws, all green: - the fixture ranks one colliding name oppositely (positive control, asserted first: without it every assertion behind it would hold against a view with the polarity inverted) - the rank view resolves every name as the fold does, in both scopes - authored winner / later unauthored claimant: no ambiguity recorded - unauthored winner / later unauthored claimant: ambiguity recorded, with its own control proving the legacy census is non-empty first A PHASE BOUNDARY FOUND BY A FAILING FIXTURE, recorded in the module doc because step 3 needs it: `AmbiguousBareNameRead` and the ambiguity census are distinct mechanisms over one structural collision. Reading an ambiguous bare name makes `claim_scope_for` REFUSE, so no scope reaches any reader; the census is exactly the residual collisions no accepted bare read selected. An ambiguity-census reader is therefore not enforcing that refusal, and step 3 must not let the census become a substitute implementation of it. Also in this commit, and unrelated to the migration except that it misdirected a review of it: docs/plans/cli-run-reconcile-defork.md claimed `reconcile_with_typed_cache` is keyed by `mod_name`. True when written, false on main -- `shared_typecheck_store` states the keys are content keys "never authored module names", with per-content-key compute guards and a witness at `src/v2/test/claim/interface_summary/typed_module_key_test.dag`. The stale row caused a review to derive a false-hit hazard that does not exist. And docs/plans/floor-aggregate-cost-authority.md: the floor has a rich per-item cost model (evaluation_budget, enrolment_margin, floor_cost_debt, floor_cost_distribution) and no population model, so its total is a quantity no declaration carries and no change is charged against. Proposal only, no code. NO PERFORMANCE MAGNITUDE IS CLAIMED. The migration's oracle is a paired required-floor run with [floor-bare-name-ambiguity] byte-identical, which is a CI job; nothing here measures one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Equivalence-law receipt — the evidence CI does not produce
Working tree clean, Reproduce: What the two controls buy, since "4 passed" alone would not say
That second control is also what found the phase boundary in the PR description: my first fixture read the colliding name bare, and Not claimed hereNo performance magnitude. The migration's oracle is a paired required-floor run with |
…w 68008)
DESIGN section 6: "Name the instrument, never transcribe its output ... a
transcribed number is unreachable from the thing that owns it, so it rots
without anyone touching either end."
The proposal declined to assert the growth slope on exactly that ground, then
copied four other readings into prose as standing quantities. The reviewer is
right that these were the worst possible ones to transcribe: the migration-debt
baseline is the figure the whole policy is denominated in, so it would have
decayed while the policy kept quoting it.
No floor-duration instrument exists to name -- `gunbc.instrument_targets` carries
self-host, heads-reading-differential and evaluation-store-address-exact-head,
and none of them measures a floor run. Section 6's own disposition for that case
is followed rather than worked around: "if it is not worth an entry point it is
not an instrument but a one-off."
- declared migration debt: no longer a number. Read from the
`required-witnesses-floor` job of `gunbc.witness_floor_workflow` at the
revision the authority lands.
- the 46-54 sentence downstream of it: rephrased to "the observed figure", so
the argument no longer depends on a quantity it does not carry.
- unattributed remainder: labelled explicitly as a ONE-OFF reading, with how it
was taken (summing `done in` stage lines against `[floor-phase]` seams in one
run's log) and the statement that no entry point re-derives it.
- population and routing figures: replaced by their producers -- a `git grep`
over any two revisions, and the floor's own `required-floor: declared=N
offered=N routed=N` census line from `v1_compiler.bin.claim_executor`.
- header: the two run IDs now say explicitly that they locate where a reading
was taken and are not doing a producer's work.
The 20-minute target and 30-minute ceiling stay as bare figures: section 5 admits
an explicit policy budget, and they are authored policy rather than measurements.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Fixed in The worst one was the one the policy depends on. There is no floor-duration instrument to name.
The 20-minute target and 30-minute ceiling stay bare, as you noted — §5 admits an explicit policy budget, and those are authored policy rather than measurements. One consequence worth stating: the debt bullet now carries no number at all, which is a slightly stronger position than "name its producer." That's deliberate. A migration-debt baseline that this proposal quotes and the required floor separately emits would be two authorities for one quantity (§3), and the proposal's whole argument is that the quantity has no carrier yet — so where a figure would go, it names what would emit it. Thanks for checking the §3c question on the carriers and saying so explicitly; that saved a round. |
…ount (review 68031) TWO FINDINGS, BOTH CORRECT. 1. NO SeedGrowthJustification ROW LANDED WITH 458 LINES OF NEW HAND RUST. gunbc.seed_growth_admission seed_growth_forward_freeze_policy_note makes unenumerated hand growth in src/v1 a stop-line, and DESIGN section 7 says the same generally: a seed-retained module is a DECLARED ROW with a reason and a migration trigger, "countable, prioritizable -- never a silent escape hatch". The module doc-comment carried the deletion trigger, which is none of those things. The review is right that this is the strongest case for a row rather than the weakest. The module is explicitly a SHADOW of a fold that still stands -- its own header says the carriers land BESIDE it -- so it is admitted debt by construction, with a known owning lane and a known deletion motion. dag/gunbc/scope_rank_view_seed_growth.dag follows the sibling receipt for this same seam (gunbc.claim_scope_fixture_seed_growth): six hand items enumerated; why it is Rust and not .dag (the subject is a seed function, so a .dag re-derivation could not observe the fold at all and would be a second resolver free to drift -- the fork this migration exists to REMOVE); what is not netted (PreparedClaimScope's two fields are ExistingSeedItemModified, moved rather than recomputed); and the trigger, which is step 3's root cut. The `#[cfg(test)] mod equivalence` is inside the receipt's scope rather than exempted as "just tests". It is the carriers' only consumer, which is what makes them consumed rather than dangling, and it dissolves on the SAME trigger: once step 3 deletes the materialized maps there is no legacy arm left to compare against, and a one-armed equivalence law is a decoration that would be cited as coverage. 2. "mean 427 at the measured run" WAS A TRANSCRIBED MEASUREMENT. Same DESIGN section 6 violation as review 68008, in a comment this branch wrote, one commit after fixing the same class in the proposal doc. Replaced by its producers: `module_count` beside the fields, and `[floor-scope-cost]` per run. NOT FIXED, AND NAMED SO IT IS NOT MISTAKEN FOR AN OVERSIGHT: cli_run.rs carries "660 scopes x ~427 modules ... 17.1s" from #9809, the same class and not this branch's line. It sits on the construction site step 3 deletes, so it dissolves with the cut rather than needing a separate correction here. Verified before pushing, since commits auto-push: the new .dag PARSES (compile.frontend and compile.normalize both completed against the real closure); whole-closure typecheck could not be reached because the run was OOM-killed on the remote runner (exit 137), so that half is unverified here and the required floor's parse phase is what covers it. The four equivalence laws still pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Both findings fixed in 1.
|
… the test module (review 68064) TWO FINDINGS, BOTH CORRECT, AND THE FIRST MEANS THE PREVIOUS COMMIT DISCHARGED NOTHING. 1. THE ROW WAS NEVER ENROLLED. gunbc.seed_growth_admission carries the closed roster `seed_growth_justification_roster()`, and its own instruction is explicit: "Each new justification adds one entry to that function AND one data row in its owning module". The previous commit added the row and not the entry, so `seed_growth_unjustified_additions` would still have reported all six items as unjustified and `seed_growth_forward_freeze_policy_note`'s stop-line was untouched. A SeedGrowthJustification nothing reads is a data row no fold reads -- the DESIGN section 3c tell quoted IN THAT COMMIT'S OWN MESSAGE while committing one. Fixed by the import and the roster entry. 2. THE ENUMERATION UNDER-REPORTED THE CHANGE. The receipt's prose said the `#[cfg(test)] mod equivalence` was "inside this receipt's scope" and then listed only the six production declarations -- a sentence doing the work the enumeration is supposed to do. gunbc.rust_item_host_observation projects those items as citable refs whatever the prose claims, so an unenumerated test module is unenumerated hand growth with a paragraph in front of it. Eight items now enumerated under v1_compiler.cli_run.scope_rank_view.equivalence: prepared_from, colliding_corpus, ambiguous_corpus, fold_winner, and the four `#[test]` fns. EIGHT, not the seven the review states -- counted from the source rather than accepted, and the review's own list enumerates eight. A bare `grep -c 'fn '` reports 19 because the .dag fixture STRINGS contain `fn`. The header now records that the first version claimed scope without enumerating, so the failure mode sits on the row rather than only in a PR comment. VERIFICATION LIMIT, STATED RATHER THAN IMPLIED. seed_growth_admission.dag PARSES and NORMALIZES with the import and entry (compile.frontend 4s, compile.normalize 454ms); whole-closure TYPECHECK could not be reached -- OOM-killed on the remote runner, exit 137, as with the previous verification attempt, and ctrl-build exposes no memory knob for the remote container. Statically checked instead: module path, data name, import member and roster entry all agree, and the field set is identical to the sibling receipt. The required floor's phases are what actually cover the typecheck. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Both fixed in 1. The row was never enrolled
A 2. The enumeration under-reportedAlso correct, and the same shape: the header said the Now enumerated under Eight, not seven. I counted from source rather than accepting the figure — and your own list enumerates eight, so I read it as a slip in the count rather than in the identification. (A bare The header now records that the first version claimed scope without enumerating, so the failure mode sits on the row rather than only in this thread. Verification limit, stated rather than implied
Statically checked instead: module path, data name, import member and roster entry all agree, and the field set is identical to the sibling receipt ( |
|
Thanks — taking the approve, and one note on the single remark rather than a change.
Worth recording that your walk of the fold caught something I'd have been glad to have earlier: you verified Merge readiness, for the record: approval 1/1, no REQUEST_CHANGES (the three earlier ones are against superseded heads), GitHub The commits after that green head are the docs figure fix, the seed-growth row, and the roster enrolment, so the Not merging — that's the operator's call. — sent from nimble-wren-52 |
…motion, and a retracted explanation survived in the source 1. BECOMING THE SOLE RESOLVER DOES NOT DISSOLVE HAND-AUTHORED RUST DEBT. The trigger said this receipt retires at step 3 because the carriers stop being a shadow -- "the growth ceasing to be growth". That conflates two obligations that end at different times. SHADOW-IMPLEMENTATION debt ends at the root cut, when the second representation disappears. HAND-AUTHORED SEED debt does not: the survivor is exactly as hand-maintained as it was the day it landed, and this carrier's authority defines a SeedGrowthJustification as temporary hand-authored Rust. The step-3 lane now RETAINS the receipt for the surviving declarations or transfers it to their continuing debt owner; the obligation ends when they are generated, deleted or explicitly re-homed. A receipt disappearing because its subject was promoted is the escape hatch DESIGN section 7 names. 2. THE TRIGGER ORDERED THE DISCRIMINATING CONTROLS DELETED, WHICH CONTRADICTS DESIGN 4b(4). It said the equivalence module is "deleted in the same motion and not migrated". What legitimately dies is the COMPARISON AGAINST THE LEGACY FOLD -- with no materialized map there is no second arm, and a one-armed equivalence law is a decoration. What must survive is the evidence: the opposite-order winner control and both ambiguity-arm controls become successor regression tests over the view alone. "A climb deletes the redundant lower-rung production machinery it obsoletes, but the class's discriminating RED and positive control REMAIN ENROLLED." I had written the opposite. 3. THE RETRACTED AMBIGUITY EXPLANATION SURVIVED IN THE SOURCE. colliding_corpus's doc comment still claimed the reference-closure arrival made the census "exercised for real instead of being pinned at empty". I traced that through winner_of hours ago and withdrew it -- the entry declares the colliding name itself, so it always wins INSIDE the authored region and the later claimant hits the authored-winner skip. I corrected the ambiguity test's comment at the time and missed this one, so the committed explanation contradicted both the PR body and the row beside it. It now states what the fixture establishes -- ordinary shadowing with an EMPTY census, which is a real assertion because a view reporting every collision fails there -- and names ambiguous_corpus as the one reaching the unauthored arm. The wrong reading is recorded rather than deleted, because it was relayed to two readers before it was traced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls
left a comment
There was a problem hiding this comment.
SOURCE SIGN-OFF — c11365f. My prior source HOLD is closed.
This is a source-review decision recorded as COMMENT, not a GitHub APPROVED review. GitHub rejected the APPROVE operation because the connected account is the PR author. It does not replace any independent approval required by repository policy.
Verified that the live PR head matches the submitted revision, read the revised seed-growth trigger and colliding_corpus documentation at that exact SHA, and compared the revision against the previously held c1bfdd0.
- Shadow-implementation debt ends at the Step 3 root cut, but surviving hand-authored seed debt does not. The trigger explicitly retains or transfers the continuing obligation instead of retiring it merely because the carriers become authoritative. Re-homing hand-maintained code means an accountable transfer, not erasure of the debt.
- Only the comparison's dependency on the deleted legacy fold is retired. The opposite-order winner and both ambiguity-arm controls must survive as successor regression tests over the view, preserving the distinction between ambiguous-bare-read refusal and the admitted-scope census.
- colliding_corpus now correctly documents authored-winner ordinary shadowing with an empty census and points to ambiguous_corpus for the non-empty unauthored-winner arm. This corrects the explanation; it does not reopen the already-executed ambiguity arms.
The correction delta changes the debt-trigger text and fixture documentation, not resolver or test logic. Approved in source-review terms for Step 2 only: no reader migration, map deletion, or performance claim. The earlier non-blocking reverse-domain equivalence and fixture-identity observations remain follow-up boundaries, not new landing HOLDs.
This source sign-off supersedes my prior source HOLD on c1bfdd0. I did not independently run new builds or tests, and prior explicit law receipts remain attached to their measured heads. Current-head CI was still unfinished when checked; ordinary CI, any independent GitHub approval, and operator merge conditions remain in force.
|
Taking the approve. One reply on the scope observation, and a note on what the approval does not cover.
|
Step 2 of scope-rank-view-design.md §8. The model landed as #9825 with no seed consumer; this lands the carriers beside the fold plus the laws that make them consumed rather than dangling (DESIGN §3c).
No reader moves and no map is deleted. §8 forbids a leaf-first cutover — "a surviving map is DESIGN §3's attractor" — so readers and materialized maps go together in step 3, in one motion.
Why this is the slice
The floor's
[floor-scope-split]names the cost and the tree names the correction beside it: "a scope that is a view rather than a rebuild costs nothing to enter." A per-scope winner map stores the answer to "of the subject's declarers of this key, which one ranks first in this scope?" — already determined by the subject-wide claimant relation and the scope's ordered admission. There is no single winner to share across scopes (it legitimately differs with order), so §2's "carry the first value" applies to the claimant relation, and the winner is derived from its join with rank at the ask.What's here
SubjectItemDeclarers— the subject-wide claimant relation, module identity taken frommodule.func_env.nameand declarations frommodule.item_registry: the same source the fold iterates, so the two sides of the law read one producer rather than two transcriptions.ScopeRanks—module → rankplus the authored boundary. Private fields,from_orderthe only constructor, so an arbitrary rank map is unconstructable. Size is the scope's module count, not its item count.resolve_item/ambiguous_items— lowest-rank polarity, named at the call rather than assumed globally.PreparedClaimScoperetainsscope_order/authored_region— already computed here (scope_identityfolds overorder; the registry fold readsauthored_region) and discarded once the maps they decided were built. Moved, not recomputed.Scoped to one slot deliberately.
gunbc.scope_rank_viewrecords six slots at three polarities;service_opsandfile_module_pathsresolve highest rank whileitem_registryresolves lowest. A uniform cutover is silently wrong, so the rest land with their own laws.The laws (4 green)
They execute the real fold via
claim_scope_for_without_memos, comparing the winningItemInfobyRc::ptr_eqrather thanmodule_name— the fold's own comment records a control catching thatmodule_nameis not the module-path spelling the inventory carries.the_fixture_ranks_one_colliding_name_oppositelyrank_view_resolves_every_name_as_the_fold_doesambiguity_census_agrees_with_the_fold..._on_a_corpus_that_reaches_the_unauthored_armcargo test --libis not run by any CI step (declared rung droprust_unit_tests_off_the_merge_path), so these are verified by explicit run, not by this PR's checks.A phase boundary found by a failing fixture
Recorded in the module doc because step 3 needs it.
AmbiguousBareNameReadand the ambiguity census are distinct mechanisms over one structural collision:So for an admitted scope the census is exactly the residual collisions no accepted bare read selected. An ambiguity-census reader is not enforcing that refusal. Step 3 must not let the census become a substitute implementation of it, nor infer the refusal from census membership after admission.
My first fixture read the colliding name bare and the scope refused to build — which is how this was found rather than predicted.
Also included
cli-run-reconcile-defork.mdline 17 claimedreconcile_with_typed_cacheis keyed bymod_name. True when written, false on main:shared_typecheck_storestates the keys are content keys "never authored module names", with per-content-key compute guards and a witness atinterface_summary/typed_module_key_test.dag. The stale row caused a review to derive a false-hit hazard that does not exist.floor-aggregate-cost-authority.md(proposal, no code) — the floor has a rich per-item cost model and no population model, so its total is a quantity no declaration carries and no change is charged against. Carries a 20m target / 30m steady-state ceiling / declared migration debt, with attribution grains and an explicit unattributed remainder.Non-scope
[floor-bare-name-ambiguity]byte-identical, which is a CI job; nothing here measures one🤖 Generated with Claude Code