Repository navigation
QUARRY: import-deletion semantics, binding controls and migration oracle (superseded by the clean namespaced-subject cutover) - #8115
gunbai-bot[bot] wants to merge 53 commits into
Conversation
#8084 and #8080 were closed as quarry, so the base session/valiant-boar-65 sits at an archived head that will not move again. This is the lane's source contribution replayed onto main: the eleven authored files, with every generated artifact re-derived from the merged authority on this base rather than carried across (plan, stage0, .gitattributes, ci.yml). None of CI2's diff comes with it. Replay proven by execution, not assumed. regen_divergence_count=0 with build exit checked first, and every witness re-run on this base: the declaration matrix 18/18, the import-deletion bridge 3/3, and the four sibling scoped-roster files 13/4/4/7/3 -- zero failures. Contents, in the order they landed: Bridge real authored source into occurrence binding, with exposure grounding a parameter rather than a hardwired assumption. Commit B: pin the parser declaration-category denominator by execution. Every authored declaration form gets a row, including the forms that mint nothing -- the zero rows are the load-bearing half. Commit C: mint type declarations, constructors and fields, role-directed in `stamp_parsed_node_children`. It cannot be shape-inferred per node: a product FIELD node carries `inferred` Present with a Present ident_span, and a payload VARIANT carries the same `connective: Conj` a product declaration does, so a shape-first rule turns fields into type declarations. The member kind is a fact about the parent. A pattern's field position was minted as a FieldOccurrence DECLARATION. It names which field is being destructured, so it is a reference; the binder beside it is the declaration. Two defects at one authored name, discriminated by three rows keyed on exact occurrence identity so neither could green by masking the other. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The heal job failed because it regenerated a workflow path it is not credentialed to push: `.github/workflows/ci.yml` was one derivation pass behind this branch's emit plan. The single changed line is the heal job's own authored-conflict exclude list, which is derived from the plan, so it was missing the three stage0 modules this lane adds (the bridge witness, the declaration matrix, and its support module). Cause was mine and mechanical: `main_wet` derives ci.yml from the plan it reads at START, so a change that adds emitted files needs a second pass. I ran one on this base. Two passes now, and a third pass produces no further change, so the fixed point is shown rather than assumed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolutions, by class rather than by file: AUTHORED. `dag/gunbc/explicit_witness_admission.dag` conflicted on one row I had deleted and main still carries — the `english_emit_add_prose_holds` promotion I did as a favour for another lane. Took MAIN's side: that promotion belongs in its own change, not carried inside an import-deletion PR where a wrong call would red this branch for an unrelated reason. GENERATED. `.gitattributes`, `ci.yml`, the emit plan, `lib.rs` and one emitted witness were all regenerated from the merged authority rather than hand-resolved, per the driver's own instruction. Taking main's whole self-consistent stage0 as the bootstrap first mattered: a per-file `--ours` mixture built 44 errors, because half the seed was mine and half was main's. THE KEYSTONE GREENED, and its expect-red admission is deleted. Established in BOTH directions rather than observed once: against main's parser witness_import_less_reference_reaches_the_real_provider FAILS, against commit C's it PASSES, and the provider-withheld control stays green in both — so the pass is the new type-declaration population, not a closure that happens to carry the name. Its file is now enrolled file-grain beside its two controls, uniformly green. Scope unchanged: this is the SUPPLIED-PROVIDER claim, so provider discovery and provider-file edge projection remain open. That deletion also emptied `known_red_probe_v1_envelope_roster`, which fixes the floor's arm-time refusal on the previous push. My keystone admission had enrolled `gunbc_v1_claim_scoped_known_red_probe_batch` — a conditionally-enrolled batch — without the companion positional row the clamp table requires, exactly the ENROLLMENT COUPLING its own note warns about. Un-enrolling restores 6 positional batches against 6 clamp rows, so no clamp row was added, no budget was raised, and no operator signature is owed. INHERITED, NOT MINE: main cannot derive its own generated artifacts. This carries the `HasTrigger` heal (also opened standalone as #8117) because without it no plan can be derived here at all; the second break, `SubstrateLongLaneRow`, is #8116's and is deliberately not duplicated. Until both land, this branch cannot complete its regen chain, and that is an inherited blocker rather than this lane's red. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#8116 carries both halves of main's #8059 skew break and is proven green -- main_wet EXIT=0 with zero drift -- so this branch's copy of the same 81 rows is redundant. Pushing an identical repair from two directions into a merge is the duplication itself, not a safety margin, and the manager owning #8116 asked explicitly that it not happen. CONSEQUENCE, stated rather than hidden: this branch cannot derive an emit plan again until #8116 lands, so its three new emitted stage0 modules stay unregistered and the regen chain stays red. That red is inherited from main, not produced here, and it clears by merging main once #8116 is in. #8115 stays draft until then. Also correcting arithmetic I put in the closed PR and in the merge commit before it: 77 is the POPULATION of SubstrateLongLaneRow literals, not the count of broken fields. The broken field count is 18, out of 21 dissolve_on spellings, three of which are prose inside strings. The number I quoted answered a neighbouring question and read as though it answered this one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three reds are inherited from main, and there is no fix for me to pushAll three failing checks trace to one break in main's own file, not to anything in this PR's diff. Verified per-step rather than inferred from the rollup:
Reproduced on pristine main, not on a branch: a clean checkout of #8116 is the fix and it carries both halves. I verified it independently: So this PR stays draft and red until #8116 lands, at which point a merge of main clears all three. Deliberately not pushing anything to make these go green — the only available fix would be a duplicate of #8116, which is the redundancy, not the remedy. — sent from calm-ram-435 |
…delete-imports-on-main
#8116 landed both halves of the #8059 dissolution-carrier skew and #8110 was reverted, so main derives its own artifacts again and this branch's inherited red clears. Merged with no conflicts -- the previous commit had already reverted the duplicated heal, which is what left nothing to collide. The three new emitted stage0 modules are now registered by the derived plan rather than by hand: the bridge witness, the declaration matrix, and its support module. `main_wet` reaches a fixed point proven by BYTES rather than by a third quiet pass -- md5 of .gitattributes, ci.yml and the emit plan is unchanged across a further run -- and the two-round seed regen verifies at regen_divergence_count=0 with build exit checked before the verify. Evidence re-run on the merged tree, not carried over: all seven scoped-roster witness files green -- the declaration matrix 18/18, the import-deletion bridge 3/3, and the four siblings 13/4/4/7/3. Zero failures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The CI auto-heal merged main into this branch and pushed a regeneration (c43a89d) while I was doing the same work locally. Its result is not self-consistent and must not be taken: measured on that exact head, `regen_stage0 --verify` reports regen_divergence_count=5, while this tree reports 0. WHAT IT DROPPED, and how it is visible: the heal's emitted `v1_compiler_parse.rs` contains ZERO occurrences of `parsed_module_item_declares_type_name` while its own `src/v1/02_parse.dag` still contains commit C in full. So the source claims role-directed minting and the seed does not implement it -- a source/artifact divergence, committed. The cause is the heal regenerating with release-bins built from a merge ref that predates commit C; an emitter that does not know about a change cannot emit it, and its output then looks like a clean regeneration. This merge is `-s ours` deliberately rather than a file-by-file resolution. The remote's only unique content is those five stale generated files; its merge of main is the same main commit (4bd738b) this branch already merged, so nothing authored is discarded. Verified after the fact rather than assumed: divergence stays 0 and all seven scoped-roster witness files stay green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The one red is main's, reproduced exactly — not this PR's
Established as set equality, not by eyeballing similar names. I extracted the failing Not one of those five files is in this PR's diff. All 11 are already claimed, across two open heals — so there is again nothing here for me to push without duplicating someone else's work:
One of the eleven is a different class and worth naming rather than lumping in: This PR stays draft until #8125 and #8122 land; a merge of main then clears it. The lane's own evidence is unaffected and re-runs green on this exact head: declaration matrix 18/18, import-deletion bridge 3/3, four sibling roster files 13/4/4/7/3. — sent from calm-ram-435 |
…delete-imports-on-main
Inherited reds cleared — verified by running them, not by reading the fix#8122 landed as I re-ran all eleven previously-failing witnesses on this head rather than treating the merge as proof. Ten pass in place. The eleventh no longer exists — That distinction is the point: a witness that stops existing where it used to reads identically to one that got repaired, and only the second is coverage. Same shape as the One note on this merge for anyone auditing the seed: the rebuild was a 0.09s no-op, which is normally the stale-binary signature. It's legitimate here — the merge changed no The merge commit carries git's default message; this comment is the receipt for it. — sent from calm-ram-435 |
Module identity does not delete an import. An import line names a FILE, so the thing replacing it has to produce a file-grain edge -- the loader needs to know which file to pull into the closure, and a claim that only says which MODULE a reference belongs to leaves that unanswered. The keystone proved the reference reaches the right module; these rows prove the same binding projects the provider file, through the production projection rather than a copy of it. Three new rows, and the pair is discriminating in both directions: the consumer names LiveTreeDisposition TWICE (parameter type, return type), so a correct projection yields exactly 2 binding-provenance rows -- derived from the fixture's own text, not read off the parser; both rows name the same provider file, so the file-grain projection must dedupe them to exactly 1 edge, asserted with exact consumer and provider paths and a no-self-edge clause. Two rows becoming two edges is a dedup failure that over-loads the closure; two becoming zero drops the dependency the loader needs. One is the only answer that is right for a reason. a control that a withheld provider projects NO provenance rows and NO edges, distinct from the keystone's own control -- without it both counts above could be satisfied by a projection emitting edges from an empty binding population, which is the direction that silently loads files nothing references. PROVEN DISCRIMINATING, not assumed: perturbing the fixture to a single mention reds both count rows while the dedupe row still reports 1 -- so the counts are load-bearing and the dedupe row measures a different fact rather than echoing them. NO NEW MACHINERY, which item 5 requires: the provenance population and the dedup come from std.occurrence_binding_candidates, and the module-to-file index is built from the closure's own module_files rows. Nothing walks a filesystem, scans names, or builds a second module-to-file map. `ModulePathFileRow` is declared as an import for the same reason as last time -- it appears in a signature, so the emitted seed needs it, and that dependency is invisible in an import list until the build says so. This lane's own subject. regen_divergence_count=0, build exit checked first. 7/7 on this witness, 18/18 on the declaration matrix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…g it THE DEFECT, which was mine and was the exact class this lane exists to delete. The previous revision reached its 2-provenance/1-edge result through a FAIL-OPEN ADAPTER: it matched only ReferenceBindingProjectionBound, discarded every other outcome, then hand-constructed AllReferencesBound from the survivors. So a population where one reference bound and another did not would have reported a complete closure and emitted a provider-file edge -- the false-skip direction, which silently under-loads. Every refusal arm (assembly, index, walk, binding, file projection, unbound, ambiguous) also collapsed to an empty list, so the withheld-provider control proved only that refusal and legitimate-zero are represented identically. THE REPAIR. One assembly, then the production total path and nothing local: structural_binding_walk_selected_references returns a BoundReferencePopulation that is AllReferencesBound or ReferencePopulationRefused carrying its first failure, and reference_derived_dependency_projection turns that into Ready or a typed binding/file refusal. This file no longer constructs AllReferencesBound, folds projections, or uses [] to mean a stage refused. Outcomes are one coproduct reusing the production refusal types; only two arms are local, and both are about the fixture's own population (unknown candidate path, reference-count mismatch). Not the top-level helper, deliberately: reference_derived_dependency_projection_for_assembled_closure selects through the clause-e filter, which excludes TypeOccurrence, so it would have selected zero references and reported Ready with zero rows -- every count assertion passing vacuously. Moving TypeOccurrence into clause e to reuse that walk is item 4's wrong turn and is not taken here. PROVEN DISCRIMINATING BY REINSTATING THE DEFECT, not argued: with the fail-open put back, exactly two rows red -- the withheld-provider and partial-population controls -- and every other row, INCLUDING the 2-to-1 pair, passed. The positive law never detected the fail-open and never could, because a fabricated success is still a success. Those two controls stay enrolled as the executing evidence that totality holds. The planted partial-population control needed a second repair to have teeth: its first version selected only the subject's references, so the unbindable one never entered the population and the row passed against a Ready projection. Selection now takes a name list and the control requires all three references, one of which cannot bind. Also in this commit, from the same review: idb_source_for's "every non-consumer path is the provider" default is gone, replaced by explicit CandidateSource rows. Under the default, an unrelated candidate silently received the real provider's text, so unrelated and actual provider were not representable as different contents and every later provider-discovery control would have been misleading. An unknown path now refuses. the keystone is renamed from real_provider to supplied_provider and the read-off-disk/live-corpus claims are gone. Both sources are embedded and the provider is handed in, which the note admitted while the name denied. new controls: pool-independence as an EQUALITY on binding identities and the edge set (not merely "still green"), same-file provenance retained with no self-edge, malformed source as a parse refusal, and selection refusal. Item 3 is NOT complete: the ambiguity control needs candidate declaration identities that ReferenceBindingProjectionAmbiguous does not currently carry, and the review requires repairing that carrier rather than working around it here. Missing/conflicting module-file controls are also still owed. 12/12 on this witness, 18/18 on the declaration matrix, divergence 0 with build exit checked first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… ambiguity and storage controls
ReferenceBindingProjectionAmbiguous named an unbindable reference and threw
away what it was ambiguous BETWEEN. resolve_reference_occurrence_binding
already returned OccurrenceAmbiguous { occurrence, candidates } and the
projection matched `candidates: _`, so a consumer could learn that two
declarations competed and never which two -- and two ambiguity outcomes of
equal cardinality over different declarations are different states with
different remedies. The carrier now carries the upstream
AmbiguousBindingCandidates<OccurrenceId> itself; no new type was minted,
because head+second+tail already makes a one-candidate ambiguity
unconstructible.
The same class was then found one layer out, by tightening a control rather
than by reading code: the bridge witness collapsed
AssembledCrossFileBindingClosureRefused to a bare marker, so a storage
contradiction could not be asserted at its identities. It carries the
refusal through now.
Controls added, each asserting identities rather than counts:
- two admissible providers of one name refuse as ambiguous, naming both
competing declaration OccurrenceIds and joining each against the declaration
population of the assembled transport
- two files claiming ONE module path refuse at closure assembly, naming the
module path and both competing files. Which stage refuses is measured: an
earlier version tolerated assembly OR index refusal, which is a two-answer
assertion that would have passed had the contradiction moved between stages
- a bound population projected against an index with the provider module's row
REMOVED refuses the file projection, so a dropped edge cannot read as success
Stale prose stripped: the offline recipe still named a `real_provider`
function that no longer exists, listed two other functions that no longer
exist, and described an expected red this file no longer carries. The
provider is SUPPLIED by the fixture, and the recipe now says so and stops
enumerating a roster the file-grain enrollment already expands.
15/15 green by execution. Terminal acceptance is unchanged and unreached:
imports, their grammar and their AST are still present, and no production
node is accepted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…mitter defect Four generated artifacts conflicted (.gitattributes, ci.yml, the emit plan, lib.rs). Resolved by regeneration, not by picking a side: main's bytes predate this branch's three new src/v1 witness modules, so taking either side would have produced a plan that omits or duplicates them. Regeneration surfaced a real defect rather than only bytes. `regen_stage0 --verify` reported divergence 0 while `cargo build` failed with E0308: a nested coproduct pattern through a reference-counted field emits `projection.as_ref()` matched against a bare enum, so the pattern the v1 interpreter accepts does not survive emission. Byte-fidelity is not target-language validity, and the verify step cannot see the difference. The control is authored as two sequential matches -- semantically identical, and the idiom the surrounding corpus already uses. That is not a repair, and `idb_nested_rc_pattern_emitter_defect` says so at the site, names the emitted file, and carries its dissolution: the Rc wrap-decision predicate. Changing a load-bearing emitter is not this control's business. 15/15 green by execution after the split; seed rebuilds clean; verify at 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…he measured namespace frontier on the roadmap DECLARATION DENOMINATOR, three forms measured rather than assumed. A probe rendered each population once and was then deleted rather than left behind as a second instrument: - a type ALIAS mints TypeOccurrence. It is the third named-type shape and the one a connective-keyed rule misses, so the whole-population row now asserts THREE named types, not two -- with two the alias hole was undetectable from this file while both existing rows passed. - the pattern field position mints a FieldOccurrence REFERENCE at 394-411 whose containment locates it inside the matching function. This is the positive half of a pair whose other half only says no DECLARATION sits there -- satisfied equally by a correct reference and by nothing being minted at all, which would drop the edge silently. Asserting it required a references-side projection; the support authority now renders references at full identity too. - a module-scope value declaration mints NOTHING. `data name: T = v` binds no name, so a bare cross-file reference to a module datum cannot bind and the derived closure is short by every module-value edge in the corpus. The module-value row is enrolled EXPECTING RED, not written as a zero row in the green file. A zero row asserting the empty population would be green today and would make the defect the contract -- the shape DESIGN section 5 names when it rules that a test asserting a degradation's own string enshrines it. The row asserts population size and not category, because which OccurrenceCategory a module member value binds is a genuinely open modelling question and a red row is not where it gets decided. Cause located at parsed_occurrence_role_for_node, which classifies a bodied node by the ABSENCE of a type annotation -- a defect distinct from the three role-directed minting closed. Its admission carries the companion positional clamp row the enrollment coupling requires. ROADMAP, in this commit because the capability boundary moved. NO FRONTIER ADVANCES and that is the correct reading: the provider is SUPPLIED by the fixture, nothing discovers one from a source root, no ordinary compiled path asks for any of it, and the closing contract's capability rows read Unavailable under the same triggers as before. Editing an admission row to reflect fixture evidence would be the rung inflation namespace_node_recut_note already priced. What lands is the measured state, dated, naming both what fifteen executing controls established and what they did not, plus the module-value hole so it is not discovered late -- and the lane joins the focused page because it is being worked. Imports, their grammar and their AST are all still present; the hand-written edge producer is untouched; nothing is cut over. 20/20 green in the enrolled matrix, the red row red as declared, seed rebuilds clean, verify at 0, and the clamp, focus, frontier, document, execution-contract and roadmap gates all pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ching clause (e) Clause (e) excludes TypeOccurrence for a stated reason -- a parser-produced annotation such as `Int` would enter the population and refuse it whole, because std.types was never given to the closure. Both easy repairs are forbidden. Reclassifying TypeOccurrence as clause-(e)-inducing makes that clause say something its contract does not, and every consumer inherits the change silently. Dropping an unbindable type reference to keep the projection green renders "could not see the provider" as "nothing is depended on" -- the empty-observation narrow, strictly worse than the widen DESIGN section 5 forbids, because a widen is expensive and a narrow is silently uncovered. So dependency-inducement becomes its own authority with one arm per ROUTE, COMPOSED over clause (e) rather than replacing it: it reads the clause-(e) verdict first and inspects the category only inside the NotInducing arm, so clause (e) remains the authority for its own question. Both routes then reach the SAME BoundReferencePopulation through one fold over ONE candidate index -- the N2 typed entry already returns a ReferenceBindingProjection, so no second binding authority was minted. Its index-supplied twin exists because the inputs-taking entry rebuilds a candidate index per call, which is correct for a single-reference API and quadratic inside a walk. Six controls, and the load-bearing pair is measured at the EDGE: - clause (e) STILL excludes type references. Its own row, because the point of adding an authority instead of editing the filter is that this stays true. - the admission table is total over the closed coproduct: fields and methods stay excluded, carrying the category they excluded. Asserting only the type arm would let a change that admitted field references pass, and a field reference admitted as dependency-inducing makes every record access look like a file dependency. - clause (e) ALONE derives ZERO edges for a type-only consumer, and the joined walk derives exactly ONE, to the provider file. An earlier draft asserted clause (e) selects nothing there; measurement refuted it -- it selects one same-file parameter mention, which is why the discriminator is the edge and not the population. The zero row alone is satisfied by a projector that produces nothing; the one-edge row alone by one that always emits an edge to any supplied provider. Together neither passes. - three admitted references reach one population at an EXACT count; a join that dropped a route would satisfy any lower bound. - an unsupplied type reference refuses and NAMES the occurrence. That name is the loader's work list, which is the whole reason the production switch waits. The production projection deliberately does NOT consume this yet, and the authority note says so: admitting type references makes the demand real, and the demand is item 6's fixed point. A surface with no consumer is coverage by illusion, so its dissolution is named -- when the switch lands, reference_derived_dependency_binding_references has no caller and deletes. 21/21 in the bridge witness; the candidates, pool-independence and N2 type binding witnesses stay green; seed rebuilds clean; verify at 0. CI red on this branch remains INHERITED from main and is unchanged by this commit: main @341d320 fails the same check with the same two classes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
module_path_file_row_note has said, since it was written, that v2.compiler.source_authority ModuleStorageBinding / ModuleStorageIndex is the single home for the path-to-module binding and that ModulePathFileRow is a scaffold projection OF it. Nothing performed that projection. Every ModulePathFileRow in the tree was a hand-authored literal inside a witness, so the two representations coexisted with no derivation between them -- the exact parallel-representation state the note claimed to be avoiding, and the reason provider discovery had nothing to consume. This is the missing function, and it lives with the binding because the binding is that module's fact. TWO ARMS, because a module does not always have a file. ParsedFromSource carries an Artifact whose file_path IS the storage realization. ProducedByBehavior means a module the compiler produced: there is no file, and every path the projection could invent -- the module name reshaped, the empty string, the producer's own file -- is indistinguishable downstream from a real one, which is fabricated plausible output. So it refuses, naming the module and its producer. The index projection refuses WHOLE, and that is the load-bearing decision. The tempting arm projects the file-backed bindings and drops the rest: every positive row still passes, and the caller receives a row set it believes is the whole storage picture with a module silently missing -- the empty-observation narrow at set grain. A caller that legitimately wants only the file-backed subset filters the index first, which is a statement of intent rather than a silent loss. Six controls. The positive row pins BOTH derived facts at exact values -- dotted module path and the artifact's own path -- because asserting that some row appeared would pass for a projection that answered about the wrong module or invented a path from the name. The whole-refusal row plants an unprojectable binding BETWEEN two projectable ones, so a dropping implementation would return two rows and read as complete. Multiple failures are all reported, so the deficit is countable rather than first-only. Order is asserted at both ends, which is what a reversed fold swaps. And an empty index is Ready with no rows, stated as its own row so "no input" stays distinguishable from "input whose answer was dropped". This is the first half of item 5: provider discovery needs a derived row population, and until now there was none. The second half consumes the whole-tree parsed manifest discover_source_root_ingest --emit-module-binding-manifest already produces, supplied as modules in an ephemeral overlay source root the way module_binding_supply_transport does -- so no new filesystem walker, name scanner or module-to-file map is required, and the rows arrive as modules rather than through a Filesystem service, which dissolves the placement contradiction stage0_emission_model_gap_note records. 6/6 green by execution; verify at 0; no generated artifact moved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main
…ur the prose-row wall THE PROSE-ROW GATE WAS RIGHT AND IS NOW GREEN. It refused exactly one row -- module_path_file_row_projection_note in src/v2/compiler/source_authority.dag, a path already migrated to authored // annotations -- and counted 26 further rows as out-of-scope residue it reports without enforcing. The refused rationale moves into a leading // block above the declaration it explains, which is what DESIGN section 4c admits. Nothing was weakened to pass: the argument is unchanged, only its carrier. PROVIDER ROWS NOW COME FROM THE REAL TREE. The new witness projects the whole-source-root PARSED module-to-path manifest through the authority, and the point is what it does NOT add: no filesystem walker, no name scanner, no module-to-file map, no second dependency producer. discover_source_root_ingest --emit-module-binding-manifest already emits those rows via v1_compiler_parse, and module_binding_supply_transport already overlays them as a MODULE in an ephemeral source root, so they arrive as data through carriers that existed. Arriving as a module is also what makes this reachable: a filesystem_read would drag the Filesystem service into the emission closure, which under src/v1 produces an unregisterable dry_run.rs -- the placement contradiction the bridge witness records. Five controls, enrolled in that transport's claim list: the real rows project; EVERY manifest binding projects, asserted as a count identity against the manifest's own count, so a Ready answer is the claim that the whole observed corpus is file-backed; a known module resolves to its known real path; an absent module does not appear; and a REAL module bound to the WRONG file does not appear either -- that last one distinct from the absent-module row because it is the failure a projection reshaping names into paths would produce, and it would pass the absent row. All are vacuity-guarded: run without the overlay, the manifest is the committed Empty stub and an empty index projects to an empty row set that is legitimately Ready, so every claim requires a populated manifest and a non-empty projection first. A PRODUCER DEFECT FOUND BY MEASUREMENT, named rather than routed around. A second known pair in the dag/ root was authored and REMOVED: the manifest cannot carry that root at all. The producer renders the artifact id and textual locus file as a BARE symbol from the file stem, and dag/ holds dag/std/import.dag and dag/extdeps/languages/go/module.dag, so a two-root emit writes `id: ^import` and `file: ^module` -- keywords -- and the whole manifest fails to parse. Measured: 3517 rows written, then `for_each_parsed_module_binding: parse error ... expected identifier or ( after ^, found keyword`. This matters to the lane rather than being trivia: providers live in dag/ as well as src/v2, so reference-derived closure over the real corpus cannot complete while the producer cannot describe half of it. The limit is stated on the consuming witness and on the transport with its dissolution -- the file path is already carried as a String in the same row, so the stem-derived symbol is a second, weaker naming of a fact the row already has. Also corrected here: I had described this manifest as whole-TREE. It is whole-source-ROOT, and the transport passes src/v2 only. 5/5 green through the transport against a real overlay; the sibling consistency and crate-layout claims in the same gate are unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d defect instead of restating it TWO FIXES, one of them a correction to the previous commit. THE WITNESS WAS DISCOVERED AND RUN WITHOUT ITS OVERLAY. CI ran six of my rows through the corpus discovery walk -- which picks up any *_test.dag under a source root, not only the three scan dirs -- and outside the transport host_module_bindings is the committed Empty stub, so the vacuity guard refused and every row returned false. The guard was working; the placement was wrong. It now carries a WitnessExclusionRow in exactly the crate_layout posture, which is the same manifest, the same Empty read and the same refusal, and it says explicitly that the refusal is the guard working rather than a defect. The witness keeps its executing consumer: the transport's ClaimRun roster. This is the local-green-is-not-CI-path-green class, and I walked into it: the five rows passed through the transport and passed against a hand-made overlay, and neither of those is the admission path. THE dag/-ROOT DEFECT WAS ALREADY DOCUMENTED, and the previous commit presented it as a find. gunbc.commit_workflow heal_writer_claims_no_fixture_exemptions_note records that discover_source_root_ingest mints edge identifiers from source-file BASENAMES with no keyword escaping, and names all three colliding files -- dag/extdeps/bmc/capability.dag, dag/extdeps/languages/go/module.dag and dag/std/import.dag, minting ^capability, ^module and ^import. I reproduced it independently and found two of the three. The witness now CITES that authority rather than standing a second description of the same fact beside it, which is the nicknaming DESIGN section 3 forbids applied to prose, and it takes that note's dissolution trigger instead of minting another. What is genuinely new is kept and stated: the consequence for this lane, that providers live in dag/ too, so reference-derived closure over the real corpus cannot complete while the producer cannot describe half of it. The exact-witness-admission gate is green with the new row. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main
…brace that broke every gate DISCOVERY/ENROLLMENT REPAIR, and the roster is now one authority. The five overlay-dependent claims were inline in the transport's call, so the function names existed only inside an expression no coverage accounting can read. They are now `module_binding_supply_claims`, one declared List<ClaimRun> the transport consumes, so execution and any consumer census read the SAME rows rather than two lists that can drift. The names are not duplicated anywhere. Discovery no longer executes them. The corpus walk picks up any *_test.dag under a source root -- not only the three scan dirs -- and outside the overlay host_module_bindings is the committed Empty stub, so the vacuity guard refuses and every row returns false. Selection is removed with a WitnessExclusionRow in exactly the crate_layout posture (same manifest, same Empty read, same refusal); scan dirs are NOT broadened and no vacuity guard is weakened. TWO CONTROLS I DELETED, RESTORED. Rewriting the dag/-root comment in the previous commit replaced a span that swallowed msrs_an_absent_module_is_not_projected and msrs_a_real_module_is_not_bound_to_the_wrong_file. It surfaced as `no such function` when the roster called them, which is the one way it could surface -- the file still parsed and the remaining three still passed, so nothing else would have said so. Both are back with their arguments intact. A BRACE THAT BROKE EVERY GATE. #8148 landed a reason string containing `Classified{LocalRead}`, and `{` opens interpolation in .dag, so the module raised `undefined variable 'LocalRead'` and nothing that resolves explicit_witness_admission could run -- which is every gate I needed. Escaped to `\{LocalRead\}`. One character, no semantic change, and it is a base-side defect fixed here only because it blocks this branch entirely. Executed: transport gate true (11 claims, mine among them); bridge witness 21/21; main_wet to a no-op fixed point; regen_stage0 re-emitted and the seed rebuilt clean; regen --verify divergence 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e, third instance of one class dag_compile_clean_gate_passes was the only red left after the discovery repair, and its hard diagnostics were `unresolved type 'ArtifactIdentity'` in three cache witnesses this branch never touched. Cause: two declarations of that name now exist -- dag/std/cache_interface.dag's generic ArtifactIdentity<T>, and a new non-generic ArtifactIdentity in src/v2/compiler/self_host/generation.dag that arrived with main. Adding a name to the flat namespace is a corpus-wide edit, so the generic uses stopped resolving in files unrelated to either. The newer name yields, per single authority, and it is renamed rather than suffixed because the old name was wrong for it: the type is `ArtifactMaterialized | ArtifactNotMaterialized`, which is a MATERIALIZATION STATE and not an identity at all -- the field holding it is already called materialized_artifact. It becomes ArtifactMaterialization, with artifact_identity_agrees following as artifact_materialization_agrees. Eight sites across three files; no behaviour change. THIS IS THE THIRD INSTANCE OF ONE CLASS IN TWO DAYS, and that is the finding rather than the rename. gunbc#8151 fixed the same shape twice (Memory against std.measure's Quantity variant, unsatisfied_capabilities against the auth fold), and both times the break surfaced in a third file that neither PR touched. A flat-namespace homonym is DECIDABLE, so it is a construction wall waiting on the containment authority -- which is this lane's own terminal work -- not a matter of diligence. Until that lands it recurs at roughly the rate two lanes mint the same bare noun, and each recurrence costs an unrelated PR its CI. Executed: the three cache witnesses and both self-host witnesses green; main_wet to a no-op fixed point; regen_stage0 re-emitted; seed rebuilt clean; regen --verify divergence 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ecutingConsumer The admission refusal was mine and the classification was wrong: 5 UnclassifiedPathDeferral, "enrolled witness row(s) excluded from discovery name zero executing consumer" (run 31567336073). WHY OfflineLocalRecipe WAS THE WRONG ARM, having copied it from the crate_layout siblings. witness_path_policy_execution_standing_in maps an offline-classified row to LegacyFrozenPathDeferral only when gunbc.witness_deferral_freeze already names it, and otherwise to UnclassifiedPathDeferral, which is refused -- the forward hole the 2026-08-04 ruling opened deliberately. The siblings predate that ruling and are held by the frozen baseline, which may only SHRINK, so a NEW witness cannot join them and must not try. Copying a precedent's classification without checking which arm it reaches is what produced this. FixtureExplicitRoster is the honest arm and reaches WitnessHasExecutingConsumer, because the executing consumer genuinely exists: the declared roster module_binding_supply_claims, which the transport runs. That is the operator's second classification done at the authority rather than as an exemption -- one typed roster read by execution, and a classification the coverage fold already understands, with no second list of function names anywhere. Proven by calling the production fold rather than by rerunning the floor: witness_path_policy_execution_standing for this entry and function now returns WitnessHasExecutingConsumer, where it returned UnclassifiedPathDeferral before. The freeze witness, the exact-admission witness and the exclusion-reconciliation witness are all green; the frozen roster is untouched and did not grow. main_wet to a no-op fixed point; regen_stage0 re-emitted; seed rebuilt clean; regen --verify divergence 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e CI batch witness_live_floor_discovery_batch_count_is_four went red, and measurement said the live count is FIVE. The cause was mine: enrolling the module-value expected-red row is v1-scoped, so it enrolls the conditional gunbc_v1_claim_scoped_known_red_probe_batch, and that is a whole additional corpus batch in the floor plan -- purchased for exactly one assertion, with a companion clamp row to fund it. I did NOT bump the literal to five. Editing an oracle so it agrees with my own change is the change-detector shape, and here the change was not worth defending: a fixture-only red row that moves no production boundary is precisely what the anti-stall constraint rules out, and its cost is a per-PR batch every other lane pays. So the row, its admission and its clamp companion are removed and the count returns to four by construction rather than by re-pinning. THE REQUIREMENT IS NOT LOST, which is the only reason removing evidence is acceptable here: nothing climbed, so there is no rung to protect, and the finding is already carried in gunbc.roadmap_authority namespace_lane_measured_frontier_note -- a module-scope value declaration binds no name, so a bare cross-file reference to a module datum cannot bind and the derived closure is short by every module-value edge, with the cause located at parsed_occurrence_role_for_node. When the loader needs module-value bindings the assertion returns riding the loader's own witness, where it costs no extra batch. Deleting the source also required deleting its emitted seed file: regen refused with `committed generated stage0 file(s) are absent from the derived emission plan`, which is the derivation working -- the plan is derived from the observed module closure, so a removed module leaves its .rs orphaned and the gate says so rather than leaving dead output committed. Executed: witness_live_floor_discovery_batch_count_is_four and ci_floor_plan_witnesses green; witness_floor_appends_one_selected_native_batch green; the clamp-authority and exact-admission gates green; regen_stage0 down to 144 files; seed rebuilt clean; regen --verify divergence 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three conflicts, all resolved by taking main rather than by merging text. MY RENAME IS WITHDRAWN. main fixed the flat-namespace collision itself, renaming the self-host type to GeneratedArtifactIdentity where I had renamed it to ArtifactMaterialization. Their name is the one on main, so mine is a second answer to a question already settled -- exactly the fork this repository consolidates later at cost -- and the self-host generation, promotion-admission and both witness files are taken wholesale from origin/main. My reasoning for the other name (the type is a materialization state, not an identity) is not worth a divergence and is not re-litigated here. ci.yml conflicted as a generated artifact and was regenerated from the authority rather than hand-merged, leaving a one-line delta. Executed: both self-host witnesses and the cache witness that the collision originally broke are green; main_wet to a no-op fixed point; regen_stage0 at 144 files; seed rebuilt clean; regen --verify divergence 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ir subject
Two things, both consequences of the exposure change rather than new direction.
MODULE VALUES. A module-scope `data name: T = v` bound no name at all, so a
reference to any module datum could not bind and the derived closure was short by
every module-value edge in the corpus. The shape classifier cannot be widened
where the hole is -- it sees a node carrying both a body and a type annotation,
which is reachable from nodes that are not module items -- so the arm goes where
the question is decidable: parsed_module_item_role, asked only of a node already
known to be a module item.
The category is new rather than borrowed, and the two obvious reuses are both
wrong. LexicalValueOccurrence is explicitly NOT module-scope exposed, so it would
have declared every module datum unexported; CallableOccurrence would have
nicknamed a value as callable. ModuleValueOccurrence joins the closed coproduct as
module-scope exposed and clause-E dependency inducing, and a value reference is
admissible against it -- an expression variable cannot know whether its target is
a local binder or a module member, and the reference site is not where that is
decided. Measured on a fixture: three failing references become two, the residue
being type references genuinely outside the universe.
THE WITNESSES. Six discovery rows went red in CI that my local run did not catch,
and the reason is worth recording: I filtered a corpus run's output and read the
absence of FAIL from a filtered stream. A count of matched lines is not a count of
witnesses. Re-run unfiltered, with totals compared against the roster.
Of the six, two -- cross_file_provider_exported_exposure_at_{module_root,direct_child}_upgrades_to_root
-- had no subject left: they called the surviving grounding and demanded the
deleted RootExposure answer. They are deleted rather than inverted, because what
they would now regress is a behaviour the model no longer has, and the two
module_local_member_exposure rows beside them already assert the surviving answer
at both containment shapes. The other four are fixture-driven and were authored
bare: the clause-E consumer now references provider.helper, and the pool-
independence decoy moves from app.decoy to other.provider so it still COLLIDES
under a qualifier -- its own note predicted the collision would become a fixture
artifact under projection, and moving the module keeps it the ambiguity control it
was written to be rather than letting it pass for the wrong reason.
Green by execution: assembly 9/9, pool-independence 8/8, candidates 23/23,
closure 10/10, bridge 21/21.
FRONTIER NOTE REWRITTEN. namespace_lane_measured_frontier_note described a
supplied-provider era that no longer exists and would have sent the next reader
back to work already landed. It now records what moved (discovery, transitivity,
relational exposure, qualified type projection) and what is open at the grain that
decides dispatch: expression-position paths, the bare-authored corpus, no ordinary
compile-path consumer, and an unsealed universe. It also carries the obligation it
previously omitted -- rewire_type_env_import_str_binding_identity survives on main,
gunbc#8202 proved it cannot simply move pre-typecheck and gunbc#8227 only optimized
it, so its deletion belongs to the type-env single-authority cutover and must land
before grammar deletion.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… file An expression path arrives as a bare head reference plus a field projection -- p.first is a reference to p, not one dotted occurrence the way a TYPE path is -- and the head had nothing to resolve against: parse_module stamps a module once carrying its WHOLE dotted name, so declarations_by_name, keyed by authored spelling, has no entry for the last segment alone. Measured before: 'p' did not bind, universe declares 'p' 0 times. module_declarations_by_segment buckets NamespaceSegmentOccurrence declarations by their last segment and supplies them to bare references beside the on-chain population. Keyed by segment rather than full path because the ratified migration form is the SHORTEST qualifying container path; two modules ending in the same segment supply two candidates and fold to Ambiguous, which is the refusal rather than a nearest match. The category is read off the DeclarationOccurrence, not inferred from a dot in the text, so an ordinary declaration cannot impersonate a module. Three consequences, each deliberate rather than incidental. A module candidate skips the on-chain exposure filter: module-sibling exposure gates on same-module plus source order, both within-file relations, and a module name is visible across files by design. A value reference is admissible against a namespace segment, because the parser mints the head as ExprVar and the reference site genuinely cannot know whether a bare name is a local binder, a module member or a module. And `data name: T = v` needed its own child-stamping arm beside the lexical binder's: the catch-all stamps every child Unclassified, which loses the reference the value expression carries -- measured, the provider file's own constructor reference stopped binding, so admitting a file did not admit what it declares. Isolated receipt, no type reference to the provider anywhere in the fixture: module tmp.e.c type Str2 = TOne | TTwo data mine: Str2 = p.first -- the only cross-file reference is the head Settled: 2 file(s) admitted, 1 edge(s), 2 iteration(s) WHAT THIS IS NOT. It binds the HEAD, which is what a file dependency needs -- the provider file follows from the module declaration's own file. It does not descend to the member, so a bound head with a missing or ambiguous member is not distinguished here; that belongs to the resolver cutover. The dissolution trigger is the ReferencePath carrier both syntactic positions feed, at which point the parser mints the head as a namespace reference and the category admission above stops being needed. MEASURED AND NOT FIXED, pre-existing: a constructor reference at module scope does not bind. Constructors are module-scope exposed by category, but exposure derived from containment gives them LexicalExposure scoped to the type body, because their ancestors are [module, type] rather than [module]. Cause located at declaration_exposure_from_containment; not repaired here because it changes the exposure authority again and is independent of this commit. parser_sibling_match_arm_pattern_binder_holds fails, and the evidence says it is not from this change: main hardcodes the same ModuleLocalMemberExposure grounding this branch passes explicitly, the fixture contains no module-value item, and no module segment is named x. Its own note parks it, stating the property does not hold from authored source because match-arm bodies stamp as siblings of pattern binders. Green by execution: closure 10/10, bridge 21/21, parser matrix 20/20. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A module-scope reference to a constructor did not bind. Constructors are declared module-scope exposed by the category authority, but exposure derived from containment gave them LexicalExposure scoped to the type body, because their ancestors are [module, type] rather than [module]. So a provider file could be admitted and still fail to supply what it declares. Containment alone cannot decide this. A constructor and a field are both children of a type node and derive identical ancestors, yet one is reachable at module scope and the other is not, so shape carries strictly less information than the question needs. The nested arm now asks occurrence_category_module_scope_exposure_verdict -- the authority that already owns module-scope membership -- rather than guessing. This is not category substituted FOR exposure: the decision site still reads only DeclarationExposure. It is the grounding chosen at derivation, which is what the exposure authority already requires of its callers. The discriminating control is a pair at identical depth: nested ConstructorOccurrence derives ModuleExposure, nested FieldOccurrence stays LexicalExposure scoped to the type body. Same containment, opposite answers, so the rule cannot be satisfied by anything that merely widens exposure. End to end on the realistic shape -- a provider declaring a type with constructors and a datum initialised from one, reached by expression-position projection: module tmp.k.p module tmp.k.c type Str = SOne | STwo type Local = LOne | LTwo data first: Str = SOne data mine: Local = p.first Settled: 2 file(s) admitted, 1 edge(s), 2 iteration(s) THREE FIXTURES WERE MISLABELLING THEIR OWN SUBJECT and are corrected rather than accommodated. nested_containment_derives_lexical_exposure_holds and the seed binary's two_ancestors_lexical_exposure both passed TypeOccurrence while calling their subject a binder; a nested type IS module-scope exposed, so under the new rule they failed for the right reason. Both now carry LexicalValueOccurrence, which is what a binder is. The clause-E fixture's exposure rows now carry the same category its declaration rows already declare. Changing a test because it broke is usually the wrong repair; what distinguishes these is that the fixture disagreed with itself, and the new constructor/field pair is what actually pins the behaviour. Green by execution, each run to completion against its roster: closure 10/10, bridge 21/21, type-ref context 8/8, cross-file assembly 9/9, pool independence 8/8, candidates 23/23, parser matrix 20/20, and the compiled seed witness binary all cases pass. NOT CLAIMED: a clean whole-corpus local run. Two attempts were killed by their timeout mid-file at 545 and 6455 of 7472 witnesses, and I quoted both as totals before checking that either finished. Zero failures across ~5750 executed witnesses is what those runs support. The corpus verdict comes from CI, which completes; gunbc#8244 measures why the local shape does not (1,927s preparing entry-private worlds for 148s of evaluation) and is the reason to stop paying it per push rather than to pay it for longer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…defect The note this replaces was itself written to supersede a stale one and went stale within a day, so it is now dated and reads as a measurement rather than as a standing description. The substantive change is how expression-position work is characterised. It landed at module-head grain only, and 'descent is unimplemented' understates the consequence: a path whose member is absent or ambiguous still discovers a provider file, so the resulting edge is justified by the module head rather than by an accepted terminal declaration. Named as a provisional loading widen that may not become the final dependency authority, with the ReferencePath carrier as its closing condition. Also records why the corpus migration must be derived rather than hand-judged: the population moves while the lane works — 18,628 import lines across 2,884 files at this measurement, and one in-flight PR moves it by +147. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The head-only widen named in the previous commit is closed, and it was worse than "descent is unimplemented". Reproduced before the repair: module tmp.m.p module tmp.m.c type Other = OOne | OTwo data mine: Local = p.no_such_member Settled: 2 file(s) admitted, 1 edge(s) A file dependency was asserted against a provider that declares no such member. The edge rested on the module head, which names only where to look. THE MECHANISM, which is a category answering a question it was not asked. An expression path is a FieldOccurrence reference whose base is its child, and FieldOccurrence is excluded from clause-E dependency inducement -- correct for a record field access. That exclusion was applied to the DEPENDENCY question and silently answered the BINDING question too: an excluded reference is never added to the required population, so it never had to resolve at all. Exclusion from edge derivation had quietly become exemption from binding. A projection off a module head is not a record field access, and the difference is decidable at resolution rather than at the category: the base resolves to a NamespaceSegmentOccurrence or it does not. When it does, the segment resolves among that module's own members and the dependency is attributed to the TERMINAL declaration, which is what a file dependency actually rests on. Both directions, by execution: member exists -> Settled: 2 files, 1 edge, 5 provenance rows member absent -> Refused: 'no_such_member' Unbound, located at the segment A second gate had to move for the positive case, and finding it required distinguishing two states that look identical. Candidates WERE supplied for the existing member and every one was filtered out by category admissibility -- FieldOccurrence admitted only FieldOccurrence -- which reads as Unbound and is indistinguishable from a member that does not exist. Both fixtures refused for what looked like one reason and was two. The arm now admits module-scope member categories, narrow in effect rather than in statement: candidates for a FieldOccurrence reference are supplied at exactly one site, reached only after the base has resolved to a module, so an ordinary field access supplies nothing and cannot reach a module member by widening. DISSOLVE-ON, for both this and the head admission: the ReferencePath carrier gives a projection segment its own category at derivation, at which point a segment stops impersonating a field and both widenings are deleted rather than kept beside it. This commit closes the fail-open; it does not yet unify the two syntactic positions into one carrier. Green by execution, each run to completion against its roster: closure 10/10, bridge 21/21, candidates 23/23, pool independence 8/8, binding resolve 10/10, cross-file assembly 9/9, type-reference context 8/8. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
parser_sibling_match_arm_pattern_binder_holds cannot pass from authored source, and the parser is the reason rather than the witness. v1.compiler.parse stamps a match-arm pattern binder with the ARM's ancestors, so the binder is a SIBLING of the arm body rather than an ancestor of it; its containment-derived LexicalExposure has an exposing scope that does not contain the arm-body reference, so the isolation asserted here -- each arm's reference binding its own binder and refusing the other arm's -- cannot hold however the exposure authority is written. The file's own note has said this since the B1 rollup. What it lacked was an ADMISSION: a note is not enrollment, so the function stayed an ordinary green-required test that happened to run only when something in its import closure changed. gunbc#8115's dag/std/occurrence_binding_resolve change selected it for the first time in this lane, and it read as this PR's regression. The CI history says otherwise precisely: green at a4f6bbd, whose diff is a roadmap note and selects no src/v1 witness, and red at b4f16ae, whose diff is in that closure. Cost of the missing row, recorded because it is the argument for adding it: two bisect cycles reverting correct code against a subject I had not confirmed was the failing one. The CI log does not carry the failing witness name, so I substituted the one failing locally -- which passes in CI -- and tested theories about it. Identify the failing subject before forming a theory about the cause. The equivalent property is discharged on a hand-built transport where the arm body nests under the binder occurrence, by occurrence_binding_candidates_witness, so this row loses no coverage. It stops a known-structural red from being rediscovered as a new one. Dissolution is the parser nesting change the witness note already names, at which point the row deletes and the function re-enrolls. exact_witness_admission_witness_test 18/18. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main # Conflicts: # .gitattributes # .github/workflows/ci.yml
… main merge Both conflicted paths are generated. The merge driver marked them unmerged without markers, which is its documented behaviour for generated artifacts, so neither side was the answer: resolved to main's side to close the merge, then regenerated. The derived delta is this branch's new emitted modules entering the generated-artifact merge list and the heal exclusion list. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main
…lment owes Enrolling parser_sibling_match_arm_pattern_binder_holds in known_red_probe_v1_envelope_roster appends one RunnableDiscoveryBatch to the floor schedule. It is not a RunnableScopedWitnessBatch, so it carries no scoped clamp and falls to the positional table, which still had six rows for seven batches — claim_executor refused fail-closed at arm time, exactly as v1_claim_scoped_known_red_probe_batch_note's ENROLLMENT COUPLING clause says it would. Row: overhead 240s, per_unit_ms 1000 (the signed family witness coefficient, so a second enrolled probe re-denominates rather than being absorbed). Basis, carried in gunbc_ci_v1_envelope_known_red_probe_clamp_basis_note: 95.6s measured local x86 wall for the single enrolled row, deliberately marked as NOT a fleet observation, which is why the margin is ~2.5x rather than the family's usual 1.6x spread factor. witness_scoped_batch_is_singleton_and_outside_positional_clamps green by execution; no generated-artifact drift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nt terms
Landing the clamp row got the walk past arm time, and the corpus then named
three real reds — all the same shape, and all mine: the conditionally-appended
known-red v1-envelope probe batch was visible to the schedule side of three
laws and invisible to their declared side.
- gunbc_ci_floor_enrolled_runnable_labels_for omitted the probe entirely, so
witness_floor_schedule_preserves_enrolled_set saw a set difference. Both
conditional batches now carry a term, mirroring the native arm.
- witness_live_floor_discovery_batch_count_is_four pinned four discovery
batches; the probe is a fifth. Renamed to _is_four_plus_enrolled_probes with
the conditional as a named term, so four still reads as the unconditional
population and an enrollment stays visible rather than folded into a constant.
- witness_floor_appends_one_selected_native_batch counted schedule + scoped + 1;
the probe entered its constant. It now has its own term, so a claim about the
native lane cannot red for a reason belonging to the probe.
ci_floor_plan_witnesses (the 33-member conjunction root),
witness_floor_schedule_preserves_enrolled_set,
witness_floor_batch_clamp_params_cover_schedule,
witness_live_floor_discovery_batch_count_is_four_plus_enrolled_probes,
witness_floor_appends_one_selected_native_batch and
witness_scoped_batch_is_singleton_and_outside_positional_clamps all green by
execution; no generated-artifact drift.
The fourth failure in that run, arrow_body_form_eval_value_vertical_holds
("no field 'root' on type 'Node'"), is inherited main red from #8242 — it is the
sole failure on main's own runs 31824195524 and 31824260033 — and is being
repaired by #8269. Nothing here touches it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main
…producer WORK IN PROGRESS on the terminal draft — the carrier and producer land here with no consumer yet; the resolver and the two call-site cutovers follow in this same commit series, and only then do the two standing widenings dissolve. This PR is not independently mergeable by construction, so this is an in-flight state rather than an unconsumed artifact being landed. ReferencePath is what both spellings of a projection fold into. A type path is one occurrence carrying the whole dotted text; an expression path is a base reference plus one FieldOccurrence node per segment, the base reachable as the segment's containment child. The producer decides the dotted case from the authored text alone and otherwise walks down containment children. Two shapes are deliberate. The head is a NAME plus a span, not an occurrence identity the type spelling never allocated. And a segment carries its own span where the spelling gives it one and the whole path's span where it does not — an honestly coarse location, never a fabricated offset into a blob. Every failure arm refuses: an unindexed occurrence, a branching projection (more than one containment child is a shape this producer does not model, so it names the count rather than picking a child), empty segment text, and an unbounded descent are four distinct typed reasons, not one absorbing "no path". Established by execution before the shape was chosen, since the resolver's descent rests on it: a module member's containment parent IS the module declaration occurrence, so one containment-child step is the uniform segment rule and the qualifier suffix-match becomes removable rather than being generalised. The probe that established it was temporary and is not committed; Commit A's own controls pin it discriminatingly (bound head/bound member, bound head/missing member, bound head/ambiguous member with exact identities). Compiles clean: 0 blocking errors on the dag target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…uisite The frontier paragraph described the head-only widen as live — p binds and admits its module file while the member never resolves. That has not been true since the one-segment terminal-member resolution landed, and the row went stale inside a day. Recorded as a correction rather than a rewrite, because reading a superseded frontier as current sends the next reader to repair a fail-open that is already closed. Same correction applied to the PR body. What is actually open is restated as a SHAPE obligation, not a safety one: the one-segment repair keeps two temporary representations beside each other — a projection segment impersonating a FieldOccurrence (so binding compatibility was widened at a field reference, held safe by caller behavior rather than by construction) and a module head decided twice, once by the reference fold and again by a segment-index reconstruction. Both dissolve into ReferencePath, which consumes the accepted head binding rather than re-deriving it. Also names a prerequisite the row previously omitted. The match-arm binder known-red admission is not a resolution: the parser stamps the binder and the arm body as siblings, and when the structural resolver becomes the ordinary resolver ordinary local lexical references must still bind. Repair parser containment, green the witness, delete the admission along with the conditional batch and clamp row that exist only to carry it, keep the witness as a permanent control — rather than accumulating more CI accounting around a parser defect. No production node accepted; imports, grammar and AST all still present. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e first half owed THE CI FAILURE FIRST, because it was mine and the cause is worth stating: dag/std is a stage0 self-compile input, so the carrier commit needed the two-pass regen and I ran only the generated-artifact gate. That gate does not cover stage0 staleness — regen_verify_gate_passes does — so "no artifact drift" was a true statement about the wrong population. Seed regenerated, rebuilt, and verified: regen_divergence_count=0. Rebuilding also surfaced an emitter limitation rather than a modeling one: a fold whose element parameter is discarded emits a by-value closure where the iterator yields a reference (E0631). Replaced with length, which is the simpler spelling anyway; no behavior changes. THE RESOLVER. resolve_reference_path binds the head exactly once through the same on-chain-plus-named-modules rule an ordinary bare reference uses — there is no second segment-index reconstruction of the head beside it, because two derivations of one fact are two chances to disagree silently. Every later segment is a containment-child step, uniform for the first segment and the tenth, which is what the measured module-member containment relation bought: the qualifier suffix-match is removable rather than something to generalise. The cardinality rule is identical at every step and special-cased nowhere: zero children Unbound, one descend, more than one Ambiguous naming every candidate — never a nearest match, never first-wins. WHY THIS IS A WALL AND NOT A CHECK: the only value carrying a terminal declaration is produced by consuming every segment, so a head that bound while a segment did not has no representation as a resolved path. A caller cannot read a provider file off a partial descent, because a partial descent yields a refusal and refusals carry no declaration. CONTROLS, green by execution on real parsed source (not hand-built values), each a different decision so they are not one claim written three ways: - head and terminal both bind -> resolves to the TERMINAL declaration, asserted by the terminal's own authored spelling rather than the module head's; - head binds, segment names nothing -> refuses AT THE SEGMENT. This is the discriminating red for the head-only widen: under that widen this same input produced a ready dependency; - head names nothing -> refuses at the HEAD, before any descent, so head and segment failures stay distinguishable rather than collapsing to one Unbound. The resolved case is the positive control the refusals are read against — without it, refusals are satisfiable by a resolver that refuses everything. Whole file 24/24, denominator checked against the test fn roster. STILL OWED before the widenings can be deleted, stated rather than implied: the expression-spelling parity case, multi-segment a.b.c, ambiguous member and ambiguous head, and the ordinary record x.field negative that must never consult module members. The resolver handles them by construction; nothing has executed them yet, so nothing here claims they pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…delete-imports-on-main # Conflicts: # .gitattributes # .github/workflows/ci.yml # dag/gunbc/ci_layer_roots.dag # dag/gunbc/stage0_emit_plan_generated.dag # src/v1/stage0/src/lib.rs # src/v1/stage0/src/v1_compiler_parse.rs
…dinary field access Three more controls, all green by execution on real parsed source, and one of them forced a carrier change rather than merely passing. THE CARRIER CHANGE. A dot is not always a namespace step. x.field on an ordinary record binder is a field access: it induces no cross-file dependency of its own (the dependency came from the reference to x's TYPE) and its member is a field of a type, not a member of a module. Answering it with SegmentUnbound would report a correct field access as an unresolved name — the fabricated-plausible-output failure aimed at a well-formed program — and answering it with a resolved path would attribute a dependency to whatever declaration happened to match the field spelling. So the head's own category decides: only a NamespaceSegmentOccurrence head descends, and any other head with segments returns ReferencePathNotANamespaceProjection carrying the head declaration. That is deliberately neither success nor error: there are three outcomes, so callers handle three. That control also executes the EXPRESSION spelling of the producer end to end — the field-access occurrence walked down to its base, the base bound, and the category gate answered — which is partial type/expression parity evidence rather than an assertion that parity holds. AMBIGUITY AT BOTH GRAINS, since one is not evidence for the other: - two modules whose last segment is live_tree refuse at the HEAD, before any descent, naming both candidates; - one module declaring the same member twice refuses AT THE SEGMENT, naming both. The duplicate-member fixture is deliberately not a well-formed program: the subject is what the resolver does when a segment has two candidates, and no well-formed provider had to be corrupted to ask it. The control closure takes its provider SET as a parameter because cardinality is a property of the assembled population, not of the reference text — neither case is expressible by editing the consumer. Whole file 27/27 against the roster; seed regenerated and verified at regen_divergence_count=0. STILL OWED: multi-segment a.b.c, and full type/expression parity as its own assertion rather than as a by-product. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nd two real defects The last commit under the incremental strategy, per the operator ruling: this completes the in-flight carrier work, and no further production resolver or loader architecture lands on this branch. THE SPLIT RULE WAS WRONG, and it looked right against the corpus. The producer split at EVERY dot and took the FIRST segment as the head, which happens to work for the import-era spelling live_tree.LiveTreeDisposition -- one qualifier segment, one member -- and fails for everything else. It is now the LONGEST PREFIX naming a module: segments are consumed into the head while they still name one, and the rest is descent. That CORRECTS what I reported earlier. I said a fully qualified reference could not be represented and that the qualification policy was therefore coupled to the producer. It is not: module_named_by_qualifier already admits both an exact path and a suffix, so one rule answers both spellings. Proven by execution: v2.std.live_tree.LiveTreeDisposition resolves to the same terminal declaration as live_tree.LiveTreeDisposition. Full qualification needs no producer work. MULTI-SEGMENT descent is real rather than synthetic. Modules are flat per file, so a.b.c cannot be module-inside-module -- but a module member can have members, so live_tree.LiveTreeDisposition.ReadsLiveTree is module, then type, then variant: three segments, two containment steps, exact terminal. TWO DEFECTS FOUND BY EXECUTION, neither in the semantics. (1) A pathological rustfmt blowup that would have wedged CI's regen job. Seed regeneration formats the whole stage0 crate, so ONE emitted file can stop it: my fixture used a ~20-term string `+` chain and its emitted file did not format in 600 seconds, against 0.19s for the previous revision. Measured rather than guessed -- I first flattened my own module on suspicion, which changed nothing (0.166s either way), then bisected file by file. Rewritten as a single literal: 0.086s. The rule for emitted code is long binary-operator chains are superlinear in rustfmt; prefer one literal. (2) The known-red probe batch redded CI with FLOOR-BATCH-CLAMP-REFUSED. Its SelectionApplied resolves selection machinery from the BATCH's roots, which are deliberately dag plus src/v1, so affected_set_floor_runner had no provenance and the run refused fail-closed -- the machinery correctly reporting it is outside every root. The sibling scoped batch escapes this only by being a RunnableScopedWitnessBatch with InheritedWalkSourceRoots; a plain discovery batch has no such authority. Flipped to SelectionOff, which costs nothing: the roster is a handful of explicit expect-red entries, so there is no population to skip. Widening the roots was rejected -- it moves the subject envelope and invalidates the measured clamp basis. Bridge witness 29/29 against its roster; floor-plan conjunction green; seed verified at regen_divergence_count=0; no generated-artifact drift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… reading, not live status The operator's planning-thread review flagged the #8244 clause as already stale — the receipts sentence presented moving open branches (#8115, #8244) in present tense with live numbers, the exact §3 stale-citation class this same section warns about. The measurements stay (they are the receipt of the 2026-08-15 replanning reading); the tense and a dating clause now say so explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-08-15 bankruptcies as the closing receipts The operator's sharpened diagnosis lands in the weed paragraph: every intermediate state of a tip-first deletion must keep X alive and green, so the deletion program degenerates into maintenance and then optimization of the thing being deleted. The receipts clause records the completed disposition: #8115 and #8244 both bankrupted 2026-08-15, frozen as quarry, recut as delete-first programs (floor: delete the CI step, re-add obligations one by one from first principles; imports: strip all 19,173 authored import lines, work the typed diagnostics forward class by class). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… plus the gunbc.replacement_cut planning carrier (#8276) * DESIGN §3 standing rule: replacement migrations cut over at the root, plus the gunbc.replacement_cut planning carrier Encodes the migration doctrine developed across the operator's design threads (2026-08-15) as a §3 standing rule in gunbc.design_document, with DESIGN.md regenerated from it in the same change: - replacement vs refinement; the six-step vertical plan; atomicity is the authority transition, never the diff size - consumer-relative roots and supersession before translation: covered descendants are a deletion population, no Y counterpart owed - consumers must earn survival: the census runs over dispositions, not raw edges; reliance establishes migration cost, never correctness; admission is two zeros (undispositioned = 0, uncovered surviving = 0) - greedy root-first search: attempt the maximal cut, descend only on an exact refusal (Y-incomplete / escaping consumer / opaque -> bisect); deep cuts are the fallback decomposition of a refused root cut - evidence for surviving claims is re-enrolled; evidence whose only subject is retired behavior retires with a receipt - terminal receipt gains the two disposition rows gunbc.replacement_cut is the contract-grain planning carrier the rule cites: ReplacementCut (why_not_higher required by construction), ConsumerDisposition, EvidenceDisposition, admit_replacement_cut refusing typed and all-causes-counted. Witnessed by execution on synthetic fixtures with RED controls (8 witnesses green; compile-clean 0 blocking). Standing, attempt receipts, the outcome ledger and the roadmap projection are the named next layer (the migration-cut authority program), deliberately not pre-built here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Reconcile the DESIGN evidence-axis wording with the carrier: parked IS the blocking parking state Review 52276 read "or visibly parked" as a fourth completed evidence disposition the carrier lacks. The carrier is the intended semantics: EvidenceDisposition has three terminal arms plus EvidenceUndecided, the visible parking state that blocks admission exactly like a consumer's Undecided. The DESIGN sentence now names the symbol and states why no admitted parked arm exists: a deliberate deferral is still not a disposition against the terminal design, and admitting it would re-open the undecided-treated-as-retained hole under a politer name. Wording fix + regen only; no carrier change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Date-pin the §3 receipts clause: open-branch measurements are a dated reading, not live status The operator's planning-thread review flagged the #8244 clause as already stale — the receipts sentence presented moving open branches (#8115, #8244) in present tense with live numbers, the exact §3 stale-citation class this same section warns about. The measurements stay (they are the receipt of the 2026-08-15 replanning reading); the tense and a dating clause now say so explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Delete-first: the deletion is the census (operator rulings, 2026-08-15) Rewrites the replacement-migration section's execution order from build-beside-then-cut to the ruled default: delete X's production presence as early as possible, fix forward minimally with the new solution. The mechanism is named — a surviving X is an attractor that captures agent attention (studying becomes preserving) — and the up-front obligation census is itself struck as usually the attractor at work: in a fail-closed substrate the deletion IS the census (what refuses is what was load-bearing), the deleter owns fixing forward until green, and only the silent residue (un-enrolled evidence, external consumers) is covered by the declared 4b rung-drop instead. Carve-outs: gap-intolerant boundaries keep the staged shadow form; where no minimal Y can hold the boundary at all (the v1 seed before a candidate image exists) X stays frozen — no new investment, quarry-in-place. Restoration closes against green plus the declared residue, never against output-parity with X. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Harden the cut carrier per the 2026-08-15 planning-thread review: sealed digest-bound verdict, explicit census, closed X-role vocabulary Finding-by-finding: - Forgeable/unbound verdict: AdmittedReplacementCutPlan is now a sole_constructor record minted only by the admission fold (renamed admit_replacement_cut_plan — it judges the plan, and the vocabulary says so), carrying cut identity + a criteria digest over every plan field; admitted_matches_plan recomputes. Cross-module construction or cast refuses at compile time; an edited plan stops matching. - Internal-coherence walls: duplicate consumer/evidence/region rows refuse (one subject, one disposition — agreeing copies are still a fork); old_root_consumer == new_root refuses; coverage or ReplacedByY naming the old root refuses (fallback wearing a disposition); self-referential descent refuses. - Bottom-conflation: boundary_census is ConsumersEnumerated | BoundaryDeclaredEmpty{basis}; enumerated-but-empty refuses. - Typed descent: HigherCutRefusedBy -> DescendedFromRefusedCut naming the parent by ReplacementCutId, joinable, not prose alone. - Closed X roles: ExternalXRole (bootstrap producer, differential oracle, corpus rewriter, historical measurement) — a forbidden role has no constructor; NoExternalOracleRequired is a justified arm so absence is never ambiguous. RetireEvidence gains retirement_reason. - DESIGN: DFS/BFS wording removed (consumer-backward vertical); "substantially unchanged" clarified (semantic authority + terminal consumer survive, internals may refine); carrier sentence updated to the new symbols; present-tense roadmap claim corrected to a future obligation — no roadmap node is structurally registered to a cut yet. - Frozen-X sharpened from the live cli_run finding: frozen includes growth surfaces — a builtin registry or escape-hatch arm in a frozen X accepts no new rows (38 of 125 interpreter builtins had accreted into one driver file because the surface accepted them). Deliberately deferred, named in the module note per the review's own no-string-shaped-promises principle: exact joins against independently OBSERVED consumer/obligation/evidence/region populations (no producer exists yet), obligation-grain coverage, executed parent-refusal and census receipts, retirement-receipt authority, multi-root cut-set populations. Those are the migration-cut authority program. 17 witnesses green incl. 9 new adversarial plan-grain controls; compile-clean 0 blocking; DESIGN.md regenerated byte-matched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Seal the mint, refuse the empty external-role list (review 52304) Both findings verified real and fixed: - admitted_from was an exported ungated mint reachable by any importer, contradicting the note's "minted exclusively by the admission fold". Replaced by mint_admitted, admit_callers-sealed to admit_replacement_cut_plan alone — the verdict is now sealed twice over: sole_constructor blocks cross-module literals and casts, the caller seal blocks the in-module helper route. - admission never inspected external_x, so ExternalXRoles { roles: [] } admitted while the DESIGN sentence claimed the empty list was refused. ExternalRolesEnumeratedEmpty now refuses (the same bottom-conflation class as EnumeratedCensusEmpty), with a paired witness: empty list refuses, justified NoExternalOracleRequired admits. 18 witnesses green; compile-clean 0 blocking; DESIGN.md regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Encode the general form: delete the subject, solve incoming problems one by one via first principles The operator's distillation (2026-08-15), stated as the general behavior rather than a migration special case, lands in the fix-forward step: each breakage is asked what the broken reference IS in the terminal model — fix Y, migrate the corpus with X as offline oracle, or retire — never restored by reflex to the old binding. Bulk restoration under a red tree is the attractor's last trick. Class grain, decided deliberately and in sequence; mechanical application within a class. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Tip-first deletion is self-defeating by construction; record the 2026-08-15 bankruptcies as the closing receipts The operator's sharpened diagnosis lands in the weed paragraph: every intermediate state of a tip-first deletion must keep X alive and green, so the deletion program degenerates into maintenance and then optimization of the thing being deleted. The receipts clause records the completed disposition: #8115 and #8244 both bankrupted 2026-08-15, frozen as quarry, recut as delete-first programs (floor: delete the CI step, re-add obligations one by one from first principles; imports: strip all 19,173 authored import lines, work the typed diagnostics forward class by class). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * The operative loop as a sequence block: recurse-on-weed arm and the two-census distinction Operator's compressed sequence (2026-08-15) lands as a code block ahead of the numbered obligations: back up to the root of the weed and delete it; for each literal compile error solve from first principles — implement the terminal solution, migrate the corpus with X as offline oracle, retire with a receipt, or recurse when the error names another weed; stop at green plus the declared silent residue. The fix-forward step gains the fourth (recursion) arm and the load-vs-concealment distinction: deletion surfaces what depended on X AND what X was hiding — a load gets a disposition, an uncovered defect gets a root-cause fix in Y, because it was always broken and X merely made it unobservable (receipts: the import strip's declaration-registration gap; the floor deletion's absorbed whole-tree defects). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * The cost of deferring: the consequence catalogue, and the integration-branch vehicle for breaking cuts Two operator directives (2026-08-15) folded into the §3 replacement-migration rule. The consequence catalogue: while X stands, every nearby question is answered in X's vocabulary, so decisions are continuously premised on assumptions already scheduled for death — waste, propagation, evidence inversion, unmarked premises, each measured on the two bankrupted branches (receipts cited, not restated). A3 grounds it: a dead assumption is time-unstable, so building on one cites an authority already known to be revoked; the frozen-X freeze is premise-supply capping, not thrift. The SCM vehicle: a breaking cut never lands on main mid-loop — fork an integration branch, root deletion first commit, fix-forward there, one atomic cutover merge. integration/namespace-cut and integration/floor-cut created at main 64ebefa. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Delete-first as forcing function: with X gone, solving normally is the only reachable move Operator, 2026-08-15: 'if we do that, we're forced to solve the problem normally, as opposed to the existing approach.' Encoded as the consequence catalogue's inverse — deletion makes the cheapest next action and the first-principles action coincide — plus the standing exercise that opens every cut: enumerate what is certainly scheduled for death and delete it before any fix-forward work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * File-grain plans for the first two cut programs: floor (FLOOR-Y) and namespace (NAMESPACE-Y) Operator-directed 2026-08-15: plans/designs for both cuts with actual filenames and steps. Floor: wipe all of CI (ci.yml, falsifier.yml, falsifier-alert.yml and their emitting authorities in one motion), then re-add jobs one at a time by operator agreement, each re-add recursively delete-first — the old jobs are presumed crufty. Namespace: grammar deletion (import refuses at parse via a refusing production), then the import-name universe, host/emit machinery, the four repoints, then census fix-forward by real-specimen instrumentation. Both carry the step-gating rule (each major step closes on operator satisfaction), quarry-as-oracle-only roles, the regen-twin traps, and their ReplacementCut registration obligation. Linked from the §3 section per the orphan-doc wall; doc witnesses PASS (doc_graph_has_no_orphan_docs, doc_graph_has_no_dangling_links); DESIGN regenerated (main_wet ExitSuccess). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Namespace plan corrections from the step-1/2 boundary report Repoint (d) reclassified as restoration: the strip already silently emptied the emit use-line channel (the mask guards on source_visible_names, empty everywhere post-strip), so Rust emission is degraded until the containment-derived supply lands and emit-green before it is the suspicious result. Green bar gains the restoration item; flat topological ordering noted; the attribute-orphan surgery trap recorded (three measured defects, plus the repo-wide repair sweep that removed legitimate derives). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Floor plan: wipe landed and accepted; re-add #1 approved with the single-fold spec Operator rulings at the wipe boundary (2026-08-15): wipe accepted as landed (3a63982, -18,716 cumulative); re-add #1 approved with the spec verbatim — a single github actions emission into our own binary, running all test witnesses in the repo via a single fold — subsuming the build and witness-corpus queue items; the retained ci_workflow/ci_spec vocabulary resolves by re-homing the ten fleet step constructors into a fleet-owned module and deleting the remnants. Observed-ledger additions recorded: silent-drift exposure, the orphaned merge-admission stamp, the lost cold control, fmt-as-bypassable-hook. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Existing designs are not substitutes for deletion; namespace plan corrections from lane divergences Operator ruling encoded as its own §3 paragraph: a design authored while X lived is premise-contaminated in its sequencing — terminal shapes and maps survive as quarry, orderings never defer the deletion (live specimen: the cli_run hollowing plan's chunk ordering, cited to defer the deletion minutes before the operator ordered it cut). Both cut plans carry the one-line rule. Namespace plan corrected per the lane's divergence report: the raw-text reference scanner is refused as a §4 heuristic (edge-in-prose receipt) in favor of parse-then-derive from the Node tree, homed outside cli_run.rs; the regen-suspension declared gap and the banked-behaviors reachability obligation recorded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
|
Queue hold — authority-touching PRs (operator ruling, 2026-08-20) This PR modifies This is a queue hold, not a judgement on the change. Nothing here is wrong and nothing is being asked of you. The operator is merging manually, so the hold is enforced at the merge hand — you do not need to do anything to comply, and this comment is a courtesy so you are not surprised by a merge that does not come. Why the hold exists. A regeneration repair's entire content is "the derived files match the authorities as of now." Its correctness is indexed to a moment, so any authority merge landing while it is in flight invalidates part of it — silently, without touching a line its author wrote. Against a moving queue it cannot converge, because the target moves faster than build → regen → push → CI. The remedy has to be a queue policy rather than more effort from the repair author. Expected duration: short. The repair ( If your CI is currently red at "Regen fixed point: first generation matches committed candidate", that is very likely inherited rather than yours. Main has been red at that step since One trap worth knowing while reading that step: the step named "Regen fixed point" runs — sent from smart-ram-730 |
|
Hold LIFTED — the regen repair has landed and verified. The authority-touching hold posted on this PR earlier is over. Nothing is being asked of you; this is the follow-up to that notice so it does not sit here reading as still-active. What cleared it. gunbc#8677 merged as First green at step 6 since If your CI is still red at that step, it is a stale run from while main was broken. A re-run against current main should clear it. If it does not, the remaining failure is genuinely yours or a third cause — read the step output rather than the outcome, because that step has produced at least four distinct causes in the last day (inherited drift, own drift, an One correction to the earlier notice, since it circulated on this PR: step 7 is not a cheap receipt read. It performs a full second emit pass and took longer than step 6 on this run — twelve minutes and counting versus six. What it reads from the prior receipt rather than recomputing is the single value — sent from smart-ram-730 |
Draft. Terminal acceptance is the deletion of
import, its grammar and its AST. No checkpoint here is independently mergeable, and nothing in this PR is cut over. Every production capability admission stays unavailable; updating the measured frontier below is not accepting the node.Measured frontier
LANDED, by execution on ordinary source files
.dagunder the given source roots; refuses on unreadable, unparsable, duplicate or contradictory candidates rather than shrinking silentlyAmbiguousnaming bothdata name: T = vmintsModuleValueOccurrence: module-scope exposed, clause-E inducing, admissible from a value referencepinp.firstbinds to a module declaration and admits that module's fileSettled; member absent → typedUnboundlocated at the segment; the edge is attributed to the terminal declaration, not to the module headConstructorOccurrence→ModuleExposure, nestedFieldOccurrence→LexicalExposure, same containment depthOPEN
common
ReferencePath· expression-position terminal member descent · authored bare-reference migration · sealed candidate universe · ordinary compile-path consumption · old/new edge differential ·dependency_resolution_facts_livereplacement · type-env single-authority cutover · resolver/emitter terminal-identity cutover · A–F production acceptance · import grammar/AST/mechanism deletionThe immediate frontier — corrected, and the correction is the point
An earlier revision of this section said
pbinds whilep.first's member never resolves, so an absent or ambiguous member still discovers a provider file. That fail-open is closed at one segment and this text outlived it by a day. A stale frontier is not a harmless lag: it sends the next reader to repair something already repaired, which is exactly what a review of this PR flagged.What is open now is a shape obligation, not a safety one. The one-segment repair is a correct wall and a wrong terminal implementation, because it keeps two temporary representations side by side:
Both dissolve into one
ReferencePathfed by both syntactic positions — typep.TypeNameand expressionp.firstenter the same carrier — which binds the head once, consumes that accepted declaration identity rather than re-deriving it, descends one exact containment child per segment at arbitrary depth, and yields no dependency-ready outcome until the terminal declaration binds. The commit deletes the widenings; it does not preserve them beside the carrier.Established by execution before the shape was chosen: a module member's containment parent is the module declaration occurrence, so one containment-child step is the uniform segment rule and the qualifier suffix-match becomes removable rather than something to generalise.
Required controls, each a distinct decision rather than a restatement:
p.firstp.TypeNamep.no_such_memberUnboundfirstmembers inpAmbiguousnaming both exact identitiespa.b.cx.fieldA prerequisite this PR names rather than defers
parser_sibling_match_arm_pattern_binder_holdsis admitted as a known-red probe: the parser stamps a match-arm pattern binder and the arm body as siblings, so the binder's lexical exposure does not contain the body reference and the structural resolver cannot establish binder isolation from authored source.The admission keeps CI honest about a red that is structural from source. It is not a resolution, and it cannot survive production cutover — when the structural resolver becomes the ordinary resolver, ordinary local lexical references must still bind. The sequence is: repair parser containment for match arms → green the authored-source witness → delete its exact-red admission, together with the conditional floor batch and clamp row that exist only to carry it → keep the witness as a permanent regression control.
What replaced the deleted model
CrossFileProviderExportedExposureand its module-member →RootExposurepromotion are deleted. They made the whole source-root universe the visibility set, so any globally unique leaf bound bare from anywhere and a file's accepted declarations changed with which file the walk started from. The universe is now the declaration denominator and nothing more; a cross-module member is reached by projection or a local alias.Corpus standing
Closure over
dag + src/v2refuses on bareString, declared in bothdag/std/string_type.dagandsrc/v2/std/text.dag. The corpus is authored in the import-era bare style — currently 18,628 import lines across 2,884 files, and that population grows while this lane works. The migration is therefore derived, never hand-judged: old imported binding identity must equal new import-blind identity, per reference, with onlyEquivalentRewriteapplied mechanically, against a pinned subject.Coordination with #8244
One typed seam, and a denominator to reconcile first.
PreparedWholeTreeSubjectseals by capability — it holds no index, no source roots, no resolver — which is the shape this lane's sealed universe should take.cli_run.rspath here.dag + src/v2; FLOOR2 cutover: every SelectionOff floor batch runs against one prepared subject #8244 reports its own module population, which has moved at least once while this PR was open. This line deliberately does not transcribe that count — a copied number is a second representation that goes stale silently, and the earlier revision of this bullet proved it by quoting a figure FLOOR2 cutover: every SelectionOff floor batch runs against one prepared subject #8244 had already superseded. Cite the PR, reconcile at identity grain: source roots, exclusions, file population, module population, duplicate-module handling, invalid fixtures, modules without storage rows, storage rows without admitted modules. Completeness is an identity join, not an agreement of counts, and the accepted denominator becomes a typed receipt.Evidence discipline
Targeted rosters are run to completion against an explicit denominator; the corpus verdict comes from CI, which completes. Two local whole-corpus attempts were killed by their timeout mid-file and were quoted as totals before completion was checked — retracted in
d72aba6's commit message. Zero failures across ~5,750 executed witnesses is what those runs support, and no more.Targeted, complete: closure 10/10 · bridge 21/21 · type-reference context 8/8 · cross-file assembly 9/9 · pool independence 8/8 · candidates 23/23 · parser matrix 20/20 · compiled seed witness binary all cases.