Section 02: AOT emitter arms for builtin methods (ROOT A)
Goal
Add the missing try_emit_builtin_method LLVM arms for the registry builtin methods the interpreter dispatches but the AOT emitter has no arm for — generalizing the §09 Shape-B per-family pattern. Targets (per §01 classification): Ordering then/then_with, string escape/contains/len, char is_alpha (+ any §01-confirmed builtin-tail). Flip ori_registry backend_required:false -> true per method ONLY once its arm lands + is AOT-verified.
Implementation Sketch
For each method: add the emitter arm in compiler/ori_llvm/src/codegen/arc_emitter/builtins/ (mod.rs dispatch + the family module — ordering/, str, char). The arm consumes the realized ArcFunction call + emits LLVM matching the interpreter semantics (dual-exec parity is the gate). Do NOT touch monomorphize/mangle.rs or nounwind/prepare.rs (MonoTargetMaps). Stay out of arc.md §STOP RC-emission.
Spec References
ori_registry/src/defs/{ordering,str,char}/; arc_emitter/builtins/; missions.md §ori_llvm (faithful emission); layer-coverage.md §3.1 (L9 dual-exec parity + L10 leak MANDATORY both legs for compiler-scope).
Work Items
- TDD-first: author the failing AOT matrix — one .ori spec test per target builtin method (Ordering then/then_with, string escape/contains/len, char is_alpha) under tests/spec/, each exercising the method on the production AOT path (ori build -> run), asserting the real output. Confirm each currently emits ‘missing mono instance?’ before the fix.
- Add the AOT emitter arm for each Ordering builtin (then, then_with) in arc_emitter/builtins/ordering; verify interp==LLVM (dual-exec) + zero leaks; flip backend_required:true in ori_registry/src/defs/ordering once green.
- Add the AOT emitter arm for each string/char builtin (escape, contains, len, is_alpha + §01-confirmed builtin-tail); dual-exec + leak; flip backend_required:true per method.
- Layer-matrix closure (L1-L12 per layer-coverage.md §1): debug+release builds, AOT binary on a real target, dual-exec parity, ORI_CHECK_LEAKS=1 zero leaks, spec-corpus pins. Every target method’s signature absent from the test-all mono grep.
Items
- TDD-first: author/EXTEND the failing AOT matrix — one .ori spec leg per genuinely-arm-less target builtin (Ordering then, then_with; string escape; char is_alpha) on the production AOT path (ori build -> run), asserting the real output. EXTEND the existing interp-leg pins (tests/spec/types/ordering/then_with.ori, tests/spec/types/ordering/methods.ori, tests/spec/traits/debug/escape.ori) with the LLVM+AOT leg — NEVER author parallel .ori files. EXCLUDE str.len/str.contains: live emitter arms exist (collections/mod.rs:22-23,34), so their residual is ROOT-B transitive owned by §05 transitive-mono-worklist, not §02. Confirm each target currently emits ‘missing mono instance?’ pre-fix via the ./test-all.sh captured-log grep, NEVER diagnostics/aot-guardrail.sh.
- Add the AOT emitter arm for each Ordering builtin (then, then_with) in arc_emitter/builtins (primitives / ordering family); verify interp==LLVM (dual-exec L9) + zero leaks (L10). RECONCILE the registry drift first: ori_registry/src/defs/ordering/mod.rs:84 already marks
thenbackend_required:true with NO emitter arm (a latent BUG-02-041 E6024 hazard) — correct/verify that flag against a real AOT run as part of landing thethenarm, and set then_with backend_required:false->true only once its arm lands + is AOT-verified. Do NOT touch monomorphize/mangle.rs or nounwind/prepare.rs; stay out of arc.md §STOP RC-emission. - Add the AOT emitter arm for str.escape and char.is_alpha — the genuinely-arm-less ROOT-A string/char builtins (collections/mod.rs has no escape arm; primitives.rs/traits.rs have no char classifier arm) — in arc_emitter/builtins (str / char family); dual-exec parity (L9) + zero leaks (L10); flip ori_registry backend_required:false->true per method ONLY once its arm lands + is AOT-verified. EXCLUDE str.len/str.contains: both have live arms (collections/mod.rs:22-23,34); their residual counts are ROOT-B transitive owned by §05 transitive-mono-worklist, not §02. Re-confirm any §01-tail builtin against the live source (arm present => §05 ROOT-B) before adding an arm.
- Layer-matrix closure (L1-L12 per layer-coverage.md §1) over the FULL §02 ROOT-A builtin surface — the already-cured focused builtins (Ordering then/then_with, str.escape, char.is_alpha) AND the to_fixed family (list
to_fixed, and any genuinely-arm-less sibling in the [T, max N] conversion family): debug+release builds, AOT binary on a real target, dual-exec parity (L9), ORI_CHECK_LEAKS=1 zero leaks (L10), spec-corpus pins. Every §02 ROOT-A method’s signature ABSENT from the §07 whole-corpus ./test-all.sh captured-log mono grep (the close is recorded at §07’s one whole-corpus run per the plan’s per-section/test-all structural finding, NOT a per-section test-all). - TDD-first (to_fixed residual): author the FAILING AOT spec test for the genuinely-arm-less list/fixed-capacity conversion builtin
to_fixed([T] -> [T, max N], Spec Clause 8.2.2) on the production AOT path (ori build -> run), asserting the real output.to_fixedis a registry builtin (ori_registry/src/defs/list/mod.rs:121, MethodDef::compound, backend_required:false) the interpreter dispatches as value-identity (ori_eval/src/methods/list.rs:149 -> Value::List(list)) but the AOT emitter has NO arm (arc_emitter/builtins has no to_fixed arm) -> ROOT-A, NOT a §05 ROOT-B transitive (no live arm exists). Place the .ori leg under tests/spec/ (extend an existing fixed-capacity list spec test rather than authoring a parallel file). Confirm it currently emits ‘missing mono instance?’ pre-fix via the §07 ./test-all.sh captured-log grep (the 36-hit residual at HEAD 330fc5f6), NEVER diagnostics/aot-guardrail.sh. Re-confirm against the live registry+emitter source that to_fixed (and any sibling [T, max N] conversion builtin in the same family) is genuinely arm-less before adding an arm. - Add the AOT emitter arm for the arm-less
to_fixedlist/fixed-capacity conversion builtin in arc_emitter/builtins (list/collections family). Semantics are value-identity:[T]and[T, max N]share the same runtime Value::List representation, the capacity constraint is type-level only (Spec Clause 8.2.2) — mirror the siblingto_dynamicshape (ori_registry list/mod.rs:120, identical compound/Borrow/backend_required:false; same value-identity eval arm at list.rs:145). The arm forwards the receiver list value unchanged (no runtime fn, no RC mutation -> cleanly outside arc.md §STOP RC-emission). Verify interp==LLVM (dual-exec L9) + zero leaks (L10). Flip ori_registry backend_required:false->true forto_fixedONLY once its arm lands + is AOT-verified. Do NOT touch monomorphize/mangle.rs or nounwind/prepare.rs (MonoTargetMaps). If a sibling [T, max N] conversion builtin is also confirmed arm-less in the same review, land its arm here under the same family; ifto_dynamicis found to ALSO lack an arm and hit the same residual, land it in the same pass (same value-identity shape).
Fresh intel (regenerated)
{ “schema_version”: 1, “target”: { “kind”: “plan-section”, “ref”: “aot-mono-stdlib-completeness/s-69c6f7be” }, “generated_at”: “2026-06-24T15:40:56.495540+00:00”, “graph_state”: { “head_sha”: “f9d92587”, “last_code_import_at”: “2026-06-24T15:37:10.508Z”, “embedding_stale”: false, “insights_stale”: false, “cpg_stale”: false }, “surfaces”: {}, “summary”: “intel-package[plan-section:aot-mono-stdlib-completeness/s-69c6f7be] agent-authored dossier”, “degraded”: false, “dossier”: { “objective_symbols”: [], “tiers”: {}, “agent_authored”: true, “difficulty”: { “class”: “routine”, “research_online”: false, “research_mode”: “auto”, “signals”: [], “plan_dir”: “/home/eric/projects/ori_lang/plans/aot-mono-stdlib-completeness” } } }
(full dossier: builtin-method-aot-emitters—s-69c6f7be.intel.json)