Repository navigation
Emitter flattens nested constructor patterns: classify_arrow_body_form's Conj arm is unreachable in emitted Rust — a silent wrong answer, not a warning - #8570
Merged
Conversation
added 3 commits
August 19, 2026 19:25
…d fix --required-regen refuses corpus-wide on the pre-existing #8544 population mismatch, so this projection was obtained by invoking compile_stage0 directly (rustfmt applied exactly as write_emitted_tree does), ahead of the population-comparison gate that #8544 blocks on, per an operator ruling sanctioning that narrower path for this fix. Diffed the whole emitted stage0 tree against committed. Six other files differ from committed stage0 for reasons unrelated to this change and are intentionally left untouched: - lib.rs: two missing `pub mod` lines, a direct consequence of #8544's own population gap (three files not yet in the emit population). - v1_compiler_infer.rs, v1_std_core.rs: also #8544's subject (expr_is_any_literal / where-refinement work not yet landed on main). - std_measure.rs, std_pareto.rs, std_witness_admission.rs: unowned regen backlog — stale committed projections of other sessions' .dag authority changes that were never regenerated, unrelated to pattern/Rc/match-arm emission. Discovered as a byproduct of this verification; flagged separately, not carried by this PR. Only v1_compiler_emit_rust.rs is shipped here.
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 19, 2026
…ed a wrong merge THE HAZARD, recorded because it nearly cost a silent bad merge. `git fetch` left this worktree SHALLOW: `git rev-list --count HEAD` reported 2, the third integration's merge commit showed no parents, and divergence read as "main 11208 ahead, HEAD 2 ahead" while `git merge-base` and `git merge-base --is-ancestor` gave contradictory answers about the same pair of commits. The contradiction is what made it visible -- a single wrong number would have looked plausible. Merging on a truncated history can compute a bogus merge-base and silently resolve hunks against content that is not actually the common ancestor, which is a wrong TREE rather than a loud conflict. So the merge was not attempted until `git fetch --unshallow` restored the full 11,647-commit history, after which divergence read sanely (main 2 ahead, HEAD 441 ahead) with a real merge base. The remote was never affected -- refs/heads/integration/namespace-cut already pointed at this branch's HEAD -- so every earlier push is intact; only the local view was truncated. RESOLUTION: three conflicts, resolved HUNK-BY-HUNK keeping main's content rather than by `checkout --theirs`. Taking main's whole 05_emit_rust.dag would have discarded this branch's hand work elsewhere in that file; only the conflicting regions belong to main. Main's new emitter functions from #8570 (variant_pattern_shape_str / variant_pattern_shape_for, the nested-constructor pattern flattening) are kept intact. Also qualified v2.std.grammar.Terminal in llvm_ir.dag -- a bare payload-carrying variant construction in a widely-imported module, so it was failing MULTIPLE witnesses from one site. Decided by shape, not preference: the enclosing function returns v2.std.grammar.GrammarExpr and the literal's fields (token_class, stamp) match that declaration, while the two other modules declaring `Terminal` have different shapes. Receipts: the cut driver reported skip_kernel=3, confirming the kernel-type guard now refuses at the source rather than being swept afterwards; v1_src_dag_parse 46 file(s) parse-clean; release build green; the specimen witness returns `true`; ci_oom_reclassify advances past its unresolved type into a different class (a refinement cast), which is progress, not a fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 19, 2026
The document's loudest feature is a table sorted by diagnostic count, which invites reading count as a value function. Nothing in the census is a delta, so no number in it was wrong — but the ranking is what will be quoted, and the census will outlive the conversation that produced the rule. A diagnostic count is not a value function: a fix that makes a silent wrong answer loud always looks like a regression, and one that makes a loud error silent always looks like progress. The second direction is the dangerous one. The worked receipt is in-tree rather than asserted: re-measuring emit_module after #8570 moved its board 286 -> 276, a net of -10 that reads as noise, while unreachable_pattern went 37 -> 0 and E0004 went 1 -> 28 with all sixteen other classes byte-identical. Thirty-seven lint-shaped concealments became twenty-eight hard errors -- a climb from mitigatable to loud refusal, bought for +27 visible errors. The conversion is heterogeneous: a control module that does not reach v2.compiler.infer lost its unreachable_pattern and gained no E0004, so where the flattened arm was redundant it vanishes and where it concealed real non-exhaustiveness it surfaces. The caveat sits above the table rather than after it, because a correction placed below the thing it corrects is read second or not at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Aug 20, 2026
* Census: all 41 v2 compiler modules measured at one pinned SHA A dated observation, not a live authority: 40 boards plus one EMIT_REFUSE, measured at 90b1e4e. Main has already moved past the pin (#8570 as 52e1c4d touches a work-list file), which the header states rather than footnotes. The finding the census was called for: the boards are dominated by a shared emitted file set rather than by per-module code. E0063 takes exactly two values across all 40 boards, 16 or 0, with no intermediate value, and the discriminant is whether the module's closure reaches v2.std.compilers.target_model -- not closure size, which is refuted outright by four modules at exactly 72 files splitting across both outcomes. File-level joins for 00_compile and emit_module share 34 files, and in 34 of 34 the diagnostic count is identical: 278 diagnostics, 97% of emit_module's board. emit_module has EIGHT diagnostics in its own emitted file. That is why per-module packets kept producing roots that did not generalise -- they were roots of the shared closure, found through whichever module was assigned. Instrument limitations are stated at their real scope rather than narrowed: the import-reachability proxy under-approximates EVERYWHERE, since .dag resolves by namespace and any module may use an unimported name; zero-import modules are only where that blindness becomes total and therefore visible. What corroborates the clean population is the outcome column, not the proxy. Determinism rests on exactly two accidental receipts, both named. program_assembly is carried as its own row with no numeric board. It is not a hole and not a zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Census: state that a board is a snapshot, not a score, above the table The document's loudest feature is a table sorted by diagnostic count, which invites reading count as a value function. Nothing in the census is a delta, so no number in it was wrong — but the ranking is what will be quoted, and the census will outlive the conversation that produced the rule. A diagnostic count is not a value function: a fix that makes a silent wrong answer loud always looks like a regression, and one that makes a loud error silent always looks like progress. The second direction is the dangerous one. The worked receipt is in-tree rather than asserted: re-measuring emit_module after #8570 moved its board 286 -> 276, a net of -10 that reads as noise, while unreachable_pattern went 37 -> 0 and E0004 went 1 -> 28 with all sixteen other classes byte-identical. Thirty-seven lint-shaped concealments became twenty-eight hard errors -- a climb from mitigatable to loud refusal, bought for +27 visible errors. The conversion is heterogeneous: a control module that does not reach v2.compiler.infer lost its unreachable_pattern and gained no E0004, so where the flattened arm was redundant it vanishes and where it concealed real non-exhaustiveness it surfaces. The caveat sits above the table rather than after it, because a correction placed below the thing it corrects is read second or not at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 20, 2026
Merged
briansrls
pushed a commit
that referenced
this pull request
Aug 21, 2026
…uced the shadowed-arm defect #8570 removed Measured, not reasoned: the first version of this grouping keyed on the emitted outer pattern STRING, and the probe came back E0004 31 -> 32 with a NEW unreachable_pattern:6 -- errors, not lints, since the emitted crate denies them. Two arms of one outer variant can emit different outer patterns: NodeKind::TypeNode { ref connective, .. } -- discriminates the field NodeKind::TypeNode { connective: _, .. } -- does not String keying made those two groups, so the first lost its guard and then "matches all the relevant values" (rustc's words) -- the second arm became dead code, silently. That is exactly the silent-wrong-answer class #8570 exists to prevent, reintroduced at six sites: v2.compiler.normalize, v2.compiler.resolve, v2.compiler.eval, v2.compiler.translate, v2.std.compilers.target_model and v2.extdeps.languages.dag. The key is now the outer VARIANT, and a variant is grouped only when every arm carrying it is groupable AND agrees on both the emitted outer pattern and the discriminated field. One dissenting arm -- a wildcard field, a second Rc-bound field, an authored guard -- and the whole variant keeps the #8570 guard. This narrows coverage on purpose. A guarded arm is a visible E0004; a shadowed arm compiles clean and changes behaviour. DESIGN 4b ranks the loud refusal above the silent fault, so grouping declines wherever it cannot prove the whole variant agrees. Seed mirror regenerated: --required-regen refused on exactly one file, v1_compiler_emit_rust.rs, and its candidate is installed here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Aug 21, 2026
…04 removed, 18 given the missing case they were hiding (#8798) * Emitter: a flattened nested pattern cost exhaustiveness, so 24 sites reported the wrong missing case gunbc#8570 stopped the emitter silently swallowing sibling arms: a nested constructor pattern under an Rc-bound field became a `ref` binding plus a `matches!` guard plus a `let ... else { unreachable!() }` prelude. Rust ignores guarded arms for exhaustiveness, so any outer variant covered ONLY by such arms is reported uncovered -- measured on the 03_ingest closure at d72ffe8, E0004 = 31, every site carrying rustc's "match arms with guards don't count towards exhaustivity". The construction that removes the class rather than validating around it: when every arm covering one outer pattern discriminates the SAME single Rc-bound field and carries no other guard, the guards are unnecessary -- the discrimination is a nested match on that field and the outer arm becomes unguarded, so exhaustiveness is visible at both levels. Rust still checks the inner match, so a source that was non-exhaustive underneath still refuses; this moves where the refusal is reported and never fabricates coverage. That relocation is the point, not a side effect. A rustc control (in the probe receipt) shows an unguarded `diagnostics: None` narrowing already refuses, and names `Accepted { diagnostics: Some(_), .. }` precisely; the guard replaced that with a bare `Accepted { .. }`. So the guard was losing exhaustivity AND hiding which case was missing. Residue, declared: an arm with a string guard, an authored guard, more than one Rc-bound field, or a deeper Rc level keeps the #8570 guard. A match containing an irrefutable arm is left alone -- the wildcard already covers the outer variant, so there is no E0004 to remove. emit_typed_tco_match_arm is untouched. Next-rung trigger: a general decision-tree lowering over the whole arm matrix, which needs a fallthrough representation this grouping deliberately does not invent. v1 seed admission: purpose test, gunbc.v1_maintenance_standing v1_maintenance_purpose_ruling_note -- this serves the v2 self-host program. Seed mirror regenerated: `claim_executor --required-regen` refused on exactly one file, v1_compiler_emit_rust.rs, and its candidate is installed here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Group at variant grain: keying on the emitted pattern string reintroduced the shadowed-arm defect #8570 removed Measured, not reasoned: the first version of this grouping keyed on the emitted outer pattern STRING, and the probe came back E0004 31 -> 32 with a NEW unreachable_pattern:6 -- errors, not lints, since the emitted crate denies them. Two arms of one outer variant can emit different outer patterns: NodeKind::TypeNode { ref connective, .. } -- discriminates the field NodeKind::TypeNode { connective: _, .. } -- does not String keying made those two groups, so the first lost its guard and then "matches all the relevant values" (rustc's words) -- the second arm became dead code, silently. That is exactly the silent-wrong-answer class #8570 exists to prevent, reintroduced at six sites: v2.compiler.normalize, v2.compiler.resolve, v2.compiler.eval, v2.compiler.translate, v2.std.compilers.target_model and v2.extdeps.languages.dag. The key is now the outer VARIANT, and a variant is grouped only when every arm carrying it is groupable AND agrees on both the emitted outer pattern and the discriminated field. One dissenting arm -- a wildcard field, a second Rc-bound field, an authored guard -- and the whole variant keeps the #8570 guard. This narrows coverage on purpose. A guarded arm is a visible E0004; a shadowed arm compiles clean and changes behaviour. DESIGN 4b ranks the loud refusal above the silent fault, so grouping declines wherever it cannot prove the whole variant agrees. Seed mirror regenerated: --required-regen refused on exactly one file, v1_compiler_emit_rust.rs, and its candidate is installed here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Probe receipt: the measured E0004 conversion, per class, both directions Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Receipt: reconcile the diagnostics: None predicate, and record the 2286 total-binding arms A count published without its predicate is not a measurement: this lane's 71 and the B4 lane's 349 answer different questions from same-looking greps. Each figure now names the command that produces it. The row that matters is not in the E0004 board at all: the corpus binds diagnostics totally (a name or _) 2286 times, against 71 narrowing arms and 4 arms anywhere pinning Some. The repository already answers 'an Accepted carrying diagnostics is still accepted' by construction, 32:1 -- which argues against a third Outcome variant, since it would have to be threaded through 2286 sites that are already total and correct under the two-variant reading. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 30, 2026
… not outer-pattern bytes: two arms of one record that differ only on a plain binding lower to one nested match instead of two guarded arms (E0004 x2, rustc cannot see a guard)
rc_group_is_whole_coverage required byte-equal outer patterns, so
Edge { label: Named {..}, target: magnitude } beside
Edge { label: Positional, target: _ } fell back to the #8570 guard form
on both arms, which rustc reports as non-exhaustive (E0004 at
v2.extdeps.languages.dag and v2.std.compilers.target_model, xl0b9
board). The group now takes the outer pattern of the member whose
plain bindings are a superset of every other member's (same field,
same identifier), which selects the same values; any refutable plain
field, second Rc-bound field, or authored guard still keeps the guards.
Witness: w_record_arms_differing_only_in_plain_bindings_group_into_a_nested_match
(RED on 37b1266c: emits the guard form, measured by direct emission).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
Merged
gunbai-bot Bot
added a commit
that referenced
this pull request
Aug 31, 2026
* Emitted v2 compiler crate: a declaration's identity is its last segment, and a primitive with no realization refuses instead of inventing one
Two roots behind 175 of the 260 rustc errors on the emitted v2 compiler
closure (issue #9664, milestones 1 and 2):
- 102 x E0425: the four DeclaredCallableIdentity constructions in
v1.compiler.infer_lookup took decl_name from the AUTHORED spelling, so a
qualified call carried the whole dotted path as the declaration name and
emission rendered crate::v2_std_grammar::v2.std.grammar.f(..).
- 73 x E0425: v2.std.algebra length is a ModeledProjection of the `length`
primitive and rt_function_registry has no `length` row, so emission took
rust_runtime_bridge_name's identity arm and wrote v1_rt::length -- a symbol
the seed does not define. A primitive's identity and its per-target
realization are two facts; CallTargetIdentity carried only the first, so
every emitter had to ASSUME a bridge exists.
RuntimePrimitiveCall now carries projected_from, the declaration the roster
projected it from, and emit_rust routes to the bridge only when its own
registry holds the primitive, falls back to the declaration otherwise, and
refuses when neither exists. DeclaredCallableIdentity moves to v1.std.core so
the target type can carry it without forking the pair.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Class B: the algebra method fallback asserted a v1_rt bridge it had not checked
tier0 method resolution resolves an ordinary fn-typed RECORD FIELD through
lookup_field_in_product, so `algebra.step(..)` arrives as AlgebraMethodSemantics
carrying the field node as its method_def. The fallback at the end of that arm
hardcoded runtime_bridge: true, which emitted `v1_rt::step` -- and made
emit_rust_generic_method_call's own callable-field arm, guarded on
runtime_bridge == false, unreachable for the exact receiver it was written for.
65 E0425s on the emitted v2 compiler closure (member, apply, is_empty, step,
init, allocate_literal, ...) were that one literal.
It now passes the realization question keyed on the same registry as the
plain-call seam, so a real bridge method still lowers to a bridge, a callable
field lowers as a field, and a name that is neither reaches the existing loud
refusal rather than a fabricated symbol.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Only ModeledProjection carries projected_from: a HostRealizedSeam body is a self-call, so falling back to it would emit a nonterminating function
The declaration fallback is sound only where the declaration's body is real
code. HostRealizedSeam means the body IS a self-call, so emitting it compiles
and then loops forever -- silent wrongness, strictly worse than the unresolved
symbol it would have replaced. A seam whose target has no realization has no
honest lowering, so it carries nothing and reaches emission's refusal.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* M1: realize the two symbol bridges, which were host seams nothing declared to be host seams
v2.std.compilers.lexing symbol_lexeme and symbol_intern_lexeme have self-call
bodies -- the HostRealizedSeam shape exactly -- and the interpreter has carried
real arms for both (v4_bridge.symbol_lexeme, v4_bridge.symbol_intern_lexeme).
With no projection roster row the resolver saw ordinary declarations, so Rust
emission emitted the declaration, and
pub fn symbol_lexeme(sym: String) -> String { symbol_lexeme(sym) }
COMPILES. The emitted closure carried two functions that type-check, pass every
gate we own, and diverge from the interpreter by not terminating. Unlike the
sibling seams (decl_facts and friends, which at least refuse loudly as
unresolved v1_rt symbols) nothing anywhere reported this one -- it is absent
from the E0425 census precisely because it is silent.
extdeps.languages.rust.types already declares Symbol's target type as String,
so on this target both bridges are the identity. That is a realization of the
declared row, not a second opinion about it.
Residue named, not closed: a self-call body is a DECIDABLE structural marker of
a host seam, so the compiler could refuse an unrealized one rather than emit it.
It does not yet; that check is the class's next-rung trigger.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Regenerate the stage0 mirror for the emitter repairs (fixed point at round 2)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* test.claim fixtures: one discriminating RED per closed emission class, with boundary controls
Six rows over the three emitter defects plus the two symbol bridges. Each
class's positive and negative assertion differ only in the fact the repair
added, so no single edit satisfies both directions, and each repair carries a
boundary control that would go red had it over-reached the other way (empty_map
for the registry gate, a registered bridge method for the class-B gate).
The symbol-bridge row is deliberately not an error-count assertion: that class
COMPILED throughout the defect and diverged by not terminating, so a row
asserting 'no error' would have been green the whole time.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Fix the class-B boundary control: count has a method template, so it never reaches the seam under repair
count is answered by rust_simple_method_specs before the algebra fallback, so
the row would have gone red while executing none of the code the repair
touched. trim is in rt_function_registry and has no template, so it is one of
the few names that actually reaches that fallback.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Unbreak the fixture parse: a trailing semicolon on the note declaration
The module index refused the file outright, so none of the six witnesses were
discovered. .dag item declarations carry no terminator.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* The self-call seam wall: an unrealized host seam refuses instead of emitting compiling recursion
A whole-body self-call is the decidable structural marker of a host seam. In the
interpreter the shape is safe -- reaching it recurses to the evaluation-budget
refusal -- but emitted to Rust the same shape COMPILES and returns to no caller.
Nothing reported it: not the module index, not the compile-clean gate, not cargo
check. That is why the two symbol bridges were invisible until someone read the
emitted bytes.
emit_fn_def now asks the realization registry -- the same authority the call
sites ask, so the two cannot drift -- and suppresses the declaration when the
seam is realized, refuses with a located message when it is not. Suppression
rather than delegation is deliberate: a forwarding body would make this seam
reconstruct signatures in target types, which is the cementing the existing
suppressed-seam precedent avoids, and a realized primitive's calls all route to
the bridge anyway.
The predicate is whole-body identity, not 'contains a self-call'. Ordinary
recursion has a match, an if or a let between the head and the call, so it never
matches; expr_has_self_call walks children and would have refused most of the
compiler. Both directions carry a fixture.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* The seam wall must resolve realization through the roster's primitive, not the declaration name
Measured, not predicted: the wall refused six seams in the emitted closure and
one of them -- v2.std.collection empty_map_primitive_delegate -- is realized.
Its roster row names the empty_map primitive, whose bridge is rc_empty_map, but
rt_function_registry holds 'empty_map' and the wall looked up
'empty_map_primitive_delegate'. A declaration's name and the primitive it
realizes are two facts; the roster is the authority that joins them, and the
declaration name is only the fallback for a seam nobody has rostered.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* The seam wall's realized arm must not suppress the declaration: suppression created 10 dangling imports
Measured on the emitted closure with the wall finally in the mirror: removing a
realized seam's item left 10 unresolved imports (E0432) for symbol_lexeme,
symbol_intern_lexeme and resolve_type_node. Other modules import these
declarations; the suppression created that breakage rather than finding it.
And the reasoning that made suppression look safe is what makes it unnecessary.
A realized seam's body IS a call to itself, and resolution already routes that
call through the roster to the bridge -- so ordinary emission writes
v1_rt::symbol_lexeme(sym) as the body without help. The wall's whole job is the
UNREALIZED arm.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* The seam refusal is a generated body, not a crate-wide compile_error!: rustc's denominator is larger than the demand denominator
compile_error! fails the WHOLE crate, and that form silently assumes every seam
it refuses is one somebody calls. It is not. rustc type-checks the entire
emitted crate including declarations imported but never invoked, so the refusal
denominator is strictly larger than the entry-reachable execution closure --
five unreachable seams took the crate down.
The refusal is now a panic body with the declaration's real signature: dependent
modules resolve, the crate compiles, and only an actual invocation fails loudly.
That moves the refusal from the crate to the one declaration that earned it, and
leaves reachability to a separate instrument. An entry-rooted pruner can replace
the body later without revisiting this.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Two obligations the required floor found, both real consequences of this change
DETERMINISM DENOMINATOR (9 reach_witness rows red, including
determinism_denominator_is_closed_on_declared_primitives, whose entire job is to
notice this). v2.lens.determinism closes its denominator over
primitive_declared_definitions, so adding two canonical names without traversal
facts made the closure false. Both bridges are scalar -- symbol_lexeme maps one
Symbol to its text and symbol_intern_lexeme is its inverse -- so there is no
collection to walk and OrderFreeResult is the honest arm. HostUnspecifiedOrder
would claim a real traversal whose order the host does not pin, fabricating a
leak the primitive cannot have.
NAMESPACE WAVE ADMISSION (6 unadjudicated deltas). Four are TargetChanged for
DeclaredCallableIdentity moving v1.compiler.infer_sigs -> v1.std.core, which is
what lets CallTargetIdentity carry the declaration a runtime target was
projected from. infer_sigs imports v1.std.core, so the type could not stay put
without a cycle. Four enumerated rows, one per binding site; the two membership
deltas auto-admit as ExplicitlyEvaluatedZeroDelta. Dissolve-on: this PR merging,
by the same trigger the three prior shrinks record.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Class-C fixture was broken, not the repair: the witness pool is smaller than the corpus
The row FAILED while the mechanism was green. The probe used the qualified
spelling without importing v2.std.collection, which resolves against the real
4261-module corpus but not against compile_dag_rust_emit_check's 2973-module
witness pool. Measured both ways: emitted against the corpus the same probe
produces crate::v2_std_collection::map_get(m.clone(), "key".to_string()),
exactly what the row asserts.
The import restores module presence and does not answer the call -- decl_name
comes from the authored spelling at the call site regardless of imports -- so
the negative assertion still discriminates. Falsifier 2 is what proves that
rather than argues it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* is_empty: a conversion is not a repair -- give it the Rust realization it never had
Before the class-B change, xs |> is_empty emitted v1_rt::is_empty, a symbol the
seed does not define: 5 x E0425. After it, the same 5 sites became typed
refusals -- correct in kind, still 5 errors. The class-B repair made the gap
visible; it did not close it.
is_empty is an algebra template over FreeMonoid whose Rust realization is
Vec::is_empty, exactly as count's is Vec::len, so the fix is one row in
rust_simple_method_specs beside count. Nothing in 05_emit_rust learns a new
name: realization is a target fact and lives in the target's registry.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* A receiver's own callable field outranks every name-keyed table: class B survived one layer up
The requested is_empty negative control found a live hole rather than confirming
a safe one. Both rust_method_templates lookups are keyed on the bare method
spelling with no receiver check, so a fn-typed record field named is_empty was
captured by the target template and emitted as recv.is_empty() instead of
(recv.is_empty)(..). The class-B repair fixed the algebra FALLBACK and left the
two tables sitting in front of it.
The hole is not new and is not specific to is_empty: count, first, join, split,
take, skip, last, chars and enumerate have carried it for as long as they have
had templates. Adding is_empty made it urgent by putting the spelling most
likely to name a predicate field in front of that table.
One helper, consulted at the top of both arms before every name-keyed special
case, so the two cannot drift. Two controls: the new spelling and a pre-existing
one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Two more wave admissions: the declaring module rebinds too
v1.compiler.infer_sigs used to DECLARE DeclaredCallableIdentity, so its own two
construction sites resolved locally and produced no delta. Now that the
declaration lives in v1.std.core and infer_sigs imports it, those sites rebind
exactly like the consumers in infer_lookup. An enumeration error on my part, not
a second transition: same subject, same trigger, same dissolve.
Floor is now green on this branch (passed=2754 failed=0) -- the OrderFreeResult
traversal facts closed all nine determinism rows.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* The callable-field tier was consuming the algebra profile's identity domain, not the receiver's: 202 refusals on the first compile of the converged seed
rust_receiver_has_callable_method_field asked rust_record_field_needs_fn_rc,
which sweeps rust_struct_field_lookup_candidates -- and that list deliberately
widens a receiver's name to its container template algebra. An algebra declares
its operations as arrow-typed members, so under that widening every Map receiver
"has a callable field" named map_keys, map_values, lookup or get, and the tier
captured the very bridge calls it sits in front of.
Measured at the first compile of the round-3 converged mirror: 202 rustc
refusals, one class -- 164 E0609 (no field `map_keys` on
Rc<im::HashMap<String, Rc<ItemInfo>>> and friends), 48 E0282, 4 E0615 on `get`.
It is the same defect the tier was built to close, one level up: a name-keyed
lookup consuming an identity domain that is not its own.
The predicate now consults only the receiver's own declared record.
w_map_receiver_operation_is_not_read_as_a_callable_field is the discriminating
red: restore the candidate sweep and its must_not_contain clause fires.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Regenerate the stage0 mirror at the merge-equivalent tree: byte fixed point at round 3, six paths, each explained by an authority change
Convergence transaction on srv1 (/tmp/xl0c.sh -> /tmp/xl0g.log), on
952ffa6 = main b726547 merged with the branch. Criterion is BYTE equality
(sha256 over the whole candidate tree vs the whole installed tree), never
first_generation_equal and never the changed-path list; the full workspace
is rebuilt inside every round so a non-compiling mirror stops the line.
round 1 cand e212fe74 inst 6f55cf3e installed, compiles
round 2 cand 932b0543 inst e212fe74 drift = v1_rt.rs only (the two-hop:
v1_rt.rs is rendered by the previously compiled rt_hash_ops)
round 3 cand 932b0543 inst 932b0543 BYTE FIXED POINT -- produced by a
compiler rebuilt from the round-2 installed tree
Changed paths and their authority:
extdeps_languages_rust_emit.rs <- rt_function_registry / rust_simple_method_specs rows
std_primitive_projection.rs <- symbol_lexeme / symbol_intern_lexeme roster rows
v1_compiler_emit_rust.rs <- 05_emit_rust.dag (seam wall, callable-field tier, class B/C)
v1_compiler_infer.rs <- 04_infer.dag projected_from on RuntimePrimitiveCall
v1_compiler_runtime_rust.rs <- runtime_rust.dag symbol bridges
v1_rt.rs <- same, one hop later
On these bytes: function_value_named_application_controls_witness PASSES
(the d805243 / 952ffa6 rust-unit-tests red was the merge-driver-refused
stale v1_compiler_infer.rs, not a semantic regression); emit 175 files;
cargo check 15 errors: 9 E0425 (filesystem 2, V 2, K 2, Determinism 2, T 1),
2 E0728, 2 E0107, 1 E0391, 1 UNRESOLVED_CompilerError. No hand edit to any
generated file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* WIP tail classes
* WIP: if-equals-variant parses as a record literal; name the predicate
* WIP: annotations at module-item grain
* Regen round 1 (BuildBuddy invocation ebbdffc5, compiler gunbc=9830014a4e965ddb built from the committed mirror): v1_compiler_emit_rust.rs regenerated; candidate patch sha 05ce734c52890571
* Regen round 2 (BuildBuddy, compiler gunbc=75d74698aebcdb6e built from installed ce959e40604ffdd5): std_algebra.rs, std_nat.rs -- arrow returns now render through the Rust renderer (Rc<Vec<K>> for List<K>, Nat preserved); candidate patch sha b5b409aeebbeb6c4
* Arrow positions deviate from the generic renderer only for the two defect shapes: the unconditioned route emitted 2790 refusals where 15 stood; fix the arrow probe's variant spelling
* B: the init turbofish declines a declaration's own formals by the lambda's admission; F: a qualified type reference earns its use-line from the qualifier under export proof; both earlier cuts were measured non-events and are deleted
* Regenerate the stage0 mirror at the 0773184 freeze: byte fixed point at round 3, three paths, each explained by an authority change
srv1 (/tmp/xl0e.sh -> /tmp/xl0j.log), criterion = every regen-population
file byte-equal to installed; full workspace rebuilt as the gate each round.
round 1 gunbc=1dc61ba198c6750b from installed 0479b0df9fc5598e -> v1_compiler_emit_rust.rs
round 2 gunbc=909aa212f353bd03 from installed 8ebedc7445fadbaa -> std_algebra.rs, v1_compiler_trait_derive_emit.rs
round 3 gunbc=0d0cd70ec5b20db9 from installed 8713cb43f8ad848c -> <none> BYTE FIXED POINT
v1_compiler_emit_rust.rs <- 05_emit_rust.dag (gated arrow position, init turbofish admission, qualified-type use-lines)
std_algebra.rs <- the gated arrow route restores the pre-e9900e2 spelling of the two arrow-typed fields
v1_compiler_trait_derive_emit.rs <- one use-line synthesized for a qualified std.types.List reference under export proof
Final installed tree 8713cb43f8ad848c. No hand edit to any generated file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* One renderer for every arrow position; a type position never takes the variant arm; the qualified route synthesizes use-lines only for types the emitted source names
Four regressions the 0773184 fixed point put on the closure, each with its discriminating row:
- E0603 x16: the qualified-type route synthesized `pub use crate::v2_std_nat::Succ;` for every
`v2.std.nat.Succ { prev: .. }` record literal. A qualified name reaches the surface walk in the
same dotted spelling whether it is a type or a variant head; the route now asks the registry
whether the leaf is a TYPE declared in the named qualifier, records each decision as a census
row, and considers only leaves the emitted source actually names (it had also synthesized an
unused `DeclarationRef` import from a variant payload).
w_qualified_variant_head_earns_no_type_use_line.
- `Outcome<compile_error!("UNRESOLVED_CompilerError")>` x3 and `Rc<Medium>` E0107: two cuts had
each introduced a second per-position renderer for arrow types beside the one fn parameters use.
An arrow's return is not a different kind of type from its parameter: both positions now render
through render_rust_fn_sig_type, and render_rust_type_with_applied_binding -- which rebuilt its
EmitGraphInfo with an empty generic scope, so a fn-scope `C` rendered `_` (E0121) -- carries the
fn's generic names through that hop. The measured gate over the second renderer is deleted.
w_generic_arrow_return_renders_the_fn_scope_generic; w_arrow_return_type_keeps_its_applied_binding
(its fixture was an invalid program: Accepted lacked `diagnostics`).
- v2.std.determinism E0425 x2: traced to the bare-name disposition, not the qualified route --
`Determinism` is a type in std.determinism and a variant of v2.lens.registry LensIdV0, and
is_known_variant is corpus-wide by spelling, so a TYPE-position reference was delegated to an enum
it never named. A name in one of the module's type positions never takes the variant arm.
a_known_variant_spelling_in_a_type_position_takes_the_registry_arm (red by construction on the
old arm); the harness row is a positive control and says so, because the witness harness refuses
any pool carrying the colliding variant with NoSuchVariable.
Verified on a test binary built from the self-emitted emitter (not a regeneration): witnesses
23/24 -> 24/24 after the harness row was reshaped; closure instrument 2799 -> 2779. The regeneration
that binds these to the mirror follows as its own commit after the freeze merge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Regenerate the stage0 mirror at the 49482b0 freeze: byte fixed point at round 3, three paths, each explained by an authority change
srv1 (/tmp/xl0e2.sh -> /tmp/xl0j2.log, launched 2026-08-29T19:52:56Z), criterion = every
regen-population file byte-equal to installed; the full workspace rebuilt as the gate each round.
round 1 gunbc=14967ca810cb6609 from installed db46176cc5cf5861 -> v1_compiler_emit_rust.rs, v1_tests_claim_reference_derived_disposition_census_witness_test.rs
round 2 gunbc=5378a516528a6e0c from installed efa440bc86734f53 -> v1_compiler_trait_derive_emit.rs
round 3 gunbc=974aafe864f743f6 from installed b1a0409ce9fc79d4 -> <none> BYTE FIXED POINT
v1_compiler_emit_rust.rs <- 05_emit_rust.dag (arrow positions via the fn-signature renderer, generic scope through the applied-binding hop, type-position exemption, qualified rows with the registry type gate and token filter)
v1_tests_claim_reference_derived_disposition_census_witness_test.rs <- its .dag (in_type_position at 5 callers + the type-position control)
v1_compiler_trait_derive_emit.rs <- retracts the unused `pub use crate::std_types::List;` the earlier qualified route synthesized (token filter)
Final installed tree b1a0409ce9fc79d4; merged tree 89c55a0e7e8d949047b5d92864dfc9fe306aebc0 at the
freeze; main parent 5e80671. No hand edit to any generated file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Witness fixture only: the qualified-type positive control moves to a provider the harness pool can carry
Post-freeze, fixture-only (dag/test/claim is not a regen-population path; a no-drift regen run on
this head is recorded in the PR). Two harness facts, both measured on the fixed-point artifact
gunbc=974aafe864f743f6: a `{Determinism}` inside a .dag string literal is read as an interpolation
of that name (the row failed in the interpreter before any compile ran), and the harness pool is the
probe's DECLARED import closure, so a provider referenced only by a dotted name is absent -- and
std.determinism cannot enter it because its own body references std.perturbation the same way. The
row now uses std.decl_ref with a sibling import and says plainly that it is a positive control; the
class's discriminating red stays at the disposition grain
(a_known_variant_spelling_in_a_type_position_takes_the_registry_arm) and in the closure count.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* WIP XL-0B commit 1: thread DeclarationRef into the checkpoint-spelling callers; exact binding first; delete the redundant expression-position alias arm
* Enroll the two emission batteries under the required-gate seed prefix (test.claim.self_host_*)
* XL-0B commit 1: exact spelling at the fn-signature and declaration-type leaves; alias-rhs site reads scope.type_env
* alias-rhs leaf site reads scope.type_env
* Regenerate the stage0 mirror at the XL-0B commit-1 tree: byte fixed point at round 3
Cycle on srv1 over a1c9dde (authority tree bc2ae136138ac4aa), gate bins built each round:
round 1: compiler e33c998203b59217 from installed df30d05facfa6307 -> drift v1_compiler_emit_rust.rs
round 2: compiler ad9914da781db28d from installed c475b249666c3ba5 -> drift std_nat.rs, std_types.rs
round 3: compiler c7ac6e91c1e07861 from installed be968e441d3a2a43 -> every regen-population file byte-equal
CHANGED paths, each explained by the authority change: v1_compiler_emit_rust.rs (the threading);
std_types.rs (Bytes/Secret/SecretValue declaration sites now spell the exact grounding
std::vec::Vec<u8> / std::string::String); std_nat.rs (List<Nat> in container-argument position
renders the closed alias's resolved numeric realization i64 -- type-identical to Nat = i64).
Unit tests on the converged bytes: 552 passed, 0 failed, 140 ignored.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0B commit 2 (source): declared callees imported over builtin capture; dead RebuildEmittedFail variant; Accepted diagnostics bound and threaded; WallNow carries its fields; evaluator binding-miss answers the PartialFunction codomain; Optional-nested variant qualified by its own enum; Clone for generics forwarded by a returned closure
* XL-0E: equality admission wall in v1 acceptance (records/coproducts with function members refuse ==) + explicit identities for InterpretationAlgebra and RuntimeValue comparisons
The wall: infer_binop_type_node answered Eq/Ne with bool_type for every left
type and the ExprBinOp arm emitted no diagnostic, so '==' was accepted on
types whose equality semantics do not exist and the refusal lived below the
floor as rustc E0369 in the emitted v2 crate. equality_admission_diags now
judges both operands' complete resolved types: Arrow refuses; kernel scalars
admit; algebra carriers admit or refuse by the new declared support-axis row
std.algebra algebra_profile_equality_extensional (finite-support carriers
lift into their type arguments, PartialFunction refuses); products walk
members, coproducts walk arms, under a visited set keyed on declaration
identity (Peano Nat admits); unjudgeable members refuse. Two new blocking
diagnostics EqualityOnFunctionMember / EqualityMemberUnjudgeable, with their
two mechanical seed-transport arms (receipt expanded in the gate note).
The identities: InterpretationAlgebra comparison is the six carried slot
identity Symbols (interpretation_algebra_slot_identities_equal), consumed at
both digest-authority sites in 05_eval. RuntimeValue has NO universal Boolean
comparator any more: runtime_value_equality answers Equal/Differ/
EqualityUnavailable via the admitted structural projection, explicit
RuntimeIdentity for references, and a typed third state for closures that is
never collapsed to false; the eval verdict machinery routes Unavailable to a
RunFailed verdict, and the roundtrip/witness/test consumers match the verdict
explicitly.
Fixture: dag/test/claim/self_host_equality_admission_witness_test.dag — five
blocking reds (the two real subjects compiled against the live pool, planted
record/coproduct equivalents, PartialFunction) and four greens (v2 Peano Nat,
local recursive coproduct, structural record with containers, '!= none').
stage0 mirror carries a hand-applied minimal delta (enum variants + two arms)
solely to keep the tree buildable for regen round 1; the regen transaction
replaces it with authoritative bytes in the follow-up commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* Regenerate the stage0 mirror for commit 2 (mechanical residue): byte fixed point at round 2
Cycle on 8781269 (main parent d35cda54): round 1 drift on v1_compiler_emit_rust.rs and
v1_compiler_trait_derive_emit.rs (the two files commit 2 edits), round 2 byte fixed point;
installed tree 7fcf44b9f5c9df97, gunbc 2146d1f1844dea92. Unit 552/0. Emitted closure
cargo check 420 -> 392; line-insensitive identity diff vs the merged-tree base: 28 removed,
0 added (E0061 x6 vocab arity, E0599 GlobalBare* x4, E0004 x7, E0533, E0271, E0618 x2,
returned-closure Clone x7).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* A1: relocate the import-admission helpers to their consumer layer; C: one storage representation for Map at every position
A1 (closure prune). Counting fully qualified code references as declared edges, the declared
closure from v2.compiler.compile equals the emitted set: no module enters by bare-name binding.
The carrier was 03_name_resolve importing v2.lens.reference_deps for admission_from_module_root /
import_rows_from_parsed_module / collect_import_decl_nodes / ImportRowsState, consumed only by
v2.workflow.compile_door_ledger and self_host.frontier_probe (both outside the closure, both already
importing reference_deps). They now live in reference_deps; the two consumers import them there.
Emitted closure drops 8 modules (lens.coverage, enforcement.{grammar_coverage,standing_intent,vocab},
registry, module_graph, reference_deps, std.decl_index) and all 6 host-primitive panic sites.
C (Map). The six PartialFunction<..> positions (InferredTree.facts, EvaluationEnvironment.bindings,
four signatures) are Map<..>; the four PartialFunction { lookup: .. } constructions are empty_map()
or a first-wins map_insert fold; map_insert routes through a rostered map_insert_primitive_delegate
(closure body deleted); slots.lookup -> map_lookup. Emitter: the alias RHS renders a keyed/element
collection through the host template (type X = Map<A, B> -> Rc<HashMap<..>>), and a generic in map-key
position carries std::cmp::Eq + std::hash::Hash from the signature. Two witness rows added.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0N: generic LiteralElaboration/OperatorRealization authority — typed literal-to-Zero/Succ homomorphism at every boundary, operator realization by exact operand structure, structural Peano Nat operations (no i64 row)
* XL-0N: the Peano-Nat inhabitance witness asserts the ruled admission through its homomorphism; its expected-red row is retired by its trigger
* Close the five unrealized host seams in the emitted v2 compiler closure: one model-backed decode, and reflection segregated from what the compiler must emit
The v2 compiler's own emitted Rust crate carried five declarations with no
behaviour on that target -- panic!("unrealized host seam ...") bodies that rustc
accepts only because a diverging body type-checks. A compiler that ships a
refusal where a function should be is not fail-closed; it is a fabricated
plausible artifact whose failure is deferred to whoever calls it.
ONE OF THEM WAS A REAL DEFECT, not just misplacement.
v2.std.compilers.target_model recovered a UriScheme from a bundle node by asking
the HOST for ^UriScheme's nullary inhabitants. That answer exists only inside the
v1 interpreter's live declaration index, so the compiler could not read back a
node it had itself written -- the one call-reachable seam on the compile path.
It now folds a DECLARED roster, extdeps.uri uri_scheme_inhabitants, through a
roster-backed v2.std.node_query nullary_inhabitant_by_discriminant. Both refusal
arms survive (missing, duplicate) and the refusal is now located at the scheme
child being decoded rather than at the type declaration, which is the better
locus and was unavailable to the reflective form. The reflective
coproduct_nullary_inhabitant_by_discriminant, and the dead reflective wrappers
coproduct_arms / coproduct_arm_payload_pairs, are deleted rather than left
standing beside it.
THE OTHER FOUR WERE MODULE-GRAIN RESIDUE, and the fix is relocation, not a body.
Emission decides membership at module grain, so a host seam is emitted whenever
any NEIGHBOUR in its file is needed -- reachability never entered into it. Three
modules now separate the seam from the vocabulary the closure actually wanted:
v2.std.node_reflection resolve_type_node, coproduct_arm_keys,
coproduct_nullary_inhabitants
v2.lens.layer_import_scan layer_import_facts_live
v2.compiler.source_authority_read
the Filesystem.Read read-through and
SourceRootIngestBuild
Each keeps every consumer it had -- the two containment lenses, the self-host
closure-emit driver and frontier probe, the realization sweep, the ingest
witnesses -- and none of them is on a compile path. Nothing is deleted that had
a caller, and no seam acquires a fake body.
WHY THE SPLIT IS THE WALL AND NOT JUST A TIDY-UP. Each new module is imported
only from outside the compile closure, so a future declaration that reaches
reflection, or the filesystem, or the tree scan drags its module back in and the
seam reappears in the emitted crate at the same census grep -- loudly, in the diff
that caused it. The rule the split states is that these are INTERPRETER-time
capabilities: available to a lens or a witness reading the live tree, never to a
declaration the compiler must emit.
CARRIED CONSEQUENCE, not yet discharged in this commit: moving the two reflection
seams changes their bridge FAMILY module key in
gunbc.v1_interpreter_primitive_surface (v2.std.node / v2.std.node_query ->
v2.std.node_reflection). is_v4_bridge_family matches on the item registry's
module name, so this is inert until stage0 is regenerated; the regen lands on top
of XL-0B's converged seed.
EVIDENCE. v2.test.claim.target_model_external_authority_decode round-trips EVERY
declared scheme through bundle-then-decode (a roster short by one arm reds on its
own row), asserts that an unnamed discriminant REFUSES rather than defaulting to
an arm, and pairs that with a positive control over the identical hand-built node
shape so a shape-caused refusal cannot pass for the discriminant check. The price
of a declared roster is a second statement of the arms, so
v2.test.manual.coproduct_reflection_conformance now walls the drift both
directions by bag equality against reflected arm keys, with a non-emptiness
control so an empty reflection cannot green it vacuously.
* C corrected: InferredTree.facts stays the open PartialFunction; PartialFunction realizes as its algebra struct everywhere (HashMap rows deleted); frontier row dissolved; two TargetChanged admissions
The CI floor on 4da6059 showed the facts retyping over-reached: about 120 test and fixture sites
plus program.dag / 05_emit_orchestration define InferredTree.facts by a predicate closure, which
is exactly what the open carrier is for. inferred_tree / 04_infer / program_partition are restored.
The fork was the emitter realizing PartialFunction as HashMap in signature position and as the
algebra struct in field position; the PartialFunction HashMap rows in extdeps.languages.rust
(types.dag row, the partial_function template) are deleted so one representation stands.
EvaluationEnvironment.bindings stays Map (built by map_insert); v2_effect_io_pure's empty
environment is empty_map(). The v1 unresolved_method_frontier row for target_model lookup /
Primitive(T) is deleted: the slots.lookup -> map_lookup rewrite dissolved its one occurrence.
The two TargetChanged binding deltas for admission_from_module_root (frontier_probe,
compile_door_ledger) are admitted by exact subject in namespace_wave_admission.rs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0N: operand realization hops alias/refinement declarations to their target (NonEmptyStr, Char, VersionIdentity compare/add as their host targets)
* Move the two reflection bridge arms onto one v2.std.node_reflection family in the hand-maintained dispatch macro
`is_v4_bridge_family` decides a bridge by comparing the ITEM REGISTRY'S MODULE
NAME against a literal in `v1_bridge_family_arms!`, so relocating
resolve_type_node and coproduct_nullary_inhabitants into v2.std.node_reflection
is inert in the interpreter until this literal moves with them. Left unmoved,
both calls fall past the bridge to `ctx.lookup_fn`, reach their own .dag
self-call declaration, and recurse -- green typecheck, no diagnostic, wrong
behaviour, which is the exact shape §5 forbids.
The two former families collapse into one because they now share a module:
`distinct_dispatch_sites` in gunbc.v1_interpreter_dispatch_emit dedups sites by
module key and `render_site_block` selects that site's rows wherever they sit in
the roster, so the generated surface is a single
EvalCallBridgeStdNodeReflectionArm with both variants regardless of the two rows
not being adjacent.
WHY THIS FILE IS HAND-EDITED AND WHAT THAT COSTS, stated rather than glossed.
The family's enum, lookup fn and arm-macro names are DERIVED from
`EvalCallBridgeFamilySite.module` by module_slug_after_domain_prefix /
module_pascal_after_domain_prefix, so naming them wrongly here does not compile:
the generated symbols simply do not exist. The module LITERAL beside them is not
derived -- it is a second representation of the same roster field, and a literal
that disagrees with the roster while the derived names agree is writable and
nothing refuses it. That is a §3 fork in the seed's realization, not a defect
this change introduces, and it is named here because this change is the first
one to move the field and therefore the first to depend on the fork holding.
* XL-0E: parenthesize bare-variant comparisons in if-conditions (Variant-brace parses as record literal); flatten wall helpers to top-level fns
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* Regenerate the stage0 mirror for A1 + C (aa373f9): byte fixed point at round 3
Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, extdeps_languages_rust_types,
std_primitive_projection, v1_compiler_emit_rust, v1_compiler_infer), round 2 only compiler_tests.rs,
round 3 byte-identical; installed tree f53efd0d0173a43e, gunbc 1a2d53dd15920cf1. Unit 552/0.
Emitted closure cargo check 392 -> 278; line-insensitive identity diff vs commit 2: 112 removed,
0 added. Batteries on the converged binary: 29/29 (the two C rows red on the pre-fix compiler by
fixture emit), 14/14, 20/20.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0N: Bool row -- KernelBoolLiteral into v2.std.logic.Bool via BooleanUnfold (True/False); interpreter evaluates an elaborated literal as its kernel value; falsifier pair (row found/removed in the interpreter, constructor image vs host keyword on the emitted path)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0E regen: stage0 mirror at byte fixed point with the equality admission wall active; census repairs (native-realization leaves admit via decl_file_realizes_natively, presence exemption reads the expression spelling)
Regen transaction (local, this worktree): round 1 emitted from the committed
pre-wall mirror; candidate applied; rebuilt compiler carries the wall; its
corpus census surfaced exactly 10 refusals, all EqualityMemberUnjudgeable
false positives in two classes -- dag std Nat (native-realized scalar alias,
now admitted through the coercion authority's identity-keyed
decl_file_realizes_natively, fail-closed on unknown identity) and bare
'!= Absent' presence tests whose exemption now reads the operand expression
spelling. Round 2: first_generation_equal=true, exit 0 -- byte fixed point
with the wall live and zero corpus refusals.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* XL-0N: operand realization hops alias items by is_type_alias_item/resolved_type (the derive lane's own test) -- the structural condition on the declaration node never held, so NonEmptyStr/Char/VersionIdentity host ops were refused in the regenerated compiler
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* Commit 3 of the #9664 closure: six emitter mechanisms, the null keyword by path, and map_insert back to its .dag body under the gate's ruling
Emitter (src/v1/05_emit_rust.dag, trait_derive_emit.dag), each with a discriminating row in
self_host_emitted_call_target_realization_witness_test (pre-fix bytes observed on the seed):
- an argument into a parameter spelled Optional<T> is not unwrapped (the cardinality flag marks
only the T? sugar; the applied spelling is asked too)
- the shared-field accessor impl of a generic coproduct carries T: Clone
- a Violates literal in a record field takes the field's Witness carrier before the fn return
- a record pattern over a shared carrier derefs like a shared enum's variant pattern
- a fn returning an arrow-field record carries 'static on its generics (same gate as impl Fn)
- the fn-field record header prints well-formedness bounds asked per parameter instead of the
bounded set minus the seed set (FalsificationReceipt<Subj, A> lost A behind ValueDiff<A: Clone>)
- extdeps.languages.rust emit: the null keyword is std::option::Option::None, because a module
declaring a nullary variant named None emits pub struct None; at module scope (std.cache_interface)
v2.std.collection: map_insert is its .dag body again and map_insert_primitive_delegate with its
primitive_projection row is deleted. The delegate tripped map_carrier_shape_gate on CI at c6d9b22
(record_shaped_map_reaches_map_insert BUDGET-REFUSED): the interpreter's free_call.map_insert arm
answers Ok(None) for a non-native shape and the grounding falls through to the delegate's own
body, a self-call -- the deferred-refusal class #8887 filed. The closing move is a host fact
(a typed refusal in try_v2_std_collection_map_primitive_grounding) and is ledgered in the PR body,
not landed here, by the manager's ruling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Hoist commit-3 rationale annotations to module-item grain (§4c refuses in-body // blocks; 17 regen refusals on 780b394)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0N: operand realization reads the RESOLVED structure -- a NoConnective childless leaf whose structural name is a kernel type is a host operand (the resolver collapses NonEmptyStr/Char/VersionIdentity to their primitive RHS under the alias identity, so no resolved node is ever an alias item); refusal temporarily carries the operand's shape facts for the regen diagnosis
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0N: shape-facts suffix spells Int counts with to_string (the seed runtime has no Int-as-String cast; the cast panicked the emitter under regen)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0N: operand realization hops a where-refinement wrapper to its base (is_where_refinement_type, the type renderer's own route) -- measured under regen: NonEmptyStr/Char/VersionIdentity operands resolve to the one-child Conj refinement node, not a leaf or an alias item
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0N: operator realization matches over BinOp are total (14 closed variants enumerated) -- no non-fold residue rows for the new module
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* Commit 3 correction after the first regen: withdraw the Violates field-carrier arm (the literal resolves to the Witness declaration, spelling Witness::<Holds> at 87 sites), 'static on generics only for fn-field record returns (compose<A, B, C> stays bare), re-pin the optional and shared-record rows
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Regenerate the stage0 mirror: the reflection bridge family, the UriScheme roster, and the two projections main and the stack both moved
Four generated files, from three distinct authorities, all owed by this stack:
v1_interpreter_dispatch_generated.rs the bridge family moves to
v2.std.node_reflection -- one
EvalCallBridgeStdNodeReflectionArm with
both variants, replacing the separate
StdNode and StdNodeQuery families
extdeps_uri.rs uri_scheme_inhabitants, the declared
roster the target_model decode folds
v1_compiler_emit_rust.rs the projection whose bytes the merge
v1_compiler_infer.rs driver refused to resolve by hand
THE TWO MERGE-DRIVER REFUSALS ARE RESOLVED HERE AND NOWHERE ELSE. Both files
were left UNMERGED by merge.generated-artifact across the two main merges,
carrying the ours side verbatim with no conflict markers, precisely so the
regenerators would run against them. Picking a side would have dropped the other
side's authority-derived bytes with nothing in the tree to say so; these bytes
are the projection of the MERGED authorities, produced by the emitter, not
chosen.
WHAT THIS UNBLOCKS. The bridge family literal landed one commit earlier and was
inert until now: is_v4_bridge_family matches the item registry's module name,
and the generated lookup fn it names did not exist, so every head since has
failed to compile on E0425 -- four red checks with one cause. The seed now
defines lookup_eval_call_bridge_std_node_reflection and the hand macro resolves
against it.
MEASURED, NOT ASSUMED. An earlier run of this same loop reported convergence
that had not happened, because two of its steps failed open: main_wet was
OOM-killed on a 7 GiB runner while the script printed its success marker
regardless, and the post-restore rebuild failed while `test -x` passed on the
stale binary from the previous build -- so the rounds that followed, and a
fixed_point_equal=true, were produced by a compiler that did not carry this
change. Those readings are discarded. This run checks every step's real exit
code, and runs on a 20 GiB runner with the memory budget declared BELOW the box
rather than above it, which is why main_wet completed and regenerated the
dispatch surface at all.
STILL OWED, and deliberately not claimed by this commit: a clean regen round and
the fixed point from a compiler rebuilt off this installed tree, and the
emitted-closure census.
* XL-0N: retire the regen-diagnosis shape-facts suffix -- the where-refinement hop is confirmed at byte fixed point (6ba83b3 regen, round 2 equal)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* Rehome the layer scan out of the lens registry, declare the two reference-derived reflection imports, and adjudicate the 56 relocation bindings
Three findings from the floor, one mistake and two consequences of the
relocation working as designed.
THE MISTAKE: layer_import_facts_live was homed at v2.lens.layer_import_scan
because its only consumers are two lenses. That put a NON-LENS module inside the
population v2.lens.enforcement.lens_module_gate and the declarations phase read
as the lens registry's subject, and both refused it correctly:
declarations FAIL LENS-AUTHORSHIP-ABSENT src/v2/lens/layer_import_scan.dag:
lens `v2.lens.layer_import_scan` declares no `construction_justification`
plus lens_module_gate_holds_live and lens_closure_question_zero_holds_live. A
producer CONSUMED BY lenses is not a lens. It is now v2.std.layer_import_scan.
Closure membership is decided by REFERENCE, not by directory (DESIGN §3: paths
are discriminators, not gospel), so the seam stays out of the compile closure
from either home -- only the lens registry's population was sensitive to which,
which is exactly why the gate and not the emitter caught this.
THE SECOND: v2.test.generated.cross_representation_equality and
v2.test.lens_wiring_liveness.wiring_liveness_test carry no imports at all and
resolved coproduct_arm_keys / resolve_type_node through the reference-derived
closure. That worked while those names sat in modules every run already loaded.
Segregating them into a module NOTHING in the closure imports is the point of the
change, so the run stops loading it and the reference has to be declared:
FAIL v2.test.manual.value_null_split_witness... errored: no declaration named
'coproduct_arm_keys' in this execution's loaded index
Two import lines, not a relaxation of the split.
THE THIRD: 56 TargetChanged binding deltas, one per (module, declaration,
spelling) triple whose home moved. Every row names one exact subject with blast
radius 0, so a binding this change did not intend still refuses; none admits a
module, a prefix or a spelling in general. The count is 56 rather than 8 because
the read-through moved a type, two variants and a function that eight consumers
each reference from several declarations. They dissolve when this stack merges,
by the same trigger every shrink in that file was removed under.
WHAT THE FLOOR ALREADY CONFIRMED, and why these are the only three: all 14
changed witnesses passed, including the four target_model_external_authority_decode
rows and both UriScheme roster-drift rows. The conformance rows CALL reflection,
so they could only pass if the bridge family move routes -- the seam relocation
is green by execution, not by inspection.
* XL-0N: regenerated stage0 mirrors at byte fixed point (070a203 source, BuildBuddy regen round 3 first_generation_equal=true; partition crates rendered=14 written=0)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0N: register std.literal_elaboration and std.operator_realization in the std-core partition and gunbc.structural_realization_bindings in the v1-infer binding unit (v2.workflow.rust_crate_partition), with their module-dag edges
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* XL-0N: type_reference_declaration_ref resolves an in-place (recursive) type reference through its env binding before matching the declaration span -- v2.std.nat.Nat is recursive and answered Absent, so its literal boundary and operand identity fell to the unavailable arms while v2.std.logic.Bool worked
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* Regenerate the stage0 mirror at b115892: byte fixed point at round 3 (installed 9d44564232ba8648, gunbc eaf00f8d92931968)
Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, std_primitive_projection,
v1_compiler_emit_rust, v1_compiler_infer, v1_compiler_trait_derive_emit); round 2 the whole
population through the new emitter (std::option::Option::None, 'static on fn-field record
returns, per-parameter well-formedness bounds); round 3 byte-equal. Unit 566/0. Emitted v2 closure
cargo check 278 -> 258: 23 identities removed (8 optional-unwrap, 6 accessor &T, 5 record deref,
None capture, A: Clone, both E0310), 3 added -- the map_insert body's own rows at
v2_std_collection, the ruled cost of withdrawing the delegate. Batteries 35/35, 14/14, 20/20.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Bootstrap the two conflicted projections from the converged side so a compiler can be built to regenerate them
NOT A RESOLUTION OF THE MERGE, AND NOT BYTES ANYONE SHOULD READ AS AUTHORITATIVE.
merge.generated-artifact left v1_compiler_emit_rust.rs and v1_compiler_infer.rs
UNMERGED across the 3af83d9 merge, carrying the ours side verbatim so the
regenerators could run against them. That is the prescribed flow and it is what
the previous commit did -- but the ours side predates a signature change
3af83d9 made to the emit_rust authority, so the merged tree does not compile:
error[E0061]: v1_item_wf_propagated_clone_bounded_param_names ... provide the argument
error: could not compile `v1-compiler`
and a regenerator needs a building compiler. Neither side's bytes are the
projection of the merged authorities, so this is a choice between two wrong
seeds, and the only property that matters for a BOOTSTRAP is which one compiles.
The converged side does; ours does not.
WHAT THIS COMMIT IS NOT: it is not "picking a side" in the sense the merge driver
forbids. Picking a side as the ANSWER would leave the tree authority-ahead-of-
artifact with nothing to say so. These bytes are transient scaffolding for one
build, immediately overwritten by the regen commit that follows, which derives
them from the merged authorities -- my source change and theirs together. If that
regen does not land, this commit is wrong and the drift gate says so on the very
next run, which is the property that makes the interim safe to take rather than
a silent substitution.
* w_fn_field_record_header_keeps_the_bound_a_field_type_demands: a local fn-field type instead of the host_run closure (30 s CPU per floor fill, false through the shared-artifact path on 3af83d9); same discriminating bytes on the seed (R6<Subj, A>) and the converged compiler (R6<Subj, A: Clone>)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* std.cache_interface: the three .first() producers are Optional at the declaration (cache_facts_for_id, cache_reach_candidate_probe, cache_layer_plan_primary/fallback); every consumer matches -- a layer with no catalog facts neither beats recompute nor respects locality (typed false, no fabricated facts); planner test matches the projections
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* XL-0N: regenerated stage0 mirrors at byte fixed point on e51aff9 (BuildBuddy regen round 3 first_generation_equal=true; includes the merged #9710 commit-3 null-keyword-by-path drift and the new-module mirrors)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* Model rustc phases and derive the self-host phase board
* XL-0E: close the RuntimeValue equality leak — same-identity peel chase dispatches into declaration structure instead of re-entering the visited check
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* XL-0E: wildcard-free runtime_value_equality dispatch (nfr roster) and drop body comment (DESIGN 4c)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* Root compile-phase board in the self-host frontier
* Delete provisional emission-board authority after root cut
* Strengthen compile-phase receipts as a linked subject ledger
* XL-0N: type_reference_declaration_ref falls back to the module-visible name binding when the reference carries no ident-keyed binding (the emitter's scope env) -- the found declaration is still span-matched against the global roster, so a by-name hit only confirms an exact declaration; measured: Peano literal rows passed while the operator rows still lost Nat's identity
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y
* The host optional's variant spellings, one authority: six inline Some/None sites read rust_optional_variant_spelling, which qualifies None by path (a bare None PATTERN in std.cache_interface bound the module's pub struct None; five arms on the first regen); row w_absent_pattern_survives_a_module_declaring_a_none_variant
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Persist the first compile-phase diagnostic population
* Fix frontier identity folding and literal diagnostics
* XL-0E: regen merged tree to byte fixed point (round m2 first_generation_equal=true); re-judge the RuntimeValue witness row on the #9724 finite-Map model — the live subject now asserts admission as the over-refusal control
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* Observe parse and cargo-check phases in one instrument run
* Tighten compile-phase receipt epochs and identity semantics
* Bind frontier receipts to complete instrument observations
* Make compile-phase receipt populations structurally derivable
* Regenerate the stage0 mirror at d20440d: byte fixed point at round 3 (installed 1b8ca70c9dbf62bc, gunbc deabfe3085a2d289)
Round 1 changed v1_compiler_emit_rust; round 2 the population through the qualified None
spelling; round 3 byte-equal. Unit 575/0. Emitted v2 closure cargo check 244 -> 239, typeck
phase: the five None-in-pattern-position rows at std_cache_interface removed, nothing added
(the two re-keyed rows differ only by column).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Require dispositions for every newly exposed phase identity
* Bootstrap the XL-0E merge: the four driver-refused mirrors take XL-0E's converged bytes (the ours side lacked EqualityOnFunctionMember/EqualityMemberUnjudgeable that its non-conflicting mirrors reference; seed did not build); regen round 1 re-applies the None-spelling emitter change
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Persist and project the compile-phase frontier genesis
* XL-0E floor fixes: emit_host consumes the typed accepted_runtime_value_outcome_equality verdict (name main's #9727 imported no longer existed); empty-list literal comparison exempt as the emptiness idiom beside '== none'; regen to byte fixed point (round n2)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe
* Regenerate the stage0 mirror at 03f1631 (XL-0E integrated): byte fixed point at round 3 (installed 2be25adfee989956, gunbc 37b1266cb05babf4)
Round 1 re-applied the qualified None spelling over the bootstrap pick of XL-0E's four mirrors;
round 2 the remaining population; round 3 byte-equal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Materialize each emission measurement exactly once
* Rc-field arm grouping picks a representative by plain-binding subset, not outer-pattern bytes: two arms of one record that differ only on a plain binding lower to one nested match instead of two guarded arms (E0004 x2, rustc cannot see a guard)
rc_group_is_whole_coverage required byte-equal outer patterns, so
Edge { label: Named {..}, target: magnitude } beside
Edge { label: Positional, target: _ } fell back to the #8570 guard form
on both arms, which rustc reports as non-exhaustive (E0004 at
v2.extdeps.languages.dag and v2.std.compilers.target_model, xl0b9
board). The group now takes the outer pattern of the member whose
plain bindings are a superset of every other member's (same field,
same identifier), which selects the same values; any refutable plain
field, second Rc-bound field, or authored guard still keeps the guards.
Witness: w_record_arms_differing_only_in_plain_bindings_group_into_a_nested_match
(RED on 37b1266c: emits the guard form, measured by direct emission).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* A record-literal field value is emitted under the field's declared type, not the fn return: EmitGraphInfo.expected_type at expression grain; the Violates type argument reads it (E0308 x5, Witness at a Witness<Node>/Witness<InferredFacts> field)
rust_witness_type_arg_from_fn_return answered a Violates literal with the
enclosing fn's return carrier wherever it sat, so the four
RuntimeValueAcceptanceWitness fields at v2.compiler.eval and the
Rejected arm at v2.compiler.compile rendered
Witness::<Rc<RuntimeValueAcceptanceWitness>>::Violates against fields
declared Witness<Node> / Witness<InferredFacts>. fn_return_type stays the
fn-grain fact (rust_declared_return_is_callable reads it); the new
expected_type is the expression-grain fact: seeded by
emit_info_with_fn_return, re-seeded by emit_field_value_with_context with
the field's declared type node (record_field_expected_type), cleared when
no declaration names the field. Witness:
w_violates_at_a_record_field_takes_the_fields_declared_carrier.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* A type argument inside a record field's type expression reads its declaring module from the env binding: std.nat.Nat at Measure<Time, S, Nat> rendered Rc<Nat> in the struct and i64 in every signature (E0308 x8, E0369 x1)
Field type expressions carry no resolved inference, so
type_reference_decl_file fell back to the REFERENCE's file and the
native-alias row (dag/std/nat.dag -> i64) could not fire; the shared
wrap then rendered the argument as Rc<Nat>. type_reference_decl_file_in_env
resolves the leaf through lookup_type_by_name and accepts the binding
only when the declaration is named by the leaf (an alias RHS never
stands in for the alias); the two checkpoint-spelling queries that
already carry env consume it. Witness:
w_native_alias_type_argument_at_a_generic_field_renders_the_machine_scalar
(the must line is provisional until the RED probe prints the current
rendering; refined in the regen commit if the wrap differs).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
* Three source-shape residues the v1 floor accepted: sort_by over a type-variable element dropped its key fn (E0599 x1); a ba…
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 31, 2026
…ages/rust, derive the per-phase board from the emitted-crate census, and enroll the phase-monotone ratchet as a required witness on #9710 (#9745) * Emitted v2 compiler crate: a declaration's identity is its last segment, and a primitive with no realization refuses instead of inventing one Two roots behind 175 of the 260 rustc errors on the emitted v2 compiler closure (issue #9664, milestones 1 and 2): - 102 x E0425: the four DeclaredCallableIdentity constructions in v1.compiler.infer_lookup took decl_name from the AUTHORED spelling, so a qualified call carried the whole dotted path as the declaration name and emission rendered crate::v2_std_grammar::v2.std.grammar.f(..). - 73 x E0425: v2.std.algebra length is a ModeledProjection of the `length` primitive and rt_function_registry has no `length` row, so emission took rust_runtime_bridge_name's identity arm and wrote v1_rt::length -- a symbol the seed does not define. A primitive's identity and its per-target realization are two facts; CallTargetIdentity carried only the first, so every emitter had to ASSUME a bridge exists. RuntimePrimitiveCall now carries projected_from, the declaration the roster projected it from, and emit_rust routes to the bridge only when its own registry holds the primitive, falls back to the declaration otherwise, and refuses when neither exists. DeclaredCallableIdentity moves to v1.std.core so the target type can carry it without forking the pair. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Class B: the algebra method fallback asserted a v1_rt bridge it had not checked tier0 method resolution resolves an ordinary fn-typed RECORD FIELD through lookup_field_in_product, so `algebra.step(..)` arrives as AlgebraMethodSemantics carrying the field node as its method_def. The fallback at the end of that arm hardcoded runtime_bridge: true, which emitted `v1_rt::step` -- and made emit_rust_generic_method_call's own callable-field arm, guarded on runtime_bridge == false, unreachable for the exact receiver it was written for. 65 E0425s on the emitted v2 compiler closure (member, apply, is_empty, step, init, allocate_literal, ...) were that one literal. It now passes the realization question keyed on the same registry as the plain-call seam, so a real bridge method still lowers to a bridge, a callable field lowers as a field, and a name that is neither reaches the existing loud refusal rather than a fabricated symbol. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Only ModeledProjection carries projected_from: a HostRealizedSeam body is a self-call, so falling back to it would emit a nonterminating function The declaration fallback is sound only where the declaration's body is real code. HostRealizedSeam means the body IS a self-call, so emitting it compiles and then loops forever -- silent wrongness, strictly worse than the unresolved symbol it would have replaced. A seam whose target has no realization has no honest lowering, so it carries nothing and reaches emission's refusal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * M1: realize the two symbol bridges, which were host seams nothing declared to be host seams v2.std.compilers.lexing symbol_lexeme and symbol_intern_lexeme have self-call bodies -- the HostRealizedSeam shape exactly -- and the interpreter has carried real arms for both (v4_bridge.symbol_lexeme, v4_bridge.symbol_intern_lexeme). With no projection roster row the resolver saw ordinary declarations, so Rust emission emitted the declaration, and pub fn symbol_lexeme(sym: String) -> String { symbol_lexeme(sym) } COMPILES. The emitted closure carried two functions that type-check, pass every gate we own, and diverge from the interpreter by not terminating. Unlike the sibling seams (decl_facts and friends, which at least refuse loudly as unresolved v1_rt symbols) nothing anywhere reported this one -- it is absent from the E0425 census precisely because it is silent. extdeps.languages.rust.types already declares Symbol's target type as String, so on this target both bridges are the identity. That is a realization of the declared row, not a second opinion about it. Residue named, not closed: a self-call body is a DECIDABLE structural marker of a host seam, so the compiler could refuse an unrealized one rather than emit it. It does not yet; that check is the class's next-rung trigger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror for the emitter repairs (fixed point at round 2) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * test.claim fixtures: one discriminating RED per closed emission class, with boundary controls Six rows over the three emitter defects plus the two symbol bridges. Each class's positive and negative assertion differ only in the fact the repair added, so no single edit satisfies both directions, and each repair carries a boundary control that would go red had it over-reached the other way (empty_map for the registry gate, a registered bridge method for the class-B gate). The symbol-bridge row is deliberately not an error-count assertion: that class COMPILED throughout the defect and diverged by not terminating, so a row asserting 'no error' would have been green the whole time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Fix the class-B boundary control: count has a method template, so it never reaches the seam under repair count is answered by rust_simple_method_specs before the algebra fallback, so the row would have gone red while executing none of the code the repair touched. trim is in rt_function_registry and has no template, so it is one of the few names that actually reaches that fallback. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Unbreak the fixture parse: a trailing semicolon on the note declaration The module index refused the file outright, so none of the six witnesses were discovered. .dag item declarations carry no terminator. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The self-call seam wall: an unrealized host seam refuses instead of emitting compiling recursion A whole-body self-call is the decidable structural marker of a host seam. In the interpreter the shape is safe -- reaching it recurses to the evaluation-budget refusal -- but emitted to Rust the same shape COMPILES and returns to no caller. Nothing reported it: not the module index, not the compile-clean gate, not cargo check. That is why the two symbol bridges were invisible until someone read the emitted bytes. emit_fn_def now asks the realization registry -- the same authority the call sites ask, so the two cannot drift -- and suppresses the declaration when the seam is realized, refuses with a located message when it is not. Suppression rather than delegation is deliberate: a forwarding body would make this seam reconstruct signatures in target types, which is the cementing the existing suppressed-seam precedent avoids, and a realized primitive's calls all route to the bridge anyway. The predicate is whole-body identity, not 'contains a self-call'. Ordinary recursion has a match, an if or a let between the head and the call, so it never matches; expr_has_self_call walks children and would have refused most of the compiler. Both directions carry a fixture. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam wall must resolve realization through the roster's primitive, not the declaration name Measured, not predicted: the wall refused six seams in the emitted closure and one of them -- v2.std.collection empty_map_primitive_delegate -- is realized. Its roster row names the empty_map primitive, whose bridge is rc_empty_map, but rt_function_registry holds 'empty_map' and the wall looked up 'empty_map_primitive_delegate'. A declaration's name and the primitive it realizes are two facts; the roster is the authority that joins them, and the declaration name is only the fallback for a seam nobody has rostered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam wall's realized arm must not suppress the declaration: suppression created 10 dangling imports Measured on the emitted closure with the wall finally in the mirror: removing a realized seam's item left 10 unresolved imports (E0432) for symbol_lexeme, symbol_intern_lexeme and resolve_type_node. Other modules import these declarations; the suppression created that breakage rather than finding it. And the reasoning that made suppression look safe is what makes it unnecessary. A realized seam's body IS a call to itself, and resolution already routes that call through the roster to the bridge -- so ordinary emission writes v1_rt::symbol_lexeme(sym) as the body without help. The wall's whole job is the UNREALIZED arm. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam refusal is a generated body, not a crate-wide compile_error!: rustc's denominator is larger than the demand denominator compile_error! fails the WHOLE crate, and that form silently assumes every seam it refuses is one somebody calls. It is not. rustc type-checks the entire emitted crate including declarations imported but never invoked, so the refusal denominator is strictly larger than the entry-reachable execution closure -- five unreachable seams took the crate down. The refusal is now a panic body with the declaration's real signature: dependent modules resolve, the crate compiles, and only an actual invocation fails loudly. That moves the refusal from the crate to the one declaration that earned it, and leaves reachability to a separate instrument. An entry-rooted pruner can replace the body later without revisiting this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Two obligations the required floor found, both real consequences of this change DETERMINISM DENOMINATOR (9 reach_witness rows red, including determinism_denominator_is_closed_on_declared_primitives, whose entire job is to notice this). v2.lens.determinism closes its denominator over primitive_declared_definitions, so adding two canonical names without traversal facts made the closure false. Both bridges are scalar -- symbol_lexeme maps one Symbol to its text and symbol_intern_lexeme is its inverse -- so there is no collection to walk and OrderFreeResult is the honest arm. HostUnspecifiedOrder would claim a real traversal whose order the host does not pin, fabricating a leak the primitive cannot have. NAMESPACE WAVE ADMISSION (6 unadjudicated deltas). Four are TargetChanged for DeclaredCallableIdentity moving v1.compiler.infer_sigs -> v1.std.core, which is what lets CallTargetIdentity carry the declaration a runtime target was projected from. infer_sigs imports v1.std.core, so the type could not stay put without a cycle. Four enumerated rows, one per binding site; the two membership deltas auto-admit as ExplicitlyEvaluatedZeroDelta. Dissolve-on: this PR merging, by the same trigger the three prior shrinks record. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Class-C fixture was broken, not the repair: the witness pool is smaller than the corpus The row FAILED while the mechanism was green. The probe used the qualified spelling without importing v2.std.collection, which resolves against the real 4261-module corpus but not against compile_dag_rust_emit_check's 2973-module witness pool. Measured both ways: emitted against the corpus the same probe produces crate::v2_std_collection::map_get(m.clone(), "key".to_string()), exactly what the row asserts. The import restores module presence and does not answer the call -- decl_name comes from the authored spelling at the call site regardless of imports -- so the negative assertion still discriminates. Falsifier 2 is what proves that rather than argues it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * is_empty: a conversion is not a repair -- give it the Rust realization it never had Before the class-B change, xs |> is_empty emitted v1_rt::is_empty, a symbol the seed does not define: 5 x E0425. After it, the same 5 sites became typed refusals -- correct in kind, still 5 errors. The class-B repair made the gap visible; it did not close it. is_empty is an algebra template over FreeMonoid whose Rust realization is Vec::is_empty, exactly as count's is Vec::len, so the fix is one row in rust_simple_method_specs beside count. Nothing in 05_emit_rust learns a new name: realization is a target fact and lives in the target's registry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A receiver's own callable field outranks every name-keyed table: class B survived one layer up The requested is_empty negative control found a live hole rather than confirming a safe one. Both rust_method_templates lookups are keyed on the bare method spelling with no receiver check, so a fn-typed record field named is_empty was captured by the target template and emitted as recv.is_empty() instead of (recv.is_empty)(..). The class-B repair fixed the algebra FALLBACK and left the two tables sitting in front of it. The hole is not new and is not specific to is_empty: count, first, join, split, take, skip, last, chars and enumerate have carried it for as long as they have had templates. Adding is_empty made it urgent by putting the spelling most likely to name a predicate field in front of that table. One helper, consulted at the top of both arms before every name-keyed special case, so the two cannot drift. Two controls: the new spelling and a pre-existing one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Two more wave admissions: the declaring module rebinds too v1.compiler.infer_sigs used to DECLARE DeclaredCallableIdentity, so its own two construction sites resolved locally and produced no delta. Now that the declaration lives in v1.std.core and infer_sigs imports it, those sites rebind exactly like the consumers in infer_lookup. An enumeration error on my part, not a second transition: same subject, same trigger, same dissolve. Floor is now green on this branch (passed=2754 failed=0) -- the OrderFreeResult traversal facts closed all nine determinism rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The callable-field tier was consuming the algebra profile's identity domain, not the receiver's: 202 refusals on the first compile of the converged seed rust_receiver_has_callable_method_field asked rust_record_field_needs_fn_rc, which sweeps rust_struct_field_lookup_candidates -- and that list deliberately widens a receiver's name to its container template algebra. An algebra declares its operations as arrow-typed members, so under that widening every Map receiver "has a callable field" named map_keys, map_values, lookup or get, and the tier captured the very bridge calls it sits in front of. Measured at the first compile of the round-3 converged mirror: 202 rustc refusals, one class -- 164 E0609 (no field `map_keys` on Rc<im::HashMap<String, Rc<ItemInfo>>> and friends), 48 E0282, 4 E0615 on `get`. It is the same defect the tier was built to close, one level up: a name-keyed lookup consuming an identity domain that is not its own. The predicate now consults only the receiver's own declared record. w_map_receiver_operation_is_not_read_as_a_callable_field is the discriminating red: restore the candidate sweep and its must_not_contain clause fires. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror at the merge-equivalent tree: byte fixed point at round 3, six paths, each explained by an authority change Convergence transaction on srv1 (/tmp/xl0c.sh -> /tmp/xl0g.log), on 952ffa6 = main b726547 merged with the branch. Criterion is BYTE equality (sha256 over the whole candidate tree vs the whole installed tree), never first_generation_equal and never the changed-path list; the full workspace is rebuilt inside every round so a non-compiling mirror stops the line. round 1 cand e212fe74 inst 6f55cf3e installed, compiles round 2 cand 932b0543 inst e212fe74 drift = v1_rt.rs only (the two-hop: v1_rt.rs is rendered by the previously compiled rt_hash_ops) round 3 cand 932b0543 inst 932b0543 BYTE FIXED POINT -- produced by a compiler rebuilt from the round-2 installed tree Changed paths and their authority: extdeps_languages_rust_emit.rs <- rt_function_registry / rust_simple_method_specs rows std_primitive_projection.rs <- symbol_lexeme / symbol_intern_lexeme roster rows v1_compiler_emit_rust.rs <- 05_emit_rust.dag (seam wall, callable-field tier, class B/C) v1_compiler_infer.rs <- 04_infer.dag projected_from on RuntimePrimitiveCall v1_compiler_runtime_rust.rs <- runtime_rust.dag symbol bridges v1_rt.rs <- same, one hop later On these bytes: function_value_named_application_controls_witness PASSES (the d805243 / 952ffa6 rust-unit-tests red was the merge-driver-refused stale v1_compiler_infer.rs, not a semantic regression); emit 175 files; cargo check 15 errors: 9 E0425 (filesystem 2, V 2, K 2, Determinism 2, T 1), 2 E0728, 2 E0107, 1 E0391, 1 UNRESOLVED_CompilerError. No hand edit to any generated file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * WIP tail classes * WIP: if-equals-variant parses as a record literal; name the predicate * WIP: annotations at module-item grain * Regen round 1 (BuildBuddy invocation ebbdffc5, compiler gunbc=9830014a4e965ddb built from the committed mirror): v1_compiler_emit_rust.rs regenerated; candidate patch sha 05ce734c52890571 * Regen round 2 (BuildBuddy, compiler gunbc=75d74698aebcdb6e built from installed ce959e40604ffdd5): std_algebra.rs, std_nat.rs -- arrow returns now render through the Rust renderer (Rc<Vec<K>> for List<K>, Nat preserved); candidate patch sha b5b409aeebbeb6c4 * Arrow positions deviate from the generic renderer only for the two defect shapes: the unconditioned route emitted 2790 refusals where 15 stood; fix the arrow probe's variant spelling * B: the init turbofish declines a declaration's own formals by the lambda's admission; F: a qualified type reference earns its use-line from the qualifier under export proof; both earlier cuts were measured non-events and are deleted * Regenerate the stage0 mirror at the 0773184 freeze: byte fixed point at round 3, three paths, each explained by an authority change srv1 (/tmp/xl0e.sh -> /tmp/xl0j.log), criterion = every regen-population file byte-equal to installed; full workspace rebuilt as the gate each round. round 1 gunbc=1dc61ba198c6750b from installed 0479b0df9fc5598e -> v1_compiler_emit_rust.rs round 2 gunbc=909aa212f353bd03 from installed 8ebedc7445fadbaa -> std_algebra.rs, v1_compiler_trait_derive_emit.rs round 3 gunbc=0d0cd70ec5b20db9 from installed 8713cb43f8ad848c -> <none> BYTE FIXED POINT v1_compiler_emit_rust.rs <- 05_emit_rust.dag (gated arrow position, init turbofish admission, qualified-type use-lines) std_algebra.rs <- the gated arrow route restores the pre-e9900e2 spelling of the two arrow-typed fields v1_compiler_trait_derive_emit.rs <- one use-line synthesized for a qualified std.types.List reference under export proof Final installed tree 8713cb43f8ad848c. No hand edit to any generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * One renderer for every arrow position; a type position never takes the variant arm; the qualified route synthesizes use-lines only for types the emitted source names Four regressions the 0773184 fixed point put on the closure, each with its discriminating row: - E0603 x16: the qualified-type route synthesized `pub use crate::v2_std_nat::Succ;` for every `v2.std.nat.Succ { prev: .. }` record literal. A qualified name reaches the surface walk in the same dotted spelling whether it is a type or a variant head; the route now asks the registry whether the leaf is a TYPE declared in the named qualifier, records each decision as a census row, and considers only leaves the emitted source actually names (it had also synthesized an unused `DeclarationRef` import from a variant payload). w_qualified_variant_head_earns_no_type_use_line. - `Outcome<compile_error!("UNRESOLVED_CompilerError")>` x3 and `Rc<Medium>` E0107: two cuts had each introduced a second per-position renderer for arrow types beside the one fn parameters use. An arrow's return is not a different kind of type from its parameter: both positions now render through render_rust_fn_sig_type, and render_rust_type_with_applied_binding -- which rebuilt its EmitGraphInfo with an empty generic scope, so a fn-scope `C` rendered `_` (E0121) -- carries the fn's generic names through that hop. The measured gate over the second renderer is deleted. w_generic_arrow_return_renders_the_fn_scope_generic; w_arrow_return_type_keeps_its_applied_binding (its fixture was an invalid program: Accepted lacked `diagnostics`). - v2.std.determinism E0425 x2: traced to the bare-name disposition, not the qualified route -- `Determinism` is a type in std.determinism and a variant of v2.lens.registry LensIdV0, and is_known_variant is corpus-wide by spelling, so a TYPE-position reference was delegated to an enum it never named. A name in one of the module's type positions never takes the variant arm. a_known_variant_spelling_in_a_type_position_takes_the_registry_arm (red by construction on the old arm); the harness row is a positive control and says so, because the witness harness refuses any pool carrying the colliding variant with NoSuchVariable. Verified on a test binary built from the self-emitted emitter (not a regeneration): witnesses 23/24 -> 24/24 after the harness row was reshaped; closure instrument 2799 -> 2779. The regeneration that binds these to the mirror follows as its own commit after the freeze merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror at the 49482b0 freeze: byte fixed point at round 3, three paths, each explained by an authority change srv1 (/tmp/xl0e2.sh -> /tmp/xl0j2.log, launched 2026-08-29T19:52:56Z), criterion = every regen-population file byte-equal to installed; the full workspace rebuilt as the gate each round. round 1 gunbc=14967ca810cb6609 from installed db46176cc5cf5861 -> v1_compiler_emit_rust.rs, v1_tests_claim_reference_derived_disposition_census_witness_test.rs round 2 gunbc=5378a516528a6e0c from installed efa440bc86734f53 -> v1_compiler_trait_derive_emit.rs round 3 gunbc=974aafe864f743f6 from installed b1a0409ce9fc79d4 -> <none> BYTE FIXED POINT v1_compiler_emit_rust.rs <- 05_emit_rust.dag (arrow positions via the fn-signature renderer, generic scope through the applied-binding hop, type-position exemption, qualified rows with the registry type gate and token filter) v1_tests_claim_reference_derived_disposition_census_witness_test.rs <- its .dag (in_type_position at 5 callers + the type-position control) v1_compiler_trait_derive_emit.rs <- retracts the unused `pub use crate::std_types::List;` the earlier qualified route synthesized (token filter) Final installed tree b1a0409ce9fc79d4; merged tree 89c55a0e7e8d949047b5d92864dfc9fe306aebc0 at the freeze; main parent 5e80671. No hand edit to any generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Witness fixture only: the qualified-type positive control moves to a provider the harness pool can carry Post-freeze, fixture-only (dag/test/claim is not a regen-population path; a no-drift regen run on this head is recorded in the PR). Two harness facts, both measured on the fixed-point artifact gunbc=974aafe864f743f6: a `{Determinism}` inside a .dag string literal is read as an interpolation of that name (the row failed in the interpreter before any compile ran), and the harness pool is the probe's DECLARED import closure, so a provider referenced only by a dotted name is absent -- and std.determinism cannot enter it because its own body references std.perturbation the same way. The row now uses std.decl_ref with a sibling import and says plainly that it is a positive control; the class's discriminating red stays at the disposition grain (a_known_variant_spelling_in_a_type_position_takes_the_registry_arm) and in the closure count. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * WIP XL-0B commit 1: thread DeclarationRef into the checkpoint-spelling callers; exact binding first; delete the redundant expression-position alias arm * Enroll the two emission batteries under the required-gate seed prefix (test.claim.self_host_*) * XL-0B commit 1: exact spelling at the fn-signature and declaration-type leaves; alias-rhs site reads scope.type_env * alias-rhs leaf site reads scope.type_env * Regenerate the stage0 mirror at the XL-0B commit-1 tree: byte fixed point at round 3 Cycle on srv1 over a1c9dde (authority tree bc2ae136138ac4aa), gate bins built each round: round 1: compiler e33c998203b59217 from installed df30d05facfa6307 -> drift v1_compiler_emit_rust.rs round 2: compiler ad9914da781db28d from installed c475b249666c3ba5 -> drift std_nat.rs, std_types.rs round 3: compiler c7ac6e91c1e07861 from installed be968e441d3a2a43 -> every regen-population file byte-equal CHANGED paths, each explained by the authority change: v1_compiler_emit_rust.rs (the threading); std_types.rs (Bytes/Secret/SecretValue declaration sites now spell the exact grounding std::vec::Vec<u8> / std::string::String); std_nat.rs (List<Nat> in container-argument position renders the closed alias's resolved numeric realization i64 -- type-identical to Nat = i64). Unit tests on the converged bytes: 552 passed, 0 failed, 140 ignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0B commit 2 (source): declared callees imported over builtin capture; dead RebuildEmittedFail variant; Accepted diagnostics bound and threaded; WallNow carries its fields; evaluator binding-miss answers the PartialFunction codomain; Optional-nested variant qualified by its own enum; Clone for generics forwarded by a returned closure * XL-0E: equality admission wall in v1 acceptance (records/coproducts with function members refuse ==) + explicit identities for InterpretationAlgebra and RuntimeValue comparisons The wall: infer_binop_type_node answered Eq/Ne with bool_type for every left type and the ExprBinOp arm emitted no diagnostic, so '==' was accepted on types whose equality semantics do not exist and the refusal lived below the floor as rustc E0369 in the emitted v2 crate. equality_admission_diags now judges both operands' complete resolved types: Arrow refuses; kernel scalars admit; algebra carriers admit or refuse by the new declared support-axis row std.algebra algebra_profile_equality_extensional (finite-support carriers lift into their type arguments, PartialFunction refuses); products walk members, coproducts walk arms, under a visited set keyed on declaration identity (Peano Nat admits); unjudgeable members refuse. Two new blocking diagnostics EqualityOnFunctionMember / EqualityMemberUnjudgeable, with their two mechanical seed-transport arms (receipt expanded in the gate note). The identities: InterpretationAlgebra comparison is the six carried slot identity Symbols (interpretation_algebra_slot_identities_equal), consumed at both digest-authority sites in 05_eval. RuntimeValue has NO universal Boolean comparator any more: runtime_value_equality answers Equal/Differ/ EqualityUnavailable via the admitted structural projection, explicit RuntimeIdentity for references, and a typed third state for closures that is never collapsed to false; the eval verdict machinery routes Unavailable to a RunFailed verdict, and the roundtrip/witness/test consumers match the verdict explicitly. Fixture: dag/test/claim/self_host_equality_admission_witness_test.dag — five blocking reds (the two real subjects compiled against the live pool, planted record/coproduct equivalents, PartialFunction) and four greens (v2 Peano Nat, local recursive coproduct, structural record with containers, '!= none'). stage0 mirror carries a hand-applied minimal delta (enum variants + two arms) solely to keep the tree buildable for regen round 1; the regen transaction replaces it with authoritative bytes in the follow-up commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror for commit 2 (mechanical residue): byte fixed point at round 2 Cycle on 8781269 (main parent d35cda54): round 1 drift on v1_compiler_emit_rust.rs and v1_compiler_trait_derive_emit.rs (the two files commit 2 edits), round 2 byte fixed point; installed tree 7fcf44b9f5c9df97, gunbc 2146d1f1844dea92. Unit 552/0. Emitted closure cargo check 420 -> 392; line-insensitive identity diff vs the merged-tree base: 28 removed, 0 added (E0061 x6 vocab arity, E0599 GlobalBare* x4, E0004 x7, E0533, E0271, E0618 x2, returned-closure Clone x7). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A1: relocate the import-admission helpers to their consumer layer; C: one storage representation for Map at every position A1 (closure prune). Counting fully qualified code references as declared edges, the declared closure from v2.compiler.compile equals the emitted set: no module enters by bare-name binding. The carrier was 03_name_resolve importing v2.lens.reference_deps for admission_from_module_root / import_rows_from_parsed_module / collect_import_decl_nodes / ImportRowsState, consumed only by v2.workflow.compile_door_ledger and self_host.frontier_probe (both outside the closure, both already importing reference_deps). They now live in reference_deps; the two consumers import them there. Emitted closure drops 8 modules (lens.coverage, enforcement.{grammar_coverage,standing_intent,vocab}, registry, module_graph, reference_deps, std.decl_index) and all 6 host-primitive panic sites. C (Map). The six PartialFunction<..> positions (InferredTree.facts, EvaluationEnvironment.bindings, four signatures) are Map<..>; the four PartialFunction { lookup: .. } constructions are empty_map() or a first-wins map_insert fold; map_insert routes through a rostered map_insert_primitive_delegate (closure body deleted); slots.lookup -> map_lookup. Emitter: the alias RHS renders a keyed/element collection through the host template (type X = Map<A, B> -> Rc<HashMap<..>>), and a generic in map-key position carries std::cmp::Eq + std::hash::Hash from the signature. Two witness rows added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: generic LiteralElaboration/OperatorRealization authority — typed literal-to-Zero/Succ homomorphism at every boundary, operator realization by exact operand structure, structural Peano Nat operations (no i64 row) * XL-0N: the Peano-Nat inhabitance witness asserts the ruled admission through its homomorphism; its expected-red row is retired by its trigger * Close the five unrealized host seams in the emitted v2 compiler closure: one model-backed decode, and reflection segregated from what the compiler must emit The v2 compiler's own emitted Rust crate carried five declarations with no behaviour on that target -- panic!("unrealized host seam ...") bodies that rustc accepts only because a diverging body type-checks. A compiler that ships a refusal where a function should be is not fail-closed; it is a fabricated plausible artifact whose failure is deferred to whoever calls it. ONE OF THEM WAS A REAL DEFECT, not just misplacement. v2.std.compilers.target_model recovered a UriScheme from a bundle node by asking the HOST for ^UriScheme's nullary inhabitants. That answer exists only inside the v1 interpreter's live declaration index, so the compiler could not read back a node it had itself written -- the one call-reachable seam on the compile path. It now folds a DECLARED roster, extdeps.uri uri_scheme_inhabitants, through a roster-backed v2.std.node_query nullary_inhabitant_by_discriminant. Both refusal arms survive (missing, duplicate) and the refusal is now located at the scheme child being decoded rather than at the type declaration, which is the better locus and was unavailable to the reflective form. The reflective coproduct_nullary_inhabitant_by_discriminant, and the dead reflective wrappers coproduct_arms / coproduct_arm_payload_pairs, are deleted rather than left standing beside it. THE OTHER FOUR WERE MODULE-GRAIN RESIDUE, and the fix is relocation, not a body. Emission decides membership at module grain, so a host seam is emitted whenever any NEIGHBOUR in its file is needed -- reachability never entered into it. Three modules now separate the seam from the vocabulary the closure actually wanted: v2.std.node_reflection resolve_type_node, coproduct_arm_keys, coproduct_nullary_inhabitants v2.lens.layer_import_scan layer_import_facts_live v2.compiler.source_authority_read the Filesystem.Read read-through and SourceRootIngestBuild Each keeps every consumer it had -- the two containment lenses, the self-host closure-emit driver and frontier probe, the realization sweep, the ingest witnesses -- and none of them is on a compile path. Nothing is deleted that had a caller, and no seam acquires a fake body. WHY THE SPLIT IS THE WALL AND NOT JUST A TIDY-UP. Each new module is imported only from outside the compile closure, so a future declaration that reaches reflection, or the filesystem, or the tree scan drags its module back in and the seam reappears in the emitted crate at the same census grep -- loudly, in the diff that caused it. The rule the split states is that these are INTERPRETER-time capabilities: available to a lens or a witness reading the live tree, never to a declaration the compiler must emit. CARRIED CONSEQUENCE, not yet discharged in this commit: moving the two reflection seams changes their bridge FAMILY module key in gunbc.v1_interpreter_primitive_surface (v2.std.node / v2.std.node_query -> v2.std.node_reflection). is_v4_bridge_family matches on the item registry's module name, so this is inert until stage0 is regenerated; the regen lands on top of XL-0B's converged seed. EVIDENCE. v2.test.claim.target_model_external_authority_decode round-trips EVERY declared scheme through bundle-then-decode (a roster short by one arm reds on its own row), asserts that an unnamed discriminant REFUSES rather than defaulting to an arm, and pairs that with a positive control over the identical hand-built node shape so a shape-caused refusal cannot pass for the discriminant check. The price of a declared roster is a second statement of the arms, so v2.test.manual.coproduct_reflection_conformance now walls the drift both directions by bag equality against reflected arm keys, with a non-emptiness control so an empty reflection cannot green it vacuously. * C corrected: InferredTree.facts stays the open PartialFunction; PartialFunction realizes as its algebra struct everywhere (HashMap rows deleted); frontier row dissolved; two TargetChanged admissions The CI floor on 4da6059 showed the facts retyping over-reached: about 120 test and fixture sites plus program.dag / 05_emit_orchestration define InferredTree.facts by a predicate closure, which is exactly what the open carrier is for. inferred_tree / 04_infer / program_partition are restored. The fork was the emitter realizing PartialFunction as HashMap in signature position and as the algebra struct in field position; the PartialFunction HashMap rows in extdeps.languages.rust (types.dag row, the partial_function template) are deleted so one representation stands. EvaluationEnvironment.bindings stays Map (built by map_insert); v2_effect_io_pure's empty environment is empty_map(). The v1 unresolved_method_frontier row for target_model lookup / Primitive(T) is deleted: the slots.lookup -> map_lookup rewrite dissolved its one occurrence. The two TargetChanged binding deltas for admission_from_module_root (frontier_probe, compile_door_ledger) are admitted by exact subject in namespace_wave_admission.rs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: operand realization hops alias/refinement declarations to their target (NonEmptyStr, Char, VersionIdentity compare/add as their host targets) * Move the two reflection bridge arms onto one v2.std.node_reflection family in the hand-maintained dispatch macro `is_v4_bridge_family` decides a bridge by comparing the ITEM REGISTRY'S MODULE NAME against a literal in `v1_bridge_family_arms!`, so relocating resolve_type_node and coproduct_nullary_inhabitants into v2.std.node_reflection is inert in the interpreter until this literal moves with them. Left unmoved, both calls fall past the bridge to `ctx.lookup_fn`, reach their own .dag self-call declaration, and recurse -- green typecheck, no diagnostic, wrong behaviour, which is the exact shape §5 forbids. The two former families collapse into one because they now share a module: `distinct_dispatch_sites` in gunbc.v1_interpreter_dispatch_emit dedups sites by module key and `render_site_block` selects that site's rows wherever they sit in the roster, so the generated surface is a single EvalCallBridgeStdNodeReflectionArm with both variants regardless of the two rows not being adjacent. WHY THIS FILE IS HAND-EDITED AND WHAT THAT COSTS, stated rather than glossed. The family's enum, lookup fn and arm-macro names are DERIVED from `EvalCallBridgeFamilySite.module` by module_slug_after_domain_prefix / module_pascal_after_domain_prefix, so naming them wrongly here does not compile: the generated symbols simply do not exist. The module LITERAL beside them is not derived -- it is a second representation of the same roster field, and a literal that disagrees with the roster while the derived names agree is writable and nothing refuses it. That is a §3 fork in the seed's realization, not a defect this change introduces, and it is named here because this change is the first one to move the field and therefore the first to depend on the fork holding. * XL-0E: parenthesize bare-variant comparisons in if-conditions (Variant-brace parses as record literal); flatten wall helpers to top-level fns Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror for A1 + C (aa373f9): byte fixed point at round 3 Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, extdeps_languages_rust_types, std_primitive_projection, v1_compiler_emit_rust, v1_compiler_infer), round 2 only compiler_tests.rs, round 3 byte-identical; installed tree f53efd0d0173a43e, gunbc 1a2d53dd15920cf1. Unit 552/0. Emitted closure cargo check 392 -> 278; line-insensitive identity diff vs commit 2: 112 removed, 0 added. Batteries on the converged binary: 29/29 (the two C rows red on the pre-fix compiler by fixture emit), 14/14, 20/20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: Bool row -- KernelBoolLiteral into v2.std.logic.Bool via BooleanUnfold (True/False); interpreter evaluates an elaborated literal as its kernel value; falsifier pair (row found/removed in the interpreter, constructor image vs host keyword on the emitted path) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0E regen: stage0 mirror at byte fixed point with the equality admission wall active; census repairs (native-realization leaves admit via decl_file_realizes_natively, presence exemption reads the expression spelling) Regen transaction (local, this worktree): round 1 emitted from the committed pre-wall mirror; candidate applied; rebuilt compiler carries the wall; its corpus census surfaced exactly 10 refusals, all EqualityMemberUnjudgeable false positives in two classes -- dag std Nat (native-realized scalar alias, now admitted through the coercion authority's identity-keyed decl_file_realizes_natively, fail-closed on unknown identity) and bare '!= Absent' presence tests whose exemption now reads the operand expression spelling. Round 2: first_generation_equal=true, exit 0 -- byte fixed point with the wall live and zero corpus refusals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * XL-0N: operand realization hops alias items by is_type_alias_item/resolved_type (the derive lane's own test) -- the structural condition on the declaration node never held, so NonEmptyStr/Char/VersionIdentity host ops were refused in the regenerated compiler Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Commit 3 of the #9664 closure: six emitter mechanisms, the null keyword by path, and map_insert back to its .dag body under the gate's ruling Emitter (src/v1/05_emit_rust.dag, trait_derive_emit.dag), each with a discriminating row in self_host_emitted_call_target_realization_witness_test (pre-fix bytes observed on the seed): - an argument into a parameter spelled Optional<T> is not unwrapped (the cardinality flag marks only the T? sugar; the applied spelling is asked too) - the shared-field accessor impl of a generic coproduct carries T: Clone - a Violates literal in a record field takes the field's Witness carrier before the fn return - a record pattern over a shared carrier derefs like a shared enum's variant pattern - a fn returning an arrow-field record carries 'static on its generics (same gate as impl Fn) - the fn-field record header prints well-formedness bounds asked per parameter instead of the bounded set minus the seed set (FalsificationReceipt<Subj, A> lost A behind ValueDiff<A: Clone>) - extdeps.languages.rust emit: the null keyword is std::option::Option::None, because a module declaring a nullary variant named None emits pub struct None; at module scope (std.cache_interface) v2.std.collection: map_insert is its .dag body again and map_insert_primitive_delegate with its primitive_projection row is deleted. The delegate tripped map_carrier_shape_gate on CI at c6d9b22 (record_shaped_map_reaches_map_insert BUDGET-REFUSED): the interpreter's free_call.map_insert arm answers Ok(None) for a non-native shape and the grounding falls through to the delegate's own body, a self-call -- the deferred-refusal class #8887 filed. The closing move is a host fact (a typed refusal in try_v2_std_collection_map_primitive_grounding) and is ledgered in the PR body, not landed here, by the manager's ruling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Hoist commit-3 rationale annotations to module-item grain (§4c refuses in-body // blocks; 17 regen refusals on 780b394) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: operand realization reads the RESOLVED structure -- a NoConnective childless leaf whose structural name is a kernel type is a host operand (the resolver collapses NonEmptyStr/Char/VersionIdentity to their primitive RHS under the alias identity, so no resolved node is ever an alias item); refusal temporarily carries the operand's shape facts for the regen diagnosis Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: shape-facts suffix spells Int counts with to_string (the seed runtime has no Int-as-String cast; the cast panicked the emitter under regen) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: operand realization hops a where-refinement wrapper to its base (is_where_refinement_type, the type renderer's own route) -- measured under regen: NonEmptyStr/Char/VersionIdentity operands resolve to the one-child Conj refinement node, not a leaf or an alias item Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: operator realization matches over BinOp are total (14 closed variants enumerated) -- no non-fold residue rows for the new module Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Commit 3 correction after the first regen: withdraw the Violates field-carrier arm (the literal resolves to the Witness declaration, spelling Witness::<Holds> at 87 sites), 'static on generics only for fn-field record returns (compose<A, B, C> stays bare), re-pin the optional and shared-record rows Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror: the reflection bridge family, the UriScheme roster, and the two projections main and the stack both moved Four generated files, from three distinct authorities, all owed by this stack: v1_interpreter_dispatch_generated.rs the bridge family moves to v2.std.node_reflection -- one EvalCallBridgeStdNodeReflectionArm with both variants, replacing the separate StdNode and StdNodeQuery families extdeps_uri.rs uri_scheme_inhabitants, the declared roster the target_model decode folds v1_compiler_emit_rust.rs the projection whose bytes the merge v1_compiler_infer.rs driver refused to resolve by hand THE TWO MERGE-DRIVER REFUSALS ARE RESOLVED HERE AND NOWHERE ELSE. Both files were left UNMERGED by merge.generated-artifact across the two main merges, carrying the ours side verbatim with no conflict markers, precisely so the regenerators would run against them. Picking a side would have dropped the other side's authority-derived bytes with nothing in the tree to say so; these bytes are the projection of the MERGED authorities, produced by the emitter, not chosen. WHAT THIS UNBLOCKS. The bridge family literal landed one commit earlier and was inert until now: is_v4_bridge_family matches the item registry's module name, and the generated lookup fn it names did not exist, so every head since has failed to compile on E0425 -- four red checks with one cause. The seed now defines lookup_eval_call_bridge_std_node_reflection and the hand macro resolves against it. MEASURED, NOT ASSUMED. An earlier run of this same loop reported convergence that had not happened, because two of its steps failed open: main_wet was OOM-killed on a 7 GiB runner while the script printed its success marker regardless, and the post-restore rebuild failed while `test -x` passed on the stale binary from the previous build -- so the rounds that followed, and a fixed_point_equal=true, were produced by a compiler that did not carry this change. Those readings are discarded. This run checks every step's real exit code, and runs on a 20 GiB runner with the memory budget declared BELOW the box rather than above it, which is why main_wet completed and regenerated the dispatch surface at all. STILL OWED, and deliberately not claimed by this commit: a clean regen round and the fixed point from a compiler rebuilt off this installed tree, and the emitted-closure census. * XL-0N: retire the regen-diagnosis shape-facts suffix -- the where-refinement hop is confirmed at byte fixed point (6ba83b3 regen, round 2 equal) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Rehome the layer scan out of the lens registry, declare the two reference-derived reflection imports, and adjudicate the 56 relocation bindings Three findings from the floor, one mistake and two consequences of the relocation working as designed. THE MISTAKE: layer_import_facts_live was homed at v2.lens.layer_import_scan because its only consumers are two lenses. That put a NON-LENS module inside the population v2.lens.enforcement.lens_module_gate and the declarations phase read as the lens registry's subject, and both refused it correctly: declarations FAIL LENS-AUTHORSHIP-ABSENT src/v2/lens/layer_import_scan.dag: lens `v2.lens.layer_import_scan` declares no `construction_justification` plus lens_module_gate_holds_live and lens_closure_question_zero_holds_live. A producer CONSUMED BY lenses is not a lens. It is now v2.std.layer_import_scan. Closure membership is decided by REFERENCE, not by directory (DESIGN §3: paths are discriminators, not gospel), so the seam stays out of the compile closure from either home -- only the lens registry's population was sensitive to which, which is exactly why the gate and not the emitter caught this. THE SECOND: v2.test.generated.cross_representation_equality and v2.test.lens_wiring_liveness.wiring_liveness_test carry no imports at all and resolved coproduct_arm_keys / resolve_type_node through the reference-derived closure. That worked while those names sat in modules every run already loaded. Segregating them into a module NOTHING in the closure imports is the point of the change, so the run stops loading it and the reference has to be declared: FAIL v2.test.manual.value_null_split_witness... errored: no declaration named 'coproduct_arm_keys' in this execution's loaded index Two import lines, not a relaxation of the split. THE THIRD: 56 TargetChanged binding deltas, one per (module, declaration, spelling) triple whose home moved. Every row names one exact subject with blast radius 0, so a binding this change did not intend still refuses; none admits a module, a prefix or a spelling in general. The count is 56 rather than 8 because the read-through moved a type, two variants and a function that eight consumers each reference from several declarations. They dissolve when this stack merges, by the same trigger every shrink in that file was removed under. WHAT THE FLOOR ALREADY CONFIRMED, and why these are the only three: all 14 changed witnesses passed, including the four target_model_external_authority_decode rows and both UriScheme roster-drift rows. The conformance rows CALL reflection, so they could only pass if the bridge family move routes -- the seam relocation is green by execution, not by inspection. * XL-0N: regenerated stage0 mirrors at byte fixed point (070a203 source, BuildBuddy regen round 3 first_generation_equal=true; partition crates rendered=14 written=0) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: register std.literal_elaboration and std.operator_realization in the std-core partition and gunbc.structural_realization_bindings in the v1-infer binding unit (v2.workflow.rust_crate_partition), with their module-dag edges Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: type_reference_declaration_ref resolves an in-place (recursive) type reference through its env binding before matching the declaration span -- v2.std.nat.Nat is recursive and answered Absent, so its literal boundary and operand identity fell to the unavailable arms while v2.std.logic.Bool worked Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Regenerate the stage0 mirror at b115892: byte fixed point at round 3 (installed 9d44564232ba8648, gunbc eaf00f8d92931968) Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, std_primitive_projection, v1_compiler_emit_rust, v1_compiler_infer, v1_compiler_trait_derive_emit); round 2 the whole population through the new emitter (std::option::Option::None, 'static on fn-field record returns, per-parameter well-formedness bounds); round 3 byte-equal. Unit 566/0. Emitted v2 closure cargo check 278 -> 258: 23 identities removed (8 optional-unwrap, 6 accessor &T, 5 record deref, None capture, A: Clone, both E0310), 3 added -- the map_insert body's own rows at v2_std_collection, the ruled cost of withdrawing the delegate. Batteries 35/35, 14/14, 20/20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Bootstrap the two conflicted projections from the converged side so a compiler can be built to regenerate them NOT A RESOLUTION OF THE MERGE, AND NOT BYTES ANYONE SHOULD READ AS AUTHORITATIVE. merge.generated-artifact left v1_compiler_emit_rust.rs and v1_compiler_infer.rs UNMERGED across the 3af83d9 merge, carrying the ours side verbatim so the regenerators could run against them. That is the prescribed flow and it is what the previous commit did -- but the ours side predates a signature change 3af83d9 made to the emit_rust authority, so the merged tree does not compile: error[E0061]: v1_item_wf_propagated_clone_bounded_param_names ... provide the argument error: could not compile `v1-compiler` and a regenerator needs a building compiler. Neither side's bytes are the projection of the merged authorities, so this is a choice between two wrong seeds, and the only property that matters for a BOOTSTRAP is which one compiles. The converged side does; ours does not. WHAT THIS COMMIT IS NOT: it is not "picking a side" in the sense the merge driver forbids. Picking a side as the ANSWER would leave the tree authority-ahead-of- artifact with nothing to say so. These bytes are transient scaffolding for one build, immediately overwritten by the regen commit that follows, which derives them from the merged authorities -- my source change and theirs together. If that regen does not land, this commit is wrong and the drift gate says so on the very next run, which is the property that makes the interim safe to take rather than a silent substitution. * w_fn_field_record_header_keeps_the_bound_a_field_type_demands: a local fn-field type instead of the host_run closure (30 s CPU per floor fill, false through the shared-artifact path on 3af83d9); same discriminating bytes on the seed (R6<Subj, A>) and the converged compiler (R6<Subj, A: Clone>) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * std.cache_interface: the three .first() producers are Optional at the declaration (cache_facts_for_id, cache_reach_candidate_probe, cache_layer_plan_primary/fallback); every consumer matches -- a layer with no catalog facts neither beats recompute nor respects locality (typed false, no fabricated facts); planner test matches the projections Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: regenerated stage0 mirrors at byte fixed point on e51aff9 (BuildBuddy regen round 3 first_generation_equal=true; includes the merged #9710 commit-3 null-keyword-by-path drift and the new-module mirrors) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Model rustc phases and derive the self-host phase board * XL-0E: close the RuntimeValue equality leak — same-identity peel chase dispatches into declaration structure instead of re-entering the visited check Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * XL-0E: wildcard-free runtime_value_equality dispatch (nfr roster) and drop body comment (DESIGN 4c) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Root compile-phase board in the self-host frontier * Delete provisional emission-board authority after root cut * Strengthen compile-phase receipts as a linked subject ledger * XL-0N: type_reference_declaration_ref falls back to the module-visible name binding when the reference carries no ident-keyed binding (the emitter's scope env) -- the found declaration is still span-matched against the global roster, so a by-name hit only confirms an exact declaration; measured: Peano literal rows passed while the operator rows still lost Nat's identity Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * The host optional's variant spellings, one authority: six inline Some/None sites read rust_optional_variant_spelling, which qualifies None by path (a bare None PATTERN in std.cache_interface bound the module's pub struct None; five arms on the first regen); row w_absent_pattern_survives_a_module_declaring_a_none_variant Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Persist the first compile-phase diagnostic population * Fix frontier identity folding and literal diagnostics * XL-0E: regen merged tree to byte fixed point (round m2 first_generation_equal=true); re-judge the RuntimeValue witness row on the #9724 finite-Map model — the live subject now asserts admission as the over-refusal control Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Observe parse and cargo-check phases in one instrument run * Tighten compile-phase receipt epochs and identity semantics * Bind frontier receipts to complete instrument observations * Make compile-phase receipt populations structurally derivable * Regenerate the stage0 mirror at d20440d: byte fixed point at round 3 (installed 1b8ca70c9dbf62bc, gunbc deabfe3085a2d289) Round 1 changed v1_compiler_emit_rust; round 2 the population through the qualified None spelling; round 3 byte-equal. Unit 575/0. Emitted v2 closure cargo check 244 -> 239, typeck phase: the five None-in-pattern-position rows at std_cache_interface removed, nothing added (the two re-keyed rows differ only by column). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Require dispositions for every newly exposed phase identity * Bootstrap the XL-0E merge: the four driver-refused mirrors take XL-0E's converged bytes (the ours side lacked EqualityOnFunctionMember/EqualityMemberUnjudgeable that its non-conflicting mirrors reference; seed did not build); regen round 1 re-applies the None-spelling emitter change Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Persist and project the compile-phase frontier genesis * XL-0E floor fixes: emit_host consumes the typed accepted_runtime_value_outcome_equality verdict (name main's #9727 imported no longer existed); empty-list literal comparison exempt as the emptiness idiom beside '== none'; regen to byte fixed point (round n2) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror at 03f1631 (XL-0E integrated): byte fixed point at round 3 (installed 2be25adfee989956, gunbc 37b1266cb05babf4) Round 1 re-applied the qualified None spelling over the bootstrap pick of XL-0E's four mirrors; round 2 the remaining population; round 3 byte-equal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Materialize each emission measurement exactly once * Rc-field arm grouping picks a representative by plain-binding subset, not outer-pattern bytes: two arms of one record that differ only on a plain binding lower to one nested match instead of two guarded arms (E0004 x2, rustc cannot see a guard) rc_group_is_whole_coverage required byte-equal outer patterns, so Edge { label: Named {..}, target: magnitude } beside Edge { label: Positional, target: _ } fell back to the #8570 guard form on both arms, which rustc reports as non-exhaustive (E0004 at v2.extdeps.languages.dag and v2.std.compilers.target_model, xl0b9 board). The group now takes the outer pattern of the member whose plain bindings are a superset of every other member's (same field, same identifier), which selects the same values; any refutable plain field, second Rc-bound field, or authored guard still keeps the guards. Witness: w_record_arms_differing_only_in_plain_bindings_group_into_a_nested_match (RED on 37b1266c: emits the guard form, measured by direct emission). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A record-literal field value is emitted under the field's declared type, not the fn return: EmitGraphInfo.expected_type at expression grain; the Violates type argument reads it (E0308 x5, Witness at a Witness<Node>/Witness<InferredFacts> field) rust_witness_type_arg_from_fn_return answered a Violates literal with the enclosing fn's return carrier wherever it sat, so the four RuntimeValueAcceptanceWitness fields at v2.compiler.eval and the Rejected arm at v2.compiler.compile rendered Witness::<Rc<RuntimeValueAcceptanceWitness>>::Violates against fields declared Witness<Node> / Witness<InferredFacts>. fn_return_type stays the fn-grain fact (rust_declared_return_is_callable reads it); the new expected_type is the expression-grain fact: seeded by emit_info_with_fn_return, re-seeded by emit_field_value_with_context with the field's declared type node (record_field_expected_type), cleared when no declaration names the field. Witness: w_violates_at_a_record_field_takes_the_fields_declared_carrier. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A type argument inside a record field's type expression reads its declaring module from the env binding: std.nat.Nat at Measure<Time, S, Nat> rendered Rc<Nat> in the struct and i64 in every signature (E0308 x8, E0369 x1) Field type expressions carry no resolved inference, so type_reference_decl_file fell back to the REFERENCE's file and the native-alias row (dag/std/nat.dag -> i64) could not fire; the shared wrap then rendered the argument as Rc<Nat>. type_reference_decl_file_in_env resolves the leaf through lookup_type_by_name and accepts the binding only when the declaration is named by the leaf (an alias RHS never stands in for the alias); the two checkpoint-spelling queries that already carry env consume it. Witness: w_native_alias_type_argument_at_a_generic_field_renders_the_machine_scalar (the must line is provisional until the RED probe prints the current rendering; refined in the regen commit if the wrap differs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.c…
briansrls
pushed a commit
that referenced
this pull request
Aug 31, 2026
… an unreachable prelude (#9803) * Emitted v2 compiler crate: a declaration's identity is its last segment, and a primitive with no realization refuses instead of inventing one Two roots behind 175 of the 260 rustc errors on the emitted v2 compiler closure (issue #9664, milestones 1 and 2): - 102 x E0425: the four DeclaredCallableIdentity constructions in v1.compiler.infer_lookup took decl_name from the AUTHORED spelling, so a qualified call carried the whole dotted path as the declaration name and emission rendered crate::v2_std_grammar::v2.std.grammar.f(..). - 73 x E0425: v2.std.algebra length is a ModeledProjection of the `length` primitive and rt_function_registry has no `length` row, so emission took rust_runtime_bridge_name's identity arm and wrote v1_rt::length -- a symbol the seed does not define. A primitive's identity and its per-target realization are two facts; CallTargetIdentity carried only the first, so every emitter had to ASSUME a bridge exists. RuntimePrimitiveCall now carries projected_from, the declaration the roster projected it from, and emit_rust routes to the bridge only when its own registry holds the primitive, falls back to the declaration otherwise, and refuses when neither exists. DeclaredCallableIdentity moves to v1.std.core so the target type can carry it without forking the pair. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Class B: the algebra method fallback asserted a v1_rt bridge it had not checked tier0 method resolution resolves an ordinary fn-typed RECORD FIELD through lookup_field_in_product, so `algebra.step(..)` arrives as AlgebraMethodSemantics carrying the field node as its method_def. The fallback at the end of that arm hardcoded runtime_bridge: true, which emitted `v1_rt::step` -- and made emit_rust_generic_method_call's own callable-field arm, guarded on runtime_bridge == false, unreachable for the exact receiver it was written for. 65 E0425s on the emitted v2 compiler closure (member, apply, is_empty, step, init, allocate_literal, ...) were that one literal. It now passes the realization question keyed on the same registry as the plain-call seam, so a real bridge method still lowers to a bridge, a callable field lowers as a field, and a name that is neither reaches the existing loud refusal rather than a fabricated symbol. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Only ModeledProjection carries projected_from: a HostRealizedSeam body is a self-call, so falling back to it would emit a nonterminating function The declaration fallback is sound only where the declaration's body is real code. HostRealizedSeam means the body IS a self-call, so emitting it compiles and then loops forever -- silent wrongness, strictly worse than the unresolved symbol it would have replaced. A seam whose target has no realization has no honest lowering, so it carries nothing and reaches emission's refusal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * M1: realize the two symbol bridges, which were host seams nothing declared to be host seams v2.std.compilers.lexing symbol_lexeme and symbol_intern_lexeme have self-call bodies -- the HostRealizedSeam shape exactly -- and the interpreter has carried real arms for both (v4_bridge.symbol_lexeme, v4_bridge.symbol_intern_lexeme). With no projection roster row the resolver saw ordinary declarations, so Rust emission emitted the declaration, and pub fn symbol_lexeme(sym: String) -> String { symbol_lexeme(sym) } COMPILES. The emitted closure carried two functions that type-check, pass every gate we own, and diverge from the interpreter by not terminating. Unlike the sibling seams (decl_facts and friends, which at least refuse loudly as unresolved v1_rt symbols) nothing anywhere reported this one -- it is absent from the E0425 census precisely because it is silent. extdeps.languages.rust.types already declares Symbol's target type as String, so on this target both bridges are the identity. That is a realization of the declared row, not a second opinion about it. Residue named, not closed: a self-call body is a DECIDABLE structural marker of a host seam, so the compiler could refuse an unrealized one rather than emit it. It does not yet; that check is the class's next-rung trigger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror for the emitter repairs (fixed point at round 2) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * test.claim fixtures: one discriminating RED per closed emission class, with boundary controls Six rows over the three emitter defects plus the two symbol bridges. Each class's positive and negative assertion differ only in the fact the repair added, so no single edit satisfies both directions, and each repair carries a boundary control that would go red had it over-reached the other way (empty_map for the registry gate, a registered bridge method for the class-B gate). The symbol-bridge row is deliberately not an error-count assertion: that class COMPILED throughout the defect and diverged by not terminating, so a row asserting 'no error' would have been green the whole time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Fix the class-B boundary control: count has a method template, so it never reaches the seam under repair count is answered by rust_simple_method_specs before the algebra fallback, so the row would have gone red while executing none of the code the repair touched. trim is in rt_function_registry and has no template, so it is one of the few names that actually reaches that fallback. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Unbreak the fixture parse: a trailing semicolon on the note declaration The module index refused the file outright, so none of the six witnesses were discovered. .dag item declarations carry no terminator. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The self-call seam wall: an unrealized host seam refuses instead of emitting compiling recursion A whole-body self-call is the decidable structural marker of a host seam. In the interpreter the shape is safe -- reaching it recurses to the evaluation-budget refusal -- but emitted to Rust the same shape COMPILES and returns to no caller. Nothing reported it: not the module index, not the compile-clean gate, not cargo check. That is why the two symbol bridges were invisible until someone read the emitted bytes. emit_fn_def now asks the realization registry -- the same authority the call sites ask, so the two cannot drift -- and suppresses the declaration when the seam is realized, refuses with a located message when it is not. Suppression rather than delegation is deliberate: a forwarding body would make this seam reconstruct signatures in target types, which is the cementing the existing suppressed-seam precedent avoids, and a realized primitive's calls all route to the bridge anyway. The predicate is whole-body identity, not 'contains a self-call'. Ordinary recursion has a match, an if or a let between the head and the call, so it never matches; expr_has_self_call walks children and would have refused most of the compiler. Both directions carry a fixture. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam wall must resolve realization through the roster's primitive, not the declaration name Measured, not predicted: the wall refused six seams in the emitted closure and one of them -- v2.std.collection empty_map_primitive_delegate -- is realized. Its roster row names the empty_map primitive, whose bridge is rc_empty_map, but rt_function_registry holds 'empty_map' and the wall looked up 'empty_map_primitive_delegate'. A declaration's name and the primitive it realizes are two facts; the roster is the authority that joins them, and the declaration name is only the fallback for a seam nobody has rostered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam wall's realized arm must not suppress the declaration: suppression created 10 dangling imports Measured on the emitted closure with the wall finally in the mirror: removing a realized seam's item left 10 unresolved imports (E0432) for symbol_lexeme, symbol_intern_lexeme and resolve_type_node. Other modules import these declarations; the suppression created that breakage rather than finding it. And the reasoning that made suppression look safe is what makes it unnecessary. A realized seam's body IS a call to itself, and resolution already routes that call through the roster to the bridge -- so ordinary emission writes v1_rt::symbol_lexeme(sym) as the body without help. The wall's whole job is the UNREALIZED arm. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The seam refusal is a generated body, not a crate-wide compile_error!: rustc's denominator is larger than the demand denominator compile_error! fails the WHOLE crate, and that form silently assumes every seam it refuses is one somebody calls. It is not. rustc type-checks the entire emitted crate including declarations imported but never invoked, so the refusal denominator is strictly larger than the entry-reachable execution closure -- five unreachable seams took the crate down. The refusal is now a panic body with the declaration's real signature: dependent modules resolve, the crate compiles, and only an actual invocation fails loudly. That moves the refusal from the crate to the one declaration that earned it, and leaves reachability to a separate instrument. An entry-rooted pruner can replace the body later without revisiting this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Two obligations the required floor found, both real consequences of this change DETERMINISM DENOMINATOR (9 reach_witness rows red, including determinism_denominator_is_closed_on_declared_primitives, whose entire job is to notice this). v2.lens.determinism closes its denominator over primitive_declared_definitions, so adding two canonical names without traversal facts made the closure false. Both bridges are scalar -- symbol_lexeme maps one Symbol to its text and symbol_intern_lexeme is its inverse -- so there is no collection to walk and OrderFreeResult is the honest arm. HostUnspecifiedOrder would claim a real traversal whose order the host does not pin, fabricating a leak the primitive cannot have. NAMESPACE WAVE ADMISSION (6 unadjudicated deltas). Four are TargetChanged for DeclaredCallableIdentity moving v1.compiler.infer_sigs -> v1.std.core, which is what lets CallTargetIdentity carry the declaration a runtime target was projected from. infer_sigs imports v1.std.core, so the type could not stay put without a cycle. Four enumerated rows, one per binding site; the two membership deltas auto-admit as ExplicitlyEvaluatedZeroDelta. Dissolve-on: this PR merging, by the same trigger the three prior shrinks record. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Class-C fixture was broken, not the repair: the witness pool is smaller than the corpus The row FAILED while the mechanism was green. The probe used the qualified spelling without importing v2.std.collection, which resolves against the real 4261-module corpus but not against compile_dag_rust_emit_check's 2973-module witness pool. Measured both ways: emitted against the corpus the same probe produces crate::v2_std_collection::map_get(m.clone(), "key".to_string()), exactly what the row asserts. The import restores module presence and does not answer the call -- decl_name comes from the authored spelling at the call site regardless of imports -- so the negative assertion still discriminates. Falsifier 2 is what proves that rather than argues it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * is_empty: a conversion is not a repair -- give it the Rust realization it never had Before the class-B change, xs |> is_empty emitted v1_rt::is_empty, a symbol the seed does not define: 5 x E0425. After it, the same 5 sites became typed refusals -- correct in kind, still 5 errors. The class-B repair made the gap visible; it did not close it. is_empty is an algebra template over FreeMonoid whose Rust realization is Vec::is_empty, exactly as count's is Vec::len, so the fix is one row in rust_simple_method_specs beside count. Nothing in 05_emit_rust learns a new name: realization is a target fact and lives in the target's registry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A receiver's own callable field outranks every name-keyed table: class B survived one layer up The requested is_empty negative control found a live hole rather than confirming a safe one. Both rust_method_templates lookups are keyed on the bare method spelling with no receiver check, so a fn-typed record field named is_empty was captured by the target template and emitted as recv.is_empty() instead of (recv.is_empty)(..). The class-B repair fixed the algebra FALLBACK and left the two tables sitting in front of it. The hole is not new and is not specific to is_empty: count, first, join, split, take, skip, last, chars and enumerate have carried it for as long as they have had templates. Adding is_empty made it urgent by putting the spelling most likely to name a predicate field in front of that table. One helper, consulted at the top of both arms before every name-keyed special case, so the two cannot drift. Two controls: the new spelling and a pre-existing one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Two more wave admissions: the declaring module rebinds too v1.compiler.infer_sigs used to DECLARE DeclaredCallableIdentity, so its own two construction sites resolved locally and produced no delta. Now that the declaration lives in v1.std.core and infer_sigs imports it, those sites rebind exactly like the consumers in infer_lookup. An enumeration error on my part, not a second transition: same subject, same trigger, same dissolve. Floor is now green on this branch (passed=2754 failed=0) -- the OrderFreeResult traversal facts closed all nine determinism rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * The callable-field tier was consuming the algebra profile's identity domain, not the receiver's: 202 refusals on the first compile of the converged seed rust_receiver_has_callable_method_field asked rust_record_field_needs_fn_rc, which sweeps rust_struct_field_lookup_candidates -- and that list deliberately widens a receiver's name to its container template algebra. An algebra declares its operations as arrow-typed members, so under that widening every Map receiver "has a callable field" named map_keys, map_values, lookup or get, and the tier captured the very bridge calls it sits in front of. Measured at the first compile of the round-3 converged mirror: 202 rustc refusals, one class -- 164 E0609 (no field `map_keys` on Rc<im::HashMap<String, Rc<ItemInfo>>> and friends), 48 E0282, 4 E0615 on `get`. It is the same defect the tier was built to close, one level up: a name-keyed lookup consuming an identity domain that is not its own. The predicate now consults only the receiver's own declared record. w_map_receiver_operation_is_not_read_as_a_callable_field is the discriminating red: restore the candidate sweep and its must_not_contain clause fires. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror at the merge-equivalent tree: byte fixed point at round 3, six paths, each explained by an authority change Convergence transaction on srv1 (/tmp/xl0c.sh -> /tmp/xl0g.log), on 952ffa6 = main b726547 merged with the branch. Criterion is BYTE equality (sha256 over the whole candidate tree vs the whole installed tree), never first_generation_equal and never the changed-path list; the full workspace is rebuilt inside every round so a non-compiling mirror stops the line. round 1 cand e212fe74 inst 6f55cf3e installed, compiles round 2 cand 932b0543 inst e212fe74 drift = v1_rt.rs only (the two-hop: v1_rt.rs is rendered by the previously compiled rt_hash_ops) round 3 cand 932b0543 inst 932b0543 BYTE FIXED POINT -- produced by a compiler rebuilt from the round-2 installed tree Changed paths and their authority: extdeps_languages_rust_emit.rs <- rt_function_registry / rust_simple_method_specs rows std_primitive_projection.rs <- symbol_lexeme / symbol_intern_lexeme roster rows v1_compiler_emit_rust.rs <- 05_emit_rust.dag (seam wall, callable-field tier, class B/C) v1_compiler_infer.rs <- 04_infer.dag projected_from on RuntimePrimitiveCall v1_compiler_runtime_rust.rs <- runtime_rust.dag symbol bridges v1_rt.rs <- same, one hop later On these bytes: function_value_named_application_controls_witness PASSES (the d805243 / 952ffa6 rust-unit-tests red was the merge-driver-refused stale v1_compiler_infer.rs, not a semantic regression); emit 175 files; cargo check 15 errors: 9 E0425 (filesystem 2, V 2, K 2, Determinism 2, T 1), 2 E0728, 2 E0107, 1 E0391, 1 UNRESOLVED_CompilerError. No hand edit to any generated file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * WIP tail classes * WIP: if-equals-variant parses as a record literal; name the predicate * WIP: annotations at module-item grain * Regen round 1 (BuildBuddy invocation ebbdffc5, compiler gunbc=9830014a4e965ddb built from the committed mirror): v1_compiler_emit_rust.rs regenerated; candidate patch sha 05ce734c52890571 * Regen round 2 (BuildBuddy, compiler gunbc=75d74698aebcdb6e built from installed ce959e40604ffdd5): std_algebra.rs, std_nat.rs -- arrow returns now render through the Rust renderer (Rc<Vec<K>> for List<K>, Nat preserved); candidate patch sha b5b409aeebbeb6c4 * Arrow positions deviate from the generic renderer only for the two defect shapes: the unconditioned route emitted 2790 refusals where 15 stood; fix the arrow probe's variant spelling * B: the init turbofish declines a declaration's own formals by the lambda's admission; F: a qualified type reference earns its use-line from the qualifier under export proof; both earlier cuts were measured non-events and are deleted * Regenerate the stage0 mirror at the 0773184 freeze: byte fixed point at round 3, three paths, each explained by an authority change srv1 (/tmp/xl0e.sh -> /tmp/xl0j.log), criterion = every regen-population file byte-equal to installed; full workspace rebuilt as the gate each round. round 1 gunbc=1dc61ba198c6750b from installed 0479b0df9fc5598e -> v1_compiler_emit_rust.rs round 2 gunbc=909aa212f353bd03 from installed 8ebedc7445fadbaa -> std_algebra.rs, v1_compiler_trait_derive_emit.rs round 3 gunbc=0d0cd70ec5b20db9 from installed 8713cb43f8ad848c -> <none> BYTE FIXED POINT v1_compiler_emit_rust.rs <- 05_emit_rust.dag (gated arrow position, init turbofish admission, qualified-type use-lines) std_algebra.rs <- the gated arrow route restores the pre-e9900e2 spelling of the two arrow-typed fields v1_compiler_trait_derive_emit.rs <- one use-line synthesized for a qualified std.types.List reference under export proof Final installed tree 8713cb43f8ad848c. No hand edit to any generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * One renderer for every arrow position; a type position never takes the variant arm; the qualified route synthesizes use-lines only for types the emitted source names Four regressions the 0773184 fixed point put on the closure, each with its discriminating row: - E0603 x16: the qualified-type route synthesized `pub use crate::v2_std_nat::Succ;` for every `v2.std.nat.Succ { prev: .. }` record literal. A qualified name reaches the surface walk in the same dotted spelling whether it is a type or a variant head; the route now asks the registry whether the leaf is a TYPE declared in the named qualifier, records each decision as a census row, and considers only leaves the emitted source actually names (it had also synthesized an unused `DeclarationRef` import from a variant payload). w_qualified_variant_head_earns_no_type_use_line. - `Outcome<compile_error!("UNRESOLVED_CompilerError")>` x3 and `Rc<Medium>` E0107: two cuts had each introduced a second per-position renderer for arrow types beside the one fn parameters use. An arrow's return is not a different kind of type from its parameter: both positions now render through render_rust_fn_sig_type, and render_rust_type_with_applied_binding -- which rebuilt its EmitGraphInfo with an empty generic scope, so a fn-scope `C` rendered `_` (E0121) -- carries the fn's generic names through that hop. The measured gate over the second renderer is deleted. w_generic_arrow_return_renders_the_fn_scope_generic; w_arrow_return_type_keeps_its_applied_binding (its fixture was an invalid program: Accepted lacked `diagnostics`). - v2.std.determinism E0425 x2: traced to the bare-name disposition, not the qualified route -- `Determinism` is a type in std.determinism and a variant of v2.lens.registry LensIdV0, and is_known_variant is corpus-wide by spelling, so a TYPE-position reference was delegated to an enum it never named. A name in one of the module's type positions never takes the variant arm. a_known_variant_spelling_in_a_type_position_takes_the_registry_arm (red by construction on the old arm); the harness row is a positive control and says so, because the witness harness refuses any pool carrying the colliding variant with NoSuchVariable. Verified on a test binary built from the self-emitted emitter (not a regeneration): witnesses 23/24 -> 24/24 after the harness row was reshaped; closure instrument 2799 -> 2779. The regeneration that binds these to the mirror follows as its own commit after the freeze merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror at the 49482b0 freeze: byte fixed point at round 3, three paths, each explained by an authority change srv1 (/tmp/xl0e2.sh -> /tmp/xl0j2.log, launched 2026-08-29T19:52:56Z), criterion = every regen-population file byte-equal to installed; the full workspace rebuilt as the gate each round. round 1 gunbc=14967ca810cb6609 from installed db46176cc5cf5861 -> v1_compiler_emit_rust.rs, v1_tests_claim_reference_derived_disposition_census_witness_test.rs round 2 gunbc=5378a516528a6e0c from installed efa440bc86734f53 -> v1_compiler_trait_derive_emit.rs round 3 gunbc=974aafe864f743f6 from installed b1a0409ce9fc79d4 -> <none> BYTE FIXED POINT v1_compiler_emit_rust.rs <- 05_emit_rust.dag (arrow positions via the fn-signature renderer, generic scope through the applied-binding hop, type-position exemption, qualified rows with the registry type gate and token filter) v1_tests_claim_reference_derived_disposition_census_witness_test.rs <- its .dag (in_type_position at 5 callers + the type-position control) v1_compiler_trait_derive_emit.rs <- retracts the unused `pub use crate::std_types::List;` the earlier qualified route synthesized (token filter) Final installed tree b1a0409ce9fc79d4; merged tree 89c55a0e7e8d949047b5d92864dfc9fe306aebc0 at the freeze; main parent 5e80671. No hand edit to any generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Witness fixture only: the qualified-type positive control moves to a provider the harness pool can carry Post-freeze, fixture-only (dag/test/claim is not a regen-population path; a no-drift regen run on this head is recorded in the PR). Two harness facts, both measured on the fixed-point artifact gunbc=974aafe864f743f6: a `{Determinism}` inside a .dag string literal is read as an interpolation of that name (the row failed in the interpreter before any compile ran), and the harness pool is the probe's DECLARED import closure, so a provider referenced only by a dotted name is absent -- and std.determinism cannot enter it because its own body references std.perturbation the same way. The row now uses std.decl_ref with a sibling import and says plainly that it is a positive control; the class's discriminating red stays at the disposition grain (a_known_variant_spelling_in_a_type_position_takes_the_registry_arm) and in the closure count. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * WIP XL-0B commit 1: thread DeclarationRef into the checkpoint-spelling callers; exact binding first; delete the redundant expression-position alias arm * Enroll the two emission batteries under the required-gate seed prefix (test.claim.self_host_*) * XL-0B commit 1: exact spelling at the fn-signature and declaration-type leaves; alias-rhs site reads scope.type_env * alias-rhs leaf site reads scope.type_env * Regenerate the stage0 mirror at the XL-0B commit-1 tree: byte fixed point at round 3 Cycle on srv1 over a1c9dde (authority tree bc2ae136138ac4aa), gate bins built each round: round 1: compiler e33c998203b59217 from installed df30d05facfa6307 -> drift v1_compiler_emit_rust.rs round 2: compiler ad9914da781db28d from installed c475b249666c3ba5 -> drift std_nat.rs, std_types.rs round 3: compiler c7ac6e91c1e07861 from installed be968e441d3a2a43 -> every regen-population file byte-equal CHANGED paths, each explained by the authority change: v1_compiler_emit_rust.rs (the threading); std_types.rs (Bytes/Secret/SecretValue declaration sites now spell the exact grounding std::vec::Vec<u8> / std::string::String); std_nat.rs (List<Nat> in container-argument position renders the closed alias's resolved numeric realization i64 -- type-identical to Nat = i64). Unit tests on the converged bytes: 552 passed, 0 failed, 140 ignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0B commit 2 (source): declared callees imported over builtin capture; dead RebuildEmittedFail variant; Accepted diagnostics bound and threaded; WallNow carries its fields; evaluator binding-miss answers the PartialFunction codomain; Optional-nested variant qualified by its own enum; Clone for generics forwarded by a returned closure * XL-0E: equality admission wall in v1 acceptance (records/coproducts with function members refuse ==) + explicit identities for InterpretationAlgebra and RuntimeValue comparisons The wall: infer_binop_type_node answered Eq/Ne with bool_type for every left type and the ExprBinOp arm emitted no diagnostic, so '==' was accepted on types whose equality semantics do not exist and the refusal lived below the floor as rustc E0369 in the emitted v2 crate. equality_admission_diags now judges both operands' complete resolved types: Arrow refuses; kernel scalars admit; algebra carriers admit or refuse by the new declared support-axis row std.algebra algebra_profile_equality_extensional (finite-support carriers lift into their type arguments, PartialFunction refuses); products walk members, coproducts walk arms, under a visited set keyed on declaration identity (Peano Nat admits); unjudgeable members refuse. Two new blocking diagnostics EqualityOnFunctionMember / EqualityMemberUnjudgeable, with their two mechanical seed-transport arms (receipt expanded in the gate note). The identities: InterpretationAlgebra comparison is the six carried slot identity Symbols (interpretation_algebra_slot_identities_equal), consumed at both digest-authority sites in 05_eval. RuntimeValue has NO universal Boolean comparator any more: runtime_value_equality answers Equal/Differ/ EqualityUnavailable via the admitted structural projection, explicit RuntimeIdentity for references, and a typed third state for closures that is never collapsed to false; the eval verdict machinery routes Unavailable to a RunFailed verdict, and the roundtrip/witness/test consumers match the verdict explicitly. Fixture: dag/test/claim/self_host_equality_admission_witness_test.dag — five blocking reds (the two real subjects compiled against the live pool, planted record/coproduct equivalents, PartialFunction) and four greens (v2 Peano Nat, local recursive coproduct, structural record with containers, '!= none'). stage0 mirror carries a hand-applied minimal delta (enum variants + two arms) solely to keep the tree buildable for regen round 1; the regen transaction replaces it with authoritative bytes in the follow-up commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror for commit 2 (mechanical residue): byte fixed point at round 2 Cycle on 8781269 (main parent d35cda54): round 1 drift on v1_compiler_emit_rust.rs and v1_compiler_trait_derive_emit.rs (the two files commit 2 edits), round 2 byte fixed point; installed tree 7fcf44b9f5c9df97, gunbc 2146d1f1844dea92. Unit 552/0. Emitted closure cargo check 420 -> 392; line-insensitive identity diff vs the merged-tree base: 28 removed, 0 added (E0061 x6 vocab arity, E0599 GlobalBare* x4, E0004 x7, E0533, E0271, E0618 x2, returned-closure Clone x7). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A1: relocate the import-admission helpers to their consumer layer; C: one storage representation for Map at every position A1 (closure prune). Counting fully qualified code references as declared edges, the declared closure from v2.compiler.compile equals the emitted set: no module enters by bare-name binding. The carrier was 03_name_resolve importing v2.lens.reference_deps for admission_from_module_root / import_rows_from_parsed_module / collect_import_decl_nodes / ImportRowsState, consumed only by v2.workflow.compile_door_ledger and self_host.frontier_probe (both outside the closure, both already importing reference_deps). They now live in reference_deps; the two consumers import them there. Emitted closure drops 8 modules (lens.coverage, enforcement.{grammar_coverage,standing_intent,vocab}, registry, module_graph, reference_deps, std.decl_index) and all 6 host-primitive panic sites. C (Map). The six PartialFunction<..> positions (InferredTree.facts, EvaluationEnvironment.bindings, four signatures) are Map<..>; the four PartialFunction { lookup: .. } constructions are empty_map() or a first-wins map_insert fold; map_insert routes through a rostered map_insert_primitive_delegate (closure body deleted); slots.lookup -> map_lookup. Emitter: the alias RHS renders a keyed/element collection through the host template (type X = Map<A, B> -> Rc<HashMap<..>>), and a generic in map-key position carries std::cmp::Eq + std::hash::Hash from the signature. Two witness rows added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: generic LiteralElaboration/OperatorRealization authority — typed literal-to-Zero/Succ homomorphism at every boundary, operator realization by exact operand structure, structural Peano Nat operations (no i64 row) * XL-0N: the Peano-Nat inhabitance witness asserts the ruled admission through its homomorphism; its expected-red row is retired by its trigger * Close the five unrealized host seams in the emitted v2 compiler closure: one model-backed decode, and reflection segregated from what the compiler must emit The v2 compiler's own emitted Rust crate carried five declarations with no behaviour on that target -- panic!("unrealized host seam ...") bodies that rustc accepts only because a diverging body type-checks. A compiler that ships a refusal where a function should be is not fail-closed; it is a fabricated plausible artifact whose failure is deferred to whoever calls it. ONE OF THEM WAS A REAL DEFECT, not just misplacement. v2.std.compilers.target_model recovered a UriScheme from a bundle node by asking the HOST for ^UriScheme's nullary inhabitants. That answer exists only inside the v1 interpreter's live declaration index, so the compiler could not read back a node it had itself written -- the one call-reachable seam on the compile path. It now folds a DECLARED roster, extdeps.uri uri_scheme_inhabitants, through a roster-backed v2.std.node_query nullary_inhabitant_by_discriminant. Both refusal arms survive (missing, duplicate) and the refusal is now located at the scheme child being decoded rather than at the type declaration, which is the better locus and was unavailable to the reflective form. The reflective coproduct_nullary_inhabitant_by_discriminant, and the dead reflective wrappers coproduct_arms / coproduct_arm_payload_pairs, are deleted rather than left standing beside it. THE OTHER FOUR WERE MODULE-GRAIN RESIDUE, and the fix is relocation, not a body. Emission decides membership at module grain, so a host seam is emitted whenever any NEIGHBOUR in its file is needed -- reachability never entered into it. Three modules now separate the seam from the vocabulary the closure actually wanted: v2.std.node_reflection resolve_type_node, coproduct_arm_keys, coproduct_nullary_inhabitants v2.lens.layer_import_scan layer_import_facts_live v2.compiler.source_authority_read the Filesystem.Read read-through and SourceRootIngestBuild Each keeps every consumer it had -- the two containment lenses, the self-host closure-emit driver and frontier probe, the realization sweep, the ingest witnesses -- and none of them is on a compile path. Nothing is deleted that had a caller, and no seam acquires a fake body. WHY THE SPLIT IS THE WALL AND NOT JUST A TIDY-UP. Each new module is imported only from outside the compile closure, so a future declaration that reaches reflection, or the filesystem, or the tree scan drags its module back in and the seam reappears in the emitted crate at the same census grep -- loudly, in the diff that caused it. The rule the split states is that these are INTERPRETER-time capabilities: available to a lens or a witness reading the live tree, never to a declaration the compiler must emit. CARRIED CONSEQUENCE, not yet discharged in this commit: moving the two reflection seams changes their bridge FAMILY module key in gunbc.v1_interpreter_primitive_surface (v2.std.node / v2.std.node_query -> v2.std.node_reflection). is_v4_bridge_family matches on the item registry's module name, so this is inert until stage0 is regenerated; the regen lands on top of XL-0B's converged seed. EVIDENCE. v2.test.claim.target_model_external_authority_decode round-trips EVERY declared scheme through bundle-then-decode (a roster short by one arm reds on its own row), asserts that an unnamed discriminant REFUSES rather than defaulting to an arm, and pairs that with a positive control over the identical hand-built node shape so a shape-caused refusal cannot pass for the discriminant check. The price of a declared roster is a second statement of the arms, so v2.test.manual.coproduct_reflection_conformance now walls the drift both directions by bag equality against reflected arm keys, with a non-emptiness control so an empty reflection cannot green it vacuously. * C corrected: InferredTree.facts stays the open PartialFunction; PartialFunction realizes as its algebra struct everywhere (HashMap rows deleted); frontier row dissolved; two TargetChanged admissions The CI floor on 4da6059 showed the facts retyping over-reached: about 120 test and fixture sites plus program.dag / 05_emit_orchestration define InferredTree.facts by a predicate closure, which is exactly what the open carrier is for. inferred_tree / 04_infer / program_partition are restored. The fork was the emitter realizing PartialFunction as HashMap in signature position and as the algebra struct in field position; the PartialFunction HashMap rows in extdeps.languages.rust (types.dag row, the partial_function template) are deleted so one representation stands. EvaluationEnvironment.bindings stays Map (built by map_insert); v2_effect_io_pure's empty environment is empty_map(). The v1 unresolved_method_frontier row for target_model lookup / Primitive(T) is deleted: the slots.lookup -> map_lookup rewrite dissolved its one occurrence. The two TargetChanged binding deltas for admission_from_module_root (frontier_probe, compile_door_ledger) are admitted by exact subject in namespace_wave_admission.rs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: operand realization hops alias/refinement declarations to their target (NonEmptyStr, Char, VersionIdentity compare/add as their host targets) * Move the two reflection bridge arms onto one v2.std.node_reflection family in the hand-maintained dispatch macro `is_v4_bridge_family` decides a bridge by comparing the ITEM REGISTRY'S MODULE NAME against a literal in `v1_bridge_family_arms!`, so relocating resolve_type_node and coproduct_nullary_inhabitants into v2.std.node_reflection is inert in the interpreter until this literal moves with them. Left unmoved, both calls fall past the bridge to `ctx.lookup_fn`, reach their own .dag self-call declaration, and recurse -- green typecheck, no diagnostic, wrong behaviour, which is the exact shape §5 forbids. The two former families collapse into one because they now share a module: `distinct_dispatch_sites` in gunbc.v1_interpreter_dispatch_emit dedups sites by module key and `render_site_block` selects that site's rows wherever they sit in the roster, so the generated surface is a single EvalCallBridgeStdNodeReflectionArm with both variants regardless of the two rows not being adjacent. WHY THIS FILE IS HAND-EDITED AND WHAT THAT COSTS, stated rather than glossed. The family's enum, lookup fn and arm-macro names are DERIVED from `EvalCallBridgeFamilySite.module` by module_slug_after_domain_prefix / module_pascal_after_domain_prefix, so naming them wrongly here does not compile: the generated symbols simply do not exist. The module LITERAL beside them is not derived -- it is a second representation of the same roster field, and a literal that disagrees with the roster while the derived names agree is writable and nothing refuses it. That is a §3 fork in the seed's realization, not a defect this change introduces, and it is named here because this change is the first one to move the field and therefore the first to depend on the fork holding. * XL-0E: parenthesize bare-variant comparisons in if-conditions (Variant-brace parses as record literal); flatten wall helpers to top-level fns Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror for A1 + C (aa373f9): byte fixed point at round 3 Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, extdeps_languages_rust_types, std_primitive_projection, v1_compiler_emit_rust, v1_compiler_infer), round 2 only compiler_tests.rs, round 3 byte-identical; installed tree f53efd0d0173a43e, gunbc 1a2d53dd15920cf1. Unit 552/0. Emitted closure cargo check 392 -> 278; line-insensitive identity diff vs commit 2: 112 removed, 0 added. Batteries on the converged binary: 29/29 (the two C rows red on the pre-fix compiler by fixture emit), 14/14, 20/20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: Bool row -- KernelBoolLiteral into v2.std.logic.Bool via BooleanUnfold (True/False); interpreter evaluates an elaborated literal as its kernel value; falsifier pair (row found/removed in the interpreter, constructor image vs host keyword on the emitted path) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0E regen: stage0 mirror at byte fixed point with the equality admission wall active; census repairs (native-realization leaves admit via decl_file_realizes_natively, presence exemption reads the expression spelling) Regen transaction (local, this worktree): round 1 emitted from the committed pre-wall mirror; candidate applied; rebuilt compiler carries the wall; its corpus census surfaced exactly 10 refusals, all EqualityMemberUnjudgeable false positives in two classes -- dag std Nat (native-realized scalar alias, now admitted through the coercion authority's identity-keyed decl_file_realizes_natively, fail-closed on unknown identity) and bare '!= Absent' presence tests whose exemption now reads the operand expression spelling. Round 2: first_generation_equal=true, exit 0 -- byte fixed point with the wall live and zero corpus refusals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * XL-0N: operand realization hops alias items by is_type_alias_item/resolved_type (the derive lane's own test) -- the structural condition on the declaration node never held, so NonEmptyStr/Char/VersionIdentity host ops were refused in the regenerated compiler Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Commit 3 of the #9664 closure: six emitter mechanisms, the null keyword by path, and map_insert back to its .dag body under the gate's ruling Emitter (src/v1/05_emit_rust.dag, trait_derive_emit.dag), each with a discriminating row in self_host_emitted_call_target_realization_witness_test (pre-fix bytes observed on the seed): - an argument into a parameter spelled Optional<T> is not unwrapped (the cardinality flag marks only the T? sugar; the applied spelling is asked too) - the shared-field accessor impl of a generic coproduct carries T: Clone - a Violates literal in a record field takes the field's Witness carrier before the fn return - a record pattern over a shared carrier derefs like a shared enum's variant pattern - a fn returning an arrow-field record carries 'static on its generics (same gate as impl Fn) - the fn-field record header prints well-formedness bounds asked per parameter instead of the bounded set minus the seed set (FalsificationReceipt<Subj, A> lost A behind ValueDiff<A: Clone>) - extdeps.languages.rust emit: the null keyword is std::option::Option::None, because a module declaring a nullary variant named None emits pub struct None; at module scope (std.cache_interface) v2.std.collection: map_insert is its .dag body again and map_insert_primitive_delegate with its primitive_projection row is deleted. The delegate tripped map_carrier_shape_gate on CI at c6d9b22 (record_shaped_map_reaches_map_insert BUDGET-REFUSED): the interpreter's free_call.map_insert arm answers Ok(None) for a non-native shape and the grounding falls through to the delegate's own body, a self-call -- the deferred-refusal class #8887 filed. The closing move is a host fact (a typed refusal in try_v2_std_collection_map_primitive_grounding) and is ledgered in the PR body, not landed here, by the manager's ruling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Hoist commit-3 rationale annotations to module-item grain (§4c refuses in-body // blocks; 17 regen refusals on 780b394) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: operand realization reads the RESOLVED structure -- a NoConnective childless leaf whose structural name is a kernel type is a host operand (the resolver collapses NonEmptyStr/Char/VersionIdentity to their primitive RHS under the alias identity, so no resolved node is ever an alias item); refusal temporarily carries the operand's shape facts for the regen diagnosis Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: shape-facts suffix spells Int counts with to_string (the seed runtime has no Int-as-String cast; the cast panicked the emitter under regen) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: operand realization hops a where-refinement wrapper to its base (is_where_refinement_type, the type renderer's own route) -- measured under regen: NonEmptyStr/Char/VersionIdentity operands resolve to the one-child Conj refinement node, not a leaf or an alias item Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: operator realization matches over BinOp are total (14 closed variants enumerated) -- no non-fold residue rows for the new module Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Commit 3 correction after the first regen: withdraw the Violates field-carrier arm (the literal resolves to the Witness declaration, spelling Witness::<Holds> at 87 sites), 'static on generics only for fn-field record returns (compose<A, B, C> stays bare), re-pin the optional and shared-record rows Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Regenerate the stage0 mirror: the reflection bridge family, the UriScheme roster, and the two projections main and the stack both moved Four generated files, from three distinct authorities, all owed by this stack: v1_interpreter_dispatch_generated.rs the bridge family moves to v2.std.node_reflection -- one EvalCallBridgeStdNodeReflectionArm with both variants, replacing the separate StdNode and StdNodeQuery families extdeps_uri.rs uri_scheme_inhabitants, the declared roster the target_model decode folds v1_compiler_emit_rust.rs the projection whose bytes the merge v1_compiler_infer.rs driver refused to resolve by hand THE TWO MERGE-DRIVER REFUSALS ARE RESOLVED HERE AND NOWHERE ELSE. Both files were left UNMERGED by merge.generated-artifact across the two main merges, carrying the ours side verbatim with no conflict markers, precisely so the regenerators would run against them. Picking a side would have dropped the other side's authority-derived bytes with nothing in the tree to say so; these bytes are the projection of the MERGED authorities, produced by the emitter, not chosen. WHAT THIS UNBLOCKS. The bridge family literal landed one commit earlier and was inert until now: is_v4_bridge_family matches the item registry's module name, and the generated lookup fn it names did not exist, so every head since has failed to compile on E0425 -- four red checks with one cause. The seed now defines lookup_eval_call_bridge_std_node_reflection and the hand macro resolves against it. MEASURED, NOT ASSUMED. An earlier run of this same loop reported convergence that had not happened, because two of its steps failed open: main_wet was OOM-killed on a 7 GiB runner while the script printed its success marker regardless, and the post-restore rebuild failed while `test -x` passed on the stale binary from the previous build -- so the rounds that followed, and a fixed_point_equal=true, were produced by a compiler that did not carry this change. Those readings are discarded. This run checks every step's real exit code, and runs on a 20 GiB runner with the memory budget declared BELOW the box rather than above it, which is why main_wet completed and regenerated the dispatch surface at all. STILL OWED, and deliberately not claimed by this commit: a clean regen round and the fixed point from a compiler rebuilt off this installed tree, and the emitted-closure census. * XL-0N: retire the regen-diagnosis shape-facts suffix -- the where-refinement hop is confirmed at byte fixed point (6ba83b3 regen, round 2 equal) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Rehome the layer scan out of the lens registry, declare the two reference-derived reflection imports, and adjudicate the 56 relocation bindings Three findings from the floor, one mistake and two consequences of the relocation working as designed. THE MISTAKE: layer_import_facts_live was homed at v2.lens.layer_import_scan because its only consumers are two lenses. That put a NON-LENS module inside the population v2.lens.enforcement.lens_module_gate and the declarations phase read as the lens registry's subject, and both refused it correctly: declarations FAIL LENS-AUTHORSHIP-ABSENT src/v2/lens/layer_import_scan.dag: lens `v2.lens.layer_import_scan` declares no `construction_justification` plus lens_module_gate_holds_live and lens_closure_question_zero_holds_live. A producer CONSUMED BY lenses is not a lens. It is now v2.std.layer_import_scan. Closure membership is decided by REFERENCE, not by directory (DESIGN §3: paths are discriminators, not gospel), so the seam stays out of the compile closure from either home -- only the lens registry's population was sensitive to which, which is exactly why the gate and not the emitter caught this. THE SECOND: v2.test.generated.cross_representation_equality and v2.test.lens_wiring_liveness.wiring_liveness_test carry no imports at all and resolved coproduct_arm_keys / resolve_type_node through the reference-derived closure. That worked while those names sat in modules every run already loaded. Segregating them into a module NOTHING in the closure imports is the point of the change, so the run stops loading it and the reference has to be declared: FAIL v2.test.manual.value_null_split_witness... errored: no declaration named 'coproduct_arm_keys' in this execution's loaded index Two import lines, not a relaxation of the split. THE THIRD: 56 TargetChanged binding deltas, one per (module, declaration, spelling) triple whose home moved. Every row names one exact subject with blast radius 0, so a binding this change did not intend still refuses; none admits a module, a prefix or a spelling in general. The count is 56 rather than 8 because the read-through moved a type, two variants and a function that eight consumers each reference from several declarations. They dissolve when this stack merges, by the same trigger every shrink in that file was removed under. WHAT THE FLOOR ALREADY CONFIRMED, and why these are the only three: all 14 changed witnesses passed, including the four target_model_external_authority_decode rows and both UriScheme roster-drift rows. The conformance rows CALL reflection, so they could only pass if the bridge family move routes -- the seam relocation is green by execution, not by inspection. * XL-0N: regenerated stage0 mirrors at byte fixed point (070a203 source, BuildBuddy regen round 3 first_generation_equal=true; partition crates rendered=14 written=0) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: register std.literal_elaboration and std.operator_realization in the std-core partition and gunbc.structural_realization_bindings in the v1-infer binding unit (v2.workflow.rust_crate_partition), with their module-dag edges Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * XL-0N: type_reference_declaration_ref resolves an in-place (recursive) type reference through its env binding before matching the declaration span -- v2.std.nat.Nat is recursive and answered Absent, so its literal boundary and operand identity fell to the unavailable arms while v2.std.logic.Bool worked Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Regenerate the stage0 mirror at b115892: byte fixed point at round 3 (installed 9d44564232ba8648, gunbc eaf00f8d92931968) Round 1 changed the five authority mirrors (extdeps_languages_rust_emit, std_primitive_projection, v1_compiler_emit_rust, v1_compiler_infer, v1_compiler_trait_derive_emit); round 2 the whole population through the new emitter (std::option::Option::None, 'static on fn-field record returns, per-parameter well-formedness bounds); round 3 byte-equal. Unit 566/0. Emitted v2 closure cargo check 278 -> 258: 23 identities removed (8 optional-unwrap, 6 accessor &T, 5 record deref, None capture, A: Clone, both E0310), 3 added -- the map_insert body's own rows at v2_std_collection, the ruled cost of withdrawing the delegate. Batteries 35/35, 14/14, 20/20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Bootstrap the two conflicted projections from the converged side so a compiler can be built to regenerate them NOT A RESOLUTION OF THE MERGE, AND NOT BYTES ANYONE SHOULD READ AS AUTHORITATIVE. merge.generated-artifact left v1_compiler_emit_rust.rs and v1_compiler_infer.rs UNMERGED across the 3af83d9 merge, carrying the ours side verbatim so the regenerators could run against them. That is the prescribed flow and it is what the previous commit did -- but the ours side predates a signature change 3af83d9 made to the emit_rust authority, so the merged tree does not compile: error[E0061]: v1_item_wf_propagated_clone_bounded_param_names ... provide the argument error: could not compile `v1-compiler` and a regenerator needs a building compiler. Neither side's bytes are the projection of the merged authorities, so this is a choice between two wrong seeds, and the only property that matters for a BOOTSTRAP is which one compiles. The converged side does; ours does not. WHAT THIS COMMIT IS NOT: it is not "picking a side" in the sense the merge driver forbids. Picking a side as the ANSWER would leave the tree authority-ahead-of- artifact with nothing to say so. These bytes are transient scaffolding for one build, immediately overwritten by the regen commit that follows, which derives them from the merged authorities -- my source change and theirs together. If that regen does not land, this commit is wrong and the drift gate says so on the very next run, which is the property that makes the interim safe to take rather than a silent substitution. * w_fn_field_record_header_keeps_the_bound_a_field_type_demands: a local fn-field type instead of the host_run closure (30 s CPU per floor fill, false through the shared-artifact path on 3af83d9); same discriminating bytes on the seed (R6<Subj, A>) and the converged compiler (R6<Subj, A: Clone>) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * std.cache_interface: the three .first() producers are Optional at the declaration (cache_facts_for_id, cache_reach_candidate_probe, cache_layer_plan_primary/fallback); every consumer matches -- a layer with no catalog facts neither beats recompute nor respects locality (typed false, no fabricated facts); planner test matches the projections Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * XL-0N: regenerated stage0 mirrors at byte fixed point on e51aff9 (BuildBuddy regen round 3 first_generation_equal=true; includes the merged #9710 commit-3 null-keyword-by-path drift and the new-module mirrors) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * Model rustc phases and derive the self-host phase board * XL-0E: close the RuntimeValue equality leak — same-identity peel chase dispatches into declaration structure instead of re-entering the visited check Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * XL-0E: wildcard-free runtime_value_equality dispatch (nfr roster) and drop body comment (DESIGN 4c) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Root compile-phase board in the self-host frontier * Delete provisional emission-board authority after root cut * Strengthen compile-phase receipts as a linked subject ledger * XL-0N: type_reference_declaration_ref falls back to the module-visible name binding when the reference carries no ident-keyed binding (the emitter's scope env) -- the found declaration is still span-matched against the global roster, so a by-name hit only confirms an exact declaration; measured: Peano literal rows passed while the operator rows still lost Nat's identity Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013koFunEtpLQCnvUiz85k7Y * The host optional's variant spellings, one authority: six inline Some/None sites read rust_optional_variant_spelling, which qualifies None by path (a bare None PATTERN in std.cache_interface bound the module's pub struct None; five arms on the first regen); row w_absent_pattern_survives_a_module_declaring_a_none_variant Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Persist the first compile-phase diagnostic population * Fix frontier identity folding and literal diagnostics * XL-0E: regen merged tree to byte fixed point (round m2 first_generation_equal=true); re-judge the RuntimeValue witness row on the #9724 finite-Map model — the live subject now asserts admission as the over-refusal control Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Observe parse and cargo-check phases in one instrument run * Tighten compile-phase receipt epochs and identity semantics * Bind frontier receipts to complete instrument observations * Make compile-phase receipt populations structurally derivable * Regenerate the stage0 mirror at d20440d: byte fixed point at round 3 (installed 1b8ca70c9dbf62bc, gunbc deabfe3085a2d289) Round 1 changed v1_compiler_emit_rust; round 2 the population through the qualified None spelling; round 3 byte-equal. Unit 575/0. Emitted v2 closure cargo check 244 -> 239, typeck phase: the five None-in-pattern-position rows at std_cache_interface removed, nothing added (the two re-keyed rows differ only by column). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Require dispositions for every newly exposed phase identity * Bootstrap the XL-0E merge: the four driver-refused mirrors take XL-0E's converged bytes (the ours side lacked EqualityOnFunctionMember/EqualityMemberUnjudgeable that its non-conflicting mirrors reference; seed did not build); regen round 1 re-applies the None-spelling emitter change Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Persist and project the compile-phase frontier genesis * XL-0E floor fixes: emit_host consumes the typed accepted_runtime_value_outcome_equality verdict (name main's #9727 imported no longer existed); empty-list literal comparison exempt as the emptiness idiom beside '== none'; regen to byte fixed point (round n2) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015r24mvNDYTTLUVYyagfMWe * Regenerate the stage0 mirror at 03f1631 (XL-0E integrated): byte fixed point at round 3 (installed 2be25adfee989956, gunbc 37b1266cb05babf4) Round 1 re-applied the qualified None spelling over the bootstrap pick of XL-0E's four mirrors; round 2 the remaining population; round 3 byte-equal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Materialize each emission measurement exactly once * Rc-field arm grouping picks a representative by plain-binding subset, not outer-pattern bytes: two arms of one record that differ only on a plain binding lower to one nested match instead of two guarded arms (E0004 x2, rustc cannot see a guard) rc_group_is_whole_coverage required byte-equal outer patterns, so Edge { label: Named {..}, target: magnitude } beside Edge { label: Positional, target: _ } fell back to the #8570 guard form on both arms, which rustc reports as non-exhaustive (E0004 at v2.extdeps.languages.dag and v2.std.compilers.target_model, xl0b9 board). The group now takes the outer pattern of the member whose plain bindings are a superset of every other member's (same field, same identifier), which selects the same values; any refutable plain field, second Rc-bound field, or authored guard still keeps the guards. Witness: w_record_arms_differing_only_in_plain_bindings_group_into_a_nested_match (RED on 37b1266c: emits the guard form, measured by direct emission). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A record-literal field value is emitted under the field's declared type, not the fn return: EmitGraphInfo.expected_type at expression grain; the Violates type argument reads it (E0308 x5, Witness at a Witness<Node>/Witness<InferredFacts> field) rust_witness_type_arg_from_fn_return answered a Violates literal with the enclosing fn's return carrier wherever it sat, so the four RuntimeValueAcceptanceWitness fields at v2.compiler.eval and the Rejected arm at v2.compiler.compile rendered Witness::<Rc<RuntimeValueAcceptanceWitness>>::Violates against fields declared Witness<Node> / Witness<InferredFacts>. fn_return_type stays the fn-grain fact (rust_declared_return_is_callable reads it); the new expected_type is the expression-grain fact: seeded by emit_info_with_fn_return, re-seeded by emit_field_value_with_context with the field's declared type node (record_field_expected_type), cleared when no declaration names the field. Witness: w_violates_at_a_record_field_takes_the_fields_declared_carrier. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * A type argument inside a record field's type expression reads its declaring module from the env binding: std.nat.Nat at Measure<Time, S, Nat> rendered Rc<Nat> in the struct and i64 in every signature (E0308 x8, E0369 x1) Field type expressions carry no resolved inference, so type_reference_decl_file fell back to the REFERENCE's file and the native-alias row (dag/std/nat.dag -> i64) could not fire; the shared wrap then rendered the argument as Rc<Nat>. type_reference_decl_file_in_env resolves the leaf through lookup_type_by_name and accepts the binding only when the declaration is named by the leaf (an alias RHS never stands in for the alias); the two checkpoint-spelling queries that already carry env consume it. Witness: w_native_alias_type_argument_at_a_generic_field_renders_the_machine_scalar (the must line is provisional until the RED probe prints the current rendering; refined in the regen commit if the wrap differs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU * Three source-shape residues the v1 …
This was referenced Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/v1/05_emit_rust.dag's Rc-aware pattern emission flattened nested constructorpatterns on Rc-wrapped enum fields out of the match arm's pattern position into a
body-level
let-else unreachable!()assertion. When two sibling arms shared thesame outer discriminant but differed only in a nested Rc-wrapped constructor (e.g.
classify_arrow_body_form'sTypeNode { connective: Atom { .. } }vsTypeNode { connective: Conj }), the flattening made both arms' outer patternsidentical, so rustc's exhaustiveness/reachability check saw the first arm as
subsuming the second. This is never silent: it is a hard
cargo buildfailureunder
#, ora runtime panic on a valid input if that lint is relaxed — either way, a real
input can never take the intended
Conjarm; before the fix it either fails tocompile or silently returns the wrong
ArrowBodyForm.Fix:
collect_pattern_rc_variant_guardscomputes amatches!(field.as_ref(), Shape)guard for each Rc-ref'd nested refutable pattern and merges it into the arm's
guard_parts(alongside the pre-existingfield_guardsand the arm's own guard),in both
emit_typed_match_armandemit_typed_tco_match_arm. Thelet-elseprelude that does the actual binding is untouched — its
unreachable!()becomestrue-by-construction (guarded by the match arm reaching it at all) instead of an
asserted lie, per DESIGN.md §5 (construction over validation).
A static structural census of the corpus for this pattern shape found 133 sites
across 87 files (identity-grain match, positive control confirmed against a known
site). This is a caveated over-approximation of affected call sites, not a
guarantee every one panics/fails to build today — some may be masked by arm
ordering that happens not to collide. Not all 133 are touched by this PR; the fix
is at the emission mechanism, so it covers all of them going forward.
A separate, unrelated finding — 13 call sites hardcoding an empty
scrut_type: ""scrutinee-type context — is explicitly queued and NOT part of this PR.
Regenerated stage0 mirror
--required-regencurrently refuses corpus-wide on a pre-existing, unrelatedpopulation mismatch (#8544). Per an operator-sanctioned narrower path, the
projection was obtained by invoking
compile_stage0directly (same rustfmtnormalization
write_emitted_treeapplies), ahead of the population-comparisongate #8544 blocks on.
The whole emitted stage0 tree was diffed against committed. Beyond
v1_compiler_emit_rust.rs(this fix), six other files differ from committedstage0, all for reasons unrelated to this change, and are intentionally left
untouched by this PR:
lib.rs,v1_compiler_infer.rs,v1_std_core.rs— stage0 surface-ownership: disposition the 10-row required-regen population (1 emitted-not-committed + 9 committed-not-emitted) one row at a time; NOT a roster append #8544's own subject(three files not yet in the emit population;
expr_is_any_literal/where-refinement work not yet landed on main).
std_measure.rs,std_pareto.rs,std_witness_admission.rs— unowned regenbacklog: stale committed projections of other sessions'
.dagauthoritychanges that were never regenerated, unrelated to pattern/Rc/match-arm
emission. Surfaced as a byproduct of this verification and reported
separately (not carried by this PR); when stage0 surface-ownership: disposition the 10-row required-regen population (1 emitted-not-committed + 9 committed-not-emitted) one row at a time; NOT a roster append #8544's population gate is fixed
and the tree is regenerated, these three land for free.
Test plan
/tmp/red_repro) using theverbatim pre-fix emitted
classify_arrow_body_formwith#[allow(unreachable_patterns)]added only to get past rustc's deny,confirmed the runtime panic / wrong-answer behavior underneath the
compile-time defect.
Rust crate scoped to
src/v2/std/node.dag's closure with the pre-fixstage0 binary (
/tmp/emit_out) vs. the post-fix, freshly rebuiltgunbc(
/tmp/emit_out_new). Both trees carry an unrelated, pre-existingduplicate-type build error (3x E0308,
OccurrenceIdcollision — anartifact of this narrow scoped
--entrycompile, present identically inboth trees, out of scope for this fix). This 5 -> 3 count is scoped to
this scoped
--entry src/v2/std/node.dagclosure'scargo build --lib— a separate subject from the fleet's materialization_carriers board
(currently 43 per-class at
0c7b916ffc) — not a claim about that board.Before: 5 errors (3 E0308 + 2
unreachable_patterndeny errors). After:3 errors (only the pre-existing E0308s — both
unreachable_patternerrors gone).
/tmp/green_repro) built the verbatimpost-fix
classify_arrow_body_formunder# and exercised three cases at runtime,including the case that binds (
ComputationNode { behavior: b }, notonly the wildcard
Atomcase) — all pass:Conj -> RecordConstructBody: OKAtom -> DirectAtomBody: OKComputationNode { behavior: b } -> ComputationBody { behavior: Transform }: OK (binding preserved)