The heart of the pipeline. Embeds the typst 0.15 compiler as a library to compile-check a lesson and export a PDF, with diagnostics mapped back to source spans (the product's value). - LessonWorld: a typst World over the engineering-file directory tree. vpath = real relative path (ADR-0007); the per-target driver is mounted in-memory as `main` (.cph/driver-<target>.typ, never written to disk); @local/cph-render is resolved from render_dir (CPH_RENDER_DIR / with_render_dir), no package install or network. Fonts via typst-kit FontStore (system CJK). - Driver generation: from the manifest, per target — static root-relative `include` of each content file (⇒ module body content, ADR-0006), assembled into the frozen `display(info, target, parts)` call; optional lemma proof emitted only if proof.typ exists; example `source` scalar threaded through. - Diagnostics: typst SourceDiagnostic (errors + warnings) → cph_diag::Diagnostic. 0.15 DiagSpan handled via span.id() + WorldExt::range → file-relative SourceSpan with 1-based line/col; driver-internal spans re-pointed with a "generated driver" hint, never dropped. typst hints/trace carried through. - Engine API: new / with_render_dir / compile_check / build_pdf. - 6 tests incl. build_pdf_with_real_render — full World→driver→cph-render→PDF producing real PDF-1.7 output (student 42KB / teacher 54KB). clippy/fmt clean. Also fixes render/typst.toml `compiler = ">=0.15.0"` → `"0.15.0"`: typst 0.15's manifest parser rejects a `>=` comparator on the compiler field (the 0.14 CLU WU-2 tested against was lenient). This unblocks loading the real render package. Pinned: typst/typst-pdf/typst-syntax/typst-library/typst-layout/typst-kit =0.15.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
crates/
These crates implement the rule-based lesson checker that aligns to the
semantic master in spec/: it reads an engineering-file (one lesson, ADR-0005)
laid out per ADR-0008 (declarative manifest.toml + per-element
element.toml), validates structure and content, and emits diagnostics.
cph-diag (the shared diagnostic vocabulary), cph-model (the ADR-0008 loader),
and cph-typst (the typst World / compile / span-mapping layer) are
deliberately reusable by future components such as an exporter, which is why
they live in this repo-wide crates/ directory rather than under any single
component; cph-schema (kind JSON Schemas + validation), cph-check
(orchestration + render-coverage) and cph-cli (the cph command-line
entrypoint) are the checker proper.
Crate map
| crate | owner | role |
|---|---|---|
cph-diag |
WU-1 | shared diagnostic vocabulary (Severity, DiagCode, Diagnostic, SourceSpan) — reusable |
cph-model |
WU-1 | parses the ADR-0008 layout into an in-memory ordered Lesson — reusable |
cph-schema |
WU-3 | the 4 stdlib kind JSON Schemas + structural validation |
cph-typst |
WU-4 | typst World, driver generation, compile, PDF, span mapping — reusable |
cph-check |
WU-5 | orchestration: render-coverage and the full check pipeline |
cph-cli |
WU-5 | the cph command-line entrypoint |
Build
# from the repository root (the cargo workspace root)
cargo build # all crates
cargo test # cph-diag + cph-model unit/integration tests
cargo clippy --all-targets -- -D warnings
cargo fmt --check