design: ratify form (B) prose projection (iter 20e tidy)
Family-20 tidy-iter: ailang-architect drift review surfaced DESIGN.md silence on the new prose surface as the highest-leverage gap. Decision 6 now has a 'Form (B) — human prose projection' subsection naming the lossy-vs-lossless contract, the no-parser- by-design choice, and the LLM-mediated round-trip. CLI block gained 'ail prose' and 'ail merge-prose'. No code changes. Form (B) does not weaken any Decision 6 invariant: JSON-AST remains the only hashable artefact, form (A) the canonical authoring surface, 30-production grammar unchanged. Two architect findings deferred (prompt-template lockstep test; snapshot-fixture cross-family coupling). Family 20 closes. JOURNAL queue: empty.
This commit is contained in:
@@ -9167,3 +9167,80 @@ practice the family stays as-shipped.
|
||||
validates the merge product; `merge-prose` only composes the
|
||||
prompt.
|
||||
|
||||
|
||||
## 2026-05-08 — Family-20 tidy-iter (Iter 20e)
|
||||
|
||||
Per CLAUDE.md "Tidy-iter at family boundaries" — every named iter
|
||||
family closes with a tidy-iter. `ailang-architect` ran a drift
|
||||
review of family 20 and reported three actionable items, plus two
|
||||
non-actionable observations.
|
||||
|
||||
### Architect findings
|
||||
|
||||
1. **DESIGN.md silent on form (B).** Decision 6 documents form (A)
|
||||
extensively but never names the new prose surface. The CLI
|
||||
section (`docs/DESIGN.md` "## CLI") lists `render`/`parse` but
|
||||
not `prose`/`merge-prose`. JOURNAL has the design pinning, but
|
||||
DESIGN.md is the canonical spec — this is the highest-leverage
|
||||
fix.
|
||||
2. **Prompt-template drift hazard.** `compose_merge_prose_prompt`
|
||||
in `crates/ail/src/main.rs` and the prompt block in
|
||||
`docs/PROSE_ROUNDTRIP.md` are byte-equivalent twins maintained
|
||||
by hand. No test enforces equality. Bounded — the comment in
|
||||
`main.rs` line 240–242 already names the lockstep — but real.
|
||||
3. **Snapshot-fixture coupling.** `ailang-prose/tests/snapshot.rs`
|
||||
binds prose tests to four 18-family RC fixtures. Any future
|
||||
iter touching those examples must re-render the `.prose.txt`.
|
||||
Not actionable until a real refactor forces it.
|
||||
|
||||
### Resolved this iter
|
||||
|
||||
**Item 1 — ratified.** Two edits to `docs/DESIGN.md`:
|
||||
|
||||
- New subsection at the end of Decision 6 (after Iter 14e
|
||||
refinements, before Decision 7): `### Form (B) — human prose
|
||||
projection (Family 20)`. ~50 lines documenting form (B) as the
|
||||
"display" projection Decision 6's architectural pin already
|
||||
anticipated, the lossy-vs-lossless contract, and the fact that
|
||||
form (B) has no parser by design (round-trip is LLM-mediated,
|
||||
not compiler-passed).
|
||||
- CLI block extended with `ail prose` and `ail merge-prose` lines.
|
||||
|
||||
The new subsection explicitly does NOT weaken any Decision 6
|
||||
invariant: JSON-AST remains the only hashable artefact, form (A)
|
||||
remains the canonical authoring surface, the 30-production grammar
|
||||
is unchanged, and `check`/`codegen` stay projection-agnostic.
|
||||
|
||||
### Deferred
|
||||
|
||||
**Item 2 (prompt-template lockstep)** — the existing
|
||||
`// Keep this template in lockstep with docs/PROSE_ROUNDTRIP.md`
|
||||
comment at `main.rs:240–242` is the audit trail. Adding an
|
||||
equality test would require parsing the Markdown block in the
|
||||
doc; brittle. Stays queued; will close if the next iter touching
|
||||
the prompt actually surfaces the drift.
|
||||
|
||||
**Item 3 (snapshot-fixture coupling)** — not actionable; documented
|
||||
as known consequence of cross-family snapshot binding.
|
||||
|
||||
### Family 20 final state
|
||||
|
||||
- 20a: prose renderer skeleton + `ail prose` CLI
|
||||
- 20b: infix + paren elision + doc-wrap + nested-match
|
||||
- 20c: rolled into 20a
|
||||
- 20d: `ail merge-prose` + `docs/PROSE_ROUNDTRIP.md`
|
||||
- 20e: this tidy-iter — DESIGN.md ratification
|
||||
|
||||
Three deferred polishes from 20b (let-inlining, `do io/print_int`
|
||||
→ `print` sugar, doc-wrap widow control) remain queued; all three
|
||||
need real-corpus signal to know whether the heuristic is right.
|
||||
|
||||
JOURNAL queue: empty again.
|
||||
|
||||
### Files touched this iter
|
||||
|
||||
- `docs/DESIGN.md` — Form (B) subsection in Decision 6, CLI block
|
||||
extension. ~60 lines added.
|
||||
- `docs/JOURNAL.md` — this entry.
|
||||
|
||||
No code changes. Build/test status unchanged from 20d (green).
|
||||
|
||||
Reference in New Issue
Block a user