# curriculum-project-hub 教研生产的数字化解决方案。核心思路:课程像 DAW / 剪辑软件那样有一个**结构化的工程文件**;coding agent 协助编辑它;一个 rule-based checker(类编译器)校验其合法性并给出 helpful fix hint。目标是把教研从一次性的文档,沉淀成**可累积、可校验、可复用的资产**。 这是一个 **monorepo**。它的组织方式本身就表达了一条原则:**`docs/adr/` 是系统级决策的唯一权威来源,代码注释把关键不变量锚到 ADR 编号,可 grep。** ## 安装 `cph` 命令行 当前版本 **0.0.2**。从源码安装(本仓库根目录): ```sh cargo install --path crates/cph-cli --locked ``` `render` 包已嵌入二进制(build.rs 编译期拷入 + `include_dir!`),所以装好后**无需任何环境变量、不依赖源码树**即可用。渲染包按版本解压到 per-user cache(`~/.cache/cph/render-/` 或 macOS `~/Library/Caches/cph/...`);开发时可设 `CPH_RENDER_DIR` 指向 live `render/` 目录覆盖。 ```sh cph --version # cph 0.0.2 cph init <工程目录> # 脚手架:manifest.toml + .cph-version + 默认 exports/student.typ + 空 kind 目录 cph add --root <工程目录> <名称> # 新增 part(segment/example/lemma/sop):建目录+空白内容文件+追加 [[children]] cph check <工程目录> # 校验合法性(7 类诊断) cph build <工程目录> --target student -o build/student.pdf # 渲讲义 PDF ``` ```sh cph outline <工程目录> # 默认写入 <工程目录>/outline.pdf cph outline <工程目录> --format md # 或 json / pdf cph outline <工程目录> --format pdf --force # 明确允许覆盖已有 outline.pdf ``` 大纲节点来自根及各级容器 `manifest.toml` 的 `[[children]]`;可在 child 上填写多行 `notes = """…"""` 作为教师备课提示。它会进入 outline 的 JSON/Markdown, 并在 PDF 中以独立的“教学提示”区域呈现,不会混入学生/教师讲义正文。 `init` / `add` 是纯本地的创作脚手架(与 ADR-0013 的 `completions` 同类,不涉及 hub 语义):`init` 产出一个 `cph check` 可过的工程根;`add` 按 kind 建 `<子目录>/<名称>/` + `element.toml` + 必填内容字段(`segment→textbook.typ`、 `example→problem/solution.typ`、`lemma→stmt.typ`、`sop→sop.typ`),并把配套 `[[children]]` 追加进根 `manifest.toml`(保持数组连续,不破坏注释;ADR-0036)。缺省 `--root` 为当前目录。 **版本契约(ADR-0016):** 教研工程文件根放一个 `.cph-version` 文件,内容为它面向的 cph 版本(如 `0.0.2`)。`cph` 加载时比对自身版本,不相容则报 `E-CPH-VERSION` error 并拒绝(当前判定为版本完全相等;后续可放宽为 semver 区间,只改一处谓词)。`examples/` 与本仓 fixture 已带该文件作为迁移起点;缺文件的工程暂时跳过此检查(OPEN)。 Shell 补全(可选): ```sh cph completions zsh > ~/.zfunc/_cph # 或 bash/fish/powershell/elvish ``` ## 仓库布局 ``` README.md ← 本文件:总览 + 宪法(下面 5 条) CLAUDE.md ← 全局 agent 操作手册(管整个 repo) docs/adr/ ← 系统级架构决策记录(跨部件,决策的唯一权威来源) CONTEXT.md ← 平台语言词汇表(术语与禁用说法) Cargo.toml ← 仓库级 cargo workspace(实现部件共用,便于跨部件复用 crate) crates/ ← 实现:rule-based checker(语义由 ADR 锚定)。见 crates/README.md cph-diag / cph-model / cph-schema / cph-typst ← 可复用基础(模型/校验/typst 引擎) cph-check / cph-cli ← checker 本体 + `cph` 命令行 render/ ← typst 渲染包 cph-render(checker 的渲染后端,ADR-0005) examples/ ← 样例工程文件(如 TH-141),流水线的真实输入 hub/ ← SaaS Hub:飞书协作、org 管理、agent runtime 与生产部署 (exporter/ …) ← 将来的其他部件,平级于 crates/ ``` 实现部件共用一个仓库根的 cargo workspace,使基础 crate(模型、typst 引擎)能被 未来部件(如 exporter)复用,而非各自重造。 ## 宪法 这 4 条是本仓库的协作约定,是一切工作的前提。 1. **角色 —— ADR 是决策真相。** 跨部件的语义决策只记录在 `docs/adr/`,一份决策一份 ADR,编号顺延、正文不改写历史。代码里的关键不变量用注释锚到 ADR 编号,保持可 grep。没有第二份权威文档。 2. **对齐机制 —— 人肉承载,无机器兜底。** CI 只验各部件自身良构(build / test / clippy),**没有**决策↔实现的一致性 gate。实现对齐 ADR,由"开发者 review + agent 巡逻 diff"这个人肉环节承载。发现漂移,报告它,不要默默让其中一边将就另一边。 3. **形态 —— 自包含。** 凡 ADR 未明文规定的,开发者与 agent 双方都不该假设;遇到没覆盖的地方,**显式 surface** 出来让开发者决定。 4. **深度判据 —— 只收录分歧点。** 一条语义该不该写进 ADR,取决于一句话:**"不写明,开发者与 agent 会不会各自做出不同假设?"** 会 → 进 ADR;显然的东西 / 纯 plumbing / 普通 CRUD 字段 → 不进(写进去只稀释信噪比、增加维护面)。 深度上限是**你愿意在每次实现变更时手动回头同步的量**——写得比你能维护的更深,多出来的部分会率先过期、反过来误导实现。 ## CI Rust checker 的本地与 CI 工具链由根 `rust-toolchain.toml` 固定;`.gitea/workflows/checker-check.yml` 必须安装同一精确版本并执行 `cargo fmt --all --check`、Clippy `-D warnings` 与 workspace 全测试。升级 Rust 时这两处必须在同一提交更新并通过完整 checker gate。