41%

Section 03: Inherent-Method Mono on Generic Type (BUG-04-091)

Status: In Progress Goal: Close the inherent-method-on-generic-type gap. impl<T> Box<T> { @unwrap (self) -> T } resolves at codegen for every monomorphized Box<int> / Box<str> / etc., across LOCAL-module receivers (§03.1-§03.3) AND cross-module imported-method receivers (§03.4-§03.5 per Decision 02).

Context: Per §01.3 BUG-04-091 entry, the parser side closed when BUG-01-002 landed (2026-04-29); codegen side remains. The reduced shape (@unwrap with no method-level generics, just inherent on Box<T>) is the canonical repro at compiler/ori_llvm/tests/aot/generics.rs::test_generic_method_on_generic_type (currently #[ignore]). Distinct from §02’s cross-module TOP-LEVEL gap: §03 owns the inherent-method registration gap for both local AND imported receivers per Decision 02 §03.4/§03.5 scope expansion. Distinct from §04’s complex-generic-arg dispatch: this section’s receivers are simple Box<T> shapes where T is a single type parameter.

Reference implementations:

  • Rust rustc_trait_selection::traits::project::find_inherent_impls_for_generic — inherent impls on impl<T> Type<T> enumerated separately from trait impls; mono dispatch discriminates by Type<concrete_args>.
  • Swift SIL::SILModule::lookUpFunctionInModule — specialization-aware lookup; inherent methods registered with full generic context.

Depends on: §01 (cite §01.3 BUG-04-091), §02 (collect_mono_functions signature now stable after §02.1).

Intelligence Reconnaissance

Queries planned:

  • scripts/intel-query.sh --human callers "impl_sigs" --repo ori — every site constructing or consuming the impl-sig table.
  • scripts/intel-query.sh --human file-symbols "compiler/ori_arc/src/codegen/arc_emitter" --repo ori — apply.rs surface for codegen-side method dispatch.
  • scripts/intel-query.sh --human similar "find_inherent_impls" --repo rust,swift --limit 3 — cross-language inherent-impl lookup patterns.
  • scripts/intel-query.sh --human callers "MonoInstance::receiver_type" --repo ori — how upstream code discriminates method receivers.

Results summary (≤500 chars, recorded 2026-05-14) [ori]: TO BE POPULATED at section start by running the queries above. Scaffold authored 2026-05-14 — queries deferred to execution time when impl_sigs dispatch surface is current.


03.1 MonoInstance emission for inherent methods on generic receivers

File(s): compiler_repo/compiler/ori_types/src/infer/expr/calls/method_call.rs (infer_method_call at line 24, infer_method_call_named at line 106 — per §01.2 F4 supersession); compiler_repo/compiler/ori_types/src/infer/expr/calls/monomorphization.rs:31 maybe_record_mono_instance (the top-level emission hook §03.1 parallels; relocated by the calls-module split).

03.1.0 Line-coordinate refresh + §02 prerequisite-output gate (REQUIRED first task)

Before authoring any code change in §03.1-§03.5, refresh every monomorphize/mod.rs / multi.rs / compile_common.rs / method_call.rs line citation in this section against current HEAD:

  • git rev-parse HEAD — record the verification SHA in §03 HISTORY (one-line entry: YYYY-MM-DD §03 line-coordinate refresh — HEAD <sha>).
  • Verify monomorphize/mod.rs signatures: pub fn collect_mono_functions( should be at line ~71 (signature at HEAD f5a37d327); impl_sig_by_name construction at ~86-90; import_sig_by_name at ~94-97; per-instance dispatch loop at ~107-118 (receiver.is_some branch at ~112-113); silent-skip at ~119-128. If drift >5 lines from §03.2/§03.5 body citations, update body line numbers BEFORE authoring code.
  • Verify multi.rs::CompiledModuleInfo struct at ~line 195; public_functions field at ~line 204; extract_public_function_types call site at ~line 331; extract_public_function_types definition at ~line 402; pub-function loop body at ~line 433. If drift >5 lines from §03.4 body citations, update §03.4 BEFORE authoring code.
  • Verify ori_arc/src/lower/calls/mod.rs::lower_method_call at line 297 (per §03.2 cite); update §03.2 body if drifted.
  • Verify compile_common.rs::run_codegen_pipeline call site at ~lines 236-253; import_sigs construction at ~lines 217-234; imported_mono_fns parameter at ~line 206. If drifted, update §03.5 §03.4 body wiring instructions.
  • §02 prerequisite-output gate (per frontmatter success_criteria §02-prerequisite-output-gate row): confirm §02.1 status complete in section-02-import-sigs-traversal.md frontmatter sections: array AND collect_mono_functions signature at monomorphize/mod.rs:59 includes import_sigs: &[(Name, FunctionSig)] parameter (delivered by commit 3bb8aa725 per §02 success_criteria row 2). If §02.1 incomplete OR signature missing the parameter → STOP §03.1 work, surface gate failure to §02.N close-out path. §03.1-§03.3 may proceed under partial §02.N close (per gate rule). §03.4 + §03.5 BLOCKED until §02.3 + §02.4 status complete AND §02.N close-out unchecked items resolved.

03.1.1 Typeck emission cure (§01.2 F4 supersession)

  • Locate the typeck emission site that produces MonoInstance records for inherent method calls (per §01.2 mapping at method_call.rs:23 / method_call.rs:105). Identify why impl<T> Box<T> { @unwrap } called as b.unwrap() for Box<int> does not produce a MonoInstance { fn_name: unwrap, receiver_type: Some(Box<int>), generic_args: [int], impl_args: [int], method_args: [], concrete_param_types, concrete_return_type, body_type_map } (per frontmatter unified-MonoInstance-tuple-shape success_criteria row).
  • Fix the typeck pass: ensure inherent methods on generic types emit a MonoInstance discriminated by the concrete instantiation of the receiver’s generic args. The impl_args field carries the receiver-side substitution; the receiver_type: Some(Idx) field carries the FULL concrete receiver type (e.g., Idx of Box<int>, NOT just the generic shell Box<_>).
  • Verify MonoInstance dedup logic: two calls to Box<int>.unwrap share one instance; Box<int>.unwrap and Box<str>.unwrap are distinct.
  • Subsection close-out (03.1) — MANDATORY before §03.2:
    • cargo build --release succeeds.
    • Manual repro: Box<int> { inner: 42 }.unwrap() produces a MonoInstance with receiver_type = Some(Box<int>). Verified via ORI_LOG=ori_types=debug ori check fixture.ori: recorded mono instance ... receiver=Idx(101) impl_args=[Type(Idx::INT)] method_args=[].
    • Run /improve-tooling retrospectively on §03.1.
    • Run /sync-claude on §03.1 — typeck emission semantics changed; check typeck.md §EX-* + types.md §RG-3.
    • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

03.2 collect_mono_functions impl_sigs dispatch — discriminate by generic_self_type

File(s): compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:70-75 (impl_sig_by_name construction at HEAD f5a37d327); compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:89-97 (per-instance dispatch loop, receiver-bearing branch at lines 112-113); compiler_repo/compiler/ori_arc/src/lower/calls/mod.rs:297 (lower_method_call per scripts/intel-query.sh symbols lower_method_call --repo ori; the arc_emitter/apply.rs path referenced in earlier drafts does not exist at HEAD).

The current first-match dedup in monomorphize/mod.rs:70-75:

let mut impl_sig_by_name: FxHashMap<Name, &FunctionSig> =
    FxHashMap::with_capacity_and_hasher(impl_sigs.len(), FxBuildHasher);
for (name, sig) in impl_sigs {
    impl_sig_by_name.entry(*name).or_insert(sig);  // first match wins
}

This drops the generic-self-type discrimination — if multiple impl<T> Type<T> blocks register the same method name, only the first registers, and per-receiver mono dispatch fails.

03.2.1 Keyed-lookup conversion

  • Change impl_sig_by_name from FxHashMap<Name, &FunctionSig> to FxHashMap<(Name, Option<Idx>), &FunctionSig> keyed by (method_name, receiver_generic_pattern). The receiver_generic_pattern is the generic shell Box<_> (interned Idx of the shell type with type parameters as fresh vars, NOT the instantiated Box<int>). The Option<Idx> shell aligns with MonoInstance.receiver_type: Option<Idx> (None = top-level fallback, Some = method-receiver discrimination); §03.5 extends the SAME key shape across host + imported sources, NOT a parallel parameter shape.
  • Helper: add Pool::generic_shell(idx: Idx) -> Idx (or equivalent) on ori_types::Pool that maps a concrete instantiation Box<int> to its generic shell Box<_> by replacing every concrete type argument in the receiver Tag::Named with fresh Tag::BoundVars (depth-first traversal — nested generic args Box<Option<int>> shell to Box<Option<_>> then Box<_>-at-top via outer shell; concrete primitives in arg positions become BoundVars; existing BoundVars unchanged); shell construction MUST round-trip through ori_types::canon per .claude/rules/types.md §TY-3 (canonical-pattern equality) + §TF-2 (free-var substitution invariants) so two different instantiations of the same impl block produce byte-identical shell Idx. If a free function already exists at HEAD (search Pool:: symbols via scripts/intel-query.sh symbols Pool --repo ori), reuse it; do not add a parallel.
  • Update the lookup site (receiver-bearing branch) to consult (instance.fn_name, instance.receiver_type.map(|r| pool.generic_shell(r))) instead of (instance.fn_name) alone. Keep instance.receiver_type.is_some() as the branch discriminator (unchanged from §02.1 shape).
  • In ori_arc/src/lower/calls/mod.rs::lower_method_call, the apply lowering to resolve inherent methods on generic types through the new keyed lookup. The lowering consumes the resolved mono instance from collect_mono_functions; no parallel lookup table at the lower site.

03.2.2 Un-ignore + parity

  • Un-ignore compiler/ori_llvm/tests/aot/generics.rs::test_generic_method_on_generic_type.
  • Verify MonoFunction mangled-name collision audit: Box<int>.unwrap and Box<str>.unwrap produce DISTINCT mangled names (per monomorphize/mod.rs:112-120 mangle_mono_name consumes instance.impl_args which now carry post-substitution receiver type per §03.1 emission cure).

03.2.3 Subsection close-out (03.2) — MANDATORY before §03.3

  • cargo test --release -p ori_llvm --test aot generics::test_generic_method_on_generic_type passes.
  • No regression in cargo test --release -p ori_llvm --test aot generics.
  • Run /improve-tooling retrospectively on §03.2.
  • Run /sync-claude on §03.2 — collect_mono_functions internal dedup key changed; check llvm.md §Type-Qualified Mangling + repr.md §RP-6 declaration-order ↔ memory-order.
  • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

03.3 Matrix tests — generic-receiver inherent methods

File(s): compiler_repo/compiler/ori_llvm/tests/aot/generics.rs

Matrix:

Receiver shapeInner type TMethod shapeTest name
Box<T>int@unwrap (self) -> Ttest_box_int_unwrap
Box<T>str@unwrap (self) -> Ttest_box_str_unwrap
Box<T>[int]@unwrap (self) -> Ttest_box_list_int_unwrap
Box<T>struct@unwrap (self) -> Ttest_box_struct_unwrap
Wrapper<T> (nested)Box<int>@inner (self) -> Ttest_wrapper_box_int_inner
Holder<T>int@map (self, f: T -> T) -> T (method body has internal let)test_holder_int_map_int
  • Author all 6 matrix tests + corresponding .ori fixtures.
  • Each test pins both Ok behavior + semantic pin (regression guard if §03.2 dedup change reverted).
  • Negative pin: test_box_method_with_drifted_args_emits_typeck_error — method-args/impl-args drift produces clean E2xxx, not E5001 codegen crash.
  • Subsection close-out (03.3)status: complete:
    • All 6 matrix tests + 1 negative pin pass.
    • timeout 150 diagnostics/dual-exec-verify.sh tests/aot/generics.rs — interpreter/LLVM parity holds.
    • Run /improve-tooling retrospectively on §03.3.
    • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

03.4 AOT export surface — multi.rs::public_methods + extract_public_method_types (per Decision 02)

Files (line coordinates verified at HEAD f5a37d327; refresh per §03.1.0 before authoring code if drift detected):

  • compiler_repo/compiler/oric/src/commands/build/multi.rs:331extract_public_function_types call site (top-level only today)
  • compiler_repo/compiler/oric/src/commands/build/multi.rs:195-230CompiledModuleInfo struct decl; public_functions: Vec<(String, Vec<ori_types::Idx>, ori_types::Idx)> field at line 212
  • compiler_repo/compiler/oric/src/commands/build/multi.rs:414-423CompiledModuleInfo construction (post-extraction)
  • compiler_repo/compiler/oric/src/commands/build/multi.rs:402extract_public_function_types definition (helper §03.4’s extract_public_method_types mirrors); pub-function loop body at line 475
  • compiler_repo/compiler/oric/src/commands/compile_common.rs:206imported_mono_fns: &[super::ImportedMonoFn] param; compile_common.rs:217-234import_sigs construction (Decision 02 scope = AOT side); call to run_codegen_pipeline at compile_common.rs:236-253

03.4.1 ImplMethodInfo carrier shape (RECEIVER-BEARING — load-bearing)

The public_methods exporter MUST carry the receiver Idx (the FULL concrete or generic-shell receiver type), NOT just the receiver type’s string name. Stripping the Idx shell to (receiver_type_name: String, method_name: String, FunctionSig) loses the discrimination data §03.2’s (Name, Option<Idx>)-keyed impl_sig_by_name lookup is built against — this is the data-shape contract per frontmatter’s unified-MonoInstance-tuple-shape success_criteria row.

Verbatim carrier shape:

pub(super) struct ImplMethodInfo {
    /// Receiver type's Idx in the source module's type pool — generic shell
    /// (e.g., Idx of `Box<_>` with type params as Tag::BoundVar) so post-
    /// re-interning at the host module gives a stable lookup key for
    /// `impl_sig_by_name` per §03.5's keyed dispatch.
    pub(super) receiver_type_idx: ori_types::Idx,
    /// Interned method name on the host's interner (post-re-intern).
    pub(super) method_name: ori_ir::Name,
    /// Method signature with Self placeholder substituted; param/return Idx
    /// values in source-module pool coordinates (re-interned at host).
    pub(super) sig: ori_types::FunctionSig,
}

03.4.2 multi.rs public_methods exporter wiring

  • Add public_methods: Vec<ImplMethodInfo> field to CompiledModuleInfo at multi.rs:212 (alongside existing public_functions). Populate at construction site multi.rs:414-423 via new extract_public_method_types call paralleling extract_public_function_types at line 331.
  • Add extract_public_method_types helper in multi.rs mirroring extract_public_function_types at line 402. Walks TypeCheckResult.impl_registry for the source module, filters to pub impl methods (per impl<T> Box<T> { @method } where the enclosing impl block OR the method declaration carries pub), returns Vec<ImplMethodInfo> with receiver Idx set to the impl’s receiver_type_idx (post-substitution with Tag::BoundVar for type params, i.e., the generic shell). Per impl block: enumerate each pub method, construct one ImplMethodInfo carrying (receiver_type_idx, method_name, sig).
  • Extend compile_common.rs consumer wiring: at compile_common.rs:206-234, after import_sigs is constructed (lines 217-234), construct a parallel imported_impl_sigs: Vec<(Name, Option<Idx>, FunctionSig)> from each imported CompiledModuleInfo.public_methods Vec. Re-intern method names + re-map receiver Idx into the host’s merged pool (mirrors §02.3’s build_imported_mono_state re-interning path at multi.rs::build_imported_mono_state re-interning path). The Option<Idx> shell carries Some(receiver_type_idx_in_host_pool) for every method (None reserved for top-level/no-receiver, matching the §03.5 imported_impl_sigs parameter shape; see §03.5 Data-Shape Contract block).
  • Thread through codegen pipeline: pass &imported_impl_sigs alongside existing &import_sigs in the call to run_codegen_pipeline at compile_common.rs:236-253; downstream run_codegen_pipeline → run_borrow_inference → collect_mono_functions chain accepts the new parameter (wired at §03.5).
  • Update multi.rs unit tests to cover public_methods enumeration: positive (pub impl method exported with correct receiver_type_idx), negative (private impl method NOT exported), edge (impl block where the impl is pub but a contained method is not, AND inverse — impl is not pub but a method is pub).

03.4.3 Subsection close-out (03.4) — status: complete

  • cargo build --release && cargo build both succeed.
  • cargo test --release -p oric --test build reports same pass count plus the new public_methods exporter tests.
  • Manual end-to-end repro: 2-module fixture under tests/aot/fixtures/imported_methods/ (a sibling module defines pub impl<T> Box<T> { @unwrap (self) -> T }; host imports + calls b.unwrap() for Box<int>) — verify extract_public_method_types populates public_methods with ImplMethodInfo { receiver_type_idx: Idx(Box<_>), method_name: unwrap, sig: ... } via ORI_LOG=oric=debug capture.
  • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

03.5 Cross-module impl_sig_by_name dispatch — consult imported method sigs (per Decision 02)

Files (line coordinates verified at HEAD f5a37d327; refresh per §03.1.0 if drift detected):

  • compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:59 (collect_mono_functions signature)
  • compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:70-75 (impl_sig_by_name construction; §03.2 converts to (Name, Option<Idx>) key)
  • compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:89-97 (per-instance dispatch loop; receiver-bearing branch at lines 112-113; silent-skip at lines 119-128)
  • compiler_repo/compiler/oric/src/test/runner/arc_lowering.rs:39 (test-runner symmetric wiring per §02.2 precedent)
  • compiler_repo/compiler/ori_llvm/src/evaluator/compile.rs:232 (JIT call site — passes &[] for both import_sigs and imported_impl_sigs per JIT-single-module carve-out)

03.5.1 Data-Shape Contract (load-bearing — codex + gemini convergence cure)

collect_mono_functions parameter shape MUST be:

pub fn collect_mono_functions(
    mono_instances: &[MonoInstance],
    function_sigs: &[FunctionSig],
    impl_sigs: &[(Name, FunctionSig)],                       // host-module methods (§02 unchanged)
    import_sigs: &[(Name, FunctionSig)],                     // cross-module top-level (§02 landed)
    imported_impl_sigs: &[(Name, Option<Idx>, FunctionSig)], // §03.5 NEW — RECEIVER-BEARING
    interner: &StringInterner,
    pool: &Pool,
) -> Vec<MonoFunction>

The Option<Idx> slot in imported_impl_sigs carries the generic-shell receiver Idx for every entry (Some(generic_shell)); the None discriminant is reserved for future top-level-from-method-table cases and is currently unused by §03.4’s exporter (which always emits Some(receiver_type_idx)). Stripping the Option<Idx> to &[(Name, FunctionSig)] (top-level shape) loses the per-receiver discrimination §03.2’s impl_sig_by_name lookup is keyed against, collapsing Box<int>.unwrap and Box<str>.unwrap back to the first-match failure mode this section cures. The shape MUST match §03.4’s extract_public_method_types output projection (after host-pool re-interning) and §03.2’s (Name, Option<Idx>) lookup key — single data shape across emit / export / consume per impl-hygiene.md §SSOT.

03.5.2 Lookup-chain extension

  • Extend collect_mono_functions signature at monomorphize/mod.rs:59 to accept imported_impl_sigs: &[(Name, Option<Idx>, FunctionSig)] after the existing import_sigs parameter. Parameter order matches §02’s import_sigs precedent (top-level extension first, then method extension); shared key shape per §03.2/§03.5.1.
  • Populate unified impl_sig_by_name at monomorphize/mod.rs:70-75 from BOTH impl_sigs (host module — re-keyed by §03.2 to (name, receiver_generic_pattern)) AND imported_impl_sigs (cross-module — already carries (name, Option<Idx>, sig)). Host-wins-on-collision: iterate host impl_sigs first, then imported_impl_sigs with entry.or_insert semantics (first-match preserved per §02.1’s import_sig_by_name shape). Receiver Idxes from imported_impl_sigs must be re-interned into the merged host pool BEFORE insertion (re-interning landed at §03.4 in compile_common.rs:217-234 extension).
  • Verify per-instance dispatch at monomorphize/mod.rs:89-97: when instance.receiver_type.is_some(), the receiver-bearing branch at line 112-113 consults the unified impl_sig_by_name. With imported method sigs registered, BUG-04-091 fixtures (Box<int>.unwrap, Box<str>.unwrap) lookup non-empty → no silent skip at lines 119-128 → no E5001 at LLVM verification.
  • Wire imported_impl_sigs through codegen pipeline: from compile_common.rs:236-253 run_codegen_pipeline call (which §03.4 extends to forward the new parameter), through codegen_pipeline/mod.rsrun_borrow_inference (which collect_mono_functions is called from), into the test runner at arc_lowering.rs:39 symmetrically (passes &[] empty slice when no imported_impl_sigs available for the test scope). The JIT call site at evaluator/compile.rs:232 passes &[] for imported_impl_sigs (mirror §02’s &[] for import_sigs) — cross-module imported-method dispatch is AOT-only per JIT single-module carve-out (per frontmatter dual-exec-parity carve-out + 00-overview.md Extension-Surface Map §03 row).

03.5.3 Named imported-method matrix (cures codex blind-spot 2026-05-16 finding 3)

Per Decision 02 frontmatter row, the specific imported-method matrix Option<int>.unwrap(), Result<int,str>.ok(), [int].first() MUST land as explicit AOT test fixtures in §03.5 (NOT deferred to §06). Tests + fixtures:

Test nameReceiver shapeMethodFixture path
test_imported_method_option_int_unwrapOption<int> (imported)unwraptests/aot/fixtures/imported_methods/option_int_unwrap/{lib.ori,main.ori}
test_imported_method_result_int_str_okResult<int, str> (imported)oktests/aot/fixtures/imported_methods/result_int_str_ok/{lib.ori,main.ori}
test_imported_method_list_int_first[int] (imported)firsttests/aot/fixtures/imported_methods/list_int_first/{lib.ori,main.ori}

Each fixture: lib.ori defines pub impl<T> X<T> { @method ... }; main.ori imports and invokes for the concrete T. Driver wiring follows §02.4’s compile_to_llvm_with_imported_monos pattern at commit 3bb8aa725; per-test assertion follows tests/aot/poly_lambda_mono.rs shape (verify cargo test --release -p ori_llvm --test aot returns the expected runtime value AND ORI_LOG=ori_llvm::monomorphize=debug shows zero silent-skip firings on the matrix fixtures per frontmatter MONO-REG invariant row).

  • Author the 3 fixtures + 3 tests above.
  • Each test pins both Ok behavior (returns expected unwrapped/ok/first value) AND semantic-pin (regression guard if §03.5 wiring reverted — test name asserts the cross-module dispatch path was exercised).
  • Negative pin: test_imported_method_box_int_method_receiver_mismatch — invoke imported method on receiver whose concrete type does NOT match any registered impl produces clean E2xxx typeck error (NOT E5001 codegen crash).

03.5.4 collect_mono_functions unit tests

  • Add to monomorphize/tests.rs: positive (test_collect_mono_imported_impl_method_resolves) — imported_impl_sigs populated with (unwrap, Some(Idx(Box<_>)), sig); instance carries receiver_type: Some(Idx(Box<int>)); verify resolution non-empty + correct sig. Negative (test_collect_mono_top_level_does_not_consult_imported_impl_sigs) — top-level instance with receiver_type: None AND name matching an imported_impl_sigs entry: must NOT resolve via the imported_impl path (top-level chain only). Matrix coverage parallel to §03.3 (6 receiver-type × method shapes) under cross-module fixture topology.

03.5.5 Subsection close-out (03.5) — status: complete

  • test_generic_method_on_generic_type un-ignored AND passes (#[ignore] reason removed; un-ignore landed at §03.2.2).
  • All 6 §03.3 matrix tests + 3 §03.5.3 imported-method matrix tests + new monomorphize/tests.rs unit tests pass.
  • timeout 150 diagnostics/dual-exec-verify.sh tests/aot/generics.rs — interpreter/LLVM parity holds (JIT-eligible tests; AOT-only cross-module imports are exempt per frontmatter dual-exec carve-out, tagged with // AOT-only: cross-module imported-method; JIT scope is single-module per evaluator/compile.rs:232).
  • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

03.R Third Party Review Findings

Populated by /tpr-review at §03.N.


03.N Completion Checklist

  • All 03.1, 03.2, 03.3, 03.4, 03.5 subsections status: complete (verify against frontmatter blocks_section_close: array).
  • §02 prerequisite-output gate (frontmatter success_criteria row) satisfied: §02.N close-out unchecked items resolved OR §03.4 / §03.5 gating documented as deferred until §02.N close (per gate rule — local §03.1-§03.3 may complete under partial §02.N close).
  • §03.5.3 named imported-method matrix shipped: test_imported_method_option_int_unwrap + test_imported_method_result_int_str_ok + test_imported_method_list_int_first pass via cargo test --release -p ori_llvm --test aot.
  • /tpr-review clean across reviewer set.
  • /impl-hygiene-review clean after TPR.
  • python -m scripts.plan_corpus check plans/aot-mono-completeness/section-03-inherent-method-mono.md exit 0.
  • cargo st green for tests/spec/traits/ + tests/spec/generics/ corpus (inherent-method mono on generic receivers — both JIT and AOT consume impl_sig lookup-chain semantics §03.5 hardens; per overview Mission Success Criteria cargo st regression-guard row + section frontmatter success_criteria row 13 cargo st regression-guard).
  • BUG-04-091 tracker entry annotated <!-- delivered-by: plans/aot-mono-completeness/section-03-inherent-method-mono.md --> (retirement at §07).
  • Section frontmatter flipped to status: complete, reviewed: true.

HISTORY

  • 2026-06-07 §03 line-coordinate refresh — HEAD 59f645300: all §03 body + frontmatter citations refreshed (monomorphize/mod.rs signature :71→:59, impl_sig_by_name :86-90→:70-75, dispatch loop :107-118→:89-97, silent-skip :119-128→:98-110, mangle :130-138→:112-120; multi.rs CompiledModuleInfo :203→:195, public_functions :212→:204, extract call :346→:331, definition :444→:402; method_call.rs infer_method_call :23→:24, infer_method_call_named :105→:106; maybe_record_mono_instance relocated to infer/expr/calls/monomorphization.rs:31 by the calls-module split; JIT site compile.rs :230→:232; AOT consumption codegen_pipeline/mod.rs :138→:143; compile_common.rs imported params now bundled as ImportedSurfaces per §02 hygiene refactor). §02 prerequisite gate VERIFIED: §02 status complete + reviewed true; collect_mono_functions signature carries import_sigs parameter — §03.4/§03.5 fully unblocked.

  • 2026-05-17 — /review-plan editor pass on section-03-inherent-method-mono.md (Step 5 single-section mode, run_id wa1): integrity audit reported 1 Minor status-text-drift (body Status: Not Started vs frontmatter in-review) + 3 informational findings (cited-subsection-resolution / depends-on-vs-citation-drift forward-references / depends-on-closure §02 in-progress); blind-spots from codex + gemini + opencode surfaced 6 substantive items, all addressed. Edits landed:

    • (1) Line-coordinate refresh + §02 prerequisite-output gate (cures opencode + gemini blind spots): added §03.1.0 prerequisite task requiring git rev-parse HEAD SHA record + verification of monomorphize/mod.rs / multi.rs / compile_common.rs / method_call.rs line citations against HEAD before code authoring. Refreshed all body line numbers to current HEAD f5a37d327 (monomorphize/mod.rs:59 for signature; :86-90 for impl_sig_by_name construction; :107-118 for dispatch loop; multi.rs:195-230 for CompiledModuleInfo; :346 for extract call; :444 for definition; compile_common.rs:217-253 for run_codegen_pipeline wiring). Encoded §02 prerequisite gate in frontmatter success_criteria + §03.1.0 task block — §03.4/§03.5 BLOCKED until §02.3+§02.4+§02.N resolved; §03.1-§03.3 may proceed under partial §02.N close (cures gemini blind-spot 2026-05-17 finding 4).
    • (2) Data-shape contract unification (cures codex + gemini convergence): added §03.4.1 ImplMethodInfo carrier struct definition carrying receiver_type_idx: Idx (NOT receiver_type_name: String); added §03.5.1 Data-Shape Contract block with verbatim collect_mono_functions signature carrying imported_impl_sigs: &[(Name, Option<Idx>, FunctionSig)] (NOT &[(Name, FunctionSig)]). Encoded the unified tuple shape in frontmatter unified-MonoInstance-tuple-shape success_criteria row — single data shape across emit (§03.1) / export (§03.4) / consume (§03.5) per impl-hygiene.md §SSOT.
    • (3) Named imported-method matrix added inline (cures codex blind-spot 2026-05-16 §2): added §03.5.3 block with 3 explicit AOT tests (test_imported_method_option_int_unwrap / ..._result_int_str_ok / ..._list_int_first) + fixture paths under tests/aot/fixtures/imported_methods/ mirroring §02.4’s imported_generics/ layout. Removed deferral to §06; matrix is part of §03.5 deliverables.
    • (4) Ordering primitives added to frontmatter (cures opencode blind-spot finding 6): subsection_depends_on: {"03.2": ["03.1"], "03.3": ["03.2"], "03.4": ["03.1"], "03.5": ["03.2", "03.4"], "03.R": ["03.5"], "03.N": ["03.R"]} + blocks_section_close: ["03.1", "03.2", "03.3", "03.4", "03.5", "03.R", "03.N"] — mirrors §02 frontmatter pattern at section-02-import-sigs-traversal.md:23-35. §03.5 explicitly depends on both §03.2 (lookup key shape) AND §03.4 (exporter for imported_impl_sigs source).
    • (5) Section restructure: split §03.1 into §03.1.0 (prerequisite verification) + §03.1.1 (typeck emission cure); split §03.2 into §03.2.1 (keyed-lookup conversion) + §03.2.2 (un-ignore + parity) + §03.2.3 (close-out); split §03.4 into §03.4.1 (carrier shape) + §03.4.2 (exporter wiring) + §03.4.3 (close-out); split §03.5 into §03.5.1 (data-shape contract) + §03.5.2 (lookup-chain extension) + §03.5.3 (named matrix) + §03.5.4 (unit tests) + §03.5.5 (close-out). Restructure preserves subsection-id stability (frontmatter sections: array unchanged); §03.1.0/§03.2.1/etc are sub-tasks within parent subsection scope.
    • (6) Status-text drift cohesion fix (cures Step 1.7 INTEGRITY:status-text-drift Minor): body Status: line at line 52 updated from Not StartedIn Review matching frontmatter status: in-review; status semantics annotated with flip rule referencing the §02 prerequisite gate.
    • (7) Updated §03.N completion checklist to reference frontmatter blocks_section_close: array + §03.5.3 named matrix + §02 prerequisite gate. No structural promotion / splits / new sibling sections required — restructure stayed within §03 subsection scope per routing.md §4 budget thresholds (§03 body line count remains under default 300-line budget cap per routing.md §5).
  • 2026-05-17 — /tpr-review round 1 cures (Step 6 round 1, run_id uuuxx4cd; codex + gemini + opencode reviewer set; fork-context Opus adjudicator): round verdict: 6 actionable findings (1 High agreement-cluster codex+opencode + 5 singletons); 3 false positives rejected by adjudicator (gemini misread intentional host-vs-cross-module shape asymmetry: host impl_sigs re-keyed at lookup site per §03.2.1, cross-module imported_impl_sigs serializes receiver_idx in the parameter because impl block resides in another module). Cures applied:

    • (1) [High] 00-overview.md:118 Extension-Surface Map row for §03: imported_impl_sigs: &[(Name, FunctionSig)]&[(Name, Option<Idx>, FunctionSig)] matching §03.5.1 Data-Shape Contract; added inline rationale referencing the receiver-discrimination invariant.
    • (2) [Medium] section-03:309 ordinal drift: success_criteria row 4 cargo st regression-guardrow 13 cargo st regression-guard (row 4 is test_generic_method_on_generic_type passes; row 13 is the cargo st regression-guard entry).
    • (3) [Minor] section-03:69 status-line parenthetical strip: **Status:** In Review (per frontmatter...flipped to in-progress...)**Status:** In Review — the flip semantics live in success_criteria + §03.1.0, duplicating in status line was rationale-prose per skill-vocabulary.md §3.
    • (4) [Minor] section-03:142 Pool::generic_shell algorithm spec: amended the citation block with explicit depth-first traversal rule for nested generic args, byte-identical-Idx round-trip invariant via ori_types::canon, and scripts/intel-query.sh symbols Pool reuse-search directive per types.md §TY-3/§TF-2.
    • (5) [informational] section-05:20 depends_on: ["01", "02", "04"]["01", "02", "03", "04"] — adds §03 as predecessor since both §03.5 and §05 extend collect_mono_functions parameter list (parameter-composition safety for DAG traversal).
    • (6) [informational] section-03:22 TPR-session provenance citation in success_criteria body: stripped (per gemini blind-spot 2026-05-16 finding 4) from the §02 prerequisite-output gate criterion — provenance now lives in this HISTORY entry vs the prescriptive success_criteria text per state-discipline.md §7. Round-loop state-machine note: record-verdict accepted 6 actionable findings then next round-step emitted exit_clean with rounds_completed: 0 instead of apply_cures — script-state-machine inconsistency between verdict-acceptance and round-step transition. Findings cured inline per /tpr-review §7 “Fix NOW” disposition; script gap filed via /add-bug for future-runs preservation. Round exit: clean (no actionable findings remain post-cure).
  • 2026-05-17 — /commit-push halt skipped — halt_reason: extended_check_fail, failing repo: /home/eric/projects/ori_lang/compiler_repo, scope: cross-scope (parallel-session AIMS burden-lower work failing compiler_repo pre-commit full-check; this session’s cures land entirely in plan-body .md files under plans/aot-mono-completeness/, /home/eric/projects/ori_lang wrapper repo only): per skill-control-contract.md §Autopilot Mode unified hook-failure clause, autopilot proceeds without committing this round’s cures; whoever owns the parallel-session compiler_repo work clears the dirty tree via user-typed /commit-push --bypass (Claude NEVER initiates bypass per feedback_commit_push_bypass_flag.md). Working-tree cures preserved for next user touchpoint or downstream /commit-push run.

  • 2026-06-07 — §03.3 matrix authored; verification blocked on cross-scope ori_arc mid-refactor: all 6 §03.3 positive matrix cells + the negative pin authored as AOT tests in compiler/ori_llvm/tests/aot/generics.rs with fixtures under tests/aot/fixtures/generics/test_box_int_unwrap / test_box_str_unwrap / test_box_list_int_unwrap / test_box_struct_unwrap / test_wrapper_box_int_inner (nested Wrapper<Box<int>>.inner()Box<int>.unwrap()) / test_holder_int_map_int + test_box_method_with_drifted_args_emits_typeck_error. The Holder cell’s fixture was corrected from the prior @transform (self) -> T (no closure param) to the matrix-mandated @map (self, f: T -> T) -> T with internal let — the original under-covered the closure-parameter-on-monomorphized-method dimension the cell exists to exercise (the test name test_holder_int_map_int already named “map”); the closure path is now exercised per the plan matrix rather than designed around (INVERTED-TDD ban). Verification (all 6 + negative pin pass; +7 vs 83/23 baseline; dual-exec parity) is BLOCKED: cargo check -p ori_arc fails (BurdenAnalysisCtx lacks transfer_through_return_results, referenced in burden_lower/{mod,emit,ownership_scans,tests}.rs) — an uncommitted, incomplete mid-refactor owned by the parallel aims-burden-tracking session. Per Git Safety this session does NOT edit that struct (parallel-held uncommitted work). §03.3 left OPEN/unverified; authored test code preserved in the working tree (uncommitted — /commit-push would halt on the same cross-scope extended_check_fail). Verify + flip §03.3 close-out when ori_arc compiles. Blocker is out of this session’s reach; the recurring /loop (5-min cron) owns retry.

  • 2026-06-07 — §03.3 matrix verified after ori_arc unblocked: 2/7 pass, 5/7 expose an umbrella layout-substitution facet owned by §04/§08 (NOT a new bug, NOT in-section to fix): parallel aims-burden-tracking session landed its BurdenAnalysisCtx refactor; ori_arc + ori_llvm build again. Ran the §03.3 matrix (release AOT). RESULTS: test_box_int_unwrap PASS + test_box_method_with_drifted_args_emits_typeck_error PASS — these validate §03’s actual deliverable (inherent-method mono registration on a generic receiver works end-to-end for an int receiver; the mangled mono method _ori_unwrap$..SBox3_str.. is emitted, so registration is sound). The other 5 cells FAIL on ONE root cause: a generic type parameter T (Idx(141), Tag::named) is NOT substituted in monomorphized type positions, surfacing as ori_llvm::codegen::type_info::store warn “Named/Applied/Alias type has no Pool resolution” → TypeInfo::Errori64 fallback → E5001 Invalid InsertValueInst operands. Two manifestations of the same gap: (a) generic-struct FIELD layout — type_info/store.rs:320 Tag::Applied (Box<str>) resolves via resolve_fully to the GENERIC Box<T> struct whose struct_fields are [T] unsubstituted, emitting a single shared %ori.Box = type { i64 } for ALL instantiations (box_str / box_list_int / box_struct; wrapper_box_int_inner where the field is the nested generic Box<int> struct vs the scalar-i64 fallback); (b) closure-param function-type in a mono method signature — Holder<int>.@map (self, f: (T) -> T) keeps T unsubstituted in the (T) -> T param type. Isolation proof: /tmp/box_str_nomethod.ori (a Box<str> constructed + field-accessed with ZERO methods) reproduces the identical %ori.Box = type { i64 } + E5001 — so this is a pre-existing generic-struct/type instantiation-layout gap, fully independent of §03’s method-mono work. OWNERSHIP: per 00-overview.md (this plan IS the cure for the architectural-completeness gap; “do NOT fix these tests individually outside their owning section; built bottom-up”), the layout-substitution facet is owned by §04 (Complex-Generic-Arg Method Mono — Wrapper<Box<int>> is exactly “receivers whose type params are themselves complex generics”) + §08 (whose absorbed crash chain at this section’s 2026-05-16 §08 inline-absorbed HISTORY is verbatim “insert_value on non-struct value (index 0) — type resolution produced wrong layout”). No new /add-bug filed (umbrella owns it; a separate bug would be PLAN_ROUTING_DRIFT). No out-of-section hand-fix (violates the plan’s bottom-up rule). PLAN-COHERENCE note for §04/§06/§07 owners: §03.3’s matrix as authored embeds 5 cells whose cure lands in §04/§08 — an undeclared backward dependency (§03.3 ← §04/§08). Cleanest resolution at the owning sections: declare §03.3’s 5 non-int-layout cells blocks_section_close-deferred to the §06 full-matrix sweep (which runs AFTER §04/§08’s layout-substitution cure), leaving §03.3 to pin only what §03 delivers (box_int + negative pin). The 5 authored cells are correct regression pins for the cure and MUST stay. AUTHORING FIX this round: the Holder fixture’s f: T -> T (informal plan-matrix notation) was grammar-invalid — grammar.ebnf:361 function_type = "(" [ type {"," type} ] ")" "->" type requires parens — corrected to f: (T) -> T (parser was right; E1001 was my fixture bug, not a compiler bug). §03.3 stays OPEN (5 cells blocked by §04/§08). Test authoring preserved in working tree (uncommitted; /commit-push halts on the parallel session’s red test_borrow_list_int_*/test_edge_* baseline extended_check_fail).

  • 2026-06-07 — §03.3 generic-struct-instantiation-layout cure LANDED: 6/7 cells pass (the prior “owned by §04/§08” read was WRONG — the served §03 success_criteria scope these cells to §03 itself): per the orchestrator-served §03 success_criteria (“Matrix: impl Box { @method } × {int, str, [int], struct}” + “Wrapper × {nested impl, …}”), the non-int cells are §03’s OWN deliverable, so “do NOT fix tests outside their owning section” MANDATES fixing them here. Root cause: register_concrete_applied_resolutions (infer/expr/calls/monomorphization.rs) only registers Applied → concrete Struct resolutions for Applied types found as VALUES in a mono instance’s body_type_map (binder substitutions {Named("T") → str}). For an inherent method the receiver’s concrete Box<str> is the self type, NEVER a body_type_map value — so its concrete struct layout was never registered, and codegen’s type_info/store.rs:320 Tag::Applied fell back to the generic Box<T> (single shared %ori.Box = type { i64 }). Box<int> passed only by i64-fallback coincidence (false pass). Free functions were unaffected because their param types ARE body_type_map values (why §02.4’s top-level matrix passed). TWO-PART FIX, both in UNCHURNED files (decoupled from the parallel calls/ refactor):

    • (1) monomorphization.rs maybe_record_method_mono_instance: after build_and_register_body_type_map, also resolve_applied_type(pool, receiver, &struct_type_params) to register the receiver’s concrete Applied → Struct resolution (recurses into nested generic fields → Wrapper<Box<int>> also registers its Box<int> field). Typeck structurally-interns Box<str> once (TI-1), so the @main construction-site Idx shares the resolution.
    • (2) pool/construct/mod.rs Pool::generic_shell: derive the dispatch shell from the receiver’s OWN Tag::Applied structure (the set_resolution side-map never changes the tag) instead of resolve_fully-first — resolve_fully only when the receiver is not already Applied. Without (2), (1) regressed box_int to “missing mono instance”: registering Box<int> → Struct made resolve_fully(Box<int>) collapse to the Struct, breaking §03.2’s (method, Box<_>) dispatch key. generic_shell is the one §03.2 site that wasn’t resolution-robust (nominal_type_name already handles both Applied and Struct). Isolated empirically by reverting (1) alone: box_int passed, proving (1)+(2) jointly required.
    • VERIFIED (release AOT): test_box_int_unwrap / test_box_str_unwrap / test_box_list_int_unwrap / test_box_struct_unwrap / test_wrapper_box_int_inner (nested) / test_box_method_with_drifted_args (negative pin) all PASS — 6/7. NO regression introduced: §02 poly_lambda_mono stays 5/5; the other 32 generics failures are cross-scope parallel-aims-burden-tracking RC defects (ori_rc_dec on already-freed double-free + RC allocation not freed leak in test_borrow_list_int_*/test_edge_*/test_*forwarder*/test_path_sensitive_*) confirmed by their RC error class — NOT mono/layout, NOT my surface.
    • REMAINING (1/7): test_holder_int_map_int (Holder<int>.@map (self, f: (T) -> T) — closure param) fails “unresolved function map — missing mono instance”. Distinct axis: typeck DOES record the instance (recorded mono instance ... receiver=Idx(219)) + the receiver resolution fires, but codegen collect_mono_functions surfaces no usable map mono fn for the body-apply (no “skipping” log; LLVM aborts pre-emit). The closure-param second arg is the sole difference from the 6 passing cells; the local impl_sigs dispatch of a closure-param generic method needs tooling-first instrumentation (grep-level tracing isn’t converging) — recorded as the §03.3 remaining item, NOT abandoned. Holder fixture syntax already grammar-corrected to f: (T) -> T per grammar.ebnf:361.
    • COMMIT BLOCKED: the parallel session’s red RC baseline makes /commit-push halt on cross-scope extended_check_fail; the verified 2-part fix (monomorphization.rs + pool/construct/mod.rs) + §03.3 fixtures/tests stay preserved uncommitted until the parallel RC work greens (or user-typed /commit-push --bypass; Claude never initiates). §03.3 stays OPEN on the 1 Holder cell.
    • HOLDER LOCUS (refined, read-only trace — for the next instrumentation pass): map IS registered in impl_sigs (check/bodies/impls.rs:313 register_impl_sig, unconditional — no closure-param skip), and typeck records the instance + dispatch. The failure is in codegen apply-lookup resolve_callee (codegen/arc_emitter/apply.rs:175-191): for a generic method only lookup_mono_dispatch (apply.rs:136) can resolve it — via the mono_instance_id fast-path (ctx.mono_dispatch_by_id) OR the arg-type fallback (ctx.mono_dispatch[callee], matching resolve_fully(param)==resolve_fully(arg)). All 4 chain steps miss → “unresolved function map”. Most-likely cause: either the per-call-site mono_instance_id dispatch entry isn’t reaching map’s Apply carrier (so the fast-path is skipped), or the arg-type fallback fails matching the CLOSURE arg (int) -> int (function-type equality under resolve_fully). Tooling-first next step: add a tracing::debug! in lookup_mono_dispatch logging mono_instance_id.is_some(), mono_dispatch_by_id hit, and the arg-type-match params-vs-args — needs a stable build (parallel ori_arc is oscillating non-compiling).
    • HOLDER ROOT CAUSE (PINPOINTED via the added permanent tracing::debug! in lookup_mono_dispatch, arc_emitter/apply.rs): trace lookup_mono_dispatch arg-type fallback result callee=map n_entries=1 n_args=2 matched=false + NO “id fast-path” log. So: (1) map’s Apply carrier has mono_instance_id=None (the typeck record_mono_with_dispatch call_expr_id→MonoInstanceId entry is NOT reaching the ARC Apply carrier for this call shape — so the mono_dispatch_by_id fast-path is skipped); (2) the mono fn WAS built (n_entries=1); (3) the arg-type fallback’s per-element resolve_fully(param)==resolve_fully(arg) FAILS on the CLOSURE arg f (self matches; the (int) -> int closure param vs the lambda’s ARC type do not resolve_fully-equal). Contrast: the 6 working cells never reach lookup_mono_dispatch — they resolve at chain step 1 lookup_method_by_receivermethod_functions[(type, method)]. So closure-param (multi-arg) methods uniquely fall through to the arg-type fallback, which can’t match the closure parameter. This is an ORTHOGONAL pre-existing closure-param-method dispatch gap that the layout fix merely UNMASKED (Holder went “no Pool resolution” → “closure-arg dispatch miss”). FIX DIRECTION (two candidates, next pass): (a) publish mono_instance_id onto the closure-param method’s Apply carrier so the mono_dispatch_by_id fast-path resolves it (bypasses arg-matching) — the architecturally-cleaner path since the typeck dispatch entry already exists; OR (b) make the arg-type fallback’s function/closure-type equality robust (the lambda’s ARC closure type vs the concrete (int) -> int param). (a) preferred. The tracing::debug! diagnostic stays committed-with-the-fix (uncommitted now per the commit-blocker). §03.3 OPEN on this 1 cell.
    • HOLDER FIX IMPLEMENTED (fix (a), the named-arg dispatch-publication gap): the extended tracing::debug! (lookup_mono_dispatch arg-mismatch detail) pinned it exactly — map’s self arg matches (param=Idx(225) Struct == arg=Idx(225) Struct, thanks to the layout fix) but the CLOSURE arg fails (param=Idx(221) Tag::function != arg=Idx(224) Tag::function, two structurally-distinct (int) -> int that don’t intern-equal in the fragile fallback). ROOT: h.map(f: ...) is a NAMED-arg call → ExprKind::MethodCallNamedori_canon::desugar::calls.rs::desugar_method_call_named, which built the same CanExpr::MethodCall as the positional lower_method_call BUT never called record_mono_dispatch_if_present — so the typeck mono_dispatch_map entry was never translated to the CanonResult.mono_dispatch_map_can carrier, leaving the ARC Apply mono_instance_id=None and forcing the fragile arg-type fallback. The 6 working cells use no named args (positional MethodCall, which DOES publish). FIX (3 files, all in ori_canon, decoupled from the parallel ori_arc/ori_types-calls churn): (1) desugar/calls.rs desugar_method_call_named gains a call_expr_id: ExprId param + calls self.record_mono_dispatch_if_present(call_expr_id, can_id) after the push (mirroring lower_method_call); (2) lower/expr.rs:300 passes id to it; (3) lower/collections.rs record_mono_dispatch_if_present bumped fnpub(crate) (cross-module call from desugar/). With the dispatch entry published, map’s Apply carries its mono_instance_id and lookup_mono_dispatch’s mono_dispatch_by_id fast-path resolves it directly — bypassing the closure-type-fragile arg-matching. CROSS-PLAN SEQUENCING DEPENDENCY (big-picture, grounded 2026-06-07): aot-mono-completeness is architecturally DOWNSTREAM of aims-burden-tracking, which is actively rebuilding the AIMS/repr/RC foundation this plan’s mono work sits on. Evidence: after aims-burden-tracking landed new commits, box_int (a §03.2 deliverable that passed earlier this session WITH my exact §03.3 changes) regressed to E5001 ret i8 %proj.0 vs i64; a decisive diagnostic — ./ori build <box_int_fixture> fails with repr-narrowing ON but BUILDS+RUNS (exit 0) with ORI_NO_REPR_OPT=1 — proves the regression is the foundation’s integer-narrowing change interacting with my concrete-generic-struct registration (the Box<int> field narrows to i8 while the unwrap projection return stays i64; a missing sext at the storage→return boundary). A separate Tag::rigid_var reaching codegen (PC-2) also surfaces (narrowing-independent). CONCLUSION: §03 mono-completeness CANNOT be reliably verified or committed while the AIMS/repr/RC foundation is in flight — each foundation landing re-invalidates the mono layer on top. The §03 fix (layout 2-part + Holder named-arg dispatch) is implemented and correct against a STABLE foundation. Correct sequencing: aims-burden-tracking foundation must STABILIZE (compile-green + RC-baseline-green) before §03 re-verification. Grinding §03 verification against the shifting foundation is futile (litter of churn windows, mid-run rebuilds, flapping box_int). PRIOR (now superseded by the above): VERIFICATION BLOCKED: ori_arc broke AGAIN under the parallel aims-burden-tracking session (E0061 arg-count mismatch at burden_lower/mod.rs:356 + ownership_scans.rs:170); ori_canon (which depends on ori_arc) + ori_llvm can’t build through it. The fix is sound (errors are entirely in parallel burden_lower, none in my 3 files); when ori_arc compiles, the Holder cell should pass → §03.3 7/7. The fix + the two tracing::debug! diagnostics stay preserved uncommitted with the rest of the §03 work.
    • 4TH-BUG ROOT (deepest, 2026-06-07, stable-window read-only RCA): the box_int/wrapper/holder int-field failure is NOT a missing-sext-at-projection bug per se — it is an UNSUBSTITUTED RigidVar(T) in the mono method body. The impl generic T is Named(T) in the resolved sig (impl_signature.rs substitute_named_in_pool) but RigidVar(T) (fresh var_id) in the body (check_impl_method binds impl generics as rigid vars). build_and_register_body_type_map maps only Named(T)->int; the body’s RigidVar(T) is missed. CRUCIALLY pool::substitute::build_mono_body_type_map masks on HAS_VAR|HAS_BOUND_VAR and explicitly handles BoundVar but EXCLUDES HAS_RIGID_VAR + substitute_in_pool does not substitute RigidVar by var_id — so even adding the impl rigid-var id to var_subst would not help without extending the mask + substitute_in_pool. So RigidVar(T) survives to codegen (PC-2 violation, type_info/store unreachable type tag rigid_var); sext_narrowed_field then sees dst_ty != Tag::Int (it is RigidVar) and skips the widen, leaving ret i8 vs i64 once repr narrows the field. My earlier pool.rigid_var(name) map attempt was INEFFECTIVE + REVERTED (line 266: rigid_var allocates a FRESH var_id each call, never matching the body’s). FIX DIRECTION (shared-substitution, deferred per the gate-and-wait decision until foundation stable+green): (1) extend build_mono_body_type_map mask to include HAS_RIGID_VAR + make substitute_in_pool substitute RigidVar(var_id) like BoundVar; (2) thread the impl rigid-var ids (scan the generic sig’s RigidVar leaves -> var_state name -> impl_type_args concrete) into var_subst. Touches foundation substitution machinery the parallel aims-burden-tracking work may also edit -> author deliberately in a stable+green window, not a stable-but-RC-red one. Two permanent tracing::debug! diagnostics in lookup_mono_dispatch (apply.rs) remain for the next pass.
  • 2026-06-07 — §03.3 re-verification against re-churned foundation: 4/7 pass; gate still HALF-met (RC-baseline red); blocker confirmed out-of-reach: foundation re-grounded at HEAD 2785086a4 (new landings since prior session: ec8f82397 feat(typeck): resolve impl-level generic params as RigidVars for method dispatch + f9d1304f6 + 2785086a4 monomorphization refinement). cargo check -p ori_llvm -p ori_canon -p ori_arc -p ori_types GREEN and cargo build --release -p ori_llvm --test aot GREEN — the prior ori_arc-won’t-compile blocker is CLEARED. Ran the §03.3 release-AOT matrix: PASS test_box_str_unwrap / test_box_list_int_unwrap / test_box_struct_unwrap / test_box_method_with_drifted_args_emits_typeck_error (negative pin) = 4/7; FAIL test_box_int_unwrap / test_wrapper_box_int_inner / test_holder_int_map_int = 3/7. box_int REGRESSED from the prior session’s pass — the exact documented oscillation: the foundation’s RigidVar-method-dispatch landing (ec8f82397) re-invalidated the §03 layer (unsubstituted RigidVar(T) → repr-narrowing missing-sext → E5001, per the 4TH-BUG ROOT entry above). The documented RigidVar fix direction (build_mono_body_type_map mask + substitute_in_pool) is BLOCKED OUT OF REACH this session: (a) ec8f82397 just rewrote the impl-generic→RigidVar binding the prior RCA targeted — that RCA is now stale and a fix authored against it would mis-target; (b) the foundation RC-baseline is RED (generics 76 pass / 36 fail; the 32 non-§03 failures are parallel-aims-burden-tracking RC TDD-pins test_borrow_list_int_* / test_edge_* / test_path_sensitive_* / test_generic_forwarder_* — double-free/leak class, NOT mono/layout, NOT this surface), so no clean verification signal exists for any §03 fix; (c) the foundation is mid-signature-change (working-tree ori_types/.../tests.rs shows E0107 expected 7 arguments, found 6 on a foundation fn the parallel session is re-signaturing) — authoring into it races + clobbers parallel-held uncommitted work per Git Safety. GATE STATUS: compile-green YES, RC-baseline-green NO → §03 re-verification stays gated. §03.3 left OPEN (3 cells red; no false close per INVERTED-TDD ban). No out-of-section hand-fix; no /add-bug (umbrella owns it; aot-mono-completeness is downstream of aims-burden-tracking — a separate bug would be PLAN_ROUTING_DRIFT). Re-verify + close §03.3 when aims-burden-tracking greens its RC baseline (the 4/7 passing non-RigidVar cells prove the §03 layout fix in working-tree monomorphization.rs + pool/construct/mod.rs + impl_signature.rs sound for the non-RigidVar axis). STRUCTURAL GAP (root of the per-session re-discovery): this cross-plan dependency (aot-mono-completeness ← aims-burden-tracking foundation) is documented in HISTORY but NOT encoded as a routing-visible blocker, so the orchestrator keeps routing here and each session re-walks the wall.

  • 2026-06-07 — §03.3 re-confirm: blocker now IN-FLIGHT (RigidVar fix being staged by the parallel session); orchestrator livelock gap CURED: HEAD unchanged (2785086a4); §03.3 matrix re-run = same 4/7 pass, 3/7 fail (box_int / wrapper_box_int_inner / holder_int_map_int). NEW signal: the parallel aims-burden-tracking session is now actively STAGING the RigidVar substitution fix — compiler_repo working tree shows pool/substitute/mod.rs (the exact substitute_in_pool machinery the 4TH-BUG-ROOT fix direction names) + impl_lookup.rs + monomorphize/mod.rs index-modified (M , staged). Authoring the §03 RigidVar fix now would collide with their staged commit-prep (Git Safety: never touch parallel-staged work; 4TH-BUG-ROOT decision: author only in a stable+green window). The fix is the foundation session’s to land (pool/substitute = AIMS/repr layer owned by aims-burden-tracking); §03 consumes it. STILL BLOCKED OUT OF REACH; §03.3 left OPEN. ORCHESTRATOR FIX SHIPPED (separate /improve-tooling run 1780878502-34efc267, commit deferred cross-scope): the markdown _step_5_emit_focus handoff now wires route_progress_guard (progress-fingerprint self-reset) so a cross-plan-blocked subsection re-served with zero progress converges to route_no_completion_progress halt after the cap instead of infinite re-hand — validated live on §03.3 (converges hop 3). Re-verify + close §03.3 once aims-burden-tracking commits the RigidVar fix (the 3 cells should then pass; the recurring /loop cron owns retry).

  • 2026-06-07 — §03.3 MATRIX VERIFIED GREEN 7/7 (foundation RigidVar fix completed in-tree by the parallel session this turn); durable close pending the foundation COMMIT: the parallel aims-burden-tracking session resumed mid-turn and WIRED its RigidVar scaffold — check/registration/impls.rs (allocate impl_rigid_var_map per impl at registration, Pass 0c) + check/bodies/impls.rs + check/bodies/method_sig.rs (allocate_generic_binders reuses the registration-time RigidVars via prealloc) + pool/substitute/mod.rs (build_mono_body_type_map/substitute_in_pool masks now include HAS_RIGID_VAR; substitute_rigid_var + build_impl_rigid_var_subst consumed at impl_signature.rs:121 + monomorphization.rs:357). ori_types now compiles clean (dead-code gone). Ran the §03.3 release-AOT matrix: test_box_int_unwrap / test_box_str_unwrap / test_box_list_int_unwrap / test_box_struct_unwrap / test_wrapper_box_int_inner / test_holder_int_map_int / test_box_method_with_drifted_args_emits_typeck_error (negative pin) — ALL 7 PASS. The unsubstituted-RigidVar(T)→repr-narrowing→E5001 root (4TH-BUG-ROOT) is cured by the registration-time RigidVar alloc + reuse (the recording scan + body share identical var_ids). NOT YET CLOSED: (a) compiler_repo HEAD still 2785086a4 — the RigidVar fix is UNCOMMITTED working-tree (parallel session’s); per the documented trigger §03.3 closes after the foundation COMMIT, not against ephemeral state; (b) the broader generics run shows 35 failures = parallel aims-burden-tracking RC TDD-pins (test_borrow_list_int_*/test_edge_*/test_path_sensitive_*/test_generic_forwarder_* — their in-flight burden work, NOT §03 surface), so a §03.3 close-out /commit-push would sweep their incomplete RC baseline → halt. ACTION on the foundation commit: re-run the 7-cell matrix (expect 7/7) + dual-exec parity, then flip §03.3 → complete and advance to §03.4. Authoring the RigidVar fix myself was NOT needed (user-authorized takeover became moot — the parallel session completed it during the same turn); no §03-side code was written, no parallel work clobbered.

  • 2026-06-08 — §03.3 oscillating 6/7↔7/7; the ONLY non-passing cell (box_list_int_unwrap) DEFINITIVELY localized to the parallel session’s list-RC use-after-free (NOT §03 mono): as the parallel aims-burden-tracking session iterates its move/burden + list-RC realization, the §03.3 matrix oscillates (7/7 when their RC is stable, 6/7 when mid-broken). Localized the 6/7 state: box_list_int_unwrap exits -139 (SIGSEGV). Standalone repro (/tmp/bli.ori = the fixture) crashes WITH and WITHOUT ORI_NO_REPR_OPT=1 (so NOT a repr/layout interaction), gdb backtrace = ori_buffer_rc_dec_ori_main, and ORI_TRACE_RC shows a textbook UAF: the [1,2,3] buffer is dec→rc=0→FREED, then inc on the freed pointer (rc=1 (live=0)) → crash. Ownership is conclusive: EVERY non-list cell passes (box_int/box_str/box_struct/wrapper/holder/negative-pin) — only the [int]-LIST cell UAFs, in ori_buffer_rc_dec (list-RC), matching the parallel session’s 35 red test_borrow_list_int_* list-RC double-free/UAF failures. The RC placement is emitted by ori_arc (AIMS realization, aims-burden-tracking’s domain) — NOT §03’s mono registration (which works for the list cell; the crash is downstream in RC). NOT fixed here: per Git Safety + the user’s “ignore parallel agent issues” directive, §03 does not touch ori_arc/ori_rt list-RC. §03.3 stays OPEN on this one parallel-RC-collateral cell; the §03 mono deliverable is sound (6/7 mono-verified + the list cell’s mono works). Closes when the parallel list-RC stabilizes (box_list_int → green); recurring 5-min cron re-checks. No #[ignore] (the cell legitimately passes on a stable RC baseline — silencing it would game the gate).