96%

Section 01: Root Cause Analysis — Shared Monomorphization Completeness Gap

Status: Complete Goal: Build the gap map every downstream section will cite. Pure investigation; no .rs edits land in this section.

Context: All four absorbed bugs reduce to “an Apply / Invoke carrier exists in realized ARC IR for which collect_mono_functions did not register a MonoFunction.” Without a shared gap map, each downstream section risks re-discovering the same producer-phase boundary. Investigation up front prevents §02/§03/§04/§05 from each making slightly different assumptions about which phase creates the carrier (typeck vs canon mono_dispatch_map vs ARC-lowering builtin emission).

Reference implementations:

  • Rust rustc_monomorphize::collector::collect_used_items — driver-side mono collection traverses crate_inherent_impls + import_data + builtin call sites. Pattern: one driver, multiple instance sources.
  • Swift SILGen::emitConcretizationsForMonomorphicGenerics — similar shape; the registration site enumerates ALL call sites, including imported and builtin.

Plan-local invariant — MONO-REG (replaces incorrect aims-rules.md §IC-1 citation; IC-1 is SCC/topological ordering, NOT Apply-target registration):

Every Apply / Invoke carrier present in realized ARC IR SHALL have either (a) a registered MonoFunction in CodegenContext.mono_dispatch_by_id, OR (b) be a runtime/protocol ccc surface explicitly enumerated in §01.4’s out-of-scope list. Calling-convention classification per codegen-rules.md §AB-6: Ori user/imported/builtin functions → fastcc; runtime functions → ccc. Silent skip (the tracing::debug!("mono instance for unknown function — skipping") branch at compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:93-101) violates MONO-REG and surfaces as E5001 at LLVM module verification.

Depends on: None. This is the foundation section.

Intelligence Reconnaissance

Queries planned (run when this section starts; record outcomes here):

  • scripts/intel-query.sh --human file-symbols "compiler_repo/compiler/ori_llvm/src/monomorphize" --repo ori — full inventory of mono crate symbols + line spans
  • scripts/intel-query.sh --human callers "collect_mono_functions" --repo ori — every call site, blast radius for signature changes
  • scripts/intel-query.sh --human callers "MonoInstance" --repo ori — every site that constructs or consumes the record type
  • scripts/intel-query.sh --human callers "emit_apply" --repo ori — ARC-lowering Apply producers (BUG-04-114 producer-phase mapping)
  • scripts/intel-query.sh --human similar "collect_mono_functions" --repo rust,swift,lean4 --limit 5 — cross-language mono collection prior art

Results summary (recorded 2026-05-14) [ori]: callers collect_mono_functions returns 4 sites — JIT (evaluator/compile.rs:230), AOT (codegen_pipeline/mod.rs:138 via run_borrow_inference at line 77), and 2 unit tests (monomorphize/tests.rs:139,168). MonoInstance and emit_apply graph queries returned empty (graph-corpus embedding gap for these symbols); direct source reads via §01.1 sub-agent confirmed MonoInstance emission lives in ori_types::check and emit_apply is invoked from ori_arc::lower::collections::lower_cast + ori_arc::lower::calls::emit_call_or_invoke. similar collect_mono_functions returned no embedding (graph-corpus gap); reference-compiler patterns (rustc collect_used_items, swift SILGen::emitConcretizationsForMonomorphicGenerics) cited in §01 preamble. Blast radius for collect_mono_functions signature change: 4 callers (2 production + 2 tests); all 4 update in same commit per impl-hygiene.md §API Stability.

See .claude/skills/query-intel/compose-intel-summary.md for the full query protocol.


01.1 collect_mono_functions API surface + call-site inventory (JIT + AOT + evaluator)

File(s):

  • compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs
  • compiler_repo/compiler/ori_llvm/src/evaluator/compile.rs
  • compiler_repo/compiler/oric/src/commands/codegen_pipeline/mod.rs
  • compiler_repo/compiler/oric/src/commands/compile_common.rs
  • compiler_repo/compiler/oric/src/test/runner/imported_mono.rs

The function (compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:59):

pub fn collect_mono_functions(
    mono_instances: &[MonoInstance],
    function_sigs: &[FunctionSig],
    impl_sigs: &[(Name, FunctionSig)],
    interner: &StringInterner,
    pool: &Pool,
) -> Vec<MonoFunction>
  • Read compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs end-to-end and document: signature lookup logic (lines 66–102), mangling site (line 104), dedup site (lines 117–119), the silent-skip branch (lines 93–101).
  • Inventory ALL three call sites (JIT + AOT + evaluator) — confirmed via grep at scaffolding time, formalize during execution:
    • JIT (test-runner) path: compiler_repo/compiler/ori_llvm/src/evaluator/compile.rs:230 — calls collect_mono_functions(...) then extends with imported_mono_functions pre-built via build_imported_mono_functions (see next checkbox).
    • AOT (ori build) path: compiler_repo/compiler/oric/src/commands/codegen_pipeline/mod.rs:138 — calls collect_mono_functions(mono_instances, function_sigs, impl_sigs, interner, pool) from the AOT codegen pipeline; import_sigs is constructed at compiler_repo/compiler/oric/src/commands/compile_common.rs:206-223 but never passed (BUG-04-119 surface).
    • Evaluator pre-pass path: compiler_repo/compiler/oric/src/test/runner/imported_mono.rs:28build_imported_mono_functions constructs Vec<MonoFunction> separately from imported_generic_sigs map, returning ImportedMonoFn = (MonoFunction, usize, ori_ir::Name) tuples; evaluator extends collect’s output with these (separate-pass pattern).
  • Document the architectural divergence between JIT/evaluator pre-pass and AOT integrated path — and justify §02’s choice of integrated-signature (extend collect_mono_functions with import_sigs parameter) vs pre-pass (mirror build_imported_mono_functions on the AOT side). One-sentence justification target: integrated-signature wins for AOT because the AOT pipeline has no equivalent of the test-runner’s pre-built imported_generic_sigs map; replicating that map at AOT would create the second LEAK:scattered-knowledge site §02 explicitly cures.
  • Document the consumer contract — declare_mono_functions reads instance_ids to populate CodegenContext.mono_dispatch_by_id (lines 30–38 doc comment).
  • Subsection close-out (01.1) — flip subsection status: complete; record JIT/AOT/evaluator call-site table in this subsection for §02 (signature extension owner), §03/§04 (downstream consumers), and §05 (builtin emission caller).

§01.1 Findings (recorded 2026-05-14)

(per §01.1) — authoritative collect_mono_functions shape + call-site table for §02–§05 to cite.

F1 — Function shape (monomorphize/mod.rs)

SiteLinesBehavior
Function definitionmod.rs:59-65pub fn collect_mono_functions(mono_instances, function_sigs, impl_sigs, interner, pool) -> Vec<MonoFunction>
Signature lookup logicmod.rs:66-102Builds fn_sig_by_name (FxHashMap, line 71-72) and impl_sig_by_name (line 73-77, first-match via entry().or_insert() — load-bearing for BUG-04-091/BUG-04-061 H2 hypothesis); per-instance dispatch at mod.rs:88-92 (receiver_type.is_some() → impl, else top-level)
Silent-skip branchmod.rs:93-101let Some(generic_sig) = lookup else { tracing::debug!(... "mono instance for unknown function — skipping"); continue; }; — exact message at line 99. MONO-REG violation surface — every absorbed bug eventually hits this branch.
Manglingmod.rs:104-111mangle_mono_name(fn_name, generic_args, impl_args, method_args, interner, pool)
Dedupmod.rs:117-120if let Some(&existing) = name_to_index.get(&mangled_name) { result[existing].instance_ids.push(instance_id); continue; } — collapses by mangled name; instance_ids accumulator preserves caller-side mapping for declare_mono_functions

F2 — Call-site table (the three production paths + 2 tests)

PathCallerArgument shapeSource signatures
JIT (test-runner)evaluator/compile.rs:230-236(mono_instances, function_sigs, impl_sigs, interner, self.pool)LOCAL only; line 237 appends imported_mono_functions: Vec<MonoFunction> (passed as parameter to compile_module_with_tests, pre-built by §F4 path)
AOT (ori build)codegen_pipeline/mod.rs:138-144 (inside run_borrow_inference at mod.rs:77)(mono_instances, function_sigs, impl_sigs, interner, pool)LOCAL only — import_sigs parameter exists at run_codegen_pipeline:273 and is routed exclusively to fc.declare_imports(import_sigs) at mod.rs:430, never passed to collect_mono_functions. THIS IS BUG-04-119.
Test: collect_produces_concrete_sigmonomorphize/tests.rs:139unit-test fixture
Test: collect_skips_unknown_functionmonomorphize/tests.rs:168unit-test fixture

declare_mono_functions consumer contract (per mod.rs:30-38 doc comment on MonoFunction.instance_ids): “Consumed by declare_mono_functions to populate CodegenContext.mono_dispatch_by_id for the abstract-index dispatch path.” Both production callers invoke fc.declare_mono_functions(&mono_functions) (evaluator/compile.rs:339, codegen_pipeline/mod.rs:435).

F3 — JIT/evaluator pre-pass shape (imported_mono.rs)

ComponentCitationShape
Type aliasimported_mono.rs:22type ImportedMonoFn = (MonoFunction, usize, ori_ir::Name) — 3-tuple: (function, module_index, source_body_name)
Pre-pass functionimported_mono.rs:28pub(super) fn build_imported_mono_functions(type_result: &TypeCheckResult, imported_generic_sigs: &FxHashMap<Name, (FunctionSig, usize, Name)>, _per_module_caches: &[FxHashMap<Idx, Idx>], merged_pool: &mut Pool, interner: &StringInterner) -> Vec<ImportedMonoFn>
Lookup siteimported_mono.rs:49imported_generic_sigs.get(&instance.fn_name) (silent skip on miss at line 53)
Manglingimported_mono.rs:55reuses monomorphize::mangle_mono_name (no parallel mangling logic)
Dedupimported_mono.rs:63-66same mangled-name dedup pattern as collect_mono_functions

F4 — Architectural divergence + §02 cure-shape justification

JIT/evaluator uses two-pass merge: build_imported_mono_functions runs as separate pre-pass, consuming a pre-built imported_generic_sigs: FxHashMap<Name, (FunctionSig, usize, Name)> (the test-runner’s per-module crawl carries module provenance + alias-vs-original-name mapping); its output is appended via extend after collect_mono_functions runs on local instances (evaluator/compile.rs:230-237).

AOT has no equivalent mapcompile_common.rs:206-223 constructs import_sigs: Vec<(Name, FunctionSig)> from ImportedFunctionInfo records (mangled-name + concrete param/return types) intended for external-symbol declaration via fc.declare_imports(). This is a different data shape than imported_generic_sigs (no module provenance, no alias-vs-original split) and is consumed by a different LLVM pathway (fc.declare_imports, not mono lookup).

§02 cure-shape choice — integrated-signature over pre-pass mirror, justified:

  • Pre-pass mirror would require building an AOT-side imported_generic_sigs-equivalent map, which (a) creates a SECOND signature-source structure the AOT pipeline must maintain, (b) duplicates the JIT’s module-crawl logic in a new home (LEAK:algorithmic-duplication per impl-hygiene.md §Algorithmic DRY), and (c) leaves collect_mono_functions callers split — JIT goes through pre-pass, AOT goes through a copy.
  • Integrated-signature extends collect_mono_functions with an import_sigs parameter (or a separate imported_function_sigs: &[(Name, FunctionSig)] slice merged into the lookup table inside the function). All call sites converge on one source-of-truth path; the JIT’s existing build_imported_mono_functions becomes the merge-point for module-provenance-bearing consumers (it can stay or be folded into the integrated path in a follow-on cleanup; §02’s job is the parameter extension, not the pre-pass migration).

The AOT pipeline architecturally aligns with the local-only collect_mono_functions shape — it has no second pass equivalent to the test-runner’s pre-built map. §02’s cure preserves that alignment by extending the one function rather than adding a parallel structure.

F5 — Cross-language prior art (cited from §01 preamble — graph similar returned no embedding)

  • rustc rustc_monomorphize::collector::collect_used_items — driver-side collector traverses crate_inherent_impls + import_data + builtin call sites in ONE driver, not a pre-pass over imports + a main collector over locals. Same pattern §02 chooses.
  • Swift SILGen::emitConcretizationsForMonomorphicGenerics — the registration site enumerates ALL call sites (including imported and builtin) through a single API; the architectural choice mirrors integrated-signature.

Both reference compilers chose integrated-signature over separate-pass for the same architectural reason — driver-side enumeration with one signature-lookup contract.


01.2 Upstream MonoInstance emission paths in typeck

File(s):

  • compiler_repo/compiler/ori_types/src/check/exports.rs + emission sites referenced from compiler_repo/compiler/ori_types/src/infer/expr/calls/ (MonoInstance emission paths; check/mod.rs:341-407 is set_imported_type_metadata/finish_with_pool boilerplate, not emission)

  • compiler_repo/compiler/ori_types/src/check/mod.rs:68-77 (MonoIdentityKey)

  • compiler_repo/compiler/ori_types/src/check/mod.rs:423-440 (dedup site)

  • compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:73-77 (impl_sig_by_name first-match)

  • Read compiler_repo/compiler/ori_types/src/check/mod.rs:341-407 and document: what triggers MonoInstance emission, what receiver types are handled (top-level vs methods), what generic-arg substitutions are recorded. Findings recorded below — check/mod.rs:341-407 is set_imported_type_metadata/finish_with_pool boilerplate as the plan body’s “File(s)” note states; actual emission lives in infer/expr/calls/monomorphization.rs:133-152 (eager) + check/exports.rs:349-356 (deferred), both via MonoInstance::new_top_level.

  • Document the MonoIdentityKey tuple shape (compiler_repo/compiler/ori_types/src/check/mod.rs:68-77): (Name, Vec<GenericArg>, Vec<GenericArg>, Vec<GenericArg>, Vec<Idx>, Option<Idx>)(fn_name, generic_args, impl_args, method_args, concrete_param_types, receiver_type). The tuple ALREADY includes concrete_param_types and receiver_type; the dedup retain at lines 423-440 collapses by full key. Caveat for BUG-04-061 diagnosis (see §01.4): the dedup predicate appears structurally correct on first read; the gap may be in upstream emission failing to produce two distinct MonoInstance records, OR in impl_sig_by_name first-match at monomorphize/mod.rs:73-77 suppressing the second lookup. §01.4 records a targeted typeck-trace checkbox to disambiguate.

  • Trace inherent-method-on-generic emission: for impl<T> Box<T> { @unwrap (self) -> T = self.inner }, where does typeck emit the MonoInstance for Box<int>.unwrap? File:line for BUG-04-091 gap. Finding (LOAD-BEARING — supersedes both §01.4 BUG-04-091 candidate hypotheses): typeck emits ZERO MonoInstance records for inherent method calls on generic impl blocks. Grep for MonoInstance::new_method returns zero hits across ori_types/src/. infer_method_call / infer_method_call_named in infer/expr/calls/method_call.rs resolve impl methods via lookup_impl_methodresolve_impl_signaturecheck_positional_args, but neither path calls maybe_record_mono_instance or any other emission hook. Box<int>.unwrap and Box<str>.unwrap produce zero records, NOT one and NOT two. §01.4 BUG-04-091 cure surface re-anchored upstream — recorded as F4 below.

  • Document TypedModule.mono_dispatch_map: Vec<(ExprId, MonoInstanceId)> per types.md:894 — the canonical per-call-site dispatch map consumed by ori_canon (mono_dispatch_map_can) and ori_llvm downstream. This is the contract the MONO-REG invariant operates over (one entry per call-site ExprId resolving to a MonoInstanceId).

  • Subsection close-out (01.2) — flip subsection status: complete; record typeck-emission table for §03 (inherent-method-on-generic gap owner) and §04 (complex-generic-arg dedup gap owner).

§01.2 Findings (recorded 2026-05-14)

(per §01.2) — authoritative typeck-side MonoInstance emission contract for §03 (BUG-04-091 owner) and §04 (BUG-04-061 owner).

F1 — MonoIdentityKey shape

SiteCitationVerbatim
Type alias declarationori_types/src/check/mod.rs:70-77type MonoIdentityKey = (Name, Vec<GenericArg>, Vec<GenericArg>, Vec<GenericArg>, Vec<Idx>, Option<Idx>); — fields: (fn_name, generic_args, impl_args, method_args, concrete_param_types, receiver_type)
VisibilityInternal type alias (NOT pub); used only inside check/mod.rs

The 6-tuple discriminator is structurally complete (carries receiver type + concrete param types). Plan body’s caveat for BUG-04-061 — that the dedup predicate is structurally correct on first read — verified.

F2 — Emission sites (TWO paths, both top-level only)

PathSiteTriggerArgsreceiver_type
Eager (concrete)ori_types/src/infer/expr/calls/monomorphization.rs:133-152 (in maybe_record_mono_instance)Top-level free function call (infer_call at call_inference.rs:84, infer_call_named at call_inference.rs:172) where callee has non-empty scheme_var_ids AND all type vars resolved to concrete typesMonoInstance::new_top_level(fn_name, generic_args, concrete_param_types, concrete_return_type, body_type_map) then engine.record_mono_with_dispatch(call_expr_id, instance)None (always — new_top_level sets receiver_type=None, impl_args=method_args=[])
Deferred (resolution)ori_types/src/check/exports.rs:349-356 (in try_resolve_deferred_call, driven by resolve_deferred_mono_calls)Generic-calling-generic chains where maybe_record_mono_instance recorded a DeferredMonoCall because type vars remained unresolved at call-site; resolved transitively in finish_with_poolSame MonoInstance::new_top_level call shapeNone (deferred path also top-level only)

Both paths emit only MonoInstance::new_top_level. There is no MonoInstance::new_method constructor in use; grep confirms zero hits in src/.

F3 — Dedup site

SiteCitationPredicate
Dedup loopori_types/src/check/mod.rs:423-450 (in finish_with_pool)Retain-unique by full MonoIdentityKey 6-tuple via FxHashMap<MonoIdentityKey, u32>. Two instances collapse iff every field matches. NOT mangled-name dedup — structural tuple dedup.
Post-dedup sortori_types/src/check/mod.rs:457-473Sort-by-fn_name pass; permutation map (dedup_to_sorted) applied to remap mono_dispatch_pre_dedup entries

Plan body cited 423-440; actual range is 423-450 (cure: drift narrows to whichever exact line the §04 cure touches; §04 owner re-cites at fix time).

F4 — Inherent-method-on-generic emission gap (BUG-04-091 root cause)

LOAD-BEARING DIAGNOSIS — supersedes the §01.4 BUG-04-091 two-candidate hypothesis.

ori_types/src/infer/expr/calls/method_call.rs resolves inherent impl method calls via:

  1. lookup_impl_method(receiver_type, method_name) → returns (ImplId, ImplMethodSig) from impl registry
  2. resolve_impl_signature(impl_method_sig, generic_args) → substitutes Self = receiver_type, returns concrete FunctionSig
  3. check_positional_args(args, concrete_sig) → type-checks args + returns concrete return Idx

Neither step 1, 2, nor 3 calls maybe_record_mono_instance or any other emission hook. The method-call inference path returns the resolved return Idx to the call site WITHOUT ever pushing onto engine.mono_instances. The grep grep -rn "MonoInstance::new_method" compiler_repo/compiler/ori_types/src/ returns ZERO hits (confirmed by §01.2 sub-agent sweep).

Implication for BUG-04-091:

Plan body’s §01.4 BUG-04-091 entry posits two candidates:

  • (1) impl_sig_by_name first-match at monomorphize/mod.rs:73-77 returns the unsubstituted scheme-var sig and treats Box<int>.unwrap + Box<str>.unwrap as the same instance
  • (2) typeck never emits a discriminated MonoInstance per concrete T

The §01.2 finding establishes a THIRD truth: typeck emits zero MonoInstance records for Box<T>.unwrap calls of any concrete T. The downstream monomorphize/mod.rs lookup never sees impl-method instances at all because typeck never produces them.

§01.4 BUG-04-091 cure surface is therefore upstream — ori_types::infer::expr::calls::method_call.rs needs a method-call emission hook analogous to the top-level maybe_record_mono_instance. The cure-shape choice (extend MonoInstance::new_top_level to accept receiver_type + impl_args + method_args non-empty, OR add a dedicated MonoInstance::new_method constructor) is §03’s call when it opens for work. §01.4 owns the reconciliation between this finding and its prior two-candidate diagnosis at execution time.

This finding does NOT change BUG-04-061’s diagnosis — BUG-04-061 is Option<T>::unwrap which is itself a top-level prelude function (Option is a sum type with unwrap as a member function, not an impl method). The plan body’s H1/H2 hypotheses for BUG-04-061 remain in scope; §01.4 disambiguates them at execution time per the existing checkbox.

F5 — TypedModule.mono_dispatch_map consumer chain

LayerCitationField shapeContract
ori_types (producer)output/mod.rs:404pub mono_dispatch_map: Vec<(ExprId, MonoInstanceId)>Vec sorted by ExprId.raw() for Salsa Eq+Hash; lookup via binary search (dispatch_map_lookup); empty for non-generic call sites
ori_types (writer)check/mod.rs:479-492 (in finish_with_pool)Iterates mono_dispatch_pre_dedup, remaps pre-dedup MonoInstanceIds through old_to_dedup ∘ dedup_to_sorted permutation, sorts by ExprId.raw()
ori_canon (translator)lower/mod.rs:309 + lower/collections.rs:72-76 (record_mono_dispatch_if_present)mono_dispatch_map_can: Vec<(CanId, MonoInstanceId)>Per CanExpr::Call/CanExpr::MethodCall, binary-searches typed.mono_dispatch_map for AST call_expr_id, pushes (can_id, mono_id) onto mono_dispatch_map_can; sorted by CanId; emitted on CanonResult
ori_llvm (consumer)codegen/arc_emitter/context.rs:288-299mono_dispatch: FxHashMap<Name, Vec<(Vec<Idx>, Name)>> AND mono_dispatch_by_id: FxHashMap<MonoInstanceId, Name>Both built from MonoFunction.instance_ids (which comes from CanonResult.mono_dispatch_map_can); lookup_mono_dispatch() resolves generic callee → concrete mangled name at terminators.rs:651 and apply.rs:125-133

MONO-REG invariant scope (per §01 preamble): the contract operates over mono_dispatch_map’s (ExprId, MonoInstanceId) pairs at the typeck boundary; downstream, ori_canon’s mono_dispatch_map_can is the equivalent for CanExpr call sites; ori_llvm’s mono_dispatch_by_id is the dispatch surface where MONO-REG is enforced — the tracing::debug!("mono instance for unknown function — skipping") branch at monomorphize/mod.rs:99 fires when an ExprId/CanId carries a MonoInstanceId that has no MonoFunction entry in mono_dispatch_by_id.

Plan-body citation correction (drift): the plan body cites types.md:894 for the field declaration; the SOURCE declaration is at ori_types/src/output/mod.rs:404. types.md is a rules file and may carry a stale line number; the source is authoritative per tooling-first.md §1 (graph-first, source second).


01.3 ARC-lowering builtin Apply producer inventory

File(s):

  • compiler_repo/compiler/ori_arc/src/lower/collections/mod.rs:320-331 (lower_cast__cast producer)
  • compiler_repo/compiler/ori_arc/src/lower/calls/mod.rs:55-68 (emit_call_or_invoke vs direct emit_apply with None for builtins)

__cast is created in ARC-lowering, not typeck (verified at scaffolding time: lower_cast interns "__cast" and calls emit_apply(ty, cast_fn, vec![val], Some(span), None) — the None dispatch argument means no MonoInstanceId is threaded). This contradicts a typeck-only reading of MonoInstance emission; the BUG-04-114 producer is in ori_arc, not ori_types.

  • Read compiler_repo/compiler/ori_arc/src/lower/collections/mod.rs:320-331 and document lower_cast’s Apply emission: name (__cast), dispatch arg (None), type (ty from caller). Confirmed: lower_cast calls emit_apply(ty, cast_fn, vec![val], Some(span), None) at collections/mod.rs:328-330 (actual emission line) — None for mono_instance_id.
  • Read compiler_repo/compiler/ori_arc/src/lower/calls/mod.rs:55-68 and document the dispatch-argument convention: emit_call_or_invoke threads mono_instance_id via lookup_mono_dispatch; builtin emitters (lower_cast, lower_iterator_next, lower_index, etc.) call emit_apply/emit_invoke directly with None. This None IS the gap surface for BUG-04-114. Confirmed: emit_call_or_invoke at calls/mod.rs:65-80 is the unique dispatch-threading gateway, invoked exclusively for user-visible Call/MethodCall CanExpr nodes; doc comment at calls/mod.rs:63 makes the None for builtins explicit by design.
  • Inventory ALL ARC-lowering builtin Apply producers (use intel-query callers emit_apply --repo ori filtered to ori_arc/src/lower/):
    • lower_cast (__cast) — BUG-04-114 primary surface
    • Other builtin emitters TBD at execution time (likely candidates: lower_iterator_next, lower_index, lower_panic, lower_drop). Record name + file:line for each; §05 picks which require mono registration (Ori-typed) vs which are runtime ccc surfaces (out-of-scope for MONO-REG per the calling-convention classification). Inventory complete — recorded as F1/F2/F3 below. lower_panic/lower_drop resolve to runtime ori_panic/ori_iter_drop ccc surfaces (Class B, out of scope); the actual Class A cure surface narrows to __index (2 sites), __cast (1 site), __iter_next (2 sites) — 5 total call sites across 3 builtin names.
  • Map each producer to its calling-convention class per codegen-rules.md §AB-6: builtin Ori-typed Apply targets (operate on Ori values, fastcc) MUST be registered as MonoFunction; runtime ccc surfaces (ori_rt_* C-ABI calls) are out-of-scope for MONO-REG. Record the classification table. Classification recorded as F2 (Class A — needs cure) + F3 (Class B — out of scope) below.
  • Subsection close-out (01.3) — flip subsection status: complete; record producer table + calling-convention classification for §05 (builtin Apply mono registration owner).

§01.3 Findings (recorded 2026-05-14)

(per §01.3) — authoritative ARC-lowering builtin Apply producer inventory + AB-6 classification for §05 (builtin Apply mono registration owner).

F1 — Dispatch-threading convention (calls/mod.rs)

SiteCitationBehavior
Builder API (5-arg)lower/builder/emission.rs:32 (emit_apply), :174 (emit_invoke)(ty, name, args, span, mono_instance_id: Option<MonoInstanceId>)mono_instance_id is the LAST positional arg
Indirect APIlower/builder/emission.rs:56 (emit_apply_indirect), :224 (emit_invoke_indirect)Closure-call paths; no mono_instance_id arg (closures aren’t monomorphized at this layer)
Threading gatewaylower/calls/mod.rs:65-80 (emit_call_or_invoke)Unique dispatch-threading site; receives mono_instance_id from lookup_mono_dispatch(call_expr_id) and forwards to emit_apply/emit_invoke
Convention contractlower/calls/mod.rs:63 (doc comment)“Built-in calls emitted from other lowering helpers go directly through emit_apply/emit_invoke with None and do not flow through this helper.”

emit_call_or_invoke is invoked from lower_call (calls/mod.rs:213 FunctionRef, :221 SelfRef, :252 Ident) and lower_method_call (calls/mod.rs:352). All four sites pass a lookup_mono_dispatch(call_expr_id)-derived MonoInstanceId (Class C — already covered).

F2 — Class A: Ori-typed builtin Apply producers (NEEDS MONO-REG cure in §05)

ProducerBuiltin nameFile:lineApply argsCalling convention
lower_index__index (via ProtocolBuiltin::Index.name())lower/collections/mod.rs:184-188[recv: T, idx: int] — Ori-typed receiverfastcc
emit_list_element (free fn)__index (via ProtocolBuiltin::Index.name())lower/collections/mod.rs:394-396[list: List<T>, idx: int] — Ori-typed listfastcc
lower_cast__castlower/collections/mod.rs:328-330[val: T] — Ori-typed sourcefastcc
lower_for_iterator__iter_next (via ProtocolBuiltin::IterNext.name())lower/control_flow/for_loops/for_iterator.rs:100-106[iter_val, elem_ty_marker: T] — Ori-typed iteratorfastcc
lower_for_yield_iterator__iter_next (via ProtocolBuiltin::IterNext.name())lower/control_flow/for_yield.rs:216-222[iter_val, elem_ty_marker: T] — same shapefastcc

Total Class A: 5 call sites across 3 distinct builtin names (__index, __cast, __iter_next). Every Class-A site emits an Apply with None for mono_instance_id; codegen’s collect_mono_functions lookup (per §01.1 F1) hits the silent-skip branch at monomorphize/mod.rs:93-101; LLVM verification fires E5001 unresolved function ... in apply — missing mono instance (per lower/collections/mod.rs:328 for the __cast BUG-04-114 reproducer).

§05 cure scope (per MONO-REG): register a MonoFunction for each of the 5 Class-A call sites at the producer site (during ARC lowering — mono_instance_id plumbed via a new mono-registration channel parallel to the typeck-side mono_dispatch_map), AND extend ori_llvm::monomorphize::collect_mono_functions with a builtin_sigs lookup channel (3 builtin names — __index, __cast, __iter_next). This is parallel to but architecturally distinct from §02’s typeck-side cure (extending import_sigs for top-level functions); the cures share the silent-skip branch as their downstream verification site but emit at different producer phases.

F3 — Class B: Runtime ccc surfaces (OUT OF SCOPE for MONO-REG)

Builtin familyProducer sitesCalling conventionRationale
ori_iter_dropfor_loops/for_iterator.rs:191, for_yield.rs:327cccC-ABI runtime; ori_rt_*
ori_list_newfor_yield.rs:178, for_yield_option.rs:86cccC-ABI runtime
ori_list_pushfor_yield.rs:295-301, control_flow/mod.rs:261-268, for_yield_option.rs:167-173cccC-ABI runtime
ori_list_takefor_yield.rs:337, for_yield_option.rs:197cccC-ABI runtime
ori_print* (int/float/bool/str)lower/constructs.rs:83cccC-ABI runtime
ori_panic / ori_panic_cstrlower/constructs.rs:115,125,155, for_loops/for_range.rs:273cccC-ABI runtime; emit_invoke (unwind-capable)
ori_catch_recoverlower/constructs.rs:275cccC-ABI runtime
ori_format_*lower/constructs.rs:347cccC-ABI runtime
iter (creates opaque iterator)loops.rs:174, for_yield.rs:58,69cccC-ABI runtime
ori_list_slice_droplower/collections/mod.rs:413cccC-ABI runtime

Total Class B: ~17 call sites. Per codegen-rules.md §AB-6, runtime functions use ccc and are excluded from MONO-REG by the plan-local invariant (§01 preamble bullet (b): “be a runtime/protocol ccc surface explicitly enumerated”). §05 MUST NOT register MonoFunction entries for any Class-B emitter; doing so would cause double-registration at codegen and conflict with runtime_decl/runtime_functions.rs declarations.

F4 — Class C: Threaded dispatch (already correct — no §05 work)

ProducerFile:lineDispatch source
lower_call (FunctionRef path)lower/calls/mod.rs:213lookup_mono_dispatch(call_expr_id) on CanExpr::Call
lower_call (SelfRef path)lower/calls/mod.rs:221lookup_mono_dispatch(call_expr_id) on CanExpr::Call
lower_call (Ident path)lower/calls/mod.rs:252lookup_mono_dispatch(call_expr_id) on CanExpr::Call
lower_method_calllower/calls/mod.rs:352lookup_mono_dispatch(call_expr_id) on CanExpr::MethodCall

These four sites flow through emit_call_or_invoke (F1), which threads the typeck-derived MonoInstanceId from mono_dispatch_map_can. They are correctly registered when typeck emits a corresponding MonoInstance (per §01.2 F2). The §01.2 BUG-04-091 finding (typeck emits ZERO MonoInstance for inherent method calls on generics) is a typeck-side gap, not an ARC-lowering gap — the Class-C lower_method_call site is wired correctly; it just receives None from lookup_mono_dispatch because typeck never populated the entry.

F5 — Cross-section synthesis (BUG-04-114 producer-phase confirmation + §05 cure-shape)

The plan-body assertion that “the BUG-04-114 producer is in ori_arc, not ori_types” (§01.3 preamble) is confirmed: __cast is synthesized DURING lower_cast (lower/collections/mod.rs:328-330), AFTER typeck has exited the call site. Typeck never sees the __cast Apply because it doesn’t exist yet at typeck time — __cast is an ARC-lowering construct, not a user-visible call.

§05’s cure shape is therefore a two-arm intervention parallel to §02’s typeck-side cure:

  1. Producer-side (ori_arc::lower::*): add a mono-registration call adjacent to each Class-A emit_apply site (5 sites), threading a synthesized MonoInstanceId for the builtin’s concrete instantiation. The MonoInstance shape mirrors the typeck-side MonoInstance::new_top_level (no receiver, no impl args) but with builtin-specific fn_name (__index / __cast / __iter_next).
  2. Lookup-side (ori_llvm::monomorphize::collect_mono_functions): extend the lookup table with a builtin_sigs: &[(Name, FunctionSig)] parameter (parallel to §02’s import_sigs extension); the FunctionSig for each builtin is registry-derived (or hardcoded in a small builtin-sig table — §05 picks shape).

§05 owns both arms; §03 (BUG-04-091, inherent-method-on-generic) is independent and lives entirely in ori_types::infer::expr::calls::method_call.rs per §01.2 F4. §04 (BUG-04-061, complex-generic-arg dedup) is also independent and lives in ori_types::check-side dedup OR ori_llvm::monomorphize::impl_sig_by_name-side first-match (the plan-body H1/H2 disambiguation, owned by §01.4 + §04).


01.4 Per-bug gap classification + empirical verification

Per-bug record fields (apply this shape to every absorbed bug):

  • Producer phase (typeck ori_types::check vs ARC-lowering ori_arc::lower::* vs canon mono_dispatch_map)

  • Upstream gap site (where the carrier is created without a registered mono, OR where MonoInstance should be emitted but isn’t)

  • Downstream verification site (where LLVM verification fires E5001)

  • Owning section (§02 / §03 / §04 / §05) cure shape

  • Empirical verification (compile the reproducer fixture; capture pre-dedup mono_instances dump where applicable; confirm theoretical trace matches actual behavior)

  • BUG-04-119 (owner: §02) — Producer: typeck MonoInstance emission completes correctly for imported generic call sites (host module’s import resolution produces the call-site ExprId). Upstream gap: compiler_repo/compiler/oric/src/commands/compile_common.rs:206-223 constructs import_sigs but compiler_repo/compiler/oric/src/commands/codegen_pipeline/mod.rs:138 does NOT pass them to collect_mono_functions on the AOT path; lookup falls through to the silent-skip branch. Downstream: E5001 unresolved function 'assert_eq' in apply/invoke — missing mono instance at LLVM verification. Verify empirically: compile compiler_repo/compiler/ori_llvm/tests/aot/poly_lambda_mono.rs::test_poly_lambda_with_imported_assert_eq_int; confirm import_sigs is non-empty at construction site and absent at collect_mono_functions callsite. VERIFIED 2026-05-14: fixture exists at named path; #[ignore] reason text per test-disposition.md discipline reads BUG-04-119: AOT ori build lacks imported generic monomorphization — captures failure mode matching §01.1 F2 trace (import_sigs constructed at compile_common.rs:206-223, never passed to collect_mono_functions at codegen_pipeline/mod.rs:138). Cure on §02 unblocks the fixture (re-enable + cargo test).

  • BUG-04-091 (owner: §03) — Producer: typeck emits MonoInstance for impl<T> Box<T> { @unwrap }; the registered impl_sig has Self = Box<T> (with T as scheme-var, not substituted). Upstream gap: candidate (1) impl_sig_by_name first-match at compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:73-77 returns the unsubstituted scheme-var sig and treats Box<int>.unwrap + Box<str>.unwrap as the same instance; candidate (2) typeck never emits a discriminated MonoInstance per concrete T. Downstream: unresolved function 'unwrap' in apply at compiler_repo/compiler/ori_arc/src/codegen/arc_emitter/apply.rs. Verify empirically: dump pre-dedup mono_instances for tests/aot/generics.rs::test_generic_method_on_generic_type reproducer; count distinct (fn_name=unwrap, receiver_type) pairs. If two are emitted → §03 cures in impl_sig_by_name; if one → §03 cures upstream emission. VERIFIED 2026-05-14 (with §01.2 F4 supersession): fixture exists at named path; #[ignore] reason text reads BUG-04-091: ... Inherent method on generic type (impl<T> Box<T> { @m (self) -> T }) triggers 'unresolved function in apply — missing mono instance' at codegen. Captured failure mode matches §01.2 F4’s authoritative diagnosis: typeck emits ZERO MonoInstance records for inherent method calls (neither candidate H1 nor H2 — the cure-surface for §03 is upstream in ori_types::infer::expr::calls::method_call.rs, NOT in monomorphize.rs:73-77). The original two-candidate dump is moot — typeck never reaches the dedup; the dump would show zero records of any kind.

  • BUG-04-061 (owner: §04) — Producer: typeck emits MonoInstance for Option<T>::unwrap. Diagnosis IS NOT YET GROUNDED: the dedup predicate at compiler_repo/compiler/ori_types/src/check/mod.rs:423-440 uses MonoIdentityKey which already includes concrete_param_types and receiver_type, so it would structurally distinguish Option<int>.unwrap from Option<[int]>.unwrap IF two records are emitted with different keys. Two open hypotheses, EXACTLY ONE confirmed during execution: (H1) upstream emission produces only ONE record for both call sites (gap is in ori_types::check); (H2) upstream emission produces TWO records but impl_sig_by_name first-match at monomorphize/mod.rs:73-77 suppresses the second lookup (gap is in ori_llvm::monomorphize). Disambiguation checkbox: dump pre-dedup mono_instances for the Option<[int]>.unwrap() reproducer (target test: test_option_complex_arg_unwrap — new fixture authored by §04); if two MonoInstance records with distinct MonoIdentityKeys exist, H2 confirmed (§04 cures in monomorphize/mod.rs); if only one, H1 confirmed (§04 cures in ori_types/src/check). §04 cure surface is gated on this disambiguation outcome; the diagnosis becomes authoritative only after the dump runs. VERIFICATION-PENDING-§04 2026-05-14: fixture test_option_complex_arg_unwrap does not exist yet — plan body explicitly says “new fixture authored by §04”. §04 owns BOTH fixture authoring AND the H1/H2 dump-driven disambiguation; §01.4 records the dependency. NOTE: per §01.2 F4, Option<T>::unwrap is a top-level prelude function (Option is a sum type with unwrap as a top-level associated function via the spec’s prelude), so the typeck-zero-MonoInstance result for inherent impl methods does NOT apply here — H1/H2 disambiguation remains live.

  • BUG-04-114 (owner: §05) — Producer: ARC-lowering compiler_repo/compiler/ori_arc/src/lower/collections/mod.rs:320-331 (lower_cast) emits the __cast Apply carrier with None dispatch arg; typeck never sees this Apply because it is synthesized DURING ori_arc::lower, after typeck has exited. Upstream gap: __cast is a builtin Apply target; MonoInstance emission for builtin Apply in generic bodies is missing; no MonoInstanceId is threaded onto the carrier. Downstream: unresolved function __cast in apply — missing mono instance at LLVM module verification before realize. Verify empirically: compile tests/aot/generics.rs::test_borrow_list_int_one_borrow_apply_then_return_no_leak; dump mono_instances at collect_mono_functions entry — __cast instance MUST be absent; this confirms the producer phase is ARC-lowering (not typeck) and the cure surface lives in ori_arc::lower::collections + ori_arc::mono (mono registration during lowering), with the parallel signature extension in ori_llvm::monomorphize (separate builtin_sigs lookup channel). LIVE: cargo test -p ori_llvm --test aot test_borrow_list_int_one_borrow_apply_then_return_no_leak FAILED with the exact predicted error chain — WARN ori_llvm::codegen::arc_emitter::apply: unresolved function __cast in apply — missing mono instance? followed by error[E5001]: LLVM module verification failed ... unresolved function __cast in apply — missing mono instance?. End-to-end trace confirmed: §01.3 F2 (lower_cast emits __cast with None at lower/collections/mod.rs:328-330) → §01.1 F1 (codegen lookup hits silent-skip branch at monomorphize/mod.rs:99 because __cast has no entry in function_sigs / impl_sigs / [pending] builtin_sigs) → LLVM module verification fires E5001. The fixture is the canonical reproducer; §05’s cure must include re-running it green.

  • Subsection close-out (01.4) — flip subsection status: complete; record the four producer-phase classifications + empirical-verification outcomes so §02–§05 cite the authoritative gap diagnosis (post-disambiguation for BUG-04-061), not the speculative scaffold.

§01.4 Findings (recorded 2026-05-14)

(per §01.4) — authoritative per-bug producer-phase classification + empirical-verification outcomes for §02–§05 to cite.

F1 — Per-bug verification outcome table

BugOwnerProducer phase (§01 anchor)Cure surfaceEmpirical statusReproducer fixture
BUG-04-119§02AOT driver wiring (per §01.1 F2) — compile_common.rs:206-223 builds import_sigs; codegen_pipeline/mod.rs:138 doesn’t pass it to collect_mono_functionsori_llvm::monomorphize::collect_mono_functions signature extension + AOT run_borrow_inference callsite update + 4-caller blast-radius update (per §01.1 F2)Disposition-tracked — fixture #[ignore]’d with BUG-04-119 reason text (test-disposition.md discipline); reason captures failure mode matching §01.1 F2 trace; un-ignore + cargo test = empirical proof on curecompiler_repo/compiler/ori_llvm/tests/aot/poly_lambda_mono.rs::test_poly_lambda_with_imported_assert_eq_int
BUG-04-091§03typeck method-call inference (per §01.2 F4) — ori_types::infer::expr::calls::method_call.rs infer_method_call / infer_method_call_named resolve impl methods but NEVER call maybe_record_mono_instanceAdd method-call emission hook in ori_types::infer::expr::calls::method_call.rs parallel to top-level maybe_record_mono_instance; MonoInstance shape carries receiver_type=Some(concrete) + impl_args=[concrete substitution]; downstream monomorphize.rs:73-77 impl_sig_by_name will receive non-zero entries to dispatchDisposition-tracked — fixture #[ignore]’d with BUG-04-091 reason matching §01.2 F4 supersession (typeck emits ZERO records, neither candidate H1 nor H2); reason text empirically anchors the failure modecompiler_repo/compiler/ori_llvm/tests/aot/generics.rs::test_generic_method_on_generic_type
BUG-04-061§04Typeck top-level emission (per §01.2 F2) — Option<T>::unwrap is top-level prelude function, NOT inherent method (so §01.2 F4 typeck-zero result doesn’t apply); H1/H2 disambiguation still liveH1: cure in ori_types::check-side emission (one record per (receiver_type, concrete_param_types)); H2: cure in ori_llvm::monomorphize::impl_sig_by_name first-match logic. Disambiguation requires the dumpVerification-pending-§04test_option_complex_arg_unwrap fixture does NOT exist yet (plan body: “new fixture authored by §04”); §04 owns BOTH fixture authoring AND dump-driven H1/H2 disambiguation. §01.4’s empirical-verification commitment is RECORDED as a §04-owned dependency, not a §01.4-fulfilled outcometests/aot/...test_option_complex_arg_unwrap (TBD by §04)
BUG-04-114§05ARC-lowering builtin Apply emission (per §01.3 F2) — lower_cast at lower/collections/mod.rs:328-330 emits __cast with None for mono_instance_id; codegen silent-skip at monomorphize/mod.rs:99 (per §01.1 F1)Two-arm cure (per §01.3 F5): (a) producer-side mono-registration adjacent to all 5 Class-A emit_apply sites in ori_arc::lower::* (__index x2, __cast x1, __iter_next x2); (b) ori_llvm::monomorphize::collect_mono_functions extension with builtin_sigs: &[(Name, FunctionSig)] parameterLIVE-VERIFIED — fixture FAILS now with exact predicted error chain (WARN ori_llvm::codegen::arc_emitter::apply: unresolved function 'unresolved function __cast in apply — missing mono instance?' + error[E5001]); §01.3 F2 trace + §01.1 F1 trace confirmed end-to-end against actual codegen outputcompiler_repo/compiler/ori_llvm/tests/aot/generics.rs::test_borrow_list_int_one_borrow_apply_then_return_no_leak

F2 — Disposition-tracking discipline note

Three of four reproducer fixtures (BUG-04-119, BUG-04-091, BUG-04-114-no-actually-114-is-live) are tracked as #[ignore] annotations with BUG-XX-NNN tokens in the reason text per .claude/rules/test-disposition.md (Critical-grade discipline; reviewers flag untracked annotations as DISPOSITION_DRIFT:untracked-annotation). The reason text serves as the empirical-anchor surface — it captures the failure mode caught by a prior canonical reproducer. §02/§03 cures MUST re-enable the corresponding fixture (remove #[ignore]) AND verify it passes; §05 cures MUST flip the live-failing fixture to green.

test_borrow_list_int_one_borrow_apply_then_return_no_leak is NOT #[ignore]’d — it’s a live-failing test in the corpus; the umbrella plan’s existence is what tracks the failure (no separate #[ignore] needed because the cure plan is the tracking artifact). On §05 cure landing, the test transitions from FAIL to PASS in-place.

test_option_complex_arg_unwrap is fixture-pending; §04 owns its authoring per §01.4 BUG-04-061 entry above.

F3 — Cross-bug producer-phase summary (closes §01’s authoritative-map success criterion)

Producer phaseBugs§01 anchorCure-owning section
typeck top-level emission (infer/expr/calls/monomorphization.rs) — works correctly today; gap is downstream wiringBUG-04-119§01.1 F2 (AOT path)§02
typeck method-call emission (infer/expr/calls/method_call.rs) — MISSING entirelyBUG-04-091§01.2 F4§03
typeck top-level OR codegen impl_sig dispatch — disambiguation pendingBUG-04-061§01.2 F2 + §01.1 F1§04
ARC-lowering builtin Apply emission (lower/collections/mod.rs, lower/control_flow/for_loops/, lower/control_flow/for_yield.rs) — MISSING for 5 Class-A sitesBUG-04-114§01.3 F2 + §01.1 F1§05

Producer-phase coverage: 3 distinct phases (typeck top-level, typeck method-call, ARC-lowering builtin) + 1 codegen-side dispatch nuance (BUG-04-061 H2 candidate). All four absorbed bugs map to a single architectural concern — MONO-REG invariant violation at the monomorphize/mod.rs:99 silent-skip branch — but they reach that branch via FOUR distinct producer paths, each owned by a separate cure section.

This satisfies §01’s third success_criterion: MONO-REG invariant recorded (§01 preamble + §01.4 F3) with file:line evidence (§01.1/§01.2/§01.3 findings) and calling-convention classification (§01.3 F2 Class A fastcc + F3 Class B ccc) per codegen-rules.md §AB-6.


01.N Completion Checklist

  • All 01.1, 01.2, 01.3, 01.4 subsections status: complete. Verified 2026-05-14 via section frontmatter inspection.
  • No .rs edits landed under §01-attributed commits (verify: git diff --name-only origin/main...HEAD -- 'compiler_repo/**/*.rs' returns empty for commits authored by §01). Verified 2026-05-14: §01-attributed commits (1917c29 §01.2 close, 1f9bf0e §01.3 close, c1b7d3b parallel-session-absorbed §01.4 close, plus the 4 status-sync commits) touched only markdown plan files. No compiler_repo/**/*.rs paths in any §01-authored commit.
  • Section frontmatter flipped to status: complete, reviewed: true (the latter via §07.N close-out flow). reviewed: true already set from prior /review-plan run; status: in-progress → complete flips when plan-complete.py --complete-all runs at §01.N close (this checkbox).
  • No /improve-tooling retrospective required (read-only investigation produces no tooling deltas). Verified — no tooling work in §01; no diagnostic scripts created or modified.
  • No /sync-claude required (no API changes; §02–§05 own their /sync-claude invocations when their signature changes land). Verified — §01 produced no spec/rule drift; §02 will trigger sync-claude when collect_mono_functions signature extension lands.
  • Cite-back verification is OUT OF SCOPE for §01.N — moved to §02–§05 success_criteria per routing.md §5 topological-order discipline (a predecessor cannot gate on content of not-yet-started successors). §02–§05 each verify their own (per §01.N) cite-back when they open for work.

HISTORY

  • 2026-05-14 — /review-plan Step 6 round 1 cures uncommitted (autopilot): /tpr-review round 1 surfaced 3 actionable findings (compile_common.rs citation drift 200-215→206-223, §07 §00.3 anchor→§07.N, 00-overview.md aims-rules.md §IC-1 citation→MONO-REG plan-local invariant). Cures applied to working tree; /commit-push halted at compiler_repo extended_check_fail (parallel-session ori_arc::aims::intraprocedural + ori_types::registry edits failing full-check, not in this session’s scope). Per .claude/rules/skill-control-contract.md §Autopilot Mode unified hook-failure clause, autopilot proceeded with dirty tree; cures remain in working tree pending parallel-session cross-scope cleanup OR user-typed /commit-push --bypass. Round 2 dispatched against in-memory cured state.
  • 2026-05-14 — /commit-push halt skipped — halt_reason: authorized_writes_violation, failing repo: /home/eric/projects/ori_lang, scope: cross-scope: Step 4 plan_cleanup attempted to write bug-tracker/section-03-eval.md outside its allowed_output_globs (parallel-session bug-tracker consolidation artifact c1b7d3b). My §01.4 close-out work (Findings F1-F3 + 5 checkbox flips + status complete) was absorbed into c1b7d3b feat(bug-tracker): consolidate MD files into open/closed aggregates (+40/-6 lines on this file) prior to my /commit-push round. Per autopilot unified hook-failure clause, advancing to §01.N via --bypass-gate dirty_tree. Working-tree dirty state (5 files of recurring subsection-status sync) is cross-scope parallel-session work; clearing owned by parallel session OR future user-typed /commit-push --bypass.
  • 2026-05-14 — /commit-push halt skipped — halt_reason: authorized_writes_violation, failing repo: /home/eric/projects/ori_lang, scope: cross-scope: Step 4 plan_invalidate attempted to write scripts/plan_corpus/migrations/006_md_to_json.py outside its allowed_output_globs (parallel-session plan-corpus-tooling work). §01 close-out work (frontmatter status: in-progress → complete + 6 §01.N checkboxes flipped to [x] + HISTORY entries) is in working tree alongside cross-scope parallel-session artifacts. Per autopilot unified hook-failure clause, advancing to §02 via --bypass-gate dirty_tree — §01 frontmatter already reads status: complete in working-tree file (orchestrator reads file state, not just HEAD); cross-scope cleanup owned by parallel session OR future user-typed /commit-push --bypass.

01.R — Third Party Review Findings

  • Rounds completed: 3
  • Reviewer set: codex, gemini, opencode
  • Final outcome: clean (round_clean: true; meta_only_streak_qualifies: false)

Round 1 — 3 actionable cures applied (compile_common.rs:200-215 → 206-223 in 2 occurrences; §07 §00.3 anchor → §07.N; 00-overview.md cross-phase contract precondition aims-rules.md §IC-1 → MONO-REG plan-local invariant). Plus 2 false_positives (codex call-site/producer-phase conflation; opencode types.md:894 dead-edge misread).

Round 2 — 4 adjudicator-blessed actionable cures + 2 propagation cures (compile_common.rs:184-240 narrowing to 206-223 in 00-overview.md:39+:182 and section-02-import-sigs-traversal.md:46+:92; aims-rules.md §IC-1 → MONO-REG/AB-6 in section-05-builtin-apply-mono.md:86 + index.md:104; check/mod.rs:341-407 emission citation narrowed in section-01:105). Plus 1 false_positive (opencode third_party_review.status mid-pipeline misread) and 3 gemini informational meta findings.

Round 3 — 0 actionable. All 5 findings false_positive (gemini misreads of planned-query block + bullet-vs-excerpt + permitted-HISTORY-prose; opencode re-raises of round-1/round-2 false_positives).

No - [ ] items file from this round-loop — round 3 is clean.