CC端到端开发skill:步骤契约的重要性

前言:这篇文章解释 fully-coding 中最重要的治理机制:步骤契约。它让一次 Claude Code 开发任务不再依赖“模型记得什么”,而是依赖每一步明确落盘的输入、输出和退出条件。

本博文对应的代码仓库见:(Github)[https://github.com/seedily/claude-coding-skills]

背景

在 Claude Code 中做复杂开发时,最容易出问题的不是代码能力,而是流程漂移。

常见情况包括:

  • 需求还没澄清,就开始写代码。
  • 文件范围没定位清楚,改动越做越大。
  • 方案没有记录,后续评审不知道按什么标准判断。
  • 测试失败后继续更新文档,造成“文档看起来完成,代码实际不可用”。
  • 中断后恢复时,不知道应该从哪一步继续。

fully-codingworkflow-rules.md 显式定义了每一步的进入条件、必填输入、必填输出和退出条件。这个设计让每一步都变成一个可验证的关卡。

这正是 SDD(Specification-Driven Development,规范驱动开发)的核心:规范先于实现存在,并且是流程推进的第一性产物。fully-coding 不是先写代码再补说明,而是先把需求、范围、方案、实现记录、评审结论和测试结果变成明确规范,再让下一步基于这些规范继续。这样一来,其工作过程就不会完全依赖会话上下文,从而能够支持超长周期的编程任务。

什么是步骤契约

步骤契约可以理解为每一步的最小完成标准。

它不替代角色 Prompt,也不规定所有实现细节,而是回答四个问题:

  1. 这一步什么时候可以开始?
  2. 这一步必须读取什么输入?
  3. 这一步必须写出什么输出?
  4. 这一步满足什么条件才能进入下一步?

这四个问题把每个步骤都变成了可交接单元。只要文档字段完整,下一个角色、下一次执行,甚至中断后的续跑进程,都能知道“上一棒交付了什么、当前还能不能继续”。

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.md Step 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:把规范作为第一性产物,而不是把规范当成代码完成后的附属说明。

它的价值不在于让流程变多,而在于让每一步都有明确边界:

  1. 开始前知道输入是否足够。
  2. 执行中知道应该写出什么。
  3. 结束时知道能不能进入下一步。
  4. 中断后知道从哪里恢复。

这就是 fully-coding 从“代码生成命令”变成“交付流水线”的关键。

posted @ 2026-06-23 19:33  鱼007  阅读(10)  评论(0)    收藏  举报