CC端到端开发skill:心跳、阻塞与续跑机制
前言:这篇文章介绍
fully-coding的运行时可靠性设计。它通过 heartbeat、任务状态机、blockLog 和 auto-resume,让一次长时间 Claude Code 开发任务在中断后仍能安全恢复。
本博文对应的代码仓库见:(Github)[https://github.com/seedily/claude-coding-skills]
背景
Claude Code 执行复杂任务时,常见风险不是“不会写代码”,而是任务运行时间变长后状态失控。
例如:
- 任务跑到一半,终端关闭了。
- 电脑重启,执行状态丢失。
- 流程遇到需要用户确认的风险,但没有明确记录。
- 用户重新启动任务,却不知道该从 Step 4 继续,还是从 Step 5 继续。
- 多个恢复进程同时尝试接管同一个任务,导致重复执行。
fully-coding 用一套心跳与续跑规则处理这些问题。核心文件是 heartbeat-resume-rules.md,核心状态记录在 {ts}-codingLog.md 的 frontmatter 中。
这套机制能成立,前提是每一步都已经按 SDD(Specification-Driven Development,规范驱动开发)的方式落盘。也就是说,规范是第一性产物:当前状态、当前步骤、阻塞原因、恢复入口都不是依赖临时对话记忆,而是写在可读取的文档字段里。
心跳字段
每个任务的 codingLog.md frontmatter 都会维护一组状态字段:
---
type: coding-log-template
status: running
last-heartbeat: 20250615-120530
current-step: 5
current-role: developer
pid: 12345
batch-subtask: false
---
这些字段分别表示:
| 字段 | 作用 |
|---|---|
status |
当前任务状态 |
last-heartbeat |
上次心跳时间 |
current-step |
当前执行到第几步 |
current-role |
当前主导角色 |
pid |
当前 Orchestrator 进程标识 |
batch-subtask |
是否为 batch 子任务 |
其中最关键的是 status 和 last-heartbeat。前者说明任务处于什么阶段,后者说明原执行进程是否可能失联。
任务状态机
fully-coding 定义了 7 种任务状态:
| 状态 | 含义 |
|---|---|
running |
正在执行 |
resuming |
某个恢复进程正在尝试接管 |
blocked |
遇到阻塞,等待用户确认 |
stalled |
心跳超时,原进程无响应 |
failed |
任务失败且无法继续 |
planned |
--plan-only 已完成 Step 1-4,等待用户决定是否继续实现 |
completed |
已完成 |
状态流转可以用下面的图表示:
这套状态机的重点是避免“误恢复”和“重复恢复”。
为什么需要 resuming 状态
假设某个任务已经 stalled,同时有两个恢复动作被触发:
- 用户手动执行
/fully-coding --auto-resume。 - 定时任务也执行了
/fully-coding --auto-resume。
如果没有 resuming 这个过渡状态,两个进程可能同时认为自己可以接管,然后重复执行同一个步骤。
fully-coding 的做法是:
- 恢复前先把状态写成
resuming。 - 写入当前进程的
pid和最新last-heartbeat。 - 再次读取 frontmatter 确认状态仍属于自己。
- 确认成功后,才改为
running并继续执行。
这相当于一个轻量的原子接管协议。
auto-resume 的判断顺序
续跑不是直接继续,而是按顺序检查。
这个顺序能避免三类错误:
- 已完成任务被重复执行。
--plan-only产物未经用户确认就自动进入开发。- 阻塞事件未处理就继续往下跑。
planned 状态的特殊性
planned 是 --plan-only 的完成状态。它表示 Step 1-4 已经完成,任务已经生成需求、范围和方案,但还没有修改业务代码。
普通 --auto-resume 不会自动接管 planned 任务。
如果用户确认要继续实现,需要显式执行:
/fully-coding --start-step 5 --task-id {ts}
这个设计很关键。因为 --plan-only 的语义是“先审方案”,不能让自动续跑在用户未确认的情况下进入代码实现。
blockLog 的作用
blockLog.md 不是普通日志,它只在流程必须暂停等待用户确认时创建。
典型情况包括:
- 3 次自动修复后仍无法解决的 block 级问题。
- 3 次测试修复后仍失败且无法继续。
- 破坏性或不可逆操作需要用户决策。
- 当前角色无法自行修复的步骤失败。
blockLog 的价值是把“为什么停下来”写清楚:
| 字段 | 作用 |
|---|---|
| 阻塞步骤 | 哪一步停了 |
| 阻塞类型 | 评审阻塞、测试失败、编译错误、外部依赖缺失等 |
| 阻塞原因 | 为什么不能自动继续 |
| 修复建议 | 用户可以怎么处理 |
| 用户确认状态 | 待确认 / 已确认 |
| 用户处理方案 | 用户最终如何决策 |
它不是日志堆积,而是一份交接文档。无论是用户接手判断,还是后续自动恢复继续执行,都能先读到明确可见的暂停原因和恢复条件。
什么时候不登记 blockLog
fully-coding 特别强调:不是一有问题就登记 blockLog。
以下情况不登记:
- Step 6 评审发现问题,但仍在 3 次自动修复循环内。
- Step 7 测试失败,但仍在 3 次自动修复循环内。
- Step 6 有条件通过,流程可以继续。
这个规则避免了 blockLog 被普通修复噪音污染。只有真正需要用户确认的中断,才进入 blockLog。
batch 子任务如何隔离
fully-coding-batch 会把一个大需求拆成多个子任务,每个子任务复用 fully-coding 的 Step 3-9。
为了避免独立任务和 batch 子任务互相抢占,codingLog.md 会包含:
batch-subtask: true
独立任务的 --auto-resume 会跳过 batch 子任务。batch 子任务由 fully-coding-batch --auto-resume 统一调度。
这保证了两类任务的恢复边界清晰。
这套机制适合什么场景
心跳和续跑机制特别适合:
- 长时间执行的企业功能开发。
- 需要跨多轮自动修复的任务。
- 会产生多个文档和代码变更的复杂任务。
- 需要定时自动接管 stalled 任务的场景。
- batch 串行开发多个子任务的场景。
它尤其适合超长周期编程。因为任务周期越长,越不能只依赖“模型还记得什么”,而要依赖规范化文档把状态、决策和阻塞点固定下来。
它不一定适合很小的一次性任务。对于只改一行配置的小任务,完整状态机可能显得重。
总结
fully-coding 的心跳与续跑机制解决的是“长任务如何不中断、不重复、不失控”的问题。
它的关键设计包括:
- 用 frontmatter 保存运行状态。
- 用 heartbeat 判断原进程是否失联。
- 用
resuming做原子接管。 - 用
planned保护方案模式不自动进入开发。 - 用
blockLog.md记录真正需要用户确认的阻塞。 - 用
batch-subtask隔离独立任务和批次子任务。
这些机制让 fully-coding 更像一个可恢复的开发状态机,而不是一次性代码生成命令。

浙公网安备 33010602011771号