Files
curriculum-project-hub/spec/Spec/Courseware/Render.lean
T
sjfhsjfh 09b026f598 feat(spec): backfill Export terminology + diagnostics/legality/pipeline (ADR-0009/0010)
Lift the business decisions the MVP made into the Lean master, per constitution
rule 5. lake build green (20 jobs), no sorry.

- Artifact.lean: `inductive Artifact | singleFile | fileTree` — product shape is
  part of a target's value (ADR-0009); it determines the assemble/reduce step.
- Render.lean reworked target-centric (ADR-0009, amends ADR-0005's matrix):
  `TargetSpec` carries `artifact` + a per-kind `renders` map (field visibility
  lives in this map); `RenderConfig.spec : TargetId → Option TargetSpec`; `covers`
  rewritten (target must exist AND its map covers the kind) — semantics continuous
  with ADR-0005 so renderIgnored still typechecks. `BuildStepForm` (declarative |
  shell) is a structural anchor for the build form (shell hatch = ADR-0005's
  medium-only category b) without replicating the schema.
- Diagnostic.lean extended: `DiagKind` (7 classes) + `DiagKind.severity` (six
  error, renderIgnored warning); `Oracle` makes external-facility verdicts
  (compiles/refsResolve/dataConforms/contentFilesPresent) an explicit
  implementation boundary; `Legal` = no error-level diagnostic (backfills
  ADR-0005's deferred full-legality), with renderIgnored deliberately excluded
  (it's a warning).
- Pipeline.lean: the 5 phases (load→structural→schema→compile→coverage) as
  structure — order + the compile gate (compile runs only on zero prior errors) +
  load halts the pipeline. Algorithms stay out of Lean (depth ceiling).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 08:36:29 +08:00

87 lines
4.1 KiB
Lean4
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Spec.Courseware.Primitives
import Spec.Courseware.Artifact
/-!
# Render —— export target = 一次 build(ADR-0009,修订 ADR-0005)
ADR-0005 曾把渲染建成被动的 (kind × target) 查表矩阵。ADR-0009 **修订**之:一个 export
target 是**一次 build**,消费整节 lesson、产出一个有类型的 `Artifact`。一次 build =
**map + reduce**:
- **map(per-kind)**:每个 kind 如何变成中间片段——声明式、按 kind 索引;`RenderRule`
是这张 map 的载荷。**字段可见性**(student 隐 `solution`/`proof`,teacher 全显)就住在
这张 per-kind map 里,不是独立概念、也不在 element 上。
- **reduce/assemble**:有序片段如何折叠成产物——**由 `Artifact` 形状决定**(见
`Courseware.Artifact`),框架按形状提供 assembler,build 只挑形状。
本模块建 target-中心的结构与"某 kind 在某 target 下是否已配规则"的判定(`covers`,
`Diagnostic` 依赖它)。`RenderRule` 的载荷仍由 `Primitives` 抽象承载(ADR-0009 显式
OPEN);build 形态(声明式 + shell 口子)以一个**结构锚点** `BuildStepForm` 体现——钉
"该有的结构"而**不**复刻具体 schema(宪法第 5 条)。
-/
namespace Spec.Courseware
variable (P : Primitives)
/--
build 步骤的**形态**(结构锚点, ADR-0009;具体 schema 字段 `OPEN`)。
ADR-0009 定 build 的表达形态 = **声明式 schema + 一个 `run`-shell 逃生口**(近似
GitHub Actions、**非** Makefile)。这里只把这个二分立成一个具名结构,让"build 要么声明
式、要么走 shell 口子"成为契约里可引用的事实:
- `declarative` —— 声明式步骤(per-kind map 的常规情形)。
- `shell` —— shell 逃生口。ADR-0005 的 (b) 类 medium-only 信息(HTML 交互、npm build)
正是落在这里——它属于 target 的 build,**不**上 element。
**刻意不**把 schema 的字段、shell 命令的内部结构写进来:那是实现细节(ADR-0009 OPEN),
此锚点只承诺"build 步骤分声明式与 shell 两形态"这一骨架。
-/
inductive BuildStepForm where
| declarative
| shell
/--
一个 export target 的 build 规格(`PINNED` target-中心结构, ADR-0009)。
- `artifact` —— 产物形状(`Courseware.Artifact`)。它**决定** reduce/assemble 怎么折叠
(单文件 vs 文件树),故是 target 值的一部分,而非事后的输出选项。
- `renders` —— per-kind map:`renders k = none` 表示 kind `k` 在此 target 下**无渲染
规则**(该 element 会被该 target 忽略,见 `Diagnostic.renderIgnored`);`some _` 表示
有。框架默认与文件 override 最终坍缩成这一个映射(ADR-0009 的 default-at-creation +
文件内 override);契约只看最终每格的有无,不区分"默认"与"改过"。
-/
structure TargetSpec where
/-- 该 target 产物的形状(decides assemble, ADR-0009)。 -/
artifact : Artifact
/-- per-kind map:kind ↦ 该 kind 在此 target 下的渲染规则(无则 `none`)。 -/
renders : P.KindId Option P.RenderRule
/--
渲染配置(`PINNED` target-中心, ADR-0009;修订 ADR-0005 的矩阵)。
`spec t = none` 表示 target `t` **未声明**(此工程文件不导出该 target);`some s` 给出该
target 的 build 规格 `s`。注意这比旧矩阵多了一层:旧矩阵默认每个 (kind,target) 格都在,
现在先要 target **存在**,其 build 规格再各自决定每个 kind 渲不渲。
-/
structure RenderConfig where
/-- target ↦ 该 target 的 build 规格(未声明则 `none`)。 -/
spec : P.TargetId Option (TargetSpec P)
/--
kind `k` 在 target `t` 下**已配渲染规则**(`PINNED`, ADR-0009;承接 ADR-0005 `covers`)。
成立 ⟺ target `t` 已声明(`spec t = some s`)**且**其 per-kind map 对 `k` 非空
(`s.renders k = some _`)。`covers` 为假即"此 kind 在此 target 下无从渲染"——checker
据此报 warning(见 `Spec.Courseware.Diagnostic.renderIgnored`)。语义与 ADR-0005 的
`covers` 连续,只是判定下沉到 target 的 build 规格里。`P` 隐式以便点记法。
-/
def RenderConfig.covers {P : Primitives} (c : RenderConfig P)
(k : P.KindId) (t : P.TargetId) : Prop :=
match c.spec t with
| none => False
| some s => (s.renders k).isSome
end Spec.Courseware