spec: schema-camelcase-fix — expand scope to data-model.md + rustdoc layer (refs #30)
Spec amendment after plan-recon flagged four missed touch-points in the brainstorm grounding-check loop: 1. `design/contracts/data-model.md:142-147` — fenced JSON-block in the canonical data-model contract. The data-model contract IS the canonical-schema doc (INDEX.md row, ratifying test `tests/design_schema_drift.rs`); leaving it on camelCase after `ast.rs` ships kebab is a direct Honesty-Rule violation. 2. Three rustdoc strings in production source that describe the present-state schema vocabulary: `ast.rs:8`, `parse.rs:81`, `check/lib.rs:1707`. Each enumerates the rename targets in prose; left unchanged they would describe a state that no longer exists. 3. Better home for the new schema-shape pin: `design_schema_drift.rs` (not `schema_coverage.rs`). That file already operates as the data-model-contract ratifying test, already builds Term::Lam exemplars at L121-129, and uses `anchor_in_jsonc_block` to walk data-model.md fenced blocks — the proposed extension slots directly into the existing pin family. 4. Experiment-tree files (`experiments/2026-05-12-.../master/spec.md`, `rendered/*.md`, `runs/**`) carry old tags. Per Honesty-Rule analogy with docs/plans/* — these are frozen historical artefacts of the 2026-05-12 cross-model-authoring experiment and are NOT migrated. The experiment's `master/examples/*.ail.json` fixture IS migrated (live JSON the workspace loader can deserialise); surrounding prose is not. Plus an editorial fix: the fixture-occurrence count parenthetical corrected from "3" to "2" — each fixture has one `paramTypes` + one `retType`, one per line. Spec re-dispatched through `ailang-grounding-check` (Step 7.5 re-PASS). All 9 load-bearing claims ratified, with 2 negative-grep "no test pins this" ratifications openly flagged in the agent report as a Boss-override-eligible shape. Acceptance criteria renumbered to 7 (was 6). Touch-point count now: 2 serde-renames + 1 workspace.rs literal + 2 .ail.json fixtures + 1 data-model.md fenced block + 3 rustdoc strings = 9 files, all small edits. No hash-pin refresh required.
This commit is contained in:
@@ -17,7 +17,7 @@ the canonical JSON layer.
|
||||
|
||||
## Architecture
|
||||
|
||||
This is a schema-only milestone. Three layers are affected:
|
||||
This is a schema-only milestone. Four layers are affected:
|
||||
|
||||
1. **Canonical JSON tag layer.** Two `#[serde(rename = "...")]`
|
||||
attributes on `Term::Lam` in `crates/ailang-core/src/ast.rs:492,494`
|
||||
@@ -41,7 +41,42 @@ This is a schema-only milestone. Three layers are affected:
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/examples/fn_with_lambda.ail.json`
|
||||
- `crates/ailang-core/src/workspace.rs:1925-1926`
|
||||
(Verified via `grep -rn '"paramTypes"\|"retType"' --include="*.rs"
|
||||
--include="*.json"` — exhaustive list.)
|
||||
--include="*.json"` — exhaustive list. Each fixture carries
|
||||
exactly two occurrences of the two tags combined, one per line.)
|
||||
|
||||
4. **Canonical-schema contract + rustdoc layer.** Three rustdoc
|
||||
strings in production source describe the present-state schema
|
||||
(rather than implementation history); per the Honesty Rule
|
||||
(`design/contracts/honesty-rule.md`) they must read truthfully
|
||||
after the rename:
|
||||
- `crates/ailang-core/src/ast.rs:8` — module-level `//!` enumerating
|
||||
example field renames.
|
||||
- `crates/ailang-surface/src/parse.rs:81` — module-level `//!`
|
||||
mentioning `lam`'s `paramTypes` carry.
|
||||
- `crates/ailang-check/src/lib.rs:1707` — rustdoc on the InstanceMethod
|
||||
routing helper.
|
||||
|
||||
Plus the canonical data-model contract document itself, which
|
||||
ships fenced JSON blocks describing the schema verbatim:
|
||||
- `design/contracts/data-model.md:142-147` — the `Term::Lam`
|
||||
fenced-JSON schema block.
|
||||
|
||||
The data-model contract IS the canonical schema documentation
|
||||
(linked from `design/INDEX.md` row `data-model`, with ratifying
|
||||
test `crates/ailang-core/tests/design_schema_drift.rs`). Leaving
|
||||
it on the old tags after `ast.rs` ships kebab would be a direct
|
||||
Honesty-Rule violation.
|
||||
|
||||
The experiment-tree under
|
||||
`experiments/2026-05-12-cross-model-authoring/` (master spec,
|
||||
renderings, run transcripts) carries the old tags in multiple
|
||||
places. These are frozen historical artefacts of the 2026-05-12
|
||||
cross-model-authoring experiment — analogous to `docs/plans/*.md`
|
||||
under the Honesty Rule — and are NOT migrated by this milestone.
|
||||
The experiment's `master/examples/fn_with_lambda.ail.json` IS
|
||||
migrated (it is a checked-in JSON fixture the workspace loader
|
||||
could deserialise); the surrounding prose documents and run
|
||||
transcripts are not.
|
||||
|
||||
**Hash blast radius is zero on pinned modules.** None of the
|
||||
`.ail` modules pinned in `crates/ailang-core/tests/hash_pin.rs`
|
||||
@@ -180,20 +215,27 @@ the surrounding fixture content is untouched.
|
||||
| Component | Change |
|
||||
|-----------|--------|
|
||||
| `crates/ailang-core/src/ast.rs:492,494` | Two `#[serde(rename)]` strings: `"paramTypes" → "param-types"`, `"retType" → "ret-type"`. |
|
||||
| `crates/ailang-core/src/workspace.rs:1925-1926` | In-source JSON-literal in a test: same two key renames. |
|
||||
| `examples/test_loop_binder_captured_by_lambda.ail.json` | Same two key renames (verified 3 occurrences combined of the two tags via `grep -c`). |
|
||||
| `experiments/2026-05-12-cross-model-authoring/master/examples/fn_with_lambda.ail.json` | Same two key renames (verified 3 occurrences combined). |
|
||||
| `crates/ailang-surface/src/{print,parse}.rs` | **No change.** Form-A never used these tag names. |
|
||||
| `crates/ailang-core/src/ast.rs:8` | Module-level `//!` rustdoc — substitute the new tag spellings in the example list. |
|
||||
| `crates/ailang-surface/src/parse.rs:81` | Module-level `//!` rustdoc — substitute the new tag spelling. |
|
||||
| `crates/ailang-check/src/lib.rs:1707` | `///` rustdoc — substitute the new tag spellings. |
|
||||
| `crates/ailang-core/src/workspace.rs:1925-1926` | In-source JSON-literal in `ct1_validator_walks_lam_embedded_types` (function at L1911): same two key renames. |
|
||||
| `design/contracts/data-model.md:142-147` | Fenced JSON-block in the canonical data-model contract: same two key renames. |
|
||||
| `examples/test_loop_binder_captured_by_lambda.ail.json` | Same two key renames (2 occurrences total of the two tags, one per line). |
|
||||
| `experiments/2026-05-12-cross-model-authoring/master/examples/fn_with_lambda.ail.json` | Same two key renames (2 occurrences total). |
|
||||
| `crates/ailang-surface/src/{print,parse}.rs` (code) | **No change.** Form-A never used these tag names — only `parse.rs:81` rustdoc above. |
|
||||
| `crates/ailang-core/tests/hash_pin.rs` | **No change.** No pinned `.ail` module contains `(lam ...)` (verified per-file). |
|
||||
|
||||
Historic documents (`docs/plans/2026-05-10-23.3-...`,
|
||||
`docs/plans/2026-05-09-22b3-monomorphisation.md`,
|
||||
`docs/plans/2026-05-09-22c-user-class-e2e.md`,
|
||||
`docs/plans/24.2.md`) embed the old tag names inside example JSON
|
||||
blocks. Per the Honesty Rule
|
||||
(`design/contracts/honesty-rule.md`), historic plan documents
|
||||
describe the state at the time of writing — not the present state —
|
||||
and are NOT migrated.
|
||||
Historic / frozen documents NOT migrated (per Honesty Rule
|
||||
analogue: these describe state at the time of writing, not the
|
||||
present state):
|
||||
- `docs/plans/2026-05-10-23.3-...md`,
|
||||
`docs/plans/2026-05-09-22b3-monomorphisation.md`,
|
||||
`docs/plans/2026-05-09-22c-user-class-e2e.md`, `docs/plans/24.2.md`
|
||||
— embed old tag names in example JSON blocks.
|
||||
- `experiments/2026-05-12-cross-model-authoring/master/spec.md`,
|
||||
`experiments/2026-05-12-cross-model-authoring/rendered/*.md`,
|
||||
and any `experiments/2026-05-12-cross-model-authoring/runs/**`
|
||||
transcripts — frozen artefacts of the 2026-05-12 experiment.
|
||||
|
||||
## Data flow
|
||||
|
||||
@@ -257,12 +299,20 @@ The milestone is GREEN if:
|
||||
- `cargo test -p ailang-surface --test round_trip` passes — confirms
|
||||
Form-A is untouched.
|
||||
- A single targeted assertion is added: a fresh test in
|
||||
`crates/ailang-core/tests/schema_coverage.rs` (or equivalent
|
||||
existing schema-shape test) verifies that
|
||||
`crates/ailang-core/tests/design_schema_drift.rs` verifies that
|
||||
`serde_json::to_value(&Term::Lam{...})` emits the keys
|
||||
`"param-types"` and `"ret-type"` (and NOT the old camelCase). The
|
||||
test pins the new schema layer concretely so a future regression
|
||||
cannot silently flip the rename string back.
|
||||
`"param-types"` and `"ret-type"` (and NOT the old camelCase),
|
||||
AND extends the existing fenced-block anchor sweep to assert
|
||||
that `design/contracts/data-model.md` contains the new tag
|
||||
spellings inside the `Term::Lam` fenced JSON block. The home
|
||||
is `design_schema_drift.rs` (not `schema_coverage.rs`, which is
|
||||
a corpus-coverage walker) because that file already operates as
|
||||
the data-model contract's ratifying test, already builds
|
||||
`Term::Lam` exemplars (L121-129), and already pins the
|
||||
`data-model.md` ↔ schema pairing via the
|
||||
`anchor_in_jsonc_block` helper. The two assertions pin the
|
||||
schema layer and the contract document together so a future
|
||||
regression cannot silently flip the rename string back.
|
||||
- `cargo build --workspace` produces no new clippy warnings.
|
||||
|
||||
No bench-regression check is required: the rename is a string
|
||||
@@ -272,15 +322,19 @@ literal swap at compile time with no runtime cost path.
|
||||
|
||||
1. Tag-rename change in `crates/ailang-core/src/ast.rs:492,494` is
|
||||
landed and observable in serialisation output.
|
||||
2. Three call-sites (`workspace.rs` + two `.ail.json` fixtures)
|
||||
carry the new tag names verbatim.
|
||||
3. `cargo test --workspace` is GREEN.
|
||||
4. `cargo test -p ailang-surface --test round_trip` is GREEN
|
||||
2. All four code call-sites (`workspace.rs` JSON-literal + two
|
||||
`.ail.json` fixtures + `design/contracts/data-model.md` fenced
|
||||
JSON block) carry the new tag names verbatim.
|
||||
3. All three rustdoc strings (`ast.rs:8`, `parse.rs:81`,
|
||||
`check/lib.rs:1707`) describe the new tag spellings.
|
||||
4. `cargo test --workspace` is GREEN.
|
||||
5. `cargo test -p ailang-surface --test round_trip` is GREEN
|
||||
(Form-A unchanged invariant).
|
||||
5. A new schema-shape assertion test fires GREEN with the new tag
|
||||
names and would fire RED with the old ones.
|
||||
6. The commit body references `closes #30`. No `docs/plans/*.md`
|
||||
files are mutated.
|
||||
6. The new `design_schema_drift.rs` assertion(s) fire GREEN with
|
||||
the new tag names and would fire RED with the old ones.
|
||||
7. The commit body references `closes #30`. No `docs/plans/*.md`,
|
||||
`experiments/.../master/spec.md`, `experiments/.../rendered/*`,
|
||||
or `experiments/.../runs/*` files are mutated.
|
||||
|
||||
## Feature-acceptance gate
|
||||
|
||||
|
||||
Reference in New Issue
Block a user