DSH 开发实践
从 DeepSeek Harness 提炼、可搬到任何仓库的做法。宿主负责拆任务、排计划、管 Todo;本 Skill 只补判断和证据。不引入第二套任务库或会话状态。
定位
这不是"从零搭项目"的工作流,也不是要替代已有的计划/编码/审查流程。它的定位是叠加层:当改的是行为、架构、契约、流程或落盘格式这类以后会有人回头审视的决定时,帮你把 Harness 用血换来的四件事补上——事实有没有摸清、长期决定有没有留痕、证据有没有按表面拿全、收尾有没有如实说清。
只改格式/无歧义命名/错别字标 not applicable,走宿主常规检查。不确定就按非平凡处理。
0. 先探测,再落地
别一上来就建一套目录。先看宿主有什么就用什么:
- 有
AGENTS.md/CLAUDE.md/贡献指南就读它,没有也不为此新建一套规范。 - 有
docs/adr/、docs/decisions/、Issue 模板等决策记录就沿用,把语义映射到本 Skill 的 lifecycle/class 即可。 - 没有决策记录再建最小 Note 树:轻量项目只建
.agents/notes/implemented/<class>/,用到proposed/rejected/archived再建;已有空目录可直接删掉。团队长期仓库再建全套。
1. 动手前先把事实搞清
不为此新建状态文件,记在宿主当前上下文里:
- 找到项目根,把根和受影响目录的规则读一遍。
- 看一眼工作区,把无关改动标出来——不覆盖、不重置、不算到这次任务里。
- 找到真正会用到这次改动的地方:源码/构建/测试/生成物/线上入口,只看声明不够要找到消费方。
- 翻已有长期决定(ADR/Note/Issue),先看在用的再看归档。
- 列出会影响哪些可观察表面(见 §5),每个表面怎么验。
记下:已确认的事实、还没验证的假设、会动到哪些文件和表面、无关改动、需要人来拍板的问题。
需求有分歧或多个合理方案时,先把每个分支问清楚再写代码。追问本身不产代码——有追问/访谈类 Skill 就调它,没有就用同样提问把分支覆盖到再进 §2。
2. 先分类,再定边界
分类(只决定要留什么证据,不额外加阶段):局部/机械 · 行为变更 · 跨表面变更 · 高风险(安全/丢数据/兼容/并发/不可逆)。
定边界——优先复用已有扩展点和靠谱依赖,别为了"像个架构"硬抽象:
- 默认值放在显式的解析/归一化那一步,别藏在执行函数里的
?? default。 - 会随环境变的东西做成可校验的配置项,别写死成常量或散落在多处。
- 能独立判断的非法配置在加载时就报错,其他错误在最早能定位的地方报,别静默跳过或吞掉未知的分支(封闭联合用
assertNever,开放联合走有文档的默认分支)。 - 在解析、文件、持久化、外部 JSON、进程/Worker、网络这些边界上校验不可信数据;同进程内已定类型的数据不用重复设防。
- 管好所有权和生命周期:注册/释放、取消、清理、错误传播要成对;别引入两套事实源或宽泛兼容层却证明不了现有边界兜不住。
- 别把某一个实现的枚举升为全局标准——能力由提供方声明,核心只透传;协议归提供方管、由提供方自愈,消费方别去硬改提示符或协议细节。
- 评估依赖时看净删除、健康度、边界贴合度:能真删掉实现+测试+文档才值得引入,手写协议/解析/重试之类优先看现成包。
做并发/清理/子进程改动时,必读
references/defensive-checklist.md的完整清单。
3. 长期决定怎么记
这是最值得搬走的部分。每个非平凡改动在同一 PR 里新增或更新至少一条 Note,纯机械可不写;已有覆盖就更新,别重复新建;不要把一条 Note 改写成另一个决定。
- 放哪:
{lifecycle}/{class}/yyyy-mm-dd-topic.md,有既定目录就映射语义。lifecycleproposed(可选)→implemented→rejected(能防重犯才留)→archived(冻结);classfeature/bug-fix/simplification/architecture/process/testing(封闭集,新增需改门禁)。 - 写成什么样:
# Agent Note: <标题>+Status: <状态 — 一句话>+Problem+Proposal|Decision+ 按需的 bespoke 技术节 + 必写的Alternatives considered(每个真考虑过的备选及为什么没选,不写就重审)+Acceptance criteria|Consequences|Risks。implemented用现在时,归档加Archived: YYYY-MM-DD后冻结。 - 新建/更新/归档:先搜现有归属;决定没变只事实/验证变了就更新;只有新增长期决定/防重犯否决/可复用复盘才新建;完全取代才归档,部分取代两份都留并互链。
小项目允许"一话题一份 implemented",提案讨论写在 PR 描述或 Alternatives considered 里。
4. 带着证据做
做最小自洽改动,在行为真正被消费的地方测。测试写外部可观察行为和边界,别复述实现。
- 异步不是同步:别把
running/idle当单条消息的结果;清理要等到静止(先关监听再杀进程、等子进程退出);回调异常由调度器兜住;正交结果(超时/退出码/信号)分开报。 - 涉及部分视图编辑(如配置页只拿到脱敏快照)走"算 diff 发 ops + 带版本号防覆盖",别用全量
replace把看不见的字段洗掉。 - 公开或模型可见行为变了,同步更新契约、快照或 SDK 投影;持久化格式变了要处理旧数据的降级而非硬报错。
- 别用 normalizer 盖失败、别放宽校验、别用 mock 代替真实集成;在消费方的真实入口上验(走发布形态的 Loader/bin/worker,而非手搭的
ctx.plugin(...))。 - 同一子任务内别反复刷同一句进度,阶段变了或有新证据再更新。
完整实现自检见
references/defensive-checklist.md。
5. 按表面拿证据
源码和产物分开验——源码过了不代表产物过了,一个投影过了不代表兄弟也过了。只挑相关表面做最小够用集:
| 表面 | 怎么验 |
|---|---|
| 纯规则/转换 | 聚焦单测,含非法与边界 |
| 包/API 行为 | 包测试 + 真实消费方或组合入口 |
| CLI/配置 | 源码/配置启动与失败路径 |
| 浏览器/UI | 把应用跑起来,走一遍代表性交互,看桌面/移动布局 |
| 生成输出 | 从权威来源重生成并 diff |
| 快照/转录/模型可见输出 | 无密钥回放或项目认可的快照(拍模型实际看到的,不是日志本身) |
| 构建/发布产物 | 干净构建 + 用真实产物起一次/冒烟 |
| 持久化/协议/线数据 | 往返、迁移/版本、非法数据拒绝 |
| 安全/并发/清理 | 明确的拒绝、取消、释放与失败路径 |
再补两条 Harness 最近用血换来的:
- 数据和元数据一起裁:截断丢掉工具调用时,其对应的签名/回放元数据也要一起丢,否则持久化后下一轮直接卡死;读到旧脏数据要降级而非硬报错。
- 一条证据链:浏览器/UI 证据要来自同一次真实运行的同一服务和同一会话,别把多轮截图拼成一张图;录屏/GIF 要可追溯到同一 commit。
本地只跑相关表面,覆盖率/快照/构建等门禁和 CI 各管各的,报清楚实际跑了哪些命令及结果就行,不用每次全量。详表与坑位见 references/evidence-by-surface.md。
6. 审查与收尾
收尾前自问:
- 和需求/非目标对得上?每处改动都有验收或写清为何没法测?
- 契约/文档/生成物/快照/兄弟消费方同步了?有无重复/第二事实源/隐藏默认值/陈旧兼容/说不清的不对称?
- 错误会响亮失败、清理成对?注释直接完整无过程泄露?
- 要删东西先证明有消费方、行为等价、净删除量;没明确理由别在功能改动里顺手重构无关代码。
自检不过再按需读 references/review-checklist.md 的必拦项与人工必查。
文档与注释:说人话、点名谁做了什么、在什么条件下会怎样;别把推理过程泄露进注释。一个事实只在一处讲透,其他地方链过去。自检见 references/prose-checklist.md。
简化机会:收尾或重构时扫一遍重复/过度设计/可删的兼容层,见 references/simplification-checklist.md。
如实收尾:同步文档/契约/生成物/Note,跑宿主最终机械检查。报告分开写:实际跑了什么及结果 / 刻意没跑什么及原因 / 已验证行为 / 已知限制与剩余风险 / 有意没动的文件。没证据别声称验过浏览器/集成/覆盖率/发布。
停止条件
需求或验收实质冲突、长期决定归属不清、涉数据/安全/协议/兼容/不可逆但无策略、找不到入口或证据、无关改动无法安全归属、方案要并行事实源或宽泛兼容却无证据、测试与实现打架且推不出预期——先停下找人确认,别编计划或谎报成功。
集成约定
可叠加在任何流程上,和宿主显式规则冲突时听宿主的。必须保住四条:动手前摸清事实与现行决定;实现是最小且有依据的长期正确改动;证据盖住每个受影响表面且源码/产物分开;最终报告分清事实/未做/风险且 Note 与文档已同步。
References
按需加载,不必每次全读:
references/defensive-checklist.md— 定边界与实现时的防御自检(展开版)references/evidence-by-surface.md— 表面对照表与两条易踩坑(展开版)references/review-checklist.md— 审查必拦项与人工必查(展开版)references/prose-checklist.md— 文档与注释自检(展开版)references/simplification-checklist.md— 简化机会自检(展开版)