forked from EduCraft/curriculum-project-hub
feat(spec): Artifact gets fields, target = artifact + typed steps, drop RenderRule (ADR-0011)
Fix the abstraction level review flagged. lake build green (20 jobs), no sorry. - Artifact.lean: bare enum → ADT with fields — singleFile(filepath) / fileTree(root, outputs:glob). The product semantics (one file where, vs a tree of what) are pinned in fields + doc, not erased behind empty constructors. Paths/globs carried as String (semantics in doc; no filesystem algebra). - Render.lean: Step inductive (typstCompile(template) | shell(run)) replaces the loose BuildStepForm. TargetSpec = artifact + steps:List Step + covers:Kind→Prop (the old renders:Kind→Option RenderRule is gone — coverage is now a plain declaration; the render "how" lives in the typstCompile template). covers / renderIgnored semantics continuous with ADR-0005. - Primitives.lean: RenderRule field removed (the per-target payload is retired per ADR-0011); a note records where the "how" now lives. - Diagnostic.lean unchanged in meaning (covers signature stable; Legal still quantifies over declared targets). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,30 +1,35 @@
|
||||
/-!
|
||||
# Artifact —— export target 的产物形状
|
||||
# Artifact —— export target 的产物(ADR-0009 / 0011)
|
||||
|
||||
ADR-0009:一个 export target 是**一次 build**,产出一个**有类型的产物**(artifact)。
|
||||
产物的**形状**是 target 值的一部分——"产出单个文件还是一棵文件树"是真分歧点,因为它
|
||||
改变 `cph build` 到底吐出什么、消费方期待什么,故进契约。
|
||||
ADR-0011 进一步钉死:产物不是一个光秃的标签,而是**带字段的 ADT**——"产物到底指什么"
|
||||
(单个文件落在哪 / 一棵树产出哪些文件)是不好猜的领域语义,必须写进字段 + doc,而非
|
||||
抹成 `singleFile | fileTree` 两个空构造子。
|
||||
|
||||
本模块只钉**形状**这一层。具体后端/格式(用哪个 PDF 引擎、哪种 markdown 方言)是
|
||||
ADR-0009 显式 OPEN 的,不在此承诺。
|
||||
路径/glob 在此用 `String` 承载并由 doc 赋义(它们就是文本:一个相对路径、一个 glob
|
||||
模式),不复刻文件系统类型——契约只钉"这个字段是什么",不建模路径代数。
|
||||
-/
|
||||
|
||||
namespace Spec.Courseware
|
||||
|
||||
/--
|
||||
export 产物的形状(`PINNED`, ADR-0009)。
|
||||
export 产物(`PINNED` 带字段 ADT, ADR-0011)。
|
||||
|
||||
- `singleFile` —— 一份打包文档(讲义 PDF、教案 PDF)。
|
||||
- `fileTree` —— 一棵文件树 + 索引(第三方平台 archive)。
|
||||
- `singleFile (filepath)` —— 产物是**单个文件**,落在 `filepath`(相对工程根的路径)。
|
||||
讲义 PDF、教案 PDF 即此。`filepath` 说清"这一份产物写到哪"。
|
||||
- `fileTree (root) (outputs)` —— 产物是 `root` 目录下、匹配 `outputs` **glob** 的**一组
|
||||
文件**(第三方平台 archive 即此)。用 glob 而非显式清单:比逐个枚举轻,又让消费方/
|
||||
checker 知道"这次 build 该产出哪些文件"、可据以校验产物完整性。
|
||||
|
||||
**为什么这是分歧点而非实现细节**:产物是单件还是多件,决定 reduce/assemble 这一步
|
||||
怎么折叠(见 `Render`:`singleFile` 按 lesson 序拼成一份文档再编译——这也是交叉引用
|
||||
`@ref` 与 例题N 计数器能工作的前提;`fileTree` 每 part 一文件 + 索引),也决定
|
||||
`cph build` 写一个文件还是一个目录。后端/格式(typst→PDF、markdown 方言…)仍 OPEN,
|
||||
故此处**只枚举形状**,不带后端标签。
|
||||
**为什么字段进契约**:产物形状决定 `cph build` 吐一个文件还是一个目录、消费方期待什么;
|
||||
也决定 reduce/assemble 怎么折叠(`singleFile` 把有序片段拼成一份再编译——这也是交叉引用
|
||||
`@ref` 与 例题N 计数器能工作的前提;`fileTree` 每 part 落一文件)。后端/格式(哪个 PDF
|
||||
引擎、哪种 markdown 方言)仍 OPEN(ADR-0009),不在字段里。
|
||||
-/
|
||||
inductive Artifact where
|
||||
| singleFile
|
||||
| fileTree
|
||||
/-- 单文件产物,落在 `filepath`(相对工程根)。 -/
|
||||
| singleFile (filepath : String)
|
||||
/-- 多文件产物:`root` 目录下匹配 `outputs` glob 的文件集。 -/
|
||||
| fileTree (root : String) (outputs : String)
|
||||
|
||||
end Spec.Courseware
|
||||
|
||||
Reference in New Issue
Block a user