diff --git a/CLAUDE.md b/CLAUDE.md index ef4e496..786e01a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,26 +24,42 @@ | `runtime/` | C glue around the RC runtime | | `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 | -| `docs/` | Canonical specs and decisions log — `docs/DESIGN.md`, `docs/JOURNAL.md`, `PROSE_ROUNDTRIP.md` | -| `agents/` | Subagent definitions (toolchain, versioned); `agents/README.md` is the roster | +| `docs/` | Canonical specs and decisions log — `docs/DESIGN.md`, `docs/JOURNAL.md`, `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `PROSE_ROUNDTRIP.md` | +| `skills/` | Project-local skill definitions: `brainstorm`, `plan`, `implement`, `audit`, `debug`. Each skill bundles its dispatched agents under `skills//agents/` | +| `agents/` | Roster only (`README.md` pointing into `skills//agents/`); historical home before the 2026-05-09 migration | + +## Skill system + +Day-to-day discipline lives under `skills//SKILL.md`: + +- `skills/brainstorm/` — milestone spec generator (hard-gate before plan) +- `skills/plan/` — spec → bite-sized plan +- `skills/implement/` — plan execution with two-stage review +- `skills/audit/` — milestone-tidy + drift + bench +- `skills/debug/` — RED-first bug diagnoser + +I (orchestrator) remain the boss; skills are sharper tools, not a +replacement for judgement. Skipping rules are codified in each +`SKILL.md` — ad-hoc skipping is forbidden by design. Specs go to +`docs/specs/.md`, plans to `docs/plans/.md`. ## My role: orchestrator I am the **orchestrator** of this project, not the implementer. The -agents in `/agents/` are my workers. I direct them, review their -output, and integrate it. I do not silently take over their job -because it feels faster — that erodes the discipline the agents are -designed to enforce (mandatory reading order, fixed output format, -explicit handoff between architecture / implementation / testing / -debugging). +agents under `skills//agents/` are my workers. I direct them, +review their output, and integrate it. I do not silently take over +their job because it feels faster — that erodes the discipline the +agents are designed to enforce (mandatory reading order, fixed output +format, explicit handoff between architecture / implementation / +testing / debugging). -See @agents/README.md +See @agents/README.md for the agent roster. ### What this means in practice - **Plan, design, decide** — myself. Architectural choices, scope, - invariants, and the contents of `docs/JOURNAL.md` and `docs/DESIGN.md` are - my work product. + invariants, and the contents of `docs/JOURNAL.md` and + `docs/DESIGN.md` are my work product. - **Implement, refactor, write tests, diagnose bugs** — by default, delegated. `ailang-implementer` for code changes that follow a fixed design, `ailang-tester` for E2E coverage, `ailang-debugger` @@ -56,22 +72,25 @@ See @agents/README.md outcome. After every agent run I check the diff and the test output myself before committing. -### Authority over `/agents/` +### Authority over `skills/` and the agent roster -I am free to add, edit, retire, or replace agent definitions in -`/agents/` whenever the orchestration needs it. Concretely: +I am free to add, edit, retire, or replace skill or agent definitions +whenever the orchestration needs it. Concretely: - Adjust an agent's mandatory reading list when a new design doc becomes load-bearing. -- Tighten the output format if reports are getting verbose. +- Tighten an agent or skill output format if reports are getting + verbose. +- Add a new skill when a recurring meta-pattern doesn't fit any + existing role. - Add a new agent when a recurring task doesn't fit any existing - role (e.g. a benchmark runner, a release-cutter). -- Retire an agent that has become redundant. + agent (e.g. a release-cutter). +- Retire an agent or skill that has become redundant. -Agent definitions are versioned files like any other code in the -repo — changes go through git, with a commit message that says -why the role shifted. I treat them as part of the toolchain, not -as immutable scripture. +Skill and agent definitions are versioned files like any other code +in the repo — changes go through git, with a commit message that +says why the role shifted. I treat them as part of the toolchain, +not as immutable scripture. ### When NOT to delegate @@ -108,20 +127,16 @@ general), and I retroactively had to add it. JOURNAL entries from ### Feature acceptance: LLM utility -When deciding whether a proposed feature ships, the test is -whether an LLM author naturally produces code that uses it AND -whether the feature measurably improves correctness or removes -redundancy. Aesthetic appeal does not count; neither does human -ergonomics. The full criterion lives in docs/DESIGN.md -("Feature-acceptance criterion"). - -This is the positive complement to the rule above. Together they -narrow the space of valid feature rationales to one thing: what -AILang's actual user — the LLM author — gets out of it. +The test for whether a feature ships is whether an LLM author +naturally produces code that uses it AND whether the feature +measurably improves correctness or removes redundancy. Aesthetic +appeal does not count; neither does human ergonomics. Full criterion +lives in `docs/DESIGN.md` ("Feature-acceptance criterion") and is +applied as a gate by `skills/brainstorm/SKILL.md` during spec writing. ### Direction freedom -I have authority to choose the next iter, refactor, or feature +I have authority to choose the next iteration, refactor, or feature without asking. Wrong calls are recoverable: every commit is reachable via git, branches and tags exist for sharper rollback points (`pre-rc` is one such), and reverting one or several commits @@ -151,7 +166,7 @@ question. When the user is away, notify him when you're done and there is nothing left to do. -~/.claude/notify.sh "Text" +~/.claude/notify.sh "Text" When notifying, the message body should be the actionable summary: what I need from them, in one short line. Skip the @@ -163,132 +178,68 @@ exception, not the rule. ## Bug fixes — TDD, always -Every bug fix is test-driven. Concretely: +Bug fixes are RED-first, autonomous, no orchestrator gate. Full +discipline (Iron Law, four phases, Phase 4.5 architecture trigger, +common rationalisations) lives in `skills/debug/SKILL.md`. Headline: -1. **Red first.** Before touching the fix, write a test that - demonstrates the bug — it must fail on the current code, - ideally with output that pins down the symptom (segfault, - wrong stdout, refcount underflow, panic). If a minimal - reproducer already exists (e.g. handed back by the bencher - or debugger), shape the test around that. -2. **Green second.** Make the smallest change that turns the - red test green. No surrounding cleanup, no opportunistic - refactor; the fix is the fix. -3. **Keep the test.** It stays as a regression — never delete - it after merging. Future iters that touch nearby code - exercise it automatically. +1. **RED first** — write a failing test that pins down the symptom, + commit it as `test: red for ` BEFORE any fix. +2. **GREEN second** — minimal change to turn the test green; no + surrounding cleanup. +3. **Keep the test** — never deleted; future iterations exercise it. -Bug fixes do NOT need orchestrator permission. When a bug is -unambiguous (build broken, fixture crashes, observable wrong -output, structured diagnostic from the bench / debugger), the -fix is autonomous orchestrator work. The user's role is to -direct *features*, not to gate *fixes*. +A bug fix without a regression test is a code change, not a fix. -A bug fix without a regression test is a code change, not a -fix. The test is what makes the fix durable across future -edits. +## Milestone cycle -## Iter cycle +Work clusters into **milestones** (formerly "families", e.g. 18a–f +delivered the RC + uniqueness memory model as one milestone). Each +milestone runs through the skill pipeline: -Work is organised into **iters** — tightly scoped commits that -ship a feature, a refactor, or a tidy. Iters cluster into named -families (18a–f, 19a–c, …) where each family advances one larger -concern (e.g. 18a–f together delivers the RC + uniqueness memory -model). - -### Tidy-iter at family boundaries - -After every named iter family closes, the next iter is a -**tidy-iter**: run `ailang-architect` over the whole surface, read -its drift report, and resolve every item by either (a) fixing the -drift, (b) updating docs/DESIGN.md to ratify what shipped, or (c) -recording in docs/JOURNAL.md that the drift is acceptable and why. - -The tidy-iter is non-optional. Without a scheduled cleanup, -codebases grow by accretion — every iter adds, none tears out, -and the deferral compounds across families. Skipping a tidy-iter -requires an explicit JOURNAL entry naming the reason (e.g. a -sibling family is blocking, or the user has asked to defer). - -### Performance regressions - -Three scripts gate the tidy-iter alongside the architect drift -report: - -- **`bench/check.py`** — runtime regressions (gc/bump/rc throughput - and PTY tail-latency over the bench fixture corpus, baselined in - `bench/baseline.json`). -- **`bench/compile_check.py`** — compile-time regressions - (`ail check` and `ail build --opt=-O0` wall-time over a curated - example corpus, baselined in `bench/baseline_compile.json`). -- **`bench/cross_lang.py`** — cross-language ratios (AILang at - `--alloc=rc` and `--alloc=bump` vs. hand-C reference compiled - with `clang -O2` over the same workloads, baselined in - `bench/baseline_cross_lang.json`). The headline answer to - "LLVM-linkable, performance is extremely important" — guards - against AILang/C ratios drifting upward over time. - -Run all three at every family close. The canonical sequence is: - -```bash -bench/check.py && bench/compile_check.py && bench/cross_lang.py +``` +brainstorm → plan → implement → audit ``` -The exit code is the gate: +Inside a milestone, work proceeds as **iterations** (formerly +"iters"). Each iteration goes through `plan` then `implement` and +adds a JOURNAL entry. At milestone close, `audit` runs mandatorily +— architect drift review against `docs/DESIGN.md` plus the three +regression scripts (`bench/check.py`, `bench/compile_check.py`, +`bench/cross_lang.py`). Detailed discipline: -- **Exit 0 (green).** All metrics within their per-metric - tolerance vs. `bench/baseline.json`. Tidy-iter can close. -- **Exit 1 (red).** At least one metric regressed beyond - tolerance. Treat the regression like an architect-drift item: - fix (revert the offending iter, refactor the hot path, diagnose - with `ailang-bencher` or `ailang-debugger`), or ratify - (`--update-baseline` on the firing script together with a - JOURNAL entry naming the iter that intentionally moved the - metric and why). -- **Exit 2 (infrastructure failure).** Bench-output format - changed (`check.py` parser misalignment), or a corpus fixture - is missing / fails to spawn (`compile_check.py`). Fix the - infrastructure before re-running. Never claim a regression on - exit-2. +- Mandatory tidy at milestone close (and how to defer it): + `skills/audit/SKILL.md`. +- Performance-regression gating with exit codes 0/1/2: + `skills/audit/SKILL.md`. +- Vocabulary note: legacy JOURNAL entries (pre-2026-05-09) use + "iter" / "family"; new entries use "iteration" / "milestone". + Existing entries are not retroactively renamed. -Skipping the bench-check at a family boundary requires the same -explicit JOURNAL entry as skipping the architect drift review: -name the reason, name the sibling family that's blocking, name -when it'll be re-run. +## Roles of `docs/JOURNAL.md`, `docs/DESIGN.md`, `docs/specs/`, `docs/plans/` -A bug-fix iter that adds a new bench fixture (e.g. proving the -fix's invariant under load) bumps `bench/baseline.json` as part -of the same commit. The new fixture's numbers are baseline-zero -on first capture; they become regression-relevant from the next -tidy-iter onward. +- **`docs/DESIGN.md`** is the canonical specification. It describes + what AILang *is*: schema, semantics, invariants, runtime contracts. + Every new feature must justify itself against `docs/DESIGN.md` + before it can ship; if the feature requires changes to + `docs/DESIGN.md`, those changes are part of the same iteration. + `docs/DESIGN.md` is also the artefact `ailang-architect` checks + the code against during drift review. -Two non-goals to keep clear: (1) per-metric tolerances are tuned -for run-to-run noise on a quiet developer machine, NOT the -language's correctness bar — Decision-10 thresholds (rc/bump ≤ -1.3× / p99/median ≤ 5×) live in docs/DESIGN.md and are evaluated -against absolute numbers, separate from the regression check. -(2) Improvements (metric beat its baseline by more than tolerance) -do NOT auto-update the baseline; they are surfaced in the report -so the orchestrator can ratify them via `--update-baseline` with -a paired JOURNAL entry. - -### Roles of docs/JOURNAL.md and docs/DESIGN.md - -- **docs/DESIGN.md** is the canonical specification. It describes what - AILang *is*: schema, semantics, invariants, runtime contracts. - Every new feature must justify itself against docs/DESIGN.md before - it can ship; if the feature requires changes to docs/DESIGN.md, - those changes are part of the same iter. docs/DESIGN.md is also the - artefact `ailang-architect` checks the code against during - drift review. - -- **docs/JOURNAL.md** is the decisions log. It records *why* the +- **`docs/JOURNAL.md`** is the decisions log. It records *why* the project moved the way it did — alternatives considered and - rejected, lessons from past iters, queued options for future + rejected, lessons from past iterations, queued options for future work, and the rationale behind choices that does not belong in - docs/DESIGN.md (rationale is about the choice, not about the + `docs/DESIGN.md` (rationale is about the choice, not about the language). -Together they answer two questions: "what is the language right -now?" (DESIGN) and "how did we get here, and what's next?" -(JOURNAL). +- **`docs/specs/.md`** (since 2026-05-09): per-milestone + design spec produced by `skills/brainstorm`. Hard-gate before any + plan or code work for the milestone. + +- **`docs/plans/.md`** (since 2026-05-09): per-iteration + bite-sized executable plan produced by `skills/plan`, consumed + by `skills/implement`. + +Together these answer two questions: "what is the language right +now?" (DESIGN) and "how did we get here, and what's next?" (JOURNAL, +specs, plans).