# audit embedding-abi-m1 — milestone close (CLEAN — carry-on, NO ratify)

**Date:** 2026-05-18
**Scope:** `064599e..e406d07`
**Verdict:** Milestone audit **CLEAN**. Architect `clean` (one
`[low]` evidence-adjudicated to carry-on); bench `check.py` exit 1
**decisively causally exonerated** (21/21 byte-identical bench
binaries vs pre-milestone), `compile_check.py` / `cross_lang.py`
exit 0. No fix iteration, **no baseline ratify**.

## Commit map

- `064599e` — pre-milestone HEAD (bench/architect diff baseline).
- `51160e9` spec, `b0bd7ef` plan — docs only.
- `123ae1b` — USER-authored roadmap-P2 ("DESIGN.md → `design/`
  role-split"), `docs/roadmap.md` only, path-disjoint — explicitly
  out of M1 audit scope (Boss roadmap maintenance, architect told
  to skip it; it is not M1 code/doc work).
- `818177d` — iter partial (Tasks 1–3) + a Boss plan Repair
  (Design-decision 6, the module≠stem fixture defect).
- `e406d07` — iter completion (Tasks 4–7) + INDEX line.

## Step 1 — Architect drift review

**Status: `clean`.** All four focus areas + standing concerns
verified against the `064599e..e406d07` diff:

- **Invariant 1 (clean core) holds semantically.** No
  finance/`data-server` vocabulary, logic, or dependency entered
  `ailang-core` / `ailang-codegen` / `runtime/`. `backtest_step`
  is an opaque author-chosen string flowing through generic
  `FnDef.export`; the only "backtest" occurrences in core/codegen
  are test-fixture filenames + mangled-symbol assertions in test
  files, not domain knowledge. AILang↔host meeting point correctly
  deferred (no `ail-embed`, no runtime lifecycle API) — M1 scope
  respected.
- **DESIGN.md honesty rule satisfied.** New §"Embedding ABI (M1)"
  + fn-JSON `"export"` line + `FnDef.export` rustdoc are
  present-tense current state; "provisional until M3" / "M2 will
  change this C signature" are correctly *labelled* reserved-
  unimplemented, not stated as present fact, no
  post-mortem/Wunschdenken. Sweep hits (DESIGN.md:50/:2060/:62)
  all pre-existing, out of M1 range.
- **Lockstep intact.** `FnDef` ↔ DESIGN.md §Data-model fn-JSON ↔
  `design_schema_drift.rs`/`spec_drift.rs` all carry the field.
  The `@<sym>` forwarder is additive raw-IR emission *beside* the
  unchanged `@ail_<module>_<fn>` mangling — does not route through
  `lower_app`, so the `lower_app`/`is_static_callee` and
  `Pattern::Lit` lockstep pairs are not engaged. Schema stays
  exhaustively-constructed (~85 sites uniform `export: None`, no
  `_ =>` / `..Default::default()` — plan Design-decision 1
  honoured). In-source `missing_entry_main_is_error` pin (now
  L3411) behaviourally byte-unchanged (only the mandatory field
  added). `_adapter`/`_clos` closure pair untouched (spec "Out of
  scope").
- **Design-decision 6 confirmed correct, not re-flagged.** The
  gate/headline fixtures' `(module embed_*)` == file-stem; the
  divergence from the spec's *illustrative* `(module backtest)` /
  `(module bad)` blocks is expected under the loader's
  module==stem invariant + spec Decision 2 (C symbol
  `backtest_step` decoupled via `(export …)`). The fixtures
  *demonstrate* the decoupling rather than violate the spec.

**Drift / debt — one item, adjudicated:**

- `[low]` ~85 inserted `export: None,` lines indented to the
  struct-literal brace column rather than the field column
  (`rustfmt`-divergent struct literals; compiles 611/0, semantics
  unaffected). **Orchestrator adjudication → carry-on (NOT a fix,
  NOT pending).** Evidence: `cargo fmt --all --check` reports
  **1137 fmt-divergent locations tree-wide** (pre-existing
  `builtins.rs` / `diagnostic.rs` / dozens of `lib.rs` sites
  predating M1). rustfmt is demonstrably **not** a project
  convention — the hand-formatted codebase tolerates 1137
  divergences. The architect's premise ("a `cargo fmt` pass would
  churn later") is therefore moot: no such gate exists or is
  coming, and selectively rustfmt-aligning 85 of 1137 sites would
  *impose* a standard the project does not hold, which is noise,
  not tidy. This is an evidence-based adjudication of the
  architect's finding (premise falsified), not "trivial, ignore
  it". If AILang ever adopts a fmt gate that is a tree-wide
  decision (1137 sites), unrelated to M1.

## Step 2 — Bench-regression check

| Script | Exit | Result |
|---|---|---|
| `bench/check.py` | **1** | 63 metrics; 7 regressed, 2 improved, 54 stable |
| `bench/compile_check.py` | 0 | 24 metrics; 0 regressed |
| `bench/cross_lang.py` | 0 | 25 metrics; 0 regressed |

**The 7 `check.py` firings:**
`throughput.bench_list_sum.bump_s` +12.27%,
`throughput.bench_hof_pipeline.bump_s` +12.67%,
`throughput.bench_list_sum_explicit.bump_s` +13.74%,
`latency.explicit_at_rc.p99_9_us` +36.13%,
`latency.explicit_at_rc.max_us` +101.43%,
`latency.implicit_at_rc.p99_9_us` +67.32%,
`latency.implicit_at_rc.max_us` +123.57%.

**Decisive causal exoneration (bencher localisation).** Hypothesis:
M1's `Target::Executable` default leaves the entire bench corpus's
emitted machine code byte-unchanged; the firings are pre-existing
environmental/sampling noise, not M1.

- **21/21 bench binaries `cmp`-byte-identical** between `064599e`
  and `e406d07` (`bench_list_sum_bump` sha `dce18c288904c9f0` at
  both commits; every one of the 6 fixtures × 3 modes + 3 latency
  arms IDENTICAL, 0 DIFFER). `ail` self-hash differs (expected —
  Rust source changed for the embedding ABI) but the *emitted
  machine code* for every bench fixture is identical because every
  fixture builds an executable via the unchanged `Target::Executable`
  default. **Zero codegen/runtime causal mechanism exists.**
- The RC-latency tails reproduce *on the byte-identical oracle
  binary itself*, swinging 3× run-to-run (`explicit_at_rc.max_us`
  per-run 376→1200 us; `implicit_at_rc.max_us` 562→1742 us) while
  median/p99 hold steady — the documented `-n 5` single-sample-
  jitter signature.
- Fresh `check.py` re-run: the `*.bump_s` trio → ok, 4 of 7
  original firings → ok, only `explicit_at_rc.max_us` still trips
  (+26%, byte-oracle-proven environmental).
- Both firing families map (confirmed, not assumed) onto the two
  pre-existing **roadmap-P2** tracked items: `*.bump_s` baseline-
  vs-current-hardware staleness, and the RC-latency `*.max_us` /
  `*.p99_9_us` `-n 5` structural false-positive (this is the ~4th
  zero-runtime-change milestone close on which they fire and
  collapse on identical-code re-run).

**Classification: carry-on, NO baseline ratify.** Per the audit
Iron Law a baseline update requires a paired JOURNAL ratify entry
naming an iter that *intentionally* moved the metric; M1 by
construction moved **zero** default-path bytes (21/21 binaries
identical), so a ratify would bake noise into `baseline.json` —
forbidden. The spec forecloses a zero-codegen baseline bump. The
residual flapping is pre-existing, already roadmap-P2-tracked; the
genuinely next-best action (re-capture `baseline.json` on current
hardware at higher N, or widen single-sample tail tolerances) is a
separate bench-harness iteration, **not** an M1 concern — the two
P2 items remain orchestrator-owned and are NOT bundled into this
close (bencher recommendation honoured, consistent with the
remove-mut-var-assign / docs-honesty-lint closes).

## Step 3/4 — Resolution

**carry-on (clean).** No fix iteration, no ratify, no commit beyond
this journal + its INDEX line. Architect clean; the sole `[low]` is
evidence-adjudicated non-actionable; bench firings decisively
non-causal (21/21 byte-identical binaries) and mapped to existing
P2 noise. Both bench gates that can pass on the merits do
(`compile_check`/`cross_lang` exit 0; `check.py` exit 1 causally
exonerated).

**M1 milestone audit CLEAN.** Next pipeline step: `fieldtest` —
M1 added user-visible authoring surface (`(export "<sym>")`), so
the surface-touch fieldtest gate applies before milestone close.
