# dsh-learn-everything 验收矩阵 本矩阵把 [SPEC §9 里程碑](./../SPEC.md#9-里程碑与验收) 的验收标准映射到可重复执行的自动化证据。M1–M3 已落地(提交 1f880da → 7c01a6d → 032aa33);M4 门禁(本仓库)逐项列证据。keyless 门禁不读取用户 `$DSH_HOME`,所有 Session、profile 数据都位于测试临时目录。 | 里程碑 | # | 标准 | 自动化证据 | |---|---:|---|---| | M1 脚手架 | 1 | 构建 / typecheck 绿 | `pnpm run typecheck`(`build:host` + `tsconfig.host/client/spec` 三个编译面) | | M1 | 2 | 单测绿 | `pnpm test`(`config.spec.ts`、`fold.spec.ts`、`project.spec.ts`、`mermaid.spec.ts`) | | M1 | 3 | `/learn` 状态机 + `learning:policy` 段 + `teach` 工具 | `pnpm run test:smoke`:Loader 子进程装配后,`learningMode` 服务、`learning:policy` 段、`teach` 工具均已注册;mode off 时该段渲染空串、on 时渲染内置引导 | | M1 | 4 | `teach` 模式门禁 | 同一 smoke:模式外 `teach` 调用返回 `only available in learning mode` 错误,模式内返回 `{ ok: true }` | | M1 | 5 | 卡片渲染 | keyless Web 快照(`pnpm run test:web` replay)覆盖 `tool.call.toolview` 卡片 | | M2 教学闭环 | 1 | 讲解→复述→判定→回讲一轮闭环 | `pnpm run test:e2e`(真实模型 `tests/learning-loop.e2e.ts`,缺 key 自跳) | | M2 | 2 | 至多两次提问收尾 | e2e `assertLoop`:`askCount ≤ 2`,且 `ask_user_question` 至少一次 | | M2 | 3 | 判定驱动缺口回讲 | e2e:最后一张有效卡片出现在首次复述答案之后、标题不同于首卡、小节数不增(不重发整卡) | | M2 | 4 | model-visible ⟺ logged | e2e:`learning/mode` 事件入会话日志 | | M3 富 HTML | 1 | 代码高亮 | Web 快照 golden 含 shiki 语言横幅 `javascript` 与 `function makeCounter()` | | M3 | 2 | mermaid 渲染成 SVG | Web 快照断言 `data-diagram-state="ready"` 的 SVG 计数为 1、pending/error 为 0、节点标签渲染进 SVG | | M3 | 3 | keyless assembled replay | `pnpm run test:web` replay 通过(replay 3 连绿) | | M4 门禁 | 1 | README Model Experience(canonical 格式) | `README.md` §Model Experience:每个 model-context 入口一个 H3 + 三个有序 H4,`learning:policy` 引导逐字 H5 引用 | | M4 | 2 | Known Limitations 对齐 SPEC §10 | `README.md` §Known Limitations and Deferred Work(mermaid 体积、长内容折叠未做、判定软约束等) | | M4 | 3 | 安装/组合 smoke | `pnpm run test:smoke`(REAL-composition:经 Loader/子进程装配 `cordis.yml`,非 hand-mounted `ctx.plugin`) | | M4 | 4 | 验收矩阵 | 本文件 | | M4 | 5 | GIF 演示 | 本地留档 GIF(真实服务 + 真实模型轮次,禁止 fixture),见 [§GIF](#gif) | ## 发布候选门禁 ```sh pnpm run typecheck pnpm test DSH_SOURCE_DIR=/absolute/path/to/dsh pnpm run test:web DSH_SOURCE_DIR=/absolute/path/to/dsh pnpm run test:smoke DSH_SOURCE_DIR=/absolute/path/to/dsh pnpm run test:e2e # 有 DEEPSEEK_API_KEY 才跑 DSH_SOURCE_DIR=/absolute/path/to/dsh pnpm run dsh:link:check git diff --check ``` ## GIF 故事板(6 帧,真实 DeepSeek 模型):`/learn on` → `teach` 卡片(高亮代码 + mermaid SVG)→ `ask_user_question` 复述题 → 模拟用户残缺作答 → 判定 + 补缺口卡片 → 收尾。 - 成品:`.playwright-mcp/learning-loop.gif`(1200×750,13s,6 帧,352KB,gitignored 本地留档)。帧存 `.playwright-mcp/gif-frames-learning-loop/`,用 `record-browser-gif` skill 的 `scripts/encode_gif.py` 编码(python3 + ffmpeg + ffprobe),ffmpeg 解码抽查首/中/末帧确认顺序与最终停顿。 - 演示 commit SHA:记录于 base commit `032aa33`(M3)+ 未提交的 M4 工作树;本矩阵所属提交即演示 head。 - 是否真实模型:是(`deepseek-v4-flash`,真实 API key,真实 dsh web 服务 + 插件 profile;无 fixture/模拟)。