Repository navigation
Run the emitted v2 compiler natively and close construct coverage - #10692
Conversation
…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>
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>
… 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.
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.
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Repair-Judged: docs/design-rung-drops.md
…rounding-frontier-3100
…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>
…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>
…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
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 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".
| DataVariantUntagged => | ||
| if (value.children |> count) == 0 { | ||
| Emitted { json: "null" } |
There was a problem hiding this comment.
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 👍 / 👎.
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
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
#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>
…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>
… 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…
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
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
* 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>
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>
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.
… 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>
…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>
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.dagclosure 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.dagsource with mirrors regenerated through the sanctioned regen path, each with discriminating witnesses:PointwisePowerinhabitant rows — twelve native panic sites disagreeing with the structurally rendered carrier.{}where the emitted Rust carrier is a unit struct requiringnull(theBoolEncodingFactpanic) — fixed insrc/v1/05_emit.dag.DataVariantWireSpellingindex (EmitGraphInfo.data_variant_wire_spellings) built in05_emit_rust.dag, so internally-tagged, bare-string, untagged, and tagged variants all serialize per their home module's declaredVariantEncodingpolicy; ambiguous same-name coproducts insert a fail-closedSpellingRefused.v2_std_integer.rs(locality wins).Natunresolved inv2_lens_fact_density.rs(qualified reference without import).S: Clonebound propagation gap instd_realization_measurement.rs(transitive over call hops).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 (nativeemit()output == interpretedemit()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_frontieris nowSelfEmittedNative, each backed by a native-only verdict arm (positive + wrong-octet broken control) in the file-grain-enrolled wet entryemit_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, theretained_via_eval_agreementconstructor lost its last consumer and was deleted (DESIGN §3c); theInterpreterRetainedvariant 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) <- Variantcluster —02_parse.dagrestores structural text reads (string_headmatch overCharFound/CharAbsent) in place of host-carrier operations, root-causing the shared type-error cluster.prepare_grammarshared-fill cost class —GrammarFirstAnalysis.nullable_setis now the enumeration it always was (List<Symbol>, thesync_tokensrepair's own precedent), soPreparedGrammarpasses the cross-claim tier's total portability walk, and the new nullarydag_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.Bool/Stringrequalification bindings inextdeps.languages.python,extdeps.languages.typescript,std.compilers.target_model, andstd.integer) with transition admissions carrying rationale and dissolution.prepare_grammarwarm-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.infer_atom_grounding_rulesclaims, the twoinfer_product_introductionclaims, and thedag_binding_denotationclaim 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_inferredspellings into the fixture's home:direct_rust_door_specimen_resolved()— the deepest portable stage, since theInferredTreeone stage up carries the factsPartialFunction— is warm-enrolled, and each claim re-derives infer from the served resolved tree.emit_host_native_only_loop_holdsat 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-producerclaim_batchentries against 174-247ms whole-claim local receipts). The repair adds one sharedEmittedFamilyCrate { source, native_key }record inv2.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)
v2-emitter-first-behavioral-module), plus operator acceptance.v2.test.*through the emitted native crate — the CI job roster is closed to growth without operator sign-off (2026-09-04 ruling).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>) withconsumer_claims=6each, and all twelve former ceiling-band claimsplanned-and-passed; 31 of the verdict file's 34 arms executed in this run's changed-witness population, all passed.claim_batchon 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 byclaim_batch: PASS.claim_batchonpure_producer_share_refusal_test.daglive-roster controls: PASS (the two new rows collide with neither the refused nor the pending roster).cargo clippy --all-targets -- -D warningsclean,cargo fmt --all --checkclean, regen (generated_artifact_gate.dagmain_wet) no drift.