From 55ce6d0d7098719ecb7d404487e3c18195ddc11f Mon Sep 17 00:00:00 2001 From: Brummel Date: Thu, 21 May 2026 12:45:51 +0200 Subject: [PATCH] =?UTF-8?q?spec:=20schema-camelcase-fix=20=E2=80=94=20expa?= =?UTF-8?q?nd=20scope=20to=20data-model.md=20+=20rustdoc=20layer=20(refs?= =?UTF-8?q?=20#30)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- docs/specs/2026-05-21-schema-camelcase-fix.md | 108 +++++++++++++----- 1 file changed, 81 insertions(+), 27 deletions(-) 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