iter cma.2: harness binary + 4 tasks + reference solutions + 4 integration tests
Sibling standalone Cargo crate `harness/` under experiments/2026-05-12-cross-model-authoring/ (out-of-workspace idiom carried forward from cma.1 verbatim). Six modules: strip_locations (regex pass for form-asymmetric location info, calibrated against five real `ail check`/`ail parse` stderr captures), pipeline (subprocess wrapper for parse|check|build + 5s-timeout exec; preflight on ail+clang), ionos (blocking reqwest client + retry policy per spec), mock (canned-response loader), scoring (CSV + summary.md), tasks (definition struct + loader). main.rs ties them into the per-(cohort,task) loop with budget accounting and per-turn artefact recording. Four MVP tasks land with reference solutions that compile, build, and execute green through the actual ail+clang pipeline: t1_add_three (chained `+` + io/print_int), t2_length (polymorphic List + recursion), t3_main_prints (minimal IO module), t4_count_zeros (prelude Eq Int + branched if). Reference solutions stay in canonical AILang form — param_modes is omitted when every parameter is the Implicit default, consistent with the existing examples/ corpus. 13/13 tests green: 5 lib unit (strip_locations) + 5 integration (strip_locations against verbatim captured fixtures) + 1 verify_references (drives every reference through the real ail+clang pipeline) + 1 mock_full_run (full eight-row sweep with mixed green-on-turn-2 + turn-limit cycles) + 1 budget_abort (synthetic budget exhaustion with budget_abort rows + run_status). Two implementer-phase repairs beyond the plan, both small and surfaced in the iter journal Concerns: 1. pipeline.rs renames the program file to `<module-name>.ail.json` between parse and check because `ail check` enforces filename stem == module name (compiler contract the plan did not anticipate). 2. main.rs fills synthetic budget_abort rows for tasks the outer loop never reached so scores.csv preserves the expected eight-row shape on budget exhaustion. One plan/text mismatch carried over: README "Total 8 passed" reflects the plan's four-suite count; actual sweep produces 13. Doc-fix candidate for cma.3. cma.3 (live IONOS run + DESIGN.md addendum + roadmap edits) remains out of scope.
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
# iter cma.2 — Harness binary + four tasks + reference solutions + three integration tests
|
||||
|
||||
**Date:** 2026-05-12
|
||||
**Started from:** 21c2d2cfaa999980f727a069792e3bd073c1f1e7
|
||||
**Status:** DONE
|
||||
**Tasks completed:** 13 of 13
|
||||
|
||||
## Summary
|
||||
|
||||
Stands up the sibling `harness/` standalone Cargo crate under
|
||||
`experiments/2026-05-12-cross-model-authoring/`, mirroring the
|
||||
out-of-workspace idiom from cma.1's `render/`. Six modules under
|
||||
`harness/src/`: `strip_locations` (regex pass for form-asymmetric
|
||||
location info), `pipeline` (subprocess wrapper around
|
||||
`ail parse|check|build` plus the model's compiled binary, with a
|
||||
fail-fast preflight on `ail` + `clang`), `ionos` (blocking reqwest
|
||||
client with retry policy), `mock` (canned-response loader keyed by
|
||||
cohort/task/turn), `scoring` (CSV + summary.md writers), `tasks`
|
||||
(task-definition struct + loader). `main.rs` ties them into the
|
||||
per-(cohort, task) loop. Four task definitions (`t1_add_three`,
|
||||
`t2_length`, `t3_main_prints`, `t4_count_zeros`) with reference
|
||||
solutions that all reach green through the actual ail+clang
|
||||
pipeline. 13/13 tests pass: 5 inline unit tests under `--lib`
|
||||
(strip_locations), 5 strip_locations integration tests against
|
||||
verbatim recon-captured stderr fixtures, 1 verify_references
|
||||
integration test driving every reference through the real pipeline,
|
||||
1 mock_full_run end-to-end with eight rows and per-cohort artefact
|
||||
trees, 1 budget_abort with the harness aborting cleanly under a
|
||||
1500-token cap.
|
||||
|
||||
## Per-task notes
|
||||
|
||||
- cma.2.1: Bootstrap harness Cargo project + skeleton — created
|
||||
`harness/{Cargo.toml,.gitignore,src/lib.rs,src/main.rs}` plus
|
||||
six stub module files. Empty `[workspace]` table at the top of
|
||||
Cargo.toml keeps the crate out of the root workspace. Cargo.lock
|
||||
gitignored per spec. First `cargo build` succeeded with the
|
||||
expected unused-import warnings on the skeleton.
|
||||
- cma.2.2: strip_locations module — written verbatim from the
|
||||
plan with 5 inline unit tests (json_pointer, byte_offset, line/
|
||||
column, Caused-by chain, passthrough). All 5 green on first run.
|
||||
- cma.2.3: pipeline module — written verbatim from the plan plus
|
||||
a small implementer-phase repair: `ail check` enforces filename
|
||||
stem == module name, so `pipeline::run_pipeline` extracts the
|
||||
top-level `"name"` field from the JSON via a new
|
||||
`module_name_from_json` helper and renames the working file to
|
||||
`<module_name>.ail.json` before invoking `ail check`. Without
|
||||
this, every reference would have failed at the `ail check` step
|
||||
with "module name in file does not match expected name from
|
||||
path". See Concerns.
|
||||
- cma.2.4: ionos module — written verbatim from the plan; added
|
||||
`thiserror = "1"` to `[dependencies]`. Compile-time warnings
|
||||
about three unused things on the `IonosClient` path (Auth, Usage,
|
||||
`last_err` assignment) are expected and flagged in the plan.
|
||||
- cma.2.5: mock module — written verbatim; compile clean.
|
||||
- cma.2.6: scoring module — written verbatim; compile clean.
|
||||
- cma.2.7: tasks module — written verbatim; compile clean.
|
||||
- cma.2.8: Author four task definitions + reference solutions —
|
||||
task.json files written verbatim from the plan text. Reference
|
||||
`.ail.json` files authored fresh against the cma.1 templates
|
||||
(hello.ail.json shape for t3; gc_stress.ail.json's polymorphic
|
||||
`List a` shape for t2 and t4; canonical chained `+` for t1's
|
||||
three-arg sum; canonical `eq` invocation pattern + branched `if`
|
||||
for t4's count_zeros). All four references compile clean and
|
||||
produce the expected stdout. Reference solutions intentionally
|
||||
omit `param_modes` because every parameter is Implicit and the
|
||||
canonical AILang form omits the field in that case — consistent
|
||||
with hello.ail.json, list.ail.json, eq_primitives_smoke.ail.json,
|
||||
and the explanatory doc in `master/examples/param_modes_all.ail.json`.
|
||||
See Concerns. Added `tempfile = "3"` to `[dev-dependencies]` for
|
||||
the `verify_references.rs` integration test. The test runs every
|
||||
reference through `pipeline::run_pipeline(Cohort::Json, ...)`
|
||||
end-to-end (ail parse-check-build-execute); passes when
|
||||
`AIL_BIN` is set to the release binary.
|
||||
- cma.2.9: Wire main.rs end-to-end — written verbatim from the
|
||||
plan; added `tempfile = "3"` to `[dependencies]` (not only
|
||||
dev-deps) because `main.rs::run_one` uses it for per-turn
|
||||
workdir. Compile clean (modulo the three flagged warnings from
|
||||
ionos).
|
||||
- cma.2.10: Five stderr fixtures + strip_locations integration
|
||||
test — all five fixture files written verbatim from the plan
|
||||
(which itself captured them from recon's run against current HEAD).
|
||||
Integration test asserts strip behaviour against each fixture;
|
||||
5/5 green on first run.
|
||||
- cma.2.11: mock_full_run integration test + mock_full_run.json
|
||||
fixture — fixture authored by inlining each
|
||||
`master/tasks/<id>.reference.ail.json` as the `content` field
|
||||
for the green-path entries, plus `ail render` for the AILX-cohort
|
||||
inlines (verbatim AILX serialisations of the same references).
|
||||
Test runs the harness binary against the fixture; 8 rows total
|
||||
(4 tasks × 2 cohorts), `(json, t3_main_prints)` reaches green on
|
||||
turn 2 (matches the plan's intended cycle: broken-then-fixed),
|
||||
`(ailx, t1_add_three)` runs to the 5-turn limit (`(module garbage)`
|
||||
repeated). All artefacts (turn_N_program.ext,
|
||||
turn_N_request.json, turn_N_response.json,
|
||||
turn_N_check_stderr.txt, turn_N_run_stdout.txt) land in
|
||||
`per_cohort/<cohort>/<task>/`. 1/1 green.
|
||||
- cma.2.12: budget_abort integration test — test verbatim from
|
||||
the plan, plus an implementer-phase repair to `main.rs`: with a
|
||||
tiny budget (1500), the outer loop broke out after consuming
|
||||
~2400 tokens across tasks 1+2 (both green on turn 1), but
|
||||
neither row carried `final_status = budget_abort` because the
|
||||
inner `run_one` only marks BudgetAbort if the budget is exhausted
|
||||
*during* the turn loop. The plan's test assertion expects at
|
||||
least one row with `budget_abort`. Repair: after the outer loop
|
||||
breaks with `run_status="budget_exceeded"`, fill in the not-yet-run
|
||||
(cohort, task) pairs with synthetic `BudgetAbort` rows. mock_full_run
|
||||
remains green (the new code only runs on budget_exceeded).
|
||||
1/1 green. See Concerns.
|
||||
- cma.2.13: README update + final sweep — appended "Running the
|
||||
harness" section to `experiments/.../README.md` verbatim from the
|
||||
plan. Full `cargo test` sweep: 5 (lib unit, strip_locations) + 5
|
||||
(integ, strip_locations) + 1 (verify_references) + 1
|
||||
(mock_full_run) + 1 (budget_abort) = 13/13 green. `git status`
|
||||
shows the README modification + the new harness/ tree + the new
|
||||
master/tasks/ files, all unstaged.
|
||||
|
||||
## Concerns
|
||||
|
||||
- **Pipeline filename-matching: minimal repair landed in `pipeline.rs`,
|
||||
not flagged in the plan.** `ail check` enforces filename stem ==
|
||||
module name; the plan's `run_pipeline` writes the model's program
|
||||
to `prog.{ext}`, which would have been rejected at every `ail
|
||||
check` invocation. The repair adds a 9-line helper
|
||||
`module_name_from_json` (reads JSON, returns top-level `name`) plus
|
||||
14 lines in `run_pipeline` that rename `prog.ail.json` ->
|
||||
`<module_name>.ail.json` between parse and check. Behaviour
|
||||
outside that rename is unchanged. The structural alternative
|
||||
(telling the model to name its module `prog`) would have been
|
||||
semantically wrong — the task description prompts say "module
|
||||
named t1_add_three" etc. Recommend a forward-fix sweep in cma.3
|
||||
if the structural decision (whether the pipeline or the prompt
|
||||
owns module naming) warrants spec attention.
|
||||
- **`param_modes` omitted from every reference solution.** The plan's
|
||||
Step 8.2 text says "mode annotations on every parameter", but the
|
||||
templates the plan references (hello.ail.json, list.ail.json,
|
||||
eq_primitives_smoke.ail.json, etc.) all omit `param_modes`, and
|
||||
the `param_modes_all.ail.json` master example's own doc string
|
||||
documents "Implicit mode is the legacy default — `param_modes` is
|
||||
omitted from canonical JSON when every entry is Implicit". The
|
||||
references stay in canonical form. If the plan's intent was
|
||||
explicit `["implicit", "implicit", ...]` annotations on every
|
||||
reference, that is a follow-on amendment.
|
||||
- **Budget-abort row-filling, minimal repair landed in `main.rs`,
|
||||
not flagged in the plan.** Without it, Task 12's test fails on
|
||||
the assertion `expected at least one budget_abort row`. Repair
|
||||
is gated on `run_status == "budget_exceeded"` so the green path
|
||||
is unchanged.
|
||||
- **README "Total 8 passed" text mismatches Step 13.2's "13 passed"
|
||||
expectation.** The plan's README text (Step 13.1) advertises four
|
||||
test suites with "Total 8 passed" — counts the four integration
|
||||
suites but skips the 5 inline unit tests under `--lib`. Step 13.2
|
||||
expects 13 across `--lib` + 4 integration tests. The README text
|
||||
is reproduced verbatim per plan; the actual sweep produces 13.
|
||||
Recommend a docfix in cma.3 ("Total 13 passed across --lib + 4
|
||||
integration tests"), but the cma.2 plan locked the README copy.
|
||||
- **`AIL_BIN` env required for `verify_references.rs` and
|
||||
`mock_full_run.rs` to run from a fresh shell.** These tests shell
|
||||
out to `ail`; without `ail` on PATH the preflight bails. The
|
||||
README documents this. CI integration is out of scope.
|
||||
|
||||
## Known debt
|
||||
|
||||
- The harness has not yet been live-fired against IONOS (deferred
|
||||
to cma.3 per spec). The retry/backoff path in
|
||||
`ionos::IonosClient::post` has no test coverage in cma.2 (mock
|
||||
mode bypasses it entirely).
|
||||
- Three compile warnings in `ionos.rs` (`Auth` and one `Usage` are
|
||||
read in tests/other code; `last_err` second assignment is
|
||||
intentional dead-store for retry-loop symmetry). Not addressed.
|
||||
|
||||
## Files touched
|
||||
|
||||
Modified (1):
|
||||
- `experiments/2026-05-12-cross-model-authoring/README.md`
|
||||
|
||||
New — harness crate (8 source, 4 integration tests, 6 fixtures, 1
|
||||
manifest, 1 .gitignore):
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/Cargo.toml`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/.gitignore`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/lib.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/main.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/strip_locations.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/ionos.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/mock.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/scoring.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/src/tasks.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/strip_locations.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/verify_references.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/mock_full_run.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/budget_abort.rs`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/check_unbound_var.stderr`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/check_type_mismatch.stderr`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/check_bare_xmod.stderr`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/check_schema_missing_field.stderr`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/parse_unclosed.stderr`
|
||||
- `experiments/2026-05-12-cross-model-authoring/harness/tests/fixtures/mock_full_run.json`
|
||||
|
||||
New — master tasks (4 task.json + 4 reference.ail.json):
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t1_add_three.task.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t1_add_three.reference.ail.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t2_length.task.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t2_length.reference.ail.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t3_main_prints.task.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t3_main_prints.reference.ail.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t4_count_zeros.task.json`
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/tasks/t4_count_zeros.reference.ail.json`
|
||||
|
||||
## Stats
|
||||
|
||||
bench/orchestrator-stats/2026-05-12-iter-cma.2.json
|
||||
@@ -21,3 +21,4 @@
|
||||
- 2026-05-12 — audit-rt: milestone close (Roundtrip Invariant) — architect drift fixed in rt.tidy (3 items: Direction-2 5th test, roadmap P1 removed, wording sync); bench all-green → 2026-05-12-audit-rt.md
|
||||
- 2026-05-12 — iter boss: `/boss` skill — autonomous-mode discipline (Direction freedom, Notifications, WhatsNew procedure) extracted from CLAUDE.md into a user-invoked skill → 2026-05-12-iter-boss.md
|
||||
- 2026-05-12 — iter cma.1: master mini-spec + render binary for cross-model authoring experiment (13 fixtures cover 34/34 AST variants, 4 test gates green, rendered/{json,ailx}.md checked in; out-of-workspace nested crate) → 2026-05-12-iter-cma.1.md
|
||||
- 2026-05-12 — iter cma.2: harness binary + 4 tasks + reference solutions + 4 integration tests (six modules, real-pipeline preflight via verify_references, 13/13 tests green; pipeline.rs renames program file to module-name for ail check) → 2026-05-12-iter-cma.2.md
|
||||
|
||||
Reference in New Issue
Block a user