Skip to content

feat(engine): mcVersion 2 compilers in the Rust engine (D-0020) - #263

Merged
sksizer merged 1 commit into
mainfrom
feat/mcv2-rust-compiler
Jul 16, 2026
Merged

sksizer merged 1 commit into
mainfrom
feat/mcv2-rust-compiler

Conversation

@sksizer

@sksizer sksizer commented Jul 16, 2026

Copy link
Copy Markdown
Owner

What

PR 3 of the D-0020 series (#261, #262): the Rust engine mirrors the mcVersion 2 declarative surface, keeping the two engines semantics-identical ahead of the shared-fixture v2 twins (PR 4).

  • declarative/schema_v2.rs — the JSON Schema 2020-12 subset: properties/required (optional-by-default; required entries must name declared properties)/additionalProperties, minLength/maxLength/pattern + composable format (the runtime Schema::Format widened to {format, min, max, pattern}, issues emitted in Zod's chained order), minimum/maximum, type: integer, items/minItems/maxItems, [T,"null"] unions, validated const; per-node closed keys with the same three rejection classes as the TS side (v1-spelling migration hints, the 34-keyword outside-subset list, unknown key).
  • declarative/body_v2.rs — additionalSections, the full minContains/maxContains occurrence recipe onto the repeatable machinery, hoisted nested sections, list items (checkbox | schema); v1 keys rejected with migration hints.
  • Finding.hint — Option<String>, serde-skipped when absent so existing consumers and goldens see byte-identical output; nearest-enclosing description resolution threaded through the structure/content/frontmatter walks with contract-root fallback.
  • v1 documents compile unchanged; the envelope dispatches on mcVersion; inline config contracts compile with their config's version.

Example (same document + contract as #262's demo, Rust side)

mcVersion: 2
kind: contract
description: root desc
frontmatter:
  type: object
  required: [id]
  properties:
    id: { type: string, pattern: '^D-\d{4}$', description: "the D-#### id" }
body:
  order: none
  sections:
    - section: Summary
      description: one-paragraph outcome
let contract = load_contract(yaml)?;               // v2 dispatch
let findings = contract.validate(doc, "t.md");
// frontmatter/type            hint: Some("the D-#### id")   ← field description
// structure/section-missing   hint: Some("one-paragraph outcome")
// (hint is None — and absent from JSON — wherever no description is in scope)

Gates

  • cargo test -p markdown-contract-engine: 180 unit tests + corpus harness green (up from 149; shared-corpus goldens untouched — 51 fixtures / 8 ts-only skips unchanged).
  • cargo clippy --all-targets -- -D warnings clean; cargo fmt --check clean; cargo check --workspace --all-targets clean (one test-literal hint: None touch in apps/desktop's engine map to keep the workspace compiling).
  • Envelope tests that asserted "mcVersion 2 is rejected" now assert v3 rejection (inherent to the version-set change).

Notes: this crate has no text renderer (the runner returns Findings), so the human hint: line lives on the TS side only; JSON serialization carries the field here. v2 parity fixtures for the shared corpus land in PR 4 with the corpus migration.

…y beside v1 (D-0020)

Mirrors the TS v2 surface: schema_v2 (JSON Schema 2020-12 subset — properties/
required/additionalProperties with optional-by-default, minLength/maximum/items/
integer, [T,"null"] unions, composable format on a widened Schema::Format,
validated const, closed per-node keys with the three rejection classes) and
body_v2 (additionalSections, minContains/maxContains onto the repeatable
machinery, hoisted sections, list items). Finding gains hint (serde-skipped when
absent); descriptions thread through structure/content/frontmatter walks with
nearest-enclosing resolution and a contract-root fallback. v1 documents compile
unchanged; shared-corpus goldens untouched. 180 unit tests + corpus harness
green; clippy/fmt clean.
@sksizer
sksizer merged commit 127fdf6 into main Jul 16, 2026
5 checks passed
@sksizer
sksizer deleted the feat/mcv2-rust-compiler branch July 16, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant