diff --git a/docs/specs/2026-05-21-schema-camelcase-fix.md b/docs/specs/2026-05-21-schema-camelcase-fix.md index 8f2db68..0cd369b 100644 --- a/docs/specs/2026-05-21-schema-camelcase-fix.md +++ b/docs/specs/2026-05-21-schema-camelcase-fix.md @@ -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