/-!
# Artifact —— export target 的产物(ADR-0009 / 0011)

ADR-0009:一个 export target 是**一次 build**,产出一个**有类型的产物**(artifact)。
ADR-0011 进一步钉死:产物不是一个光秃的标签,而是**带字段的 ADT**——"产物到底指什么"
(单个文件落在哪 / 一棵树产出哪些文件)是不好猜的领域语义,必须写进字段 + doc,而非
抹成 `singleFile | fileTree` 两个空构造子。

路径/glob 在此用 `String` 承载并由 doc 赋义(它们就是文本:一个相对路径、一个 glob
模式),不复刻文件系统类型——契约只钉"这个字段是什么",不建模路径代数。
-/

namespace Spec.Courseware

/--
export 产物(`PINNED` 带字段 ADT, ADR-0011)。

- `singleFile (filepath)` —— 产物是**单个文件**,落在 `filepath`(相对工程根的路径)。
  讲义 PDF、教案 PDF 即此。`filepath` 说清"这一份产物写到哪"。
- `fileTree (root) (outputs)` —— 产物是 `root` 目录下、匹配 `outputs` **glob** 的**一组
  文件**(第三方平台 archive 即此)。用 glob 而非显式清单:比逐个枚举轻,又让消费方/
  checker 知道"这次 build 该产出哪些文件"、可据以校验产物完整性。

**为什么字段进契约**:产物形状决定 `cph build` 吐一个文件还是一个目录、消费方期待什么;
也决定 reduce/assemble 怎么折叠(`singleFile` 把有序片段拼成一份再编译——这也是交叉引用
`@ref` 与 例题N 计数器能工作的前提;`fileTree` 每 part 落一文件)。后端/格式(哪个 PDF
引擎、哪种 markdown 方言)仍 OPEN(ADR-0009),不在字段里。
-/
inductive Artifact where
  /-- 单文件产物,落在 `filepath`(相对工程根)。 -/
  | singleFile (filepath : String)
  /-- 多文件产物:`root` 目录下匹配 `outputs` glob 的文件集。 -/
  | fileTree (root : String) (outputs : String)

end Spec.Courseware
