feat(checker): cph-schema — 4 kind JSON Schemas + validation (WU-3)

Declarative JSON Schema per kind (segment/example/lemma/sop), embedded as real
.json artifacts (ADR-0006) and validated by a small hand-rolled interpreter
(properties/required/type/enum/additionalProperties + the `x-cph-content`
marker) — no jsonschema-crate churn for a one-optional-string scalar surface.
`x-cph-content: true` marks content fields (not in element.toml; require sibling
<field>.typ); everything else is an element.toml scalar. `validate(desc)` is
self-contained: UnknownKind for unknown kinds, MissingContentFile (path named in
message) for absent required .typ, SchemaViolation for bad scalars; lemma proof
optional ⇒ no diagnostic when absent. 8 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 01:33:40 +08:00
parent c17af60bb0
commit 752a5c661d
12 changed files with 661 additions and 2 deletions
Generated
+31
View File
@@ -29,6 +29,12 @@ dependencies = [
[[package]]
name = "cph-schema"
version = "0.1.0"
dependencies = [
"cph-diag",
"cph-model",
"serde_json",
"toml",
]
[[package]]
name = "cph-typst"
@@ -56,6 +62,12 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.2"
@@ -110,6 +122,19 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "serde_spanned"
version = "0.6.9"
@@ -185,3 +210,9 @@ checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [
"memchr",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"