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,9 +1,8 @@
//! loop-recur iter 2: pin tests that the loop/recur typecheck
//! fixtures produce the expected diagnostic codes (or zero
//! diagnostics for the positive sum_to-class case). Mirrors
//! `mut_typecheck_pin.rs`; negative fixtures live as `.ail.json`
//! so the diagnostic code is the load-bearing assertion, not the
//! surface form.
//! Pin tests that the loop/recur typecheck fixtures produce the
//! expected diagnostic codes (or zero diagnostics for the positive
//! `sum_to`-class case). Mirrors `mut_typecheck_pin.rs`; negative
//! fixtures live as `.ail.json` so the diagnostic code is the
//! load-bearing assertion, not the surface form.
use ailang_check::check_workspace;
use ailang_surface::load_workspace;
@@ -29,10 +28,10 @@ fn check_fixture(fixture_name: &str) -> Vec<String> {
#[test]
fn loop_sum_to_typechecks_clean() {
// examples/loop_sum_to.ail shipped in iter-1 as the round-trip
// fixture; in iter-2 it must ALSO typecheck clean (it returned
// the synth Internal stub in iter-1). One fixture, two
// properties — no near-duplicate corpus file.
// `examples/loop_sum_to.ail` doubles as the round-trip fixture and
// the positive typecheck pin: it must typecheck without any
// diagnostic. One fixture, two properties — no near-duplicate
// corpus file.
let codes = check_fixture("loop_sum_to.ail");
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
// captures fall back to plain `ailang_rc_dec` because we
// 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,
// 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 ()
(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
(tail-do OP-NAME ARG*) ; tail-position effect
(let NAME VALUE-TERM BODY-TERM) ; binding
@@ -290,10 +290,10 @@ Parenthesised forms:
(lam (params (typed NAME TYPE)*)
(ret RETURN-TYPE)
(effects EFFECT-NAME*)?
(body TERM)) ; anonymous function (Iter 8b)
(body TERM)) ; anonymous function
(seq EFFECTFUL-TERM RESULT-TERM) ; sequence; lhs evaluated for effect
(clone TERM) ; explicit RC clone (Iter 18c.1)
(reuse-as SOURCE-TERM BODY-TERM) ; explicit reuse hint (Iter 18d.1)
(clone TERM) ; explicit RC clone
(reuse-as SOURCE-TERM BODY-TERM) ; explicit reuse hint
(loop (NAME TYPE INIT)* BODY-TERM+) ; strict iteration block (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.
Constructors are NEVER called with `app`; always use `term-ctor`.
- `tail-app` / `tail-do` mark the call as occurring in tail position
per Decision 8. Codegen lowers them to `musttail call`. Use the
tail variant whenever a recursive call is the final action of an
arm — it converts unbounded recursion into iteration. Non-tail
variants are otherwise indistinguishable in semantics.
- `tail-app` / `tail-do` mark the call as occurring in tail position;
the tag is explicit rather than inferred. Codegen lowers them to
`musttail call`. Use the tail variant whenever a recursive call is
the final action of an arm — it converts unbounded recursion into
iteration. Non-tail variants are otherwise indistinguishable in
semantics.
- `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,
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
// dispatch rule, with `AmbiguousMethodResolution` /
// `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 /
// method-completeness checks.
+3 -3
View File
@@ -76,13 +76,13 @@ fn design_md_has_no_wunschdenken() {
fn design_md_has_no_doc_archaeology() {
let d = norm(&design_corpus());
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`"),
"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"),
"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"),
"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)"),
"design/: the second per-type-print-op retirement-narrative sentence is history");
assert!(!d.contains("originally listed here as the eighth fixture, was retired"),