iter embedding-abi-m1.1 (DONE 7/7): Embedding-ABI M1 — scalar AILang fn callable from C/Rust

Tasks 4-7 on the Boss-Repaired plan, completing the M1 iteration:

- Task 4: check-side export-signature gate — CheckError variants
  ExportNonScalarSignature / ExportHasEffects (codes
  export-non-scalar-signature / export-has-effects), code() arms,
  check_fn gate (params->ret->effects, first-violation-wins,
  unconditional on f.export.is_some()). The clause-3 discriminator
  in code: effectful/non-scalar exports fail to typecheck. 6/6.
- Task 5: codegen Target::StaticLib — Target enum, threaded param,
  @main/MissingEntryMain gated behind Target::Executable, one
  external @<sym> forwarder per export to @ail_<module>_<fn>
  (fn_scalar_sig/llvm_scalar). In-source missing_entry_main_is_error
  byte-unchanged. Lowering pin 2/2.
- Task 6: CLI ail build --emit=staticlib — clap field, Cmd::Build
  branch, build_staticlib (verbatim build_to prefix + has_export
  guard + two-archive clang -c/ar rcs tail) + run_cmd. CLI pin 2/2.
- Task 7: C-host E2E coherent-stop proof (cc links
  libembed_backtest_step.a + libailang_rt.a, backtest_step(0,3)=9 /
  (9,4)=25, s==25, exit 0) + DESIGN.md §"Embedding ABI (M1)"
  (scalar C ABI, provisional until M3). E2E pin 1/1.

Independent Boss verification: E2E 1/1, gate 6/6, full workspace
0 failures, roundtrip_cli + design_schema_drift + spec_drift green,
Invariant 1 holds (no new dep in core/codegen/runtime). 3 behaviour-
neutral plan pseudo-vs-reality concerns in the journal. Default-exe
codegen/runtime path byte-unchanged (check.py firing = tracked-P2
known-noise, audit-adjudicated). INDEX line added.

Completes the M1 iteration (impl). Milestone-close audit + fieldtest
(surface-touching) are the next pipeline steps.
This commit is contained in:
2026-05-18 14:50:27 +02:00
parent 818177d835
commit e406d07d81
17 changed files with 804 additions and 81 deletions
@@ -2,22 +2,31 @@
"iter_id": "embedding-abi-m1.1",
"date": "2026-05-18",
"mode": "standard",
"outcome": "PARTIAL",
"outcome": "DONE",
"tasks_total": 7,
"tasks_completed": 3,
"reloops_per_task": { "1": 0, "2": 0, "3": 0, "4": 0 },
"tasks_completed": 7,
"reloops_per_task": { "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0 },
"review_loops_spec": 0,
"review_loops_quality": 0,
"blocked_reason": "spec-ambiguous",
"blocked_reason": null,
"notes": {
"blocked_task": 4,
"blocked_detail": "load_workspace stem-match (workspace.rs:182 ModuleNameMismatch) is mutually unsatisfiable with the plan's verbatim fixtures (spec-mandated module `backtest` in file embed_backtest_step.ail; bad/bad_io/... in embed_export_*_rejected.ail) plus the verbatim load_workspace-based gate pin. Structural spec/plan defect rippling Tasks 4-7; Boss/spec decision required (Option 1: rename fixture files to module stems, keep module backtest).",
"dispatch_history": "Two dispatches. First dispatch: Tasks 1-3 DONE + Boss-committed at 818177d; Task 4 BLOCKED (spec-ambiguous) on a Boss plan-defect (fixtures declared module != file-stem; loader hard-enforces module == file-stem at workspace.rs:438). Boss Repaired the plan (Design-decision 6 / Option 2: module == file stem, C symbol decoupled via (export ...)) and re-dispatched task_range [4,7]. Second dispatch (this run): Tasks 4-7 all DONE on the corrected plan, zero re-loops, zero review loops.",
"first_dispatch_block": {
"blocked_task": 4,
"blocked_reason": "spec-ambiguous",
"resolution": "Boss plan Repair (Design-decision 6, Option 2 over the orchestrator-recommended Option 1) + Tasks 4-7 re-dispatch; resolved cleanly."
},
"concerns": [
"Task 2: plan symbol content_hash_fn(&FnDef) nonexistent; mirrored hash_pin.rs def_hash(&Def) per the plan NOTE's own resolution clause (planner pseudo-vs-reality class).",
"Task 4: plan fixture `*.` Float-multiply head nonexistent; used the typeclass-generic `*` head per the plan NOTE (not yet exercised — gate BLOCKED before run).",
"INFRA: docs/roadmap.md externally modified mid-session; path-disjoint from iter; left untouched (Boss-owned)."
"Task 2 (committed at 818177d): plan symbol content_hash_fn(&FnDef) nonexistent; mirrored hash_pin.rs def_hash(&Def) per the plan NOTE (planner pseudo-vs-reality class).",
"Task 4: no `*.` Float-multiply head; embed_export_float_ok.ail uses `(app * a b)` per the corrected plan (concern folded into the plan Repair; now exercised — gate GREEN).",
"Task 5: plan Step 3(b) says emit_ir calls lower_workspace_inner directly; reality emit_ir->lower_workspace->lower_workspace_inner(_,_,Executable). Intent (in-source missing_entry_main_is_error pin byte-unchanged) delivered + verified GREEN; behaviour-neutral planner pseudo-vs-reality note.",
"Task 7: plan-verbatim embed_e2e.rs imported unused std::path::Path; reduced to PathBuf (warning-clean, behaviour-identical).",
"Task 7: plan code-block showed `### Embedding ABI (M1)` but the same step's prose says 'same heading level as Mangling scheme' (## in DESIGN.md); used ## for document consistency.",
"INFRA (first dispatch, resolved): docs/roadmap.md externally modified mid-session; Boss-committed separately as roadmap maintenance; NOT in the Tasks 4-7 working tree."
],
"fnDef_threading_sites": "~85 export:None literals across 18 files via compile-driven enumeration (2 dependency-ordered waves), cargo build --workspace exits 0",
"tests_state": "Tasks 1-3 + pre-existing all green; only the deliberately-RED embed_export_gate (6 tests) fails workspace-wide"
"cross_checks_executed": "All six named implementer-judgement cross-checks resolved as plan-confirming (Type::Con {name,args} no mode field; declared_effs already Vec<String> so no into_iter().collect() needed; synth::llvm_type Int->i64/Float->double exact mirror; no pre-existing run_cmd; ailang_core::Def crate-root re-exported; load_workspace/check_workspace/Diagnostic.code are the main.rs:580-581 symbols).",
"tests_state": "Full workspace 0 failures. New: embed_export_gate 6/6, embed_staticlib_lowering 2/2, embed_staticlib_cli 2/2, embed_e2e 1/1 (coherent-stop). roundtrip_cli green; codegen in-source missing_entry_main_is_error green; design_schema_drift 8/8 + spec_drift 8/8.",
"bench_trio": "compile_check.py exit 0; cross_lang.py exit 0; check.py exit 1 = tracked P2 *.bump_s / *.max_us known-noise envelope (3 regressed/2 improved/58 stable), plan Step 6 = audit-adjudicated not a plan gate; architect_sweeps.sh exit 1 pre-existing both with/without the DESIGN.md edit (no new flagged phrasing introduced).",
"fnDef_threading_sites": "~85 export:None literals across 18 files (committed at 818177d, Task 2)"
}
}