Skip to content

XL-0-INFER: classify and repair inference-failure survivors - #9854

Merged
gunbai-bot[bot] merged 6 commits into
mainfrom
session/stern-ferret-752
Sep 1, 2026
Merged

gunbai-bot[bot] merged 6 commits into
mainfrom
session/stern-ferret-752

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Scope

Establish or refute a shared producer across the post-#9850 E0282/E0308 survivors in v2.compiler.infer, v2.compiler.parse, and v2.std.compilers.target_model; repair the producers this lane owns and retain discriminating REDs plus positive controls.

Pre-registered prediction (before measurement)

Before measurement, I predicted no shared root and predicted only v2_compiler_infer.rs E0282 would be removed. I explicitly predicted the infer E0308, parse E0282, and target-model char E0308 would survive; the fifth ownership E0308 was added to the cohort after the first draft. Falsifiers included rustc asking for the infer element rather than accumulator, any predicted survivor disappearing, any addition, and a revert arm failing for a different reason.

Attribution and falsification

The prediction was falsified. Raw post-#9850 cargo JSON and emitted bytes partition the five rows into four causes:

  • v2.compiler.infer facts_map_from_entries: the source return is Outcome<PartialFunction<Node, InferredFacts>>, but every Rust type renderer treated any two-argument declared container as literal map and emitted HashMap. The direct E0308 removed expected PartialFunction<K,V> context and induced the neighbouring E0282. Both infer rows share this producer.
  • v2.compiler.parse parse_lexeme_digest: separate Lexeme = List<Char> / host-String body-boundary row, reclassified to XL-0T (vivid-deer-102) rather than fixed here.
  • v2.std.compilers.target_model target_value_expression_char_unicode_scalar: a Char code point was placed directly in Atom.identity: Symbol.
  • v2.std.compilers.target_model target_use_site_ownership_catalog_lookup_step_for_row: the outer catalog-invalid constructor was passed where the inner lookup coproduct was required.

The selector cause also includes v2.std.collection map_insert: its declared Map<K,V> host realization met a structural record literal. This class was reassigned from gentle-koi-869 and is repaired here at the shared selector.

Selector population

The diagnostic census found two direct HashMap/structural-carrier mismatches, but the source-grain census found 10 affected PartialFunction<K,V> type positions: three production positions and seven witness/fixture positions. Rustc noticed only one of the three production positions. Two of three production sites were silently misrendered. This is why the repair reads the declared target inhabitant rather than chasing diagnostics.

An unknown carrier cannot reach the selector: node_is_keyed_collection first requires membership in the carrier alias roster. For a rostered carrier, absence from the target inhabitant roster is the decided structural answer, not an unresolved lookup default.

Repair

One emit_keyed_container_type producer now answers every generic and Rust-specific type-renderer keyed arm from coerce_container_template(target, authored carrier). Map retains its declared FinitelySupportedFunction -> HashMap Rust inhabitant; PartialFunction has no host inhabitant and remains structural. Native-container record literals that cannot construct that inhabitant emit a loud refusal expression instead of constructing a second carrier under the native signature.

The target-model fixes intern the one-character lexeme before storing it as an atom identity, and keep catalog-invalid absorbing before conversion to the inner lookup type.

Fixture dispositions

The seven existing src/v2 witness/fixture positions are not bulk-updated. Their source types now render through the corrected selector; no expected-byte edits were made:

  • v2.test.lens_common.infer_fixture: corrected carrier only; no expectation edit.
  • v2.test.lens_structural_resolution.unresolved_infer_witness: corrected carrier only; no expectation edit.
  • v2.test.lens_structural_resolution.binds_to_resolved_test: corrected carrier only; no expectation edit.
  • v2.test.lens_structural_resolution.unbound_symbol_at_use: corrected carrier only; no expectation edit.
  • v2.test.lens_structural_resolution.module_import_out_of_scope: corrected carrier only; no expectation edit.
  • v2.test.lens_structural_resolution.facts_lookup_miss: corrected carrier only; no expectation edit.
  • v2.test.claim.manual.infer_emit_compile_anchor: corrected carrier only; no expectation edit.

Scoreboard

Measured against the ancestry-valid parent 0e8c49ddee9310a1e231265a8f8463ab4357d124, with both trees filtered by rustc's own level=error: 6 removed / 57 surviving / 1 added, net -5. Both directions reconcile independently: 6+57=63 baseline and 1+57=58 candidate. A full survivor label join found zero changed defects among the 51 unique surviving identity+code keys; the same five duplicated keys occur on both sides.

The six removals are the two infer rows (E0282/E0308), the v2_std_collection E0308/E0560 pair, the target-model ownership E0308, and the target-model character-identity E0308. The sole addition is a successor at the same target-model character expression: the old expected String, found i64 at column 15 is gone and expected String, found Rc<Vector<i64>> appears at column 43. This is one repaired site exposing its next defect, not an unrelated regression elsewhere.

One raw positional removed/added pair in parse was excluded as displacement: the identical expected Rc<Vector<i64>>, found String defect moved from line 839 to 836. Four doubled surviving keys are tokenize text-carrier rows behind the separate text-carrier arbiter; their survival is expected and does not falsify this selector repair. The parse row remains reassigned to XL-0T rather than silently subtracted.

Verification

  • Source-built focused claims: all six pass — the three target-model RED/control claims, structural PartialFunction type rendering, native Map type rendering, and native-Map record-shape refusal.
  • Required regeneration named exactly v1_compiler_emit.rs and v1_compiler_emit_rust.rs before the main merge. The merge driver later named concurrent v1_compiler_emit_rust.rs and v1_compiler_infer.rs projections; both were regenerated from the merged authorities, never selected or hand-edited.
  • Rebuilt-seed regeneration is at fixed point: first_generation_equal=true, 148 planned/executed/adjudicated, with only the declared main.rs divergence.

Instrument deficit

tools.emission_entry_instrument measure_entry_emission persists normalized identity but discards rustc expected/found children. That prevents later producer attribution from its receipt alone; the next-rung trigger is retaining those structured diagnostic children in the report.

Base

Originally investigated on PR #9850's 66-row boundary, then merged through current main 0e8c49ddee9310a1e231265a8f8463ab4357d124 so the final census has a valid ancestry relation and concurrent generated projections are authority-derived.

gunbc-ci-auto-heal and others added 6 commits August 31, 2026 23:30
…key use-line derivation on the resolved kernel identity

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
…ion_equal=true)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
# Conflicts:
#	src/v1/stage0/src/v1_compiler_emit_rust.rs
#	src/v1/stage0/src/v1_compiler_infer.rs
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 1, 2026 04:13
@gunbai-bot
gunbai-bot Bot merged commit 5d7bef7 into main Sep 1, 2026
6 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/stern-ferret-752 branch September 1, 2026 04:41
@briansrls
briansrls restored the session/stern-ferret-752 branch September 1, 2026 04:55
gunbai-bot Bot pushed a commit that referenced this pull request Sep 1, 2026
… nullary-alias-applied-argument class

TWO CHANGES TO docs/plans/compiler-guarantee-recovery-gap-analysis.md, both building on
the third-inhabitance-seam row landed by #9879 rather than beside it.

1. THE EXPOSED SUBSET, which #9879's row explicitly left unmeasured.

Re-derived independently over dag/, src/v1/ and src/v2/ at origin/main 6741a39,
per that row's own instruction to re-derive rather than quote:

  69 bodyless declarations / 66 distinct names -- JOINING #9879's 69 at identity grain,
  not merely at count. A first pass matching ^type X$ found 62; the missing 7 are the
  PARAMETERIZED bodyless declarations (Compose<carrier, dimension>, MachineWidth<bits>
  twice, ReferenceModel<T>, CppTargetDataModel<...>, CppTargetProfile<...>,
  ConfigPatchRecord<Config>). 62 + 7 = 69, so the two censuses agree on membership.

Reachability in PARAMETER position -- where a non-inhabiting value can actually flow in:

  Symbol            (v2.std.node)          1045 parameter sites
  SourceSpan        (v2.lens.application)   129
  Bytes             (std.types)               4
  ConfigPatchRecord (v2.std.patch)            1

and nothing else. 33 names appear only in field position; 27 appear in no parameter,
field or return position at all. Compose and MachineWidth are among the unexposed --
type CONSTRUCTORS applied as type arguments, never parameter types.

So the headline is not 69: the exposure is dominated by ONE declaration, Symbol, the
substrate's own identity field, by an order of magnitude.

CEILING SPLIT THREE WAYS, because one value would overstate the row:
  (a) declared-abstract by ruling (Symbol, Unit) -- construction discipline at the
      boundary through a minting authority, NOT arms. R3 at such sites, R2 corpus-wide.
  (b) the 27 type-level tags -- hole unreachable, no climb needed. Filing them as
      exposure would inflate the class and bury the member that matters.
  (c) SourceSpan and Bytes -- genuinely exposed, unruled, recorded so they are countable.

Class rung is the minimum across parts: below floor. Trigger names the CAPABILITY per
4b(3) -- a bodyless declared type inhabitable only through a declared minting authority,
AND the direct-call inhabitance judgment consulting it. #9854's witness is a wall for
ONE SITE and does not retire the row.

METHOD LIMITS carried in the row: single-line fn matching undercounts multi-line
signatures; field position over-counts. Bounds, not exact counts; the shape is robust.

2. A NEW CLASS: a nullary alias rendered with its body's type argument applied to it.

Two instances, different aliases, one shape: a refusal at a LexText-declared parameter
printed expected 'Node(LexText<Product(Char)>)' though type LexText = FreeMonoid<Char>
is nullary; and a repair to is_host_text_carrier_type emitted
pub fn string_is_empty(s: String<i64>), which is not valid Rust.

The harm is that a malformed type READS AS A REAL REFUSAL: the LexText arm produced 129
refusals against the qualified spelling's 30, and the 129 was reported and endorsed as a
stricter wall over a larger population before the diagnostic text was read closely enough
to notice the alias cannot take an argument. A population inflated by a printer defect is
worse than a missing measurement, because it gets quoted.

Both instances reproduced on a binary built from a pristine origin/main export with the
is_host_text_carrier_type repair verified absent from the compiled mirror, each arm
carrying a firing positive control. The row deliberately does NOT name a repair site --
three lanes are converging on 05_emit_rust.dag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019o3436yxdGdYZa53YopdQH
gunbai-bot Bot added a commit that referenced this pull request Sep 1, 2026
…ol — and a nullary alias rendered with an applied type argument (#9888)

* Measure the bodyless-type exposed subset (4 names of 66) and file the nullary-alias-applied-argument class

TWO CHANGES TO docs/plans/compiler-guarantee-recovery-gap-analysis.md, both building on
the third-inhabitance-seam row landed by #9879 rather than beside it.

1. THE EXPOSED SUBSET, which #9879's row explicitly left unmeasured.

Re-derived independently over dag/, src/v1/ and src/v2/ at origin/main 6741a39,
per that row's own instruction to re-derive rather than quote:

  69 bodyless declarations / 66 distinct names -- JOINING #9879's 69 at identity grain,
  not merely at count. A first pass matching ^type X$ found 62; the missing 7 are the
  PARAMETERIZED bodyless declarations (Compose<carrier, dimension>, MachineWidth<bits>
  twice, ReferenceModel<T>, CppTargetDataModel<...>, CppTargetProfile<...>,
  ConfigPatchRecord<Config>). 62 + 7 = 69, so the two censuses agree on membership.

Reachability in PARAMETER position -- where a non-inhabiting value can actually flow in:

  Symbol            (v2.std.node)          1045 parameter sites
  SourceSpan        (v2.lens.application)   129
  Bytes             (std.types)               4
  ConfigPatchRecord (v2.std.patch)            1

and nothing else. 33 names appear only in field position; 27 appear in no parameter,
field or return position at all. Compose and MachineWidth are among the unexposed --
type CONSTRUCTORS applied as type arguments, never parameter types.

So the headline is not 69: the exposure is dominated by ONE declaration, Symbol, the
substrate's own identity field, by an order of magnitude.

CEILING SPLIT THREE WAYS, because one value would overstate the row:
  (a) declared-abstract by ruling (Symbol, Unit) -- construction discipline at the
      boundary through a minting authority, NOT arms. R3 at such sites, R2 corpus-wide.
  (b) the 27 type-level tags -- hole unreachable, no climb needed. Filing them as
      exposure would inflate the class and bury the member that matters.
  (c) SourceSpan and Bytes -- genuinely exposed, unruled, recorded so they are countable.

Class rung is the minimum across parts: below floor. Trigger names the CAPABILITY per
4b(3) -- a bodyless declared type inhabitable only through a declared minting authority,
AND the direct-call inhabitance judgment consulting it. #9854's witness is a wall for
ONE SITE and does not retire the row.

METHOD LIMITS carried in the row: single-line fn matching undercounts multi-line
signatures; field position over-counts. Bounds, not exact counts; the shape is robust.

2. A NEW CLASS: a nullary alias rendered with its body's type argument applied to it.

Two instances, different aliases, one shape: a refusal at a LexText-declared parameter
printed expected 'Node(LexText<Product(Char)>)' though type LexText = FreeMonoid<Char>
is nullary; and a repair to is_host_text_carrier_type emitted
pub fn string_is_empty(s: String<i64>), which is not valid Rust.

The harm is that a malformed type READS AS A REAL REFUSAL: the LexText arm produced 129
refusals against the qualified spelling's 30, and the 129 was reported and endorsed as a
stricter wall over a larger population before the diagnostic text was read closely enough
to notice the alias cannot take an argument. A population inflated by a printer defect is
worse than a missing measurement, because it gets quoted.

Both instances reproduced on a binary built from a pristine origin/main export with the
is_host_text_carrier_type repair verified absent from the compiled mirror, each arm
carrying a firing positive control. The row deliberately does NOT name a repair site --
three lanes are converging on 05_emit_rust.dag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019o3436yxdGdYZa53YopdQH

* Correct category (b): the 27 are exposure-on-first-use, not inert -- proven by execution

eager-hawk-376 challenged the exclusion and they were right. DESIGN 4b judges
reachability BY WHAT A FIXTURE MAY AUTHOR, not by what the accepted corpus contains,
so "never used in parameter position in the corpus" is not grammar-absence.

Measured in an ordinary (non-v2.*) module, so seam (1)'s exemption is not in play,
against the pristine origin/main binary:

  fn vd_takes_phantom(x: Phantom) -> Int   fed "abc"  -> resolves clean, EXECUTES, returns 1
  fn vd_takes_persecond(x: PerSecond) -> Int fed 7    -> resolves clean, EXECUTES, returns 2
  planted positive control length(xs: n) on Int        -> REFUSES

The control is what makes the silence a measurement rather than a judgment that never
ran, and reaching the body makes this admission proven by execution rather than by a
silent compile.

So the 27 are CORPUS-UNOCCUPIED, not grammar-absent: exposure-on-first-use, acquiring
exposure the moment anyone writes the construct with nothing to refuse them. Filing them
as inert was the bounded-population-reads-as-progress trap.

Two of the 27 are measured, from two different declaring modules; the other 25 are the
same shape and are recorded by class rather than each by receipt, which the row says.

The exposure split is now three-way: exposed now (4 names, Symbol dominating),
exposure-on-first-use (27), grammar-absent (none found). Population, Symbol
concentration, below-floor rung and capability-grain trigger all unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019o3436yxdGdYZa53YopdQH

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls deleted the session/stern-ferret-752 branch September 1, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants