v0.1.1 — Type system + validation foundation
Make the schema artifacts spec/tier1.schema.json and spec/recipe.schema.json the active source of truth for plugin types and runtime validation, replacing the ad-hoc TypeScript types in src/types/config.ts. This is the load-bearing implementation step for the schema-as-primitive architectural commitment — the v0.1 schema spec becomes the contract any producer must satisfy, not just the bundled engine.
Status
Section titled “Status”✅ Done (2026-05-04). 27 unit tests + 5 validation E2E tests passing. AJV (Ajv2020) + ajv-formats wired into plugin startup; validator handles exposed on plugin instance for E2E reachability; spec/*.schema.json compiled at load with fail-fast on schema malformation. CrosswalkerConfig interface renamed to ImportRecipe across the codebase (4 source files); semantic migration to the spec-shape ImportRecipe deferred to v0.1.2 where render() lands.
Open question status (decided 2026-05-04):
- ✅ Q1: Generated TS types committed to
src/types/generated/for PR-diff visibility on schema impact - ⏸ Q2: AJV strict mode deferred — current setup is
strict: false; revisit at v0.2 once we have more spec experience - ✅ Q3: Type rename done now (
CrosswalkerConfig→ImportRecipe); semantic migration via Phase-0 compat shim deferred to v0.1.2 where the engine refactor naturally absorbs it
Dependencies
Section titled “Dependencies”- ✅ v0.1 design phase commitments — settled
- ✅
spec/tier1.schema.json+spec/recipe.schema.json— published - ✅
bun run fixtures— running
Blocks: v0.1.2 needs typed Recipe interface; v0.1.3 needs typed Tier1ConceptNote interface for the generation engine refactor.
In:
- TS type generation pipeline (
json-schema-to-typescriptor equivalent) - AJV validator instance loaded at plugin startup
- Recipe validation on
loadRecipe()(reject malformed early; show line+column errors to user) - Tier 1 frontmatter validation before write (
generation-engine.ts) - CI step:
bun run fixturesthen validate every generated.mdagainstspec/tier1.schema.json
Out:
- AJV strict-mode opt-in (defer; could be a v0.1.5+ refinement)
- Custom format validators beyond what
ajv-formatsprovides - Schema migration tooling (deferred to v0.1 phase 2 of the 4-phase migration plan)
Concrete tasks
Section titled “Concrete tasks”- Add
json-schema-to-typescriptandajv+ajv-formatstodevDependencies - Add
bun run codegenscript: generatessrc/types/generated/tier1.tsandsrc/types/generated/recipe.tsfromspec/*.schema.json - Replace
src/types/config.tsCrosswalkerConfiginterface with the generatedImportRecipetype (rename ripples — see Ch 22 §10.7 4-phase migration plan) - Phase-0 compatibility shim: legacy
hierarchycolumn-role still loads as syntactic sugar for the newtarget.layoutform - New
src/validation/validator.ts— exportsvalidateRecipe(obj),validateTier1Frontmatter(obj)using AJV instances loaded from spec - Wire validator into plugin startup (
main.ts); fail-fast with clear error if a recipe is malformed - CI workflow step: run
bun run fixtures, then validate every emitted markdown’s frontmatter againsttier1.schema.json - Unit tests in
tests/validation.test.tscovering: valid recipe, missing required field, bad mechanism enum value, malformed CURIE, mechanism-heading-without-level_depth
Success criteria
Section titled “Success criteria”-
bun run buildproduces output with zeroanyreferring to recipe / Tier 1 frontmatter types - AJV catches malformed recipes with line + column error messages users can act on
- CI fails (red) if any fixture violates
tier1.schema.json - Re-running
bun run codegenafter a schema bump regenerates types deterministically (no manual edits needed) - E2E:
tests/e2e/validation.spec.tspasses (bun run e2e) — load a malformed recipe via the import wizard; assert that an AJV error surfaces in a user-facing Notice rather than silently corrupting Tier 1 output (see testing-patterns skill)
Files to touch
Section titled “Files to touch”package.json— new devDeps +codegenscriptsrc/types/config.ts— replaced by generated types; legacy types removedsrc/types/generated/— new (generated, gitignored OR committed for diff visibility — pick one)src/validation/validator.ts— newsrc/main.ts— wire validator at startupsrc/generation/generation-engine.ts— callvalidateTier1Frontmatter()before writesrc/import/import-wizard.ts— callvalidateRecipe()on save.github/workflows/*.yml— fixture validation steptests/validation.test.ts— newdocs/src/content/docs/development/testing.mdx— document the new CI step
Estimated effort
Section titled “Estimated effort”1–2 days
Open questions
Section titled “Open questions”- Commit generated types to git or gitignore? (Pro-commit: easier code review of schema impact. Pro-gitignore: no drift risk.)
- AJV strict mode now or defer? (Strict catches more bugs; can be noisy initially.)
Related
Section titled “Related”Concept pages:
- ETL and import (the schema-as-primitive pillar) — why schema is the load-bearing primitive
- Terminology — definitions: recipe, Tier 1, CURIE, producer, validator
- What makes Crosswalker unique — schema-as-primitive distinguishes Crosswalker from ad-hoc importers
- Ontology evolution — why schema validation is non-negotiable
Agent context:
- v0.1 schema spec — the build target this milestone makes runtime
- Vision — runtime-agnostic recipe schema is the central modularity commitment
- Tradeoffs — strict vs. lenient validation tradeoffs
Design decisions (synthesis logs):
- v0.1 import-engine design (2026-05-04) — the design phase that produced the spec
- Ch 22 synthesis (target-structure expressivity) — recipe shape; §9 has the 4-phase migration plan that frames the legacy
hierarchyshim - Ch 23 synthesis (bundle/engine/language) — §6 commits to JSON Schema + AJV + JSONata
- v0.1 stack pivot (2026-05-02)
- v0.1.1 delivery log (2026-05-04) — what shipped + system-design diagram
Research deliverables:
- Ch 22 deliverable (target-structure expressivity)
- Ch 23 deliverable (bundle/engine/language)
- Ch 20 deliverable a (T1TMA primitives)
Spec & schema files:
spec/tier1.schema.json— Tier 1 frontmatter contractspec/recipe.schema.json— recipe shape- JSON Schema 2020-12
Other milestones:
- v0.1.2 — render() v1 — what this milestone unblocks
- Milestone hub