design: 20-family tidy-iter — refresh Data model + ecosystem inventory
Architect drift review after Family 20 surfaced four items; (1) and
(2) are doc drift fixed here, (3) and (4) are recorded as acceptable.
DESIGN.md changes:
- Data model section rewritten from "Data model (MVP)" claiming
only fn/const exist to "Data model" reflecting all three Def
kinds. Added the missing schema fields the architect named:
`tail` flag on app/do, the `seq` / `clone` / `reuse-as` / `letrec`
terms, `paramModes` / `retMode` on Type::Fn, `suppress` on FnDef,
`drop-iterative` on TypeDef, `args` on Type::Con, `vars` on
TypeDef. Each additive field's hash-stable serialisation is
called out once at the top so individual mentions stay terse.
`Suppress`, `ParamMode`, `Literal`, `Pattern` get their own
sub-blocks.
- Pipeline diagram now shows `--alloc=gc` (links libgc;
transitional) and `--alloc=rc` (emits ailang_rc_inc / _dec;
canonical) as two backends sharing the same MIR.
- Ecosystem inventory gained a "Surface forms" bullet for
ailang-surface (Iter 14c, lossless Form-A printer/parser) and
ailang-prose (Family 20, lossy Form-B projection). CLI bullet
now lists parse, render, prose, merge-prose.
JOURNAL entry records the architect findings, the resolutions for
items (1) and (2), and the acceptable-drift status of (3)
FnDef::synthetic factor-out (defer to next schema-additive
FnDef field) and (4) linearity.rs spurious warning (not
corpus-triggered).
Pure documentation iter — no code changes. 288 workspace tests
unchanged and green.
This commit is contained in:
+126
-3
@@ -9638,6 +9638,129 @@ that always works without a tool-use-capable client.
|
||||
### Family / arc state
|
||||
|
||||
20f closes the prose-roundtrip arc for now. JOURNAL queue is
|
||||
empty again. Tidy iter for 20a / b / d / e / f together can wait
|
||||
until the next family closes — the architect drift-review
|
||||
discipline applies as before.
|
||||
empty again. The 20-family tidy-iter follows immediately per
|
||||
CLAUDE.md ("the tidy-iter is non-optional, every named family
|
||||
closes with one"); the previous note here ("can wait") was
|
||||
incorrect and has been superseded by the actual tidy below.
|
||||
|
||||
## 2026-05-08 — 20-family tidy-iter (DESIGN.md refresh)
|
||||
|
||||
### Why
|
||||
|
||||
Per CLAUDE.md, every named iter family closes with a tidy-iter:
|
||||
run `ailang-architect`, resolve each item (fix the drift, ratify
|
||||
in DESIGN.md, or record in JOURNAL why it is acceptable). Family
|
||||
20 — 20a, 20b, 20d, 20e, 20f — added a whole new surface
|
||||
(`ailang-prose`), a CLI subcommand pair (`ail prose` /
|
||||
`ail merge-prose`), an embedded Form-A spec, and the drift-test
|
||||
trip-wire. The architect surfaced four items.
|
||||
|
||||
### Architect findings (verbatim, abridged)
|
||||
|
||||
1. **`docs/DESIGN.md` "Data model (MVP)" block stale** —
|
||||
missing: `tail` flag on `app`/`do`, `seq`, `clone`,
|
||||
`reuse-as`, `let-rec`, `paramModes`/`retMode` on `fn`,
|
||||
`suppress` on `FnDef`, `drop_iterative` on `TypeDef`,
|
||||
`Type::Con.args`, `TypeDef.vars`. Pipeline diagram still
|
||||
said "links libgc" only — did not mention `--alloc=rc`.
|
||||
The deferral was already noted in 19a-arc tidy.
|
||||
2. **Project ecosystem inventory missing `ailang-surface` and
|
||||
`ailang-prose`** — the section's own rule says new tools
|
||||
are added "as soon as they are established"; both crates
|
||||
are well past that threshold (14c and 20a respectively).
|
||||
`ail prose` and `ail merge-prose` were also missing from
|
||||
the CLI bullet.
|
||||
3. **`FnDef { suppress: vec![] }` synthesis fan-out at 45
|
||||
sites** — `ailang-codegen` plus `ailang-core::desugar`
|
||||
alone has 16. 19a-arc tidy noted 7 and deferred. Each
|
||||
schema-additive `FnDef` / `Type::Fn` field hits every site;
|
||||
a `FnDef::synthetic(...)` constructor is the absorbing fix.
|
||||
4. **`linearity.rs` known debt (L117–125)** — deeply-nested
|
||||
match on a sub-binder produces a spurious
|
||||
`over-strict-mode` warning. Not fired by current corpus;
|
||||
module doc records the gap. Acceptable.
|
||||
|
||||
### Resolutions
|
||||
|
||||
**(1) and (2)** — fixed in this tidy. `docs/DESIGN.md`:
|
||||
|
||||
- **Data model section rewritten end-to-end.** Was titled
|
||||
"Data model (MVP)" with stale `MVP only fn and const`; now
|
||||
"Data model" reflecting that all three kinds (`fn`, `const`,
|
||||
`type`) are real surface forms. Added every additive field
|
||||
documented in `crates/ailang-core/src/ast.rs` with the
|
||||
schema-additive `skip_serializing_if` rationale called out
|
||||
once at the top so each individual mention can stay terse.
|
||||
The `Suppress`, `ParamMode`, `Literal`, and `Pattern`
|
||||
sub-schemas now have their own blocks.
|
||||
- **Pipeline diagram extended.** Now shows `--alloc=gc` (links
|
||||
libgc; transitional) and `--alloc=rc` (emits
|
||||
`ailang_rc_inc` / `_dec`; canonical) as two backends sharing
|
||||
the same MIR. The 18a–18d additions (`Term::Clone`,
|
||||
`Term::ReuseAs`) get a sentence pointing at where they
|
||||
materialise under `--alloc=rc`.
|
||||
- **Ecosystem inventory** gained a "Surface forms" bullet
|
||||
between Language core and CLI, naming `ailang-surface`
|
||||
(Iter 14c) as the lossless Form-A printer/parser fixed by
|
||||
Decision 6 with `parse ∘ print = id` as gating contract,
|
||||
and `ailang-prose` (Family 20) as the lossy Form-B
|
||||
projection with no parser whose re-integration goes through
|
||||
`docs/PROSE_ROUNDTRIP.md`. The CLI bullet now lists
|
||||
`parse`, `render`, `prose`, `merge-prose`.
|
||||
|
||||
**(3) `FnDef::synthetic(...)` constructor** — *deferred, not
|
||||
addressed in this tidy.* Reason: the right factor-out shape is
|
||||
not yet obvious. Most existing call sites differ on more than
|
||||
just `suppress` — they have to compute `params`, build a
|
||||
`Type::Fn`, etc. — so a one-arg constructor saves nothing; the
|
||||
useful constructor is roughly `FnDef::new(name, ty, params,
|
||||
body)` with `doc: None, suppress: vec![]` defaults. That is a
|
||||
real change in 45 sites and should land as its own iter when the
|
||||
schema next grows a `FnDef` field (forcing the touch anyway).
|
||||
Recorded in the JOURNAL queue.
|
||||
|
||||
**(4) `linearity.rs` sub-binder spurious warning** —
|
||||
*acceptable, recorded.* The warning fires on a synthetic shape
|
||||
that the current corpus does not produce; module doc names the
|
||||
gap; an actual customer-impact trigger would warrant a fix, not
|
||||
preemptive work. Status quo holds.
|
||||
|
||||
### Acceptable drift summary
|
||||
|
||||
- `FnDef::synthetic(...)` factor-out — deferred until the next
|
||||
schema-additive `FnDef` field (rationale: existing fan-out
|
||||
pattern works, change is large but mechanical, and the cost
|
||||
is amortised by piggybacking on the next forced touch).
|
||||
- `linearity.rs` deeply-nested-match-on-sub-binder spurious
|
||||
warning — accepted (not corpus-triggered; cost of fix
|
||||
exceeds cost of the false positive at this scale).
|
||||
|
||||
### What this tidy does NOT do
|
||||
|
||||
- No code changes. Pure documentation iter.
|
||||
- No new tests. Existing 288 workspace tests stay green.
|
||||
- No DESIGN.md content removed. The pre-tidy "Data model (MVP)"
|
||||
block is replaced rather than amended because it had grown
|
||||
factually incorrect; the historical context lives in
|
||||
`git log` and in the iter-by-iter JOURNAL entries that
|
||||
introduced each schema field.
|
||||
|
||||
### JOURNAL queue (post-tidy)
|
||||
|
||||
- **`FnDef::synthetic(...)` factor-out** — to be done when the
|
||||
next schema-additive `FnDef` field forces the touch anyway.
|
||||
- **Deferred richer integration paths** (from 20f): tool-use
|
||||
schemas, MCP server, LSP. All additive over the static-prompt
|
||||
round-trip; pick when prioritised.
|
||||
- **Boehm retirement** — `--alloc=gc` is transitional;
|
||||
`--alloc=rc` is canonical. Boehm-side scaffolding to be
|
||||
removed once the rc backend covers the full corpus.
|
||||
- **Family 21+** (typeclasses, polymorphic ADTs at runtime,
|
||||
pattern-binding generalisation) — long-horizon language work.
|
||||
|
||||
### Family / arc state
|
||||
|
||||
The 20-family is now formally closed with this tidy. Codebase
|
||||
is in good form: no architecturally load-bearing drift, all
|
||||
tests green, two minor items recorded as acceptable. The next
|
||||
iter can be a feature pick from the queue.
|
||||
|
||||
Reference in New Issue
Block a user