Files
AILang/docs/journals/2026-05-12-audit-eob.md
T
Brummel 8b1ceba5f8 audit-eob: close milestone heap-str-abi via eob.tidy
Architect drift review (range 750f97e..78e8338): drift_found with
three [high — spec acceptance] DESIGN.md items left over from the
heap-str-abi spec's acceptance criteria, plus one [medium] record-
keeping note. All three high items fixed inline as eob.tidy (Boss-
mechanical edits — small scope, content fully known from the just-
closed milestone, no plan / implement dispatch warranted):

1. DESIGN.md (Float-semantics block): replaced the stale 'float_to_str
   is type-installed but codegen-deferred' caveat with a one-paragraph
   statement that float_to_str and int_to_str are fully wired,
   allocate a heap-Str slab, and carry ret_mode: Own.

2. DESIGN.md ('What is supported' inventory): dropped the codegen-
   deferred parenthetical from float_to_str; added int_to_str to the
   inventory with the same Str-ABI cross-reference.

3. DESIGN.md (new 'Str ABI' subsection after Float-semantics): documents
   the dual realisation (static-Str packed-struct globals vs heap-Str
   malloc slabs), the shared consumer ABI (Str pointer at len-field
   offset 0, bytes at payload+8, inherited strcmp semantics), and the
   codegen-level non-RC invariant for static-Str (move-tracking +
   non-escape lowering + Type::Con{name:"Str"} carve-outs in
   field_drop_call and drop_symbol_for_binder's App arm).

Medium-severity hs.4-journal forward-pointer item skipped: INDEX.md
already chains hs.4 → eob.1 chronologically, and eob.1's journal
explicitly cross-references hs.4's deferred fix.

Bench-regression check:
- compile_check.py: exit 0; 24 metrics all stable
- cross_lang.py: exit 0; 25 metrics all stable
- check.py: exit 1; 2 regressed (bench_list_sum.bump_s +12.6%,
  bench_hof_pipeline.bump_s +11.65%, both marginal, the other four
  bump_s metrics stable — most parsimonious explanation is per-
  fixture system noise on ~50ms benches), 5 improved beyond
  tolerance (latency.explicit_at_rc.p99_us / p99_9_us / p99_over_median
  cluster — third consecutive audit showing the same shift
  uncorrelated with milestone work, plus two gc_over_bump mirrors of
  the bump_s regressions).

Baseline left pristine on every script for the third consecutive
audit. Latency cluster has persisted across audit-cma → audit-ms →
audit-eob without an identified cause; ratifying via --update-baseline
would obscure the next attributable signal. bump_s cluster is first-
sighting; first-sighting rule says observe in the next audit, do not
ratify on first sight.

Heap-str-abi milestone fully closed:
- Static-Str layout migrated (hs.1, hs.2 + spec amend).
- Heap-Str runtime wired (hs.3, hs.4).
- Effect-op-borrow rule + RC-discipline (eob.1).
- DESIGN anchors landed across eob.1 (arg-position policy under
  Decision 10) and eob.tidy (Str-ABI subsection, signatures-inventory
  cleanup).
2026-05-12 21:36:27 +02:00

6.4 KiB

audit-eob — Milestone close: heap-str-abi (closing iter eob.1)

Date: 2026-05-12 Milestone: heap-str-abi (hs.1 + hs.2 + hs.3 + hs.4 + eob.1) Status: Closed, three DESIGN.md tidies applied inline (eob.tidy)

Architect drift review

ailang-architect reported drift_found across the commit range 750f97e..78e8338. Lockstep invariants and codegen ABI all intact; three high-severity items in DESIGN.md plus one medium record-keeping note.

[high — spec acceptance] docs/DESIGN.md:2338-2342float_to_str described as "type-installed but codegen-deferred" with CodegenError::Internal. Stale since hs.4.

[high — spec acceptance] docs/DESIGN.md:2387 — same caveat inside the "What is supported" inventory; int_to_str was absent from the inventory entirely.

[high — spec acceptance] docs/DESIGN.md (missing) — no "Str ABI" anchor documenting the heap-Str / static-Str dual realisation, shared consumer ABI, or codegen-elision invariant for static-Str-in-RC-paths.

[medium — record-keeping] docs/journals/2026-05-12-iter-hs.4.md closed DONE_WITH_CONCERNS with weakened RC assertions; eob.1 retroactively restored the strict invariants. No forward-pointer appended; readers cross-walk via INDEX.md.

Tidy fixes applied inline (eob.tidy)

All three high-severity DESIGN.md drift items addressed in this audit commit (Boss-mechanical edits — no separate plan / implement dispatch warranted; the spec amend was small, the Str-ABI-anchor content was already fully known from the just-closed milestone):

  1. docs/DESIGN.md:2338-2343 (float_to_str caveat block): replaced the codegen-deferred prose with a one-paragraph statement that float_to_str and int_to_str are fully wired, allocate a heap-Str slab, and carry ret_mode: Own. Forward-references the new Str-ABI anchor.

  2. docs/DESIGN.md:2387-2392 (inventory bullet): dropped the codegen-deferred parenthetical from float_to_str; added int_to_str : (Int) -> Str to the inventory; pointer to the Str-ABI section for the dual realisation.

  3. docs/DESIGN.md (new "Str ABI" subsection placed after the Float-semantics block, before "What is not (yet) supported"): documents the two realisations (static-Str packed-struct <{ i64, [N+1 x i8] }> globals in .rodata; heap-Str slabs allocated via ailang_rc_alloc(8 + len + 1)); the shared consumer ABI (Str pointer at len-field offset 0, bytes at payload + 8, inherited strcmp semantics); and the codegen-level non-RC invariant for static-Str (move-tracking partial-drop + non-escape lowering + Type::Con { name: "Str" } carve-outs at field_drop_call and drop_symbol_for_binder's App arm).

Medium-severity hs.4-journal forward-pointer: skipped. INDEX.md already links hs.4 → eob.1 chronologically; the eob.1 journal explicitly cross-references hs.4's deferred fix as the iter's motivation. A forward-pointer in hs.4's own file would push the append-only convention; the cross-walk from INDEX is sufficient.

Bench-regression check

Sequence run as Boss (the && chain in audit-SKILL.md tripped at check.py's exit 1; compile_check.py and cross_lang.py then run separately to read their exit codes cleanly):

  • check.py: exit 1 — 63 metrics; 2 regressed, 5 improved beyond tolerance, 56 stable.
    • Regressions: bench_list_sum.bump_s +12.60% (tol 10%); bench_hof_pipeline.bump_s +11.65% (tol 10%). Both only marginally over tolerance; the other four bump_s metrics (bench_tree_walk, bench_closure_chain, bench_compute_collatz, bench_list_sum_explicit) are stable within ±7%.
    • Improvements: three on the latency.explicit_at_rc cluster (p99_us -37.37%, p99_9_us -40.14%, p99_over_median -37.35%); two gc_over_bump mirrors on bench_list_sum and bench_hof_pipeline (ratio falls because the denominator — bump_s — rose; same physical signal as the bump regressions).
  • compile_check.py: exit 0; 24 metrics, all stable within ±25%.
  • cross_lang.py: exit 0; 25 metrics, all stable within ±15%.

Classification

Latency cluster (latency.explicit_at_rc.p99_us / p99_9_us / p99_over_median): third consecutive sighting across audit-cmaaudit-msaudit-eob. audit-ms flagged this as "one more audit before considering ratification"; this is that one more audit.

eob.1's only codegen-side touchpoints are the drop.rs Str carve-out (8 LOC) and the ret_mode: Own flip at four signature sites; none of those should plausibly shift latency p99 by 37%. The signal predates this milestone (audit-cma was three milestones ago). Conservative call: still do not baseline-update on this audit. The cluster is real and persistent, but the underlying cause is unknown, and a baseline update without an identified attribution would obscure the next signal that does have an attributable cause.

Recommendation forward: if the cluster persists into the next two audits unchanged, ratify with --update-baseline and a journal entry naming the persistence as the ratify rationale (absence of identified cause being the standing fact). If the cluster shifts or shrinks meaningfully, that is itself the attribution signal.

bump_s cluster (bench_list_sum.bump_s, bench_hof_pipeline.bump_s): first sighting in any recent audit. Both metrics only marginally over the 10% tolerance. The other four bump_s measurements are stable, which makes "shared underlying bump-allocator change" unlikely; per-fixture system noise (12.6% on a ~50ms benchmark is ~6ms of jitter) is the most parsimonious explanation.

eob.1 made zero changes to bump-allocator codepaths. The implementer's end-report flagged this same cluster as appearing during the workspace bench sweep before commit. Conservative call: first-sighting rule — do not baseline-update; observe in the next audit; if it persists, investigate.

Baseline left pristine on every script for the third consecutive audit. No --update-baseline invocation.

Status

Closed. Heap-str-abi milestone fully landed:

  • Static-Str layout migrated (hs.1, hs.2).
  • Heap-Str runtime additions wired (hs.3, hs.4).
  • Effect-op-borrow rule + RC-discipline closes (eob.1).
  • DESIGN.md anchors both arg-position rules + Str-ABI dual realisation (eob.1 + eob.tidy in this audit).
  • WhatsNew entry + roadmap P1 close (eob.1).

Working tree exits audit clean. main HEAD advances by exactly this audit commit.