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.
This commit is contained in:
2026-05-20 11:21:37 +02:00
parent 55ad0fa37f
commit 8e586f493f
28 changed files with 362 additions and 373 deletions
+35 -34
View File
@@ -43,7 +43,7 @@ it measurably improves correctness or removes redundancy.
| `bench/` | Regression harnesses (`check.py`, `compile_check.py`, `cross_lang.py`) and the throughput-and-latency runner (`run.sh`); `bench/reference/` holds the hand-C corpus for cross-language ratios | | `bench/` | Regression harnesses (`check.py`, `compile_check.py`, `cross_lang.py`) and the throughput-and-latency runner (`run.sh`); `bench/reference/` holds the hand-C corpus for cross-language ratios |
| `examples/` | AILang fixtures used by tests and benches | | `examples/` | AILang fixtures used by tests and benches |
| `design/` | The canonical contract ledger — `design/INDEX.md` (sole addressable spine: a typed Contracts + Models table), `design/contracts/` (prose-authoritative test-linked invariants), `design/models/` (onboarding whitepapers) | | `design/` | The canonical contract ledger — `design/INDEX.md` (sole addressable spine: a typed Contracts + Models table), `design/contracts/` (prose-authoritative test-linked invariants), `design/models/` (onboarding whitepapers) |
| `docs/` | Specs and decisions log — `docs/journals/` (per-iter journals + `INDEX.md`; incl. the migrated design decision-records), `docs/journal-archive.md` (pre-2026-05-11 history), `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `PROSE_ROUNDTRIP.md` | | `docs/` | Specs and roadmap — `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `docs/roadmap.md` (forward queue), `docs/journal-archive.md` (pre-2026-05-11 history, content-frozen), `PROSE_ROUNDTRIP.md`. Per-iter history lives in `git log`. |
| `skills/` | Project-local skill definitions and their agents. See `skills/README.md` for the skill table, agent roster, and discovery layout. | | `skills/` | Project-local skill definitions and their agents. See `skills/README.md` for the skill table, agent roster, and discovery layout. |
## Skill system ## Skill system
@@ -75,8 +75,8 @@ See @skills/README.md for the skill + agent roster.
### What this means in practice ### What this means in practice
- **Plan, design, decide** — myself. Architectural choices, scope, - **Plan, design, decide** — myself. Architectural choices, scope,
invariants, and the contents of `docs/journals/` and the invariants, commit bodies, and the contents of the `design/`
`design/` ledger are my work product. ledger are my work product.
- **Implement, refactor, write tests, diagnose bugs** — by default, - **Implement, refactor, write tests, diagnose bugs** — by default,
delegated. `ailang-implementer` for code changes that follow a delegated. `ailang-implementer` for code changes that follow a
fixed design, `ailang-tester` for E2E coverage, `ailang-debugger` fixed design, `ailang-tester` for E2E coverage, `ailang-debugger`
@@ -97,12 +97,14 @@ Two project-wide rules govern who touches git history and how:
brainstormer, planner, debugger, fieldtester, docwriter, brainstormer, planner, debugger, fieldtester, docwriter,
architect, bencher — runs `git commit`. Every agent writes its architect, bencher — runs `git commit`. Every agent writes its
output (spec, plan, code, tests, fixtures, rustdoc edits, RED output (spec, plan, code, tests, fixtures, rustdoc edits, RED
tests, journal files, stats, updated baselines) into the working tests, stats, updated baselines; `BLOCKED.md` on PARTIAL/BLOCKED
tree as unstaged changes. I inspect the result with iter outcomes) into the working tree as unstaged changes. I
`git status` / `git diff`, decide commit shape (often one inspect the result with `git status` / `git diff`, decide commit
cohesive iter-level commit; sometimes a few logical commits when shape (often one cohesive iter-level commit; sometimes a few
the changes genuinely cover separate concerns), and commit. logical commits when the changes genuinely cover separate
Per-task or per-phase commits are not a goal in themselves. concerns), and commit. Per-task or per-phase commits are not a
goal in themselves. `BLOCKED.md` is never committed by
convention — Boss removes it on repair or discard.
- **main HEAD is sacrosanct.** Nobody (including me) runs - **main HEAD is sacrosanct.** Nobody (including me) runs
`git reset` or `git revert` on main. main moves forward only via `git reset` or `git revert` on main. main moves forward only via
my commits. The consequence is the working-tree-as-quarantine my commits. The consequence is the working-tree-as-quarantine
@@ -114,8 +116,7 @@ Two project-wide rules govern who touches git history and how:
These rules supersede earlier mechanics that involved per-iter These rules supersede earlier mechanics that involved per-iter
branches and per-task agent commits. See `skills/README.md` branches and per-task agent commits. See `skills/README.md`
"Conventions" for the same rules in skill-system form, and the "Conventions" for the same rules in skill-system form.
2026-05-11 journal for the failure mode that motivated the change.
### Authority over `skills/` and the agent roster ### Authority over `skills/` and the agent roster
@@ -145,8 +146,8 @@ not as immutable scripture.
use approach X or Y?") — that is orchestrator work. use approach X or Y?") — that is orchestrator work.
- When I have already loaded the relevant context for a different - When I have already loaded the relevant context for a different
reason and a sub-agent would have to redo the same reading. In reason and a sub-agent would have to redo the same reading. In
that case I do the small change inline and note in the per-iter that case I do the small change inline and note in the commit
journal why I bypassed the agent. body why I bypassed the agent.
### Design rationale ≠ implementation effort ### Design rationale ≠ implementation effort
@@ -167,8 +168,7 @@ equally, and even then it should be named as a tiebreaker, not as
the primary reason. The 18a "Type::Fn metadata vs. Type variant" the primary reason. The 18a "Type::Fn metadata vs. Type variant"
call is the canonical anti-example: the right reason was semantic call is the canonical anti-example: the right reason was semantic
locality (modes belong to fn-parameter positions, not to types in locality (modes belong to fn-parameter positions, not to types in
general), and I retroactively had to add it. JOURNAL entries from general), and I retroactively had to add it.
2026-05-08 record the lesson.
### Feature acceptance: LLM utility ### Feature acceptance: LLM utility
@@ -193,11 +193,12 @@ Work clusters into **milestones**, each subdivided into
→ fieldtest`), skipping rules, and bench-exit-code gating live in → fieldtest`), skipping rules, and bench-exit-code gating live in
`skills/README.md` and the per-skill `SKILL.md` files. `skills/README.md` and the per-skill `SKILL.md` files.
Vocabulary note: legacy JOURNAL entries (pre-2026-05-09) use Vocabulary note: legacy entries in `docs/journal-archive.md`
"iter" / "family"; new entries use "iteration" / "milestone". (pre-2026-05-09) use "iter" / "family"; current vocabulary is
Existing entries are not retroactively renamed. "iteration" / "milestone". Existing archive entries are not
retroactively renamed.
## Roles of the `design/` ledger, `docs/journals/`, `docs/journal-archive.md`, `docs/roadmap.md`, `docs/specs/`, `docs/plans/` ## Roles of the `design/` ledger, `git log`, `docs/journal-archive.md`, `docs/roadmap.md`, `docs/specs/`, `docs/plans/`
- **The `design/` ledger** is the canonical specification. It - **The `design/` ledger** is the canonical specification. It
describes what AILang *is*: schema, semantics, invariants, runtime describes what AILang *is*: schema, semantics, invariants, runtime
@@ -209,18 +210,17 @@ Existing entries are not retroactively renamed.
feature requires changes to a contract, those changes are part of feature requires changes to a contract, those changes are part of
the same iteration. The `design/` ledger is also the artefact the same iteration. The `design/` ledger is also the artefact
`ailang-architect` checks the code against during drift review. `ailang-architect` checks the code against during drift review.
The current-state-mirror discipline is unchanged, just re-homed: A contract describes only the actual present state; forward intent
a contract describes only the actual present state; forward intent goes to `docs/roadmap.md`, history and rationale to `git log`
goes to `docs/roadmap.md`, history and rationale to (see `design/contracts/honesty-rule.md`).
`docs/journals/` (see `design/contracts/honesty-rule.md`).
- **`docs/journals/<YYYY-MM-DD>-iter-<id>.md`** is the decisions - **`git log`** is the project history. Iter and audit commit
log, one file per iter. Each file records *why* the iter moved bodies carry the *why* — alternatives considered and rejected,
the way it did — alternatives considered and rejected, lessons, verification steps, ratify statements, lessons. The Boss writes
rationale that does not belong in the `design/` ledger. Append-only these bodies at commit time; they are the durable record. Read
per file; new files are appended via `docs/journals/INDEX.md`. recent state with `git log -5 --format=full`; chronological scan
`docs/journals/INDEX.md` is the chronological pointer list, with `git log --oneline -30`; per-milestone scope with
orchestrator-maintained, one line per iter. `git log <prev-milestone-close>..HEAD --format=full`.
- **`docs/journal-archive.md`** is the archived monolithic - **`docs/journal-archive.md`** is the archived monolithic
decisions log for everything pre-2026-05-11. Content-frozen. decisions log for everything pre-2026-05-11. Content-frozen.
@@ -231,8 +231,8 @@ Existing entries are not retroactively renamed.
orchestrator owns this file and is responsible for keeping it orchestrator owns this file and is responsible for keeping it
current: adding new entries, reprioritising, removing items current: adding new entries, reprioritising, removing items
that are done or dropped. Entries are checkbox lines; finished that are done or dropped. Entries are checkbox lines; finished
items get checked off, then removed (with a one-line mirror in items get checked off, then removed once they stop being
the per-iter journal) once they stop being interesting context. interesting context.
- **`docs/specs/<milestone>.md`** (since 2026-05-09): per-milestone - **`docs/specs/<milestone>.md`** (since 2026-05-09): per-milestone
design spec produced by `skills/brainstorm`. Hard-gate before any design spec produced by `skills/brainstorm`. Hard-gate before any
@@ -243,5 +243,6 @@ Existing entries are not retroactively renamed.
by `skills/implement`. by `skills/implement`.
Together these answer three questions: "what is the language right Together these answer three questions: "what is the language right
now?" (the `design/` ledger), "how did we get here?" (per-iter now?" (the `design/` ledger), "how did we get here?" (`git log`,
journals, specs, plans), and "what's next?" (roadmap). plus `docs/journal-archive.md` for pre-2026-05-11 context), and
"what's next?" (roadmap).
+3 -5
View File
@@ -22,13 +22,12 @@
//! kept linking the stale pre-`7bfa11e` non-atomic //! kept linking the stale pre-`7bfa11e` non-atomic
//! `g_rc_alloc_count++` whose race produced the jittering //! `g_rc_alloc_count++` whose race produced the jittering
//! `Σallocs` undercount (`Σfrees` stable-exact). `build.rs` now //! `Σallocs` undercount (`Σfrees` stable-exact). `build.rs` now
//! tracks `runtime/` (this iter, `bugfix-swarm-rc-alloc-undercount`); //! tracks `runtime/` (a bugfix iter, `bugfix-swarm-rc-alloc-undercount`);
//! the fresh atomic archive relinks and the leak Σ balances //! the fresh atomic archive relinks and the leak Σ balances
//! deterministically (`Σallocs == Σfrees == 12000003`, every run). //! deterministically (`Σallocs == Σfrees == 12000003`, every run).
//! This test is the integration-level acceptance of both `7bfa11e` //! This test is the integration-level acceptance of both `7bfa11e`
//! and the build-dependency fix. Body preserved verbatim — it was //! and the build-dependency fix. Body preserved verbatim — it was
//! quarantined, never weakened. See //! quarantined, never weakened.
//! docs/journals/2026-05-19-iter-bugfix-swarm-rc-alloc-undercount.md.
use std::process::Command; use std::process::Command;
use std::sync::Arc; use std::sync::Arc;
@@ -136,8 +135,7 @@ fn symbol_fan_swarm_bit_exact() {
/// (`Σallocs == Σfrees == 12000003`, every run). This test is the /// (`Σallocs == Σfrees == 12000003`, every run). This test is the
/// integration-level acceptance of both `7bfa11e` and the /// integration-level acceptance of both `7bfa11e` and the
/// build-dependency fix. Body unchanged — it was quarantined, never /// build-dependency fix. Body unchanged — it was quarantined, never
/// weakened. See /// weakened.
/// docs/journals/2026-05-19-iter-bugfix-swarm-rc-alloc-undercount.md.
#[test] #[test]
fn symbol_fan_swarm_leak_free() { fn symbol_fan_swarm_leak_free() {
let Some((_stdout, stderr)) = run_swarm_or_skip() else { return }; let Some((_stdout, stderr)) = run_swarm_or_skip() else { return };
@@ -1,9 +1,8 @@
//! loop-recur iter 2: pin tests that the loop/recur typecheck //! Pin tests that the loop/recur typecheck fixtures produce the
//! fixtures produce the expected diagnostic codes (or zero //! expected diagnostic codes (or zero diagnostics for the positive
//! diagnostics for the positive sum_to-class case). Mirrors //! `sum_to`-class case). Mirrors `mut_typecheck_pin.rs`; negative
//! `mut_typecheck_pin.rs`; negative fixtures live as `.ail.json` //! fixtures live as `.ail.json` so the diagnostic code is the
//! so the diagnostic code is the load-bearing assertion, not the //! load-bearing assertion, not the surface form.
//! surface form.
use ailang_check::check_workspace; use ailang_check::check_workspace;
use ailang_surface::load_workspace; use ailang_surface::load_workspace;
@@ -29,10 +28,10 @@ fn check_fixture(fixture_name: &str) -> Vec<String> {
#[test] #[test]
fn loop_sum_to_typechecks_clean() { fn loop_sum_to_typechecks_clean() {
// examples/loop_sum_to.ail shipped in iter-1 as the round-trip // `examples/loop_sum_to.ail` doubles as the round-trip fixture and
// fixture; in iter-2 it must ALSO typecheck clean (it returned // the positive typecheck pin: it must typecheck without any
// the synth Internal stub in iter-1). One fixture, two // diagnostic. One fixture, two properties — no near-duplicate
// properties — no near-duplicate corpus file. // corpus file.
let codes = check_fixture("loop_sum_to.ail"); let codes = check_fixture("loop_sum_to.ail");
assert!(codes.is_empty(), "expected zero diagnostics, got {codes:?}"); assert!(codes.is_empty(), "expected zero diagnostics, got {codes:?}");
} }
+1 -1
View File
@@ -344,7 +344,7 @@ impl<'a> Emitter<'a> {
// cascade through the per-type drop fn; closure-typed // cascade through the per-type drop fn; closure-typed
// captures fall back to plain `ailang_rc_dec` because we // captures fall back to plain `ailang_rc_dec` because we
// don't keep a per-pair drop pointer alongside the env // don't keep a per-pair drop pointer alongside the env
// cell (yet). Iter 18d/18e revisit this. // cell.
// //
// - `drop_<thunk>_pair(p)` — load the env from offset 8, // - `drop_<thunk>_pair(p)` — load the env from offset 8,
// call `drop_<thunk>_env(env)`, then dec the pair box. // call `drop_<thunk>_env(env)`, then dec the pair box.
+10 -9
View File
@@ -278,7 +278,7 @@ Parenthesised forms:
``` ```
(lit-unit) ; the unit value () (lit-unit) ; the unit value ()
(app FN ARG+) ; function application (≥1 arg) (app FN ARG+) ; function application (≥1 arg)
(tail-app FN ARG+) ; tail-position application (Decision 8) (tail-app FN ARG+) ; tail-position application
(do OP-NAME ARG*) ; effect operation (do OP-NAME ARG*) ; effect operation
(tail-do OP-NAME ARG*) ; tail-position effect (tail-do OP-NAME ARG*) ; tail-position effect
(let NAME VALUE-TERM BODY-TERM) ; binding (let NAME VALUE-TERM BODY-TERM) ; binding
@@ -290,10 +290,10 @@ Parenthesised forms:
(lam (params (typed NAME TYPE)*) (lam (params (typed NAME TYPE)*)
(ret RETURN-TYPE) (ret RETURN-TYPE)
(effects EFFECT-NAME*)? (effects EFFECT-NAME*)?
(body TERM)) ; anonymous function (Iter 8b) (body TERM)) ; anonymous function
(seq EFFECTFUL-TERM RESULT-TERM) ; sequence; lhs evaluated for effect (seq EFFECTFUL-TERM RESULT-TERM) ; sequence; lhs evaluated for effect
(clone TERM) ; explicit RC clone (Iter 18c.1) (clone TERM) ; explicit RC clone
(reuse-as SOURCE-TERM BODY-TERM) ; explicit reuse hint (Iter 18d.1) (reuse-as SOURCE-TERM BODY-TERM) ; explicit reuse hint
(loop (NAME TYPE INIT)* BODY-TERM+) ; strict iteration block (loop-recur) (loop (NAME TYPE INIT)* BODY-TERM+) ; strict iteration block (loop-recur)
(recur ARG*) ; re-enter enclosing loop (loop-recur) (recur ARG*) ; re-enter enclosing loop (loop-recur)
``` ```
@@ -302,11 +302,12 @@ Notes:
- `app` and `do` REQUIRE the right tag for the right thing. - `app` and `do` REQUIRE the right tag for the right thing.
Constructors are NEVER called with `app`; always use `term-ctor`. Constructors are NEVER called with `app`; always use `term-ctor`.
- `tail-app` / `tail-do` mark the call as occurring in tail position - `tail-app` / `tail-do` mark the call as occurring in tail position;
per Decision 8. Codegen lowers them to `musttail call`. Use the the tag is explicit rather than inferred. Codegen lowers them to
tail variant whenever a recursive call is the final action of an `musttail call`. Use the tail variant whenever a recursive call is
arm — it converts unbounded recursion into iteration. Non-tail the final action of an arm — it converts unbounded recursion into
variants are otherwise indistinguishable in semantics. iteration. Non-tail variants are otherwise indistinguishable in
semantics.
- `seq` is `(seq A B)` — A is evaluated for its effects and result - `seq` is `(seq A B)` — A is evaluated for its effects and result
discarded; B is the value of the whole expression. For pure A, discarded; B is the value of the whole expression. For pure A,
prefer `(let _ A B)` or just drop A. prefer `(let _ A B)` or just drop A.
+1 -1
View File
@@ -570,7 +570,7 @@ fn build_registry(
// (built workspace-flat in `ailang-check`) and runs the type-driven // (built workspace-flat in `ailang-check`) and runs the type-driven
// dispatch rule, with `AmbiguousMethodResolution` / // dispatch rule, with `AmbiguousMethodResolution` /
// `class-method-shadowed-by-fn` as the per-call-site outcomes. // `class-method-shadowed-by-fn` as the per-call-site outcomes.
// See `docs/journals/2026-05-13-iter-mq.3.md` for the rationale. // See the type-driven-dispatch decision-record for the rationale.
// Pass 2: register each instance, with coherence / uniqueness / // Pass 2: register each instance, with coherence / uniqueness /
// method-completeness checks. // method-completeness checks.
+3 -3
View File
@@ -76,13 +76,13 @@ fn design_md_has_no_wunschdenken() {
fn design_md_has_no_doc_archaeology() { fn design_md_has_no_doc_archaeology() {
let d = norm(&design_corpus()); let d = norm(&design_corpus());
assert!(!d.contains("An earlier draft of this Decision said"), assert!(!d.contains("An earlier draft of this Decision said"),
"design/: doc-archaeology ('an earlier draft said … a follow-up replaced it') lives in docs/journals/"); "design/: doc-archaeology ('an earlier draft said … a follow-up replaced it') lives in git log");
assert!(!d.contains("previously all diagnostics were `Error`"), assert!(!d.contains("previously all diagnostics were `Error`"),
"design/: 'previously all diagnostics were Error' is project history → docs/journals/"); "design/: 'previously all diagnostics were Error' is project history → git log");
assert!(!d.contains("What did change in 2026-05-13 (this milestone) is"), assert!(!d.contains("What did change in 2026-05-13 (this milestone) is"),
"design/: 'what did change in <date> (this milestone)' is post-mortem narrative"); "design/: 'what did change in <date> (this milestone)' is post-mortem narrative");
assert!(!d.contains("primitives were retired 2026-05-14 in the per-type-print-op retirement"), assert!(!d.contains("primitives were retired 2026-05-14 in the per-type-print-op retirement"),
"design/: 'X were retired <date> in iter Y' is history → docs/journals/"); "design/: 'X were retired <date> in iter Y' is history → git log");
assert!(!d.contains("were retired in the per-type-print-op retirement (2026-05-14)"), assert!(!d.contains("were retired in the per-type-print-op retirement (2026-05-14)"),
"design/: the second per-type-print-op retirement-narrative sentence is history"); "design/: the second per-type-print-op retirement-narrative sentence is history");
assert!(!d.contains("originally listed here as the eighth fixture, was retired"), assert!(!d.contains("originally listed here as the eighth fixture, was retired"),
+6 -6
View File
@@ -56,11 +56,11 @@ evolving in lockstep with the language:
sole addressable spine for canonical state), `design/contracts/` sole addressable spine for canonical state), `design/contracts/`
(test-linked invariants), `design/models/` (onboarding (test-linked invariants), `design/models/` (onboarding
whitepapers). whitepapers).
- **Docs** (`docs/`): `docs/journals/` (per-iter decisions log; see - **Docs** (`docs/`): `docs/journal-archive.md` (archived monolith
`INDEX.md`), `docs/journal-archive.md` (archived monolith for for pre-2026-05-11 history, content-frozen), `roadmap.md` (forward
pre-2026-05-11 history), `roadmap.md` (forward queue), `specs/` queue), `specs/` (per-milestone design specs), `plans/` (per-
(per-milestone design specs), `plans/` (per-iteration iteration implementation plans). Current iter / audit history
implementation plans). lives in `git log`.
- **Tests**: unit tests per crate plus E2E in `crates/ail/tests/e2e.rs`. Every - **Tests**: unit tests per crate plus E2E in `crates/ail/tests/e2e.rs`. Every
new compiler path needs a test, otherwise the feature does not count as done. new compiler path needs a test, otherwise the feature does not count as done.
@@ -68,7 +68,7 @@ evolving in lockstep with the language:
### Project language: English ### Project language: English
All in-tree content is written in English: source code (identifiers, All in-tree content is written in English: source code (identifiers,
comments, string literals, CLI help), design documents, the journal, agent comments, string literals, CLI help), design documents, agent
prompts, READMEs, commit messages, examples, and `CLAUDE.md`. The live prompts, READMEs, commit messages, examples, and `CLAUDE.md`. The live
conversation between user and me stays German for ergonomic reasons; conversation between user and me stays German for ergonomic reasons;
everything that lands in git is English. This keeps diffs and tooling output everything that lands in git is English. This keeps diffs and tooling output
+4 -3
View File
@@ -9,9 +9,10 @@ Two things never belong in a contract or model file:
lives in `docs/roadmap.md`. lives in `docs/roadmap.md`.
- **History and rationale** (how a prior draft read, what changed - **History and rationale** (how a prior draft read, what changed
since, why one option was chosen, why another was rejected, what since, why one option was chosen, why another was rejected, what
was dropped in some iteration) — that lives in `docs/journals/`. was dropped in some iteration) — that lives in `git log` (iter
Decision-records are journal content, not ledger content; this is and audit commit bodies). Decision-records are commit-body
the honesty rule it holds itself to. content, not ledger content; this is the honesty rule it holds
itself to.
A cross-reference that does belong stays: it is a formal, A cross-reference that does belong stays: it is a formal,
file-relative Markdown link into the durable tier (`design/` or file-relative Markdown link into the durable tier (`design/` or
+4 -2
View File
@@ -133,7 +133,8 @@ is too.
**The GC bench (`bench/run.sh`) showed **The GC bench (`bench/run.sh`) showed
Boehm contributing a substantial fraction of runtime on allocation-heavy workloads Boehm contributing a substantial fraction of runtime on allocation-heavy workloads
that hold the heap fully live (bench notes in JOURNAL). The that hold the heap fully live (raw numbers in `bench/orchestrator-stats/`;
prior bench iter commit bodies record the runs). The
mainstream "RC + inference" position is extended with mandatory mainstream "RC + inference" position is extended with mandatory
LLM-author mode annotations (`borrow` / `own`), explicit `clone`, LLM-author mode annotations (`borrow` / `own`), explicit `clone`,
first-class `reuse-as`, and `drop-iterative` data attrs.** first-class `reuse-as`, and `drop-iterative` data attrs.**
@@ -165,7 +166,8 @@ env struct) and `bench_hof_pipeline` (poly-ADT + indirect
dispatch). The closure-chain fixture measures wider than the 1.3× dispatch). The closure-chain fixture measures wider than the 1.3×
linear/tree target: each step pays two allocs and two decs against linear/tree target: each step pays two allocs and two decs against
one bump-pointer bump, doubling the allocation tax on closure one bump-pointer bump, doubling the allocation tax on closure
construction (current ratio recorded in JOURNAL bench entries). construction (current ratio recorded in
`bench/orchestrator-stats/` and the bench iter commit bodies).
This is a representational cost of the closure-pair layout, This is a representational cost of the closure-pair layout,
not a defect in the RC implementation; a future slab/pool not a defect in the RC implementation; a future slab/pool
allocator for fixed-shape pair cells (a Boehm-retirement follow-up) allocator for fixed-shape pair cells (a Boehm-retirement follow-up)
+2 -2
View File
@@ -146,8 +146,8 @@ with the visible target, not in the call instruction. The
end-to-end gain shrinks toward zero on larger callee bodies and end-to-end gain shrinks toward zero on larger callee bodies and
cold call sites, but the architectural claim — "mono enables cold call sites, but the architectural claim — "mono enables
optimisations vdisp forbids" — holds across the spectrum optimisations vdisp forbids" — holds across the spectrum
(`bench/mono_dispatch.py` and the corresponding JOURNAL bench-notes (`bench/mono_dispatch.py` and `bench/orchestrator-stats/`
entry record the measured ratios). record the measured ratios).
The separator is `__` rather than `#` or `@` because `#` and `@` The separator is `__` rather than `#` or `@` because `#` and `@`
are invalid in LLVM IR global identifiers (the IR verifier rejects are invalid in LLVM IR global identifiers (the IR verifier rejects
+3 -4
View File
@@ -1,9 +1,8 @@
# JOURNAL # JOURNAL
> **Status:** archived 2026-05-11. New iter journals live under > **Status:** archived 2026-05-11. Content-frozen. This file is the
> `docs/journals/`. See `docs/journals/INDEX.md` for the > historical record for entries prior to that date. Current iter and
> chronological pointer list. This file remains the historical > audit history lives in `git log` (commit bodies).
> record for entries prior to that date.
Chronological notes for myself. Not every change; only decisions, obstacles, Chronological notes for myself. Not every change; only decisions, obstacles,
and observations that future iterations will need. and observations that future iterations will need.
+63 -94
View File
@@ -8,10 +8,9 @@ work progresses.
## Conventions ## Conventions
- One checkbox per entry. `- [ ]` is open; `- [~]` is in progress - One checkbox per entry. `- [ ]` is open; `- [~]` is in progress
(work has started — a plan exists, a branch is open, or commits are (work has started — a plan exists or commits are landing); `- [x]`
landing); `- [x]` is done. A finished entry may stay briefly for is done. A finished entry may stay briefly for context, then is
context, then is removed (with a one-line mirror in removed; the durable record stays in `git log`.
`docs/journals/`).
- Each entry is tagged by **kind** and lives under a **priority** - Each entry is tagged by **kind** and lives under a **priority**
bucket: bucket:
- **\[milestone\]** — big chunk that will get a `docs/specs/<milestone>.md`. - **\[milestone\]** — big chunk that will get a `docs/specs/<milestone>.md`.
@@ -22,11 +21,11 @@ work progresses.
- **\[idea\]** — not yet decision-ready, no commitment. - **\[idea\]** — not yet decision-ready, no commitment.
- Optional `depends on:` line names another entry that has to land - Optional `depends on:` line names another entry that has to land
first. first.
- Optional `context:` line points to the journal entry (per-iter - Optional `context:` line points to the rationale. For current
file under `docs/journals/` or, for pre-2026-05-11 entries, the work this is a spec file under `docs/specs/` or a commit hash
archived `docs/journal-archive.md`) where the rationale lives. (`git show <hash>`); for pre-2026-05-11 entries it points to the
The roadmap is intentionally terse; rationale stays in the archived `docs/journal-archive.md`. The roadmap is intentionally
journals. terse; rationale stays in those sources.
- Priority buckets: - Priority buckets:
- **P0** — in flight. Spec or plan already exists. - **P0** — in flight. Spec or plan already exists.
- **P1** — next up. Decision made; not yet started. - **P1** — next up. Decision made; not yet started.
@@ -54,11 +53,9 @@ work progresses.
programs, all worked first try without mutable locals — the programs, all worked first try without mutable locals — the
removal thesis empirically confirmed). Decoupled from removal thesis empirically confirmed). Decoupled from
Stateful-islands. Stays here briefly for context; remove once Stateful-islands. Stays here briefly for context; remove once
stale (full record in `docs/journals/INDEX.md`). stale (full record in `git log`).
- context: `docs/specs/2026-05-18-remove-mut-var-assign.md`; - context: `docs/specs/2026-05-18-remove-mut-var-assign.md`;
`docs/specs/2026-05-18-fieldtest-remove-mut-var-assign.md`; `docs/specs/2026-05-18-fieldtest-remove-mut-var-assign.md`
`docs/journals/2026-05-18-iter-remove-mut-var-assign.1.md`;
`docs/journals/2026-05-18-audit-remove-mut-var-assign.md`
- [x] **\[milestone\]** Prose `loop` binders — projection redesign — - [x] **\[milestone\]** Prose `loop` binders — projection redesign —
CLOSED 2026-05-18. Form-B prose now renders loop binders as a CLOSED 2026-05-18. Form-B prose now renders loop binders as a
@@ -75,8 +72,7 @@ work progresses.
P2 `*.bump_s` environmental staleness, latency-tail proven sampling P2 `*.bump_s` environmental staleness, latency-tail proven sampling
noise by re-run); no fieldtest (projection-only, no authoring- noise by re-run); no fieldtest (projection-only, no authoring-
surface change). Stays here briefly for context; remove once stale. surface change). Stays here briefly for context; remove once stale.
- context: `docs/specs/2026-05-18-prose-loop-binders.md`; - context: `docs/specs/2026-05-18-prose-loop-binders.md`; surfaced
`docs/journals/2026-05-18-audit-prose-loop-binders.md`; surfaced
from the loop/recur prose review (2026-05-18 chat). from the loop/recur prose review (2026-05-18 chat).
- [x] **\[milestone\]** Standalone `loop` / `recur` — CLOSED 2026-05-18. - [x] **\[milestone\]** Standalone `loop` / `recur` — CLOSED 2026-05-18.
@@ -91,7 +87,7 @@ work progresses.
no-termination exact). Two orthogonal non-blocking findings routed no-termination exact). Two orthogonal non-blocking findings routed
to P2 todos (niladic `(app f)` — re-confirms mut-local F3; module to P2 todos (niladic `(app f)` — re-confirms mut-local F3; module
`(doc)` diagnostic hint). Stays here briefly for context; remove `(doc)` diagnostic hint). Stays here briefly for context; remove
once stale (full record in `docs/journals/INDEX.md`). once stale (full record in `git log`).
- context: `docs/specs/2026-05-17-loop-recur.md`; - context: `docs/specs/2026-05-17-loop-recur.md`;
`docs/specs/2026-05-18-fieldtest-loop-recur.md`; principles entry `docs/specs/2026-05-18-fieldtest-loop-recur.md`; principles entry
`docs/specs/2026-05-17-llm-surface-discipline.md` §6.2. `docs/specs/2026-05-17-llm-surface-discipline.md` §6.2.
@@ -121,11 +117,9 @@ work progresses.
P3 below; bench causally exonerated — HEAD vs `5bb7211`/`de66eb7` P3 below; bench causally exonerated — HEAD vs `5bb7211`/`de66eb7`
bench binaries `cmp`-byte-identical, NO ratify); no fieldtest (zero bench binaries `cmp`-byte-identical, NO ratify); no fieldtest (zero
authoring-surface change). Stays here briefly for context; remove authoring-surface change). Stays here briefly for context; remove
once stale (full record in `docs/journals/INDEX.md`). once stale (full record in `git log`).
- context: `docs/specs/2026-05-18-docs-honesty-lint.md` - context: `docs/specs/2026-05-18-docs-honesty-lint.md`
(grounding-check PASS 10/10); (grounding-check PASS 10/10).
`docs/journals/2026-05-18-iter-docs-honesty-lint.1.md`;
`docs/journals/2026-05-18-audit-docs-honesty-lint.md`
## P1 — Next ## P1 — Next
@@ -158,11 +152,9 @@ work progresses.
precise+self-correcting; 3 working) — 3 non-blocking findings precise+self-correcting; 3 working) — 3 non-blocking findings
routed to the two follow-up items directly below. Stays here routed to the two follow-up items directly below. Stays here
briefly for context; remove once stale (full record in briefly for context; remove once stale (full record in
`docs/journals/INDEX.md`). `git log`).
- context: `docs/specs/2026-05-18-embedding-abi-m1.md`; - context: `docs/specs/2026-05-18-embedding-abi-m1.md`;
`docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md`; `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md`
`docs/journals/2026-05-18-iter-embedding-abi-m1.1.md`;
`docs/journals/2026-05-18-audit-embedding-abi-m1.md`
- [x] **\[todo\]** form_a.md scalar-parameter mode carve-out — docs- - [x] **\[todo\]** form_a.md scalar-parameter mode carve-out — docs-
honesty tidy (M1 fieldtest friction + spec_gap#1, shared root) — honesty tidy (M1 fieldtest friction + spec_gap#1, shared root) —
@@ -184,10 +176,9 @@ work progresses.
gate (the pin IS the regression coverage). plan gate (the pin IS the regression coverage). plan
`docs/plans/form-a-scalar-param-mode-carveout.md` (`4c266a6`) → iter `docs/plans/form-a-scalar-param-mode-carveout.md` (`4c266a6`) → iter
`7d7f04e`. Stays here briefly for context; remove once stale (full `7d7f04e`. Stays here briefly for context; remove once stale (full
record in `docs/journals/INDEX.md`). record in `git log`).
- context: `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md` - context: `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md`
findings [friction] + [spec_gap]#1; findings [friction] + [spec_gap]#1.
`docs/journals/2026-05-18-iter-form-a-scalar-param-mode-carveout.md`.
- [x] **\[feature\]** `ail emit-ir --emit=staticlib` — restore the - [x] **\[feature\]** `ail emit-ir --emit=staticlib` — restore the
Decision-5 IR-readability affordance for kernels (M1 fieldtest Decision-5 IR-readability affordance for kernels (M1 fieldtest
@@ -213,10 +204,9 @@ work progresses.
reuses the M1-audited codegen path, no invariant/surface change). reuses the M1-audited codegen path, no invariant/surface change).
plan `docs/plans/emit-ir-staticlib.md` (`03493c9`) → iter plan `docs/plans/emit-ir-staticlib.md` (`03493c9`) → iter
`bcfe554`. Stays here briefly for context; remove once stale (full `bcfe554`. Stays here briefly for context; remove once stale (full
record in `docs/journals/INDEX.md`). record in `git log`).
- context: `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md` - context: `docs/specs/2026-05-18-fieldtest-embedding-abi-m1.md`
finding [spec_gap]#2; finding [spec_gap]#2.
`docs/journals/2026-05-18-iter-emit-ir-staticlib.md`.
- [x] **\[milestone\]** Embedding ABI — M2: per-thread runtime - [x] **\[milestone\]** Embedding ABI — M2: per-thread runtime
context + concurrency safety — CLOSED 2026-05-18. A compiled context + concurrency safety — CLOSED 2026-05-18. A compiled
@@ -257,11 +247,8 @@ work progresses.
ratify) → tidy `a80d495` (the `## Embedding ABI` lockstep rename, ratify) → tidy `a80d495` (the `## Embedding ABI` lockstep rename,
drift resolved). No fieldtest (zero authoring-surface change). drift resolved). No fieldtest (zero authoring-surface change).
Stays here briefly for context; remove once stale (full record in Stays here briefly for context; remove once stale (full record in
`docs/journals/INDEX.md`). `git log`).
- context: `docs/specs/2026-05-18-embedding-abi-m2.md`; - context: `docs/specs/2026-05-18-embedding-abi-m2.md`.
`docs/journals/2026-05-18-iter-embedding-abi-m2.1.md`;
`docs/journals/2026-05-18-audit-embedding-abi-m2.md`;
`docs/journals/2026-05-18-iter-embedding-abi-m2.tidy.md`.
- [x] **\[milestone\]** Embedding ABI — M3: frozen value layout + - [x] **\[milestone\]** Embedding ABI — M3: frozen value layout +
single ADT/record crossing + RC ownership contract — CLOSED single ADT/record crossing + RC ownership contract — CLOSED
@@ -297,12 +284,9 @@ work progresses.
families, NO ratify) → tidy `63d7d60` (pin-safe; drift resolved). families, NO ratify) → tidy `63d7d60` (pin-safe; drift resolved).
No fieldtest (zero authoring-surface change). Stays here briefly No fieldtest (zero authoring-surface change). Stays here briefly
for context; remove once stale (full record in for context; remove once stale (full record in
`docs/journals/INDEX.md`). `git log`).
- depends on: Embedding ABI — M2. - depends on: Embedding ABI — M2.
- context: `docs/specs/2026-05-18-embedding-abi-m3.md`; - context: `docs/specs/2026-05-18-embedding-abi-m3.md`.
`docs/journals/2026-05-18-iter-embedding-abi-m3.1.md`;
`docs/journals/2026-05-18-audit-embedding-abi-m3.md`;
`docs/journals/2026-05-18-iter-embedding-abi-m3.tidy.md`.
- [x] **\[milestone\]** Embedding ABI — M5: `ail-embed` adapter + - [x] **\[milestone\]** Embedding ABI — M5: `ail-embed` adapter +
`data-server` wiring + thread-swarm backtest — **DONE 2026-05-19**, `data-server` wiring + thread-swarm backtest — **DONE 2026-05-19**,
@@ -337,13 +321,7 @@ work progresses.
Stays one cycle for context, then prune. Stays one cycle for context, then prune.
- depends on: Embedding ABI — M3 (shipped); Tick-coverage on M3 - depends on: Embedding ABI — M3 (shipped); Tick-coverage on M3
(shipped `170464f`). (shipped `170464f`).
- context: `docs/specs/2026-05-19-embedding-abi-m5.md`; iter - context: `docs/specs/2026-05-19-embedding-abi-m5.md`.
journals `2026-05-19-iter-embedding-abi-m5.{1,2,3,tidy}.md` +
`…-m5.2-resume-attempt.md` + bugfix
`…-rc-global-stats-race.md` / `…-swarm-rc-alloc-undercount.md`;
audit `docs/journals/2026-05-19-audit-embedding-abi-m5.md`; M4
retirement
`docs/journals/2026-05-18-brainstorm-embedding-abi-m4-retired.md`.
- [x] **\[milestone\]** Heap-`Str` ABI — runtime infrastructure for - [x] **\[milestone\]** Heap-`Str` ABI — runtime infrastructure for
malloc-backed, refcounted `Str` values alongside the existing malloc-backed, refcounted `Str` values alongside the existing
@@ -376,8 +354,7 @@ work progresses.
blocked the original spec retired in mq.3 (2026-05-13); spec blocked the original spec retired in mq.3 (2026-05-13); spec
`docs/specs/2026-05-13-24-show-print.md` re-derived 24.2 + 24.3 `docs/specs/2026-05-13-24-show-print.md` re-derived 24.2 + 24.3
against the post-mq architecture. against the post-mq architecture.
- context: spec `docs/specs/2026-05-13-24-show-print.md`; per-iter - context: spec `docs/specs/2026-05-13-24-show-print.md`.
journals 2026-05-12-iter-24.1, 2026-05-13-iter-24.2, 2026-05-13-iter-24.3.
## P2 — Medium-term ## P2 — Medium-term
@@ -412,7 +389,7 @@ work progresses.
discipline, not a third patch). No fieldtest (zero discipline, not a third patch). No fieldtest (zero
authoring-surface change — reasoned exclusion). Stays briefly authoring-surface change — reasoned exclusion). Stays briefly
for context; remove once stale (full record in for context; remove once stale (full record in
`docs/journals/INDEX.md`). Original decided-shape rationale `git log`). Original decided-shape rationale
retained below for context until pruned. retained below for context until pruned.
**Motivation.** The just-closed `docs-honesty-lint` milestone is **Motivation.** The just-closed `docs-honesty-lint` milestone is
@@ -499,12 +476,9 @@ work progresses.
rewrites enforced invariants and agent contracts. rewrites enforced invariants and agent contracts.
- context: spec `docs/specs/2026-05-19-design-md-rolesplit.md` - context: spec `docs/specs/2026-05-19-design-md-rolesplit.md`
(incl. the Boss-adjudicated relocation Appendix; grounding-check (incl. the Boss-adjudicated relocation Appendix; grounding-check
PASS ×2); audit `docs/journals/2026-05-19-audit-design-md-rolesplit.md`; PASS ×2); origin 2026-05-18 chat (DESIGN.md-management
iter journals `2026-05-19-iter-design-md-rolesplit.{1,tidy}.md`; dialogue — six-turn convergence). CLOSED — audited +
`docs/journals/2026-05-19-design-decision-records.md`; origin drift-resolved; hard gate enforces the honesty spirit.
2026-05-18 chat (DESIGN.md-management dialogue — six-turn
convergence). CLOSED — audited + drift-resolved; hard gate
enforces the honesty spirit.
- [x] **\[milestone\]** Formal cross-links in the `design/` ledger - [x] **\[milestone\]** Formal cross-links in the `design/` ledger
(browsable wiki) — CLOSED 2026-05-19. The positive completion (browsable wiki) — CLOSED 2026-05-19. The positive completion
@@ -534,13 +508,10 @@ work progresses.
(grounding-check PASS ×3 across two corpus-grounded amendments — (grounding-check PASS ×3 across two corpus-grounded amendments —
clause-6 + cross-ref definition; clause-5 fence-skip + closed clause-6 + cross-ref definition; clause-5 fence-skip + closed
convert-set enumeration); plan convert-set enumeration); plan
`docs/plans/design-ledger-formal-links.1.md`; iter journal `docs/plans/design-ledger-formal-links.1.md`; origin this
`docs/journals/2026-05-19-iter-design-ledger-formal-links.1.md`; session's six-turn design conversation following the split close.
audit `docs/journals/2026-05-19-audit-design-ledger-formal-links.md`; CLOSED — audit clean (zero drift, bench trio 0/0/0); no tidy,
origin this session's six-turn design conversation following the no fieldtest (zero authoring-surface change — reasoned exclusion).
split close. CLOSED — audit clean (zero drift, bench trio
0/0/0); no tidy, no fieldtest (zero authoring-surface change —
reasoned exclusion).
- [ ] **\[milestone\]** Flat array/slice primitive — performance - [ ] **\[milestone\]** Flat array/slice primitive — performance
follow-up to the Embedding ABI arc, *not* a capability gap. follow-up to the Embedding ABI arc, *not* a capability gap.
@@ -562,10 +533,9 @@ work progresses.
- depends on: Embedding ABI — M5 (shipped; measured ~206 ns/tick - depends on: Embedding ABI — M5 (shipped; measured ~206 ns/tick
— the justification input now exists). — the justification input now exists).
- context: 2026-05-18 chat (user deferred this to keep the ABI - context: 2026-05-18 chat (user deferred this to keep the ABI
arc clean); M5 audit arc clean); the friction-harvest number recorded in the M5
`docs/journals/2026-05-19-audit-embedding-abi-m5.md` (the audit commit; M4 retirement decision recorded in the M5 closing
friction-harvest number); M4 retirement commits.
`docs/journals/2026-05-18-brainstorm-embedding-abi-m4-retired.md`.
- [ ] **\[milestone\]** Iteration-totality story — structural + - [ ] **\[milestone\]** Iteration-totality story — structural +
Int-bounded total recursion with *enforced* non-negativity. Int-bounded total recursion with *enforced* non-negativity.
@@ -580,14 +550,14 @@ work progresses.
- depends on: a future `Nat`/refinement-types milestone (no spec - depends on: a future `Nat`/refinement-types milestone (no spec
yet). yet).
- context: `docs/specs/2026-05-16-iteration-discipline-revert.md` - context: `docs/specs/2026-05-16-iteration-discipline-revert.md`
(why the 2026-05 attempt was reverted) and (why the 2026-05 attempt was reverted); the branching-builder
`docs/journals/2026-05-15-iter-it.3.md` (the branching-builder counter-example that surfaced the gap landed in the it.3 iter
counter-example that surfaced the gap). commit.
- [x] **\[milestone\]** Retire `io/print_int` / `io/print_bool` / - [x] **\[milestone\]** Retire `io/print_int` / `io/print_bool` /
`io/print_float` effect-ops + migrate example corpus to `print`. `io/print_float` effect-ops + migrate example corpus to `print`.
Shipped 2026-05-14 as iter rpe.1. Shipped 2026-05-14 as iter rpe.1.
- context: per-iter journal `docs/journals/2026-05-14-iter-rpe.1.md`. - context: shipped in the rpe.1 iter commit.
- [x] **\[todo\]** Author `examples/prelude.ail` alongside - [x] **\[todo\]** Author `examples/prelude.ail` alongside
`examples/prelude.ail.json`. (Satisfied 2026-05-13 by iter `examples/prelude.ail.json`. (Satisfied 2026-05-13 by iter
@@ -648,13 +618,13 @@ work progresses.
`<` etc. resolved via the typeclass instead of the built-in `<` etc. resolved via the typeclass instead of the built-in
primitive comparators. No commitment; gated on bench re-baselining primitive comparators. No commitment; gated on bench re-baselining
to make sure the indirection doesn't tank latency. to make sure the indirection doesn't tank latency.
- context: JOURNAL 2026-05-09 - context: `docs/journal-archive.md` (2026-05-09 entry).
- depends on: Post-22 Prelude — Eq/Ord (shipped 23.5) - depends on: Post-22 Prelude — Eq/Ord (shipped 23.5)
- [x] **\[todo\]** `types` / `ctor_index` overlay shape question — - [x] **\[todo\]** `types` / `ctor_index` overlay shape question —
decide whether the env's two parallel ctor maps should collapse decide whether the env's two parallel ctor maps should collapse
into one overlay, or stay split. Surfaced during the into one overlay, or stay split. Surfaced during the
env-construction unify audit. env-construction unify audit.
- context: JOURNAL 2026-05-10 ("Audit close: env-construction unify"); closed by iter ctt.1 — DESIGN.md §"Env construction" anchors the split decision. - context: `docs/journal-archive.md` (2026-05-10 "Audit close: env-construction unify"); closed by iter ctt.1 — DESIGN.md §"Env construction" anchors the split decision.
- [x] **\[todo\]** CLI human-mode diagnostic surface for `WorkspaceLoadError`. - [x] **\[todo\]** CLI human-mode diagnostic surface for `WorkspaceLoadError`.
Shipped 2026-05-14 as iter cli-diag-human — a new `load_workspace_human` Shipped 2026-05-14 as iter cli-diag-human — a new `load_workspace_human`
helper in `crates/ail/src/main.rs` routes 9 non-JSON helper in `crates/ail/src/main.rs` routes 9 non-JSON
@@ -662,14 +632,14 @@ work progresses.
`workspace_error_to_diagnostic`, so the bracketed `[code]` prefix is `workspace_error_to_diagnostic`, so the bracketed `[code]` prefix is
preserved across `ail check`, `build`, `run`, `emit-ir`, `prose`, preserved across `ail check`, `build`, `run`, `emit-ir`, `prose`,
`describe`, `deps`, `diff`, `manifest`. `describe`, `deps`, `diff`, `manifest`.
- context: per-iter journal `docs/journals/2026-05-14-iter-cli-diag-human.md`. - context: shipped in the cli-diag-human iter commit.
- [x] **\[todo\]** Retire dead `KindMismatch` arm — `validate_classdefs`'s - [x] **\[todo\]** Retire dead `KindMismatch` arm — `validate_classdefs`'s
`walk_kind_mismatch` path is structurally unreachable through `walk_kind_mismatch` path is structurally unreachable through
well-formed schema post-ct.1 (the canonical-form validator catches well-formed schema post-ct.1 (the canonical-form validator catches
the malformed `Type::Con { name: param }` shape earlier). The the malformed `Type::Con { name: param }` shape earlier). The
enum variant + `walk_kind_mismatch` helper stay as dead-but-defensive enum variant + `walk_kind_mismatch` helper stay as dead-but-defensive
code; a future tidy can delete both. code; a future tidy can delete both.
- context: JOURNAL 2026-05-11 ("Iteration ct.1"); closed by iter ctt.3 — variant + helper + dispatch + Display arm all deleted; canonical-form-rejection test stays green asserting `BareCrossModuleTypeRef`. - context: `docs/journal-archive.md` (2026-05-11 "Iteration ct.1"); closed by iter ctt.3 — variant + helper + dispatch + Display arm all deleted; canonical-form-rejection test stays green asserting `BareCrossModuleTypeRef`.
- [x] **\[todo\]** Re-key `Registry.type_def_module` to handle - [x] **\[todo\]** Re-key `Registry.type_def_module` to handle
bare-name-collision-across-modules — `BTreeMap<String, String>` keyed bare-name-collision-across-modules — `BTreeMap<String, String>` keyed
by bare type name silently overwrites when two modules each define by bare type name silently overwrites when two modules each define
@@ -677,11 +647,11 @@ work progresses.
and `N.Foo` to whichever insert won. Acceptable for current corpus and `N.Foo` to whichever insert won. Acceptable for current corpus
(distinct bare type names across modules), but the proper fix is to (distinct bare type names across modules), but the proper fix is to
key by `(owning_module, bare_name) → defining_module`. key by `(owning_module, bare_name) → defining_module`.
- context: JOURNAL 2026-05-11 ("Iteration ct.1") — flagged by ct.1.5a quality reviewer. - context: `docs/journal-archive.md` (2026-05-11 "Iteration ct.1") — flagged by ct.1.5a quality reviewer.
- [ ] **\[feature\]** 22c — typeclass corpus expansion. User-defined - [ ] **\[feature\]** 22c — typeclass corpus expansion. User-defined
classes beyond the prelude four; multi-parameter classes; superclass classes beyond the prelude four; multi-parameter classes; superclass
chains; richer instance bodies. Deferred from milestone 22. chains; richer instance bodies. Deferred from milestone 22.
- context: JOURNAL 2026-05-09 - context: `docs/journal-archive.md` (2026-05-09 entry).
- [x] **\[milestone\]** Module-qualified class names + type-driven - [x] **\[milestone\]** Module-qualified class names + type-driven
method dispatch — retired the `MethodNameCollision` workaround; method dispatch — retired the `MethodNameCollision` workaround;
shipped 2026-05-13 as iters mq.1 (canonical-form extension for shipped 2026-05-13 as iters mq.1 (canonical-form extension for
@@ -701,7 +671,7 @@ work progresses.
- [ ] **\[todo\]** Boehm full retirement — remove the transitional - [ ] **\[todo\]** Boehm full retirement — remove the transitional
Boehm GC path now that RC + uniqueness is the canonical memory Boehm GC path now that RC + uniqueness is the canonical memory
story. story.
- context: JOURNAL pre-22, "Boehm transitional" - context: `docs/journal-archive.md` (pre-22, "Boehm transitional").
- [ ] **\[feature\]** Closure-pair slab / pool — codegen tweak to - [ ] **\[feature\]** Closure-pair slab / pool — codegen tweak to
pool the env+code closure pairs instead of one-shot heap allocs. pool the env+code closure pairs instead of one-shot heap allocs.
Bench-gated. Bench-gated.
@@ -720,8 +690,7 @@ work progresses.
real flat-closed-set / IO-only / `IndexMap`+codegen-`match` real flat-closed-set / IO-only / `IndexMap`+codegen-`match`
mechanism, satellite lockstep done, guarded by a 4-test mechanism, satellite lockstep done, guarded by a 4-test
doc-presence pin. No language/checker/codegen change. doc-presence pin. No language/checker/codegen change.
- context: per-iter journal - context: shipped in the effect-doc-honesty iter commit.
`docs/journals/2026-05-16-iter-effect-doc-honesty.md`.
- [ ] **\[todo\]** `io/print_float` always-emit-`.0` — surface - [ ] **\[todo\]** `io/print_float` always-emit-`.0` — surface
printer always emits `.` or `e/E` so re-lex routes to Float; printer always emits `.` or `e/E` so re-lex routes to Float;
the runtime printer (`printf("%g\n", v)`) doesn't, so `2.0` the runtime printer (`printf("%g\n", v)`) doesn't, so `2.0`
@@ -736,7 +705,7 @@ work progresses.
`ailang-core`: private-item links from public doc, unresolved `ailang-core`: private-item links from public doc, unresolved
intra-crate links). All predate the design-md-consolidation intra-crate links). All predate the design-md-consolidation
milestone; treat as a one-off sweep. milestone; treat as a one-off sweep.
- context: JOURNAL 2026-05-10 ("Audit close: design-md-consolidation"). - context: `docs/journal-archive.md` (2026-05-10 "Audit close: design-md-consolidation").
- [ ] **\[todo\]** `ailang-plan-recon` site-undercount countermeasure - [ ] **\[todo\]** `ailang-plan-recon` site-undercount countermeasure
(P2, **escalated** — now a structural recon-contract defect, no (P2, **escalated** — now a structural recon-contract defect, no
longer a single-milestone curiosity) — the recon agent hand-lists longer a single-milestone curiosity) — the recon agent hand-lists
@@ -775,7 +744,7 @@ work progresses.
Constrain the test to scan only §"Data model" + ParamMode Constrain the test to scan only §"Data model" + ParamMode
block, or extract JSON-schema blocks into a machine-readable block, or extract JSON-schema blocks into a machine-readable
file the test consumes. file the test consumes.
- context: JOURNAL 2026-05-10 ("Audit close"). - context: `docs/journal-archive.md` (2026-05-10 "Audit close").
- [ ] **\[todo\]** Split `BadCrossModuleTypeRef` into two diagnostics — - [ ] **\[todo\]** Split `BadCrossModuleTypeRef` into two diagnostics —
the current single shape collapses unknown-owner and the current single shape collapses unknown-owner and
known-owner / unknown-type-in-owner into one message. The two known-owner / unknown-type-in-owner into one message. The two
@@ -856,8 +825,8 @@ work progresses.
- context: remove-mut-var-assign close audit, bencher localisation - context: remove-mut-var-assign close audit, bencher localisation
(2026-05-18) — byte-identical-binary causal exoneration + the (2026-05-18) — byte-identical-binary causal exoneration + the
3-milestone false-positive history. 3-milestone false-positive history.
- context: `docs/journals/2026-05-16-audit-iteration-discipline-revert.md` - context: the bencher localisation evidence in the
(the bencher localisation evidence). iteration-discipline-revert audit commit.
- [x] **\[todo\]** `check_in_workspace` per-module overlay narrowing — - [x] **\[todo\]** `check_in_workspace` per-module overlay narrowing —
`crates/ailang-check/src/lib.rs:1234` still clears+rebuilds `crates/ailang-check/src/lib.rs:1234` still clears+rebuilds
`env.ctor_index` per-module; ct.3.2 narrowed the analogous mono `env.ctor_index` per-module; ct.3.2 narrowed the analogous mono
@@ -866,8 +835,8 @@ work progresses.
time, not the runtime ctor lookup (which is type-driven post-ct.2.2). time, not the runtime ctor lookup (which is type-driven post-ct.2.2).
Narrowing is mechanical but needs a careful read to confirm no Narrowing is mechanical but needs a careful read to confirm no
other consumer survives. other consumer survives.
- context: JOURNAL 2026-05-11 ("Iteration ct.4") — milestone close - context: `docs/journal-archive.md` (2026-05-11 "Iteration ct.4") —
follow-up; closed by iter ctt.1 — recon confirmed the rebuild is the load-bearing consumer of in-band DuplicateCtor (pinned by `crates/ailang-check/tests/duplicate_ctor_pin.rs`); the asymmetry with the mono side is intentional. milestone close follow-up; closed by iter ctt.1 — recon confirmed the rebuild is the load-bearing consumer of in-band DuplicateCtor (pinned by `crates/ailang-check/tests/duplicate_ctor_pin.rs`); the asymmetry with the mono side is intentional.
- [x] **\[feature\]** `str_concat : (borrow Str, borrow Str) -> Str` — - [x] **\[feature\]** `str_concat : (borrow Str, borrow Str) -> Str` —
heap-Str concatenation primitive. Shipped 2026-05-13 as iter heap-Str concatenation primitive. Shipped 2026-05-13 as iter
str-concat (closes fieldtest-form-a friction #4). Symmetric to the str-concat (closes fieldtest-form-a friction #4). Symmetric to the
@@ -876,7 +845,7 @@ work progresses.
registration, `ailang-codegen` extern + `lower_app` arm, plus a registration, `ailang-codegen` extern + `lower_app` arm, plus a
fresh `examples/show_user_adt_with_label.ail` corpus fixture fresh `examples/show_user_adt_with_label.ail` corpus fixture
exercising the LLM-natural Show-body shape. exercising the LLM-natural Show-body shape.
- context: per-iter journal 2026-05-13-iter-str-concat.md. - context: shipped in the str-concat iter commit.
- [~] **\[milestone\]** Stateful islands — bounded mutation for - [~] **\[milestone\]** Stateful islands — bounded mutation for
streaming workloads (`Stateful a b` + `!Mut` effect + `mut` streaming workloads (`Stateful a b` + `!Mut` effect + `mut`
@@ -1035,7 +1004,7 @@ work progresses.
qualified `Type::Con` through pattern lowering would type-anchor qualified `Type::Con` through pattern lowering would type-anchor
it symmetric to the ct.2.2 typecheck-side fix. Not load-bearing it symmetric to the ct.2.2 typecheck-side fix. Not load-bearing
(uniqueness is enforced at typecheck), but cleaner. (uniqueness is enforced at typecheck), but cleaner.
- context: JOURNAL 2026-05-11 ("Iteration ct.3" + ct.4 close). - context: `docs/journal-archive.md` (2026-05-11 "Iteration ct.3" + ct.4 close).
- [ ] **\[todo\]** `compare_primitives_smoke` IR-shape assertion — - [ ] **\[todo\]** `compare_primitives_smoke` IR-shape assertion —
observe `compare__Int` / `compare__Bool` / `compare__Str` symbols observe `compare__Int` / `compare__Bool` / `compare__Str` symbols
in the emitted IR. Blocked on `emit-ir` CLI not running mono; in the emitted IR. Blocked on `emit-ir` CLI not running mono;
@@ -1044,8 +1013,8 @@ work progresses.
build`. The E2E stdout assertion already covers correctness; the build`. The E2E stdout assertion already covers correctness; the
IR-shape test would catch refactor regressions that rename IR-shape test would catch refactor regressions that rename
mono symbols. mono symbols.
- context: JOURNAL 2026-05-11 ("Iteration ct.4") — dropped from - context: `docs/journal-archive.md` (2026-05-11 "Iteration ct.4") —
ct.4.4 when the BLOCKED condition surfaced. dropped from ct.4.4 when the BLOCKED condition surfaced.
- [ ] **\[idea\]** Latency methodology rework — switch from per-run - [ ] **\[idea\]** Latency methodology rework — switch from per-run
timing to a histogram-based approach so tail-latency regressions timing to a histogram-based approach so tail-latency regressions
@@ -1054,13 +1023,13 @@ work progresses.
sites (class × 3, class method × 2, instance × 3, instance method sites (class × 3, class method × 2, instance × 3, instance method
× 1). No regression pin today; only worth it if a 22b.4a-era × 1). No regression pin today; only worth it if a 22b.4a-era
diagnostic needs to change. diagnostic needs to change.
- context: JOURNAL 2026-05-10 ("Iteration 22-tidy.7") - context: `docs/journal-archive.md` (2026-05-10 "Iteration 22-tidy.7").
- [ ] **\[idea\]** `write_type` `Type::Forall` arm in - [ ] **\[idea\]** `write_type` `Type::Forall` arm in
`crates/ailang-prose/src/lib.rs` silently drops constraints in `crates/ailang-prose/src/lib.rs` silently drops constraints in
inline-type rendering. Dormant — surface forms today only carry inline-type rendering. Dormant — surface forms today only carry
forall at fn-signature top level. Fix only if a future feature forall at fn-signature top level. Fix only if a future feature
carries forall + constraints inline. carries forall + constraints inline.
- context: JOURNAL 2026-05-10 ("Iteration 22-tidy.6") - context: `docs/journal-archive.md` (2026-05-10 "Iteration 22-tidy.6").
- [ ] **\[idea\]** Richer integration paths between RC and - [ ] **\[idea\]** Richer integration paths between RC and
uniqueness — deferred from the 21' arc; revisit once the uniqueness — deferred from the 21' arc; revisit once the
uniqueness inference covers more program shapes. uniqueness inference covers more program shapes.
@@ -1084,5 +1053,5 @@ work progresses.
negative-lookbehind / line-range exclusion so the rule's own example negative-lookbehind / line-range exclusion so the rule's own example
list is not a hit. P3 — may be cut; the architect adjudicates the list is not a hit. P3 — may be cut; the architect adjudicates the
single known self-match trivially today. single known self-match trivially today.
- context: `docs/journals/2026-05-18-audit-docs-honesty-lint.md` - context: docs-honesty-lint audit commit (architect `[medium]`
(architect `[medium]` advisory wart, carry-on) advisory wart, carry-on).
+20 -16
View File
@@ -8,7 +8,8 @@ established practice without explicitly violating a named rule.
The system was bootstrapped on 2026-05-09. See The system was bootstrapped on 2026-05-09. See
`docs/specs/2026-05-09-skill-system.md` for the design and `docs/specs/2026-05-09-skill-system.md` for the design and
`docs/journal-archive.md` ("Skill system live") for the rationale. `docs/journal-archive.md` ("Skill system live") for the rationale
both content-frozen and reachable only as historical context.
## The eight skills ## The eight skills
@@ -16,7 +17,7 @@ The system was bootstrapped on 2026-05-09. See
|-------|---------|--------|------------| |-------|---------|--------|------------|
| [`brainstorm`](brainstorm/SKILL.md) | New milestone starting | `docs/specs/<milestone>.md` | Hard-gate before plan | | [`brainstorm`](brainstorm/SKILL.md) | New milestone starting | `docs/specs/<milestone>.md` | Hard-gate before plan |
| [`planner`](planner/SKILL.md) | New iteration within an open milestone | `docs/plans/<iteration>.md` | Hard-gate before implement | | [`planner`](planner/SKILL.md) | New iteration within an open milestone | `docs/plans/<iteration>.md` | Hard-gate before implement |
| [`implement`](implement/SKILL.md) | Plan exists | Code + tests + per-iter journal entry, all uncommitted in the working tree | Standard iteration path | | [`implement`](implement/SKILL.md) | Plan exists | Code + tests (and `BLOCKED.md` on PARTIAL/BLOCKED), all uncommitted in the working tree | Standard iteration path |
| [`audit`](audit/SKILL.md) | Milestone closing OR baseline drift suspected | Drift report + bench-regression report | **Mandatory** at milestone close | | [`audit`](audit/SKILL.md) | Milestone closing OR baseline drift suspected | Drift report + bench-regression report | **Mandatory** at milestone close |
| [`docwriter`](docwriter/SKILL.md) | API surface stabilized; rustdoc lag suspected | rustdoc updates in `///` and `//!`, uncommitted in the working tree | No — Boss-dispatched only | | [`docwriter`](docwriter/SKILL.md) | API surface stabilized; rustdoc lag suspected | rustdoc updates in `///` and `//!`, uncommitted in the working tree | No — Boss-dispatched only |
| [`fieldtest`](fieldtest/SKILL.md) | Boss-dispatched post-audit field test on a milestone that touched user-visible surface | 2-4 `.ail` example fixtures + `docs/specs/<date>-fieldtest-<milestone>.md`, all uncommitted in the working tree | No — Boss-dispatched only | | [`fieldtest`](fieldtest/SKILL.md) | Boss-dispatched post-audit field test on a milestone that touched user-visible surface | 2-4 `.ail` example fixtures + `docs/specs/<date>-fieldtest-<milestone>.md`, all uncommitted in the working tree | No — Boss-dispatched only |
@@ -40,7 +41,7 @@ The system was bootstrapped on 2026-05-09. See
| |
v v
audit --(drift)--> plan + implement (tidy iteration) audit --(drift)--> plan + implement (tidy iteration)
--(ratify)-> JOURNAL + --update-baseline --(ratify)-> --update-baseline + ratify paragraph in audit commit body
--(clean)-+ --(clean)-+
| |
[Boss: iter complete? if surface-touch:] [Boss: iter complete? if surface-touch:]
@@ -97,7 +98,8 @@ Every agent file follows the same superpowers-derived template:
- **What this role is for:** one short paragraph naming the failure mode - **What this role is for:** one short paragraph naming the failure mode
the agent exists to prevent. the agent exists to prevent.
- **Standing reading list:** the always-binding documents (CLAUDE.md, - **Standing reading list:** the always-binding documents (CLAUDE.md,
design/INDEX.md, latest per-iter journals, plus role-specific anchors). design/INDEX.md, `git log --format=full` for recent state, plus
role-specific anchors).
- **Carrier contract:** what the controller hands the agent (`task_text`, - **Carrier contract:** what the controller hands the agent (`task_text`,
`diff`, `hypothesis`, etc.). Agents do NOT open `docs/plans/` or `diff`, `hypothesis`, etc.). Agents do NOT open `docs/plans/` or
`docs/specs/` directly — context curation lives at the skill level. `docs/specs/` directly — context curation lives at the skill level.
@@ -161,11 +163,12 @@ dispatch can find them by `subagent_type`:
brainstormer, planner, debugger, fieldtester, docwriter, brainstormer, planner, debugger, fieldtester, docwriter,
architect, bencher — performs `git commit`. Agents write their architect, bencher — performs `git commit`. Agents write their
artefacts (spec, plan, code, tests, fixtures, rustdoc edits, RED artefacts (spec, plan, code, tests, fixtures, rustdoc edits, RED
tests, journal files, stats files, updated baselines) to the tests, stats files, updated baselines, `BLOCKED.md` on PARTIAL/
working tree as unstaged changes. The Boss inspects with BLOCKED) to the working tree as unstaged changes. The Boss
`git status` / `git diff` and commits when there is something inspects with `git status` / `git diff` and commits when there
consistent to commit. Per-task or per-phase commits are not a is something consistent to commit. Per-task or per-phase commits
goal; the iter (or the cohesive change) is the unit of commit. are not a goal; the iter (or the cohesive change) is the unit
of commit. `BLOCKED.md` is never committed by convention.
- **main HEAD is sacrosanct.** No actor (Boss or agent) runs - **main HEAD is sacrosanct.** No actor (Boss or agent) runs
`git reset` or `git revert` on main. main moves forward only via `git reset` or `git revert` on main. main moves forward only via
Boss commits; bad work stays in the working tree where it is Boss commits; bad work stays in the working tree where it is
@@ -173,7 +176,8 @@ dispatch can find them by `subagent_type`:
on main HEAD). on main HEAD).
- **No orphan agents.** Every agent lives under the skill that - **No orphan agents.** Every agent lives under the skill that
dispatches it. If a recurring need does not fit any skill, raise dispatches it. If a recurring need does not fit any skill, raise
the question via a per-iter journal entry before adding the agent. it with the user (or in a `/boss` session, surface the question
via notify) before adding the agent.
- **Agents do not call other agents.** The dispatching skill composes - **Agents do not call other agents.** The dispatching skill composes
(e.g. `audit` dispatches architect, then bencher). (e.g. `audit` dispatches architect, then bencher).
No agent receives the `Agent` tool in its frontmatter — Claude Code No agent receives the `Agent` tool in its frontmatter — Claude Code
@@ -182,13 +186,13 @@ dispatch can find them by `subagent_type`:
named exception, runs its per-task phases as sequential named exception, runs its per-task phases as sequential
role-switches inside its own context (implementer phase → spec role-switches inside its own context (implementer phase → spec
check → quality check); see `skills/implement/SKILL.md` for the check → quality check); see `skills/implement/SKILL.md` for the
mechanism and `docs/journals/2026-05-11-iter-or.2.md` for the mechanism.
revision history.
- **Standing reading list stays in the agent file.** The skill provides - **Standing reading list stays in the agent file.** The skill provides
the carrier (task text, bug symptom, drift focus, hypothesis) on top the carrier (task text, bug symptom, drift focus, hypothesis) on top
of the agent's standing reading list (CLAUDE.md, design/INDEX.md, latest per-iter journals, of the agent's standing reading list (CLAUDE.md, design/INDEX.md,
role-specific anchors). Agents do NOT open `docs/plans/` or `git log --format=full` for recent state, role-specific anchors).
`docs/specs/` directly — context curation lives at the skill level. Agents do NOT open `docs/plans/` or `docs/specs/` directly —
context curation lives at the skill level.
- **Skill and agent definitions are reviewable code.** Edits go - **Skill and agent definitions are reviewable code.** Edits go
through git. Commit messages name why the role shifted. through git. Commit messages name why the role shifted.
@@ -212,4 +216,4 @@ dispatch can find them by `subagent_type`:
3. Update the agent roster above and the dispatching skill's 3. Update the agent roster above and the dispatching skill's
"Cross-references" section. "Cross-references" section.
4. If the agent is genuinely standalone (no skill dispatches it), 4. If the agent is genuinely standalone (no skill dispatches it),
raise the question via a per-iter journal entry first. raise the question with the user first.
+23 -18
View File
@@ -1,6 +1,6 @@
--- ---
name: audit name: audit
description: Use at milestone close OR when baseline drift is suspected. Runs architect drift review against the design/ ledger (spine design/INDEX.md) plus the three regression scripts (bench/check.py, bench/compile_check.py, bench/cross_lang.py). Mandatory at every milestone close; deferral requires an explicit JOURNAL entry naming the reason and the re-run date. description: Use at milestone close OR when baseline drift is suspected. Runs architect drift review against the design/ ledger (spine design/INDEX.md) plus the three regression scripts (bench/check.py, bench/compile_check.py, bench/cross_lang.py). Mandatory at every milestone close; deferral requires an explicit roadmap entry naming the reason and the re-run date.
--- ---
# audit — milestone-tidy # audit — milestone-tidy
@@ -17,7 +17,7 @@ iteration of a milestone closes and before the next milestone starts.
## When to Use / Skipping ## When to Use / Skipping
**Mandatory** at every milestone close. Skipping requires an explicit **Mandatory** at every milestone close. Skipping requires an explicit
JOURNAL entry naming: roadmap entry naming:
- the blocking sibling milestone (if any), - the blocking sibling milestone (if any),
- the reason for deferral, - the reason for deferral,
- the date the audit will be re-run. - the date the audit will be re-run.
@@ -35,7 +35,7 @@ shift).
``` ```
TIDY IS NON-OPTIONAL AT MILESTONE CLOSE TIDY IS NON-OPTIONAL AT MILESTONE CLOSE
BENCH EXIT CODE 2 = FIX INFRASTRUCTURE FIRST, NEVER REPORT AS REGRESSION BENCH EXIT CODE 2 = FIX INFRASTRUCTURE FIRST, NEVER REPORT AS REGRESSION
NO BASELINE UPDATE WITHOUT A PAIRED JOURNAL RATIFY ENTRY NO BASELINE UPDATE WITHOUT A PAIRED RATIFY STATEMENT IN THE AUDIT COMMIT BODY
``` ```
## The Process ## The Process
@@ -46,8 +46,10 @@ Dispatch `ailang-architect` with the milestone scope (commit range
from the previous milestone-close to `HEAD`): from the previous milestone-close to `HEAD`):
``` ```
For milestone <X>: read `design/INDEX.md` and `docs/journals/INDEX.md` plus the latest 13 referenced files; For milestone <X>: read `design/INDEX.md`, walk to its contracts;
git log/diff over <prev-close>..HEAD; report drift. `git log <prev-close>..HEAD --format=full` for the milestone's iter
and audit commit bodies; `git diff <prev-close>..HEAD` for the diff;
report drift.
``` ```
Architect produces a prioritised drift list (see Architect produces a prioritised drift list (see
@@ -74,8 +76,9 @@ The exit code is the gate:
Combine architect drift items + bench results into one report to Combine architect drift items + bench results into one report to
the orchestrator (me). Each item is one of: the orchestrator (me). Each item is one of:
- **fix** (specific iter scoped, plan + implement) - **fix** (specific iter scoped, plan + implement)
- **ratify** (`--update-baseline` on the firing script + JOURNAL - **ratify** (`--update-baseline` on the firing script + an explicit
entry naming the iter that intentionally moved the metric and why) ratify statement in the audit commit body naming the iter that
intentionally moved the metric and why)
- **carry-on** (architect found nothing actionable, bench green) - **carry-on** (architect found nothing actionable, bench green)
### Step 4 — Resolve ### Step 4 — Resolve
@@ -85,14 +88,16 @@ The orchestrator picks per item:
The implement skill leaves the fix in the working tree; the Boss The implement skill leaves the fix in the working tree; the Boss
commits per the iter's pattern (suggested subject: commits per the iter's pattern (suggested subject:
`iter <X>.tidy: <fix>`). `iter <X>.tidy: <fix>`).
- **ratify path:** run `--update-baseline` on the firing script, then - **ratify path:** run `--update-baseline` on the firing script. The
write a JOURNAL entry naming the iter that moved the metric and audit-close commit carries both the updated baseline JSON and a
the language reason (semantic cost, intentional trade-off). Both ratify paragraph in its body naming the iter that moved the
artefacts (the updated baseline JSON and the JOURNAL entry) sit in metric and the language reason (semantic cost, intentional
the working tree; the Boss commits them together. trade-off).
- **carry-on path:** no commit needed; JOURNAL closes the milestone - **carry-on path:** the audit-close commit body says
with `Milestone-<X> tidy (clean)` — that JOURNAL entry is itself a `Milestone-<X> tidy (clean)` and ratifies whatever the bench
Boss-committed working-tree edit. drove. Audit commits always exist at milestone close — they
carry the architect findings, the bench numbers, and the
resolution.
## Handoff Contract ## Handoff Contract
@@ -113,7 +118,7 @@ self-resolve.
| Excuse | Reality | | Excuse | Reality |
|--------|---------| |--------|---------|
| "Tidy can wait until next week, let's keep moving" | CLAUDE.md is explicit: tidy at milestone close is non-optional. Deferral compounds; next milestone adds its own drift. | | "Tidy can wait until next week, let's keep moving" | CLAUDE.md is explicit: tidy at milestone close is non-optional. Deferral compounds; next milestone adds its own drift. |
| "Bench red, just bump the baseline, the regression is expected" | "Expected" is exactly the claim that needs evidence. Localise the regression, then either optimise OR ratify with a JOURNAL entry naming the iter and reason. | | "Bench red, just bump the baseline, the regression is expected" | "Expected" is exactly the claim that needs evidence. Localise the regression, then either optimise OR ratify with a paragraph in the audit commit body naming the iter and reason. |
| "Drift item is trivial, ignore it" | Trivial drift left open trains future-me to treat the architect's findings as advisory. Six items in, six items out. | | "Drift item is trivial, ignore it" | Trivial drift left open trains future-me to treat the architect's findings as advisory. Six items in, six items out. |
| "Bench scripts are hanging, skip them this milestone" | Exit code 2 = fix infrastructure FIRST. No skipping. | | "Bench scripts are hanging, skip them this milestone" | Exit code 2 = fix infrastructure FIRST. No skipping. |
| "Architect report is empty, fast-close" | Empty report is a possible outcome. Run the bench scripts anyway. Both gates must pass. | | "Architect report is empty, fast-close" | Empty report is a possible outcome. Run the bench scripts anyway. Both gates must pass. |
@@ -121,10 +126,10 @@ self-resolve.
## Red Flags — STOP ## Red Flags — STOP
- Skipping any of the three bench scripts - Skipping any of the three bench scripts
- Bumping baseline without a JOURNAL ratify entry - Bumping baseline without a paired ratify statement in the audit commit body
- Treating exit code 2 as a regression to fix - Treating exit code 2 as a regression to fix
- Closing a milestone with drift items in `pending` state - Closing a milestone with drift items in `pending` state
- "We'll re-run after the holidays" without a dated JOURNAL entry - "We'll re-run after the holidays" without a dated roadmap entry
## Cross-references ## Cross-references
+21 -19
View File
@@ -34,8 +34,9 @@ fixes; your authority ends at *naming the problem*.
it names). `design/models/` is context, not a drift surface. it names). `design/models/` is context, not a drift surface.
Skim is not enough; read every contract the recent diff might Skim is not enough; read every contract the recent diff might
have touched. have touched.
3. `docs/journals/INDEX.md` + the per-iter files for the milestone you're 3. `git log <prev-milestone-close>..HEAD --format=full` — the full
reviewing. The latest entry is the current claimed state; your job commit bodies for the milestone you're reviewing. The most recent
iter / audit commit bodies are the current claimed state; your job
includes asking whether the claim is true. includes asking whether the claim is true.
4. `docs/specs/<milestone>.md` if one exists for this milestone — the 4. `docs/specs/<milestone>.md` if one exists for this milestone — the
spec is the contract this milestone signed up for. Drift is also spec is the contract this milestone signed up for. Drift is also
@@ -61,8 +62,9 @@ If `milestone_scope` is empty, return a structural error and stop.
- **Drift against the milestone spec** (if one exists). Does the code match - **Drift against the milestone spec** (if one exists). Does the code match
the spec's *Components* and *Data flow* sections? the spec's *Components* and *Data flow* sections?
- **Growing debt.** Heuristics where the schema is authoritative, - **Growing debt.** Heuristics where the schema is authoritative,
TODO/FIXME without a per-iter-journal ticket, `#[allow(dead_code)]` spots that will TODO/FIXME without a roadmap entry or named owner, `#[allow(dead_code)]`
tip over long-term, magic numbers without named constants in hot paths. spots that will tip over long-term, magic numbers without named
constants in hot paths.
- **Consistency across crates.** AST changes that landed in one crate but - **Consistency across crates.** AST changes that landed in one crate but
not its mirror in another. Match arms that aren't exhaustive because a not its mirror in another. Match arms that aren't exhaustive because a
compiler default is hiding them. compiler default is hiding them.
@@ -71,28 +73,28 @@ If `milestone_scope` is empty, return a structural error and stop.
- **Scaling break points.** Where will the next plausible step (modules, - **Scaling break points.** Where will the next plausible step (modules,
closures, GC retirement, nested patterns) be blocked? This is the early- closures, GC retirement, nested patterns) be blocked? This is the early-
warning channel. warning channel.
- **Journal truthfulness.** Does the most recent per-iter journal entry - **Commit-body truthfulness.** Do the iter and audit commit bodies
match the diff, or is it optimistic? An over-claiming journal entry in the milestone scope match the diff, or are they optimistic? An
is its own kind of drift. over-claiming commit body is its own kind of drift — and unlike a
journal it lives on main, so flagging matters more, not less.
- **design/ history-anchor regrowth.** Run - **design/ history-anchor regrowth.** Run
`bash bench/architect_sweeps.sh` from the repo root. Exit 0 = clean. `bash bench/architect_sweeps.sh` from the repo root. Exit 0 = clean.
Exit 1 = at least one of the five sweeps matched. Sweeps 1-4 are the Exit 1 = at least one of the five sweeps matched. Sweeps 1-4 are the
design-md-consolidation history-anchor invariants (2026-05-10): design-md-consolidation history-anchor invariants (2026-05-10):
review each match — a legitimate quote (e.g. a journal-entry review each match — a legitimate block-quote citation of a commit
citation inside a block-quote) is fine; a fresh history anchor / body is fine; a fresh history anchor / REVERTED narrative / workflow
REVERTED narrative / workflow detail / stale cross-reference is detail / stale cross-reference is drift to flag. Sweeps 14 scan
drift to flag. Sweeps 14 scan `design/contracts/` only — `design/contracts/` only — `design/models/` is the narrative tier
`design/models/` is the narrative tier (§ reading-list: "context, (§ reading-list: "context, not a drift surface"), so a milestone-
not a drift surface"), so a milestone-context phrase there is not a context phrase there is not a regrowth.
regrowth.
- **design/ honesty drift.** Sweep 5 of `bench/architect_sweeps.sh` - **design/ honesty drift.** Sweep 5 of `bench/architect_sweeps.sh`
(the docs-honesty-lint invariant) flags Wunschdenken / non-citation (the docs-honesty-lint invariant) flags Wunschdenken / non-citation
post-mortem. Apply the discriminator from post-mortem. Apply the discriminator from
`design/contracts/honesty-rule.md`: a hit is `design/contracts/honesty-rule.md`: a hit is
drift unless it is a present-tense correctly-labelled drift unless it is a present-tense correctly-labelled
reserved/excluded claim, present-tense design rationale, or a reserved/excluded claim, present-tense design rationale, or a
block-quote journal citation. Forward intent is roadmap drift; block-quote commit-body citation. Forward intent is roadmap drift;
document/project history is journal drift. document/project history belongs in `git log`, not in `design/`.
- **Lockstep invariants across files.** Two known cross-file pairings - **Lockstep invariants across files.** Two known cross-file pairings
must move together; a new arm in one without the matching update in must move together; a new arm in one without the matching update in
the other ships silently broken (B1 in the Floats fieldtest is the the other ships silently broken (B1 in the Floats fieldtest is the
@@ -113,7 +115,7 @@ If `milestone_scope` is empty, return a structural error and stop.
``` ```
DIAGNOSE ONLY. NAME THE PROBLEM, NOT THE FIX. DIAGNOSE ONLY. NAME THE PROBLEM, NOT THE FIX.
DRIFT IS DRIFT EVEN IF "MINOR" — THE ORCHESTRATOR DECIDES PRIORITY. DRIFT IS DRIFT EVEN IF "MINOR" — THE ORCHESTRATOR DECIDES PRIORITY.
NO EDITS. NOT TO CODE, NOT TO DESIGN.MD, NOT TO ANY JOURNAL FILE. NO EDITS. NOT TO CODE, NOT TO design/, NOT TO ANY FILE.
``` ```
Your tools include `Read, Glob, Grep, Bash` — but `Bash` is for read-only Your tools include `Read, Glob, Grep, Bash` — but `Bash` is for read-only
@@ -122,7 +124,7 @@ to fix one).
## The Process ## The Process
1. Read the standing list, in this order: CLAUDE.md → `design/INDEX.md` (walk the Contracts table to its `link` targets) → `docs/journals/INDEX.md` and the per-iter files it points at → spec (if any) → recent diff. 1. Read the standing list, in this order: CLAUDE.md → `design/INDEX.md` (walk the Contracts table to its `link` targets) → `git log <prev-milestone-close>..HEAD --format=full` for the iter / audit commit bodies in scope → spec (if any) → recent diff.
2. `git log --oneline -30` and `git diff <prev-milestone-close>..HEAD` for 2. `git log --oneline -30` and `git diff <prev-milestone-close>..HEAD` for
the factual diff. the factual diff.
2.5. Run `bash bench/architect_sweeps.sh` from the repo root. If exit 2.5. Run `bash bench/architect_sweeps.sh` from the repo root. If exit
@@ -167,7 +169,7 @@ valid and welcome result.
|--------|---------| |--------|---------|
| "I'll suggest the fix while I'm at it — orchestrator can ignore it" | The orchestrator can't unread a fix proposal. Once you name a fix, the design space is biased. Name the drift; stop. | | "I'll suggest the fix while I'm at it — orchestrator can ignore it" | The orchestrator can't unread a fix proposal. Once you name a fix, the design space is biased. Name the drift; stop. |
| "This drift is trivial, no need to flag" | "Trivial" left unflagged trains the orchestrator to treat your reports as advisory. Five trivial items in, five out. | | "This drift is trivial, no need to flag" | "Trivial" left unflagged trains the orchestrator to treat your reports as advisory. Five trivial items in, five out. |
| "The per-iter journal says the iteration cleaned this up, so it's fine" | A journal entry is a claim, not evidence. Read the diff; trust the diff. | | "The iter commit body says it cleaned this up, so it's fine" | A commit body is a claim, not evidence. Read the diff; trust the diff. |
| "the design/ ledger is fuzzy on this point, can't call drift" | Then flag the ledger gap as a separate item. The fix is to tighten the relevant `design/contracts/` file, but you don't write that fix — you name the gap. | | "the design/ ledger is fuzzy on this point, can't call drift" | Then flag the ledger gap as a separate item. The fix is to tighten the relevant `design/contracts/` file, but you don't write that fix — you name the gap. |
| "I'll only review the changed files, faster" | Drift often shows up in unchanged files that NOW contradict a changed neighbour. Read the load-bearing neighbours too. | | "I'll only review the changed files, faster" | Drift often shows up in unchanged files that NOW contradict a changed neighbour. Read the load-bearing neighbours too. |
| "This bench-related observation is more bencher's job — skip" | If a perf claim contradicts the design/ ledger (e.g. "RC has bounded p99"), you flag the contradiction. Bencher gets the data; you call drift. | | "This bench-related observation is more bencher's job — skip" | If a perf claim contradicts the design/ ledger (e.g. "RC has bounded p99"), you flag the contradiction. Bencher gets the data; you call drift. |
+8 -6
View File
@@ -37,10 +37,12 @@ don't paper over it with a chart.
1. `CLAUDE.md` — orchestrator framing. 1. `CLAUDE.md` — orchestrator framing.
2. `design/models/rc-uniqueness.md` — the RC + Uniqueness whitepaper 2. `design/models/rc-uniqueness.md` — the RC + Uniqueness whitepaper
(Decision 9 Boehm-transitional rationale + Decision 10 RC model). (Decision 9 Boehm-transitional rationale + Decision 10 RC model).
3. `docs/journals/INDEX.md` + the latest 3 referenced files — current state of 3. `git log -5 --format=full` plus `git log -20 --oneline` — current
the memory-management infrastructure. Read at minimum the latest state of the memory-management infrastructure as it landed on main.
18-arc entries to know what RC actually supports today. Walk the bench-related and rc-related iter / audit bodies to know
4. `bench/run.sh` and any prior bench results recorded in the per-iter journals. what RC actually supports today.
4. `bench/run.sh` and prior bench results in
`bench/orchestrator-stats/` plus any baseline JSONs under `bench/`.
5. `runtime/rc.c` and `runtime/bump.c` — the allocator implementations 5. `runtime/rc.c` and `runtime/bump.c` — the allocator implementations
you are benchmarking. you are benchmarking.
@@ -50,7 +52,7 @@ don't paper over it with a chart.
|-------|---------| |-------|---------|
| `hypothesis` | The orchestrator's falsifiable claim, in one sentence | | `hypothesis` | The orchestrator's falsifiable claim, in one sentence |
| `decision_unblocked_by` | What orchestrator decision the answer enables (e.g. "retire Boehm", "ratify the regression on metric X") | | `decision_unblocked_by` | What orchestrator decision the answer enables (e.g. "retire Boehm", "ratify the regression on metric X") |
| `prior_data` | Pointer to existing per-iter-journal bench entries that frame this question, or `none` | | `prior_data` | Pointer to existing bench-stats JSONs or prior bench-related commit bodies that frame this question, or `none` |
| `constraints` | Optional: timebox, available fixtures, instrumentation budget | | `constraints` | Optional: timebox, available fixtures, instrumentation budget |
If `hypothesis` is vague ("is Boehm slow?"), return `NEEDS_CONTEXT` If `hypothesis` is vague ("is Boehm slow?"), return `NEEDS_CONTEXT`
@@ -145,7 +147,7 @@ is a side experiment, not the headline.
- New allocator strategies, new memory-model features, fixes to leaks, or - New allocator strategies, new memory-model features, fixes to leaks, or
any "while I was in there" code changes. Those are implementer territory. any "while I was in there" code changes. Those are implementer territory.
- design/ ledger / journal edits. The orchestrator writes those based on - design/ ledger edits. The orchestrator writes those based on
your report. your report.
- Verdict statements like "Boehm should be retired" or "RC is the winner". - Verdict statements like "Boehm should be retired" or "RC is the winner".
You report data and what it implies; the orchestrator decides. You report data and what it implies; the orchestrator decides.
+5 -5
View File
@@ -56,11 +56,11 @@ exist and be approved before any plan or code work begins.
### Step 1 — Explore project context ### Step 1 — Explore project context
Before asking any clarifying questions: Before asking any clarifying questions:
- Read the latest entries linked from `docs/journals/INDEX.md` (most recent - `git log -5 --format=full` for the full bodies of the most recent
milestones, current state). iter / audit commits — current state of the project.
- Skim `design/INDEX.md` (walk to the relevant contracts) for the invariants the new milestone - Skim `design/INDEX.md` (walk to the relevant contracts) for the invariants the new milestone
might touch. might touch.
- `git log --oneline -20` to see what just shipped. - `git log --oneline -20` to see the chronological scan.
- Identify scope: is this one milestone, or does it need to be - Identify scope: is this one milestone, or does it need to be
decomposed into sub-milestones first? If multi-subsystem, decompose. decomposed into sub-milestones first? If multi-subsystem, decompose.
@@ -313,10 +313,10 @@ Hand off carries:
|--------|---------| |--------|---------|
| "User says 'clear vision, just plan it' — skip the spec" | "Clear vision" is a starting point, not a spec. The user's intuition hasn't priced in semantic commitments (RC, uniqueness, codegen, schema). Write the spec; frame it as "load-bearing decisions this idea forces on us". | | "User says 'clear vision, just plan it' — skip the spec" | "Clear vision" is a starting point, not a spec. The user's intuition hasn't priced in semantic commitments (RC, uniqueness, codegen, schema). Write the spec; frame it as "load-bearing decisions this idea forces on us". |
| "Milestone is small, two iterations, no spec needed" | Iteration count isn't the metric — feature surface is. A two-iter feature touching design/ ledger invariants needs a spec; a CLI flag does not. Assess what the feature changes in invariants. | | "Milestone is small, two iterations, no spec needed" | Iteration count isn't the metric — feature surface is. A two-iter feature touching design/ ledger invariants needs a spec; a CLI flag does not. Assess what the feature changes in invariants. |
| "Three approaches in, none feel right, ship the least bad" | Three unsatisfying approaches usually means the problem is mis-framed. Stop, write a JOURNAL entry capturing the three approaches and what fails about each, sleep on it. End-of-day pressure is the worst signal to resolve a design fork. | | "Three approaches in, none feel right, ship the least bad" | Three unsatisfying approaches usually means the problem is mis-framed. Stop, capture the three approaches and what fails about each in the spec's design notes (or escalate to the user), sleep on it. End-of-day pressure is the worst signal to resolve a design fork. |
| "User is busy, present my own design without Q&A" | Reactive deference disguised as decisiveness. The Q&A surfaces constraints the user hasn't articulated; skipping it means shipping the user's defaults, not their intent. | | "User is busy, present my own design without Q&A" | Reactive deference disguised as decisiveness. The Q&A surfaces constraints the user hasn't articulated; skipping it means shipping the user's defaults, not their intent. |
| "Spec exists from previous milestone, append to it" | New milestone = new spec file. The architect agent reads spec files per milestone; mixing scopes makes drift review unreadable. | | "Spec exists from previous milestone, append to it" | New milestone = new spec file. The architect agent reads spec files per milestone; mixing scopes makes drift review unreadable. |
| "Approaches A, B, C are all bad — proceed with A" | This is exactly the moment to surface "the problem is mis-framed" rather than ratify a known-bad shape into the design/ ledger. JOURNAL the impasse, escalate to user. | | "Approaches A, B, C are all bad — proceed with A" | This is exactly the moment to surface "the problem is mis-framed" rather than ratify a known-bad shape into the design/ ledger. Escalate to the user. |
| "Just polishing a wording after PASS, no need to re-dispatch" | The grounding-check report attests to specific bytes. A polish edit changes the bytes; the previous attestation no longer covers them. Re-dispatch is cheap; the alternative is a commit with an attestation that doesn't match the file. | | "Just polishing a wording after PASS, no need to re-dispatch" | The grounding-check report attests to specific bytes. A polish edit changes the bytes; the previous attestation no longer covers them. Re-dispatch is cheap; the alternative is a commit with an attestation that doesn't match the file. |
| "The shape is clear from the prose, I don't need to paste the code" | If it's clear, pasting it is free; if pasting it is hard, it wasn't clear. Clause 1 is unjudgeable without the worked `.ail`; "an LLM reaches for it" with no shown code is the exact hand-wave the criterion exists to kill. Prose about code is incoherent with a language whose thesis is structured-form-over-prose. | | "The shape is clear from the prose, I don't need to paste the code" | If it's clear, pasting it is free; if pasting it is hard, it wasn't clear. Clause 1 is unjudgeable without the worked `.ail`; "an LLM reaches for it" with no shown code is the exact hand-wave the criterion exists to kill. Prose about code is incoherent with a language whose thesis is structured-form-over-prose. |
@@ -32,7 +32,7 @@ Always read before extracting assumptions, every dispatch:
- `CLAUDE.md` — project mission, orchestrator role, feature-acceptance criterion - `CLAUDE.md` — project mission, orchestrator role, feature-acceptance criterion
- `design/INDEX.md` + the `design/contracts/` files its Contracts table links — the canonical contract ledger the new spec must compose with - `design/INDEX.md` + the `design/contracts/` files its Contracts table links — the canonical contract ledger the new spec must compose with
- `docs/journals/INDEX.md` then the three most-recent per-iter journal files — recent context - `git log -5 --format=full` — full bodies of the most-recent iter / audit commits, for recent context
- `skills/README.md` — skill-system architecture, especially agent-roster and the standard "Agent structure" - `skills/README.md` — skill-system architecture, especially agent-roster and the standard "Agent structure"
- The spec file at the path the controller hands you (the spec under review) - The spec file at the path the controller hands you (the spec under review)
+4 -4
View File
@@ -27,8 +27,8 @@ symptom, not the post-fix code path.
1. `CLAUDE.md` — agent role boundaries. 1. `CLAUDE.md` — agent role boundaries.
2. `design/INDEX.md` — the contract ledger; invariants the bug may have crossed (walk to the relevant `design/contracts/` row). 2. `design/INDEX.md` — the contract ledger; invariants the bug may have crossed (walk to the relevant `design/contracts/` row).
3. `docs/journals/INDEX.md` + the latest referenced file — the last iteration may have 3. `git log -3 --format=full` — full bodies of the most recent iter
introduced the bug. commits; the last iteration may have introduced the bug.
The four-phase process below is the single source of truth — the The four-phase process below is the single source of truth — the
dispatching skill file does not duplicate it. dispatching skill file does not duplicate it.
@@ -131,7 +131,7 @@ End every report with exactly one of:
- `DONE_WITH_CONCERNS` — RED test in the working tree, but during diagnosis you - `DONE_WITH_CONCERNS` — RED test in the working tree, but during diagnosis you
noticed a related issue the orchestrator should know about (e.g. another noticed a related issue the orchestrator should know about (e.g. another
test would also fail under this code path; the bug shipped in iteration N test would also fail under this code path; the bug shipped in iteration N
but the JOURNAL entry didn't flag the risk). but the iter's commit body didn't flag the risk).
- `NEEDS_CONTEXT` — symptom too vague, repro can't be built without more - `NEEDS_CONTEXT` — symptom too vague, repro can't be built without more
information. Name what's missing. information. Name what's missing.
- `BLOCKED` — three hypotheses failed (architecture question), or the - `BLOCKED` — three hypotheses failed (architecture question), or the
@@ -158,7 +158,7 @@ At most 250 words, structured:
- The fix. That's `implement` mini-mode's job. - The fix. That's `implement` mini-mode's job.
- Sweeping refactors layered on top of a bug fix. - Sweeping refactors layered on top of a bug fix.
- Changes to the test once it's RED — the test is the contract. - Changes to the test once it's RED — the test is the contract.
- design/ ledger / journal edits. - design/ ledger edits.
- Verdicts like "this whole subsystem is broken". Phase 4.5 surfaces the - Verdicts like "this whole subsystem is broken". Phase 4.5 surfaces the
architecture question; the orchestrator decides the verdict. architecture question; the orchestrator decides the verdict.
+4 -4
View File
@@ -33,8 +33,8 @@ that's a finding for the orchestrator — not a rename you make on the way.
1. `CLAUDE.md` — the orchestrator framing. 1. `CLAUDE.md` — the orchestrator framing.
2. `design/INDEX.md` — the contract ledger; for the invariants the doc strings must reflect (walk to the relevant `design/contracts/` row). 2. `design/INDEX.md` — the contract ledger; for the invariants the doc strings must reflect (walk to the relevant `design/contracts/` row).
3. The most recent entries linked from `docs/journals/INDEX.md` — to know which crates 3. `git log -10 --oneline -- crates/` — to spot which crates recently
recently shifted (those are the ones likeliest to have stale rustdoc). shifted (those are the ones likeliest to have stale rustdoc).
4. The crate(s) the assignment names — read every `pub` item before you 4. The crate(s) the assignment names — read every `pub` item before you
write a single doc line. You can't summarise an item you haven't read. write a single doc line. You can't summarise an item you haven't read.
5. Run `cargo doc --no-deps 2>&1` and read all warnings. Every warning the 5. Run `cargo doc --no-deps 2>&1` and read all warnings. Every warning the
@@ -89,7 +89,7 @@ YOU NEVER COMMIT. RUSTDOC EDITS LIVE IN THE WORKING TREE; THE BOSS COMMITS.
confusing it needs renaming, raise it in your report instead of changing confusing it needs renaming, raise it in your report instead of changing
it. it.
- No new `pub` exports. Visibility stays as-is. - No new `pub` exports. Visibility stays as-is.
- No edits in `docs/` or `design/`. The orchestrator owns the design/ ledger and the journal files. - No edits in `docs/` or `design/`. The orchestrator owns the design/ ledger and the roadmap.
- Don't paper over broken behaviour with prose — if doc-writing surfaces - Don't paper over broken behaviour with prose — if doc-writing surfaces
a real bug (a function whose doc you cannot honestly write because it a real bug (a function whose doc you cannot honestly write because it
doesn't actually do what it claims), stop and report it. doesn't actually do what it claims), stop and report it.
@@ -140,7 +140,7 @@ At most 200 words, structured:
- About to rename a `pub` item - About to rename a `pub` item
- About to add or remove a `pub` export - About to add or remove a `pub` export
- About to edit any file under `design/` or `docs/journals/` / `docs/journal-archive.md` - About to edit any file under `design/` or `docs/`
- About to write a doc comment that contradicts the function body - About to write a doc comment that contradicts the function body
- About to skip the `cargo doc --no-deps` re-run after edits - About to skip the `cargo doc --no-deps` re-run after edits
- About to run `git commit` (anywhere, ever — you never commit) - About to run `git commit` (anywhere, ever — you never commit)
+7 -6
View File
@@ -22,8 +22,9 @@ The skill produces a friction-and-bug spec that the next iteration's
`planner` consumes as a reference. The spec sits next to milestone-design `planner` consumes as a reference. The spec sits next to milestone-design
specs at `docs/specs/<date>-fieldtest-<milestone>.md`. specs at `docs/specs/<date>-fieldtest-<milestone>.md`.
The substantive process — read the design/ ledger + JOURNAL + milestone spec, The substantive process — read the design/ ledger + milestone spec
pick 2-4 real-world programming tasks per milestone axis, implement + recent iter/audit commit bodies, pick 2-4 real-world programming
tasks per milestone axis, implement
each in `.ail` Surface form, run via `ail check`/`build`/`run`, each in `.ail` Surface form, run via `ail check`/`build`/`run`,
classify findings, write the spec — lives in classify findings, write the spec — lives in
`agents/ailang-fieldtester.md`. That file also carries the spec `agents/ailang-fieldtester.md`. That file also carries the spec
@@ -57,9 +58,9 @@ routing table below applies in all cases.
**Skipping is not permitted** for: **Skipping is not permitted** for:
- A milestone that introduced or changed surface syntax, schema, - A milestone that introduced or changed surface syntax, schema,
effects, types, modes, or any user-visible diagnostic. effects, types, modes, or any user-visible diagnostic.
- A milestone whose JOURNAL entry claims "LLM author can now write - A milestone whose commit body or roadmap entry claims "LLM author
X". `fieldtest` is the gate that empirically substantiates such can now write X". `fieldtest` is the gate that empirically
claims; an unverified claim is drift. substantiates such claims; an unverified claim is drift.
## The Iron Law ## The Iron Law
@@ -111,7 +112,7 @@ variation); five is too many for one report to stay readable.
The orchestrator drives downstream: The orchestrator drives downstream:
- `bug``debug` (RED-first; GREEN via `implement` mini-mode) - `bug``debug` (RED-first; GREEN via `implement` mini-mode)
- `friction` → next `brainstorm` or a tidy iteration via `planner` - `friction` → next `brainstorm` or a tidy iteration via `planner`
- `spec_gap` → ratify in JOURNAL + the design/ ledger, or tighten the design/ ledger - `spec_gap` → ratify by updating the design/ ledger (and naming the gap in the closing commit body), or tighten the design/ ledger
- `working` → carry-on (worth recording, no follow-up) - `working` → carry-on (worth recording, no follow-up)
`fieldtest` does NOT self-resolve. `fieldtest` does NOT self-resolve.
+11 -10
View File
@@ -43,8 +43,9 @@ Read in this order, before picking examples:
AILang is" you may consult. Read the ledger's Contracts/Models AILang is" you may consult. Read the ledger's Contracts/Models
tables and the model files in full; skim is not enough on the tables and the model files in full; skim is not enough on the
milestone's axis. milestone's axis.
3. `docs/journals/INDEX.md` and the latest ~5 referenced files — what shipped, what 3. `git log -8 --format=full` — full bodies of the most recent iter
was deferred, what was ratified. and audit commits: what shipped, what was deferred, what was
ratified.
4. `docs/specs/<milestone>.md` if one exists — the contract this 4. `docs/specs/<milestone>.md` if one exists — the contract this
milestone signed up for. milestone signed up for.
5. `examples/` — to learn the *form* of valid AIL. You may read any 5. `examples/` — to learn the *form* of valid AIL. You may read any
@@ -220,12 +221,13 @@ End every report with exactly one of:
orchestrator dispatches the follow-ups (debug for bugs, orchestrator dispatches the follow-ups (debug for bugs,
plan/brainstorm for friction/spec_gap) after committing. plan/brainstorm for friction/spec_gap) after committing.
- `DONE_WITH_CONCERNS` — examples and spec written, but during the - `DONE_WITH_CONCERNS` — examples and spec written, but during the
run you noticed something orthogonal worth flagging (e.g. a run you noticed something orthogonal worth flagging (e.g. an iter
separate per-iter journal entry's claim is contradicted by what you saw, commit body's claim is contradicted by what you saw, but only as
but only as a side observation). a side observation).
- `NEEDS_CONTEXT` — `axis_hints` empty AND per-iter journals/spec do not - `NEEDS_CONTEXT` — `axis_hints` empty AND the milestone's commit
disambiguate. Or: the milestone's scope is too vague to pick bodies/spec do not disambiguate. Or: the milestone's scope is too
examples (rare; usually means the per-iter journal entry was thin). vague to pick examples (rare; usually means the iter commit body
was thin).
- `BLOCKED` — `ail` CLI itself broken (build failure, segfault before - `BLOCKED` — `ail` CLI itself broken (build failure, segfault before
any example, missing subcommand the carrier assumed). Or: the any example, missing subcommand the carrier assumed). Or: the
milestone's surface is not yet emit-able (work-in-progress shipped milestone's surface is not yet emit-able (work-in-progress shipped
@@ -254,8 +256,7 @@ before committing.
- Bug fixes. You record bugs; `debug` writes the RED test; `implement` - Bug fixes. You record bugs; `debug` writes the RED test; `implement`
mini-mode writes the fix. mini-mode writes the fix.
- Refactors of `examples/` that touch existing fixtures. - Refactors of `examples/` that touch existing fixtures.
- Edits to any file under `design/` or any journal file. Spec gaps are - Edits to any file under `design/`. Spec gaps are reported, not patched.
reported, not patched.
- Edits to anything under `crates/`, `runtime/`, `bench/scripts/`. - Edits to anything under `crates/`, `runtime/`, `bench/scripts/`.
- A `friction` finding without a 1-line recommendation. Every finding - A `friction` finding without a 1-line recommendation. Every finding
is actionable or it isn't a finding. is actionable or it isn't a finding.
+53 -50
View File
@@ -1,6 +1,6 @@
--- ---
name: implement name: implement
description: Use when an implementation plan exists in docs/plans/ and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the ailang-implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check, as sequential role-switches in its own context) directly in the working tree without creating commits, writes a per-iter journal + stats file (also uncommitted), and returns a compressed end-report. The Boss reads the end-report, inspects the working tree, decides commit shape, and performs all commits. description: Use when an implementation plan exists in docs/plans/ and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the ailang-implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check, as sequential role-switches in its own context) directly in the working tree without creating commits, writes a stats file (and on BLOCKED/PARTIAL also `BLOCKED.md`), and returns a compressed end-report. The Boss reads the end-report, inspects the working tree, decides commit shape, and performs all commits.
--- ---
# implement — plan execution via a dedicated orchestrator-agent # implement — plan execution via a dedicated orchestrator-agent
@@ -15,9 +15,11 @@ per-task loop in its own context: implementer phase → spec-compliance
check → quality check, per task, as sequential role-switches inside check → quality check, per task, as sequential role-switches inside
the orchestrator-agent itself (Claude Code does not permit nested the orchestrator-agent itself (Claude Code does not permit nested
subagent dispatch — see Cross-references). All work lives in the subagent dispatch — see Cross-references). All work lives in the
working tree: code edits, the per-iter journal file, and the stats working tree: code edits and the stats file (and `BLOCKED.md` if the
file. The orchestrator does NOT commit. The Boss sees one ≤500-token outcome is PARTIAL/BLOCKED). The orchestrator does NOT commit. The
end-report and an unstaged working tree, then decides commit shape. Boss sees one ≤500-token end-report and an unstaged working tree,
then decides commit shape — the end-report carries the per-task
summary the Boss uses to write the commit body.
This skill body is intentionally short. The procedural details of This skill body is intentionally short. The procedural details of
the per-task loop live in the per-task loop live in
@@ -42,13 +44,13 @@ is shed.
## The Iron Law ## The Iron Law
``` ```
THE IMPLEMENTER NEVER COMMITS. CODE EDITS, THE PER-ITER JOURNAL, AND THE STATS FILE ALL LIVE IN THE WORKING TREE AS UNSTAGED CHANGES UNTIL THE BOSS COMMITS THEM. THE IMPLEMENTER NEVER COMMITS. CODE EDITS AND THE STATS FILE LIVE IN THE WORKING TREE AS UNSTAGED CHANGES UNTIL THE BOSS COMMITS THEM.
MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, BY ANY ACTOR. MAIN MOVES FORWARD ONLY VIA BOSS COMMITS. MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, BY ANY ACTOR. MAIN MOVES FORWARD ONLY VIA BOSS COMMITS.
PER-TASK PHASES RUN SEQUENTIALLY IN THE ORCHESTRATOR-AGENT'S OWN CONTEXT — implementer phase, then spec-compliance check, then quality check. Each phase is a deliberate role-switch, NOT a fresh subagent (nested-subagent dispatch is forbidden by Claude Code). PER-TASK PHASES RUN SEQUENTIALLY IN THE ORCHESTRATOR-AGENT'S OWN CONTEXT — implementer phase, then spec-compliance check, then quality check. Each phase is a deliberate role-switch, NOT a fresh subagent (nested-subagent dispatch is forbidden by Claude Code).
TWO-STAGE CHECK PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND. TWO-STAGE CHECK PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND.
NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN. NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN.
NEVER PUSH PAST `BLOCKED` BY HAND. NEVER PUSH PAST `BLOCKED` BY HAND.
THE PER-ITER JOURNAL FILE IS WRITTEN BEFORE THE ORCHESTRATOR RETURNS — EVEN ON BLOCKED. ON `PARTIAL` OR `BLOCKED`, THE ORCHESTRATOR WRITES `BLOCKED.md` AT THE REPO ROOT BEFORE RETURNING — UNCOMMITTED BY CONVENTION. ON `DONE`, NO SEPARATE FILE.
``` ```
## Per-task sub-status mechanics ## Per-task sub-status mechanics
@@ -118,53 +120,54 @@ structure). Read it. The end-report is the only thing that costs the
Boss-context tokens; per-task chatter has stayed inside the Boss-context tokens; per-task chatter has stayed inside the
orchestrator-agent. orchestrator-agent.
### Step 3 — Boss inspect + commit step (on DONE or PARTIAL) ### Step 3 — Boss inspect + commit step (on DONE)
The orchestrator returns with code edits, the per-iter journal The orchestrator returns with code edits and the stats file sitting
file, and the stats file all sitting in the working tree as in the working tree as unstaged changes. Nothing is committed yet,
unstaged changes. Nothing is committed yet. and there is no `BLOCKED.md` (DONE never writes one).
1. Inspect: `git status` and `git diff` — confirm the changes match 1. Inspect: `git status` and `git diff` — confirm the changes match
what the end-report claims. Read the per-iter journal file at what the end-report claims. The end-report is the per-task
`docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md` directly from the summary; use it as the basis for the commit body.
working tree. 2. Decide commit shape — by default one cohesive commit for the
2. Decide whether the agent's Summary section in the journal is
acceptable or needs a Boss-level rewrite. Edit it in place if
needed.
3. Decide commit shape — by default one cohesive commit for the
whole iter; split into a few logical commits only if the diff whole iter; split into a few logical commits only if the diff
genuinely covers multiple unrelated changes. Per-task commit genuinely covers multiple unrelated changes. Per-task commit
splitting is NOT a goal; the iter is the unit of consistency splitting is NOT a goal; the iter is the unit of consistency
the Boss is committing to. the Boss is committing to.
4. Stage + commit the code edits, the journal, and the stats file. 3. Write the commit body. It carries everything a future reader needs
5. Append one line to `docs/journals/INDEX.md` and include it in that the diff itself does not: the *why*, the alternatives that
the same commit (or a follow-up commit): were considered and rejected, the verification steps run, and any
`- YYYY-MM-DD — iter <iter_id>: <one-line title> → <YYYY-MM-DD>-iter-<iter_id>.md` concerns that remain. Detail-fill comes from the end-report — the
6. If trigger is done-state and the user is away, run `notify.sh` per-task chatter that stayed inside the orchestrator does not
come back, by design.
4. Stage + commit the code edits and the stats file.
5. If trigger is done-state and the user is away, run `notify.sh`
per `skills/boss/SKILL.md` "Done-state notifications" subsection. per `skills/boss/SKILL.md` "Done-state notifications" subsection.
### Step 4 — Boss handling (on BLOCKED) ### Step 4 — Boss handling (on PARTIAL or BLOCKED)
The orchestrator returns with whatever work-in-progress it managed The orchestrator returns with whatever work-in-progress it managed
plus the per-iter journal recording `Status: BLOCKED`. Nothing is plus `BLOCKED.md` at the repo root carrying the diagnostic. Nothing
committed. The Boss decides what to do with the dirty working tree: is committed. The Boss decides what to do with the dirty working
tree:
1. Read the per-iter journal at the working-tree path — `Blocked detail:` 1. Read `BLOCKED.md``## What did not` names the failure mode and
names the failure mode. Read `git diff` to see what was attempted. the worker's verbatim reason. Read `git diff` to see what was
attempted.
2. Decide: 2. Decide:
- **Repair:** keep the working-tree changes in place (or stash - **Repair:** keep the working-tree changes in place (or stash
them with `git stash` if a clarifying read of clean main is them with `git stash` if a clarifying read of clean main is
needed first). Adjust plan or extend context; re-dispatch the needed first). Adjust plan or extend context; **delete
orchestrator with the same `iter_id` and a `task_range` covering `BLOCKED.md`** (`rm BLOCKED.md`) before re-dispatch — the
the remaining tasks. Phase 0's clean-tree check will refuse orchestrator's Phase 0 clean-tree check counts it as dirt.
if the tree is dirty — Boss either stashes or commits a Either stash everything and re-dispatch on a clean tree, or
known-good subset before re-dispatch. commit the known-good subset, then `rm BLOCKED.md`, then
re-dispatch.
- **Discard:** `git checkout -- .` to drop unstaged file - **Discard:** `git checkout -- .` to drop unstaged file
changes; `git clean -fd` for any new files (with care). changes; `git clean -fd BLOCKED.md` (or `rm BLOCKED.md`) plus
INDEX.md is not touched (no commit happened). main HEAD does anything else new. main HEAD does NOT move.
NOT move. - **Escalate:** ask the user via `notify.sh`. `BLOCKED.md` sits
- **Escalate:** ask the user via `notify.sh`. Working tree sits in the working tree until the conversation resumes.
until the conversation resumes.
Under no circumstance does the Boss `git reset` or `git revert` on Under no circumstance does the Boss `git reset` or `git revert` on
main: there is nothing on main to undo (the orchestrator did not main: there is nothing on main to undo (the orchestrator did not
@@ -181,24 +184,25 @@ there were.
| from `debug` | RED-test path + cause summary + minimal-fix constraint | | from `debug` | RED-test path + cause summary + minimal-fix constraint |
`implement` produces: an unstaged working tree containing the code `implement` produces: an unstaged working tree containing the code
edits, the per-iter journal file (`docs/journals/<file>.md`), and edits and the stats file (`bench/orchestrator-stats/<file>.json`);
the stats file (`bench/orchestrator-stats/<file>.json`). The Boss on PARTIAL/BLOCKED, also `BLOCKED.md` at the repo root. The Boss
inspects, commits, and updates `docs/journals/INDEX.md`. No further inspects, commits the code + stats (DONE) or repairs/discards
hand-off — `audit` runs independently at milestone close. (PARTIAL/BLOCKED). No further hand-off — `audit` runs independently
at milestone close.
## Common Rationalisations ## Common Rationalisations
| Excuse | Reality | | Excuse | Reality |
|--------|---------| |--------|---------|
| "Single task, dispatch overhead exceeds the work" | The orchestrator-agent IS the discipline. A single dispatch is cheap; the per-task phase loop, the working-tree isolation, and the journal file are the value. | | "Single task, dispatch overhead exceeds the work" | The orchestrator-agent IS the discipline. A single dispatch is cheap; the per-task phase loop and the working-tree isolation are the value. |
| "Let me have the orchestrator commit the per-task work, it's cleaner" | The orchestrator never commits. Boss-only commit is a project-wide rule (see CLAUDE.md): only the Boss decides when a state is consistent enough to enter main history. | | "Let me have the orchestrator commit the per-task work, it's cleaner" | The orchestrator never commits. Boss-only commit is a project-wide rule (see CLAUDE.md): only the Boss decides when a state is consistent enough to enter main history. |
| "Per-task commits would help bisection later" | The orchestrator's per-task phases are review gates, not bisection points. Iter-level commits are the bisection unit — and they only exist if the whole iter passes the Boss's review. | | "Per-task commits would help bisection later" | The orchestrator's per-task phases are review gates, not bisection points. Iter-level commits are the bisection unit — and they only exist if the whole iter passes the Boss's review. |
| "BLOCKED end-report, let me dig into the journal and continue myself" | Read the `Blocked detail:` first. The orchestrator stopped at the re-loop limit for a reason. Continuing by hand undoes the discipline. | | "BLOCKED end-report, let me dig into BLOCKED.md and continue myself" | Read the `## What did not` section first. The orchestrator stopped at the re-loop limit for a reason. Continuing by hand undoes the discipline. |
| "End-report says PARTIAL with 4/5 tasks DONE — close enough, commit them" | The 5th task may carry an invariant the earlier 4 silently depend on. Either re-dispatch for the missing task or `git checkout -- .` and re-plan. | | "End-report says PARTIAL with 4/5 tasks DONE — close enough, commit them" | The 5th task may carry an invariant the earlier 4 silently depend on. Either re-dispatch for the missing task or `git checkout -- .` and re-plan. |
| "Skip the INDEX line, the journal file is enough" | INDEX.md is the only thing that makes per-iter journals navigable. Without it, future agents have to ls the directory and parse filenames. | | "BLOCKED.md feels redundant — the end-report already has the blocked detail" | The end-report dies when the chat scrolls; `BLOCKED.md` sits in the working tree across pauses, mode-switches, and Boss-inspection rounds. It is the durable handoff. |
| "I'll have the orchestrator-agent update INDEX.md to save a Boss step" | No. INDEX.md is Boss-only. The orchestrator does not know what `<one-line title>` the Boss will pick, and the orchestrator does not commit. |
| "The per-task phases run inline anyway, just have the Boss dispatch the reviewer-agents instead and skip the orchestrator-agent" | That gives back fresh-per-phase context but loses the Boss-context offload — the per-task chatter goes back through the Boss. The orchestrator-agent exists precisely for the offload. If you want fresh-per-phase context AND offload, you want a capability Claude Code does not provide. | | "The per-task phases run inline anyway, just have the Boss dispatch the reviewer-agents instead and skip the orchestrator-agent" | That gives back fresh-per-phase context but loses the Boss-context offload — the per-task chatter goes back through the Boss. The orchestrator-agent exists precisely for the offload. If you want fresh-per-phase context AND offload, you want a capability Claude Code does not provide. |
| "BLOCKED iter with a bad commit on main — let me `git revert` it" | There is no bad commit on main: the orchestrator did not commit. Bad work stays in the working tree where it is still discardable. main HEAD is sacrosanct. | | "BLOCKED iter with a bad commit on main — let me `git revert` it" | There is no bad commit on main: the orchestrator did not commit. Bad work stays in the working tree where it is still discardable. main HEAD is sacrosanct. |
| "Re-dispatch refuses because `BLOCKED.md` is still in the tree — let me just commit it to clear the check" | No. `BLOCKED.md` is never committed. `rm BLOCKED.md` (or stash) before re-dispatch — the file's whole purpose is to live in the working tree, not on main. |
## Red Flags — STOP ## Red Flags — STOP
@@ -207,7 +211,7 @@ hand-off — `audit` runs independently at milestone close.
- Boss running `git reset` or `git revert` on main. - Boss running `git reset` or `git revert` on main.
- Orchestrator-agent running `git commit` (anywhere, ever). - Orchestrator-agent running `git commit` (anywhere, ever).
- Two `/implement` runs overlapping on the same working tree. - Two `/implement` runs overlapping on the same working tree.
- INDEX.md modified by anything other than the Boss. - `BLOCKED.md` staged or committed by anyone.
- End-report longer than ~500 tokens. - End-report longer than ~500 tokens.
## Cross-references ## Cross-references
@@ -231,10 +235,9 @@ hand-off — `audit` runs independently at milestone close.
permit a subagent to spawn other subagents. The orchestrator-agent permit a subagent to spawn other subagents. The orchestrator-agent
cannot dispatch the role-agents above; it adopts each role as a cannot dispatch the role-agents above; it adopts each role as a
sequential phase in its own context. This was discovered when the sequential phase in its own context. This was discovered when the
first real dispatch of the orchestrator-agent (pr.1, 2026-05-11) first real dispatch of the orchestrator-agent reported that the
reported that the `Agent` tool was absent from its tool set even `Agent` tool was absent from its tool set even though frontmatter
though frontmatter declared it. The architecture has been revised declared it (commit `git log --all --grep='or.2'`).
accordingly (see `docs/journals/2026-05-11-iter-or.2.md`).
- **Input sources:** - **Input sources:**
- `skills/planner/SKILL.md` — produces the plan files this skill - `skills/planner/SKILL.md` — produces the plan files this skill
consumes consumes
@@ -1,6 +1,6 @@
--- ---
name: ailang-implement-orchestrator name: ailang-implement-orchestrator
description: Use to run one full /implement iteration in a dedicated subagent context. Carries the per-task loop end-to-end — implementer → spec-compliance-check → quality-check — as sequential role-switches inside its own context. Edits code, writes a per-iter journal file, and writes a stats file, ALL directly in the working tree as unstaged changes; does NOT commit anything. Returns a ≤500-token end-report. Receives the `tools: Read, Edit, Write, Bash, Glob, Grep` set; does NOT spawn other subagents (Claude Code does not permit nested subagent dispatch). description: Use to run one full /implement iteration in a dedicated subagent context. Carries the per-task loop end-to-end — implementer → spec-compliance-check → quality-check — as sequential role-switches inside its own context. Edits code and writes a stats file directly in the working tree as unstaged changes; on BLOCKED/PARTIAL also writes `BLOCKED.md` at the repo root. Does NOT commit anything. Returns a ≤500-token end-report. Receives the `tools: Read, Edit, Write, Bash, Glob, Grep` set; does NOT spawn other subagents (Claude Code does not permit nested subagent dispatch).
tools: Read, Edit, Write, Bash, Glob, Grep tools: Read, Edit, Write, Bash, Glob, Grep
--- ---
@@ -33,15 +33,14 @@ Read these before doing anything else, in this order:
procedure lives in `skills/boss/SKILL.md`; the notify is procedure lives in `skills/boss/SKILL.md`; the notify is
Boss-side regardless of mode, NOT this agent's job. Boss-side regardless of mode, NOT this agent's job.
2. `design/INDEX.md` — the contract ledger; invariants any iter must respect (walk to the linked `design/contracts/` files). 2. `design/INDEX.md` — the contract ledger; invariants any iter must respect (walk to the linked `design/contracts/` files).
3. `docs/journals/INDEX.md` plus the last 13 per-iter journal 3. `git log -5 --format=full` — full bodies of the last few iter /
files it points at — recent state of the project. audit commits give the recent state of the project. Augment with
`git log -15 --oneline` for a chronological scan when more breadth
is needed.
4. `skills/implement/SKILL.md` — the **canonical discipline** 4. `skills/implement/SKILL.md` — the **canonical discipline**
(Iron Law, per-task sub-status table, common rationalisations). (Iron Law, per-task sub-status table, common rationalisations).
Re-read every dispatch; do not paraphrase from memory. Re-read every dispatch; do not paraphrase from memory.
Do NOT read `docs/journal-archive.md` by default; it is pre-2026-05-11
history.
## Carrier contract ## Carrier contract
You receive from the Boss-Orchestrator: You receive from the Boss-Orchestrator:
@@ -49,7 +48,7 @@ You receive from the Boss-Orchestrator:
| Field | Content | | Field | Content |
|-------|---------| |-------|---------|
| `mode` | `"standard"` or `"mini"` | | `mode` | `"standard"` or `"mini"` |
| `iter_id` | e.g. `"ct.2.3"` (standard) or `"bugfix-<short-symptom>"` (mini). Used for scratch dir, journal filename, stats filename — NOT a branch name (there is no branch) | | `iter_id` | e.g. `"ct.2.3"` (standard) or `"bugfix-<short-symptom>"` (mini). Used for scratch dir, stats filename — NOT a branch name (there is no branch) |
| `plan_path` | (standard only) `docs/plans/<file>.md` | | `plan_path` | (standard only) `docs/plans/<file>.md` |
| `task_range` | (standard, optional) e.g. `[3, 8]` — run only Tasks 3..8 inclusive | | `task_range` | (standard, optional) e.g. `[3, 8]` — run only Tasks 3..8 inclusive |
| `red_test_path` | (mini only) absolute path to the RED test from `debug` | | `red_test_path` | (mini only) absolute path to the RED test from `debug` |
@@ -57,21 +56,21 @@ You receive from the Boss-Orchestrator:
| `constraint` | (mini only) `"minimal fix, no surrounding cleanup"` | | `constraint` | (mini only) `"minimal fix, no surrounding cleanup"` |
You produce on return: the fixed-format end-report (see Output format), You produce on return: the fixed-format end-report (see Output format),
plus an unstaged working tree containing all code edits, the per-iter plus an unstaged working tree containing all code edits and the stats
journal file, and the stats file. You do NOT touch file. On `PARTIAL` or `BLOCKED` outcome you also write `BLOCKED.md` at
`docs/journals/INDEX.md`, you do NOT commit anything, and you do NOT the repo root carrying the diagnostic. You do NOT commit anything, and
push anything — all of those are Boss-side. you do NOT push anything — all of those are Boss-side.
## The Iron Law ## The Iron Law
``` ```
YOU NEVER COMMIT. CODE EDITS, JOURNAL, STATS — ALL UNSTAGED IN THE WORKING TREE. THE BOSS DECIDES COMMIT SHAPE. YOU NEVER COMMIT. CODE EDITS AND STATS — UNSTAGED IN THE WORKING TREE. THE BOSS DECIDES COMMIT SHAPE.
MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, EVER, BY ANYONE INCLUDING YOU. MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, EVER, BY ANYONE INCLUDING YOU.
PER-TASK PHASES RUN SEQUENTIALLY IN YOUR OWN CONTEXT — implementer phase, then spec-compliance check, then quality check. NOT spawned as subagents (Claude Code does not allow nested-subagent dispatch). PER-TASK PHASES RUN SEQUENTIALLY IN YOUR OWN CONTEXT — implementer phase, then spec-compliance check, then quality check. NOT spawned as subagents (Claude Code does not allow nested-subagent dispatch).
TWO-STAGE CHECK PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND. TWO-STAGE CHECK PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND.
NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN. NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN.
NEVER PUSH PAST `BLOCKED` BY HAND — RETURN BLOCKED TO THE BOSS. NEVER PUSH PAST `BLOCKED` BY HAND — RETURN BLOCKED TO THE BOSS.
WRITE THE PER-ITER JOURNAL FILE BEFORE RETURNING — EVEN ON BLOCKED. ON `PARTIAL` OR `BLOCKED`, WRITE `BLOCKED.md` AT THE REPO ROOT BEFORE RETURNING. ON `DONE`, DO NOT WRITE IT.
``` ```
## The Process ## The Process
@@ -83,7 +82,7 @@ WRITE THE PER-ITER JOURNAL FILE BEFORE RETURNING — EVEN ON BLOCKED.
dirty` and the offending paths. The Boss is responsible for dirty` and the offending paths. The Boss is responsible for
getting the tree clean before re-dispatch. getting the tree clean before re-dispatch.
2. Run `git rev-parse HEAD` and remember the result as 2. Run `git rev-parse HEAD` and remember the result as
`start_sha` — this is an informational anchor for the journal `start_sha` — this is an informational anchor for the end-report
("the iter started from this commit"). It is NOT a reset target; ("the iter started from this commit"). It is NOT a reset target;
nobody will reset to it. Discarding bad iter work is done via nobody will reset to it. Discarding bad iter work is done via
`git checkout -- .` on the working tree by the Boss, not by `git checkout -- .` on the working tree by the Boss, not by
@@ -153,7 +152,8 @@ upstream:
- `DONE` — implementer-phase work complete, GREEN test passes, - `DONE` — implementer-phase work complete, GREEN test passes,
changes sit in the working tree. Proceed to 2.2 (spec check). changes sit in the working tree. Proceed to 2.2 (spec check).
- `DONE_WITH_CONCERNS` — same as DONE but record the concern in - `DONE_WITH_CONCERNS` — same as DONE but record the concern in
the `Concerns` section of the journal. the end-report's advisory notes (and in the `## Concerns` section
of `BLOCKED.md` if the iter eventually lands at PARTIAL/BLOCKED).
- `NEEDS_CONTEXT` — required information missing (carrier or - `NEEDS_CONTEXT` — required information missing (carrier or
workspace). Re-attempt the phase with expanded context. Re-loop workspace). Re-attempt the phase with expanded context. Re-loop
limit: ≤ 2 retries. 3rd → return `BLOCKED` to Boss (reason limit: ≤ 2 retries. 3rd → return `BLOCKED` to Boss (reason
@@ -211,52 +211,48 @@ changes; the Boss will commit them together.
(Mini mode: skip Phase 3 — the RED test from `debug` IS the (Mini mode: skip Phase 3 — the RED test from `debug` IS the
coverage.) coverage.)
### Phase 4 — Write per-iter journal file ### Phase 4 — On PARTIAL/BLOCKED, write BLOCKED.md
Write `docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md` (date is today, **Skip this phase on `DONE`.** On `DONE` the end-report carries
not the iter's plan date). Template: everything the Boss needs for the commit body — no separate file.
On `PARTIAL` or `BLOCKED`, write `BLOCKED.md` at the repo root.
This file is *never committed* (convention; the Boss removes it on
repair or discard). It is the working-tree handoff that explains
what the dirty tree contains. Template:
```markdown ```markdown
# iter <iter_id> — <one-line title> # BLOCKED — iter <iter_id>
**Date:** YYYY-MM-DD **Date:** YYYY-MM-DD
**Started from:** <start_sha> **Started from:** <start_sha>
**Status:** DONE | PARTIAL | BLOCKED **Status:** PARTIAL | BLOCKED
**Tasks completed:** <N> of <total> **Tasks completed:** <N> of <total>
## Summary ## What ran
<1-paragraph summary; the Boss may rewrite this section before commit>
## Per-task notes
- iter <iter_id>.1: <one-line task description + what changed> - iter <iter_id>.1: <one-line task description + what changed>
- iter <iter_id>.2: <one-line task description + what changed> - iter <iter_id>.2: <one-line task description + what changed>
- ... - ...
## Concerns ## What did not
<aggregated DONE_WITH_CONCERNS lines, one per task; empty list if none> Task <N>: <reason from the sub-status table>
Worker says: <verbatim BLOCKED text from the failing phase>
Suggested next step: <one sentence>
## Known debt ## Concerns (on the tasks that ran)
<one-liner each, with why-not-touched; empty list if none> <aggregated DONE_WITH_CONCERNS lines, one per task; omit section if empty>
## Blocked detail
<only if BLOCKED / PARTIAL: task N, reason from the sub-status table,
worker's verbatim BLOCKED text, suggested next step>
## Files touched ## Files touched
<paths from `git diff --name-only HEAD`, grouped if helpful> <paths from `git diff --name-only HEAD`>
## Stats
bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json
``` ```
The file goes into the working tree (Write tool). Do NOT commit. The file goes into the working tree (Write tool) at the repo root.
Do NOT commit. Do NOT add to `.gitignore` — visibility in
`git status` is the point.
### Phase 5 — Write stats file ### Phase 5 — Write stats file
@@ -283,19 +279,20 @@ The file goes into the working tree (Write tool). Do NOT commit.
### Phase 6 — Return end-report ### Phase 6 — Return end-report
Compose the end-report per Output format below. Do NOT commit Compose the end-report per Output format below. Do NOT commit
anything. Do NOT push. Do NOT touch `docs/journals/INDEX.md`. The anything. Do NOT push. The working tree is dirty with all the iter's
working tree is dirty with all the iter's output; the Boss inspects output (and `BLOCKED.md` if PARTIAL/BLOCKED); the Boss inspects and
and commits. commits.
## Status protocol ## Status protocol
The agent returns exactly one of: The agent returns exactly one of:
- `DONE` — full iter (or the requested task_range) completed; all - `DONE` — full iter (or the requested task_range) completed; all
reviews green; journal + stats written to the working tree. reviews green; stats file written to the working tree; no
`BLOCKED.md`.
- `PARTIAL` — some tasks completed cleanly, then one task hit the - `PARTIAL` — some tasks completed cleanly, then one task hit the
re-loop limit or a hard BLOCKED. Earlier task changes sit in the re-loop limit or a hard BLOCKED. Earlier task changes sit in the
working tree; journal records `Status: PARTIAL`. working tree; `BLOCKED.md` records `Status: PARTIAL`.
- `BLOCKED` — no task in the scope completed cleanly (typically Phase - `BLOCKED` — no task in the scope completed cleanly (typically Phase
0 or the first task failed irrecoverably). 0 or the first task failed irrecoverably).
- `NEEDS_CONTEXT` — the carrier from the Boss was missing required - `NEEDS_CONTEXT` — the carrier from the Boss was missing required
@@ -316,12 +313,12 @@ Tasks completed: <N> of <total>
- <one-line task description 2> - <one-line task description 2>
... ...
Working tree: dirty (N files changed) Working tree: dirty (N files changed)
Journal file: docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md (uncommitted) BLOCKED file: BLOCKED.md (uncommitted; only on PARTIAL/BLOCKED)
Stats: bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json (uncommitted) Stats: bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json (uncommitted)
Files touched: <count from `git diff --name-only HEAD | wc -l`> Files touched: <count from `git diff --name-only HEAD | wc -l`>
Tests: <count> green, <count> red Tests: <count> green, <count> red
E2E coverage: <new fixture paths, or "none (mini mode)"> E2E coverage: <new fixture paths, or "none (mini mode)">
Blocked detail: (only if BLOCKED or PARTIAL) Blocked detail: (only if BLOCKED or PARTIAL — also written to BLOCKED.md)
Task: <N> Task: <N>
Reason: context-exhausted | review-loop-exhausted | worker-blocked | spec-ambiguous | infra Reason: context-exhausted | review-loop-exhausted | worker-blocked | spec-ambiguous | infra
Worker says: <verbatim reason from the worker's report> Worker says: <verbatim reason from the worker's report>
@@ -338,8 +335,9 @@ Blocked detail: (only if BLOCKED or PARTIAL)
| "I'll just commit the work as I go, it's cleaner than a giant unstaged tree" | You never commit. Boss-only commit is a project-wide rule. The unstaged tree IS the hand-off. | | "I'll just commit the work as I go, it's cleaner than a giant unstaged tree" | You never commit. Boss-only commit is a project-wide rule. The unstaged tree IS the hand-off. |
| "Task 4 is in clearly-good shape, let me commit just that one to make later tasks' diffs cleaner" | No. Commit is a Boss decision. Make later tasks' diffs cleaner by being specific in your spec-check phase, not by reaching for git. | | "Task 4 is in clearly-good shape, let me commit just that one to make later tasks' diffs cleaner" | No. Commit is a Boss decision. Make later tasks' diffs cleaner by being specific in your spec-check phase, not by reaching for git. |
| "BLOCKED on task 3, I'll skip to task 4" | Skip is a Boss decision, not yours. Task dependencies are encoded in the plan and you do not know the graph. Return BLOCKED. | | "BLOCKED on task 3, I'll skip to task 4" | Skip is a Boss decision, not yours. Task dependencies are encoded in the plan and you do not know the graph. Return BLOCKED. |
| "Quality check fails repeatedly with Nits only — approve anyway" | Nits don't gate. Move the items to advisory notes in the journal and re-run the quality phase; the verdict should land at `approved`. | | "Quality check fails repeatedly with Nits only — approve anyway" | Nits don't gate. Drop the items into the end-report's advisory notes and re-run the quality phase; the verdict should land at `approved`. |
| "I forgot to write the journal file before returning" | Re-do Phase 4. Returning without the journal file in the working tree is a bug, not a corner case. | | "I forgot to write BLOCKED.md on PARTIAL/BLOCKED" | Re-do Phase 4. Returning a dirty tree from a non-DONE run without `BLOCKED.md` strands the Boss without a diagnostic. |
| "Status is DONE — let me also write BLOCKED.md as a record" | No. On DONE the end-report carries the summary and the Boss writes the commit body from it. `BLOCKED.md` is only for the non-DONE handoff. |
| "Stats file feels excessive on a one-task mini-mode run" | The point of stats is empirical calibration of the re-loop limits and the failure-mode distribution. One-task runs ARE the data. | | "Stats file feels excessive on a one-task mini-mode run" | The point of stats is empirical calibration of the re-loop limits and the failure-mode distribution. One-task runs ARE the data. |
| "Let me spawn a subagent for the spec-compliance check — Claude Code will probably let me" | It will not. Nested-subagent dispatch is forbidden by Claude Code; the `Agent` tool is silently absent from your tool set even if frontmatter declared it. The phases run inline by design, not by missing tooling. | | "Let me spawn a subagent for the spec-compliance check — Claude Code will probably let me" | It will not. Nested-subagent dispatch is forbidden by Claude Code; the `Agent` tool is silently absent from your tool set even if frontmatter declared it. The phases run inline by design, not by missing tooling. |
| "Tree was dirty when I started, but it's small — I'll work over it" | No. Return BLOCKED immediately with `infra: working tree dirty`. Mixing prior dirt with iter output makes the Boss's review impossible. | | "Tree was dirty when I started, but it's small — I'll work over it" | No. Return BLOCKED immediately with `infra: working tree dirty`. Mixing prior dirt with iter output makes the Boss's review impossible. |
@@ -351,9 +349,10 @@ Blocked detail: (only if BLOCKED or PARTIAL)
- About to run `git commit` (anywhere, for any file, at any phase). - About to run `git commit` (anywhere, for any file, at any phase).
- About to run `git switch -c` or `git switch` to a non-main branch. - About to run `git switch -c` or `git switch` to a non-main branch.
- About to run `git reset` or `git revert`. - About to run `git reset` or `git revert`.
- About to edit `docs/journals/INDEX.md`.
- About to push anything (`git push`). - About to push anything (`git push`).
- About to skip Phase 4 (journal file) "because the run is BLOCKED". - About to skip Phase 4 (`BLOCKED.md`) on a PARTIAL/BLOCKED outcome.
- About to write `BLOCKED.md` on a DONE outcome.
- About to commit or stage `BLOCKED.md` — it stays uncommitted by convention.
- About to return more than 500 tokens of end-report. - About to return more than 500 tokens of end-report.
- About to run the quality phase before the spec phase is `compliant`. - About to run the quality phase before the spec phase is `compliant`.
- About to skip Phase 5 (stats file) "because mini mode". - About to skip Phase 5 (stats file) "because mini mode".
@@ -29,8 +29,8 @@ of every dispatch:
1. `CLAUDE.md` — orchestrator framing, agent role boundaries. 1. `CLAUDE.md` — orchestrator framing, agent role boundaries.
2. `design/INDEX.md` — the contract ledger and sole spine. The 2. `design/INDEX.md` — the contract ledger and sole spine. The
contracts it links are binding architectural decisions. contracts it links are binding architectural decisions.
3. `docs/journals/INDEX.md` + the latest 13 milestone-relevant per-iter files. The latest 3. `git log -3 --format=full` — full bodies of the most recent iter
entry is the current state of the project. commits; the latest entry is the current state of the project.
You do **not** open `docs/plans/<iteration>.md` or `docs/specs/<milestone>.md` You do **not** open `docs/plans/<iteration>.md` or `docs/specs/<milestone>.md`
directly. The controller has already extracted what you need from them and directly. The controller has already extracted what you need from them and
@@ -85,8 +85,8 @@ the test.
are BLAKE3-16-hex over the canonical bytes. Never any whitespace-dependent are BLAKE3-16-hex over the canonical bytes. Never any whitespace-dependent
parsing. parsing.
- **LLVM:** text IR emit, `clang` as linker. No `inkwell`, no libllvm binding. - **LLVM:** text IR emit, `clang` as linker. No `inkwell`, no libllvm binding.
- **Schema version:** `ailang/v0`. On schema changes, leave a migration note - **Schema version:** `ailang/v0`. On schema changes, leave a migration
in the JOURNAL. note in the commit body.
- **Codegen:** ADT values are boxed (`malloc(8 + 8*n)`, tag@0, fields from - **Codegen:** ADT values are boxed (`malloc(8 + 8*n)`, tag@0, fields from
offset 8). Block tracking via `current_block: String` in the emitter, set offset 8). Block tracking via `current_block: String` in the emitter, set
by `start_block()`. Never heuristics that scan the body. by `start_block()`. Never heuristics that scan the body.
+3 -2
View File
@@ -24,8 +24,9 @@ invariant in the doc comment, and you stop.
## Standing reading list ## Standing reading list
1. `CLAUDE.md`, `design/INDEX.md` — invariants (the linked contracts) the tests must protect. 1. `CLAUDE.md`, `design/INDEX.md` — invariants (the linked contracts) the tests must protect.
2. `docs/journals/INDEX.md` + the latest 13 referenced files — most recent iteration entries; they tell you what 2. `git log -3 --format=full` — full bodies of the most recent iter
shipped and is therefore worth protecting. commits; they tell you what shipped and is therefore worth
protecting.
3. `examples/*.ail.json` — the canonical fixture style. The schema is 3. `examples/*.ail.json` — the canonical fixture style. The schema is
`ailang/v0`; existing examples are authoritative. `ailang/v0`; existing examples are authoritative.
4. `crates/ail/tests/e2e.rs` — the test layout you follow. 4. `crates/ail/tests/e2e.rs` — the test layout you follow.
+4 -3
View File
@@ -35,8 +35,9 @@ decomposition; your authority ends at naming where work lands.
must preserve. Walk to the contracts the carrier flags or that the must preserve. Walk to the contracts the carrier flags or that the
spec touches; do not spec touches; do not
skim sections you know the spec does not touch. skim sections you know the spec does not touch.
3. `docs/journals/INDEX.md` and the latest entries — what just 3. `git log -5 --format=full` — full bodies of the most recent iter
shipped, so the file-map does not double-count fresh work. commits; tells you what just shipped, so the file-map does not
double-count fresh work.
4. `skills/planner/SKILL.md` — the role the recon serves. Do NOT 4. `skills/planner/SKILL.md` — the role the recon serves. Do NOT
open files under `docs/plans/`; plan files are output downstream open files under `docs/plans/`; plan files are output downstream
of recon, never input. of recon, never input.
@@ -71,7 +72,7 @@ fix or write.
2. Read the spec in full. Note every reference to a path, type, 2. Read the spec in full. Note every reference to a path, type,
function, or invariant. function, or invariant.
3. Read the standing list in order: CLAUDE.md → `design/INDEX.md` 3. Read the standing list in order: CLAUDE.md → `design/INDEX.md`
(relevant contracts) → `docs/journals/INDEX.md` + latest (relevant contracts) → `git log -5 --format=full`
`skills/planner/SKILL.md`. `skills/planner/SKILL.md`.
4. For each path or symbol the spec references, run `git grep` or 4. For each path or symbol the spec references, run `git grep` or
`Glob`+`Read` to anchor it to exact line numbers in the current `Glob`+`Read` to anchor it to exact line numbers in the current