diff --git a/bench/orchestrator-stats/2026-05-18-iter-embedding-abi-m2.tidy.json b/bench/orchestrator-stats/2026-05-18-iter-embedding-abi-m2.tidy.json new file mode 100644 index 0000000..6b93430 --- /dev/null +++ b/bench/orchestrator-stats/2026-05-18-iter-embedding-abi-m2.tidy.json @@ -0,0 +1,12 @@ +{ + "iter_id": "embedding-abi-m2.tidy", + "date": "2026-05-18", + "mode": "standard", + "outcome": "DONE", + "tasks_total": 1, + "tasks_completed": 1, + "reloops_per_task": { "1": 0 }, + "review_loops_spec": 0, + "review_loops_quality": 0, + "blocked_reason": null +} diff --git a/crates/ailang-core/specs/form_a.md b/crates/ailang-core/specs/form_a.md index 3f17bb3..a9ec0a8 100644 --- a/crates/ailang-core/specs/form_a.md +++ b/crates/ailang-core/specs/form_a.md @@ -86,7 +86,7 @@ externally-callable entrypoint (Embedding ABI M1). The symbol is author-chosen and decoupled from the internal `ail__` mangling. M1 requires the fn's parameter and return types to be scalar (`Int`/`Float`) and its effect set to be empty — see -DESIGN.md §"Embedding ABI (M1)". +DESIGN.md §"Embedding ABI". `suppress` clauses silence advisory diagnostics for this def. The `code` MUST be one of the registered codes (today: `over-strict-mode`). diff --git a/crates/ailang-core/tests/docs_honesty_pin.rs b/crates/ailang-core/tests/docs_honesty_pin.rs index 59d988a..51f00ae 100644 --- a/crates/ailang-core/tests/docs_honesty_pin.rs +++ b/crates/ailang-core/tests/docs_honesty_pin.rs @@ -131,7 +131,7 @@ fn form_a_scalar_param_carveout_present_and_old_rule_absent() { assert!(f.contains("Putting a mode on a scalar parameter."), "form_a.md Pitfalls must carry the inverse pitfall — over-wrapping a scalar (site 4)"); - // --- PRESENT: the DESIGN.md §\"Embedding ABI (M1)\" mirror --- + // --- PRESENT: the DESIGN.md §\"Embedding ABI\" mirror --- assert!(d.contains("Export parameters are written **bare**: a scalar type carries no `own`/`borrow` mode"), - "DESIGN.md §Embedding ABI (M1) must mirror the canonical bare-scalar export-param rule"); + "DESIGN.md §Embedding ABI must mirror the canonical bare-scalar export-param rule"); } diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 0f67bc1..5aeceb2 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -2263,7 +2263,7 @@ overlay shape. The asymmetry between the check side and the mono side is by design and is pinned by `crates/ailang-check/tests/duplicate_ctor_pin.rs`. -## Embedding ABI (M1) +## Embedding ABI `ail build --emit=staticlib` compiles a module to a relocatable `lib.a` (program objects only) plus a separate @@ -2351,7 +2351,7 @@ are real surface forms. "params": [""...], // names bound in body, in type.params order "body": Term, "doc": "", - "export": "", // omitted when absent (hash-stable when omitted); see §"Embedding ABI (M1)" + "export": "", // omitted when absent (hash-stable when omitted); see §"Embedding ABI" "suppress": [Suppress...] // omitted when empty } diff --git a/docs/journals/2026-05-18-iter-embedding-abi-m2.tidy.md b/docs/journals/2026-05-18-iter-embedding-abi-m2.tidy.md new file mode 100644 index 0000000..d5c0c06 --- /dev/null +++ b/docs/journals/2026-05-18-iter-embedding-abi-m2.tidy.md @@ -0,0 +1,58 @@ +# iter embedding-abi-m2.tidy — lockstep section rename `Embedding ABI (M1)` → `Embedding ABI` + +**Date:** 2026-05-18 +**Started from:** d1241b12c759765f12713584ce2aab21e2a74f74 +**Status:** DONE +**Tasks completed:** 1 of 1 + +## Summary + +Audit-driven docs-honesty tidy (no parent spec; source: +`docs/journals/2026-05-18-audit-embedding-abi-m2.md`, the M2 +milestone-close audit). The DESIGN.md section `## Embedding ABI (M1)` +had a stale `(M1)` qualifier — its body now describes the post-M2 ctx +ABI present-tense, so the qualifier contradicts the current-state-mirror +discipline. Renamed the header and moved all four *live* coupled +references in lockstep so no pointer dangles at the vanished `(M1)` +title. Pure docs/test-string tidy: zero language / checker / codegen / +schema change; `ail check`/`run` byte-unchanged by construction. The +`docs_honesty_pin.rs:135` asserted substring is rename-immune (no +section-name token, matched file-wide via `d.contains`) and was left +byte-verbatim untouched; the pin staying green before AND after +empirically confirms the rename did not perturb it. + +## Per-task notes + +- iter embedding-abi-m2.tidy.1: lockstep rename across 5 live-coupling + sites in 3 files — `docs/DESIGN.md:2266` (section header) + + `docs/DESIGN.md:2354` (schema-block xref comment) + + `crates/ailang-core/tests/docs_honesty_pin.rs:134` (test comment) + + `:136` (assert-message) + `crates/ailang-core/specs/form_a.md:89` + (compiled-in forward-xref). Each site: one-line in-place `(M1)`-token + deletion, no reflow. Step-1 baseline grep showed exactly the 5 sites + present (`:135` correctly absent — no `(M1)` token); Step-6 grep + returned zero (exit 1). `docs_honesty_pin` 5 passed and + `design_schema_drift` 8 passed both before and after. Footprint + gated at exactly 3 files, 5 insertions / 5 deletions — no + `docs/journals/**`, `docs/specs/**`, `docs/plans/**`, + `bench/orchestrator-stats/**` touched (committed append-only history + retains `Embedding ABI (M1)` as correct record of the name at the + time; renaming it would falsify the record). + +## Concerns + +(none) + +## Known debt + +(none) + +## Files touched + +- `docs/DESIGN.md` (header `:2266`, schema-block xref `:2354`) +- `crates/ailang-core/tests/docs_honesty_pin.rs` (comment `:134`, assert-message `:136`; `:135` untouched) +- `crates/ailang-core/specs/form_a.md` (forward-xref `:89`) + +## Stats + +bench/orchestrator-stats/2026-05-18-iter-embedding-abi-m2.tidy.json diff --git a/docs/journals/INDEX.md b/docs/journals/INDEX.md index bd9fba9..72316a4 100644 --- a/docs/journals/INDEX.md +++ b/docs/journals/INDEX.md @@ -100,3 +100,4 @@ - 2026-05-18 — iter emit-ir-staticlib (M1-fieldtest follow-up #2, scoped [feature], DONE): resolved M1 fieldtest [spec_gap]#2 — `ail emit-ir` had no `--emit=staticlib` (only `ail build` did) and on a `main`-free kernel hit the executable-path `MissingEntryMain` rejection, so an author could not read the generated `@` forwarder for an exported kernel — the exact Decision-5 IR-readability affordance, for the exact artefact M1 introduced. Added a one-line symmetric codegen convenience `lower_workspace_staticlib(ws)` (mirrors `lower_workspace`: `--emit=exe`↔`lower_workspace`, `--emit=staticlib`↔`lower_workspace_staticlib`; delegates to the M1-audited unchanged `Target::StaticLib` forwarder path), an `emit: String` clap field on `Cmd::EmitIr` symmetric with `Cmd::Build`'s, and a zero-export guard byte-identical to `build_staticlib`'s (so the error is symmetric across both subcommands and the existing `embed_staticlib_cli.rs` substring assertion holds for both). Recon resolved the only integration risk negative (both codegen entrypoints return `Result`, the emit-ir printer already consumes `String` — no adapter). DESIGN.md *widened* not narrowed (roadmap resolution honoured): a present-tense affordance sentence in §"Embedding ABI (M1)" + a CLI-synopsis correction that also discharges a pre-existing M1 omission (`ail build --emit=staticlib` was never in the synopsis). Boss editorial calls: synopsis fixes BOTH lines (docs-as-current-state-mirror consistency, on the merits); NO new docs pin (the E2E pins behaviour; the architect's mandatory DESIGN.md read at milestone close catches stale prose — pinning every feature sentence is noise); Decision-5 prose left untouched (already present-tense correct). New E2E `crates/ail/tests/emit_ir_staticlib_cli.rs` (3 tests: positive — IR contains external `@backtest_step(` + internal `@ail_embed_backtest_step_step`, NOT `@main(`, NOT `has no main def`; zero-export guard symmetric with build's, reusing the identical `embed_noentry_baseline.ail` fixture; default-exe regression — `--emit` defaults to `exe`, a `main`-free kernel without the flag still hits `MissingEntryMain`, so the new branch cannot silently reroute the default path). RED-first observed exactly ("1 passed; 2 failed" pre-edit — the default-exe test passes because that IS the spec_gap behaviour). Independent Boss verification: the 3 new tests 3/0, `embed_staticlib_cli` 2/0 (build-side untouched), `docs_honesty_pin` 5/0 (no regression), `ail` suite 186/0, workspace 623→626 (+3 = exactly the new tests), zero diff outside the 4 in-scope paths, no fixture minted. Functional spot-check from the user-facing CLI: `ail emit-ir examples/embed_backtest_step.ail --emit=staticlib` emits `define i64 @backtest_step(...)` (the readable external forwarder) + `@ail_embed_backtest_step_step` (internal), no `@main` — the affordance is genuinely delivered. spec carrier `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md` [spec_gap]#2 + roadmap P1 entry → plan `docs/plans/emit-ir-staticlib.md` (`03493c9`) → iter this commit. Scoped feature, no audit/fieldtest gate (the E2E is the coverage; no authoring-surface or invariant change — reuses the M1-audited codegen path). → 2026-05-18-iter-emit-ir-staticlib.md - 2026-05-18 — iter embedding-abi-m2.1 (Embedding ABI — M2, DONE 9/9 across one Boss-repaired split dispatch): per-thread runtime context + concurrency safety. No authoring-surface change (the `.ail` is byte-identical to M1); the deliverable is a swarm-safe generated C ABI + de-globalised runtime, sanitiser-verified. Shipped: `runtime/rc.c` gains `ailang_ctx_t {alloc_count,free_count}` + `ailang_ctx_new`/`_free` + `__thread __ail_tls_ctx`, the two increment sites become `if (_ctx) _ctx->… else g_rc_…` (the `g_rc_*` statics + `ailang_rc_stats_atexit` + constructor RETAINED VERBATIM as the null-ctx single-threaded executable fallback — `print_no_leak_pin`/`e2e` rc_stats stay green unmodified); codegen `Target::StaticLib` forwarder gains a mandatory leading `ptr %ctx` + one `@__ail_tls_ctx = external thread_local global ptr` decl + TLS save/store/restore around the BYTE-UNCHANGED internal `@ail__` call (`_adapter`/`_clos` + internal arg vector untouched — M1 decision held; the frozen-at-M3 surface is the C `@(ctx,…)` signature, internal convention free); `build_staticlib` rejects `--alloc != rc` (RC-only swarm artefact, no shared Boehm collector by construction; default already rc; P2 Boehm-retirement untouched); DESIGN.md §"Embedding ABI (M1)" updated to post-M2 current state (provisional-until-M3 narrowed to the value/record layout; Decision-10 per-thread-ctx atomicity note) with the docs_honesty-pinned "Export parameters are written **bare**…" sentence + `(con Int)` snippet preserved verbatim; M1 `host.c`/`embed_e2e` migrated to the ctx ABI (`s==25` holds). Coherent stop sanitiser-verified by the Boss directly (not inferred): per-thread-ctx scalar swarm `-fsanitize=thread`-clean with every thread == serial oracle (capability demo); direct rc-accounting per-ctx exit 0 / 0 tsan warnings (de-globalisation positive); shared-ctx negative control a genuine `ThreadSanitizer: data race` at `rc.c:157` (`_ctx->alloc_count++` in `ailang_rc_alloc`) + `rc.c:208` (`_ctx->free_count++` in `ailang_rc_dec`), exit 66 — teeth non-vacuous, precisely targeting the de-globalised counters. Process note: the first dispatch (Tasks 1–4 clean, committed `c9a84b3` as the known-good subset) correctly BLOCKED on Task 5 having surfaced a genuine spec defect — the original Task 5 paired a `-DSHARED_CTX` negative control onto `swarm.c`, structurally impossible because a non-allocating scalar kernel writes no ctx field and `__ail_tls_ctx` is `__thread` (the spec's OWN item-1 honesty point). Boss adjudication (not a brainstorm bounce — a consistency-repair of an internally-contradictory clause whose intent is already realised by item 1): spec amended in lockstep (Goal coherent-stop, must-fail-axis item 2, Testing item 3, Acceptance) so the negative-control teeth are item-1's by the de-globalisation-proof / capability-demo split; plan Task 5 restructured (`swarm.c` per-ctx capability demo only; negative control relocated into the item-1 `rc_accounting` harness driver) + Task-3 plan-transcription error corrected (`@ail_backtest_step`→`@ail_embed_backtest_step_step`); re-dispatch `[5,9]` DONE. spec `docs/specs/2026-05-18-embedding-abi-m2.md` (user-approved, grounding-check PASS 9/9, `1c58055`) → plan `docs/plans/embedding-abi-m2.1.md` (`b3388c8`, Boss-corrected) → iter `c9a84b3` (PARTIAL 4/9 + Boss repair) + this commit (DONE 5–9). Known debt routed: DESIGN.md `## Embedding ABI (M1)` section header still says "(M1)" while the body now mirrors M2 — out of Task 7's scope-limited edit regions by design (preserve the docs_honesty_pin), a post-audit doc-honesty tidy candidate. Milestone-close `audit` next. → 2026-05-18-iter-embedding-abi-m2.1.md - 2026-05-18 — audit embedding-abi-m2 (milestone close — DRIFT: one [medium]+[low] doc-honesty item → tidy; bench exit 1 causally exonerated, NO ratify): architect `drift_found` — no DESIGN.md/spec-contract drift, Invariant 1 intact, internal-convention byte-invariant, Decision-10 atomicity note present-tense-correct (sanitiser-verified), lockstep complete, docs_honesty_pin green, no unrequested extras, Boss spec-defect repair correctly reflected; the ONE actionable item is `[medium]` DESIGN.md:2266 — section header still `## Embedding ABI (M1)` while the body now mirrors the post-M2 ctx ABI present-tense (current-state-mirror honesty mismatch; NOT a Sweep-5 catch — header/body desync only a read finds; iter-journal Known-debt flagged it truthfully, Task-7-scope-deferred to preserve the docs_honesty_pin:135 verbatim sentence) + coupled `[low]` DESIGN.md:2354 stale `see §"Embedding ABI (M1)"` xref. Bench: `check.py` exit 1 (3 regressed: bench_list_sum.bump_s +13.57%, latency.explicit_at_rc.max_us +81.96%, latency.implicit_at_rc.max_us +38.57%), compile_check/cross_lang exit 0 clean (every rc_over_c ratio within tol). M2 genuinely changed the benched runtime path (rc.c null-ctx-fallback branch), so byte-identical exoneration did NOT apply → `ailang-bencher` dispatched: swapped only rc.c pre-M2↔HEAD, disassembled the delta (3 branchless insns mov %fs/test/cmovne), interleaved core-pinned A/B — **H0 refuted, all 3 firings tracked-noise causally-exonerated**: bump_s causally impossible from M2 (bump_malloc 0 rc-counter refs; reproduces ~+12% on M2-inert code = P2 *.bump_s stale-baseline), the rc.c hunk compiled branchless + measured free (HEAD −0.63% median), max_us median/p99 flat across rc.c variants + non-reproducible within a fixed binary (3.2× spread) = P2 *.max_us -n5 structural false-positive (4th consecutive null-attributable firing). NO baseline ratified (not M2 artefacts; P2 items stay separately tracked). Resolution: `[medium]`+`[low]` → tidy iter embedding-abi-m2.tidy (header rename + :2354 xref + docs_honesty_pin.rs:134–136 (M1)-token lockstep; the pinned :135 substring stays verbatim); bench → carry-on. Milestone substantively closed + sound (capability sanitiser-verified, all contract invariants held); roadmap [~]→[x] follows the tidy landing clean. → 2026-05-18-audit-embedding-abi-m2.md +- 2026-05-18 — iter embedding-abi-m2.tidy (M2 audit `[medium]`+`[low]` doc-honesty fix, DONE 1/1, zero re-loops): lockstep-renamed the DESIGN.md section `## Embedding ABI (M1)` → `## Embedding ABI` (current-state-mirror — the body had described the post-M2 ctx ABI present-tense while the header still carried the milestone tag) across all 5 live-coupling sites: `docs/DESIGN.md:2266` (header) + `:2354` (schema-block `see §"Embedding ABI"` xref), `crates/ailang-core/tests/docs_honesty_pin.rs:134` (comment) + `:136` (assert-message), and the Boss-added 5th site `crates/ailang-core/specs/form_a.md:89` (a live forward-xref into the renamed section in the compiled-in `FORM_A_SPEC` — same dangling-xref class as :2354, surfaced by the plan-recon-undercount countermeasure, NOT in the architect's named 3-site scope; Boss folded it in on the merits because leaving it stale is a half-rename contradicting the tidy's own thesis). The `docs_honesty_pin.rs:135` asserted substring (the DESIGN.md body sentence "Export parameters are written **bare**…", 31 lines below the header, section-name-free, file-wide `d.contains`) is rename-immune and stayed byte-verbatim untouched — recon proved this definitively pre-plan; the diff confirms :135 is unchanged context between the :134/:136 hunks. Committed append-only history (journals/specs/plans/orchestrator-stats) NOT falsified — Boss-verified the diff footprint is exactly the 3 content files + journal + stats, zero history files. Pure docs/test-string tidy, zero language/checker/codegen/schema change; no audit/fieldtest gate (the docs_honesty_pin IS the regression guard — Boss-verified 5/0 before AND after, design_schema_drift 8/0, the :2354 edit moved no JSON-schema drift anchor). Recon also corrected an audit inaccuracy (the :2354 xref IS inside the `## Data model` window :2319–2558, not outside — non-blocking, the xref string is not a drift anchor). audit source `docs/journals/2026-05-18-audit-embedding-abi-m2.md` (`ad88dec`) → plan `docs/plans/embedding-abi-m2.tidy.md` (`d1241b1`) → iter this commit. → 2026-05-18-iter-embedding-abi-m2.tidy.md