# 课程 / 实验流水线

每节课是一个小而可重复的单元：回答一个系统辨识问题，并留下足够证据，让另一位工程师能够复现。流水线先作为约定存在；共享 Python 抽象应在第二个实验确认边界确实重复后再提取。[交付政策](lesson_delivery_policy.zh-CN.md)规定静态 HTML 提供解释和可使用证据，视频辅助明确问题，Marimo WASM 为可选项，计算课要求本地参考路径。实际阅读、证据和素材状态见[逐课矩阵](course/status.zh-CN.md#evidence-media-matrix)。

## 课程约定

实现前，每课声明以下内容：

| 项目 | 必须回答的问题 |
|---|---|
| 学习问题 | 初学者学完后应能解释什么？ |
| 系统边界 | 辨识哪个系统，哪些部分在边界外？ |
| Oracle | 什么隐藏真值生成数据？ |
| 观测 | 估计器得到哪些信号？ |
| Student 模型 | 允许拟合哪些结构与参数？ |
| 数据划分 | 哪些用于拟合，哪些留出？ |
| 执行方式 | 即时计算、交互等待，还是后台任务？ |
| 学员控件 | 可以改变哪一两个受限设置？ |
| 证据 | 哪些曲线、指标和诊断能回答问题？ |
| 局限 | 故意省略哪些真实效应？ |

Oracle 与 Student 参数空间不同时，还要声明共有、仅 Oracle 有、仅 Student 有的参数。共有参数才可能支持恢复结论；不匹配参数需要行为与残差证据。

这些约定防止叙事不变、模型或观测边界及验证含义却悄悄改变。

知识课引用已有实验的证据或明确标注的概念示意，不要求独立拟合实现。计算实验采用[课程设计 D03](lessons/course-design.zh-CN.md#d03)的三层信号可见性和最低证据包；用验证选择模型后，最终结论需另留未参与调整的评估数据。

## 共同流程

```text
提出问题
  → 冻结版本化配置
  → 生成 Oracle 拟合与验证观测
  → 只用拟合观测估计声明的 Student
  → 在拟合及留出数据上评价初始和辨识后模型
  → 检查诊断与失败条件
  → 在课程中解释证据
  → 提供实验文件、无界面命令、报告和检查
```

计算只由可导入的 Python 模块实现。课程文本解释推理，Marimo/Jupyter 是学习适配层，静态报告记录一次可复现运行。各展示形式不应重复实现仿真和拟合。

## 执行策略

将计算与结果浏览分开。已完成的 `ExperimentRun` 是边界：拟合产生运行结果，图表、指标、关节选择、时间轴和相机控件只读取它，不暗中重新拟合。

| 策略 | 预期等待 | 交互方式 |
|---|---:|---|
| 即时 | 约 200 ms 内 | 控件改变后响应式重算 |
| 交互 | 约 0.2–5 s | 页面明确显示运行、成功与失败 |
| 任务 | 更长时间或远程调度 | 提交工作并返回任务 ID，展示进度与取消，完成后读取结果 |

展示控件不提交计算。切换拟合/验证、关节、时间或残差视图，复用同一结果。复杂 Oracle 数据通常预先生成并缓存，拟合任务消费数据引用，而不是每次交互重新生成 Oracle。

```text
prepare_experiment(spec) → 不可变数据引用
submit_fit(数据引用, Student, estimator) → 任务 ID
observe job → 进度 / 失败 / 已完成 ExperimentRun
读取 ExperimentRun → 曲线、回放、指标、报告
```

这描述行为，还不是共享任务队列 API。第一个执行器或腿部实验超出交互预算时，再依据真实工作负载实现重试、取消、缓存和工作进程。

## 产物约定

```text
docs/lessons/<track>/<lesson>.md       叙事与练习
synthetic/<lesson>.py                  共享数值实现
synthetic/<lesson>_config.json         冻结示例配置
reports/<lesson>/report.md             有解释的运行结果
reports/<lesson>/report.png            静态视觉证据
reports/<lesson>/metrics.json          机器可读指标与来源
tests/test_<lesson>.py                 数值与边界检查
```

计算实验必须提供本地 Notebook 或命令。通过浏览器执行条件后才增加 Marimo/WASM；它们是可选适配层，不是理解课程的前提。

报告回答“这次运行发生了什么”，课程回答“为什么做、如何读、下一步试什么”。

## 验收条件

进入下一课前，需要：

1. **数值证据：** 估计器可运行，拟合/验证隔离，达到本课参数恢复或行为标准。
2. **复现证据：** 在声明的 CPU/GPU 与后端依赖环境中，用干净的复现命令重新生成报告；记录资源与运行预算，视觉入口共用实现和配置。小型 CPU 课保持 CPU 路径，大型课不强制降为 CPU。
3. **学习证据：** 读者能指出初始偏差、解释留出结果、改变一个公开设置，并说出主要局限。
4. **范围证据：** 报告声明省略项，后续复杂度由失败证据引出。

## 展示形式

静态课程是主要叙事表面；教学短片只在已有时辅助明确问题。Jupyter 保留为本地检查入口。Marimo 调用同一实现，将“修改初始模型”与 **Run identification（运行辨识）** 分开；L0 橙色预览即时变化，蓝色结果在显式拟合后更新。拟合与验证同时可见。WASM 可以在 GitHub Pages 提供这种有限交互，较重拟合、原生仿真和大数据继续本地运行。课程总览负责 K/L/H 地图，生成报告保留为固定运行产物。

## L0 对应关系

| 章节 | 问题 | 证据 |
|---|---|---|
| 入门 | 什么是系统、输入、输出与参数？ | 边界和单位 |
| 从物理到数据 | `J` 和 `b` 如何影响运动？ | 真实系统与初始模型曲线 |
| 从拟合到验证 | 拟合是否恢复了有用行为？ | 参数恢复和留出指标 |
| 假设 | 结论在哪里不再成立？ | 省略项与下一课延迟 |

下一节模型失配课沿用相同组织和产物布局。对比后，再决定是否把重复结构提取成共享的 `ExperimentRun` 或 `run_experiment(...)` API。
