Commit Graph

976 Commits

Author SHA1 Message Date
Brummel 50dc478ca5 spec: boehm-retirement — drop the transitional Boehm GC path
Resolves Gitea #4. Approach A (atomic single iteration). Six layers
in one cohesive cut: CLI `--alloc=gc` arm removed; codegen
`AllocStrategy::Gc` variant deleted with the default flipped to
`Rc`; libgc link branch removed; ~3 pure-differential e2e tests
plus the `gc_stress.ail` fixture deleted; ~9 RC-feature tests that
used GC-stdout as backstop lose only the differential assertion
(absolute fixed-stdout pin retained); M2 staticlib alloc-guard
drops its gc-arm (bump-arm preserved); design/models/rc-uniqueness
excises the Boehm-parity-oracle narrative; pipeline.md drops the
libgc pipeline-diagram arm; docs_honesty_pin flips from
Boehm-present-tense anchor to four absence-pins against
Boehm-zombie strings.

Three design forks were resolved with the user via brainstorm Q&A:

  (1) bump survives as bench-floor — `AllocStrategy::Bump`, the
      `--alloc=bump` CLI flag, and `runtime/bump.c` all stay; the
      enum keeps two variants (Rc, Bump); the codegen
      negative-complement test retargets from `AllocStrategy::Gc`
      to `AllocStrategy::Bump`. Bump's standing role is the
      raw-alloc bench-floor for RC-overhead measurement, not a
      production target.
  (2) the ~12 RC-vs-GC differential e2e tests are NOT all deleted
      wholesale — pure-differential ones (test name literally
      `*_matches_gc_*` or `*_same_stdout_as_gc`) are deleted; the
      RC-feature tests with GC as backstop keep their absolute
      stdout pin (`assert_eq!(stdout_rc.trim(), "<n>")`) and only
      lose the differential assertion. This nuance was added at
      spec time on top of the user's "delete the differential
      pattern" answer, because the differential was incidental to
      tests like `rc_box_drop` / `rc_list_drop_borrow` that pin
      drop-fn correctness under RC and would lose unrelated
      coverage if deleted entirely.
  (3) the 1.3× RC-over-bump number is retained in
      design/models/rc-uniqueness.md but reframed as a
      bench-health regression gate (not a Boehm-retirement gate);
      the closure-chain ±15% wider band is preserved analogously.

Grounding-check (ailang-grounding-check) PASS — 7 load-bearing
assumptions ratified, all spec-named paths and line numbers
verified (±2 lines), all proposed-for-removal strings present at
the spec-named locations. Assumption #7 (codegen default
currently Gc) is structurally self-evident: removing the variant
forces the default onto a surviving one by construction.

Out of scope, tracked separately:
  - Gitea #3 "Closure-pair slab / pool" — would tighten the
    closure-chain ±15% band; not blocked by retirement.
  - Any further `AllocStrategy::Bump` rework — still a
    single-variant bench instrument.

refs #4
2026-05-20 20:02:32 +02:00
Brummel 7a42989b34 iter nullary-app.1 (DONE 5/5): accept (app f) as canonical zero-arg call
Resolves Gitea #12 — the design fork from the 2026-05-20 /boss
session, surfaced independently by two prior fieldtests
(mut-local F3 + loop-recur `run_forever`).

Mechanics, layer by layer:

  Parser — `crates/ailang-surface/src/parse.rs:1322-1331` drops
    the 4-line `expected at least one argument` guard in
    `parse_app_body`. Grammar comments at file top change `term+`
    to `term*` on both `app-term` and `tail-app-term`; doc comment
    on `parse_app_body` changes `1+ args` to `0+ args`. Inline
    comment cites #12 and notes which layers below already accept
    empty args.

  Serde — `crates/ailang-core/src/ast.rs:419-425` annotates
    `Term::App.args` with `#[serde(default)]`, mirroring
    `Term::Ctor.args`'s *actual* attrs verbatim (no
    `skip_serializing_if`). Write behaviour unchanged — canonical
    JSON still emits `"args":[]` for nullary calls; only read
    behaviour gains tolerance for the `args` key being absent.
    Verified hash-impact-free at plan time:
    `grep -rn '"args":\[\]' examples/*.ail.json` returns zero
    matches, so no existing fixture's canonical bytes shift.

  Doc-honesty — `design/contracts/data-model.md`:
    (a) the `app` jsonc shape gains an explicit "args may be
        empty / read-tolerant" note;
    (b) the existing `ctor` comment claiming "args omitted when
        empty" was factually false (Ctor.args has no
        `skip_serializing_if`; a serde probe at plan time
        confirmed writes always emit `"args":[]`). Rewritten to
        describe the actual write/read asymmetry, with a
        cross-reference to the new `app` note.

  E2E pin — `crates/ail/tests/nullary_app_e2e.rs` +
    `examples/nullary_app_smoke.ail`. Defines `greet : fn()
    -> Unit !IO` and calls it as `(app greet)`; asserts stdout
    `"hello\n"`. RED→GREEN pin for the parser change AND the
    milestone-protecting E2E for nullary call surface going
    forward. Fixture literal is `"hello"` (no `\n`) because
    `io/print_str` lowers via `puts` which appends a newline —
    the plan body had a `"hello\n"` literal which would have
    yielded `"hello\n\n"`; the implementer caught and aligned to
    the canonical pattern in `examples/hello.ail` while writing
    the fixture, fix scoped to that single file.

Layers below parser untouched: typechecker's arity check at
`crates/ailang-check/src/lib.rs:3300` is `args.len() !=
params.len()` which is `0 != 0 → false` for nullary; codegen's
`args.iter().zip(sig.params.iter())` at
`crates/ailang-codegen/src/lib.rs:2410` is an empty loop;
LLVM `call @ail_<mod>_<name>()` with empty arglist is valid;
surface printer's arg-emit loop at
`crates/ailang-surface/src/print.rs:430-434` writes nothing for
empty args, producing exactly `(app f)`.

Verification: full workspace `cargo test --workspace --quiet`
green (0 failed across all crates); drift pins
`design_index_pin 5/5` + `design_schema_drift 8/8`; round-trip
`2/2`; new `nullary_app_e2e 1/1`. Stats file:
`bench/orchestrator-stats/2026-05-20-iter-nullary-app.1.json`.

closes #12
2026-05-20 18:57:14 +02:00
Brummel 7d8b3a3c10 plan: nullary-app.1 — accept (app f) as canonical zero-arg call form
Resolves the design fork in Gitea #12 (the bounce-back from the
2026-05-20 /boss session). User accepted both half-decisions:

  (a) the surface form `(app f)` becomes the canonical nullary
      call shape, dropping the "expected at least one argument"
      parser guard in `parse_app_body`;
  (b) `Term::App.args` mirrors the *actual* serde attrs of
      `Term::Ctor.args` — `#[serde(default)]` for read-tolerance,
      no `skip_serializing_if`, so writes always emit
      `"args":[]`.

The plan covers five small tasks: a RED→GREEN E2E (nullary user fn
called as `(app greet)`), the four-line parser-guard removal, the
one-attribute serde edit, and a doc-honesty fix on
`design/contracts/data-model.md` — the current "args omitted when
empty" comment on `Term::Ctor` is factually false relative to the
code (verified by a serde probe at plan time) and gets rewritten to
describe actual write/read behaviour while we are in the same jsonc
block. `design/contracts/honesty-rule.md` enforcement folded into
the same iter because leaving a stale comment behind in the block
we're modifying would be the exact failure mode the rule names.

Hash-impact verified at plan time: `grep -rn '"args":\[\]'
examples/*.ail.json` returns zero matches, so the new
`#[serde(default)]` on `App.args` is read-only behaviour change —
write side is unchanged, no existing fixture hash mutates. The
plan documents this explicitly under Task 3.2.

Two prior fieldtest specs already supplied the LLM-natural shape
evidence — `docs/specs/2026-05-15-fieldtest-mut-local.md` F3
(mut-local) and `docs/specs/2026-05-18-fieldtest-loop-recur.md`
spec_gap (`run_forever`) — so the feature-acceptance gate in
`design/contracts/feature-acceptance.md` is already passed; no
brainstorm phase needed for this iter.

refs #12
2026-05-20 18:52:22 +02:00
Brummel 70aad32e86 workflow(plan-recon): require compile-driven enumeration + existence table
Tightens `skills/planner/agents/ailang-plan-recon.md` against two
recon-contract failure modes documented in Gitea #9:

(a) For signature-change / enum-variant-add-remove / public-symbol-
    removal scopes, hand-listing of call sites or match arms has
    under-counted the blast radius four times across two milestones,
    each through a different site type (loop-recur.1 walker arms,
    loop-recur.2 cross-module synth callers, loop-recur.tidy implicit,
    remove-mut-var-assign.1 in-source `mod tests` fns + drift pin +
    `.ail.json` carve-outs + a non-enumerated E0599). The recon now
    MUST report a compile-driven enumeration (cargo check after a
    stub / exhaustive `git grep -nE` / `cargo expand`) as the
    authoritative code-site set; hand-listing is explicitly labelled
    "advisory". The compile-driven channel only covers compile-checked
    sites, so a separate sweep for drift pins, `.ail`/`.ail.json`
    fixtures, and design-doc references is required and reported
    under a "Non-compile-checked sites" section.

(b) Every path the spec names is now `ls`-verified before propagation
    into the brief. An existence claim feeding a recon is itself
    load-bearing — one prior recon brief inherited an unverified
    "X does not exist" claim (form_a.md, remove-mut-var-assign.1)
    and was caught only at milestone-close audit. The new "Spec-named
    path existence table" is mandatory for every dispatch (regardless
    of scope class); entries marked "not exists" must carry the exact
    `ls` / `git ls-files` command run, and only verified-not-exists
    entries may feed "Anchors not yet present".

Three new Common Rationalisations and three new Red Flags
calibrate against the named failure modes. The "Compile-driven
site set" / "Non-compile-checked sites" output sections may be
omitted for iterations that do not involve a signature / variant /
removal scope; the existence table is always required.

No language change; no code change. Agent-definition discipline
fix only.

closes #9
2026-05-20 18:26:54 +02:00
Brummel 13946219f5 fix(runtime): mirror surface .0-fallback in ailang_float_to_str
`runtime/str.c::ailang_float_to_str` now applies the `.0`-fallback
already enforced by the surface printer's `write_float_lit`
(crates/ailang-surface/src/print.rs lines 624-637): after the
existing `%g` snprintf, if `x` is finite and the rendered buffer
contains neither `.` nor `e`/`E`, append `.0` so a whole-valued
Float renders with Float-shaped text. The `isfinite(x)` fence
keeps `nan`/`inf`/`-inf` from matching the predicate and turning
into `nan.0`/`inf.0`. The 64-byte stack buffer's truncation guard
is extended by 2 bytes for the fallback path so the defensive
`abort()` discipline holds.

The alternative (document `%g`-without-fallback in the design/
ledger as a deliberate human-friendly contract) was rejected: the
language's stated ethos is machine-readability and round-trip
identity; the surface printer is the reference, runtime drift
from it is a defect not a feature.

Golden updates flow from the contract change. Three fixtures
encoded the old Int-shaped output for Float values:
- `crates/ail/tests/floats_e2e.rs`: `"4\n42\n-1.5\n"` →
  `"4.0\n42.0\n-1.5\n"` (1.5+2.5=4.0, int_to_float(42)=42.0).
- `crates/ail/tests/e2e.rs::mut_sum_floats_prints_55`: `"55"` →
  `"55.0"`. The accompanying doc comment used to canonicalise the
  bug ("`%g` strips the trailing `.0` — so the canonical stdout
  for Float 55.0 is `55`"); rewritten to reflect the new contract.
- `examples/mut_sum_floats.ail` docstring: same correction.

Two doc comments are updated where the post-fix contract differs
from the old text but the fixture golden does not change:
- `examples/float_to_str_smoke.ail` docstring (3.5 still renders
  as `3.5` because `.` is already present — the fallback does not
  fire).
- `crates/ail/tests/e2e.rs::float_to_str_smoke` doc comment (same
  observation, made explicit so the trip-wire's intent is clear).

Verified: `cargo test -p ail --test print_float_whole_e2e` green
(was RED at f19b0dd); `cargo test --workspace` 0 failed across
all crates and integration suites.

closes #7
2026-05-20 18:24:57 +02:00
Brummel f19b0dd860 test(runtime): RED — whole-valued Float must render with .0 suffix
Adds `examples/print_float_whole_smoke.ail` (single `(app print
2.0)`) and `crates/ail/tests/print_float_whole_e2e.rs`. The test
builds and runs the fixture through the public `ail build` CLI
and asserts stdout is `"2.0\n"`.

Currently FAILS with `left: "2\n"`, `right: "2.0\n"` — runtime
`ailang_float_to_str` uses libc `snprintf("%g", x)` which strips
trailing zeros, so a whole-valued Float prints as Int-shaped
text. The surface printer at
`crates/ailang-surface/src/print.rs::write_float_lit` (lines
624-637) already enforces the `.0`-fallback property; the runtime
drifts. This RED pins the desired symmetry.

The GREEN side will mirror the surface fallback in
`runtime/str.c::ailang_float_to_str` and update the
`floats_e2e.rs` golden (`"4\n42\n-1.5\n"` → `"4.0\n42.0\n-1.5\n"`)
plus the doc comments at `crates/ail/tests/e2e.rs` and in the
runtime/example files that documented the previous `%g`-without-
fallback contract.

The alternative (document `%g`-behaviour in design/ ledger §Float
semantics as a deliberate human-friendly contract) was rejected:
the language's stated ethos is machine-readability + round-trip
identity (CLAUDE.md §"AILang — a language for LLM authors"); the
surface printer is the reference, runtime drift from it is a
defect not a feature.

refs #7
2026-05-20 18:19:46 +02:00
Brummel a355fd861e fix(drift): scope anchor-presence check to jsonc fenced blocks
Adds `anchor_in_jsonc_block(md, anchor) -> bool` to
`design_schema_drift.rs` — a line-walking helper that toggles on
``` / ~~~ fence markers (any info-string: jsonc, json, or
unspecified — all count) and returns true only if the anchor
appears inside fenced content. Re-routes the seven
`DATA_MODEL.contains(anchor)` assertion sites in the file
(Term, Pattern, Type, Literal, Def, ParamMode, nested struct
keys) onto it.

The carrier from `debug` named six sites; in the implement phase
the orchestrator flagged a seventh — `design_md_anchors_nested_
struct_keys` — that exhibited the identical scope-widening bug and
was structurally identical to the named six. Routing it uniformly
is the cohesive shape of the fix; leaving it as `.contains()`
would have preserved a known false-positive surface inside the
same file the fix targets. The "minimal fix, no surrounding
cleanup" constraint blocks opportunistic refactor, not the
uniform application of the named one-line substitution.

Verified: 8/8 in `design_schema_drift` green (was 7 + 1 compile-
blocking RED at c8c30d5); full ailang-core suite green; full
workspace `cargo test` green, no regressions.

Mirrors the inverse `strip_fences` pattern in
`crates/ailang-core/tests/design_index_pin.rs`.

closes #10
2026-05-20 18:15:44 +02:00
Brummel c8c30d5682 test(drift): RED — anchor-presence must scope to jsonc fenced blocks
Adds `anchor_presence_check_is_scoped_to_jsonc_blocks` to
`design_schema_drift.rs`. The test pins the property in two
directions: an anchor mentioned only in prose must report ABSENT
under the scoped helper; an anchor inside a ```jsonc``` block must
report PRESENT; the live `design/contracts/data-model.md` must
remain PRESENT (anti-over-narrowing guard).

The helper `anchor_in_jsonc_block` does not yet exist — this test
compile-blocks the entire `design_schema_drift` file, which is the
intended contract pressure: the GREEN side must introduce the
helper for any drift test to run.

Pre-rolesplit the audit framed this as "anchors live in Decision 11
instead of §Data model"; the role-split iter (176821c) made
`data-model.md` its own file, but the per-match scope was never
narrowed — `.contains()` still cannot tell jsonc-block anchors
(load-bearing) from prose anchors (incidental). This RED pins the
remaining surface.

refs #10
2026-05-20 18:11:21 +02:00
Brummel 5627cc362c Update SKILL.md 2026-05-20 16:47:09 +02:00
Brummel 274c8ef291 Refactor CLAUDE.md and skills/boss/SKILL.md
Consolidate Gitea issue tracking information into CLAUDE.md and simplify
its references in skills/boss/SKILL.md. The Gitea issue tracker section
was removed from CLAUDE.md as it was redundant and the information is
now more clearly presented in skills/boss/SKILL.md.
2026-05-20 16:44:45 +02:00
Brummel 6933dc4c88 audit + close: bench-harness-recalibration CLEAN milestone close (no drift, bench 0/0/0, no tidy)
Single-iter milestone, single-artefact data update. Architect:
CLEAN — no design-ledger drift, no contract touched, no Rust source
touched. The `verification` contract (design/INDEX.md line 100)
ratifying-test (`bench/architect_sweeps.sh`) exits 0 on HEAD; the
script itself was not modified, only its input data
(`bench/baseline.json`). `jq`-keys-grep confirms zero
`max_us`/`p99_9_us` residue, matching the spec's acceptance check.
The `note` field reads as honest current-state with rationale
pointer to `docs/specs/2026-05-20-bench-harness-recalibration.md`
— no JOURNAL refs, no Wunschdenken anchors.

Bench: 0/0/0 after one stochastic-spike clarification.

- `bench/check.py`     exit 0 — 57 metrics, 0 regressed (post-recapture).
- `bench/compile_check.py` exit 0 — clean.
- `bench/cross_lang.py` first run exit 1 with one borderline
  REGRESSION (`bench_compute_intsum.ail_rc_s` +37.94% vs 35% tol on
  the sub-millisecond intsum workload — 0.5ms total, dominated by
  syscall/IO startup not algorithmic work). Bencher-pattern re-run:
  exit 0, same metric at +14.90% (23-percentage-point swing across
  two byte-identical-binary runs = classic single-sample jitter on
  the smallest workload, not drift). No baseline change to
  `bench/baseline_cross_lang.json`; the existing tolerances are
  fine.

Resolution: carry-on. No tidy iteration. No baseline change in
this audit-close commit (the iter commit `21cfccf` already wrote
the `bench/baseline.json` recapture per the iter's `--update-
baseline` step). No --update-baseline run on `cross_lang.py` (the
intsum flicker is jitter, not drift; the second-run clean exit
proves the baselines hold).

Architect drift item, [low], commit-prose correction:

The iter commit `21cfccf`'s "Follow-up noted" paragraph claims
`skills/implement/agents/ailang-implement-orchestrator.md`
references a Phase-4 per-iter journal write. That claim is wrong.
`grep -n "journal" skills/implement/agents/ailang-implement-
orchestrator.md` returns zero hits; Phase 4 of the orchestrator-
agent is `BLOCKED.md` (line 214: `### Phase 4 — On PARTIAL/BLOCKED,
write BLOCKED.md`). The orchestrator-agent's own end-report carried
the same factual error into the iter commit body. Forward-fix
recorded here: there is no orchestrator-agent staleness to chase;
no follow-up tidy iter is needed for this. main HEAD is sacrosanct
— the 21cfccf commit body stays as-is on disk, the correction
lives here.

Pipeline this milestone followed:

  brainstorm (PASS, trivial-spec path — no compiler/checker/codegen
  claims)
  -> planner (recon + plan + self-review 8/8)
  -> implement (DONE 4/4, 0 re-loops across all tasks)
  -> audit (CLEAN, no tidy, one [low] commit-prose forward-fix)

Closing Gitea #15 + #16. The `closes #15` / `closes #16` trailers
live on the iter commit `21cfccf` and will fire on push.

Spec: docs/specs/2026-05-20-bench-harness-recalibration.md
Plan: docs/plans/bench-harness-recalibration.1.md
2026-05-20 16:20:44 +02:00
Brummel 21cfccf846 iter bench-harness-recalibration.1 (DONE 4/4): drop 6 latency entries + recapture baselines
One-artefact iter on `bench/baseline.json`.  Closes Gitea #15 + #16
as documented in the spec commit `a97aaeb`.

Changes:

- `note` field rewritten forward-looking: drops the retired-JOURNAL
  workflow reference (Journal system deleted in 54f0ced) and the
  now-moot `*.max_us` tolerance convention (the metric being
  described is being removed in the same edit).  Points readers at
  `docs/specs/2026-05-20-bench-harness-recalibration.md` + closed
  issues #15 / #16 for rationale.
- 6 latency entries removed (`max_us` + `p99_9_us` × 3 arms:
  `implicit_at_gc`, `explicit_at_rc`, `implicit_at_rc`).  After the
  edit, `bench/check.py` gates only on `median_us` / `p99_us` /
  `p99_over_median` across the three latency arms.
- All remaining baselines (48 throughput + 9 latency = 57 metrics)
  regenerated by `bench/check.py --update-baseline` on HEAD
  `ddb50c3` from a fresh `bench/run.sh -n 5`.  `captured` field
  bumped 2026-05-09 → 2026-05-20.  Per-metric `tolerance_pct` and
  `version` preserved verbatim by `write_new_baseline`
  (`bench/check.py:249-284`).

Verification:

- Acceptance §1 (same-HEAD replay): `bench/check.py` exit 0, summary
  `57 metrics; 0 regressed, 0 improved, 57 stable` on first try
  (no single-run noise mitigation triggered).
- Acceptance §2 (synthetic injection): halving
  `throughput.bench_list_sum.bump_s.baseline` 0.053 → 0.026 fires
  REGRESSION row `+99.57% > 10.0%` with exit 1; restoration via
  `jq` returns the value to 0.053 and the next `bench/check.py`
  exits 0 (with 2 `improvement` rows on
  `latency.explicit_at_rc.p99_us` / `p99_over_median` at ≈-33% —
  improvements never gate; this is exactly the tail-distribution
  jitter that motivated dropping `max_us` / `p99_9_us`).

Diff shape:

- `bench/baseline.json` shows +230 / -67 lines.  Most of the line-
  count growth is the `json.dumps(indent=2)` pretty-print emitted
  by `--update-baseline` (`bench/check.py:283`) replacing the
  previous hand-formatted compact entries (each metric was one
  line; now each is six).  No behavioural delta — the file is
  semantically identical to a hand-edited version of the same
  changes.  Future `--update-baseline` runs will keep this expanded
  format.
- `bench/orchestrator-stats/2026-05-20-iter-bench-harness-recalibration.1.json`
  is the iter-stats artefact: outcome DONE, 0 re-loops across all
  4 tasks, the four bench-result fields documenting the acceptance
  outcomes.  Stats files are committed per `skills/implement/SKILL.md`
  Step 3.

No code change to `bench/check.py` / `bench/run.sh` /
`bench/latency_harness.py`.  No Rust crate touched.  `cargo test`
not exercised by this iter — the harness IS the test surface and
its replay+injection ARE the acceptance checks.

Follow-up noted (not addressed here):

- `skills/implement/agents/ailang-implement-orchestrator.md`
  references a Phase-4 per-iter journal write; the
  `docs/journals/` directory was retired in 54f0ced.  The
  orchestrator handled the mismatch by skipping the phase; the
  agent prompt itself is stale and should be edited in a follow-up
  tidy iter.

closes #15
closes #16
2026-05-20 16:15:13 +02:00
Brummel ddb50c3cb3 plan: bench-harness-recalibration.1 — drop 6 latency entries + recapture
One terminal iteration covering the whole spec.  Four tasks, all on
`bench/baseline.json`:

- Task 1: pre-recapture JSON edit — drop `max_us` + `p99_9_us` × 3
  latency arms (6 entries) and rewrite the `note` field forward-
  looking.  The 6 entries must go before `--update-baseline` runs
  because `write_new_baseline` faithfully re-baselines anything
  left in the file (recon Open Q).  The note rewrite is folded in
  here because `--update-baseline` preserves the existing note as-
  is, so any change has to happen before recapture (or as a
  separate post-recapture edit; one-edit is cleaner).
- Task 2: `bench/check.py --update-baseline` regenerates every
  remaining `baseline` value from a fresh `bench/run.sh -n 5`,
  updating `captured` → 2026-05-20 and `captured_via`.
- Task 3: acceptance §1 — fresh-HEAD replay → exit 0, 0 regressed,
  57 metrics in summary (= pre-edit 63 minus the 6 drops).
- Task 4: acceptance §2 — synthetic injection (halve
  `bench_list_sum.bump_s.baseline` via `jq`) → exit 1 + REGRESSION
  row on that metric, then restore via `jq` and confirm a final
  exit-0 replay.

Recon adjudications:

- Replay-source (recon Open Q1): fresh `bench/run.sh -n 5` for
  replay, not the same output that produced the recapture.
  Realistic acceptance scenario; with 10% throughput tolerance vs.
  ~1-2% measured run-to-run variance on the affected metrics
  (run-1 / run-2 reproduction data in spec body), there is ample
  margin.
- Note rewrite (recon Open Q2): forward-looking — drop stale
  refs (JOURNAL workflow retired 8e586f4; the `*.max_us`
  tolerance convention is now moot since the metric is gone),
  replace with pointer to docs/specs/2026-05-20-bench-harness-
  recalibration.md + closed issues #15 / #16.  Spec lives where
  the rationale lives; the note carries the gate-policy
  one-liner only.

No Rust crate touched.  `bench/check.py` / `bench/run.sh` /
`bench/latency_harness.py` unmodified.

Plan self-review (all 8 checklist items): clean.  Step granularity
checked; Task 3 collapsed from two `bench/check.py` runs to one
(single 3-minute run captures both summary and exit code).

Ready for handoff to `skills/implement`.
2026-05-20 16:07:53 +02:00
Brummel a97aaebd45 spec: bench-harness-recalibration — degate max_us/p99_9, recapture baselines
One-iteration infra milestone closing Gitea #15 + #16. Two issues
framed distinct symptoms; reproduction on 2026-05-20 HEAD via two
back-to-back `bench/check.py -n 5` runs collapses them onto a
single picture:

- #15 ("*.bump_s stale") is wider than the issue framed.  Drift
  reproduces deterministically on `bench_list_sum.bump_s`
  (+13.91% / +15.56%) AND on `bench_hof_pipeline.gc_s` (+10.60% /
  +10.94%) — not just the bump_s family.  Drift correlates with
  memory pressure: `bench_tree_walk` and `bench_compute_collatz`
  are clean across both runs.

- #16 ("*.max_us structural false-positive") has matured.  The
  "vanishes on rerun" pattern the issue documented from
  2026-05-16 / 2026-05-18 audits is gone: today
  `implicit_at_rc.max_us` reproduces at +47.20% / +49.42%, and
  `implicit_at_rc.p99_9_us` at +27.79% / +41.92%.  Same arm
  only (`implicit @ rc`); the other two latency arms are clean.
  The metrics are now drift-elevated AND structurally jitter-
  prone — both reasons to retire them from the gate.

Decision: one cohesive change, all in `bench/baseline.json`.  Drop
the six unreliable entries (`max_us` + `p99_9_us` × 3 latency
arms), then `bench/check.py --update-baseline` from current HEAD
to absorb the environmental drift in one honest cut.  No code
change to `check.py` / `run.sh` / `latency_harness.py` — the
harness already iterates only entries present in `baseline.json`,
so the schema mechanics work as-is.

Alternatives considered and rejected:

- Adding a `gated: bool` field per metric to keep `max_us` /
  `p99_9_us` measured-but-not-gated.  Pure speculative
  infrastructure: today's pathology is drift, not jitter, and
  the diagnostic value of `max_us` in the `check.py` report is
  hypothetical (it's already in `run.sh` output upstream).
  User push-back ("was soll 1?") was correct.

- Tolerance widening on the drifted metrics.  Hides the drift
  under a wider band; a real +10% codegen regress would
  slip through.

- `-n` raise for tail metrics.  Doesn't address the structural
  problem (max-of-distribution is OS-jitter-dominated regardless
  of N); blows up bench wall time ~10x.

- cpuset / `isolcpus=` pinning.  Sysadmin-layer fix that
  doesn't survive CI move or a new dev machine.

- Histogram-based latency methodology rework (Gitea #19).  The
  proper long-term fix, but a separate brainstorm; this
  milestone is the stop-gap that buys back the noise floor in
  the meantime.

Grounding-check (Step 7.5): PASS, trivial-spec path — no Rust
compiler / checker / codegen / schema / runtime claims (all
load-bearing claims are about the out-of-tree Python harness, and
are covered by the spec's own replay-pass + synthetic-injection
acceptance checks).
2026-05-20 16:02:46 +02:00
Brummel 19321d85ca workflow: add BLOCKER Gitea label — preempts everything in /boss
New label for "core functionality broken" — the only category
with a hard precedence rule baked into the skill system, not a
judgement call. No issues carry it today; the label and the
skills must know about it so that the first time one is filed,
the orchestrator handles it without a one-off "what now?"
exchange.

In-tree changes:

- CLAUDE.md: Gitea-issues bullet introduces a "precedence order
  matters" note and lists `BLOCKER` first.
- skills/boss/SKILL.md: Step 1 gains a dedicated `BLOCKER`
  precedence paragraph — every queue read starts with
  `tea issues ls --labels BLOCKER --state open`; if hit, it's
  the next dispatch (RED-first via skills/debug), preempting
  whatever else is in flight. The "finish the current agent
  call first, don't strand a working tree mid-edit" caveat is
  written in.
- skills/brainstorm/SKILL.md: Step 7.5 tea-create template
  flags that BLOCKER can stack on top of the kind label.

Universal bug-fix mechanics (RED-first TDD via skills/debug)
are unchanged — BLOCKER is a precedence tag, not a new
workflow. The /boss "Direction freedom" section continues to
gate cross-milestone hops; BLOCKER is an in-milestone preempt
that doesn't bounce back to the user (it has the orchestrator's
implicit authority by definition).

Verification: cargo test --workspace 647/0/2, architect_sweeps
exit 0.
2026-05-20 15:33:40 +02:00
Brummel 3e96e74457 workflow: add bug Gitea label + tag 6 existing bugs
New label for observable misbehaviour distinct from
additive-feature work and clean-up tasks. The /boss pickup
order treats a bug differently from a feature (a bug typically
gets RED-first TDD via skills/debug, a feature goes through
brainstorm), so the label earns its keep.

Tagged in Gitea (6 of 24 issues):

- #7  io/print_float always-emit-.0
       (surface vs runtime printer inconsistent)
- #9  ailang-plan-recon site-undercount
       (tool under-counted 4× across two milestones)
- #10 design_schema_drift.rs fidelity widening
       (test produces false negatives on §"Data model" gaps)
- #12 Zero-arg `(app f)` rejected at parse
       (parser disagrees with the AST schema)
- #15 *.bump_s throughput baseline stale
       (bench false-positive on environmental drift)
- #16 check.py RC-latency *.max_us
       (bench false-positive: 3-of-3 null changes)

Borderline cases left unlabelled (diagnostic usability,
load_workspace limitation, dormant constraint-drop, advisory
Sweep-5 wart) — they aren't observable wrong behaviour, just
suboptimal.

In-tree changes:

- CLAUDE.md: Gitea-issues bullet adds `bug` to the label set
  with the same description string Gitea carries.
- skills/boss/SKILL.md: Step 1 filter snippet includes `bug`.
- skills/brainstorm/SKILL.md: Step 7.5 tea-create template
  --labels choice set includes `bug`.

Distribution after tagging: 3 feature + 6 bug + 5 idea + 10
unlabelled = 24 open issues. Verification: cargo test
--workspace 647/0/2, architect_sweeps exit 0.
2026-05-20 15:30:29 +02:00
Brummel a5540c5620 workflow: retire milestone label — Gitea milestone container IS the concept
The `milestone` label was a dead duplicate of Gitea's first-class
milestone container. Zero issues carried it (the three actual
big-chunks — Flat array, Iteration-totality, Stateful islands —
live as Gitea milestone containers, not as labelled issues).
Same pattern as `prio:p1`: a slot that never gets used because
the concept it tries to label lives somewhere else.

Label deleted in Gitea. Remaining labels: `feature`, `idea`,
`in-progress` (three, all semantic, no taxonomy noise). Big-
chunk work continues to live as Gitea milestone containers
(reached via `tea milestones ls --repo Brummel/AILang`).

In-tree changes:

- CLAUDE.md: Gitea-issues bullet describes the three-label
  shape; explicit note that milestone is a Gitea container,
  not a label.
- skills/boss/SKILL.md: Step 1 filter set drops `milestone`,
  adds `tea milestones ls` for the container view; direction-
  freedom "new milestone" trigger reworded around the
  container, not the label.
- skills/brainstorm/SKILL.md: Step 7.5 tea-create template
  drops `milestone` from the choice set; adds a note that
  spec-needing deferred work should be filed as a Gitea
  milestone container via `tea milestones create` instead.

Verification: cargo test --workspace 647/0/2, architect_sweeps
exit 0, zero residual `milestone`-as-label refs in live docs
(grep skip-listed legitimate "Gitea milestone (container)"
prose).
2026-05-20 15:24:26 +02:00
Brummel d8379a15ba workflow: retire todo label — unlabelled IS the default bucket
`todo` and `feature` were semantically near-identical ("do it, no
spec needed") and the boss-pickup decision treated both the same.
Collapsing the larger one into "no label" cuts the tag-noise on
16 of 24 issues; the 3 `feature` issues retain the label as a
deliberate "substantive but no full spec" marker against the
unlabelled bucket of mechanical follow-ups.

Label `todo` deleted in Gitea (Tea removed it from the 16
issues automatically). Remaining labels: `milestone`, `feature`,
`idea`, `in-progress`.

In-tree changes:

- CLAUDE.md: Gitea-issues bullet describes the new shape —
  three semantic labels + unlabelled-default-bucket.
- skills/boss/SKILL.md: Step 1 filter-snippet and direction-
  freedom commentary updated.
- skills/brainstorm/SKILL.md: Step 7.5 tea-create template
  drops `todo` from the choice set and notes that omitting
  `--labels` is the default-bucket path.

Verification: cargo test --workspace 647/0/2, architect_sweeps
exit 0, zero residual `todo`-as-label refs in live docs.
2026-05-20 15:07:51 +02:00
Brummel c5fa6e6ea3 workflow: drop kind:/state: prefixes from Gitea labels
Labels renamed in Gitea (Tea propagated the rename to all 24
issues automatically):

- kind:milestone   → milestone
- kind:feature     → feature
- kind:todo        → todo
- kind:idea        → idea
- state:in-progress → in-progress

Five live labels total; no semantic ambiguity since milestone,
feature, todo, idea are all "class" and in-progress is the only
"state" — the prefixes were carrying zero distinguishing weight.

In-tree changes:

- CLAUDE.md: Gitea-issues bullet uses the bare label names.
- skills/boss/SKILL.md: Step 1 filter snippets + direction-
  freedom new-milestone trigger drop the prefixes.
- skills/brainstorm/SKILL.md: Step 7.5 tea-issues-create
  template drops the prefix on the --labels argument.

Verification: cargo test --workspace 647/0/2, architect_sweeps
exit 0, zero residual `kind:*` / `state:*` refs outside
docs/specs/ and docs/plans/.
2026-05-20 15:01:42 +02:00
Brummel c9025065d7 workflow: retire prio:p1/p2/p3 labels — kind:* alone classifies
Empirical observation after one day of running with the Gitea
backlog: P1 was permanently empty (same pattern as the old
docs/roadmap.md — anything that becomes "next-up" instantly
moves to in-progress, never sits in P1), and P3 was 6-of-8
identical to `kind:idea`. Three prio-stages were theatre; the
real distinction is "ja, irgendwann" vs "may be cut", and
`kind:idea` already carries the latter.

`prio:p1` / `prio:p2` / `prio:p3` deleted from Gitea (Tea
auto-removed them from all 24 issues). Remaining labels:
`kind:{milestone,feature,todo,idea}` + `state:in-progress`.
Issue distribution: 3 feature + 16 todo + 5 idea = 24.

In-tree changes:

- CLAUDE.md (project): Gitea-issues bullet rewritten — no
  formal priority axis, "what's next" is orchestrator
  judgement per session, `kind:idea` flagged as the
  may-be-cut marker.
- skills/boss/SKILL.md: Step 1 rewritten — `tea issues ls
  --state open` walks every open issue; selection is by
  orchestrator judgement, not by reading prio:p1 first.
  Cross-references "Queue:" updated to match.
- skills/brainstorm/SKILL.md: Step 7.5 no-override BLOCK
  template drops `prio:p2` from the `tea issues create`
  --labels argument.

Why not keep one stage (e.g. `prio:next`): no in-flight need;
a `pinned` boolean label can be added later if "next-up" ever
becomes a real distinct state. The cost of adding a label
later is one `tea labels create`; the cost of carrying dead
labels is constant cognitive load on every new issue.

Verification: cargo test --workspace 647/0/2, architect_sweeps
exit 0, zero residual prio:p* refs outside docs/specs/ and
docs/plans/ (historical, unchanged per the JOURNAL-cut
precedent).
2026-05-20 15:00:12 +02:00
Brummel 93887aa03b workflow: replace docs/roadmap.md with Gitea issue backlog
The forward queue moves out of the in-tree markdown file and into
Gitea issues at http://192.168.178.103:3000/Brummel/AILang/issues.
Labels: kind:{milestone,feature,todo,idea} + prio:{p1,p2,p3}
+ state:in-progress. Big chunks live as Gitea milestones
(containers) with full prose in the description; smaller items are
standalone issues. Browse-and-filter scales constant against
growing item count; the previous markdown file was 1059 lines, of
which ~850 were already-closed-entry verlauf (the same failure
class the JOURNAL cut removed).

Sync-drift Code<>Tracker mitigation: Soft-convention `closes #N`
/ `refs #N` in commit bodies — Gitea auto-closes the issue on
push. Captured in user-level CLAUDE.md (~/.claude/CLAUDE.md, not
in this commit) as the durable rule; no hook enforcement.

In-repo changes:

- docs/roadmap.md deleted.
- CLAUDE.md (project): Code-layout drops roadmap; /boss gating
  retargeted; Roles section rewritten with a new "Gitea issues"
  bullet (URL + tea-CLI snippet) and the closes-#N trailer note.
- skills/boss/SKILL.md: 10 sites retargeted, plus Step 1 now
  prescribes `tea issues ls --labels prio:p1` as the queue read.
- skills/brainstorm/SKILL.md: Step 7.5 no-override BLOCK now
  files a Gitea issue via `tea issues create` instead of
  appending a roadmap entry; spec deletion stays.
- skills/audit/SKILL.md + ailang-architect.md: deferral
  requirement and debt-heuristic retargeted; forward-intent
  belongs in the Gitea backlog.
- skills/fieldtest/SKILL.md, skills/docwriter/SKILL.md +
  ailang-docwriter.md: roadmap → backlog.
- design/contracts/honesty-rule.md: forward intent lives in
  the Gitea backlog (pinned phrases unchanged).
- design/INDEX.md: Docs bullet drops roadmap, adds the backlog
  URL.
- crates/ailang-core/tests/docs_honesty_pin.rs: two assert
  messages retargeted (assertion bodies unchanged).
- bench/architect_sweeps.sh: Sweep-4 TABU extended with
  `docs/roadmap\.md` so the deleted path cannot quietly regrow
  as a cross-reference in design/contracts/.

Verification:

- cargo build --workspace clean.
- cargo test --workspace: 647 passed, 0 failed, 2 ignored.
- bench/architect_sweeps.sh exit 0 (all five sweeps clean, incl.
  new TABU).
- grep over the live tree (excluding docs/specs/, docs/plans/)
  shows zero residual docs/roadmap.md refs.

Not touched: ~55 historical files under docs/specs/ and
docs/plans/ that mention docs/roadmap.md. Snapshot-character,
analogous to the JOURNAL-cut precedent — historical specs are
not mass-edited just because a live file was retired; their
mentions were correct at write time.
2026-05-20 14:48:27 +02:00
Brummel 99df14c792 workflow: scrub residual JOURNAL/journal refs missed in the first sweep
A re-grep found 15 live references (excluding docs/specs/ and
docs/plans/, which stay historical) the previous two commits
missed — all in source comments, doctests, bench helpers, and one
agent file.

Per-file:
- crates/ail/src/main.rs: typeclass-coherence diagnostic comment
  pointed at "the JOURNAL queue's wording" — points at
  design/contracts/typeclasses.md alone.
- crates/ailang-prose/src/lib.rs: `//!` header referred to
  docs/JOURNAL.md "Pinned: human-readable prose surface" —
  retargeted to design/contracts/authoring-surface.md.
- crates/ailang-check/src/lib.rs: bugfix tag + "see iter
  method-dispatch-refactor journal" prose collapsed to a clean
  rationale paragraph; the canonical shape is stated inline.
- crates/ailang-surface/tests/prelude_decouple_carve_out_pin.rs:
  "(d) record the rationale in a per-iter journal" →
  "(d) record the rationale in the commit body".
- crates/ailang-surface/tests/prelude_module_hash_pin.rs: header
  collapsed (pd.2/pd.3 milestone narrative dropped — the test's
  purpose is self-evident from its body); both "per-iter journal"
  drift-instructions point at the commit body.
- runtime/rc.c: "bench numbers in JOURNAL 18f.2" →
  "original profiling bench numbers".
- bench/run.sh: two "JOURNAL entry" comments → "commit body".
- bench/architect_sweeps.sh: header rewritten (cross-ref to the
  design-md-consolidation milestone commits, not a JOURNAL entry).
  Sweep-4 extended with two new anti-regrowth phrases
  ("see the per-iter journal", "in a per-iter journal") so journal
  prose can't grow back into design/contracts/ silently.
- skills/audit/agents/ailang-architect.md: "unlike a journal it
  lives on main" → "since it lives on main".
- ail-embed/src/bin/timeshard_runner.rs: "records it in the
  close-out journal" → "prints it to stderr".
- ail-embed/tests/timeshard.rs: two "journal-only friction timing"
  → "stderr-only friction timing".

Verification (after the edit):
- `grep -rin '\bjournal\b'` against live tree returns exactly two
  hits: the Sweep-4 regex itself (intentional — TABU phrases that
  prevent regrowth) and the PHRASES array in design_index_pin.rs
  (intentional — the same regrowth guard at test level). Both are
  load-bearing negative assertions.
- `bash bench/architect_sweeps.sh` exits 0 ("All five sweeps
  clean") — no design/-side regrowth.
- `cargo build --workspace` green; `cargo test --workspace` green.
2026-05-20 11:32:37 +02:00
Brummel 54f0ced148 workflow: delete docs/journals/ and docs/journal-archive.md
Strict application of the "Future-Use, not Verlauf" criterion to the
two remaining journal artefacts:

- `docs/journals/` (110 files): the per-iter and audit journals from
  2026-05-11 onward. Pure history; no live reader after the previous
  sweep. Entire directory removed.
- `docs/journals/2026-05-19-design-decision-records.md`: the one file
  that had live readers (`docs_honesty_pin.rs:108`, `parse.rs:80`,
  `duplicate_ctor_pin.rs:8`, three roadmap.md mentions) and was framed
  as a "relitigation guard". On re-examination its three asserted
  pinned phrases ("Regions were considered and rejected", the
  "demands annotations *because*" rationale, the prose-render
  placeholder statement) are rationale-prose, not load-bearing
  invariants — the test pinned itself, not a system property. Any
  Decision that still holds lives in the code, `design/contracts/`,
  or `design/models/`. Removed with the rest.
- `docs/journal-archive.md` (pre-2026-05-11 history): content-frozen
  long-tail history with no live reader. Removed; if anyone ever
  needs the pre-cutoff rationale they can `git log --before=2026-05-11
  --grep=<keyword>`.

Live-file consequences:
- `docs_honesty_pin.rs` `design_md_present_tense_anchors_present`:
  the three `records.*` assertions and the `read("docs/journals/…")`
  are dropped; the contract/model anchor pins remain.
- `duplicate_ctor_pin.rs`: the "why-two-overlays rationale lives in
  docs/journals/…" comment is replaced with the rationale inline.
- `parse.rs`: the "form-refinement rationale lives in docs/journals/…"
  comment is dropped (the rule body already states the refinement).
- `roadmap.md`: the decision-records mention in the DESIGN.md →
  design/ entry's body is dropped; the journal-archive.md `context:`
  pointers across ~12 closed entries are either rephrased to point
  at the relevant iter/audit (no path), or simplified to a one-line
  comment when the iter name alone carries the story.
- `CLAUDE.md` Roles section: the `docs/journal-archive.md` slot is
  removed; vocabulary note rephrased.
- `design/INDEX.md`: the Docs bullet drops `journal-archive.md`.
- `skills/README.md` bootstrap-rationale pointer rephrased.

`docs/specs/` and `docs/plans/` (per-milestone specs and per-iteration
plans) are unaffected — they remain the structured-design artefacts
they were before this sweep.

Workspace builds, full test suite green.
2026-05-20 11:25:15 +02:00
Brummel 8e586f493f workflow: replace per-iter journal system with git log + BLOCKED.md
The per-iter journal under docs/journals/ duplicated the iter commit
body's substance and accumulated as Verlauf-Doku with no Future-Use.
Sweep across all live control documents: CLAUDE.md, the 7 SKILL.md
files, the 11 agent files, design/INDEX.md and the contracts/models
that referenced journals, docs/roadmap.md, and the handful of source
comments + tests that pointed at journal files for rationale.

Mechanism changes:
- Standing-reading-lists in every agent now read `git log -N --format=full`
  for recent project state, never per-iter journal files. The architect
  reads `git log <prev-milestone-close>..HEAD --format=full` for audit
  scope.
- implement-orchestrator no longer writes a journal file. DONE outcomes
  emit just code + stats; the end-report is the per-task summary the
  Boss uses to write the commit body. PARTIAL/BLOCKED outcomes emit
  BLOCKED.md at the repo root — uncommitted by convention, Boss removes
  on repair or discard. New iron-law line + four-rationalisation row
  + red-flag bullet codify it.
- audit ratify mechanic: --update-baseline is now paired with an explicit
  ratify paragraph in the audit-close commit body, not a separate
  JOURNAL ratify entry.
- design/contracts/honesty-rule.md: "history and rationale lives in
  docs/journals/" → "lives in git log (iter and audit commit bodies)".
  Pinned phrase preserved verbatim.
- CLAUDE.md "Roles of …" section reframed: design/, git log,
  journal-archive.md (content-frozen), roadmap.md, specs/, plans/.
  No docs/journals/ slot anymore.
- roadmap.md context-lines that pointed at per-iter journals are
  dropped where the spec/commit already carries the rationale, or
  rephrased to "shipped in the <iter> iter commit" / "docs/journal-
  archive.md (<date> entry)" for pre-2026-05-11 references.

What stays (this commit):
- docs/journals/ directory and contents are NOT touched. Removing the
  contents is a separate follow-up.
- docs/journals/2026-05-19-design-decision-records.md still has live
  readers (docs_honesty_pin.rs Z 108 + parse.rs + duplicate_ctor_pin.rs
  + 3 roadmap mentions) — also follow-up.
- docs/journal-archive.md still exists; its self-pointer header has
  been updated to drop the "see docs/journals/INDEX.md" mention.

Workspace builds, full test suite green.
2026-05-20 11:21:37 +02:00
Brummel 55ad0fa37f workflow: drop docs/WhatsNew.md (Notify carries done-state on its own)
WhatsNew.md duplicated the Notify text into a file the only reader
(the user) does not consult. Removed the file and trimmed every
reference in the live control docs (CLAUDE.md, skills/boss,
skills/implement). The editorial rules (no internals,
telegram-pragmatic, factual) are preserved in skills/boss as
notify-text discipline. Historical specs/plans/journals are not
rewritten — they show the contemporaneous state.
2026-05-20 10:27:33 +02:00
Brummel ac4d545570 source: scrub iter-code / Decision-N residue from inline comments
Follow-up to bcd4181: the remaining ~530 inline `//` and `///`
comments still carrying opaque shorthand are now reformulated to
their content phrases. The only surviving `iter-<code>` reference
in source is the literal filename
`docs/journals/2026-05-13-iter-mq.3.md` (a real journal file).

Sweep covered:
  - `// Iter X.Y: <text>` prefixes (Iter 13a / 14a / 14e / 15g-aux /
    16b.x / 16d / 16e / 18b / 18c.x / 18d.x / 18e / 18g.x / 19a /
    19a.1 / 19b / 20a / 20f / 22-floats.x / 22b.x / 22c / 23.x /
    24.1 / cli-diag-human / hs.x / str-concat / etc.) — fully
    removed; the descriptive text that followed each prefix stays.
  - `// (Decision N)` and `per Decision N` and `Decision N axis 3` —
    replaced with the content phrase plus the relevant contract
    file (`design/contracts/tail-calls.md` for Decision 8,
    `design/contracts/memory-model.md` for Decision 10,
    `design/contracts/typeclasses.md` and `design/models/typeclasses.md`
    for Decision 11, `design/contracts/authoring-surface.md` for
    Decision 6, "the transitional dual-allocator" for Decision 9,
    "Effect prose" for Decision 3).
  - `// mq.X / mq.X (Task N) / mq.X journal / mq.X invariant` ->
    "the canonical-class-form rule / Class-class repurpose /
    method-dispatch-refactor journal / canonical-class-form
    invariant".
  - `// ct.X / ct.X (canonical-type-names) / ct.1.5a + ctt.2 /
    ct.2 Task N` -> "the canonical-form rule for type references /
    the canonical-form normalisation step / canonical-type-lookup
    refactor".
  - `// eob.X` -> "heap-Str-ABI" / "the Str carve-out".
  - `// rpe.X` -> "the per-type-print-op retirement".
  - `// post-mq.X / Pre-ct.X / pre-mq.X` -> "post-canonical-class-form" /
    "Pre-canonical-type-form" etc.
  - `/// Iter X regression: / /// Iter X.Y: / /// Iter A arm-close /
    /// Iter ct.4 (...): / /// Iter rpe.1 ...` -> descriptive
    phrases.

The journal filename in `crates/ailang-core/src/workspace.rs:573`
stays verbatim because it points at an actual file under
`docs/journals/`.

Tests: full `cargo test --workspace` green (80/80 test-result blocks
clean, no FAILED line). design_index_pin 5/5 + docs_honesty_pin 5/5
gating tests pass.
2026-05-20 09:58:04 +02:00
Brummel bcd41810f4 design/ + source rustdoc: replace opaque shorthand with content phrases + links
Reader-facing prose and rustdoc carried opaque shorthand like
"Decision 10", "clause-5", "mq.1", "ct.1", "eob.1", "rpe.1",
"post-mq.3", and "Iter 22b.1:" with no in-repo definition the reader
could follow. This commit replaces every such occurrence in the
durable tier the reader is most likely to land on (design/ ledger +
source //! module headers + the central /// public-item rustdoc) with
an inline content phrase plus, where applicable, a Markdown link to
the file that defines the referenced concept.

design/ ledger — 16 files:
  Definition-site headings demoted from "Decision N: <title>" to
  "<title>": authoring-surface, tail-calls, memory-model section in
  rc-uniqueness.md, dual-allocator section, typeclass design,
  effects "pure core + algebraic effects".
  Cross-reference sites: "Decision 1" -> canonical-schema principle
  (data-model); "Decision 3/4" -> effects + scope-boundaries; "Decision
  6" -> authoring-surface; "Decision 8" -> tail-calls; "Decision 9" ->
  rc-uniqueness (dual-allocator); "Decision 10" -> memory-model;
  "Decision 11" -> typeclasses (model). "clause-5" -> body-link
  durability gate. "clause-3" (in language-constraints) ->
  bug-class-reintroduction discriminator. "mq.1/2/3", "ct.1/4",
  "eob.1", "rpe.1" -> the canonical-form rule / the type-driven
  dispatch / the Str carve-out / etc. "post-mq.3" -> "type-driven".

design/contracts/feature-acceptance.md: file-local "clauses 1/2/3"
-> "criteria 1/2/3" (sprachliche Kohärenz mit der File-Überschrift
"Feature-acceptance criterion"); "the clause-3 mechanism" -> "the
bug-class-reintroduction discriminator".

Source //! module headers — 24 files:
  Stripped "Iter X.Y:" prefixes and "(Decision N)" / "(mq.X)" tags
  from spec_drift, uniqueness, reuse_shape, migrate_canonical_types,
  typeclass_22b{2,3,c}, suppress_filter, lift, mono, linearity,
  diagnostic, method_dispatch_pin, method_collision_pin,
  no_per_type_print_ops, mq3_multi_class_e2e, print_mono_body_shape,
  print_no_leak_pin, cli_diag_human_workspace_load_error,
  ct1_check_cli, prose snapshot, unbound_in_instance_method_pin,
  mono_xmod_ctor_pattern, desugar.

Central /// public-item rustdoc:
  ast.rs (full sweep — every "Iter X" + "Decision N" prefix
  reformulated; mode/Type::Fn rustdoc now points at memory-model.md;
  Constraint / SuperclassRef / InstanceDef / ClassDef rustdoc points
  at typeclasses contract).
  diagnostic.rs (all "(Iter X)" / "(mq.X)" tags on diagnostic codes
  removed).
  lib.rs (FORM_A_SPEC rustdoc points at authoring-surface.md
  instead of "Decision 6").
  canonical.rs (type_hash + Float-literal rustdoc).

Still outstanding (for a follow-up commit): ~500 inline `//`
code-body comments with `Iter X.Y` markers across the workspace, and
a handful of `///` rustdoc items in hash_pin / workspace_pin / lift /
mono / suppress_filter test-pin and internal-function bodies. Code
identifiers (test filenames like `mq3_multi_class_e2e.rs`, function
names like `iter18e_drop_iterative_default_preserves_hashes`) stay
verbatim per the user's "code identifiers stay verbatim" rule.

Tests: design_index_pin 5/5 + docs_honesty_pin 5/5; workspace builds
clean; full `cargo test --workspace` previously green (every
`test result: ok` line, no FAILED line).
2026-05-20 09:47:33 +02:00
Brummel 3e087d759a design/ ledger: prose-bridges for in-fence §-refs in data-model.md
Five §"..." cross-refs survived the main sweep because they live
inside jsonc Schema-comments — clause-5 fence-skip would treat any
[label](path) there as literal text, not as a navigable link.

Instead of touching the schema-comment style (it is self-documenting
where it sits, against the field it qualifies), this commit adds
prose paragraphs just outside the fence that turn the same
cross-references into real links:

  - Before the Def jsonc block: pointer to memory-model.md
    (canonical-form rule for cross-module class/type names) and
    embedding-abi.md (exported fn surface).
  - Before the Type jsonc block: pointer to memory-model.md for
    Type::Con.name scoping and Type::Fn parameter-mode metadata.

Also re-phrases an intra-file §"Str ABI" self-reference in
str-abi.md to "the Str ABI table below" — file-only granularity
makes a self-link sense-less; the reader wants intra-file
direction, which prose carries fine without a link.

Tests: design_index_pin (5/5) + docs_honesty_pin (5/5) stay green.
2026-05-20 00:46:37 +02:00
Brummel 19dc42f5ca design/ ledger: dense cross-linking via three topical splits + 88-link sweep
The first formal-links milestone shipped clause-5 + 8 links across the
existing file layout. Browsing surfaced that file-only granularity is
only as precise as the file boundaries — three files mixed two or
three navigation targets under one address, so the 8 links could not
multiply without ambiguity. This commit fixes the substrate, then
applies the sweep the original milestone deferred.

Splits (each extracts an already-self-contained section into its own
file so links land on the topic, not the parent doc's TOC):

  contracts/typeclasses.md
    → +contracts/prelude-classes.md  (Eq/Ord/Show ships, polymorphic `print`)
    → +contracts/method-dispatch.md  (5-step dispatch rule, candidate index)

  contracts/memory-model.md
    → +contracts/language-constraints.md  (the 4 binding constraints
                                           making RC sound without a
                                           cycle collector)

  models/authoring-surface.md
    → +models/prose-projection.md  (Form-B / `ail prose` / merge-prose)

Each new file enters design/INDEX.md as its own row (three contracts
share show_no_instance_e2e.rs / uniqueness.rs as ratifying tests;
prose-projection is a model). Two pre-existing links rebind to the
new topic-files (memory-model.md → method-dispatch.md;
float-semantics.md → prelude-classes.md).

Link sweep: 8 → 88 formal Markdown links over 23 files. Every file
in design/contracts/ + design/models/ now has at least one outgoing
link; the tree is fully connected. Links are file-relative
`[label](path)` per the established convention, fenced code blocks
are skipped (a `](` inside ```jsonc``` is literal text), the durable
tier (design/ + crates/ + runtime/) is enforced by clause-5.

Tests:
  - design_index_pin.rs (5/5 clauses): clean-cut, INDEX resolution,
    ratifying-test resolution, no decision-record prose in contracts/,
    body links durable + resolving.
  - docs_honesty_pin.rs (5/5): one assertion rebinds from typeclasses.md
    to prelude-classes.md (where the gated sentence now lives);
    design_corpus widens to include the 4 new files so the Wunschdenken
    / doc-archaeology sweeps continue to cover everything that used to
    live in the parents.

No spec/plan/journal for this batch — interactive collaboration after
the milestone closed; the user gated the splits explicitly before the
sweep.
2026-05-20 00:24:08 +02:00
Brummel cca6e3959d audit + close: design-ledger-formal-links CLEAN milestone close (no drift, bench 0/0/0, no tidy)
Cleanest close pattern in recent project history. Architect: zero
drift -- every commitment + invariant verified positively (clause-5
implements all 4 predicates incl. fence-skip, 8 link tokens match
the closed convert-set exactly, disposition-(b) applied to the 2
homeless pointers, honesty-rule positive-half pin-safe, commitments
4/7 byte-unchanged, composition invariant clause-3 ∧ clause-5 GREEN
simultaneously, out-of-scope set untouched incl. the 5 in-fence
data-model annotations, no commitment-2 violation in any reading
list, architect_sweeps clean). Bench: check.py exit 0 (63/0/0/63),
compile_check exit 0 (24/0/0/24), cross_lang exit 0 (25/0/0/25);
baseline pristine, no --update-baseline, no paired ratify.

The two spec amendments (clause-6 + cross-ref definition;
clause-5 fence-skip + closed convert-set enumeration) were the
discipline working: planner-recon and plan-corpus-fetch surfaced
gaps the brainstorm-sample missed; the spec was corpus-grounded
*before* any byte moved (grounding-check PASS x3); implementation
then ran clean 5/5 with one non-blocking concern (planner
self-review-item-8 arithmetic miss on the //! header line count --
substantive assertion unaffected; recorded as lesson).

No tidy iteration. No fieldtest -- zero authoring-surface change
(no .ail, no language construct, no compiler/checker/codegen path)
is the spec-stated reasoned exclusion, audit-confirmed.

This commit ratifies the milestone close:
- audit journal: docs/journals/2026-05-19-audit-design-ledger-formal-links.md
- journals/INDEX.md: audit pointer appended
- roadmap.md: [~] -> [x] CLOSED 2026-05-19 with full pipeline record
- WhatsNew.md: user-facing done-state entry (verbatim with notify)

Spec: docs/specs/2026-05-19-design-ledger-formal-links.md
Plan: docs/plans/design-ledger-formal-links.1.md
Iter journal: docs/journals/2026-05-19-iter-design-ledger-formal-links.1.md
Pipeline: brainstorm (PASS x3) -> planner (recon + plan +
self-review 8/8) -> implement (DONE 5/5, Boss-verified independently)
-> audit (CLEAN, no tidy).
2026-05-19 23:37:59 +02:00
Brummel 8ad91e7f24 iter design-ledger-formal-links.1 (DONE 5/5): clause-5 hard gate + 7 prose-ref conversions + 2 disposition-(b) homeless removals + honesty-rule positive-half (whole milestone in one iter)
Positive-half completion of the DESIGN.md -> design/ split: design/
body cross-references are now formal, file-relative Markdown links
into the durable tier (design/ or source), and a new in-tree hard
gate (design_index_pin.rs clause-5,
design_body_links_are_durable_and_resolve) walks every
design/contracts/*.md + design/models/*.md, strips fenced code
(strip_fences toggles on ```/~~~ lines so a ](  inside a fence is not
treated as a link), extracts every ](path), and asserts the target
resolves file-relative to a real file under design/-or-crates/-or-
runtime/; never docs/, never an in-file #anchor.

RED-first via identity-stubbed strip_fences (four embedded synthetic
vectors -- first one FAILS); replacing the stub with the real
toggle-on-fence impl turns the test GREEN. clause-5 composes with
clause-3 into the complete invariant the milestone establishes:
every contract cross-reference is EITHER a resolving durable
file-link OR clause-3-forbidden decision-record prose.

Conversions (recon-and-corpus-verified closed set):
  Task 2 (7 prose refs, 8 link tokens):
    float-semantics.md:69    Prelude classes -> [..](typeclasses.md)
    float-semantics.md:100   bare-path -> [Str ABI](str-abi.md)
    embedding-abi.md:45      "Frozen value layout" -> [..](frozen-value-layout.md)  (drop stale "below")
    memory-model.md:44       Data model -> [..](data-model.md)
    memory-model.md:105-106  Method dispatch -> [..](typeclasses.md)  (drop stale "below"; the target heading lives in typeclasses.md:227, not in this file)
    scope-boundaries.md:48   Str ABI -> [..](str-abi.md)
    scope-boundaries.md:88   mixed split: ailang-core::desugar -> source link + Pipeline -> ../models/pipeline.md (drop stale "above")
  Task 3 (2 disposition-(b) homeless removals):
    pipeline.md:60-61            (see docs/PROSE_ROUNDTRIP.md) pointer removed, CLI prose preserved
    authoring-surface.md:178-181 cross-tier pointer clause removed, ail merge-prose sentence preserved
  Task 4: honesty-rule.md positive-half paragraph inserted between L14 and the existing L15-blank-L16; both docs_honesty_pin.rs-pinned phrases byte-identical at L14/L19 (now shifted to L19 -> L25 by the +6 lines).

Out of scope, preserved (asserted independently): every intra-file
"above/below"; embedding-abi.md:51 "frozen value layout below
specifies" (no quoted title, no (see) form); data-model.md
38/66/79/206/226 (in-fence ```jsonc schema annotations -- the inline
analog of the nominal-mention carve-out). INDEX.md and the
decision-records journal byte-unchanged; clauses 1-4 of
design_index_pin.rs source byte-unchanged (the only `-` lines in
the diff are the two-line //! header rewrite Task 1 Step 5 itself
delivers).

Boss-verified independently (not on agent report alone):
  cargo test --workspace               647 passed / 0 failed
                                       (+1 vs pre-milestone 646:
                                        the new clause-5)
  cargo test --test design_index_pin   5 / 5 passed
  cargo test --test docs_honesty_pin   5 / 5 passed (additive
                                       paragraph is pin-safe)
  grep ](.../docs/.../) under design/  zero
  grep ](#)        under design/  zero
  ](-link count under design/          8 (closed convert-set)
  git diff --quiet design/INDEX.md     ok
  git diff --quiet decision-records    ok
  embedding-abi.md:48 pinned phrase    byte-identical

One Concerns item: Task-5 Step-7's plan-predicted "`-` line count = 1"
was actually 2 because Task 1 Step 5 rewrote the //! header 5 -> 8
lines (removing the original L4 + L5, not just L5). Planner self-
review-item-8 miss on my part -- a verification-arithmetic error in
the plan, NOT an implementation defect. The substantive assertion
(clauses 1-4 source byte-unchanged) is fully satisfied; the
implementer correctly flagged it and proceeded. The plan stands as
written; the assertion's `1` should have been `2`. Lesson noted for
future header-rewrite tasks.

Spec: docs/specs/2026-05-19-design-ledger-formal-links.md
(grounding-check PASS x3 across two corpus-grounded amendments --
clause-6 + cross-ref definition; clause-5 fence-skip + closed
convert-set enumeration).

Next: mandatory milestone-close audit (no fieldtest -- zero
authoring-surface change, reasoned exclusion).
2026-05-19 23:31:30 +02:00
Brummel 36599bedd9 plan: design-ledger-formal-links.1 — clause-5 + 7 conversions + 2 disposition-(b) + honesty-rule positive-half
Single iteration covering the whole milestone (same shape as
rolesplit.1; spec is small, no build-atomicity issue — clause-5 is
isolated additive code, prose edits don't affect compilation).
Five tasks, each at task-level review granularity:

  Task 1: clause-5 added to design_index_pin.rs RED-first via
          identity-stubbed strip_fences (synthetic vector FAILS) →
          correct toggle-on-fence impl (GREEN); module //!-header
          extended to name clause-5. Test count 4 → 5.
  Task 2: 7 prose-ref conversions to file-relative Markdown links
          (float-semantics:69/100, embedding-abi:45, memory-model:44/
          105, scope-boundaries:48/88 with the source+Pipeline split).
          Exact verbatim before→after for every line. clause-5 stays
          GREEN by construction (every introduced link resolves
          durable).
  Task 3: 2 disposition-(b) homeless-ref removals (pipeline:60-61
          in-fence CLI block + authoring-surface:178-181 prose).
          Pointer dropped, behavioural prose preserved.
  Task 4: honesty-rule.md pin-safe positive-half paragraph between
          L14 and the existing L15-blank (the two docs_honesty_pin
          phrases at L14/L19 each stay verbatim on their physical
          line; the additive insertion splits neither). The new
          paragraph names design_index_pin.rs clause-5 by name
          (nominal mention, not a link — consistent with the
          existing 'Ratified by:' footer style and with §Scope).
  Task 5: Whole-suite gate (646 → 647) + 5 grep+diff verifications
          (no docs/ link, no #fragment, link count = 8, in-fence
          schema-annotations intact, INDEX.md + decision-records
          journal + clauses 1-4 byte-unchanged).

Self-review 8/8: spec coverage complete; zero placeholders; names
consistent; bite-sized; no commit steps; pin contiguity verified
(L14 + L19 stay verbatim on their physical lines, replacement body
shows L14 contiguous); no signature change ⇒ no compile-gate
ordering issue; every cargo-test filter substring is a real test
name + unfiltered runs have explicit count assertions.
2026-05-19 23:21:29 +02:00
Brummel 42ff44adf6 spec: design-ledger-formal-links — corpus-grounded amendment (clause-5 fence-skip + closed enumeration)
Plan-time corpus verification surfaced a third distinct gap the
brainstorm-sample missed: data-model.md:38/66/79/206/226 are 'see §"..."'
annotations inside fenced jsonc code blocks (verified: fences at
30-87 and 203-228; the 5 refs fall inside), where a Markdown link is
literal text — not a navigable link on any renderer.

Per the "two+ surfaced ⇒ ground the spec properly once, don't iter-patch"
discipline: amendment 2 is the definitive corpus-grounded pass, not a
fourth-patch returning later. Every convert-set ref's prose-vs-fence
status + exact bytes personally verified before amending.

- clause-5 (Concrete a): adds a strip_fences helper toggling on
  triple-backtick / tilde lines; the per-file scan runs
  targets(&strip_fences(&raw)); the RED-first synthetic vector gains
  two fence-skip assertions (identity-stub of strip_fences ⇒ first
  assert fails ⇒ genuine RED). Contract grows from 3 to 4 predicates
  (+ fenced-code-not-scanned).
- Scope section: third out-of-scope carve-out — a 'see §"..."' inside
  a fenced code block is schema-example documentation = the inline-
  annotation analog of the nominal-mention carve-out (a // comment in
  a code example is code documentation, not a 'go browse there'
  pointer). Clean extension of the converged navigational-vs-nominal
  principle.
- Acceptance 3: convert-set CLOSED and exhaustive — 8 prose refs
  (float-semantics:69/100, embedding-abi:45, memory-model:44/105,
  scope-boundaries:48/88), 2 disposition-(b) homeless removals
  (pipeline:61, authoring-surface:180), 6 stay-prose (data-model
  in-fence x5, embedding-abi:51). Iter-provenance suffixes stripped
  on conversion. scope-boundaries:88 splits into a source link plus a
  Pipeline cross-file link.

grounding-check third dispatch on the amended bytes: PASS, all 8
assumptions ratified (incl. corpus-state-verified A4-A7 per the
rolesplit precedent for text-enumeration claims).
2026-05-19 23:14:56 +02:00
Brummel b1a0364bf2 spec: design-ledger-formal-links — recon-driven amendment (clause-6 + cross-ref definition)
Planner Step-2 recon (ailang-plan-recon) surfaced two spec defects;
forward-fix amendment (63b669f stands, main forward-only):

- clause-6 homeless-ref remedy was an incomplete binary. Recon proved
  roundtrip-invariant.md does NOT carry the ail-merge-prose-cycle
  content that pipeline.md:61 / authoring-surface.md:180 cite — so the
  prior canonical retarget sample was wrong. Replaced with three
  priority-ordered dispositions; PROSE_ROUNDTRIP refs take (b) (drop
  the cross-tier pointer, preserve the present-tense behavioural prose).
- Added a precise 'what counts as a cross-reference' definition:
  navigational pointer = in scope; nominal source-symbol mention = out
  of scope (keeps the milestone 'formalise the cross-references', not
  'hyperlink the ledger'). Source link only for a genuine navigational
  (see crates/...). Folds OQ2 (strip iter-provenance suffixes on
  conversion) + OQ3 (no-title directional stays prose) as byte-policies.

grounding-check re-dispatched on the amended bytes: PASS, all
assumptions ratified incl. the amendment-introduced ones.
2026-05-19 23:03:03 +02:00
Brummel 63b669fa8f spec: design-ledger-formal-links — formal cross-links in the design/ ledger
Positive completion of the DESIGN.md -> design/ split: informal prose
cross-references become formal file-relative Markdown links, gated by a
new RED-first design_index_pin.rs clause-5 (every design/ body link
resolves into the durable tier or fails the build). INDEX spine stays
repo-root-relative (registry tier, clause-1 unchanged). No authoring
surface. Eight converged commitments + the user-decided INDEX sub-fork;
grounding-check PASS 7/7. roadmap [~] in-flight.
2026-05-19 22:51:21 +02:00
Brummel 2ee408770e roadmap: close DESIGN.md->design/ ([~]->[x]); WhatsNew: design-spec-restructure done-state 2026-05-19 13:46:14 +02:00
Brummel f683f1aec8 iter design-md-rolesplit.tidy (DONE 7/7): resolve milestone-close audit drift
Gate-first TDD: widened design_index_pin.rs clause-3 to a hand-rolled
FAITHFUL Sweep-1 superset (case-sensitive digit-anchored line anchors
+ Sweep-1's ^[^/]* path-excluded date + the audit-named
decision-record phrases, case-insensitive); no regex dep; the blanket
iter-detector rejected as unworkable. Sentence-level strip of
faithfully-migrated history/decision-record prose out of 5 contract
files (the audit's 3 spot-checked + roundtrip-invariant.md +
data-model.md the exhaustive scan found) into the decision-record
journal, each replaced by its present-tense contract equivalent;
float-semantics.md stale 'see Str ABI below' -> str-abi.md;
architect_sweeps honesty sweeps re-scoped to design/contracts only
(models/ is the narrative tier) + ailang-architect.md lockstep.
Invariant: clause-3 GREEN => Sweep-1 clean in contracts/.

The prior dispatch correctly BLOCKED on a real plan defect (iso_date
lacked Sweep-1's path-exclusion, over-firing on legit
docs/specs/2026-.. citations); per the two+-defects-in-one-iteration
discipline the audit Resolution mechanism+scope were corrected
upstream in lockstep (f2cdd67) before re-dispatch, not patched a
third time.

Boss-verified independently: cargo test --workspace 646/0,
design_index_pin 4/4 (clause-3 RED->GREEN), architect_sweeps.sh exit
0 'All five sweeps clean' (acceptance criterion 9 met), acceptance
grep CLEAN, 3 docs_honesty_pin pinned runs each exactly 1 contiguous
match. Zero spec/quality re-loops. FINAL design-md-rolesplit
iteration — milestone functionally complete, audited, drift-resolved,
hard gate enforces the honesty spirit.
2026-05-19 13:44:37 +02:00
Brummel f2cdd67e69 plan+audit: design-md-rolesplit.tidy re-derived on planning-time evidence (mechanism + scope corrected)
The tidy's gate-first Task 1 RED-verification + Boss independent
verification surfaced two defects in the audit Resolution as first
written — caught exactly where the planner->Boss loop is designed to,
before any contract byte moved. Per the 'two+ defects in one
iteration => fix the upstream artifact, do not patch a third time'
discipline, the audit Resolution is corrected in lockstep with the
plan re-derivation:

- Mechanism (Resolution-4): the 'case-insensitive iter-code regex'
  clause-3 design is REJECTED as unworkable — a blanket
  iter/milestone detector conflates the memory-model rule-names
  'Iter A'/'Iter B' and ordinary words 'pre-existing'/'pre-set'/
  'pre-Boehm' with provenance, over-firing on legit present-tense
  contract prose (4 no-strip files). Replaced by a FAITHFUL Sweep-1
  superset: case-sensitive digit-anchored Sweep-1 line anchors
  (confirmed ZERO across all contracts) + Sweep-1's ^[^/]*
  path-excluded date (so docs/specs/2026-.. citations are not
  flagged — repairs the iso_date over-fire the implement
  orchestrator correctly BLOCKED on) + the audit-named
  decision-record phrases (case-insensitive). No regex dep. The
  load-bearing invariant (clause-3 GREEN => Sweep-1 clean) is
  preserved; it never required the blanket detector.
- Scope (Resolution-1): the architect's [medium] was a 3-file
  spot-check; the exhaustive scan found roundtrip-invariant.md:73
  ('at iter form-a.1') and data-model.md:149,161 ('loop-recur iter
  1:') also carry lowercase provenance. True strip set = 5 files;
  plan Task 5b adds the 2 (spirit-cleanup, not gate-blocking).

Plan self-review 8/8 re-run; clause-3 = hand-rolled faithful Sweep-1
superset, no regex dep, no blanket iter detector.
2026-05-19 13:36:14 +02:00
Brummel 4f61a7aa4f plan: design-md-rolesplit.tidy — audit drift fix (history->journal, sweep re-scope, clause-3 widen)
7 tasks executing the audit Resolution's 5 points: (1) gate-first
RED — widen design_index_pin.rs clause-3 to a hand-rolled PROVABLE
SUPERSET of architect_sweeps Sweep-1 over design/contracts/ (no
regex dep; subsumption proof inline), verify RED vs the un-stripped
tree; (2-4) sentence-level strip the faithfully-migrated
history/decision-record prose out of typeclasses.md / str-abi.md /
scope-boundaries.md into the decision-record journal, per recon's
per-sentence contract-residue map, each docs_honesty_pin pinned run
guarded contiguous; (5) fix float-semantics.md stale 'see Str ABI
below' -> str-abi.md; (6) re-scope architect_sweeps DESIGN_GLOB to
design/contracts only (models/ is the narrative tier) + lockstep
ailang-architect.md; (7) whole-tree GREEN gate (clause-3 RED->GREEN,
4/4, sweep exit 0, suite >=646/0, acceptance grep CLEAN).
Self-review 8/8.
2026-05-19 13:22:22 +02:00
Brummel 2ba5e16806 audit design-md-rolesplit (milestone close): DRIFT (one tidy iter) + bench causally-exonerated (baseline pristine)
Architect: relocation byte-faithful; one [medium] spirit-finding —
faithfully-migrated decision-record/history prose in
design/contracts/{typeclasses,str-abi,scope-boundaries}.md dodges the
6 literal clause-3 markers but is the relitigation content the
split's spirit sends to journals; [low] float-semantics.md
stale-direction 'see Str ABI below'. Both routed items: tidy not
ratify (the str-abi.md:23 advisory Sweep-1 exit-1 correctly
diagnoses real pre-existing history residue, byte-identical
DESIGN.md@deeffb1 — faithfully migrated, not split-introduced).

Bencher: causally-exonerated, DECISIVE on byte-evidence — emitted IR
AND final -O2 binaries byte-identical 176821c vs dd5b183 for all 6
check.py firings; all ~11 changed files audited
comment/docstring/diagnostic-string-only; tracked-P2 families;
compile_check/cross_lang pristine. NO-ratify, baseline pristine
(M2/M3/M5 disposition).

Resolution: one tidy iter (move history prose to the decision-record
journal; fix stale 'below'; re-scope architect_sweeps honesty sweeps
to design/contracts only — models/ is the narrative tier; widen
design_index_pin.rs clause-3 to subsume Sweep-1's history-anchor
regex over contracts/ so the hard gate enforces the spirit). No
fieldtest (zero authoring-surface change). Milestone closes after
the tidy lands Boss-verified.
2026-05-19 13:14:15 +02:00
Brummel 176821c2e7 iter design-md-rolesplit.1 (DONE 9/9): DESIGN.md -> design/ ledger role-split
The 3020-line docs/DESIGN.md is replaced by the design/ ledger:
design/INDEX.md (sole addressable spine, typed Contracts+Models tables,
polymorphic links — prose file OR authoritative source //!), 14
design/contracts/*.md test-linked invariants + 3 source-link-only
contracts (mangling/env-construction/qualified-xref, no prose file —
code is SoT), 5 design/models/*.md whitepapers, and
docs/journals/2026-05-19-design-decision-records.md (the
relitigation-guard archive — every why/rejected/does-not-do/rollback/
empirical ### moved out at ###-granularity). Clean cut: git rm
docs/DESIGN.md, no stub.

RED-first crates/ailang-core/tests/design_index_pin.rs — the 4-clause
anti-regrowth spine (DESIGN.md-gone / every-INDEX-link-resolves /
every-contract-names-a-resolvable-ratifier /
contracts-carry-no-decision-record-prose) — demonstrably RED before,
GREEN after. Build-atomic by task ordering: design_schema_drift.rs's
include_str! (the only compile-time consumer) retargeted to
design/contracts/data-model.md BEFORE the deletion; its
## Data model/## Pipeline slicer dropped (a simplification the split
enables). 2 NoInstance diagnostics + 2 lockstep E2Es retargeted to
design/contracts/{float-semantics,typeclasses}.md. ~12 agent reading
lists + 5 SKILL bodies + CLAUDE.md + skills/README.md + ~25
code/C/.ail/spec comment xrefs retargeted; OQ7 dangling 'Iter 13b'
cite deleted (no forward target — a pointer would be fiction).
honesty-rule.md rewritten so the rule names the new home
(rationale->journals), resolving the recon-found internal
contradiction; the two docs_honesty_pin.rs:70,72 pinned phrases kept
verbatim+contiguous.

Boss-verified independently: cargo test --workspace 646 passed /
0 failed; design_index_pin 4/4; acceptance grep CLEAN of live
DESIGN.md refs (residuals = only the spec-mandated clause-4
deletion-enforcer). 2 DONE_WITH_CONCERNS routed to the mandatory
milestone-close audit: (a) str-abi.md:23 '(iter str-concat,
2026-05-13)' provenance stamp trips advisory architect_sweeps Sweep-1
— Boss-confirmed byte-identical to DESIGN.md@deeffb1:2062-2065, a
faithfully-migrated PRE-EXISTING anchor (regexes verbatim, only path
retargeted), NOT split-introduced — RATIFY-or-tidy at audit; (b) a
now stale-direction intra-prose 'see Str ABI below' cross-ref in
float-semantics.md — audit-adjudication candidate. Plan defect noted:
Task 9 Step 4's verbatim acceptance grep used a ^./ anchor not
matching the system's grep -rIn output; substance re-verified CLEAN.

Spec grounding-check PASS x2. Journals INDEX + decision-records
pointer appended (Boss-only).
2026-05-19 13:04:22 +02:00
Brummel deeffb1872 plan: design-md-rolesplit.1 — the whole milestone, build-atomic by task ordering
9 tasks: (1) RED-first design_index_pin.rs 4-clause guard; (2)
design/INDEX.md + 14 prose contracts; (3) 5 model whitepapers; (4)
decision-record journal + INDEX pointer; (5) retarget the 3
doc-reading tests GREEN vs design/; (6) 2 diagnostics + 2 E2Es
lockstep; (7) architect_sweeps.sh spine repoint; (8) ~12 agent lists
+ 5 SKILL bodies + CLAUDE.md + README + bucket-(e) comment xrefs +
OQ7 cite deletion; (9) clean cut (git rm DESIGN.md) + whole-tree gate
+ acceptance grep. Build-atomicity by construction: include_str!
retarget (Task 5) precedes DESIGN.md deletion (Task 9), data-model.md
exists from Task 2 — every intermediate cargo build is green, no
monster task. Self-review 8/8 (contiguity + compile-gate-ordering +
filter-resolution scrubbed).
2026-05-19 12:16:21 +02:00
Brummel 314e5e4920 spec: design-md-rolesplit — Boss-adjudicated relocation appendix (planner recon resolution)
plan-recon surfaced 7 open questions (genuine Boss design judgement,
not architectural forks). Adjudicated and folded into the spec as an
authoritative placeholder-free Appendix relocation map (every ##/###
of DESIGN.md -> exactly one destination):

- design_index_pin.rs clause-2 widened to accept crates/**/src/*.rs
  in-source #[cfg(test)] mod tests as first-class ratifiers.
- INDEX ratifier tokens resolved to recon-verified paths; memory-model
  -> uniqueness.rs (in-source), tail-calls -> lib.rs:5044
  tail_call_in_non_tail_position_is_rejected (NOT loop_recur — different
  construct), env-construction path corrected to ailang-check/tests.
- 3 ledger additions the 12-list under-counted: qualified-xref
  (source-link only), str-abi (prose+source; the one sanctioned
  sentence-level move, 2802 bold para), scope-boundaries (present-tense
  honesty-pinned). Net 15 contracts / 5 models / 1 decision-record journal.
- OQ7: lib.rs:103 dangling 'Iter 13b' cite is deleted not retargeted
  (no forward target exists; a pointer would be fiction).

grounding-check re-dispatched after the material edit: PASS, all 6
changed/new ratifiers resolve to named currently-green tests.
2026-05-19 12:11:53 +02:00
Brummel a64b2ccb2a spec: design-md-rolesplit — DESIGN.md role-split into design/ contracts+models ledger
Role-split the 3020-line docs/DESIGN.md into design/contracts/ (the
hot, test-linked invariant set), design/models/ (one whitepaper per
model), and design/INDEX.md as the sole addressable spine; decision-
records rehomed to docs/journals/. Clean cut (DESIGN.md deleted, no
stub), ###-subsection relocation granularity, build-atomic landing
(design_schema_drift.rs include_str! forces one commit), polymorphic
INDEX links (code-SoT contracts point at source //!, no prose dup),
typed-INDEX anti-regrowth pin (design_index_pin.rs). grounding-check
PASS 13/13 after one re-dispatch (commitment-4 pin-status claim
corrected: Decision-6 :242 audit-trail sentence is pinned by no test,
retired to the decision-record journal, no successor pin by design).

roadmap: DESIGN.md->design/ marked [~] in flight (spec landed).
2026-05-19 11:58:07 +02:00
Brummel dd5b18378f docs: DESIGN.md §Embedding ABI — current-state honesty (no general-ABI claim)
The §"Embedding ABI" prose presented the M3 contract as "the
embedding ABI" — a general boundary — and justified the layout
freeze with "this is what codegen emits today". Both overclaim:

- The accepted set (bare scalar | single-ctor all-scalar record)
  is the *whole* contract, narrow by construction. The host
  hand-constructs and hand-reads the box layout directly; there
  is no general value-marshalling layer. The text now says this
  plainly instead of framing the set as a subset of a wider ABI.
- The freeze is reframed as the consequence of that direct
  layout exposure (the host is the contract surface), not as
  "frozen because that is what lower_ctor emits".
- "MUST NOT move these offsets" is corrected to "for an exported
  type" — the prior wording overclaimed the freeze as binding
  every record layout; the commitment binds exported types and
  thereby constrains codegen repacking of exported records.

Present-tense Ist-state mirror only: no lockstep/wire-contract
design, no post-mortem, no aspirational "should become". Schema
section untouched. Verified green: design_schema_drift (8),
docs_honesty_pin (5), effect_doc_honesty_pin (4),
embed_record_layout_pin (1), embed_staticlib_lowering (3).
2026-05-19 11:22:25 +02:00
Brummel d160f2c977 roadmap: close Embedding ABI — M5 ([~]->[x]) — M1–M5 arc complete, audited+ratified+doc-honest; WhatsNew + P2 reframed
M5 done 2026-05-19: real backtest over real Pepperstone tick data
through the real external data-server into the shipped M3-frozen
kernel, across a per-thread-ctx thread swarm; symbol-fan (headline
existence proof) + time-shard (first actual proof of chunk-boundary
invisibility); globally leak-free, deterministic. Zero
language/compiler change; one runtime change (7bfa11e atomic
global RC-stats fallback — user-adjudicated bounce-back, RED-first,
+ a build-dep staleness root-caused & fixed). Audit: Invariant 1
PASS, M3 frozen-layout unmoved, gc_rss trio evidenced-RATIFY
(Boehm conservative-scan artefact, Decision-9 transitional), P2
noise causally exonerated baseline-pristine, doc-honesty tidy
clean. Friction-harvest: host-per-tick-FFI ~= ~206 ns/tick at real
EURUSD volume.

- roadmap M5 [~]->[x] with the done-state summary (stays one cycle
  for context, then prune).
- roadmap P2 "Flat array/slice primitive" reframed: the
  M4-retirement forward note's deferred reconciliation is now
  done — the obsolete "1024-cell cons-chain per chunk / M4 ships
  it" framing replaced with the real residual (host-per-tick-FFI
  vs. batch crossing) anchored on M5's measured ~206 ns/tick; the
  M5-dependency is now satisfied (the justification input exists).
- WhatsNew.md done-state entry (verbatim == the notify text):
  user-facing, no internals — the embedding arc is complete.

Done-state notification fired (user away per /boss). The next
roadmap item is a new milestone (the P2 flat-array decision or
another P0) — a deliberate user call, not autonomous.
2026-05-19 03:10:04 +02:00
Brummel 70f2a318e0 iter embedding-abi-m5.tidy (DONE 3/3): milestone-close doc-honesty drift — pin-safe, doc/comment-only
Resolves the M5 milestone-close audit DRIFT (audit journal
28ab56a). Single cohesive commit, M2.tidy a80d495 / M3.tidy
63d7d60 precedent (pins are the coverage, no RED, no
audit/fieldtest gate).

- docs/DESIGN.md edit-1 §"Free (host side)": dropped the retired-M4
  forward-reference ("an additive M4 concern, not a contradiction
  of this freeze"; M4 retired 2026-05-18) -> present-tense current
  fact (a boxed-field record is not an M3 embedding type,
  export-gate-rejected; the freeze covers exactly the all-scalar
  single-ctor record).
- docs/DESIGN.md edit-2 §"Embedding ABI": reconciled the now-
  inaccurate "(no shared mutable runtime state - ... data-race-free,
  sanitiser-verified)" blanket with the real post-7bfa11e state:
  the per-allocation hot path (per-ctx counters + per-object
  refcount header) is non-atomic by design and never shared
  (Ctx:!Send, single-thread-per-ctx); the one shared datum is the
  atomic-relaxed global RC-stats fallback counter; "data-race-free,
  sanitiser-verified" retained (still true).
- runtime/rc.c:88 comment-only: stale "two unconditional ++
  operations" -> accurate "one counter bump per alloc/free ...
  relaxed atomic add on the global null-ctx fallback, a plain ++
  on the per-ctx path" (consistent with the adjacent already-
  correct :93-106 atomic block + :45-55 Threading header).

Boss-verified independently: all pins green (design_schema_drift
8/0, docs_honesty_pin 5/0, effect_doc_honesty_pin 4/0,
embed_record_layout_pin 1/0) = mechanical proof no pinned/hashed
byte moved; the adjacent separately-pinned bare-scalar sentence is
byte-identical (shifted 2299->2305 by net-added lines; substring
pin, passes); rc.c strictly comment-only (filter empty);
cargo build --workspace Finished; git scope = only docs/DESIGN.md
+ runtime/rc.c + journal/stats. Clears the M5-audit doc-honesty
debt; no new debt.

FINAL M5 iteration. The M1-M5 Embedding ABI arc is functionally
complete, audited, ratified, and doc-honest. Includes the per-iter
journal, stats, and INDEX line.
2026-05-19 03:07:40 +02:00
Brummel e81fb90d88 plan: embedding-abi-m5.tidy — milestone-close doc-honesty drift (pin-safe, doc/comment-only)
Resolves the M5 milestone-close audit DRIFT (audit journal
28ab56a). 3 tasks, doc/comment-only, recon-verified pin-safe:
T1 docs/DESIGN.md — drop the retired-M4 forward-reference
(§"Free (host side)" ~:2354-2360) + reconcile the "no shared
mutable runtime state … data-race-free" claim with the now-atomic
global RC-stats fallback (§"Embedding ABI" ~:2287-2298, must not
disturb the adjacent line-2299 pinned bare-scalar sentence);
T2 runtime/rc.c:88 — comment-only fix of the stale "two
unconditional ++" performance aside (consistent with the adjacent
already-corrected :93-106 atomic block); T3 consolidated
doc-only/pin-safe/scope gate. All 3 sites recon-verified OUTSIDE
every pinned/hashed region (design_schema_drift scans only the
post-line-2362 data-model slice; docs_honesty_pin:135 pins the
distinct line-2299 sentence; the IR-byte pin asserts generated IR
not rc.c comments). Pins green before+after = the mechanical
pin-safety proof; no RED, no audit/fieldtest gate — mirrors the
M2.tidy a80d495 / M3.tidy 63d7d60 precedent (single cohesive
commit, pins are the coverage). Last step before M5 fully closes.
2026-05-19 03:02:51 +02:00
Brummel 28ab56af7e audit embedding-abi-m5: milestone close — RATIFY gc_rss trio (evidenced) + DRIFT (one doc-honesty tidy); P2 bench noise causally exonerated, baseline pristine for it
Architect: Invariant 1 PASS (zero data-server in any compiler
crate/runtime; ail-embed its own workspace root); M3 frozen-layout
SSOT unmoved (the lone rc.c change 7bfa11e touched only the global
stats counters); rc.c header-comment honesty accurate. Drift =
[medium] DESIGN.md:2358-2360 stale "additive M4 concern" (PRE-
EXISTING — M4 retired; correctly scoped out of every M5 iter) +
[medium] DESIGN.md §"Embedding ABI" silent-drift (it asserts "no
shared mutable runtime state … data-race-free" but the now-atomic
global RC-stats fallback IS shared mutable state under concurrency;
M5 is AILang's first concurrent consumer) + [low] rc.c:88 "two
unconditional ++" imprecise → one doc-honesty tidy iteration
(embedding-abi-m5.tidy), same honesty axis, not split.

Bencher refuted my pre-audit "gc_rss allocator-orthogonal →
environmental" hypothesis WITH EVIDENCE: the 3x *.gc_rss_kb +32%
are genuine, deterministic, M5-attributable — 7bfa11e's atomic
split a branch in ailang_rc_alloc (reached by GC programs via
str.c int->str at print), spilling %r14/%rbx; a stale interior
list pointer in the new spill slot is conservatively retained by
Boehm, pinning a ~32 MB dead spine (collection #12 freed PRE 32 MB
vs HEAD 32 B); bisects exactly on the commit, IR byte-identical,
ail sha256-identical; RC/bump RSS dead-stable. bump_s + max_us are
pre-existing tracked-P2 noise (bump RC-orthogonal; max_us 1-sample
tail-jitter, PRE often worse, +65->+104% swing between runs) — NOT
M5.

RATIFY the gc_rss trio. Language reason (not effort): Decision 9 —
Boehm is explicitly transitional; AILang's committed model is RC +
uniqueness. The measurable cost of the correct, necessary,
user-approved swarm-safety fix is exclusively a Boehm
conservative-stack-scan false-retention artifact on the
transitional allocator (codegen-layout-fragile; no memory actually
leaked; RC/bump RSS dead-stable). Chasing it with an out-of-scope
codegen change invests in the path being migrated away from; the
committed RC path is unaffected. Selective baseline re-anchor:
bench/baseline.json lines 14/44/64 ONLY -> 137448/137768/137636
(bencher-confirmed steady-state); every other metric byte-pristine
(a wholesale --update-baseline would absorb the P2 noise and break
the established-envelope discipline). Re-run confirms the 3 now ok
at +-0.3%.

bump_s x2 + max_us x2: NO-ratify, causally exonerated, baseline
left pristine — identical disposition to the M2/M3/prelude-decouple
milestone closes.

Friction-harvest recorded (P2 flat-array-decision input):
host-per-tick-FFI ~= ~206 ns/tick at real EURUSD volume.

Ratify discipline: updated baseline JSON + this paired JOURNAL
ratify entry committed together (bench/baseline.json + the audit
journal + INDEX line). M5 closes after the doc-honesty tidy lands
and is Boss-verified.
2026-05-19 02:56:43 +02:00
Brummel 0900f3f413 iter embedding-abi-m5.3 (DONE 3/3): time-shard boundary-invisibility proof + friction harvest
Final functional M5 iteration (spec ae905de, plan 67027ab; on
green m5.1 204c171 + m5.2 b724cd1 whose leak-proof resolved via
dbd76e5). Proves the chunk/window-boundary-invisibility claim the
M4 retirement rests on:

- adapter::fold_window — purely additive windowed sibling of
  fold_symbol (same MidPriceStream+Kernel path; stream_tick_windowed).
  fold_symbol/MidPriceStream/Kernel byte-untouched.
- chrono as a DEV-dep only — the time-shard test derives
  (y,m)->Unix-ms bounds (data-server's own precedent) and passes
  raw ms to the bin; the bin is date-math-free; Invariant 1
  unaffected.
- new single-responsibility [[bin]] timeshard_runner — one thread
  per disjoint window, each owning its Kernel (Ctx:!Send =>
  compile-time per-thread-ctx).
- tests/timeshard.rs — spec §3 strength-ordered: (a) per-shard
  (acc,n) BIT-EXACT vs single-thread host fold of that exact window
  in stream order (THE boundary-invisibility proof); (b) Σ partials
  bit-exact by construction; (c) whole-window within REL_TOL=1e-6
  only (cross-shard f64 reassociation is host arithmetic, never a
  kernel property — bit-exact there would be the bug; tolerance
  derived from the recursive-summation error bound). Plus the
  now-deterministic leak-Σ + a journal-only friction timing capture
  (no bench gate, no timing assertion).

Concrete pin: EURUSD 2017-03/04/05 (recon-verified present,
contiguous, no gaps; data-server has no month-listing API). RED was
a genuine deterministic compile failure (declared-but-absent bin
source; Cargo missing-source error vs the plan's predicted env!
error — same cause, no false-green; benign plan-text imprecision in
Concerns).

Boss-verified independently: timeshard determinism 5/5 (no jitter);
full ail-embed suite 0 failed AND 0 ignored across all binaries
(m5.2 symbol_fan_swarm_leak_free stays un-ignored & green — the
saga's resolution intact); isolated embed_rc_global_stats_race
still green; AILang workspace data-server count 0; compiler-surface
diff empty (zero diff to crates/ailang-*, crates/ail/, runtime/,
examples/*.ail, root Cargo.toml, DESIGN.md).

Friction-harvest deliverable (P2 flat-array-decision input):
host-per-tick-FFI ~= 658 ms / 3,192,562 ticks ~= ~206 ns/tick at
real EURUSD volume.

M5 functional work complete; milestone closes next via the
mandatory audit (which also handles the pre-existing
DESIGN.md:2358-2360 "additive M4 concern" drift, out of m5.3 scope).
Includes the per-iter journal, stats, and the INDEX.md line.
2026-05-19 02:40:16 +02:00