feat(checker): cph-model manifest v2 — Artifact-with-fields + typed steps (WU-B', ADR-0011)

[targets.*] reworked: artifact is now an inline table with a type discriminator
({type="single-file",filepath} / {type="file-tree",root,outputs}) and steps is an
ordered array-of-tables ({type="typst-compile",template} / {type="shell",run}).
numbering removed entirely (presentation lives in the template per ADR-0011).

TargetConfig { name, artifact: Artifact, steps: Vec<Step> }; Artifact and Step
mirror Spec.Courseware.Artifact / Spec.Courseware.Step (doc-cited). Sensible
defaults so a bare [targets.student] still works: single-file build/<name>.pdf +
one typst-compile exports/<name>.typ. Malformed artifact/step type → non-fatal
SchemaViolation with fallback. 8 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 09:57:50 +08:00
parent de87cddaf1
commit d5bce1bede
4 changed files with 473 additions and 190 deletions
@@ -5,12 +5,14 @@ name = "bad-target-config"
[info]
title = "测试课:非法导出目标配置"
# Invalid artifact value → SchemaViolation, falls back to default (single-file).
# Invalid artifact `type` → SchemaViolation, falls back to default (single-file).
[targets.student]
artifact = "pdf-thing"
artifact = { type = "pdf-thing", filepath = "build/student.pdf" }
# numbering.heading is not an array of strings → SchemaViolation, heading None.
# Invalid step `type` → SchemaViolation; the bad step is skipped and the build
# falls back to the default step.
[targets.teacher]
artifact = "file-tree"
[targets.teacher.numbering]
heading = "not-an-array"
artifact = { type = "file-tree", root = "build/teacher", outputs = "**/*.html" }
[[targets.teacher.steps]]
type = "make-it-nice"
template = "exports/teacher.typ"