Files
AILang/docs/journals/2026-05-12-iter-cma.1.md
T
Brummel a8c29d130b iter cma.1: master mini-spec + render binary for cross-model authoring experiment
New top-level experiments/2026-05-12-cross-model-authoring/ (out of
root Cargo workspace; nested-crate standalone via empty [workspace]
table per Cargo idiom). The renderer projects one canonical
master/spec.md into two form-specific files (rendered/json.md and
rendered/ailx.md) by walking three directive forms ({form-only:
json}, {form-only: ailx}, {example: <id>}) and emitting per-example
fenced blocks sourced from 13 curated .ail.json fixtures.

Four test gates green (10/10 total):
- splitter_unit (7) — directive parser, malformed inputs panic
- spec_completeness (1) — AST-variant visitor lifted verbatim from
  schema_coverage.rs; 34/34 variants covered by the curated subset
- example_roundtrip (1) — every fixture roundtrips through
  ailang_surface::{print, parse} to identical canonical bytes
- token_balance (1) — form-only block totals balanced to 3.22% under
  tiktoken-rs::cl100k_base (gate is ±5%)

Six of the 34 variants did not have a dedicated fixture topic in the
plan and were absorbed into the closest existing fixture per the
plan's Step 4.14 escape hatch (Let/Clone → fn_calls_prelude; LetRec
→ data_with_match; If → match_literal_pattern; ReuseAs →
data_simple; Const → floats). Surfaced as a journal note, not a
plan revision.

Two ancillary additions vs. plan, both structural Cargo necessities,
spec-compatible: render/Cargo.toml carries an empty [workspace] table
so the nested crate refuses parent-workspace discovery, and
render/.gitignore drops /target + Cargo.lock. Both surfaced inline
in the per-iter journal's Concerns section.

cma.2 (harness) and cma.3 (live IONOS run + DESIGN.md addendum +
journal + roadmap edits) remain out of scope per the spec.
2026-05-12 11:43:10 +02:00

6.1 KiB
Raw Blame History

iter cma.1 — Master mini-spec + renderer for the cross-model authoring experiment

Date: 2026-05-12 Started from: fd6efdbc Status: DONE Tasks completed: 9 of 9

Summary

Stands up the master mini-spec source and the renderer binary under a new top-level experiments/2026-05-12-cross-model-authoring/ tree that lives outside the root Cargo workspace. The renderer projects one form-agnostic master/spec.md into two form-specific files (rendered/json.md and rendered/ailx.md) by walking three directive forms ({form-only: json}, {form-only: ailx}, {example: <id>}) and emitting per-example fenced blocks from 13 curated .ail.json fixtures. Four test gates land green: a 7-test splitter unit suite, a spec_completeness test borrowing the AST-variant visitor verbatim from crates/ailang-core/tests/schema_coverage.rs (34/34 variants observed across the curated subset), an example_roundtrip test mirroring the surface roundtrip contract, and a token_balance test that gates form-only block tokens to ±5% under tiktoken-rs::cl100k_base (final ratio: json=1800, ailx=1742, ratio 3.22%). Two follow-on iters (cma.2: harness, cma.3: live IONOS run + DESIGN.md addendum) are out of scope per the spec.

Per-task notes

  • cma.1.1: Bootstrap experiment dir + Cargo skeleton — created experiments/.../{README.md,render/Cargo.toml,render/src/main.rs} plus the four target directories. Spec-pinned dependency paths resolve ailang-core and ailang-surface via relative ../../../crates/... references.
  • cma.1.2: Directive splitter (TDD) — 7 unit tests RED first, then implementation; added a [lib] target so the integration tests can reach xmodel_render::splitter. GREEN on first impl run.
  • cma.1.3: spec_completeness test — visitor + EXPECTED_VARIANTS list lifted verbatim from crates/ailang-core/tests/schema_coverage.rs; only examples_dir() body and the test name changed. Confirmed RED on the empty master/examples/ directory (failure mode: "no .ail.json fixtures found").
  • cma.1.4: 13 curated .ail.json fixtures (one per file as planned). The plan's 13 fixture topics naturally covered 28 of the 34 AST variants; the remaining 6 (Def::Const, Term::Let, Term::LetRec, Term::If, Term::Clone, Term::ReuseAs) were folded into existing fixtures per the plan's Step 4.14 instruction ("Extend the fixture closest in scope … do not weaken the test"). Concrete absorptions: Let + Clone into fn_calls_prelude; LetRec into data_with_match (as a recursive count_via_letrec helper); If into match_literal_pattern (as a sign_if helper); ReuseAs into data_simple (the wrap_one body uses (reuse-as src ...)); Const into floats (a const pi : Float = 3.14). All 34 variants green on first run.
  • cma.1.5: example_roundtrip test — verbatim from plan; all 13 fixtures roundtrip through ailang_surface::print and ailang_surface::parse to the same canonical bytes on first implementation run.
  • cma.1.6: master/spec.md — 13 sections of form-agnostic prose with parallel JSON/AILX form-only blocks in §2-5, §7, §9, §10 plus the prelude table in §11 (no form-only there; the table itself is the content). Section §11's prelude tabulation reflects the live crates/ailang-check/src/builtins.rs symbol set: +, -, *, /, %, ==, !=, <, <=, >, >=, not, neg, int_to_float, float_to_int_truncate, float_to_str, is_nan, nan/inf/neg_inf, __unreachable__, plus the effect ops io/print_{int,bool,str,float}. int_to_str is explicitly named as OUT (heap-Str ABI milestone).
  • cma.1.7: Wire renderer end-to-end — examples.rs and main.rs filled in verbatim from the plan. Renderer ran clean on first invocation; json.md (33409 bytes) and ailx.md (23964 bytes) emit with the expected 13 fenced blocks each (and zero of the wrong fence type).
  • cma.1.8: token_balance test — first run reported json=1800, ailx=1692, ratio 6.00% (above the 5% threshold). One substantive AILX-side extension to §4 (mode annotations) added authoring guidance on over-strict-mode and hash stability under future default shifts; final ratio json=1800, ailx=1742, 3.22%. The rebalancing is content, not filler.
  • cma.1.9: Final render + full sweep — cargo test --manifest-path experiments/.../render/Cargo.toml ends with 10 passed; 0 failed across four test suites; git status shows the entire experiment tree as untracked.

Concerns

  • Task 1: Cargo's automatic workspace discovery hits the root manifest, so the experiment crate refuses to build on its own. The fix is the standard Cargo idiom for a nested-but-out-of-workspace crate: add an empty [workspace] table to the experiment's Cargo.toml. The plan did not enumerate this; I added it with a comment pointing at the spec authority (§Architecture lines 90-95) for the standalone constraint. Boss should confirm this is the intended mechanism vs. e.g. adding the experiment to a workspace.exclude list in the root manifest (the spec is explicit that the root Cargo.toml is not touched, which the chosen mechanism respects).
  • Task 1 ancillary: a .gitignore was added under experiments/.../render/ ignoring /target and Cargo.lock. Not enumerated in the plan but a structural necessity to keep cargo's build output and lockfile out of the repo. Boss can keep, replace with a top-level rule, or move to the root .gitignore.

Known debt

  • None surfaced inside the iter. Two named deferrals remain out of scope (cma.2 harness, cma.3 live run + DESIGN.md addendum), per the spec.

Files touched

27 new files, all under experiments/2026-05-12-cross-model-authoring/:

  • README.md
  • master/spec.md
  • master/examples/*.ail.json × 13
  • render/Cargo.toml
  • render/.gitignore
  • render/src/{main,lib,splitter,examples}.rs
  • render/tests/{splitter_unit,spec_completeness,example_roundtrip,token_balance}.rs
  • rendered/json.md
  • rendered/ailx.md

git diff --name-only HEAD | wc -l: 0 (untracked tree; use git status --porcelain --untracked-files=all experiments/... to enumerate).

Stats

bench/orchestrator-stats/2026-05-12-iter-cma.1.json