Skip to content

Run the emitted v2 compiler natively and close construct coverage - #10692

Merged
briansrls merged 54 commits into
mainfrom
cursor/v2-self-host-grounding-frontier-3100
Sep 9, 2026
Merged

briansrls merged 54 commits into
mainfrom
cursor/v2-self-host-grounding-frontier-3100

Conversation

@briansrls

@briansrls briansrls commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

What this branch does

Advances the v2 self-host direct path (plan: docs/plans/v2-self-host-direct-path-2026-09-06.md) through the XL-N "native = interpreted with every divergence typed" milestone, and closes the emit coverage frontier.

Native parity loop (emit → native build → native run)

The emitted src/v2/compiler/00_compile.dag closure is cargo-clean (171 files, no parse refusals, no cargo error identities) and the emitted native compiler binary has been executed against discriminating fixtures. Seven native-only divergence classes were found by execution and fixed at the .dag source with mirrors regenerated through the sanctioned regen path, each with discriminating witnesses:

  1. Stale PointwisePower inhabitant rows — twelve native panic sites disagreeing with the structurally rendered carrier.
  2. Fieldless record data serialized as {} where the emitted Rust carrier is a unit struct requiring null (the BoolEncodingFact panic) — fixed in src/v1/05_emit.dag.
  3. Variant record literals on the serde_json data path — now spelled from a closure-wide DataVariantWireSpelling index (EmitGraphInfo.data_variant_wire_spellings) built in 05_emit_rust.dag, so internally-tagged, bare-string, untagged, and tagged variants all serialize per their home module's declared VariantEncoding policy; ambiguous same-name coproducts insert a fail-closed SpellingRefused.
  4. Compose ambiguous-leaf poison in v2_std_integer.rs (locality wins).
  5. Nat unresolved in v2_lens_fact_density.rs (qualified reference without import).
  6. S: Clone bound propagation gap in std_realization_measurement.rs (transitive over call hops).
  7. Use-line planner qualification for qualified references reaching the emitter as bound bare leaves.

Parity evidence: reject-path parity holds across four named fixtures (native and interpreted reject with identical diagnostic multisets — all rostered known-frontier causes in compile_door_ledger.dag, not divergences), and accept-path parity is byte-identical on the add slice (native emit() output == interpreted emit() output == authority serialization).

The milestone statement, bounded to what the carriers establish: no unclassified divergences remain in the named native-parity fixture population, and the construct-level emit-coverage roster is 15 native / 0 retained. The coverage carrier answers only whether each construct's witness body has executed compiled-native behavior; it does not establish which engine compiled or ran the compiler itself.

Emit coverage frontier: closed (15 native / 0 retained)

Every roster row in v2.compiler.self_host.emit_coverage_frontier is now SelfEmittedNative, each backed by a native-only verdict arm (positive + wrong-octet broken control) in the file-grain-enrolled wet entry emit_host_native_only_verdict_test.dag — real cargo build, native run, verdict decoded from stdout, eval() never called. All 34 arms verified wet (PASS/PASS). With zero retained rows, the retained_via_eval_agreement constructor lost its last consumer and was deleted (DESIGN §3c); the InterpreterRetained variant stays as the disposition authority's other state. Census guards pin 15 native / 0 retained with all fifteen decl names in the closed membership.

This closes axis (a) — witness-body-runs-native — only. It says nothing about which engine compiled the compiler itself.

Required-floor repairs landing across this branch's heads

Seven classes the required-witnesses-floor lane measured red, each repaired at source rather than budgeted around:

  • chars(String) <- Variant cluster — 02_parse.dag restores structural text reads (string_head match over CharFound/CharAbsent) in place of host-carrier operations, root-causing the shared type-error cluster.
  • prepare_grammar shared-fill cost class — GrammarFirstAnalysis.nullable_set is now the enumeration it always was (List<Symbol>, the sync_tokens repair's own precedent), so PreparedGrammar passes the cross-claim tier's total portability walk, and the new nullary dag_prepared_grammar() is warm-enrolled so the fill lands during strict preparation, outside every per-claim budget. The claims the previous head's CI refused mid-fill now serve the landed fill.
  • meet/join arms over the 500 ms ceiling — split one member per claim (four claims: meet/join × holds/wrong-octet). The ceiling was not raised.
  • Five namespace-wave deltas — adjudicated at their exact subjects (the Bool/String requalification bindings in extdeps.languages.python, extdeps.languages.typescript, std.compilers.target_model, and std.integer) with transition admissions carrying rationale and dissolution.
  • Five unmasked over-ceiling claims — with prepare_grammar warm-stored, the classical_not emit triple and the produced_module pair ran to completion and measured over the line: each was re-running a pure ingested-fixture pipeline per claim (~370-382ms of the claim locally). The repair is the share roster's own named one — stop recomputing a pure function of program content — in its warm arm: produced_add_module_source (already nullary) and two new nullary classical_not arrow producers are preparation-forced, and the five claims serve the landed fills.
  • Seven grounding-specimen claims interrupted at 501-510ms (run 34311472357) — the four infer_atom_grounding_rules claims, the two infer_product_introduction claims, and the dag_binding_denotation claim all funnel through one direct-rust-door specimen pipeline (ingest→assemble→infer over the fixture's add_probe module; ~245ms assemble + ~72ms infer locally). The repair dissolved the three per-file *_specimen_inferred spellings into the fixture's home: direct_rust_door_specimen_resolved() — the deepest portable stage, since the InferredTree one stage up carries the facts PartialFunction — is warm-enrolled, and each claim re-derives infer from the served resolved tree.
  • Twelve native-only verdict claims in the 458-503ms ceiling band (run 34315228217 refused emit_host_native_only_loop_holds at cost=504ms; the other eleven match/loop/fold and complement/meet/join arms sat within one runner-swing of the line) — each claim re-ran its family's member-independent pure pipeline inline (primary trees, member assembly, emit_family, the native key: 186ms/142ms locally, measured by one-probe-per-producer claim_batch entries against 174-247ms whole-claim local receipts). The repair adds one shared EmittedFamilyCrate { source, native_key } record in v2.compiler.emit_module (the family emit authority both pipelines already import — one type, not one per family) and one nullary producer per family (mlf_family_primary_emitted, logic_family_primary_emitted), warm-enrolled so the emit lands at preparation; each claim serves the landed pair and pays only the cached native run. The ceiling was not raised.

What remains (operator-gated per the plan's autonomy contract)

  • Regen-grain flip — a real corpus module's production regen path switching generators (roadmap v2-emitter-first-behavioral-module), plus operator acceptance.
  • Required CI routing v2.test.* through the emitted native crate — the CI job roster is closed to growth without operator sign-off (2026-09-04 ruling).
  • Native bootstrap — the generator builds itself twice with evidence the second round could not reach the old compiler, then seed-retention drain.

Verification (at head 764658371c)

  • claim_executor --required-ci --source-root dag --source-root src/v2 --required-lane witnesses (local, tree identical to head): FloorClean — planned=3613 executed=3613 passed=3545 known_red_held=19, claims_failed=0, interrupted=0, completed_over_cost=0. [floor-shared-fill] shows both new warm fills landing at preparation (disposition=Stored, paid_by=<outside-fold>) with consumer_claims=6 each, and all twelve former ceiling-band claims planned-and-passed; 31 of the verdict file's 34 arms executed in this run's changed-witness population, all passed.
  • claim_batch on the 12 rewired family arms (wet): 12/12 PASS — verdicts and wrong-octet discrimination unchanged. The 3 arms outside the floor run's selection (the classical_not pair and one comparator mock — unchanged code, line-attribution not selecting them this round) verified separately by claim_batch: PASS.
  • claim_batch on pure_producer_share_refusal_test.dag live-roster controls: PASS (the two new rows collide with neither the refused nor the pending roster).
  • Checks from earlier heads remain valid for the surfaces this change does not touch: 57/57 self-host emitted-call-target witness suite, 8/8 emit-coverage frontier, 14/14 classical_not ingested file, cargo clippy --all-targets -- -D warnings clean, cargo fmt --all --check clean, regen (generated_artifact_gate.dag main_wet) no drift.
Open in Web Open in Cursor 

cursoragent and others added 4 commits September 6, 2026 16:29
…pected_red note's producer

The add-slice roster note in v2.workflow.floor_expected_red carried a dated
receipt (main 3a8344b: infer accepts dag_add_emitted_root; the
infer-then-translate composition refuses headed by infer_grounding_not_derived)
and named its own next-rung trigger: a .dag entry returning the per-stage
verdicts for one root, so the paragraph can name a producer instead of a
commit.

v2.compiler.self_host.candidate_generation_stage_verdicts is that entry,
parameterized over root and target: the receipt's verdict vocabulary
(infer_accepted / infer_rejected; candidate_accepted or the rejection head
reason) plus the carried-reasons lists -- the half the verdict symbols cannot
say, namely that infer accepts while carrying the frontier diagnostic on its
accepted path, so the enrolled witness's d == None conjunct fails even where
the composition reaches acceptance.

v2.test.execution.self_host_candidate_generation_stage_verdicts binds the
instrument to the slice's own fixture, with add_slice_stage_verdicts_entry the
runnable gunbc run --function form (ExitSuccess only when infer accepts clean
and the composition accepts clean). Two witnesses: infer-accepts as a
permanent positive control, and the frontier-state pin that is expected to red
the day the add-slice stall's trigger lands, flipping to a permanent
regression control in the same change that removes the roster row (DESIGN
4b(4)).

Measured by execution on this branch: the entry exits 1 printing
infer=infer_accepted, infer_carried=[infer_grounding_not_derived x10],
composition=infer_grounding_not_derived, composition_carried=[x11] -- the
receipt reproduced, with bind_outcome's pending-plus-gate chain counted. Both
witnesses PASS; the enrolled semantic witness still fails as enrolled.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…nd-to-end

infer gains the declared-inhabitant membership derivation: a node declared in
the dag language authority's declared-inhabitants roster derives its grounding
by lookup, with the roster as evidence -- the namespacing answer to the atom
authority question, at specimen scope. The add slice's ten type-spine nodes
(Arrow, Conj, Atom) are all roster members, so:

- candidate_generation_translate_self_emit_dag_add_slice_holds passes; its
  floor_expected_red roster row and per-row note delete per the roster's own
  stale-quarantine arm
- the dag same-language ingest path compiles end-to-end: cross_language_compile
  accepts, byte-equal to the authority's own serialization, no carried
  diagnostics
- the add-slice stall narrows to its four python/typescript round-trip members;
  the original trigger's causal clause was refuted by execution and is restated
  against the grammar parse-product population
- the instrument's frontier guard flips to add_slice_composition_accepts_holds
  (DESIGN 4b(4): frontier guard to permanent regression control)
- five manual witnesses flip with it: two root flips rewritten to assert the
  green state, three transitive conjunctions updated

The kinds stay frontier: non-member Arrow/Conj/Atom specimens carry
GroundingNotDerived exactly as before, and all fourteen enrolled
refusal/acceptance controls pass unchanged. The door's production path still
reds inside rust emission, untouched by this rule.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…joins binding to inhabitant once

The resolver already binds the surface spelling Int to the canonical binding
symbol dag_binding_type_int; what that binding DENOTES is the Int inhabitant
declared at dag_declared_inhabitants_core. Every hand-rolled fixture facts
lookup re-authored that join (dag_add_canonical_grounding_for,
record_construct_canonical_grounding_for). The language authority now declares
it once as dag_binding_denotation, and infer_node_facts consumes it: an Atom
whose identity is a canonical dag binding with a declared denotation derives
with that denotation as its grounding evidence.

Direct-rust-door specimen census: 14 underived -> 10 underived (the four
dag_binding_type_int atoms derive; grammar-production atoms, algebra atoms,
bare operand atoms, and the arrow/conj spine stay on the frontier unchanged).

Specimen-scope interim in the same frame as
infer_node_declared_in_dag_inhabitants: both delete in favor of consuming
resolution output when the resolver hands infer declaration-resolved
identities directly (the namespace migration's completed state).

Witness: v2.test.execution.dag_binding_denotation — all four Int binding
atoms in the door specimen derive with dag_int_inhabitant_node() as
structural evidence, and the two bare operand atoms stay GroundingNotDerived
(boundary control). Refusal suite 14/14, ingest bridge 7/7, add-slice
instruments 2/2 green; every remaining red in the at-risk population
reproduces identically on the pre-change tree and is enrolled in
floor_expected_red.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ntract

A point-in-time orientation that defers to the existing authorities
(DESIGN section 7, the four-wave self-host program, the roadmap node
chain, the three frontier carriers, the guarantee-stall roster, XL-N)
rather than restating them: state is re-derived by the named
instruments, never transcribed here. Sequences the remaining work in
roadmap order (door, parse-product grounding, first behavioral module,
XL-N milestones, native bootstrap, fixed point, v1 deletion) and states
which decisions stay operator-gated.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
cursoragent and others added 4 commits September 6, 2026 21:11
The sixth and seventh kind rules: a non-roster Conj or Arrow whose every
child carries DerivedGrounding derives, its evidence the same shape
re-formed over the children's grounding evidence (a fresh
OccurrenceSynthetic node, never the source — the self-evidence wall holds
by construction). A product with any frontier or absent child stays on the
frontier with its typed diagnostic; a childless product has no evidence to
compose and stays frontier. Roster members keep their roster evidence.

Measured on the direct-rust-door specimen (scratch probe, uncommitted):
10 underived of 15 -> 6. The parameter conj, the module-structure conjs,
and the bodied add arrow derive; what remains is the algebra atoms from
the + operation (AlgebraPrimitive, ring_field_add), the module atom
(dag_surface_module), the parameter references (x, y), and the
grammar-projection root conj that cascades once they land.

Enrolled witnesses (src/v2/test/claim/execution/infer_product_introduction_test.dag):
- product_introduction_derives_fully_evidenced_products_holds — census:
  4 Conj (3 derived, 1 frontier-by-frontier-child) + 1 Arrow (derived).
- product_introduction_composed_evidence_carries_child_groundings_holds —
  the params conj's evidence is a Conj whose x/y children target the dag
  authority's Int inhabitant.
- product_introduction_leaves_childless_conj_on_the_frontier_holds —
  boundary control via direct infer over a hand-built childless Conj.

Flip census (pre- and post-change, zero unexpected flips):
translate_underived_refusal 14/14, infer_self_grounding_wall 12/12,
branch_infer_if_then_else 2/2, compile_eval_thesis_proof 6/6,
ingest_bridge 9/9, cross_language_add_python_to_typescript 4/4,
inhabitant_neutralization 6/6 + e2e 6/6, emit_host_classical_not 14/14,
dag_binding_denotation 2/2, stage-verdicts instrument 2/2,
dag_add_emit_round_trip 4/6 (the 2 enrolled reds unchanged), door
production group still enrolled-red (unchanged).

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…roster membership

Two more specimen-scope derivations in infer_node_facts, both lookups into
declared authorities, never inventions:

- Canonical-operations roster (target_model.dag): every CanonicalOperation
  the target-model authority declares, rendered by
  target_model_canonical_operation_wire_node and gathered under one Conj
  root. The resolver canonicalizes surface operators (e.g. +) to those
  declared operations, so the wire atoms -- the operation discriminant and
  its field references -- derive by membership with the roster root as
  evidence. General over all 14 declared operations, not add-narrow.

- Grammar-productions roster (dag.dag): every production in
  dag_grammar_root() projected to its emitted surface atom under one Conj
  root keyed by production name. The bridge projects a production's parse
  into (identity atom, captured content) pairs, so the identity atom
  (dag_surface_module) derives by membership with the roster root as
  evidence. The roster derives from the grammar root, so a production
  added to the grammar joins by construction.

Both roster roots are Conj nodes, never structurally equal to any member
atom, so the self-evidence wall holds by construction (the first attempt
at the operations rule used the wire node itself as evidence and was
refused by grounding_evidence_is_source -- the wall doing its work).

Measured on the direct-rust-door specimen (scratch probe, uncommitted):
6 underived of 15 -> 2 (only the operand atoms x and y remain; the
grammar-projection root conj cascades once the module atom grounds).

Enrolled witnesses (infer_atom_grounding_rules_test.dag): each roster rule
pins derivation + evidence identity + census; a boundary control pins that
a bare atom with no authority membership stays frontier; the closing
control pins the 2-of-15 state.

Flip census: the product-introduction census witness updates 3->4 derived
conjs (the top conj now cascades) and gains a hand-built
partially-evidenced boundary control to replace the in-specimen one the
cascade consumed. Full battery otherwise unchanged: refusal suite 14/14,
grounding wall 12/12, instrument 2/2, binding-denotation 2/2, round-trips,
bridge, cross-language, neutralization, emit-host all green; enrolled reds
unchanged.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…aration

The fifth specimen-scope derivation, closing the direct-rust-door
specimen's inference frontier: an Atom whose binding an enclosing arrow's
domain declares derives with the declared domain type as its evidence --
the declaration-site annotation, itself derived (x: Int grounds the x
reference). This is the same lookup the branch-operand path already
performs (infer_find_arrow_domain_type_in_tree), now written to the
operand atom's own facts; it is scope-naive (whole-tree, first match),
recorded in the frontier note, and deletes with the other specimen-scope
rules when the resolver hands infer declaration-resolved identities. The
tree is threaded through the fold's init chain to reach infer_node_facts;
the helper had exactly one caller.

Measured on the door specimen (scratch probe, uncommitted): 2 underived
of 15 -> 0. The specimen's inference frontier is fully closed, and the
production observation advances from InferenceRejected
(infer_grounding_not_derived) to EmissionRejected
(target_use_site_ownership_lookup_miss) -- a new, typed, located deficit
in the emitter, the next gate on the path.

Flip census (all three rewrites verified by execution):
- dag_binding_denotation_leaves_unbound_operand_atoms_on_the_frontier_holds
  -> dag_binding_denotation_declares_no_denotation_for_operand_bindings_holds:
  the boundary moves to the authority itself (the denotation table returns
  Absent for x/y), true regardless of infer's other rules.
- The three emit_host classical-not refusal guards (canonical, staging,
  staging-swapped) flip to acceptance witnesses pinning the emitted text's
  shape -- the real-infer tree now fully derives, and the emission is the
  same one the equals-eval witness proves behaviorally correct. The
  translate-refuses-underived behavior stays enrolled on hand-staged
  fixtures in translate_underived_refusal_test.dag (14/14 green). The
  renames are carried into the commit_workflow and witness_deferral_freeze
  rosters.
- New witnesses: binding_reference_derives_parameter_atoms_holds (evidence
  is the domain's Int binding atom, census 2) and
  door_specimen_fully_derives_holds (0 frontier of 15).

Full battery at this state: refusal suite 14/14, grounding wall 12/12,
instrument 2/2, binding-denotation 2/2, product-introduction 4/4,
atom-rules 5/5, emit_host 14/14, round-trips 4/6 (2 enrolled reds
unchanged), bridge 9/9, cross-language 4/4, neutralization 6/6 + e2e 6/6,
branch 2/2, eval-thesis 6/6; door production group still enrolled-red
(unchanged).

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…osition and decode canonical operator wires

The door specimen's inference frontier is fully closed, so its production
observation now reaches the emission stage. Two defects surfaced there, both
fixed here:

Emission composition. generate_rust_emission_candidate served two lanes with
one root shape: the door's production path (a dag module shell) and a fixture
lane (a bare rust Arrow). The translate ownership gate queried the module
atom's ownership at a struct-field use site and refused with
target_use_site_ownership_lookup_miss, because the module's grammar-projection
conj was misread as a type record. The door's real composition is the
produced-decl path: collect declaration conjuncts from the inferred tree and
emit via emit_produced_decl. A new generate_rust_module_emission_candidate does
exactly that, enforcing an exactly-one-declaration admission policy
(rust_module_emission_decl_absent / _ambiguous). The observation and production
mint paths switch to it; the fixture-lane candidate is retained with a note
that it is fixture-only. A pure collector, produced_decl_conjs_in_tree, finds
nodes of produced-decl shape (a Conj whose first child is a Named edge to an
Arrow). Its decl-head match routes through a declared FreeMonoid<Edge>
parameter because the v1 seed stamps pattern variables from a declared
parameter type, not from a field-access scrutinee.

Operator decode. With composition fixed, source fidelity still refused: the
door emitted fn add(x: i32, y: i32) -> i32 { AlgebraPrimitive(x, y) } instead
of { x + y }. Resolution canonicalizes a surface operator atom into a
canonical-operation wire node, so a production tree's transform operator
position carries the wire, while fixture trees that bypass resolution still
carry the surface token atom. translate_project_transform_in_arrow_scope only
knew the surface-token table, so the wire missed and fell to callable apply,
rendering the discriminant identity. The projection now tries the wire decode
first (canonical_operation_from_wire_node) and only on a wire miss falls to
the surface-token table, then to callable apply; the arms are disjoint, so the
dispatch adds no fallback widening. target_transform_operator_child extracts
the operator child safely.

The door's closing expectation now greens by execution, so its known_red_probe
row in explicit_witness_admission is deleted per its own dissolution condition,
and the roadmap authority note, the door contract note, and the direct-path
plan are updated to record the green state. realized_closure_for_v2_direct_
rust_door_emit_run's module list reflects the produced-decl route.

Verified by execution: the door witness greens; the fixture, containment,
algebra, produced-decl, add-slice, and classical-not witnesses stay green;
claim_executor required-ci lanes build and witnesses both exit 0; cargo fmt and
clippy --all-targets -D warnings are clean. One pre-existing red,
witness_projection_is_active_only in the floor_cost_debt containment roster,
reproduces on the base revision and is unrelated to this change.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
@cursor cursor Bot changed the title V2 self-host grounding frontier: stage-verdicts instrument, add-slice derivation, binding denotation, direct-path plan V2 self-host grounding frontier + direct-rust-door green: stage-verdicts instrument, five derivation families, produced-decl emission Sep 7, 2026
cursoragent and others added 4 commits September 7, 2026 06:52
… membership to the closed ingest set

The declared-inhabitant roster-membership derivation in 04_infer generalized
from the dag roster to the closed ingest set (dag, python, typescript):
infer_node_declared_in_language_inhabitants returns the declaring authority's
roster root as evidence, with deep subtree membership so a declared
inhabitant's leaf fact atoms derive exactly as the inhabitant node itself.

Measured: the python fixture's 19-node frontier and the typescript fixture's
28-node frontier both close to zero; all four add-slice stall population
round-trip witnesses green; the python->typescript cross-language compile
accepts, byte-identical to ts_source_text.

Section 4b(4) flips (expecting-red probes becoming permanent regression
controls for the acceptances):
- cross_language_compile_refuses_canonical_underived_holds ->
  cross_language_compile_python_to_typescript_round_trip_holds
- inhabitant_neutralization_emit_after_neutralize / same_flavor_python /
  go_int64_to_ts refusal helpers -> round-trip controls
- inhabitant_neutralization_python_to_ts_cross_language_compile (e2e) ->
  round-trip control; python->go members stay refusal guards (go is outside
  the closed ingest set)
- cross_language_emit_inhabitant_neutralization_refuses_underived_holds ->
  round-trip control; the python->typescript emit-matrix row reads ChainProven

The add-slice stall's next-rung trigger fired, so it retired per DESIGN
4b(4): removed from all_guarantee_stalls, row file deleted, witnesses stay
enrolled.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…ess for the emitted add crate

First InterpreterRetained -> SelfEmittedNative promotion after classical_not,
executing the v2-emitter-first-behavioral-module first slice at the
coverage-frontier grain: the add family (fewest dependencies — integer
literals plus one canonical operation) now carries a native-only verdict
witness, so its behavior is established by the emitted crate's own stdout
with eval() unreachable from the verdict path.

- emit_host_native_only_add_holds: real emit -> cargo build -> native run,
  stdout pinned to the family's expected octet, sharing the kernel family's
  one-build cache key exactly as the classical_not arm shares its family's
  key (no duplicated cold build).
- emit_host_native_only_add_wrong_octet_mismatch_detected_holds: the broken
  control — a no-eval verdict has no oracle leg to break, so the expectation
  side breaks (an octet the run never produces must not match); program-side
  discrimination stays with the family's equals_eval primitive-five/six pair.
- The add coverage row flips disposition with its backing citation enrolled
  by construction (the verdict entry is file-grain enrolled in
  falsifier_self_host_wet_template_entries).
- Frontier census tests updated at identity grain: natives are exactly
  {classical_not, add}; split 2/13.

Verified by execution: all six native-only verdict tests green locally
(real wet legs — compile_skipped receipts show cold builds and native runs);
all eight emit_coverage_frontier tests green, including the unbacked-claim
RED control.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…rounding-frontier-3100

# Conflicts:
#	dag/gunbc/guarantee_stall/roster.dag
#	src/v2/compiler/self_host/candidate_generation_stage_verdicts.dag
#	src/v2/test/claim/execution/self_host_candidate_generation_stage_verdicts_test.dag
#	src/v2/workflow/floor_expected_red.dag
…fication

The row classified candidate_generation_translate_self_emit_dag_add_slice_holds
as RealDefect/CompilerBehaviourRefusal with measured evidence that translate
refuses infer_grounding_not_derived. The owner lane (v2 self-host) repaired the
subject: the declared-inhabitant roster-membership derivation grounds the
slice's type spine by lookup, and the witness passes under claim_batch
--hermetic on the merged tree. The dated classification is kept verbatim; the
disposition flips RoutedToOwner -> RepairedInThisChange with the repair
measurement appended to the evidence, so the routing carrier stops dispatching
a fixed defect. Structural witnesses (count 13, no NotReproduced, exact
partition) are untouched and pass.
@cursor cursor Bot changed the title V2 self-host grounding frontier + direct-rust-door green: stage-verdicts instrument, five derivation families, produced-decl emission V2 self-host: grounding frontier closed (door + parse products), add family SelfEmittedNative Sep 7, 2026
Main's annotation-placement wall (source annotations admit only standalone
leading blocks attached to module-scope declarations; in-body forms refuse)
reached this branch through the merge and refused 8 blocking errors on the
00_compile closure: the add-family promotion note inside the
emit_coverage_frontier_roster list and the python->typescript row note inside
the cross_language_emit_matrix list. Both blocks move above their enclosing
declarations, rephrased to name their subject row. Measured: gunbc compile of
src/v2/compiler/00_compile.dag now emits 172 files with 0 blocking errors;
both files' suites stay green (8/8 and 4/4).
…ct witness for the emitted logic family crate

The complement family's native execution runs family-grain per the
witness_family_build_grain_ruling (one crate for meet + join + complement,
argv-dispatched), so the native-only arm emits the logic family crate and
runs the complement member through the family dispatcher, sharing the
family witness's one-build cache key. The verdict is decided solely by the
emitted native run's stdout (expected octet 0, complement(True) = False);
the broken control flips the expectation side (octet 1 can never match),
with the comparator pinned by the stdout mock pair. Program-side
discrimination stays with the equals_eval agreement pair and the family
witness's all-alt leg.

The frontier row's backing citation lands in the already
file-grain-enrolled native-only verdict entry, so it is enrolled by
construction; the roster comment is rephrased to cover both 2026-09-07
promotions (add and complement). The frontier test's split and native
membership assertions move to 3 native / 12 retained.

Verified by execution: claim_batch --hermetic on
emit_host_native_only_verdict_test.dag passes all 8 witnesses (the two
new complement arms included), and emit_coverage_frontier_test.dag
passes all 8.
…ling

is_host_text_carrier_type answered true for any type expression whose
authored name reads "String", including references to the structural
alias v2.std.text.String (type String = FreeMonoid<Char>) that the
namespace lane (gunbc#9907) requalified the v2 corpus's text-carrier
fields to. The emitter rendered every one of those references as the
host String while value-position consumers rendered the structure -- the
E0308 family dominating the self-host compile-phase frontier (41 of 64
in v2_compiler_tokenize.rs on the post-merge board).

The String arm now consults the resolved declaration's provenance
against v1.compiler.coercion structural_declaration_modules_for -- the
same roster type_realization_decision reads -- so the legacy arm and the
strict decision cannot diverge on one node (DESIGN section 3, and
gunbc.recurring_failure_mode alias_resolution_collides_with_kernel_spelling).
Kernel mints and unresolved references keep the host answer exactly as
before.

Regen: the only drifted stage0 mirror is v1_compiler_emit_rust.rs
itself (no module in the stage0 closure references a structurally
declared String -- verified by the whole-population candidate tree),
installed from target/stage0-regen-candidate after the priced round's
partitioned rebuild refused MirrorHasNoOwningPackage on the emitter
(the emitter is monolith-shell, not partition-owned). Fixed point
verified by execution: claim_executor --required-regen on the rebuilt
seed reports first_generation_equal=true over 158 adjudicated mirrors.
… -> 28 errors

A field authored v2.std.text.String reached the Rust emitter as an overlay-less
resolved reference leaf and rendered the bare terminal name, which binds the
prelude String cross-module (#9813: kernel names are never overridden by
imports, so the use-line is dropped) while every value position renders the
structural carrier Rc<Vec<i64>> -- the v2_compiler_tokenize.rs E0308 family,
41 of 72 errors on the XL-N phase board.

The new rust_overlayless_alias_leaf_requires_peel arm in
render_rust_type_without_applied_binding detects the population (overlay-less
zero-parameter alias leaf, qualified spelling, String terminal segment,
closed_alias_peel_verdict agrees) and renders the alias declaration's resolved
right-hand side, projecting the same realization the fn-signature positions
already produce.

The qualified gate is load-bearing: inside the declaring module the bare name
is the correct render (the emitted module carries the alias declaration), and
the local binding's resolved_type drops the RHS type argument, so an ungated
peel rendered Rc<FreeMonoid> there (E0107 x13, E0282 x2 on the probe). Bare
String keeps denoting the kernel scalar through the host-carrier arm.

Measured: probe specimen (qualified/bare/direct-FreeMonoid/container/variant/
local-alias positions) compiles clean; XL-N compiler closure cargo check
72 -> 28 errors with the residual census dominated by the declared
text_boundary_identity_wall class (kernel String vs structural carrier at
bare-authored boundaries, 17 of 20 E0308s); v1-corpus fixed point holds
(first_generation_equal=true, 158/158 adjudicated).
…rsions + witness_violates helper

Four clusters, all measured non-hop additions between receipt_1 (155) and the
post-peel census (28); the live gate now measures 15 with zero unadmitted
regressions:

- integer.dag: integer_string_to_decimal_digits_step takes v2.std.text.String;
  the public boundary converts with chars() (text_boundary_identity_wall
  specimen discharged at this site).
- 01_tokenize.dag: Token/UnboundSourceAnnotation lexemes convert structural
  -> host String with chars_to_string() at construction, mirroring the v1
  tokenizer's host-lexeme carrier.
- target_model.dag + bash.dag: EmitSpellingEscape.from/to and
  apply_emit_spelling_escapes go structural (v2.std.text.String); the
  EmitSpellingQuote arm converts host->structural->host at its boundary;
  bash's escape rows wrap their kernel String literals with chars().
- witness.dag + 3 call sites (collection list_nth, provenance
  span_index_resolve_textual_locus_from_ids, compile outcome_with_diagnostics):
  new witness_violates<C> helper puts Violates constructions in a
  Witness-headed position so the emitter resolves the carrier type argument;
  dissolves once inference records per-call substitutions.

Verified: 48 targeted claim witnesses green (tokenize behavioral, shell
conformance, string brace escape, string length, map-lookup violates, source
text ingress, bash materialize x12, int literal smoke x6, provenance span
index x2).
…nsus at 6676531

The census at the XL-N lane tip: 155 -> 15 net, credited to the qualified-alias
peel (60cbd7b, 72 -> 28) and the twelve-error source cluster (6676531,
28 -> 15). The epoch changes on the instrument's target pinning (found by
review on gunbc#9857), admitted with receipt_1's board as the reclassified
predecessor under the identity map. Nine added identities are hop relocations
admitted by the hop index; four sit in python/typescript modules newly entered
into the emitted closure, admitted as ExposedByNewEmittedModule.

Validated: all 36 self_host_compile_phase_frontier_witness claims PASS,
including current_persisted_compile_phase_frontier_holds.
Inference substitutes the resolved declaration into a data annotation's
type-argument position, so BooleanAlgebra<v2.std.logic.Bool> reaches the
emitter with the arg BEING the type Bool = True | False declaration itself
(Disj connective, ident_span in src/v2/std/logic.dag, no Resolved wrapper).
type_reference_provenance_in_env's bare-leaf arm re-resolved that leaf in the
REFERENCING module's scope, where post-#9813 a kernel-shadowed spelling
answers the kernel declaration -- so the structural enum rendered as host
bool against a value of BooleanAlgebra<Bool> (the python.rs:328 /
typescript.rs:177 E0308 pair on the XL-N compile-phase frontier).

The connective is the discriminator: a reference node is a bare name
(NoConnective); a node carrying Conj/Disj structure IS the declaration, and
type_reference_provenance's own-span fallback already answers that shape
correctly. The guard routes declaration-shaped nodes there directly, bypassing
the scope lookup that #9813 makes answer the kernel.

Mirror regenerated via the regen round; fixed-point verified
(claim_executor --required-regen PASS).
…s at the boundaries

The receipt_2 census's fifteen identities, resolved at their sources:

- lexing.dag, dag.dag, python.dag, typescript.dag: LexPattern.text is the
  structural carrier (v2.std.text.String); the construction sites held host
  Strings. Convert at construction with chars() -- the #9907 ingress pattern.
- python.dag / typescript.dag bool groundings: qualify the annotation as
  BooleanAlgebra<v2.std.logic.Bool>; with the emitter's substituted-
  declaration provenance guard the qualified arg now renders structural.
- target_model.dag: target_lex_rule_literal_step returns the host carrier
  (chars_to_string over the structural pattern text); TargetText.source
  converts at the is_empty boundary; the unicode-scalar symbol intern converts
  its single-codepoint list to the host carrier.
- qualified_name.dag: qualified_name_from_dotted_string uses the host-carrier
  emptiness check (string_length == 0) instead of routing through the
  structural string_is_empty.
- 02_parse.dag: parse_looks_like_match_arm_start rewritten on host-carrier
  operations (string_length, char_at, code_point) rather than converting to
  the structural carrier for a two-character lookahead;
  parse_char_is_arm_pattern_lead takes the codepoint Int directly.
- v1_interpreter_primitive_surface.dag row_key: the concat pipeline lowered
  to a .concat() method call on std::string::String (E0599); rewritten as
  nested concat calls.

Measured: the 00_compile closure emits 172 files and cargo check reports
cargo_clean=true, cargo_error_population=0 under the pinned 1.93.0 toolchain.
The cargo half runs with cwd = a fresh mktemp directory; with no
rust-toolchain.toml there, rustup resolves the host's DEFAULT toolchain, so a
census under cargo 1.83 and one under cargo 1.93 would compare as equal epochs
while different compilers did the measuring -- the fabricated comparability
the target pin (gunbc#9857) excludes, one level up. Measured 2026-09-07: a
host default of 1.83.0 met a crates.io index whose freshly published
dependency manifests require edition2024, resolution failed before any
diagnostic existed, and the zero-diagnostic refusal fired on an unmeasured
tree.

The pin is propagated by copying the repo's rust-toolchain.toml into out_dir:
the file remains the sole in-repo channel authority (its header forbids a
second pinned literal), and the copy makes the measured channel true by
construction on any host. The gate's read_live_toolchain observes the same
channel because every documented actuator invokes from the repository root,
which the same file governs.
… closure's cargo census is empty

Measured at 5ee4892 by the one-entry instrument: the 172-file emitted crate
reports zero cargo error diagnostics, so the board attributes every phase a
count of zero and furthest_phase_reached stands at Borrowck. The fifteen
removals against receipt_2 need no disposition; nothing was added.

The epoch does not change: the cargo half now pins the toolchain channel by
copying the repo's rust-toolchain.toml into the scratch crate, and every
recorded comparison field is identical to receipt_2 (whose census the
fingerprint evidence shows the same 1.93.0 toolchain already compiled), so the
same-epoch arm carries no reclassified predecessor.

The frontier-state pin flips per DESIGN 4b(4):
the_published_frontier_standing_does_not_claim_typeck_or_borrowck_passed
becomes the_published_frontier_standing_claims_typeck_and_borrowck_passed, the
permanent regression control over the green state.

Validated: all 36 self_host_compile_phase_frontier_witness claims PASS,
including current_persisted_compile_phase_frontier_holds.
@cursor cursor Bot changed the title V2 self-host: grounding frontier closed (door + parse products), add family SelfEmittedNative v2 self-host: grounding frontier closed, door green, XL-N closure compiles clean (receipt_3) Sep 7, 2026
Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-rung-drops.md
cursoragent and others added 5 commits September 9, 2026 02:21
…nt cluster

Commit 285b02e converted three structural-text reads in the parser to
host-string builtins (chars(s:), string_length, char_at, code_point) while
chasing emitted-closure compile errors. Lexeme is v2.std.text.String, which
interprets as a Variant value, so every claim that parses tokens failed at
runtime with 'chars expects a string argument, got Variant' — 10 claims in
the required floor lane.

parse_lexeme_digest folds the Lexeme list directly again,
parse_char_is_arm_pattern_lead takes Char again, and
parse_looks_like_match_arm_start matches string_head's CharFound/CharAbsent
again. Verified locally: all 10 claims of the cluster pass.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…arrier + preparation-time warming

Two defects composed into the required floor's twelve FillBudgetExceeded
refusals, both repaired at source:

(1) GrammarFirstAnalysis.nullable_set was a PointwisePower<Symbol>
characteristic function — a nested closure tower the cross-claim pure tier's
publication walk refuses totally (ServeCacheValueNotPortable), so the one
fill every parse of .dag source demands could never store and every
demanding claim recomputed it. The carrier is now the enumeration it always
was (List<Symbol>, the GrammarRoot.sync_tokens repair's own precedent):
set_symbol_insert de-duplicates over symbol_list_contains (first_list_contains
renamed, it was never first-specific), the fixpoint's convergence measure is
the list's own length, and nullable_member_count dissolves into it.

(2) The fill costs more than one claim's CPU budget on the lane's runner, so
an in-fold first touch could never complete. The nullary
v2.compiler.program_assembly.dag_prepared_grammar producer moves that first
touch to strict preparation via floor_cross_claim_pure_producers_warm —
outside every per-claim budget — and every claim then serves the landed fill.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…500ms line

The two-member shape put two native-run verdicts inside one claim's 500ms
CPU budget — emit of the family crate plus the cached-run receipt walk,
twice over — and the required floor measured both meet_join arms over the
line. The ceiling is the floor's own and does not move to admit a claim
shape; the arm splits by member instead, the grain the family's equals_eval
pair already claims at (emit_host_meet_equals_eval_holds /
emit_host_join_equals_eval_holds). Each claim now pays one native run; the
family crate build stays shared through the same one-build cache key. The
coverage frontier's meet_join row re-cites emit_host_native_only_meet_holds;
the join claim carries the family's other half.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…heir exact subjects

The branch's required-witnesses lane reports five TargetChanged binding
deltas, all one change class: three String sites (EmitSpellingEscape,
apply_emit_spelling_escapes, integer_string_to_decimal_digits_step)
requalified to v2.std.text and two Bool grounding sites (py_bool_grounding,
ts_bool_grounding) requalified to v2.std.logic — the gunbc#9907
namespace-lane requalification reaching the sites the XL-N closure repair
and the chars(String) <- Variant cluster repair touched. The spelling is
identical on both sides in every row; only the declarer moved, from the
ambient kernel type set to the named authority. Five exact-subject
TransitionAdmission rows, enumerated never patterned, with the dissolution
trigger on gunbc#10692's merge.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
cursoragent and others added 2 commits September 9, 2026 04:33
…ers for the five over-ceiling claims

The prepare_grammar warm-store unmasked five changed witnesses over the
500ms per-claim ceiling: the classical_not family's three emit claims
(marginal 474-501ms, each re-running the full tokenize->resolve pipeline
on a module-constant source) and the produced_module pair (505-542ms,
each re-assembling the same two-decl module). CI's runner is ~1.8x this
lane's local host (median ratio over the 25 claims present in both
ledgers), so these project to ~900ms there — structurally over, not
variance.

The repair is the roster's own named one — stop recomputing a pure
function of program content — in its WARM arm, because a ~370-382ms
claim-forced fill leaves under 130ms of headroom and would die
mid-flight on the lane exactly as prepare_grammar's did:

- produced_add_module_source (already nullary) is enrolled directly.
- ingested_classical_not_arrow_with_body and its swapped sibling are new
  nullary producers in the ingested_fixture_arrows idiom; the three
  failing claims' tree helpers now take the arrow outcome, with the
  source-taking staging variant delegating so unselected claims keep
  their spans untouched. The arrow is the deepest pipeline stage whose
  value is closure-free and therefore portable; the InferredTree above
  it carries the facts PartialFunction and can never store.

claim_batch: 14/14 classical_not claims pass with identical verdicts.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…r for the seven unmasked over-ceiling grounding claims

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…s for the twelve ceiling-band native-only verdict claims

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 9, 2026
…ge0-boundary emissions

The floor refused this branch's first head two ways, and both are cost, not
content. Fixed at the cause rather than by raising a line.

FIRST: twelve of #10692's native-only rows tipped 6-118ms over the 500ms
per-claim ceiling. They sit deliberately just under it -- the parent's last two
commits are about keeping them there -- and this branch had re-parameterized
rust_binding_spellings, which every one of them evaluates. The profile now
OVERLAYS the single key it changes (map_insert over the Rust map) instead, so the
base map is byte-for-byte what it was and every claim already sharing one
evaluation of it keeps sharing exactly that one. A profile's delta belongs to the
profile; charging every other witness for it was the defect.

SECOND: this branch's own three claims were INTERRUPTED BEFORE VERDICT at
~1200ms each -- a full ingest-assemble-infer-emit walk per claim. Split by an
ingest-only/assemble-only probe pair, the disk read and its content-hash
verification cost 0ms and assembly costs 878ms, so the recompute was assembly,
three times, of a pure function of one file's content. Two repairs, both the
roster's own named one:

  The emission claims now run over direct_rust_door_specimen_resolved, the
  already-warm-enrolled producer of a resolved add-shaped module. A second
  producer for a specimen of the same shape would have been the duplication that
  roster exists to end.

  The two emissions themselves (profile target, base target) are nullary
  producers enrolled warm, the same shape as produced_add_module_source. Each
  claim is then a string comparison, and infer+emit is evaluated once at
  preparation rather than three times inside three budgets.

THE READ IS CLAIMED SEPARATELY, because it is a separate fact and it is free
(0-5ms): the committed fixture reaches source_ref_for_observed_storage_path and
source_root_ingest_from_source_refs, whose content-hash verification is the seam
no enrolled claim covered -- the door's specimen carries its module source
inline. The assertion is a containment, not a whole-text golden, so editing the
fixture's prose is not a test failure (a change detector, not a check).

claim_batch over the entry: 5/5 PASS. The emission claims read the door
specimen, so the expected sources name its declaration (`add`) rather than the
fixture's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X5tyxfVrw3chDNbQ3sVD3
@briansrls
briansrls marked this pull request as ready for review September 9, 2026 08:44
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-09T08:57:38.281158Z 7646583 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 764658371c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/v1/05_emit.dag
Comment on lines +521 to +523
DataVariantUntagged =>
if (value.children |> count) == 0 {
Emitted { json: "null" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Refuse ambiguous nullary untagged variants

When an UntaggedVariant coproduct contains multiple nullary variants and a data definition or dry-run mock selects a non-first variant, this emits the identical JSON value null for every arm. Serde's untagged deserializer accepts null as the first matching unit variant, so the generated value silently changes identity (for example, E.B {} round-trips as E.A). Refuse a second nullary arm under an untagged policy, or otherwise avoid this ambiguous JSON round-trip.

Useful? React with 👍 / 👎.

@briansrls
briansrls merged commit ebb1da8 into main Sep 9, 2026
4 checks passed
@briansrls
briansrls deleted the cursor/v2-self-host-grounding-frontier-3100 branch September 9, 2026 13:41
gunbai-bot Bot pushed a commit that referenced this pull request Sep 9, 2026
The merge of origin/main kept its five #10692 rows verbatim alongside my
nine. Additive-only was the right instinct for my rows and the wrong one
for rows whose trigger had already fired in the commits being merged in:
main now binds each of those spellings to its own target, so the rows
report consumed-at-base, and the floor refused with

  namespace-wave-admission (0 unadjudicated delta(s), 0 stale
  admission(s), 5 consumed admission(s) due for deletion on this
  roster-touching change)

Leaving them is not harmless. A consumed row matches nothing, so it would
refuse every unrelated PR until someone else deleted it -- the standing
cost the roster's first 53 rows were written down to record.

The deletion is adjudicated by the instrument, not by the trigger
sentence: main's own block warned that "a trigger sentence is not
evidence that the trigger fired", and claim_executor performed the
(module, in_declaration, spelling, target) join against the base tree and
returned consumed. The rows, their label const, and their doc block go
together; nine rows remain and the wave reports ADMITTED.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg
gunbai-bot Bot pushed a commit that referenced this pull request Sep 9, 2026
The required floor refused adjudication on this head with
`0 unadjudicated delta(s), 0 stale admission(s), 5 consumed admission(s)
due for deletion on this roster-touching change`. Nothing was missing:
the five `gunbc#10692` binding admissions became CONSUMED when that PR
merged, and adding this change's own two rows is the roster touch that
brings their deletion due (DESIGN 4b(4), dissolution on climb -- a climb
deletes the lower-rung machinery it obsoletes).

The rows' own trigger prose forbids taking its word for it -- "adjudicate
that deletion by joining each row against main's tree on its own
(module, in_declaration, spelling, target) tuple rather than trusting
this sentence, because a trigger sentence is not evidence that the
trigger fired." Joined all five against origin/main; each declaration
now binds its spelling to the named authority module:

  v2.std.integer integer_string_to_decimal_digits_step   -> v2.std.text
  v2.std.compilers.target_model EmitSpellingEscape       -> v2.std.text
  v2.std.compilers.target_model apply_emit_spelling_...  -> v2.std.text
  v2.extdeps.languages.python py_bool_grounding          -> v2.std.logic
  v2.extdeps.languages.typescript ts_bool_grounding      -> v2.std.logic

The two `gunbc#10818 CpuBoundStanding rehome` rows stay: their own
trigger is this PR merging, which has not happened. Deleting all seven
to make the count come out right would drop live admissions.

Pure deletion -- the five rows, their now-unreferenced label constant,
and the doc block describing them. No evidence retired: these rows carry
no discriminating control, so 4b(4)'s "production handling only, never
the evidence" has nothing to preserve here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJGbrvU2EgNeUiWfc5yK2c
cursor Bot pushed a commit that referenced this pull request Sep 9, 2026
#10692 added the ReleaseScopeEmpty decision variant on main; the
owner-flip arm enrolled by the infer_resolve partition move predates it
and no longer compiles against the merged tree (non-exhaustive match).
A release-excluded verdict for this mirror would be wrong -- the mirror
is release-visible and owned by v1-stage0-v1-infer -- so the arm answers
false, matching the sibling arms' convention. Same fix landed in the
emitter-repair split-off PR on current main.

Co-authored-by: briansrls <briansrls@gmail.com>
briansrls pushed a commit that referenced this pull request Sep 10, 2026
…ntence (#10883)

* The observer could still see the goal, because the guarantee was a sentence

std.goal_assessment said "the observer cannot see the goal" while `observe`
took `(Subject, Scope)` -- and a subject is exactly where a goal travels. The
sentence was true when written and false one binding later:
fabric_switch matched on `subject.intent`, so the desired mode selected which
lanes were read. Two of the three bindings broke the law the module advertised.

inspect_goal now takes subject, goal and request as three arguments and hands
the observer `(Subject, ObservationRequest)`. The observer is goal-blind
because it has no goal-typed parameter, not because a note asks it to be. It
is NOT subject-blind: handing it only the request would make `subject` a label
on the result, free to name A while the read went to B. Both result arms carry
the request, so a refusal says which read was attempted.

Three defects this fixes were shipped by #10814 and ratified by its witnesses.

MEMBER-LEVEL UNKNOWNS WERE PROMOTED TO WHOLE-OBSERVATION REFUSAL. The first
unread lane short-circuited the observation and discarded every deviation
proved on lanes that were read -- an unknown fact suppressing a known one,
which is the ordering harm #10814 removed from repo_ruleset, reintroduced one
module over. They are unknowns now, and the mixed case reports both.

THE DENOMINATOR CAME FROM THE OBSERVATION. Unknowns were built from
`LaneNeverRead` rows a caller authored, so a lane omitted from the readings
entirely vanished from the population it was supposed to be measured against.
The switch joins `SwitchIntent.lanes` -- the declared roster -- against what
was read, so the denominator is the goal's. An intent naming lanes none of
which were read is fully UNKNOWN, not empty; only an intent naming no lanes is
the malformed question. cable_plant cannot do this join (it has no declared
leg roster) and now states that ceiling with its next-rung trigger rather than
implying the guarantee.

THE COLLAPSE SURVIVED ONE MODULE DOWNSTREAM. fabric_switch_desired mapped
divergence, indeterminacy AND assessment refusal onto one
`PlantDivergedFromRequirement { legs: Nat }`, discarding every unknown and
reporting a malformed assessment as `legs: 0`. It carries the rows now.

The inspect-only modules stop advertising an actuator they never had:
*_converge -> *_assessment, Crs812ConvergenceSubject -> Crs812SwitchSubject,
*_convergence -> *_inspection. No alias or compatibility shim.

EVIDENCE. 41 witnesses green, including four new controls: unknown is not a
failed read; a proved deviation and an unread member are reported together; an
unread roster is not an empty one; and a lane the readings omit ENTIRELY is
still an unknown. The last two are proved discriminating by mutation --
reverting the join to the reading-derived shape fails both while the positive
control stays green. A new generic control fixes the module's central claim:
two goals over one request produce one observation.

NOT VERIFIED BY EXECUTION: repo_ruleset. Its closure reaches
gunbc.roadmap.roadmap_belt_actuate through extdeps.transports.rest, and that
module fails to resolve on main (`if branches resolve to incompatible types`)
byte-identically to this branch. Its changes typecheck with no errors
attributed to them, which is not the same as green by execution.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* The request repeated the subject, and the goal-blindness check could not go red

Two review findings, both confirmed, and the first was worse than reported.

THE OBSERVER TOOK ONE ARGUMENT WHERE THE ROOT PASSES TWO.
`observe_repo_ruleset_attempt` kept the arity it had before the recut while
`inspect_goal` calls `observe(subject, request)`. Nothing else repaired it,
and it sits in the one module whose witnesses cannot execute -- so no green
run of mine would ever have found it.

Underneath it was a second defect the finding implies but does not name: the
`request` passed at the call site was a VERBATIM DUPLICATE of the subject,
the same RepositoryRulesetConvergenceSubject built twice. Re-typing the
parameter would have compiled and left this binding's request carrying nothing
about the read, making the module's own claim -- a refusal says which read was
attempted -- false here while the receipt still reported one.

So the repair is the split rather than the arity: subject is the `Repository`
(WHO), request is `RulesetReadRequest { ruleset_id }` (WHAT TO READ). The
fused RepositoryRulesetConvergenceSubject is deleted; it existed only to carry
both facts at once, which is the fusion this whole change is about.

THE GOAL-BLINDNESS CONTROL WAS PERMANENTLY GREEN.
`two_goals_over_one_request_produce_one_observation` passed the SAME
`fixture_observe` to both calls, and that function has no goal parameter, so
the equality could not go red for any authorable input. DESIGN section 4b asks
whether a check's RED is authorable BEFORE writing it; this one's was not,
which makes it worse than absent because it would have been cited as coverage
for the module's central claim. Deleted, not repaired.

The RED that IS authorable replaces it. `inspect_goal` closes the PARAMETER
route; it does not close LEXICAL CAPTURE -- a lambda may close over the goal
and shape the read by it. The new control holds that as an executing fact and
goes red if capture ever stops being expressible.

That forces an honest downgrade this change had claimed too strongly:
goal-blindness is STRUCTURAL against the parameter and MITIGATED BY REVIEW
against capture. Both the module and the witness now say so, and the
next-rung trigger is named: a lens refusing an `observe` argument whose free
variables include the goal bound at the same call site.

Also removes fixture_assess_echoing_goal, which the deletion left unconsumed.

EVIDENCE. 41 witnesses green across four entries, post-merge with main.

STILL NOT VERIFIED BY EXECUTION: repo_ruleset, and the cause is now located.
Its closure reaches gunbc.roadmap.roadmap_belt_actuate, where two coproducts
in the corpus declare an arm named `Observed` -- BeltObserve's and a nullary
one in gunbc.self_host_compile_phase_frontier. Resolution picks the nullary,
so a branch building `Observed { live: ... }` types as Primitive rather than
Coproduct(BeltObserve). That is a DESIGN section 3 collision on main: one
name, two declarations. It is unrelated to this subject and is not fixed here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* Prose that was true before the cut and false in the same diff, twice

Three findings, all confirmed, and the first is the failure this change exists
to delete -- reintroduced by the change itself.

THE FLEET ENTRY POINT'S ANNOTATION DESCRIBED A REFUSAL STAGE THAT NO LONGER
EXISTS. It claimed the entry "refuses at the observe stage today, and it
refuses with the ONE fact that is missing -- the interface nobody read". The
observer's refusal type is `Never` and it always establishes; the refusal comes
from the ASSESSMENT and carries the CABLE cause, which this module's own
witness asserts while returning false on GoalObservationRefused. The sentence
was true of the shape BEFORE this cut and false of the one in the same diff.

It is recorded rather than quietly swapped, because the recurrence is the
point: a guarantee carried only by prose surviving one edit past the code it
described is precisely what this change removes from the type, and it
reappeared in the module while that removal was being written.

A SIBLING SWEEP FOUND A SECOND SITE THE REVIEW DID NOT CITE. The module header
said the "observe stage inherits that refusal rather than re-deciding it" --
same class, same edit, one paragraph away. The ASSESSMENT inherits it; the
observe stage cannot refuse at all. Fixed, and the reason is now stated.

Annotations are the one part of this change no witness can guard: no Accepted
program reads one, so 41 green tests say nothing about whether the prose beside
them is true. Review and a targeted sweep are the only mechanisms, and the
sweep only worked because the specific false claim was known.

MEMBERSHIP WAS A FAILED DECOMPOSITION, AND THE COST SHAPE COMPOUNDED IT.
`interface_absent_from` minted `list_length(flat_map(...)) == 0` beside the
corpus-canonical `any(xs, pred)` -- section 2's net-concepts test. Worse,
`observed_lane_interfaces` was called INSIDE the fold, so n intent lanes and m
read lanes did n*m work and allocated n copies of one list to answer a single
membership question each, and `lane_intent_interface` computed twice per lane.
The projection is hoisted once and the fold uses `any`. Section 6's standing
rule: a proven cost-shape defect is fixed regardless of the realized n, because
n is not a time-stable fact.

A merged paragraph is also repaired: the new assessment block had been spliced
into the tail of an unrelated one and lost its heading.

EVIDENCE. 17 witnesses green across the switch and cable entries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* Point the new spark witness at the renamed cable-plant module

main added test.claim.spark.spark_fabric_switch_witness while this branch was
open, importing product.cable_plant_converge. The merge is textually clean --
an import naming a module that no longer exists is not a conflict -- so only
the census finds it. Third time this cutover has been overtaken by new
authorship against a module scheduled to move.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* Adjudicate the nine bindings the cable-plant rename retargets

The floor refused this head: `namespace-wave-admission (9 unadjudicated
delta(s))`. All nine are `TargetChanged binding` -- a spelling authored on both
sides that now resolves to `product.cable_plant_assessment` instead of
`product.cable_plant_converge`, because this cut renames the module. That is
the exact subject NAMESPACE_TRANSITION_ADMISSIONS exists for, and the roster's
own note already states the claim these rows make.

THE ARITHMETIC IS THE CHECK, not the green. The wave measured eighteen deltas.
Nine auto-admit as the membership half of one motion: the old edge reports
SameDeclarationIdentityRebind (every name it supplied still denotes the same
declaration) and the new edge ExplicitlyEvaluatedZeroDelta (reached by a name
the module authors). The nine below are the binding half. Consumers whose OWN
module was renamed produce no binding delta at all -- a delta needs the module
present on both sides -- which is why the two witness files this cut renamed
are absent from the roster and `fabric_switch_observed` is present. Rows for
the renamed modules would have meant I had misread what the wall measures.

ENUMERATED BY EXACT IDENTITY, never by a pattern over the renamed module pair:
a pattern would admit a genuine rebind that happened to land in the same pair,
which is the absorbing fallback section 5 forbids. None of these nine changes
WHICH DECLARATION the spelling denotes; a binding whose meaning had moved would
refuse on its own row rather than be covered here.

TRIGGER: removed when this PR merges. The base then binds each spelling to
`product.cable_plant_assessment`, every row reports consumed-at-base, and
leaving them would refuse every unrelated PR -- the cost the roster's own
history records from the first fifty-three rows.

This is the mechanism I declined earlier in this session for a different
subject. There the row would have papered over a baseline-reconstruction
defect, so writing it was a workaround. Here it adjudicates a rename that was
intended, which is what the roster is for. Same mechanism, opposite standing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* The cable module still called its two stages four

The switch module's heading was corrected when the handler record was deleted;
the cable module's was not, so it kept announcing an actuation stage and an
unchanged-receipt stage that no longer exist and never ran for this subject.

Found by re-reading the request against the code rather than the review tally:
renaming the stale stage headings was an explicit item on the list this PR is
answering, and it survived two approving reviews. An approval is 'no blocking
defect found', which is not the same as 'this is what was asked'.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* The goal still chose what was read, one level above the observer

REVIEW FINDING, CONFIRMED, AND IT IS RUNG INFLATION IN THE MODULE ABOUT RUNG
HONESTY. `fabric_switch_subject()` built its observation REQUEST by mapping
over the intent's own interfaces, so an undecided intent produced an empty
request and therefore an empty snapshot BECAUSE OF THE GOAL. Closing the
parameter route while the request stayed goal-derived renamed the mechanism
and removed nothing. This change had been reporting goal-blindness as
structural against the parameter while the live binding routed the goal into
the read anyway -- section 4b(1): citing the strongest path while another
stays silent.

CLOSED RATHER THAN DECLARED. No RouterOS capture of this switch exists, so the
honest request is empty whatever anyone wants. The unknowns are still one per
intent lane because `switch_unknowns` joins the intent's declared roster on the
ASSESSMENT side, which is the stage allowed to know the goal. Same reported
answer; the goal no longer reaches the read. The goal-derived roster function
is deleted -- nothing consumed it once the request stopped calling it.

THE RESIDUAL DISCLOSURE WAS WRONG BY OMISSION. It named two routes; there are
three. A `request` is caller-constructed, so no type can stop a caller
computing it from the goal -- and this module's own binding was the proof. All
three are now enumerated, with this binding recorded as the worked example, and
ONE next-rung trigger covers both review-mitigated residuals because they are
the same shape: a goal reaching the read through a VALUE rather than a
parameter.

"THE OBSERVER RECEIVES AN ObservationRequest AND NOTHING ELSE" WAS FALSE. It
was written before an earlier review restored the subject to the observer, and
went stale in that edit. Corrected in std.goal_assessment and in the switch
module's own copy of the claim.

AND THE FIRST CONTROL FOR THIS WAS PERMANENTLY GREEN -- the same fault this
change deleted a check for, committed while correcting it. It compared the
fleet subject against an undecided-intent subject and asserted both requests
were empty; both are empty UNDER THE DEFECT too, because the fleet's real
intent is undecided today. Mutation caught it: restoring the defect left the
check PASS. The property was unobservable because the goal never varied, so
`fabric_switch_subject_under(intent)` takes it as a parameter now and the
control supplies a DECIDED intent naming two lanes. Under the defect that
request carries two entries. Mutation-confirmed: FAIL on the defect, positive
control green. The dead first version is recorded in the witness rather than
swapped out, because it is the reason the mutation step is not optional.

EVIDENCE. 12 witnesses green, including the new control, proved discriminating.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* The assessor's subject had five signatures and no readers

REVIEW FINDING, CONFIRMED ON ALL FIVE BINDINGS. `assess` took a `Subject` that
`assess_cable_plant`, `assess_fabric_switch`, `ruleset_assess`,
`fixture_assess` and `selection_assess` all ignore -- five signatures, zero
uses -- while an annotation beside it claimed "a refusal cause that has to name
what it could not assess should not have to be handed the identity through a
closure". Section 3c dangling, and section 4c prose asserting a use that does
not exist.

DROPPED RATHER THAN CONSUMED, which was the other option offered. Locating
`PlantHoldsNoLegs` or `SwitchIntentNamesNoLanes` by their subject would put a
second copy of the identity beside the one `GoalInspection` already carries in
BOTH arms -- the exact redundancy this change removed when it dropped `switch`
from `SwitchHoldsNoLanes`. Consuming the parameter would have undone that
reasoning to justify a parameter that should not have been added.

THE ASYMMETRY THAT REMAINS IS REAL AND IS NOW STATED. The OBSERVER keeps its
subject: gunbc.repo_ruleset's observer builds its request path from
`subject.owner` and `subject.name`, which is the one consumer that earns it.
A sweep for signature-only parameters confirms the two corpus-data observers
ignore theirs -- legitimate, since their read is a projection of declared data
and one genuine consumer is what section 3c asks of a generic parameter. The
assessor had none anywhere, which is the difference.

Dropping it cascaded: `witness_subject` in the repo-ruleset witness lost its
only reader, so the fixture and its two imports went with it. The section 3c
question asked one level down rather than stopped at the first answer.

I INTRODUCED THIS WHILE FIXING THE PREVIOUS INSTANCE OF IT. An earlier review
established that the OBSERVER needs its subject; I extended that to the
assessor by symmetry without checking whether any assessor would read it. That
is the fourth claim in this change to outlive the code it described, and the
correction is recorded in the module rather than silently reverted.

EVIDENCE. 41 witnesses green across four entries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

* Main's five admission rows were consumed the moment #10692 landed

The merge of origin/main kept its five #10692 rows verbatim alongside my
nine. Additive-only was the right instinct for my rows and the wrong one
for rows whose trigger had already fired in the commits being merged in:
main now binds each of those spellings to its own target, so the rows
report consumed-at-base, and the floor refused with

  namespace-wave-admission (0 unadjudicated delta(s), 0 stale
  admission(s), 5 consumed admission(s) due for deletion on this
  roster-touching change)

Leaving them is not harmless. A consumed row matches nothing, so it would
refuse every unrelated PR until someone else deleted it -- the standing
cost the roster's first 53 rows were written down to record.

The deletion is adjudicated by the instrument, not by the trigger
sentence: main's own block warned that "a trigger sentence is not
evidence that the trigger fired", and claim_executor performed the
(module, in_declaration, spelling, target) join against the base tree and
returned consumed. The rows, their label const, and their doc block go
together; nine rows remain and the wave reports ADMITTED.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PUtSkZTNvpWQv58Lk9cGzg

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Sep 10, 2026
… named before native bootstrap (#10886)

* Land the add-slice per-stage verdict instrument named as the floor_expected_red note's producer

The add-slice roster note in v2.workflow.floor_expected_red carried a dated
receipt (main 3a8344b5c: infer accepts dag_add_emitted_root; the
infer-then-translate composition refuses headed by infer_grounding_not_derived)
and named its own next-rung trigger: a .dag entry returning the per-stage
verdicts for one root, so the paragraph can name a producer instead of a
commit.

v2.compiler.self_host.candidate_generation_stage_verdicts is that entry,
parameterized over root and target: the receipt's verdict vocabulary
(infer_accepted / infer_rejected; candidate_accepted or the rejection head
reason) plus the carried-reasons lists -- the half the verdict symbols cannot
say, namely that infer accepts while carrying the frontier diagnostic on its
accepted path, so the enrolled witness's d == None conjunct fails even where
the composition reaches acceptance.

v2.test.execution.self_host_candidate_generation_stage_verdicts binds the
instrument to the slice's own fixture, with add_slice_stage_verdicts_entry the
runnable gunbc run --function form (ExitSuccess only when infer accepts clean
and the composition accepts clean). Two witnesses: infer-accepts as a
permanent positive control, and the frontier-state pin that is expected to red
the day the add-slice stall's trigger lands, flipping to a permanent
regression control in the same change that removes the roster row (DESIGN
4b(4)).

Measured by execution on this branch: the entry exits 1 printing
infer=infer_accepted, infer_carried=[infer_grounding_not_derived x10],
composition=infer_grounding_not_derived, composition_carried=[x11] -- the
receipt reproduced, with bind_outcome's pending-plus-gate chain counted. Both
witnesses PASS; the enrolled semantic witness still fails as enrolled.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Derive grounding for dag declared inhabitants: the add slice greens end-to-end

infer gains the declared-inhabitant membership derivation: a node declared in
the dag language authority's declared-inhabitants roster derives its grounding
by lookup, with the roster as evidence -- the namespacing answer to the atom
authority question, at specimen scope. The add slice's ten type-spine nodes
(Arrow, Conj, Atom) are all roster members, so:

- candidate_generation_translate_self_emit_dag_add_slice_holds passes; its
  floor_expected_red roster row and per-row note delete per the roster's own
  stale-quarantine arm
- the dag same-language ingest path compiles end-to-end: cross_language_compile
  accepts, byte-equal to the authority's own serialization, no carried
  diagnostics
- the add-slice stall narrows to its four python/typescript round-trip members;
  the original trigger's causal clause was refuted by execution and is restated
  against the grammar parse-product population
- the instrument's frontier guard flips to add_slice_composition_accepts_holds
  (DESIGN 4b(4): frontier guard to permanent regression control)
- five manual witnesses flip with it: two root flips rewritten to assert the
  green state, three transitive conjunctions updated

The kinds stay frontier: non-member Arrow/Conj/Atom specimens carry
GroundingNotDerived exactly as before, and all fourteen enrolled
refusal/acceptance controls pass unchanged. The door's production path still
reds inside rust emission, untouched by this rule.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Derive grounding for canonical binding atoms: dag_binding_denotation joins binding to inhabitant once

The resolver already binds the surface spelling Int to the canonical binding
symbol dag_binding_type_int; what that binding DENOTES is the Int inhabitant
declared at dag_declared_inhabitants_core. Every hand-rolled fixture facts
lookup re-authored that join (dag_add_canonical_grounding_for,
record_construct_canonical_grounding_for). The language authority now declares
it once as dag_binding_denotation, and infer_node_facts consumes it: an Atom
whose identity is a canonical dag binding with a declared denotation derives
with that denotation as its grounding evidence.

Direct-rust-door specimen census: 14 underived -> 10 underived (the four
dag_binding_type_int atoms derive; grammar-production atoms, algebra atoms,
bare operand atoms, and the arrow/conj spine stay on the frontier unchanged).

Specimen-scope interim in the same frame as
infer_node_declared_in_dag_inhabitants: both delete in favor of consuming
resolution output when the resolver hands infer declaration-resolved
identities directly (the namespace migration's completed state).

Witness: v2.test.execution.dag_binding_denotation — all four Int binding
atoms in the door specimen derive with dag_int_inhabitant_node() as
structural evidence, and the two bare operand atoms stay GroundingNotDerived
(boundary control). Refusal suite 14/14, ingest bridge 7/7, add-slice
instruments 2/2 green; every remaining red in the at-risk population
reproduces identically on the pre-change tree and is enrolled in
floor_expected_red.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Add v2 self-host direct-path orientation: axes, sequence, autonomy contract

A point-in-time orientation that defers to the existing authorities
(DESIGN section 7, the four-wave self-host program, the roadmap node
chain, the three frontier carriers, the guarantee-stall roster, XL-N)
rather than restating them: state is re-derived by the named
instruments, never transcribed here. Sequences the remaining work in
roadmap order (door, parse-product grounding, first behavioral module,
XL-N milestones, native bootstrap, fixed point, v1 deletion) and states
which decisions stay operator-gated.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Derive grounding for fully-evidenced Conj and Arrow products

The sixth and seventh kind rules: a non-roster Conj or Arrow whose every
child carries DerivedGrounding derives, its evidence the same shape
re-formed over the children's grounding evidence (a fresh
OccurrenceSynthetic node, never the source — the self-evidence wall holds
by construction). A product with any frontier or absent child stays on the
frontier with its typed diagnostic; a childless product has no evidence to
compose and stays frontier. Roster members keep their roster evidence.

Measured on the direct-rust-door specimen (scratch probe, uncommitted):
10 underived of 15 -> 6. The parameter conj, the module-structure conjs,
and the bodied add arrow derive; what remains is the algebra atoms from
the + operation (AlgebraPrimitive, ring_field_add), the module atom
(dag_surface_module), the parameter references (x, y), and the
grammar-projection root conj that cascades once they land.

Enrolled witnesses (src/v2/test/claim/execution/infer_product_introduction_test.dag):
- product_introduction_derives_fully_evidenced_products_holds — census:
  4 Conj (3 derived, 1 frontier-by-frontier-child) + 1 Arrow (derived).
- product_introduction_composed_evidence_carries_child_groundings_holds —
  the params conj's evidence is a Conj whose x/y children target the dag
  authority's Int inhabitant.
- product_introduction_leaves_childless_conj_on_the_frontier_holds —
  boundary control via direct infer over a hand-built childless Conj.

Flip census (pre- and post-change, zero unexpected flips):
translate_underived_refusal 14/14, infer_self_grounding_wall 12/12,
branch_infer_if_then_else 2/2, compile_eval_thesis_proof 6/6,
ingest_bridge 9/9, cross_language_add_python_to_typescript 4/4,
inhabitant_neutralization 6/6 + e2e 6/6, emit_host_classical_not 14/14,
dag_binding_denotation 2/2, stage-verdicts instrument 2/2,
dag_add_emit_round_trip 4/6 (the 2 enrolled reds unchanged), door
production group still enrolled-red (unchanged).

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Ground canonical-operation and grammar-production atoms by authority roster membership

Two more specimen-scope derivations in infer_node_facts, both lookups into
declared authorities, never inventions:

- Canonical-operations roster (target_model.dag): every CanonicalOperation
  the target-model authority declares, rendered by
  target_model_canonical_operation_wire_node and gathered under one Conj
  root. The resolver canonicalizes surface operators (e.g. +) to those
  declared operations, so the wire atoms -- the operation discriminant and
  its field references -- derive by membership with the roster root as
  evidence. General over all 14 declared operations, not add-narrow.

- Grammar-productions roster (dag.dag): every production in
  dag_grammar_root() projected to its emitted surface atom under one Conj
  root keyed by production name. The bridge projects a production's parse
  into (identity atom, captured content) pairs, so the identity atom
  (dag_surface_module) derives by membership with the roster root as
  evidence. The roster derives from the grammar root, so a production
  added to the grammar joins by construction.

Both roster roots are Conj nodes, never structurally equal to any member
atom, so the self-evidence wall holds by construction (the first attempt
at the operations rule used the wire node itself as evidence and was
refused by grounding_evidence_is_source -- the wall doing its work).

Measured on the direct-rust-door specimen (scratch probe, uncommitted):
6 underived of 15 -> 2 (only the operand atoms x and y remain; the
grammar-projection root conj cascades once the module atom grounds).

Enrolled witnesses (infer_atom_grounding_rules_test.dag): each roster rule
pins derivation + evidence identity + census; a boundary control pins that
a bare atom with no authority membership stays frontier; the closing
control pins the 2-of-15 state.

Flip census: the product-introduction census witness updates 3->4 derived
conjs (the top conj now cascades) and gains a hand-built
partially-evidenced boundary control to replace the in-specimen one the
cascade consumed. Full battery otherwise unchanged: refusal suite 14/14,
grounding wall 12/12, instrument 2/2, binding-denotation 2/2, round-trips,
bridge, cross-language, neutralization, emit-host all green; enrolled reds
unchanged.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Ground binding-reference atoms from the enclosing arrow's domain declaration

The fifth specimen-scope derivation, closing the direct-rust-door
specimen's inference frontier: an Atom whose binding an enclosing arrow's
domain declares derives with the declared domain type as its evidence --
the declaration-site annotation, itself derived (x: Int grounds the x
reference). This is the same lookup the branch-operand path already
performs (infer_find_arrow_domain_type_in_tree), now written to the
operand atom's own facts; it is scope-naive (whole-tree, first match),
recorded in the frontier note, and deletes with the other specimen-scope
rules when the resolver hands infer declaration-resolved identities. The
tree is threaded through the fold's init chain to reach infer_node_facts;
the helper had exactly one caller.

Measured on the door specimen (scratch probe, uncommitted): 2 underived
of 15 -> 0. The specimen's inference frontier is fully closed, and the
production observation advances from InferenceRejected
(infer_grounding_not_derived) to EmissionRejected
(target_use_site_ownership_lookup_miss) -- a new, typed, located deficit
in the emitter, the next gate on the path.

Flip census (all three rewrites verified by execution):
- dag_binding_denotation_leaves_unbound_operand_atoms_on_the_frontier_holds
  -> dag_binding_denotation_declares_no_denotation_for_operand_bindings_holds:
  the boundary moves to the authority itself (the denotation table returns
  Absent for x/y), true regardless of infer's other rules.
- The three emit_host classical-not refusal guards (canonical, staging,
  staging-swapped) flip to acceptance witnesses pinning the emitted text's
  shape -- the real-infer tree now fully derives, and the emission is the
  same one the equals-eval witness proves behaviorally correct. The
  translate-refuses-underived behavior stays enrolled on hand-staged
  fixtures in translate_underived_refusal_test.dag (14/14 green). The
  renames are carried into the commit_workflow and witness_deferral_freeze
  rosters.
- New witnesses: binding_reference_derives_parameter_atoms_holds (evidence
  is the domain's Int binding atom, census 2) and
  door_specimen_fully_derives_holds (0 frontier of 15).

Full battery at this state: refusal suite 14/14, grounding wall 12/12,
instrument 2/2, binding-denotation 2/2, product-introduction 4/4,
atom-rules 5/5, emit_host 14/14, round-trips 4/6 (2 enrolled reds
unchanged), bridge 9/9, cross-language 4/4, neutralization 6/6 + e2e 6/6,
branch 2/2, eval-thesis 6/6; door production group still enrolled-red
(unchanged).

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Green the direct-rust-door: route emission through produced-decl composition and decode canonical operator wires

The door specimen's inference frontier is fully closed, so its production
observation now reaches the emission stage. Two defects surfaced there, both
fixed here:

Emission composition. generate_rust_emission_candidate served two lanes with
one root shape: the door's production path (a dag module shell) and a fixture
lane (a bare rust Arrow). The translate ownership gate queried the module
atom's ownership at a struct-field use site and refused with
target_use_site_ownership_lookup_miss, because the module's grammar-projection
conj was misread as a type record. The door's real composition is the
produced-decl path: collect declaration conjuncts from the inferred tree and
emit via emit_produced_decl. A new generate_rust_module_emission_candidate does
exactly that, enforcing an exactly-one-declaration admission policy
(rust_module_emission_decl_absent / _ambiguous). The observation and production
mint paths switch to it; the fixture-lane candidate is retained with a note
that it is fixture-only. A pure collector, produced_decl_conjs_in_tree, finds
nodes of produced-decl shape (a Conj whose first child is a Named edge to an
Arrow). Its decl-head match routes through a declared FreeMonoid<Edge>
parameter because the v1 seed stamps pattern variables from a declared
parameter type, not from a field-access scrutinee.

Operator decode. With composition fixed, source fidelity still refused: the
door emitted fn add(x: i32, y: i32) -> i32 { AlgebraPrimitive(x, y) } instead
of { x + y }. Resolution canonicalizes a surface operator atom into a
canonical-operation wire node, so a production tree's transform operator
position carries the wire, while fixture trees that bypass resolution still
carry the surface token atom. translate_project_transform_in_arrow_scope only
knew the surface-token table, so the wire missed and fell to callable apply,
rendering the discriminant identity. The projection now tries the wire decode
first (canonical_operation_from_wire_node) and only on a wire miss falls to
the surface-token table, then to callable apply; the arms are disjoint, so the
dispatch adds no fallback widening. target_transform_operator_child extracts
the operator child safely.

The door's closing expectation now greens by execution, so its known_red_probe
row in explicit_witness_admission is deleted per its own dissolution condition,
and the roadmap authority note, the door contract note, and the direct-path
plan are updated to record the green state. realized_closure_for_v2_direct_
rust_door_emit_run's module list reflects the produced-decl route.

Verified by execution: the door witness greens; the fixture, containment,
algebra, produced-decl, add-slice, and classical-not witnesses stay green;
claim_executor required-ci lanes build and witnesses both exit 0; cargo fmt and
clippy --all-targets -D warnings are clean. One pre-existing red,
witness_projection_is_active_only in the floor_cost_debt containment roster,
reproduces on the base revision and is unrelated to this change.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Close the parse-product grounding frontier: widen declared-inhabitant membership to the closed ingest set

The declared-inhabitant roster-membership derivation in 04_infer generalized
from the dag roster to the closed ingest set (dag, python, typescript):
infer_node_declared_in_language_inhabitants returns the declaring authority's
roster root as evidence, with deep subtree membership so a declared
inhabitant's leaf fact atoms derive exactly as the inhabitant node itself.

Measured: the python fixture's 19-node frontier and the typescript fixture's
28-node frontier both close to zero; all four add-slice stall population
round-trip witnesses green; the python->typescript cross-language compile
accepts, byte-identical to ts_source_text.

Section 4b(4) flips (expecting-red probes becoming permanent regression
controls for the acceptances):
- cross_language_compile_refuses_canonical_underived_holds ->
  cross_language_compile_python_to_typescript_round_trip_holds
- inhabitant_neutralization_emit_after_neutralize / same_flavor_python /
  go_int64_to_ts refusal helpers -> round-trip controls
- inhabitant_neutralization_python_to_ts_cross_language_compile (e2e) ->
  round-trip control; python->go members stay refusal guards (go is outside
  the closed ingest set)
- cross_language_emit_inhabitant_neutralization_refuses_underived_holds ->
  round-trip control; the python->typescript emit-matrix row reads ChainProven

The add-slice stall's next-rung trigger fired, so it retired per DESIGN
4b(4): removed from all_guarantee_stalls, row file deleted, witnesses stay
enrolled.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Promote the add family to SelfEmittedNative: native-only verdict witness for the emitted add crate

First InterpreterRetained -> SelfEmittedNative promotion after classical_not,
executing the v2-emitter-first-behavioral-module first slice at the
coverage-frontier grain: the add family (fewest dependencies — integer
literals plus one canonical operation) now carries a native-only verdict
witness, so its behavior is established by the emitted crate's own stdout
with eval() unreachable from the verdict path.

- emit_host_native_only_add_holds: real emit -> cargo build -> native run,
  stdout pinned to the family's expected octet, sharing the kernel family's
  one-build cache key exactly as the classical_not arm shares its family's
  key (no duplicated cold build).
- emit_host_native_only_add_wrong_octet_mismatch_detected_holds: the broken
  control — a no-eval verdict has no oracle leg to break, so the expectation
  side breaks (an octet the run never produces must not match); program-side
  discrimination stays with the family's equals_eval primitive-five/six pair.
- The add coverage row flips disposition with its backing citation enrolled
  by construction (the verdict entry is file-grain enrolled in
  falsifier_self_host_wet_template_entries).
- Frontier census tests updated at identity grain: natives are exactly
  {classical_not, add}; split 2/13.

Verified by execution: all six native-only verdict tests green locally
(real wet legs — compile_skipped receipts show cold builds and native runs);
all eight emit_coverage_frontier tests green, including the unbacked-claim
RED control.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Record the add-slice defect's repair in the declined-live-tree classification

The row classified candidate_generation_translate_self_emit_dag_add_slice_holds
as RealDefect/CompilerBehaviourRefusal with measured evidence that translate
refuses infer_grounding_not_derived. The owner lane (v2 self-host) repaired the
subject: the declared-inhabitant roster-membership derivation grounds the
slice's type spine by lookup, and the witness passes under claim_batch
--hermetic on the merged tree. The dated classification is kept verbatim; the
disposition flips RoutedToOwner -> RepairedInThisChange with the repair
measurement appended to the evidence, so the routing carrier stops dispatching
a fixed defect. Structural witnesses (count 13, no NotReproduced, exact
partition) are untouched and pass.

* Hoist two in-body annotation blocks to module-item grain

Main's annotation-placement wall (source annotations admit only standalone
leading blocks attached to module-scope declarations; in-body forms refuse)
reached this branch through the merge and refused 8 blocking errors on the
00_compile closure: the add-family promotion note inside the
emit_coverage_frontier_roster list and the python->typescript row note inside
the cross_language_emit_matrix list. Both blocks move above their enclosing
declarations, rephrased to name their subject row. Measured: gunbc compile of
src/v2/compiler/00_compile.dag now emits 172 files with 0 blocking errors;
both files' suites stay green (8/8 and 4/4).

* Promote the complement family to SelfEmittedNative: native-only verdict witness for the emitted logic family crate

The complement family's native execution runs family-grain per the
witness_family_build_grain_ruling (one crate for meet + join + complement,
argv-dispatched), so the native-only arm emits the logic family crate and
runs the complement member through the family dispatcher, sharing the
family witness's one-build cache key. The verdict is decided solely by the
emitted native run's stdout (expected octet 0, complement(True) = False);
the broken control flips the expectation side (octet 1 can never match),
with the comparator pinned by the stdout mock pair. Program-side
discrimination stays with the equals_eval agreement pair and the family
witness's all-alt leg.

The frontier row's backing citation lands in the already
file-grain-enrolled native-only verdict entry, so it is enrolled by
construction; the roster comment is rephrased to cover both 2026-09-07
promotions (add and complement). The frontier test's split and native
membership assertions move to 3 native / 12 retained.

Verified by execution: claim_batch --hermetic on
emit_host_native_only_verdict_test.dag passes all 8 witnesses (the two
new complement arms included), and emit_coverage_frontier_test.dag
passes all 8.

* Key the emitter's host-String arm on declaration provenance, not spelling

is_host_text_carrier_type answered true for any type expression whose
authored name reads "String", including references to the structural
alias v2.std.text.String (type String = FreeMonoid<Char>) that the
namespace lane (gunbc#9907) requalified the v2 corpus's text-carrier
fields to. The emitter rendered every one of those references as the
host String while value-position consumers rendered the structure -- the
E0308 family dominating the self-host compile-phase frontier (41 of 64
in v2_compiler_tokenize.rs on the post-merge board).

The String arm now consults the resolved declaration's provenance
against v1.compiler.coercion structural_declaration_modules_for -- the
same roster type_realization_decision reads -- so the legacy arm and the
strict decision cannot diverge on one node (DESIGN section 3, and
gunbc.recurring_failure_mode alias_resolution_collides_with_kernel_spelling).
Kernel mints and unresolved references keep the host answer exactly as
before.

Regen: the only drifted stage0 mirror is v1_compiler_emit_rust.rs
itself (no module in the stage0 closure references a structurally
declared String -- verified by the whole-population candidate tree),
installed from target/stage0-regen-candidate after the priced round's
partitioned rebuild refused MirrorHasNoOwningPackage on the emitter
(the emitter is monolith-shell, not partition-owned). Fixed point
verified by execution: claim_executor --required-regen on the rebuilt
seed reports first_generation_equal=true over 158 adjudicated mirrors.

* Peel qualified String alias leaves in field position: XL-N closure 72 -> 28 errors

A field authored v2.std.text.String reached the Rust emitter as an overlay-less
resolved reference leaf and rendered the bare terminal name, which binds the
prelude String cross-module (#9813: kernel names are never overridden by
imports, so the use-line is dropped) while every value position renders the
structural carrier Rc<Vec<i64>> -- the v2_compiler_tokenize.rs E0308 family,
41 of 72 errors on the XL-N phase board.

The new rust_overlayless_alias_leaf_requires_peel arm in
render_rust_type_without_applied_binding detects the population (overlay-less
zero-parameter alias leaf, qualified spelling, String terminal segment,
closed_alias_peel_verdict agrees) and renders the alias declaration's resolved
right-hand side, projecting the same realization the fn-signature positions
already produce.

The qualified gate is load-bearing: inside the declaring module the bare name
is the correct render (the emitted module carries the alias declaration), and
the local binding's resolved_type drops the RHS type argument, so an ungated
peel rendered Rc<FreeMonoid> there (E0107 x13, E0282 x2 on the probe). Bare
String keeps denoting the kernel scalar through the host-carrier arm.

Measured: probe specimen (qualified/bare/direct-FreeMonoid/container/variant/
local-alias positions) compiles clean; XL-N compiler closure cargo check
72 -> 28 errors with the residual census dominated by the declared
text_boundary_identity_wall class (kernel String vs structural carrier at
bare-authored boundaries, 17 of 20 E0308s); v1-corpus fixed point holds
(first_generation_equal=true, 158/158 adjudicated).

* Resolve the 12 non-hop XL-N closure errors at source: text-wall conversions + witness_violates helper

Four clusters, all measured non-hop additions between receipt_1 (155) and the
post-peel census (28); the live gate now measures 15 with zero unadmitted
regressions:

- integer.dag: integer_string_to_decimal_digits_step takes v2.std.text.String;
  the public boundary converts with chars() (text_boundary_identity_wall
  specimen discharged at this site).
- 01_tokenize.dag: Token/UnboundSourceAnnotation lexemes convert structural
  -> host String with chars_to_string() at construction, mirroring the v1
  tokenizer's host-lexeme carrier.
- target_model.dag + bash.dag: EmitSpellingEscape.from/to and
  apply_emit_spelling_escapes go structural (v2.std.text.String); the
  EmitSpellingQuote arm converts host->structural->host at its boundary;
  bash's escape rows wrap their kernel String literals with chars().
- witness.dag + 3 call sites (collection list_nth, provenance
  span_index_resolve_textual_locus_from_ids, compile outcome_with_diagnostics):
  new witness_violates<C> helper puts Violates constructions in a
  Witness-headed position so the emitter resolves the carrier type argument;
  dissolves once inference records per-call substitutions.

Verified: 48 targeted claim witnesses green (tokenize behavioral, shell
conformance, string brace escape, string length, map-lookup violates, source
text ingress, bash materialize x12, int literal smoke x6, provenance span
index x2).

* Record receipt_2 on the self-host compile-phase frontier: 15-error census at 66765317ec

The census at the XL-N lane tip: 155 -> 15 net, credited to the qualified-alias
peel (60cbd7b697, 72 -> 28) and the twelve-error source cluster (66765317ec,
28 -> 15). The epoch changes on the instrument's target pinning (found by
review on gunbc#9857), admitted with receipt_1's board as the reclassified
predecessor under the identity map. Nine added identities are hop relocations
admitted by the hop index; four sit in python/typescript modules newly entered
into the emitted closure, admitted as ExposedByNewEmittedModule.

Validated: all 36 self_host_compile_phase_frontier_witness claims PASS,
including current_persisted_compile_phase_frontier_holds.

* Emitter: a substituted declaration node carries its own provenance

Inference substitutes the resolved declaration into a data annotation's
type-argument position, so BooleanAlgebra<v2.std.logic.Bool> reaches the
emitter with the arg BEING the type Bool = True | False declaration itself
(Disj connective, ident_span in src/v2/std/logic.dag, no Resolved wrapper).
type_reference_provenance_in_env's bare-leaf arm re-resolved that leaf in the
REFERENCING module's scope, where post-#9813 a kernel-shadowed spelling
answers the kernel declaration -- so the structural enum rendered as host
bool against a value of BooleanAlgebra<Bool> (the python.rs:328 /
typescript.rs:177 E0308 pair on the XL-N compile-phase frontier).

The connective is the discriminator: a reference node is a bare name
(NoConnective); a node carrying Conj/Disj structure IS the declaration, and
type_reference_provenance's own-span fallback already answers that shape
correctly. The guard routes declaration-shaped nodes there directly, bypassing
the scope lookup that #9813 makes answer the kernel.

Mirror regenerated via the regen round; fixed-point verified
(claim_executor --required-regen PASS).

* Clear the remaining XL-N closure errors at source: carrier conversions at the boundaries

The receipt_2 census's fifteen identities, resolved at their sources:

- lexing.dag, dag.dag, python.dag, typescript.dag: LexPattern.text is the
  structural carrier (v2.std.text.String); the construction sites held host
  Strings. Convert at construction with chars() -- the #9907 ingress pattern.
- python.dag / typescript.dag bool groundings: qualify the annotation as
  BooleanAlgebra<v2.std.logic.Bool>; with the emitter's substituted-
  declaration provenance guard the qualified arg now renders structural.
- target_model.dag: target_lex_rule_literal_step returns the host carrier
  (chars_to_string over the structural pattern text); TargetText.source
  converts at the is_empty boundary; the unicode-scalar symbol intern converts
  its single-codepoint list to the host carrier.
- qualified_name.dag: qualified_name_from_dotted_string uses the host-carrier
  emptiness check (string_length == 0) instead of routing through the
  structural string_is_empty.
- 02_parse.dag: parse_looks_like_match_arm_start rewritten on host-carrier
  operations (string_length, char_at, code_point) rather than converting to
  the structural carrier for a two-character lookahead;
  parse_char_is_arm_pattern_lead takes the codepoint Int directly.
- v1_interpreter_primitive_surface.dag row_key: the concat pipeline lowered
  to a .concat() method call on std::string::String (E0599); rewritten as
  nested concat calls.

Measured: the 00_compile closure emits 172 files and cargo check reports
cargo_clean=true, cargo_error_population=0 under the pinned 1.93.0 toolchain.

* Pin the cargo half's toolchain channel by construction

The cargo half runs with cwd = a fresh mktemp directory; with no
rust-toolchain.toml there, rustup resolves the host's DEFAULT toolchain, so a
census under cargo 1.83 and one under cargo 1.93 would compare as equal epochs
while different compilers did the measuring -- the fabricated comparability
the target pin (gunbc#9857) excludes, one level up. Measured 2026-09-07: a
host default of 1.83.0 met a crates.io index whose freshly published
dependency manifests require edition2024, resolution failed before any
diagnostic existed, and the zero-diagnostic refusal fired on an unmeasured
tree.

The pin is propagated by copying the repo's rust-toolchain.toml into out_dir:
the file remains the sole in-repo channel authority (its header forbids a
second pinned literal), and the copy makes the measured channel true by
construction on any host. The gate's read_live_toolchain observes the same
channel because every documented actuator invokes from the repository root,
which the same file governs.

* Record receipt_3 on the self-host compile-phase frontier: the emitted closure's cargo census is empty

Measured at 5ee4892b70 by the one-entry instrument: the 172-file emitted crate
reports zero cargo error diagnostics, so the board attributes every phase a
count of zero and furthest_phase_reached stands at Borrowck. The fifteen
removals against receipt_2 need no disposition; nothing was added.

The epoch does not change: the cargo half now pins the toolchain channel by
copying the repo's rust-toolchain.toml into the scratch crate, and every
recorded comparison field is identical to receipt_2 (whose census the
fingerprint evidence shows the same 1.93.0 toolchain already compiled), so the
same-epoch arm carries no reclassified predecessor.

The frontier-state pin flips per DESIGN 4b(4):
the_published_frontier_standing_does_not_claim_typeck_or_borrowck_passed
becomes the_published_frontier_standing_claims_typeck_and_borrowck_passed, the
permanent regression control over the green state.

Validated: all 36 self_host_compile_phase_frontier_witness claims PASS,
including current_persisted_compile_phase_frontier_holds.

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-rung-drops.md

* Remove the stale PointwisePower inhabitant rows from the four language rosters

First native-parity divergence class found by running the emitted closure on a
discriminating fixture: the algebra inhabitant rosters still carried
PointwisePower after its authority row was cut, so the emitted compiler panicked
at 12 record-shaped carrier sites while the interpreted seed refused cleanly.
The roster rows are removed in rust/python/go/typescript types.dag, the derived
coercion assertions in compiler_tests.rs regenerate without them, and two
witnesses pin the boundary: the record shape constructs its structural carrier,
and FinitePowerSet still refuses while its row stands.

Mirrors regenerated by a converged regen round (fixed point Reached, stage-1
PromoteGenerationInputs over the three language types mirrors).

* Regen gen-2 gate: compare executable digests in one spelling

The admitted side of run_built_seed_regen carries the executable-digest
spelling (current_exe_digest, next_pass_executable_digest) while the observed
side hashed the file through path_digest, which prepends the fnv1a64: tag.
Same bytes, two spellings, so the gate could never pass -- unpassable since
fa2d403dc8 (#9771). Factor current_exe_on_disk as the single path authority
and read the observed digest through current_exe_digest so both sides spell
the same bytes the same way.

* Model ReleaseScopeEmpty for release-excluded mirrors, end to end

A regen round whose only stage-2 drift was compiler_tests.rs (the PointwisePower
roster removal rewrote its derived coercion assertions) refused the rebuild
MirrorHasNoOwningPackage: the mirror is owned by no partition package, because
every item it defines is #[cfg(test)] and no release unit elaborates it. The
refusal conflated two different states -- unowned (a coverage hole) and excluded
from the release build by construction (a precise empty scope).

The model now names the class: rebuild_scope_release_excluded_mirrors rosters
its members (compiler_tests.rs, cited to emit_compiler_tests_module), the
decision answers ReleaseScopeEmpty when the whole change set is excluded, and
the actuation shape is actuatable with an empty package closure and every
partition package excluded -- the build still runs as verification, and a
compiled partition package refuses the stage. The host admits the empty closure
only when the new stage0_partition_rebuild_release_scope_empty_today query
answers true; any other empty closure still refuses. A mixed change set scopes
on its release-visible members alone.

Verified by execution: the 2026-09-08 round converged (fixed point Reached)
with stage-2 installing compiler_tests.rs alone; cargo recompiled the shell
crate on its fingerprint (the outer mod line is ungated, so rustc reads the
file) while the produced executable was byte-identical -- stage input seed
digest == output seed digest. Four new witnesses pin the arm, its actuation
shape, the mixed set, and the host-facing query's two arms; the boundary
witness (unowned cli_run.rs still refuses) keeps the roster from decaying into
the absorbing fallback.

* Round-cost receipt: project installed mirrors to the model's vocabulary

The receipt's partition-rebuild line is rendered by the model over
receipt.installed_mirrors, which the host populated from the stages'
projected_paths -- full paths -- while the partition rows and rosters key on
basenames. Every drifted round's receipt therefore rendered a spurious
RebuildScopeRefused MirrorHasNoOwningPackage line naming a full path, a false
claim on the round's own receipt. Route the projection through
emit_path_basename, the module's single path-to-basename bridge, so the field
carries the mirror names the model's vocabulary means.

* Hoist ReleaseScopeEmpty annotations to module-item grain

The ReleaseScopeEmpty modeling commit placed three // blocks inside
declaration bodies (stage0_partition_rebuild_is_actuatable,
stage0_partition_rebuild_decision, stage0_partition_rebuild_excluded_today).
The .dag realization admits annotations at module-item grain only, so the
floor lane's parse phase refused the file with 12 located errors and the
run ended floor refused. The prose is unchanged; each block now sits above
the declaration it describes.

* Spell the PointwisePower witness's finite-set exclusion as the applied realization

The witness added with the fossil-row removal excluded the bare spelling
"BTreeSet", but every emitted file's preamble imports OrdSet as BTreeSet,
so the row could never green. The exclusion's subject is the finite-set
REALIZATION the fossil row would have asserted; spell it applied
(BTreeSet<i64), which the preamble's import line does not contain.

* Emit fieldless-record data values as null for the unit-struct carrier

The second native-parity divergence class, measured 2026-09-08 on the
native run of the emitted 00_compile closure: emit_data_value_json spelled
EVERY record literal as a JSON map, including the zero-field record, while
emit_struct_from_children renders that same declaration as a Rust unit
struct (pub struct BoolEncodingFact;). serde's derived unit-struct
Deserialize reads null and rejects {}, so the emitted compiler panicked at
first touch of v2.std.logic's bool_primitive_facts: "invalid type: map,
expected unit struct BoolEncodingFact". The JSON spelling of a data value
must deserialize into the Rust type the same declaration emitted; the
record arm now spells the zero-field value null and keeps the map spelling
for non-empty records.

The mirror is taken from the required-regen candidate, not hand-edited.
Two witnesses enroll: the discriminating red (zero-field record spells
null, never {}) and the boundary control (a record with fields keeps the
map spelling).

* Bind the duplicate-definition filter ahead of its branch condition

Main's FilterInBranchCondition wall (#10699) refuses to publish a module
whose filter call sits in a branch condition, and the v2 00_compile closure
emission names primitive_duplicate_semantic_definition_violation as such a
site. The filter is pure and total; binding it with a let ahead of the
branch is the authored remediation the wall exists to force, and the
emitted closure is unchanged in behavior.

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-rung-drops.md
Ledger-Rows-Repaired: docs/design-rung-drops.md rust_unit_tests_off_the_merge_path
Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
Ledger-Rows-Repaired: docs/design-rung-drops.md transitional_admission_exception

* Emitter: three native-parity repairs for the post-merge 00_compile closure build

Three divergence classes measured as the 21 rustc errors on the natively
emitted 00_compile closure after the main merge, each repaired at the .dag
source with a discriminating witness:

- Locality wins over a foreign ambiguity (12 E0433 in v2_std_integer.rs):
  alias_rhs_base_module_filename asked the global leaf index, saw
  LeafAmbiguous for Compose, and emitted the poison marker even inside
  v2.std.integer itself, where source resolution binds the local
  declaration before any cross-module lookup. The local physical
  declaration now shadows foreign declarers; the poison marker still
  stands for a leaf two FOREIGN modules declare.
- The qualifier is the disambiguator (8 E0425/E0433 in
  v2_lens_fact_density.rs): the qualified use-line route declined any
  globally-ambiguous leaf, but a qualified reference names its provider
  in its own spelling. The route now resolves by DeclaredCallableIdentity
  at the qualifier, keeping the type-declared and export-proof walls.
  The dotted spelling reaches the route through the value surface (a
  qualified value projection's borrowed type stamps the match patterns'
  parent_enum); the witness reproduces that chain exactly, and its
  exclude half pins the E0603 boundary (the dotted VARIANT head must
  still be declined).
- Clone-bound forwarding is transitive (1 E0277 in
  std_realization_measurement.rs): the call-forwarding derivation
  re-derived only each callee's SELF-derived half, so a callee whose
  bound is itself forwarded re-derived to empty. The derivation now
  recurses over the call graph with the module's visited-set
  termination; the equality half stays one-hop as declared.

Witnesses: 56/56 PASS on the rebuilt seed; regen fixed point holds.

* Refuse variant record literals on the serde_json data path fail-closed

A record literal with parent_enum present is a variant construction whose
wire spelling is the parent coproduct's declared VariantEncoding policy --
a module-local fact of the parent's home module that emit_data_value_json
does not carry. The zero-field arm's null and the map arm's untagged fields
are both measured to fail serde deserialization under the internal-tag
default, so the arm now refuses and the caller renders compile_error!, a
build-time located refusal where a runtime panic on the data definition's
expect was the latent alternative. The refusal names its trigger: a
closure-wide wire-policy index beside EmitGraphInfo.type_decl_items.

Witness: w_variant_record_lit_on_the_json_data_path_refuses_fail_closed
forces the JSON path with a nested-record Holder and asserts the
compile_error! spelling while excluding the former null mis-serialization.

* Spell variant record literals on the serde_json data path from a closure-wide wire-policy index

The fail-closed refusal landed in 73b582dea6 fired on 5 real corpus sites
(SugarKey x2, CopiedPortCitationFrontierDisposition x3), proving variant
record literals reach the JSON data path in the 00_compile closure. This
change replaces the refusal with the correct spelling, driven by a new
closure-wide index:

- v1.compiler.infer_emit_info gains DataVariantWireSpelling, the
  language-general projection of a coproduct's Rust wire serde policy
  for one variant (InternalTagged { tag_field, tag } | BareString { tag }
  | Untagged | SpellingRefused { reason }), and EmitGraphInfo carries
  data_variant_wire_spellings: Map<String, DataVariantWireSpelling>
  keyed by coproduct.variant.
- v1.compiler.emit_rust builds the index once per emission root via
  build_data_variant_wire_spellings, resolving each coproduct's policy
  through the new shared resolve_emission_coproduct_wire_policy (the
  same function the type-emission side now calls, so the two cannot
  drift), projecting each variant through data_path_wire_variant_tag
  (rename_all and StripAffix aware), and poisoning collisions as
  SpellingRefused so ambiguity stays fail-closed.
- v1.compiler.emit's emit_data_value_json variant arm reads the index:
  internal-tagged spells {"_variant": tag, ...fields}, bare-string
  spells "tag" for nullary and refuses fielded, untagged spells the
  bare fields or null; unindexed keys and stored refusals remain
  compile-time errors. The service mock-property chain threads
  emit_info through so dry-run data spells identically.

Witnesses: w_variant_record_lit_on_the_json_data_path_refuses_fail_closed
is rewritten as ..._spells_the_internal_tag (asserts the internal-tag
map, excludes the former null mis-serialization and the refusal), and
w_fielded_variant_record_lit_on_the_json_data_path_spells_tag_and_fields
pins the fielded case. 57/57 witnesses pass; regen fixed-point holds.

* Promote field_access to SelfEmittedNative on the emit coverage frontier

Fourth native-eval construct promotion, after classical_not, add, and
complement. The native-only verdict arm pair lands in the already
file-grain-enrolled long/ entry, so the backing citation is enrolled by
construction:

- emit_host_native_only_field_access_holds pins the family one-build
  cache run's stdout to octet 9 (the byte the family witness's warm leg
  pins on the same build), eval() never called.
- emit_host_native_only_field_access_wrong_octet_mismatch_detected_holds
  breaks the expectation side with octet 1, the alt tree's byte.

Both arms verified wet locally (real cargo build + native run, sharing
the field_access family one-build cache key). The roster row flips to
SelfEmittedNative; the two census guards update per 4b(4) — the split
moves to 4 native / 11 retained and the identity-grain membership guard
is renamed to name the four-member population. The family's equals_eval
agreement pair stays enrolled as its program-side discrimination leg.

* Drop the scratch parity probe from the tree

The probe is a manual parity-loop instrument (the interpreted leg of the
native-vs-interpreted comparison), not a corpus declaration with an
executing consumer (DESIGN 6 experimental residue). It stays in use
locally as an untracked file.

* Promote match, loop, and fold_closure to SelfEmittedNative

Fifth, sixth, and seventh native-eval construct promotions. The three
match_loop_fold family rows flip together on one shared family-crate
arm shape, per the witness_family_build_grain_ruling: each arm emits
the three-member family crate once and runs its own member through the
argv dispatcher against the family one-build cache key.

- emit_host_native_only_{match,loop,fold_closure}_holds pin the warm
  legs' stdout to the family's declared octet lists (match/loop
  [0,1,0,0,0], fold [0,7,0,0,0]), eval() never called.
- The wrong-octet controls break the expectation side with each
  member's own alt octets (match/loop [0,2,0,0,0], fold
  [0,255,255,255,255]).

All six arms verified wet locally. The census guards update per 4b(4):
7 native / 8 retained, and the identity-grain membership guard is
renamed to witness_native_rows_closed_membership_holds so the name
stops encoding the volatile population.

* Promote meet_join to SelfEmittedNative on the emit coverage frontier

The meet_join family's native-only verdict arms land on the complement arm's
helper, generalized to take the family member_id: meet and join run through
the same argv-dispatched logic family crate (one-build cache key shared with
complement, per the witness_family_build_grain_ruling), eval() never called,
verdict decoded from stdout. Octets meet=1 join=1 are the bytes the family
witness's warm legs pin on this same build; the wrong-octet control expects
each member's alt byte (0), which the primary runs can never produce.

Both arms verified wet: cold build then warm hits, PASS/PASS. The roster row
flips InterpreterRetained -> SelfEmittedNative (eighth promotion); census
guards move to 8 native / 7 retained with meet_join_eval_subject named in the
closed membership.

* Promote variant_construct to SelfEmittedNative on the emit coverage frontier

The variant_construct family's native-only verdict arms follow the
field_access arm shape exactly: the tree is the family's own equals_eval
tree value (emit_variant_construct_eval_tree, no eval leg reachable), the
run shares the family one-build cache key that
emit_on_demand_variant_construct_native_one_build_holds colds, and the
expected octet 9 is the byte the family witness's warm leg pins on this
same build. The wrong-octet control expects the alt tree's byte (1), which
the primary run can never produce; the wrong-value alt leg in the family
witness keeps the program-side discrimination.

Both arms verified wet: cold build then warm hit, PASS/PASS. The roster row
flips InterpreterRetained -> SelfEmittedNative (ninth promotion); census
guards move to 9 native / 6 retained with
emit_variant_construct_eval_subgraph_node named in the closed membership.

* Close the emit coverage frontier: final six rows to SelfEmittedNative

The last six InterpreterRetained rows flip to SelfEmittedNative, taking the
roster to 15 native / 0 retained:

- filesystem_read and shell_exec_run (host-effect transport families, no
  translated arrow body): the arms reuse each family's own native leg with
  the expectation pinned as a literal grounded by the family's enrolled
  fixture pin (dag/extdeps/shell/exec.dag contains bash; its shell.Exec.Run
  argv materializes to exactly [bash, -s]), run through the families' fixed
  witness workspaces.
- module and produced_module: the arms execute the exact sources the
  equals_eval pairs run (emit_module over the add fixture tree;
  produced_add_module_source's ingested two-fn module), octet 5 pinned
  against the add family's primitive-five/six oracle leg.
- call and record_construct: the arms emit the families' own producer trees
  against their target models, octets 7 and 9 pinned against the
  primitive-seven/eight and wrong-field oracle legs.

The four families without a one-build cache witness run under per-family
fixed workspace roots; content-safety comes from the realization-digest
nesting in run_host_process_admitted (changed source colds, never serves
stale), the same mechanism the filesystem_read fixed workspace relies on.
All twelve arms verified wet: PASS/PASS each, cold builds then warm hits.

With zero retained rows the retained_via_eval_agreement constructor loses
its last consumer and is deleted (DESIGN 3c); the InterpreterRetained
variant stays as the disposition authority's other state. Census guards
move to 15 native / 0 retained with all fifteen decl names in the closed
membership.

* Record the emit coverage frontier closure in the direct-path plan

Axis C line: all fifteen roster rows are SelfEmittedNative as of
2026-09-08, interpreter_retained_rows() is empty, and the row constructor
was deleted with the last flip. Notes explicitly that this closes axis (a)
(witness-body-runs-native) only; axis (b) (the regen-grain production
flip) remains operator-gated.

* Restore structural text reads in 02_parse: the chars(String) <- Variant cluster

Commit 285b02eed2 converted three structural-text reads in the parser to
host-string builtins (chars(s:), string_length, char_at, code_point) while
chasing emitted-closure compile errors. Lexeme is v2.std.text.String, which
interprets as a Variant value, so every claim that parses tokens failed at
runtime with 'chars expects a string argument, got Variant' — 10 claims in
the required floor lane.

parse_lexeme_digest folds the Lexeme list directly again,
parse_char_is_arm_pattern_lead takes Char again, and
parse_looks_like_match_arm_start matches string_head's CharFound/CharAbsent
again. Verified locally: all 10 claims of the cluster pass.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Close the prepare_grammar shared-fill cost class: portable nullable carrier + preparation-time warming

Two defects composed into the required floor's twelve FillBudgetExceeded
refusals, both repaired at source:

(1) GrammarFirstAnalysis.nullable_set was a PointwisePower<Symbol>
characteristic function — a nested closure tower the cross-claim pure tier's
publication walk refuses totally (ServeCacheValueNotPortable), so the one
fill every parse of .dag source demands could never store and every
demanding claim recomputed it. The carrier is now the enumeration it always
was (List<Symbol>, the GrammarRoot.sync_tokens repair's own precedent):
set_symbol_insert de-duplicates over symbol_list_contains (first_list_contains
renamed, it was never first-specific), the fixpoint's convergence measure is
the list's own length, and nullable_member_count dissolves into it.

(2) The fill costs more than one claim's CPU budget on the lane's runner, so
an in-fold first touch could never complete. The nullary
v2.compiler.program_assembly.dag_prepared_grammar producer moves that first
touch to strict preparation via floor_cross_claim_pure_producers_warm —
outside every per-claim budget — and every claim then serves the landed fill.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Split the meet/join native-only arms: one member per claim under the 500ms line

The two-member shape put two native-run verdicts inside one claim's 500ms
CPU budget — emit of the family crate plus the cached-run receipt walk,
twice over — and the required floor measured both meet_join arms over the
line. The ceiling is the floor's own and does not move to admit a claim
shape; the arm splits by member instead, the grain the family's equals_eval
pair already claims at (emit_host_meet_equals_eval_holds /
emit_host_join_equals_eval_holds). Each claim now pays one native run; the
family crate build stays shared through the same one-build cache key. The
coverage frontier's meet_join row re-cites emit_host_native_only_meet_holds;
the join claim carries the family's other half.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Adjudicate the five structural-text/logic requalification deltas at their exact subjects

The branch's required-witnesses lane reports five TargetChanged binding
deltas, all one change class: three String sites (EmitSpellingEscape,
apply_emit_spelling_escapes, integer_string_to_decimal_digits_step)
requalified to v2.std.text and two Bool grounding sites (py_bool_grounding,
ts_bool_grounding) requalified to v2.std.logic — the gunbc#9907
namespace-lane requalification reaching the sites the XL-N closure repair
and the chars(String) <- Variant cluster repair touched. The spelling is
identical on both sides in every row; only the declarer moved, from the
ambient kernel type set to the named authority. Five exact-subject
TransitionAdmission rows, enumerated never patterned, with the dissolution
trigger on gunbc#10692's merge.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Share the ingested-fixture pipelines across claims: three warm producers for the five over-ceiling claims

The prepare_grammar warm-store unmasked five changed witnesses over the
500ms per-claim ceiling: the classical_not family's three emit claims
(marginal 474-501ms, each re-running the full tokenize->resolve pipeline
on a module-constant source) and the produced_module pair (505-542ms,
each re-assembling the same two-decl module). CI's runner is ~1.8x this
lane's local host (median ratio over the 25 claims present in both
ledgers), so these project to ~900ms there — structurally over, not
variance.

The repair is the roster's own named one — stop recomputing a pure
function of program content — in its WARM arm, because a ~370-382ms
claim-forced fill leaves under 130ms of headroom and would die
mid-flight on the lane exactly as prepare_grammar's did:

- produced_add_module_source (already nullary) is enrolled directly.
- ingested_classical_not_arrow_with_body and its swapped sibling are new
  nullary producers in the ingested_fixture_arrows idiom; the three
  failing claims' tree helpers now take the arrow outcome, with the
  source-taking staging variant delegating so unselected claims keep
  their spans untouched. The arrow is the deepest pipeline stage whose
  value is closure-free and therefore portable; the InferredTree above
  it carries the facts PartialFunction and can never store.

claim_batch: 14/14 classical_not claims pass with identical verdicts.

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Share the door-specimen resolved tree across claims: one warm producer for the seven unmasked over-ceiling grounding claims

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Stage0 emission boundary as a target profile: visibility and integer carrier selected, measured over the disk route

The regen-grain flip's presumptive subject (std.integer) is not producible by the
v2 generator, and neither is any other real corpus mirror. Measured, not assumed:
of the 152 committed stage0 mirrors joined to their .dag sources, exactly one
module carries a single declaration -- the shape the production composition
admits -- and that module's body stops emission. So this change lands the two
BOUNDARY selections the flip needs, and names the remainder.

The two selections are not emitter generalization. Rust owns what Rust is; this
adds what the stage0 SEED CRATE requires of a module emitted into it:

  visibility -- every committed mirror is `pub`, because the crate calls across
  module boundaries (gunbc_rust_decl_type_overlay's function is called from
  v1_compiler_emit_rust). The .dag source spells no visibility and Rust emission
  in general must not: a private item is correct at a boundary with no external
  consumer. The keyword is a Rust row; the SELECTION is the profile's.

  integer carrier -- the language's Int is unbounded and a Rust realization picks
  a primitive. The committed stage0 ABI is i64; the direct-door fixtures are
  organized around i32 and stay that way. rust_binding_spellings_for_int takes
  the carrier as a parameter rather than the base target being relabelled, which
  would have fused two boundaries into one row (DESIGN section 3).

Evidence, all three PASS by execution (claim_batch, wet -- the specimen is read
off disk, not carried inline): the profile emits
`pub fn probe_add(x: i64, y: i64) -> i64 { x + y }` through
source_ref_for_observed_storage_path -> ingest -> assemble -> infer -> the
production single-declaration composition; and two controls, one per capability
class, observe the base target emitting no `pub` and emitting i32 at the exact
positions the crate fixes. Each fails for its own reason, so a regression in one
cannot be masked by the other. No enrolled claim exercised the disk-backed
production seam before this one -- the door's own specimen carries its module
source inline.

THE REMAINDER, measured per form over real files rather than predicted. The
overlay module's body needs five further capabilities, and three of them are
inference frontier, not emission:

  x > y          EMIT refuses (transform shape invalid at the first operand)
  !a             EMIT refuses (same site)
  x + 1          INFER refuses -- integer literals are Value-kind, no rule
  let z = ...    INFER refuses -- Bind-kind, no rule
  Int? param     EMIT refuses -- type ref renders only Atom shapes
  match v {...}  ASSEMBLE refuses -- Present/Absent unbound with no import

04_infer's node_grounding_frontier_note already states this: v2 derives six of
twelve node kinds, "Transform add-shape only". So the production-compatible
corpus module is gated on that open frontier, not on a handful of spellings, and
a > b working while a && b works is a resolution/layout question rather than a
missing operator row (the canonicalization table already carries op_gt).

Also noted, unfixed and deliberately so: an unspelled type binding prints its
symbol lexeme (`bool_node_symbol`) instead of refusing, and the Rust bool
spelling exists twice -- once as a TargetAtomRealization, once as a
binding-spellings row. The repair is for produced-decl type refs to consult the
atom realization catalog, which is the first missing join rather than a new row.

One roadmap transition added between the direct door and the flip
(v2-emitter-production-compatible-corpus-module), so the flip node keeps its own
different fact: that production regeneration actually selected v2 and could not
reach the old generator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X5tyxfVrw3chDNbQ3sVD3

* Share the family-crate emitted pairs across claims: two warm producers for the twelve ceiling-band native-only verdict claims

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>

* Keep the base Rust spelling map byte-identical, and share the two stage0-boundary emissions

The floor refused this branch's first head two ways, and both are cost, not
content. Fixed at the cause rather than by raising a line.

FIRST: twelve of #10692's native-only rows tipped 6-118ms over the 500ms
per-claim ceiling. They sit deliberately just under it -- the parent's last two
commits are about keeping them there -- and this branch had re-parameterized
rust_binding_spellings, which every one of them evaluates. The profile now
OVERLAYS the single key it changes (map_insert over the Rust map) instead, so the
base map is byte-for-byte what it was and every claim already sharing one
evaluation of it keeps sharing exactly that one. A profile's delta belongs to the
profile; charging every other witness for it was the defect.

SECOND: this branch's own three claims were INTERRUPTED BEFORE VERDICT at
~1200ms each -- a full ingest-assemble-infer-emit walk per claim. Split by an
ingest-only/assemble-only probe pair, the disk read and its content-hash
verification cost 0ms and assembly costs 878ms, so the recompute was assembly,
three times, of a pure function of one file's content. Two repairs, both the
roster's own named one:

  The emission claims now run over direct_rust_door_specimen_resolved, the
  already-warm-enrolled producer of a resolved add-shaped module. A second
  producer for a specimen of the same shape would have been the duplication that
  roster exists to end.

  The two emissions themselves (profile target, base target) are nullary
  producers enrolled warm, the same shape as produced_add_module_source. Each
  claim is then a string comparison, and infer+emit is evaluated once at
  preparation rather than three times inside three budgets.

THE READ IS CLAIMED SEPARATELY, because it is a separate fact and it is free
(0-5ms): the committed fixture reaches source_ref_for_observed_storage_path and
source_root_ingest_from_source_refs, whose content-hash verification is the seam
no enrolled claim covered -- the door's specimen carries its module source
inline. The assertion is a containment, not a whole-text golden, so editing the
fixture's prose is not a test failure (a change detector, not a check).

claim_batch over the entry: 5/5 PASS. The emission claims read the door
specimen, so the expected sources name its declaration (`add`) rather than the
fixture's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X5tyxfVrw3chDNbQ3sVD3

* The probe file states the seam it is actually the subject of

Review 62939 is right, and the gap is exactly where it says: the fixture's own
annotation still described the enrolled fact as disk -> ingest -> assemble ->
infer -> emit. That was true when written and stopped being true one commit
later, when the three emission claims moved onto the door's warm-shared resolved
specimen to fit the floor's per-claim ceiling. An annotation describing a route
no claim executes is DESIGN section 5's specification-without-execution, and it
is worse than absent because it reads as coverage.

The file now states what it is the subject of -- the storage-read seam, claimed
by the two read claims over the bytes actually on disk -- and says outright that
no claim ingests, assembles, infers or emits it, with the reason the split
happened. The two facts stay separate on purpose: the READ is claimed over a real
file, the two target-profile SELECTIONS over the shared specimen, and neither
claim covers the other.

No behavior changes; the claims are unchanged and still PASS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X5tyxfVrw3chDNbQ3sVD3

* One measurement, one home: the claim file names the instrument and stops transcribing it

Review 62942 caught the drift as it happened. The same measurement -- these three
claims against the per-claim ceiling -- was transcribed twice in one diff, into
the test file and into the enrolment row, and the two copies already disagreed
(713-805 against 713-834). DESIGN section 6 forbids exactly this: name the
producer that re-derives a measurement, never copy its numbers into prose,
because a transcribed number is unreachable from the run that owns it and rots
without either end being touched. The disagreement is that rot arriving on day
zero.

The figures now live once, at the enrolment row in
v2.workflow.floor_pure_producer_share, which is where the ceiling arithmetic is
argued and where every neighbouring row already argues its own. The test file
names the instrument -- claim_batch's [witness] receipt over this entry, with the
ingest-only / assemble-only probe pair that splits the pipeline -- and states the
shape of the fact (unshared, each claim costs multiples of the ceiling; the read
pair is the cheapest in the file) without restating a number beside it.

Claims unchanged: 5/5 PASS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011X5tyxfVrw3chDNbQ3sVD3

* The…
gunbai-bot Bot pushed a commit that referenced this pull request Sep 10, 2026
Both conflicts were additive collisions at the same insertion point, not
disagreements; both sides are kept.

namespace_wave_admission.rs -- main merged #10692 (ebb1da8), which is
the trigger that made this branch's five consumed #10692 admissions due,
so main deleted them independently and added nine #10883 cable_plant
rows at the same position. Resolution keeps main's nine and re-adds this
branch's two live `gunbc#10818 CpuBoundStanding rehome` rows plus their
doc block: 11 rows total. The two are still live because their trigger is
this PR merging, which has not happened.

guarantee_stall/roster.dag -- main appended
information_retrieval_transport_cannot_report_status_stall where this
branch appended module_cited_only_in_annotation_prose_stall. Both are
kept, in import and roster order.

Merge commit rather than rebase, per the branch policy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJGbrvU2EgNeUiWfc5yK2c
gunbai-bot Bot pushed a commit that referenced this pull request Sep 10, 2026
The floor refused adjudication on the merge head with `0 unadjudicated
delta(s), 0 stale admission(s), 9 consumed admission(s) due for deletion
on this roster-touching change` -- the same 4b(4) obligation this branch
already discharged once for #10692's five, now for #10883's nine.

The mechanism is worth stating because it will recur: #10883 merged to
main, which made its own nine admissions CONSUMED. Merging main into this
branch brought them here, and this branch touches the roster (it adds two
rows of its own), so their deletion comes due on this head. A branch that
integrates main inherits main's due deletions.

Joined against main's tree before deleting rather than trusting the
count, per the rows' own instruction:

  gunbc.spark.fabric_switch_observed fabric_cable_plant CablePlant
  gunbc.spark.fabric_switch_observed fabric_leg_reading LegReadingTaken
  test.claim.spark.spark_fabric_switch_witness plant_readings_never LegNeverRead

each now binding to `product.cable_plant_assessment` on main.

The two `gunbc#10818 CpuBoundStanding rehome` rows stay. Their trigger is
this PR merging, which has not happened.

Deletes the nine rows and their now-unreferenced doc block. No evidence
retired -- 4b(4) dissolves production handling only, and these rows carry
no discriminating control.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJGbrvU2EgNeUiWfc5yK2c
briansrls added a commit that referenced this pull request Sep 10, 2026
* Land the receipts main already cites

gunbc.runner.runner_host_filtered_egress merged to main citing
gunbc.runner.runner_guest_egress_attempt, which did not. That receipt and two
siblings -- the cgroup placement and guest network observations -- were
stranded on a sibling PR that never merged, so main carried a citation naming
a module the repository does not contain.

That is the positional-reference failure in its worst form. A stale line
number decays quietly; a citation to an absent module means a reader cannot
find what was cited at all, and the claim resting on it becomes uncheckable.

They matter to what landed. runner_host_filtered_egress rejects the bridged
topology, and the record of that bridge being tried, what it exposed and why
it was abandoned lives in runner_guest_egress_attempt. Without it the
rejection reads as a preference rather than a finding.

Cherry-picked onto current main rather than resurrecting the stale branch,
which is hundreds of files behind and carries the same foreign PCI-identity
content this lane just removed from its own PR. Taking the six files leaves
all of that behind.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Cite the stranded runner receipts by import, not annotation

The three modules #10818 added were still dangling: the citing sites named them
only in comments, which DESIGN 4c erases, so they were neither citations nor
consumers. Fold the attempt, placement, and guest-network facts into the
modules that already depended on them, carry typed DeclarationRefs, and file
the class on the 4b ledgers.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Inhabit ByteSize, type the prose rows, and file the three receipt classes

The stranded receipts still carried byte quantities as Int and four findings as
String commentary. They now consume std.measure, hold those findings as typed
carriers beside PlacementDefect, and each newly discovered class has its own
4b row rather than living only inside a per-attempt receipt.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Type the three remaining narrative receipt rows

bridge_readback_defect, guest_tap_retired and corrected_claim were the same
4c class as finding 3 — withdrawn and corrected rulings held as NonEmptyStr
after this PR had already established typed carriers beside them.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fold the cpu.max refusal once, next to cpu_bound_failure

The two consumer modules were matching the same coproduct under two names, so the consumption witness counted one fact twice. One fold, imported; the witness asserts it once.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Inhabit existing network, hash, path, arch, and rate authorities in the receipts

GuestReachability was restating IPv4, prefix, and MAC as strings; those already live in extdeps.network. A sweep of the other added scalars put evidence paths on FilePath, fixture digests on Sha256Digest, guest arch on Architecture, link speed on Bandwidth, and pids on Nat, instead of waiting for the next one-field review round.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Join values to their summaries and give duplex and NUD a home

A record that carried empty: true beside procs_at_retirement: "empty", and a member list that restated placement_verdict.pid as prose, could disagree with nothing refusing. Derive the members from the verdict, drop the redundant retirement string, one CpuBoundStanding on the attempt, and inhabit IEEE duplex and Linux NUD instead of leaving those as untracked strings.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Admit the two CpuBoundStanding TargetChanged bindings #10818 produced

The floor was FloorClean and the consumption witness passed; adjudication refused on namespace-wave-admission with exactly two unadjudicated deltas — cpu_bound_standing rebinding CpuBoundStanding and CpuBoundInterfacePresent onto the attempt module. Those rows dissolve when this PR merges.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Drop the permanently-green consumption witness and the cites_* rows

A receipt of observed constants cannot make that test red except by editing the receipt. Imports and folds are the consumption claim; the stall no longer cites the deleted witness as coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Retire the five consumed #10692 admissions the roster touch makes due

The required floor refused adjudication on this head with
`0 unadjudicated delta(s), 0 stale admission(s), 5 consumed admission(s)
due for deletion on this roster-touching change`. Nothing was missing:
the five `gunbc#10692` binding admissions became CONSUMED when that PR
merged, and adding this change's own two rows is the roster touch that
brings their deletion due (DESIGN 4b(4), dissolution on climb -- a climb
deletes the lower-rung machinery it obsoletes).

The rows' own trigger prose forbids taking its word for it -- "adjudicate
that deletion by joining each row against main's tree on its own
(module, in_declaration, spelling, target) tuple rather than trusting
this sentence, because a trigger sentence is not evidence that the
trigger fired." Joined all five against origin/main; each declaration
now binds its spelling to the named authority module:

  v2.std.integer integer_string_to_decimal_digits_step   -> v2.std.text
  v2.std.compilers.target_model EmitSpellingEscape       -> v2.std.text
  v2.std.compilers.target_model apply_emit_spelling_...  -> v2.std.text
  v2.extdeps.languages.python py_bool_grounding          -> v2.std.logic
  v2.extdeps.languages.typescript ts_bool_grounding      -> v2.std.logic

The two `gunbc#10818 CpuBoundStanding rehome` rows stay: their own
trigger is this PR merging, which has not happened. Deleting all seven
to make the count come out right would drop live admissions.

Pure deletion -- the five rows, their now-unreferenced label constant,
and the doc block describing them. No evidence retired: these rows carry
no discriminating control, so 4b(4)'s "production handling only, never
the evidence" has nothing to preserve here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJGbrvU2EgNeUiWfc5yK2c

* Retire the nine consumed #10883 admissions the merge made due

The floor refused adjudication on the merge head with `0 unadjudicated
delta(s), 0 stale admission(s), 9 consumed admission(s) due for deletion
on this roster-touching change` -- the same 4b(4) obligation this branch
already discharged once for #10692's five, now for #10883's nine.

The mechanism is worth stating because it will recur: #10883 merged to
main, which made its own nine admissions CONSUMED. Merging main into this
branch brought them here, and this branch touches the roster (it adds two
rows of its own), so their deletion comes due on this head. A branch that
integrates main inherits main's due deletions.

Joined against main's tree before deleting rather than trusting the
count, per the rows' own instruction:

  gunbc.spark.fabric_switch_observed fabric_cable_plant CablePlant
  gunbc.spark.fabric_switch_observed fabric_leg_reading LegReadingTaken
  test.claim.spark.spark_fabric_switch_witness plant_readings_never LegNeverRead

each now binding to `product.cable_plant_assessment` on main.

The two `gunbc#10818 CpuBoundStanding rehome` rows stay. Their trigger is
this PR merging, which has not happened.

Deletes the nine rows and their now-unreferenced doc block. No evidence
retired -- 4b(4) dissolves production handling only, and these rows carry
no discriminating control.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJGbrvU2EgNeUiWfc5yK2c

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
cursor Bot pushed a commit that referenced this pull request Sep 10, 2026
Resolve against main's landed #10692 (emitted v2 compiler native run):
- add/add execution tests: take main's upstreamed direct_rust_door_specimen_inferred
  helper form (test bodies identical)
- floor_expected_red: take main's chunk (both sides dropped the add-slice row;
  main adds two argument_shape_at_a_declared_position rows)
- emit_coverage_frontier + emit_host_native_only_verdict_test +
  emit_host_classical_not_ingested_equals_eval_test: take main's 500ms-ceiling
  arm split (meet/join per-claim) and warm pure-producer refactors
- required_regen_host.rs: both sides applied the same current_exe_digest fix;
  keep this branch's comment explaining the digest-spelling mismatch

Co-authored-by: briansrls <briansrls@gunb.ai>
cursor Bot pushed a commit that referenced this pull request Sep 10, 2026
Brings in #10692 and the megarac machine-intake corpus. No overlapping
edits to the lane's files; the generated workflow mirror is untouched on
both sides. Main's floor is red on in-body source annotations in
dag/gunbc/machine_intake/megarac_media_attach.dag (main push run
34437200195); the grain repair lands as the next commit.
briansrls added a commit that referenced this pull request Sep 10, 2026
… repairs (#10890)

* Restore the per-class advisory census as a rostered instrument target

The compile-clean advisory census returns as `gunbc test
//gunbc/instruments:compile-clean-advisory-census`: one entry per advisory
diagnostic class over the whole-tree compile-clean closure (count, distinct
modules, distinct source positions), plus the binding-source-attributed
UnlistedImportUse worklist. The entry point is a rostered TargetBinding in
gunbc.instrument_targets with a modeled CompileCleanAdvisoryCensusObservation
in gunbc.target_binding, so the sweep that removed the unrostered bin in
gunbc#9160 cannot recur.

The dead `compile_clean_unlisted_import_census` wrapper deletes with it: the
advisory census's unlisted_import_rows carry the same rows, and a pub fn whose
only call site was its own definition is DESIGN 3c's dangling declaration. The
two .dag citations of the old symbol repoint to the subsuming census, and the
scaffold marker comment now names the remaining hand-Rust classification
surface honestly.

Also repairs a pre-existing red fixture in target_invocation_witness_test: the
planned-site fixture used test.claim.some_witness, which matches no prefix in
the static required_gate_prefixes roster since the 2026-08-29 gate bankruptcy,
so the site was DeclinedOutsideRequiredGate and the positive control could
never hold. The fixture now uses v2.test.some_witness, an on-gate prefix.

Co-authored-by: briansrls <briansrls@gmail.com>

* Flip the burndown sizing to the certified census; record per-class ceilings

unlisted_import_use_burndown_sizing now reads SizedByAuthorityCensus /
CertifiedCount over the restored instrument: 553 modules carrying 1,648
distinct (module, name) pairs out of the 4,057-module whole-tree closure,
against the stand-in's order-only 789/2,190/4,459. The hand-check fields move
into the stand-in arm they describe, and the spent supersedes_when_reachable
and authority_census_reachability fields delete -- reachability is now
constructed by the rostered binding and witnessed, not asserted by a data arm
that could rot beside a deleted entry point.

The hand-Rust dissolve trigger is NOT retired: the census is the same
hand-Rust classification transport made reachable, so the unmodeled
binding-source debt it guards is unchanged. Its description now names the
current surface.

Two annotation corrections, both rung-honesty repairs: the module claimed both
the floor path and the standalone CLI read the enforcement row, but gunbc#8286
cut the CLI's read (its mechanism was an interpreter run to answer one Bool);
the flip's terminal shape is promotion in v1.std.core diagnostic_disposition,
which both consumers already read.

And the per-class ceiling roster for all six advisory classes the census
reports, classified by attainable ceiling rather than by count, in work order:
UnlistedImportUse and UnlistedVariantValueUse mechanically fixable now;
ServiceConfigReferenceJudgmentDeferred and MethodExistenceFrontierAdmitted
declared-admission rosters whose instances carry their own triggers;
WhereRefinementUnenforced and DeclaredTypeInhabitanceUndecided walls after
grounding, each naming the evidence capability it waits on.

Co-authored-by: briansrls <briansrls@gmail.com>

* Guard UnlistedImportUse against kernel-identity bindings; own infer_resolve in the v1-infer partition

The UnlistedImportUse advisory exists to charge an authored reference
against the referencing module's import list. It also fired on
references whose resolved binding is a kernel-minted identity (span
<kernel:NAME>) -- synthetic formal nodes of imported generic functions
reached through the ancestry overlay, and authored occurrences of
lexically-introduced type parameters. No import-list edit can discharge
such a row: the binding does not come from the import list, and adding
one would rebind the reference rather than fix a listing gap.

The emission site in v1.compiler.infer_resolve now consults the existing
resolved_node_is_kernel_identity_for_name predicate (v1.compiler.core)
and declines to charge kernel-identity bindings. The discriminating
witness imported_generic_call_charges_no_unlisted_import_use_on_the_formal
(dag/test/claim/undeclared_bare_type_reference_class_witness_test.dag)
was RED pre-fix (one row on the kernel formal) and is GREEN post-fix.

Regenerating the infer_resolve mirror exposed that the mirror had no
owning package in the stage0 partition roster, so the priced regen round
refused the rebuild with MirrorHasNoOwningPackage. Per the #10037
precedent the module joins the v1-stage0-v1-infer partition (its imports
are v1-infer members and std-core only): authority row in
v2.workflow.rust_crate_partition, regenerated roster and mirrors, and
two enrolled witnesses -- the rebuild-scope owner flip and the
host-shell-to-partition-surface move.

Co-authored-by: briansrls <briansrls@gmail.com>

* Re-certify the burndown sizing after the kernel-identity guard; close the carve-out

The guard's measured effect on the authority census: UnlistedImportUse
4,621 -> 3,745 occurrences at 3,441 distinct positions across 542
modules (denominator unchanged at 4,057; pairs 1,648 -> 1,415). The
pre-fix carve-out under-counted the defect at 19 by measuring occurrence
SPANS; measured by resolved BINDING the undischargable population was
876. The ceiling row's repair note now records the closed carve-out, the
guard, and the enrolled discriminating witness, and the work-order
comment carries the post-guard totals (25,403 advisories across 6
classes; the class order is unchanged).

Co-authored-by: briansrls <briansrls@gmail.com>

* Charge no UnlistedImportUse on imported-alias expansions; gather the infer stage into the v1-infer partition

The field-access alias peel (v1.compiler.infer peel_alias_once_for_field_access)
expands an imported paramless alias's right-hand side to discover or check its
fields. It resolved that expansion with resolve_node, which enters at
masked=true, so the resolver charged the DEFINER tree's local names against the
IMPORTER's source_visible_names -- names the importer's text never wrote and
could never honestly list. The masked-boundary authority (v1.compiler.infer_resolve
resolve_node_bounded_masked_boundary) states the invariant this violated:
grounding recursions descend into defining-module structure with masked=false,
because that structure is the defining module's import responsibility, not the
use site's. The peel now calls resolve_node_bounded with masked=false; every
authored reference in its input was already charged at its own authored site, so
a masked pass here could only double-charge or mischarge. The discriminating
witness constructing_through_an_imported_alias_charges_no_unlisted_import_use_on_the_expansion
(dag/test/claim/undeclared_bare_type_reference_class_witness_test.dag) was RED
pre-fix and is GREEN post-fix.

Regenerating the infer mirror refused with MirrorHasNoOwningPackage: the
stage-04 root had no owning package in the stage0 partition roster. A generated
mirror resolves cross-module references as crate:: paths, which resolve only
within one crate root, so v1_compiler_infer can join the partition only together
with its whole monolith-owned crate-internal closure. Computed over the
generated mirrors, that closure is self-contained: the infer_* sibling stages
(access, cycle, lookup, method, patterns), v1_compiler_resolve, and
v1_compiler_ownership join v1-infer; ownership's to_string dependency pulls
v1_compiler_emit_core_support in as an owned module (its own references resolve
inside this unit); and infer_lookup's use pulls std_primitive_projection into
std-core, its proper std layer. Authority rows in
v2.workflow.rust_crate_partition, the regenerated roster, and the regenerated
crate boundaries (v1-infer, std-core, and the host shell's subtraction).

Co-authored-by: briansrls <briansrls@gmail.com>

* Re-certify the burndown sizing after the field-access alias peel; record the second closed carve-out

Co-authored-by: briansrls <briansrls@gmail.com>

* Charge no UnlistedImportUse on import-declared qualified spellings

The import-scoped policy's gate is that a module's import list says which
qualified names are visible (namespace-resolution-design.md section 7), but
build_type_env's source_visible_names only ever carried BARE spellings, so
the resolver's leaf check fired UnlistedImportUse on every masked qualified
use -- including q.def.QFoo beside import q.def { QFoo }, a row no
import-list edit could discharge. The fold now enters each imported name
under its qualified spelling as well: selective imports qualify exactly the
listed names; is-all imports qualify the module's OWN interface names, never
ancestry names, which are not containment paths under the importing module's
target and could never resolve as <that module>.<name>. A qualified use of
an unlisted name or an unimported module still fires.

The defect's census signature: the listed-import column moved 511 -> 393
(118 occurrences) when the fix landed, while definer-resolvable (242 --
qualified uses with NO import edge, dischargeable by adding the edge, so
genuine worklist rows) and pool-coincidence (2,614) stood unchanged.

Discriminating witness
test.claim.undeclared_bare_type_reference_class_witness
qualified_use_of_a_listed_import_charges_no_unlisted_import_use was RED
pre-fix and is GREEN post-fix, beside the positive control
qualified_use_without_any_import_still_charges_unlisted_import_use (the gate
still gates).

Co-authored-by: briansrls <briansrls@gmail.com>

* Read the regen round's observed executable digest from the bare-hash authority

run_built_seed_regen compared the admitted executable digest against
path_digest's fnv1a64:-prefixed rendering, while the executable-digest
authority -- current_exe_digest, next_pass_executable_digest, and every
receipt field (producer_seed_digest, output_seed_digest) -- carries
v1_rt::bytes_identity_hash with no algorithm tag, and the .dag admission
(regen_admit_candidate_generation) string-compares that family. The check
admitted the bare form against the prefixed form from its birth in #9771,
so no staged install+rebuild+re-emit round could ever pass it: the refusal
CandidateGeneratedByDifferentSeed fired on every non-trivial convergence
with the two strings differing only by the tag. Read the same authority
here; path_digest stays for artifact surfaces.

Co-authored-by: briansrls <briansrls@gmail.com>

* Re-certify the burndown sizing after the qualified-spelling fold; record the third closed carve-out

The census re-run on the fixed emitter reads UnlistedImportUse at 3,249
occurrences across 483 modules and 1,303 module/name pairs (from 3,367 /
501 / 1,330). The movement is exactly the listed-import column, 511 -> 393:
the 118 rows cleared are the qualified uses of import-declared names the
source_visible_names fold now credits. Definer-resolvable (242) and
pool-coincidence (2,614) stand unchanged -- those rows have no import
declaration to credit and are the genuine worklist.

The ceiling row records the third closed carve-out beside the first two,
and the work-order header carries the new totals (24,907 advisories across
6 classes).

Note: this row remains the hand-transcribed sizing the HOLD review's
finding 2 and route D address -- the mechanism rework (raw source-bound
receipt, merge-base-derived ratchet) follows separately; this commit keeps
the standing row current rather than stale in the interim.

Co-authored-by: briansrls <briansrls@gmail.com>

* Add false-negative controls beside the three UnlistedImportUse emission repairs

Review finding 6 (HOLD at c7603fd): the three repair arms prove the selected
false-positive rows disappear but say nothing about the boundary each repair
must not cross. Each repair widens an exclusion; a widened exclusion that also
swallows the nearby true-positive population is the absorbing fallback (DESIGN
5) wearing a repair's clothes. Three controls hold that boundary, one per
repair, each naming the mutation it exists to red:

- authored_reference_spelled_like_a_kernel_formal_still_charges_unlisted_import_use:
  authors the synthetic formal's own spelling (N) as a real declaration and
  references it bare with no import edge. The kernel-identity guard is an
  identity test (v1.std.core resolved_node_is_kernel_identity_for_name), never
  a name test; broadening it to a spelling test silences this row.
- use_site_type_argument_through_an_imported_alias_still_charges_unlisted_import_use:
  lists a parameterized alias and applies it to an authored argument the user
  does not list. The peel's masked=false covers the definer's expansion tree;
  the use-site argument is resolved masked by the standing boundary
  (v1.compiler.infer_resolve resolve_node_bounded_masked_boundary). Setting
  masked=false one level too high silences this row.
- diagnostics_from_the_alias_expansion_still_propagate: constructs through an
  imported alias whose expansion names a type that exists nowhere, so the
  UnresolvedType row reaches the outcome only through the peel's diagnostic
  accumulation. Dropping or filtering the accumulated diagnostics greens the
  compile over a construction whose fields cannot be typed.

All nine arms of the file measured GREEN by execution on the integrated tree
(merge 4324076, regen fixed point changed_paths=0): the six pre-existing
arms plus the three controls above.

Co-authored-by: briansrls <briansrls@gmail.com>

* Anchor the alias-peel propagation control to the measured two-row anatomy

The first propagation control asserted UnresolvedType(UbtrGhost) > 0 over a
construction through a broken imported alias. Mutation testing showed it did
not discriminate: with the peel's diagnostic accumulation dropped entirely,
the control stayed green. Probing the fixture shape (same sources, same
entry, same count reader) established the real anatomy on the fixed tree:

- the definer module alone charges UnresolvedType(UbtrGhost) once: the
  definer's own compile resolves a paramless alias's right-hand side at
  definition time, refuting the earlier comment's claim that a paramless
  alias resolves as a leaf until a use forces the expansion;
- an import-only user adds no row (no use, no peel);
- a field access through the alias adds the second row, which reaches the
  outcome only through the peel's concat(once.diagnostics, rest.diagnostics)
  accumulation.

The control now uses the field-access shape (no constructor-path resolution
beside the peel), asserts the exact count == 2 in the FixtureCompileRefused
arm (UnresolvedType is GateBlocking, so a Completed outcome is a gate
failure, never a pass), and names both regressions it reds: dropping the
peel's accumulated diagnostics (2 -> 1, measured under the
peel-drops-diagnostics mutation) and the definer's compile ceasing to
diagnose a broken alias definition (2 -> 1 for the other reason).

Co-authored-by: briansrls <briansrls@gmail.com>

* Handle ReleaseScopeEmpty in the infer_resolve rebuild-owner witness

#10692 added the ReleaseScopeEmpty decision variant on main; the
owner-flip arm enrolled by the infer_resolve partition move predates it
and no longer compiles against the merged tree (non-exhaustive match).
A release-excluded verdict for this mirror would be wrong -- the mirror
is release-visible and owned by v1-stage0-v1-infer -- so the arm answers
false, matching the sibling arms' convention. Same fix landed in the
emitter-repair split-off PR on current main.

Co-authored-by: briansrls <briansrls@gmail.com>

* Rework the advisory census into a raw source-bound diagnostic census

Answers the 2026-09-09 HOLD's census findings (1, 2, 4, 5):

- Finding 1 (false zero): the census counts every emitted diagnostic
  with no severity filter on the count path; disposition is a row
  attribute computed per instance through compile_clean_diagnostic_is_hard,
  keyed (class, disposition) so a mixed class carries one row per side.
  The wall is class-specific: raw UnlistedImportUse == 0, independent of
  its policy disposition, so promotion cannot vacate the assertion.
- Finding 2 (CertifiedCount stronger than provenance): the observation
  carries a five-digest identity block (source vector, compiler
  executable, resolver policy, class schema, closure); the source vector
  is materialized into memory, hashed, and the same bytes compiled, so
  the digest binds by construction. The policy's sizing arm renames to
  LiveDiagnosticObservation and is refreshed to the integrated-tree
  reading.
- Finding 4 (worklist identity): UnlistedImportCensusRow carries the
  occurrence's source position beside file/module/name/binding-source,
  with the comment stating what it is not (the Step 0 occurrence
  identity remains the bar for actuating edits).
- Finding 5 (open-string roster, non-incremental ratchet): the ceiling
  roster projects to class names and the producer executes the bijection
  witness -- duplicate, stale, and uncovered rows are typed refusals.
  The witness's first live run refused Uncovered on
  EffectSummaryIncompleteAtFunctionValue; both effect-summary classes
  are enrolled with WallAfterGrounding ceilings naming their missing
  effect-evidence capabilities.

Also deletes the dead compile_clean_diagnostic_is_advisory (its only
caller was the filtered census) and updates the witness arms: the wall
test now discriminates advisory-vs-blocking carriage of the walled
class, and the rendering/refusal arms assert the new vocabulary.

Co-authored-by: briansrls <briansrls@gmail.com>

* Hoist an in-body source annotation to module-item grain

The required-ci parse phase refuses // annotations inside a declaration
body (std.source_annotation BodyGrainNotModeled: only module-item grain
is modeled). The kernel-collision control carried its refusal-arm note
inside the match; move it above the test fn it describes. The
annotation-erased projection is unchanged, so no semantic result moves;
the interpreter entry path had tolerated the body placement, which is
why local control runs stayed green while the floor lane refused.

Co-authored-by: briansrls <briansrls@gmail.com>

* census: full gate disposition + severity, one policy snapshot, exact-vector digest, authority-derived schema

Review 2026-09-10 findings 1-4 on #10890:

1. RawDiagnosticClassObservation now carries the diagnostic authority's
   complete answer: DiagnosticCensusGateDisposition (CensusBlocking |
   CensusAdvisoryTypecheck | CensusRenderedUncounted{reason}) plus
   DiagnosticCensusSeverity as the independent axis the repository
   models. ComplexityUnknown is reported rendered-uncounted, never
   folded into advisory. Ceiling-roster coverage (Stale/Uncovered)
   scopes to CensusAdvisoryTypecheck alone.

2. Classification and provenance read ONE immutable policy snapshot:
   the policy closure vector is acquired once, canonicalized once,
   resolved once, and the UnlistedImportUse staging decision, the
   ceiling roster, and the resolver-policy digest all derive from that
   one context. The census path no longer calls the process-global
   cached policy accessor.

3. The subject source vector is canonicalized once in place and that
   exact vector feeds both the source-vector digest and
   compile_to_resolved -- the digest identifies the executed vector,
   not a canonicalization of a differently ordered one.

4. The diagnostic class schema is checked against the coproduct
   authority's own constructor census, derived parse-level from the
   v1.std.core CompilerDiagnostic declaration via
   decl_facts_corpus_walk + get_variant_names (the subject closure
   cannot carry src/v1 -- the twelve last-segment collisions). Five
   typed refusals: SchemaAuthorityAbsent, SchemaSpecimenDuplicate,
   SchemaCountMismatch, SchemaConstructorUnrepresented,
   SchemaSpecimenUnknownToAuthority. A new constructor whose author
   repaired the exhaustive matches but omitted the specimen now reds
   the census at the next run.

Co-authored-by: briansrls <briansrls@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Sep 10, 2026
…nsions, or listed qualified spellings (#10906)

* Guard UnlistedImportUse against kernel-identity bindings; own infer_resolve in the v1-infer partition

The UnlistedImportUse advisory exists to charge an authored reference
against the referencing module's import list. It also fired on
references whose resolved binding is a kernel-minted identity (span
<kernel:NAME>) -- synthetic formal nodes of imported generic functions
reached through the ancestry overlay, and authored occurrences of
lexically-introduced type parameters. No import-list edit can discharge
such a row: the binding does not come from the import list, and adding
one would rebind the reference rather than fix a listing gap.

The emission site in v1.compiler.infer_resolve now consults the existing
resolved_node_is_kernel_identity_for_name predicate (v1.compiler.core)
and declines to charge kernel-identity bindings. The discriminating
witness imported_generic_call_charges_no_unlisted_import_use_on_the_formal
was RED pre-fix (one row on the kernel formal) and is GREEN post-fix.

The guard widens an exclusion, so it lands with its adjacent
false-negative control (review finding 6):
authored_reference_spelled_like_a_kernel_formal_still_charges_unlisted_import_use
authors the synthetic formal's own spelling as a real declaration and
references it bare with no import edge; the binding is the corpus
declaration, the identity guard has no purchase, and exactly one charge
must fire. Mutation evidence: replacing the identity predicate with a
spelling test (type_name != "N") in the generated resolver turns this
control RED while the kernel-formal arm stays GREEN.

Regenerating the infer_resolve mirror exposed that the mirror had no
owning package in the stage0 partition roster, so the priced regen round
refused the rebuild with MirrorHasNoOwningPackage. Per the #10037
precedent the module joins the v1-stage0-v1-infer partition (its imports
are v1-infer members and std-core only): authority row in
v2.workflow.rust_crate_partition, regenerated roster and mirrors, and
two enrolled witnesses -- the rebuild-scope owner flip and the
host-shell-to-partition-surface move. The owner-flip arm gains the
ReleaseScopeEmpty match arm that #10692's new decision variant requires;
without it the file does not compile against current main.

Regenerated through the declared transaction on current main
(50bb0c1): generated-artifact gate main_wet, required-regen emit,
install, emit-partition-crates --write, whole rebuild (the partition
generation authority changed, so the partitioned rebuild path correctly
refused to actuate), then required-regen first_generation_equal=true and
required-regen-fixed-point fixed_point_equal=true referenced at
50bb0c1.

Co-authored-by: briansrls <briansrls@gmail.com>

* Charge no UnlistedImportUse on imported-alias expansions; gather the infer stage into the v1-infer partition

An imported paramless type alias whose expansion is resolved under the
IMPORTER's masked env charged the definer-tree argument names against an
import list that could never list them honestly -- the names are the
definer's locals, and the definer's own module compiles clean. The
masked-boundary authority (v1.compiler.infer_resolve
resolve_node_bounded_masked_boundary) states the invariant: grounding
recursions descend into DEFINING-module structure with masked=false,
because that structure is the defining module's import responsibility,
not the use site's. The field-access alias peel in v1.compiler.infer now
resolves the expansion with masked=false and accumulates every hop's
diagnostics into the NodeResolveResult carrier, so hard refusals
(UnresolvedType, ArityMismatch, InternalError) keep flowing to the
judgment-producing callers.

The repair lands with two adjacent false-negative controls (review
finding 6), each naming the mutation it reds:

- use_site_type_argument_through_an_imported_alias_still_charges_unlisted_import_use:
  a use-site type argument is authored by the user, resolved at the use
  site, and masked there by the standing authority; exactly one charge
  naming the argument must fire. Measured RED when the generic-args
  recursion is unmasked one level too high.
- diagnostics_from_the_alias_expansion_still_propagate: a field access
  through an alias whose expansion names a type that exists nowhere
  refuses with exactly TWO UnresolvedType rows naming the ghost -- one
  from the definer's own compile (which resolves a paramless alias's
  right-hand side at definition time; an earlier draft's claim that it
  does not was probe-measured false), one carried by the peel's
  accumulation. Measured 2 -> 1 when the peel returns an empty
  diagnostic list, so the == 2 assertion goes RED.

Regenerating the infer mirrors moved the whole infer stage into the
v1-stage0-v1-infer partition (the same ownership hole class as the
infer_resolve move): authority rows in v2.workflow.rust_crate_partition,
regenerated roster, mirrors, and crate projections through the declared
transaction -- generated-artifact gate main_wet, required-regen emit,
install, emit-partition-crates --write, whole rebuild (partition
generation authority changed), required-regen
first_generation_equal=true, required-regen-fixed-point
fixed_point_equal=true referenced at d625404.

Co-authored-by: briansrls <briansrls@gmail.com>

* Charge no UnlistedImportUse on import-declared qualified spellings

A qualified reference (module.Type) whose module the source declares in
an import edge was charged UnlistedImportUse on the LEAF name even when
the leaf was listed: build_type_env's source_visible_names fold carried
only the bare spellings, so the qualified spelling the author wrote
looked unlisted to the visibility check. The fold now also inserts the
qualified spelling for every imported item, so the name the text
actually wrote is the name the check looks up.

The two enrolled arms bound both sides of the boundary:
qualified_use_of_a_listed_import_charges_no_unlisted_import_use (the
false-positive row disappears) and
qualified_use_without_any_import_still_charges_unlisted_import_use (the
same qualified spelling with no import edge at all still charges exactly
once -- the repair widens recognition of listed spellings, never the
silence of unlisted ones, so this arm is the repair's own false-negative
boundary).

Regenerated through the declared transaction on top of the alias-peel
commit: required-regen emit, install, rebuild, required-regen
first_generation_equal=true, required-regen-fixed-point
fixed_point_equal=true referenced at 8511149. No partition movement:
the changed mirror stays inside the v1-infer partition that now owns it.

Co-authored-by: briansrls <briansrls@gmail.com>

* Hoist an in-body source annotation to module-item grain

The required-ci parse phase refuses // annotations inside a declaration
body (std.source_annotation BodyGrainNotModeled: only module-item grain
is modeled). The kernel-collision control carried its refusal-arm note
inside the match; move it above the test fn it describes. The
annotation-erased projection is unchanged, so no semantic result moves;
the interpreter entry path had tolerated the body placement, which is
why local control runs stayed green while the floor lane refused.

Co-authored-by: briansrls <briansrls@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants