CC端到端开发skill:步骤契约的重要性
前言:这篇文章解释
fully-coding中最重要的治理机制:步骤契约。它让一次 Claude Code 开发任务不再依赖“模型记得什么”,而是依赖每一步明确落盘的输入、输出和退出条件。
本博文对应的代码仓库见:(Github)[https://github.com/seedily/claude-coding-skills]
背景
在 Claude Code 中做复杂开发时,最容易出问题的不是代码能力,而是流程漂移。
常见情况包括:
- 需求还没澄清,就开始写代码。
- 文件范围没定位清楚,改动越做越大。
- 方案没有记录,后续评审不知道按什么标准判断。
- 测试失败后继续更新文档,造成“文档看起来完成,代码实际不可用”。
- 中断后恢复时,不知道应该从哪一步继续。
fully-coding 用 workflow-rules.md 显式定义了每一步的进入条件、必填输入、必填输出和退出条件。这个设计让每一步都变成一个可验证的关卡。
这正是 SDD(Specification-Driven Development,规范驱动开发)的核心:规范先于实现存在,并且是流程推进的第一性产物。fully-coding 不是先写代码再补说明,而是先把需求、范围、方案、实现记录、评审结论和测试结果变成明确规范,再让下一步基于这些规范继续。这样一来,其工作过程就不会完全依赖会话上下文,从而能够支持超长周期的编程任务。
什么是步骤契约
步骤契约可以理解为每一步的最小完成标准。
它不替代角色 Prompt,也不规定所有实现细节,而是回答四个问题:
- 这一步什么时候可以开始?
- 这一步必须读取什么输入?
- 这一步必须写出什么输出?
- 这一步满足什么条件才能进入下一步?
这四个问题把每个步骤都变成了可交接单元。只要文档字段完整,下一个角色、下一次执行,甚至中断后的续跑进程,都能知道“上一棒交付了什么、当前还能不能继续”。
在 fully-coding 中,所有步骤都遵守通用契约:
- 进入前检查当前步骤条件是否满足。
- 执行中更新 heartbeat、current-step、current-role、pid。
- 离开前确认必填输出已经写入文档。
- 如果章节标题存在但必填输出为空,视为步骤未完成。
- 如果无法补齐必填输出且流程无法继续,登记阻塞。
9 步契约概览
| 步骤 | 目标 | 必填输出 |
|---|---|---|
| Step 1 需求检索 | 找到需求终稿与当前任务的关系 | 原始提示词、特性摘要、需求命中情况、相关章节、差异 |
| Step 2 需求生成 | 把需求整理成可开发条目 | 新增/变更需求、验收标准、需求假设、歧义记录、关联文档 |
| Step 3 开发范围 | 定位服务、模块和文件 | 影响服务、影响模块、改动文件清单、git 分支信息 |
| Step 4 开发方案 | 写出可指导编码的方案 | 方案摘要、功能实现文档路径、关键设计决策、错误码、幂等设计 |
| Step 5 开发实现 | 按方案修改代码 | 代码变更、编译结果、错误码使用、幂等实现情况 |
| Step 6 代码评审 | DBA + Reviewer 检查风险 | DBA 意见、Reviewer 意见、问题分级、修复结果、评审结论 |
| Step 7 测试用例 | 补充并执行测试 | 测试覆盖、测试结果、未覆盖项说明 |
| Step 8 文档更新 | 同步知识库 | 更新文档清单、错误码文档更新、代码与文档偏差说明 |
| Step 9 自主进化 | 自检流程与文档一致性 | suggestion.md、Step 9 记录、completed 状态 |
契约如何防止流程漂移
1. 防止过早写代码
Step 5 的进入条件要求 Step 4 已经明确开发方案,或者在 --quick-dev 模式下至少记录轻量实现思路。
这意味着标准模式下不能从“需求一句话”直接跳到代码修改。模型必须先记录范围和方案,再进入实现。
2. 防止评审没有依据
Step 6 的输入包括:
- 本次代码 diff。
codingLog.mdStep 5。- 所有相关 rules。
- 错误码文档。
评审不是泛泛看代码,而是围绕前面文档中记录的方案、实现、错误码、幂等性和项目规则来判断。
3. 防止测试失败还继续交付
Step 7 的退出条件明确要求:
- 已补充或更新必要测试。
- 测试已执行,无法执行时必须说明原因。
- 失败测试已自动修复,或达到阻塞条件后登记 blockLog。
- 不得带未解释的失败测试进入 Step 8。
这条规则让文档更新不能掩盖代码质量问题。
4. 防止文档和代码脱节
Step 8 要求根据最终代码实现反向更新知识库,尤其是:
- 服务设计文档。
- 功能实现文档。
- 功能实现概览。
- 菜单功能迭代文档。
- 错误码文档。
如果新增或修改了功能实现文档,还要同步概览表;如果涉及菜单、页面、路由、权限入口,还要同步菜单功能迭代表。
三种执行模式下的契约差异
fully-coding 支持三种模式,每种模式的契约不同。
| 模式 | 执行范围 | 完成状态 | 关键约束 |
|---|---|---|---|
| 标准模式 | Step 1-9 | completed |
完整交付闭环 |
--plan-only |
Step 1-4 | planned |
不修改业务代码,不运行 Step 5-9 |
--quick-dev |
最小需求记录 → Step 3 → Step 5 → Step 6 → Step 7 | completed |
不执行完整 Step 4/8/9,只记录必要需求、范围、实现、评审和测试 |
这个设计解决了一个现实问题:不是所有任务都值得跑完整 9 步,但也不能为了轻量而完全放弃工程约束。
--plan-only用于先审方案。--quick-dev用于小 bug 和明确小改动。- 标准模式用于完整企业交付。
auto-fix 与 block 的分级契约
fully-coding 中,评审和测试不是发现问题就停。它把问题分成两类:
| 类型 | 含义 | 处理方式 |
|---|---|---|
| auto-fix | 可通过代码、SQL、配置或测试补充自动修复的问题 | 自动修复,最多 3 轮 |
| block | 致命且无法自动修复,必须用户决策的问题 | 达到阻塞标准后登记 blockLog 并暂停 |
auto-fix 包括命名、类型安全、业务校验、数据库索引、性能优化、测试不足等问题。
block 只用于更严格的情况,例如:
- 可被外部利用且修复涉及重大架构变更的安全漏洞。
- 可能导致生产数据不可逆损坏且需要用户决策的数据风险。
- 会破坏已发布 API 契约且无法兼容的接口变更。
- 需求本身矛盾,AI 无法判断正确方向。
关键原则是:如果能自动修,就不要阻塞用户。
契约和日志模板的关系
coding-log-template.md 是步骤契约的落盘载体。
它包含:
- Step 3 开发范围。
- Step 4 开发方案。
- Step 5 开发实现。
- Step 6 代码评审。
- Step 7 测试用例。
- Step 8 文档更新。
- Step 9 自主进化。
- 任务状态。
- 阻塞记录。
每个字段都是后续判断的依据。例如 Step 4 中的“幂等性设计说明”,会影响 Step 5 的实现检查和 Step 6 的评审检查。
契约带来的收益
1. 可恢复
中断恢复时,Orchestrator 可以读取 codingLog.md,判断哪个章节已经完成,哪个章节只是标题存在但字段为空。
2. 可审计
用户可以回看每一步的产物,知道为什么改这些文件、为什么使用这些错误码、为什么新增或复用某个功能实现文档。
3. 可交接
每一步都有明确输入、输出和退出条件,产物不是散落在对话里的临时结论,而是能被下游步骤直接读取的规范文档。这让流程可以被自动化调度,也让超长周期任务在跨天、跨会话甚至中断恢复时仍然有清晰边界。
4. 可控失败
失败不是静默发生的。能修复就自动修复;不能修复就登记 blockLog,并明确需要用户做什么决策。
5. 可持续优化
Step 9 会生成 suggestion.md,把本次执行中发现的工具改进建议记录下来,反向改进流程、模板和规则。
常见问题
为什么不直接让模型自由发挥?
因为企业项目更看重可追踪和可恢复。自由发挥适合探索,契约化适合交付。
为什么每步都要落盘?
因为落盘文档是后续角色的输入,也是中断恢复和审计的依据。如果只依赖对话上下文,一旦上下文压缩或进程中断,状态就很难还原。
为什么 block 标准这么严格?
因为过度阻塞会让自动化流程失去意义。fully-coding 的默认策略是能自动修就自动修,只有真正需要用户决策时才暂停。
总结
fully-coding 的步骤契约解决的是“复杂任务如何稳定交付”的问题。
它的基础思想是 SDD:把规范作为第一性产物,而不是把规范当成代码完成后的附属说明。
它的价值不在于让流程变多,而在于让每一步都有明确边界:
- 开始前知道输入是否足够。
- 执行中知道应该写出什么。
- 结束时知道能不能进入下一步。
- 中断后知道从哪里恢复。
这就是 fully-coding 从“代码生成命令”变成“交付流水线”的关键。

浙公网安备 33010602011771号