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
@@ -1,6 +1,6 @@
---
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
---
@@ -33,15 +33,14 @@ Read these before doing anything else, in this order:
procedure lives in `skills/boss/SKILL.md`; the notify is
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).
3. `docs/journals/INDEX.md` plus the last 13 per-iter journal
files it points at — recent state of the project.
3. `git log -5 --format=full` — full bodies of the last few iter /
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**
(Iron Law, per-task sub-status table, common rationalisations).
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
You receive from the Boss-Orchestrator:
@@ -49,7 +48,7 @@ You receive from the Boss-Orchestrator:
| Field | Content |
|-------|---------|
| `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` |
| `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` |
@@ -57,21 +56,21 @@ You receive from the Boss-Orchestrator:
| `constraint` | (mini only) `"minimal fix, no surrounding cleanup"` |
You produce on return: the fixed-format end-report (see Output format),
plus an unstaged working tree containing all code edits, the per-iter
journal file, and the stats file. You do NOT touch
`docs/journals/INDEX.md`, you do NOT commit anything, and you do NOT
push anything — all of those are Boss-side.
plus an unstaged working tree containing all code edits and the stats
file. On `PARTIAL` or `BLOCKED` outcome you also write `BLOCKED.md` at
the repo root carrying the diagnostic. You do NOT commit anything, and
you do NOT push anything — all of those are Boss-side.
## 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.
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.
NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN.
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
@@ -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
getting the tree clean before re-dispatch.
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;
nobody will reset to it. Discarding bad iter work is done via
`git checkout -- .` on the working tree by the Boss, not by
@@ -153,7 +152,8 @@ upstream:
- `DONE` — implementer-phase work complete, GREEN test passes,
changes sit in the working tree. Proceed to 2.2 (spec check).
- `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
workspace). Re-attempt the phase with expanded context. Re-loop
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
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,
not the iter's plan date). Template:
**Skip this phase on `DONE`.** On `DONE` the end-report carries
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
# iter <iter_id> — <one-line title>
# BLOCKED — iter <iter_id>
**Date:** YYYY-MM-DD
**Started from:** <start_sha>
**Status:** DONE | PARTIAL | BLOCKED
**Status:** PARTIAL | BLOCKED
**Tasks completed:** <N> of <total>
## Summary
<1-paragraph summary; the Boss may rewrite this section before commit>
## Per-task notes
## What ran
- iter <iter_id>.1: <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>
## Blocked detail
<only if BLOCKED / PARTIAL: task N, reason from the sub-status table,
worker's verbatim BLOCKED text, suggested next step>
<aggregated DONE_WITH_CONCERNS lines, one per task; omit section if empty>
## Files touched
<paths from `git diff --name-only HEAD`, grouped if helpful>
## Stats
bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json
<paths from `git diff --name-only HEAD`>
```
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
@@ -283,19 +279,20 @@ The file goes into the working tree (Write tool). Do NOT commit.
### Phase 6 — Return end-report
Compose the end-report per Output format below. Do NOT commit
anything. Do NOT push. Do NOT touch `docs/journals/INDEX.md`. The
working tree is dirty with all the iter's output; the Boss inspects
and commits.
anything. Do NOT push. The working tree is dirty with all the iter's
output (and `BLOCKED.md` if PARTIAL/BLOCKED); the Boss inspects and
commits.
## Status protocol
The agent returns exactly one of:
- `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
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
0 or the first task failed irrecoverably).
- `NEEDS_CONTEXT` — the carrier from the Boss was missing required
@@ -316,12 +313,12 @@ Tasks completed: <N> of <total>
- <one-line task description 2>
...
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)
Files touched: <count from `git diff --name-only HEAD | wc -l`>
Tests: <count> green, <count> red
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>
Reason: context-exhausted | review-loop-exhausted | worker-blocked | spec-ambiguous | infra
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. |
| "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. |
| "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`. |
| "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. |
| "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 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. |
| "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. |
@@ -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 switch -c` or `git switch` to a non-main branch.
- About to run `git reset` or `git revert`.
- About to edit `docs/journals/INDEX.md`.
- 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 run the quality phase before the spec phase is `compliant`.
- 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.
2. `design/INDEX.md` — the contract ledger and sole spine. The
contracts it links are binding architectural decisions.
3. `docs/journals/INDEX.md` + the latest 13 milestone-relevant per-iter files. The latest
entry is the current state of the project.
3. `git log -3 --format=full` — full bodies of the most recent iter
commits; the latest entry is the current state of the project.
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
@@ -85,8 +85,8 @@ the test.
are BLAKE3-16-hex over the canonical bytes. Never any whitespace-dependent
parsing.
- **LLVM:** text IR emit, `clang` as linker. No `inkwell`, no libllvm binding.
- **Schema version:** `ailang/v0`. On schema changes, leave a migration note
in the JOURNAL.
- **Schema version:** `ailang/v0`. On schema changes, leave a migration
note in the commit body.
- **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
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
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
shipped and is therefore worth protecting.
2. `git log -3 --format=full` — full bodies of the most recent iter
commits; they tell you what shipped and is therefore worth
protecting.
3. `examples/*.ail.json` — the canonical fixture style. The schema is
`ailang/v0`; existing examples are authoritative.
4. `crates/ail/tests/e2e.rs` — the test layout you follow.