mcpField
L
long-run

long-run

github.com/tmdgusyaAgent 工作流12545 次安装17 周前更新
代码仓库

关于 long-run

Long Run Harness 通过里程碑流水线编排复杂的多日任务。它将执行状态和检查点持久化以支持恢复,为每个里程碑执行计划、运行、审查流程,并在审查失败时阻止依赖任务。

主要功能

  1. 01按里程碑流水线执行工作
  2. 02在状态转换前保存状态
  3. 03从已保存的检查点恢复
  4. 04落实计划、运行、审查流程
  5. 05失败时阻止依赖任务
  6. 06并行执行符合条件的里程碑

适用场景

  1. 01中断后继续多日任务
  2. 02执行预先规划的里程碑
  3. 03协调相互独立的里程碑工作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tmdgusya/engineering-discipline --skill long-run

安装后在 Claude Code 中输入/long-run确认已加载。

详细介绍

长程运行调度器

通过里程碑流水线协调复杂任务的多日执行。每个里程碑都会依次经历 plan-crafting → run-plan → review-work,里程碑之间设有检查点,以便在中断后恢复。

核心原则

长时间运行的执行必须可恢复、可审计且故障安全。每次状态转换都会在下一项操作开始前持久化到磁盘。如果执行因任何原因停止——速率限制、崩溃、用户暂停、上下文丢失——都可以从上一个检查点恢复,而不必重复已完成的工作。

硬性门槛

  1. 执行前必须先有里程碑。 里程碑必须来自 milestone-planning skill 或由用户提供。执行期间绝不内联生成里程碑。
  2. 每个里程碑执行前后都必须更新状态文件。 不得只在内存中保存状态。如果没有写入磁盘,就等于没有发生。
  3. 每个里程碑都必须完成完整流水线。 plan-crafting → run-plan → review-work。不得走捷径。不得因为“看起来没问题”就跳过 review-work。
  4. 失败的里程碑会阻塞其依赖项。 如果 M2 依赖 M1,而 M1 未通过 review,M2 就不会启动。没有例外。
  5. 默认自主执行——里程碑之间不设审批门槛。 用户只在 milestone-planning 锁定里程碑计划时审批一次。从那时起,里程碑会按 plan → run → review → checkpoint 的顺序推进,无需暂停等待确认。仅在以下情况停止并询问:某个里程碑耗尽重试次数(failed)、Mid-Execution Correction 需要确定范围、触发集成升级,或加载的状态不一致。每个阶段转换时发布简短的状态报告,让用户随时可以中断——状态文件可确保每次暂停后都能恢复。
  6. 绝不修改已完成的里程碑。 里程碑通过 review-work 后,其文件即被锁定。如果后续里程碑需要修改前序工作,应将其作为一个新里程碑。
  7. 每个里程碑完成后都要创建检查点。 继续执行前,写入检查点文件,记录已完成的工作、测试结果和审核结论。

适用场景

  • milestone-planning 已生成里程碑 DAG 后
  • 用户说“long run”“start long run”“execute milestones”或“run all milestones”时
  • 恢复之前暂停的长程运行会话时

不适用场景

  • 里程碑尚不存在时(先使用 milestone-planning)
  • 只有一个里程碑时(直接使用 plan-crafting + run-plan)
  • 对于不需要多阶段执行的快速任务

输入

  1. 调度器状态目录路径 — 例如:docs/engineering-discipline/harness/<session-slug>/
  2. 该目录必须包含 state.md 和 milestones/*.md 文件

如果状态目录不存在,询问用户是否要先运行 milestone-planning。

流程

阶段 1:加载并验证状态
  1. 从调度器目录读取 state.md
  2. 从 milestones/ 读取所有里程碑文件
  3. 验证:
    • state.md 中引用的所有里程碑都有对应文件
    • 依赖 DAG 有效(无循环,且可以进行拓扑排序)
    • 没有里程碑处于无效状态(例如,处于“executing”状态但没有计划文件)
  4. 确定当前位置:
    • 哪些里程碑已完成?
    • 哪些里程碑已准备好启动(所有依赖项都已满足)?
    • 这是全新开始还是恢复执行?
  5. 向用户展示状态:
## Long Run Status: [Session Name]

**Progress:** N/M milestones completed
**Current phase:** [planning M3 | executing M3 | reviewing M3 | ready to start M3]
**Next up:** [M3, M4 (parallel)]

Completed: M1 ✓, M2 ✓
In progress: M3 (executing)
Pending: M4, M5
  1. 如果加载的状态一致,立即继续——状态展示是报告,不是门槛。只有当第 3 步的验证发现不一致,或 failed 里程碑阻塞后续进度时,才询问用户。
阶段 2:里程碑执行循环

按拓扑顺序处理每个里程碑:

┌─────────────────────────────────────┐
│         Milestone Pipeline          │
│                                     │
│  ┌──────────┐    ┌─────────┐        │
│  │  Plan    │───→│  Run    │        │
│  │ Crafting │    │  Plan   │        │
│  └──────────┘    └────┬────┘        │
│                       │             │
│                  ┌────▼────┐        │
│                  │ Review  │        │
│                  │  Work   │        │
│                  └────┬────┘        │
│                       │             │
│              ┌────────▼────────┐    │
│              │   PASS?         │    │
│              │  Yes → checkpoint│    │
│              │  No  → retry    │    │
│              └─────────────────┘    │
└─────────────────────────────────────┘
步骤 2-1:门槛检查

启动里程碑前:

  1. 确认所有依赖里程碑的状态均为 completed
  2. 确认没有文件与正在并行执行的里程碑冲突
  3. 更新 state.md:将里程碑状态设为 planning
  4. 使用时间戳更新执行日志
第 2-2 步:制定计划阶段
  1. 根据里程碑定义编写上下文摘要:
    • 目标 → 来自里程碑文件
    • 范围 → 里程碑文件中受影响的文件
    • 成功标准 → 来自里程碑文件
    • 约束 → 从父级问题 + 已完成里程碑的上下文继承
    • 已完成里程碑上下文约定: 对于每个已完成的前置里程碑,仅包含:
      • 创建/修改的文件(来自检查点的“Files Changed”列表)
      • 已确立的接口约定(函数签名、API 形状、类型定义)
      • 已验证达成的成功标准
    • 不要包含:执行日志、审查文档、执行者/验证者的输出,或完整检查点内容
    • 注意: 根据里程碑定义编写的上下文摘要不包含复杂度评估部分,因为路由已在里程碑规划阶段确定。摘要直接进入计划制定阶段,不再重新路由。
  2. 按照 plan-crafting 技能模式执行:
    • 在 docs/engineering-discipline/plans/YYYY-MM-DD-<milestone-name>.md 创建计划文档
    • 计划必须满足所有里程碑成功标准
    • 计划不得修改里程碑范围以外的文件
  3. 更新 state.md:记录此里程碑的计划文件路径
  4. 报告,但不等待批准: 发布简短的计划摘要(目标、任务数、涉及的文件)作为进度报告,并直接继续执行。
第 2-3 步:执行计划阶段
  1. 更新 state.md:将里程碑状态设为 executing,并将 Attempts 计数器加 1
  2. 按照 run-plan 技能模式执行计划:
    • 每项任务都进行执行者-验证者循环
    • 对独立任务进行并行执行
    • 验证者的信息相互隔离
  3. 如果 run-plan 在某项任务重试 3 次后仍报告失败:
    • 更新 state.md:将里程碑状态设为 failed
    • 在执行日志中记录失败详情
    • 停止并向用户报告。 不要继续处理依赖此里程碑的后续里程碑。
  4. 如果所有任务均已完成:进入审查阶段
第 2-4 步:审查工作阶段
  1. 更新 state.md:将里程碑状态设为 validating
  2. 按照 review-work 技能模式执行:
    • 根据计划文档进行信息隔离审查
    • 给出二元的 PASS/FAIL 判定
  3. 如果 PASS:
    • 更新 state.md:将里程碑状态设为 completed
    • 写入检查点文件(参见下文的检查点格式)
    • 更新执行日志
    • 继续下一个里程碑
  4. 如果 FAIL:
    • 在执行日志中记录审查发现
    • 重试决策(根据 state.md 中跨崩溃保留的 Attempts 计数器):
      • 如果 Attempts == 1:返回第 2-3 步,并附上审查反馈(重新执行同一计划)
      • 如果 Attempts == 2:返回第 2-2 步(将审查反馈作为约束重新制定计划)
      • 如果 Attempts >= 3:将状态设为 failed,停止并向用户报告
步骤 2-5:跨里程碑集成检查

里程碑通过 review-work 后,但在写入检查点之前,请验证该里程碑的输出是否与之前完成的所有里程碑正确集成:

  1. 运行项目最高级别的验证(使用 state.md 中的 Verification Strategy,或按照 plan-crafting 的 Verification Discovery 顺序重新发现)
  2. 检查跨里程碑接口: 如果已完成的里程碑定义或使用了前置里程碑的接口,请验证它们是否兼容(函数签名匹配、API 契约有效、类型一致)

如果集成检查通过: 继续写入检查点。

如果集成检查失败 — 跨里程碑失败响应:

该里程碑已通过自身的 review-work(内部正确性),但破坏了与其他里程碑的集成。这是一个边界问题。

  1. 诊断(尝试 1):

    • 阅读失败输出
    • 确定哪个接口边界或交互出现问题
    • 判断修复属于当前里程碑,还是需要新增纠正里程碑
    • 如果可在当前里程碑范围内修复:派发定向修复工作者 → 重新运行 review-work → 重新运行集成检查
    • 如果修复超出当前里程碑范围:升级处理
  2. 诊断(尝试 2):

    • 如果第一次修复未解决问题,重新分析
    • 应用第二次定向修复
    • 重新运行集成检查
  3. 升级给用户(2 次尝试均失败后):

    • 报告:涉及哪些里程碑、哪个集成边界失败、尝试过哪些修复
    • 选项:添加纠正里程碑、回滚到检查点、接受并继续(用户确认存在集成缺口)
    • 将用户的决定记录在 state.md 执行日志中
步骤 2-6:检查点

里程碑通过 review 后:

写入 checkpoints/M<N>-checkpoint.md:

# Checkpoint: M<N> — [Milestone Name]

**Completed:** YYYY-MM-DD HH:MM
**Duration:** [time from planning start to review pass]
**Attempts:** [number of plan-execute-review cycles]

## Plan File
`docs/engineering-discipline/plans/YYYY-MM-DD-<name>.md`

## Review File
`docs/engineering-discipline/reviews/YYYY-MM-DD-<name>-review.md`

## Test Results
[Full test suite status at checkpoint time]

## Files Changed
[List of files created/modified in this milestone]

## State After Milestone
[Brief description of system state — what works now that didn't before]
阶段 3:并行执行里程碑

当多个里程碑的所有依赖均已满足且不存在文件冲突时:

  1. 确定可并行的里程碑组
  2. 先为所有并行里程碑运行 plan-crafting(依次执行——计划很轻量)
  3. 将所有计划摘要作为一份进度报告发布(无需等待批准),然后并发派发每个里程碑的流水线:
    • 每个里程碑运行 run-plan → review-work
    • 每个里程碑都在工作树中运行(isolation: "worktree"),以防止文件冲突
    • 两者完成并通过 review 后,将工作树合并回来
  4. 如果其中一个失败:分别处理(如果不存在依赖,另一个可以继续)

工作树合并协议:

  1. 两个里程碑分别在各自的工作树中通过 review
  2. 检查工作树更改之间是否存在文件冲突
  3. 如果没有冲突:依次合并(先合并 M_lower,再合并 M_higher)
  4. 如果检测到冲突:停止,报告给用户,并请求手动解决
  5. 合并后:对合并结果运行完整测试套件
  6. 如果测试失败:停止并报告给用户
阶段 4:完成

所有里程碑完成后(包括 milestone-planning 中的 Integration Verification Milestone):

  1. 更新 state.md:将整体状态设为 completing
  2. 最终 E2E 门禁: 对完全集成的代码库最后一次运行项目最高级别的验证
  3. 运行完整测试套件以检查回归
  4. 如果最终 E2E 门禁失败:
    • 诊断:确定哪个里程碑的输出可能导致问题
    • 通过 Mid-Execution Correction 流程创建纠正里程碑
    • 通过完整流水线执行纠正里程碑(plan-crafting → run-plan → review-work)
    • 修正后重新运行 E2E 门禁
    • 如果 2 次纠正尝试均失败:向用户升级处理并提供完整诊断
  5. 如果最终 E2E 门禁通过: 更新 state.md:将整体状态设为 completed
  6. 生成完成摘要:
# Long Run Complete: [Session Name]

**Started:** YYYY-MM-DD
**Completed:** YYYY-MM-DD
**Total milestones:** N
**Total attempts:** [sum of all milestone attempts]

## Milestone Summary

| Milestone | Status | Attempts | Duration |
|-----------|--------|----------|----------|
| M1: [name] | ✓ completed | 1 | 2h |
| M2: [name] | ✓ completed | 2 | 4h |
| ...

## Final Test Suite
[PASS/FAIL — N passed, M failed]

## Files Changed (Total)
[Aggregated list across all milestones]
  1. 呈现给用户,并建议使用 simplify 进行最后一次代码质量检查

恢复协议

恢复已暂停或中断的会话时:

  1. 阅读 state.md,确定最后已知状态
  2. 针对每个里程碑,确定恢复操作:
上次状态恢复操作
pending正常开始
planning重新开始制定计划(计划文件可能不完整)
executing检查运行计划的进度;继续执行或重新开始
validating重新开始 review-work(审查可能不完整)
completed跳过(已完成检查点)
failed向用户说明失败情况;询问是重试还是跳过(见下方“跳过规则”)
skipped跳过(用户之前选择跳过此里程碑)
  1. 对于处于 executing 状态的里程碑:检查计划中的任务是否已勾选。从第一个未勾选的任务继续。
  2. 从 state.md 中读取 Attempts 计数器,确定剩余重试次数。恢复时不要重置计数器——它会在崩溃后保留,以防止无限重试。
  3. 将恢复计划作为状态报告发布,然后继续。只有当 failed 里程碑阻塞执行路径或状态不一致时,才询问用户。

执行中纠正

如果执行过程中发现已完成里程碑的输出有误,或需要新增里程碑:

  1. 暂停执行——不要继续执行依赖该里程碑的后续里程碑
  2. 记录发现,在 state.md 的执行日志中说明发现的问题以及触发发现的里程碑
  3. 需要用户决策: 向用户说明情况和选项:
    • 添加纠正里程碑: 创建新的里程碑定义(由用户编写目标和成功标准,或仅针对新范围重新运行 milestone-planning)。将其按适当依赖关系插入 DAG。然后从新里程碑恢复执行。
    • 从检查点重新规划: 回退到某个已完成里程碑的检查点,将后续里程碑标记为 pending,并将其 Attempts 重置为 0,然后从该位置重新开始。
    • 中止: 将整体状态设为 failed 并停止。
  4. 新里程碑遵循相同的流程——plan-crafting → run-plan → review-work。即使是“快速修复”,也不能走捷径。
  5. 绝不修改已完成的里程碑(硬性门槛 #6 仍然适用)。纠正里程碑会通过完整的计划周期生成新文件或覆盖现有文件。

跳过规则

用户选择跳过失败的里程碑时:

  1. 在 state.md 中将里程碑状态设为 skipped
  2. 在执行日志中记录跳过事件及用户给出的原因
  3. 默认情况下,被跳过里程碑的依赖项也会被阻塞——与 failed 相同。DAG 的约定是:只有前置条件为 completed 时,依赖项才能运行。
  4. 用户可以通过确认缺少前置条件,明确解除对依赖项的阻塞:“尽管 M2 已跳过,仍继续执行 M4。”在执行日志中记录此例外。
  5. 如果用户解除对依赖项的阻塞,在 plan-crafting 期间向该里程碑的 Context Brief 添加备注:“前置条件 M2 已跳过。以下输出缺失:[根据 M2 的成功标准列出]。”

**已跳过的里程碑无法取消跳过。**如果用户希望之后尝试该里程碑,请创建一个目标相同的新里程碑。

时长限制

如果单个里程碑的总活跃时间(从规划开始到审查完成)过长:

  1. 软限制: 如果里程碑处于 planning 或 executing 状态的时间,明显占整体工作的比例过大,则暂停并向用户报告:“里程碑 M3 已进行较长时间。继续、缩小范围还是中止?”
  2. 尝试次数硬限制: 3 次尝试上限(F1)限制了重试循环。但如果单次尝试的 plan-crafting 生成了 15 个以上的任务,则暂停并报告:“此里程碑的计划包含 N 个任务——对于单个里程碑来说可能过大。请考虑拆分。”
  3. 目的: 防止单个失控的里程碑耗尽整个执行预算,或因测试不稳定而无限期运行。

上下文窗口管理

长时间运行的会话会达到上下文窗口限制。Claude Code 会自动压缩较早的消息(上下文折叠)。必须设计好执行框架以应对这种情况:

  1. 绝不要依赖对话记忆来保存状态。 所有状态都保存在磁盘上的 state.md 和里程碑文件中。如果上下文被压缩,执行框架会重新读取状态文件,不会丢失任何信息。
  2. 每个里程碑都是一个全新的上下文边界。 开始为新里程碑制定计划时,工作子 Agent 会从干净的上下文开始。它只会收到里程碑定义和已完成前置里程碑的上下文(见 F8 约定),而不会收到完整的对话历史。
  3. 检查点文件是唯一可信来源。 如果在里程碑执行期间上下文丢失,恢复时应读取检查点文件,而不是经过压缩的对话摘要。
  4. 避免累积大量内联状态。 不要在对话中不断汇总所有里程碑。应通过路径引用 state.md 和检查点文件。

速率限制处理

长时间运行的会话会遇到速率限制。Claude Code 内置了带指数退避的重试机制(最多重试 10 次,最长退避 5 分钟)。执行框架应配合此机制,而不是与之对抗:

  1. 让 claude-code 处理临时速率限制。 短暂的 429/529 错误会自动进行退避重试。不要每次遇到 API 错误就提前保存状态。
  2. 遇到持续的速率限制时保存状态。 如果速率限制持续时间超过自动重试窗口(你会看到反复出现的“rate limit”消息),请立即将当前状态记录到磁盘。
  3. 在执行日志中记录速率限制事件及其时间戳。
  4. 向用户报告:“遇到速率限制。状态已保存。准备好后使用 long-run 恢复。”
  5. 不要在 claude-code 的内置重试机制之上添加手动重试循环,这会导致重试放大。
  6. 后台 Agent 中止: Claude Code 的后台 Agent(例如 critic 子 Agent)遇到 529 过载错误时会立即中止,而不是重试。因此,milestone-planning 中的 critic 失败处理(重新分派一次,使用最低可行评审小组)才有必要——critic 失败往往由临时速率限制导致,而不是永久性错误。

反模式

反模式失败原因
不使用 milestone-planning,而是在内联内容中生成里程碑里程碑缺少对抗性评审;分解效果不佳
因为里程碑“很简单”而跳过 review-work未发现的缺陷会在多个里程碑中累积
里程碑失败后仍继续执行依赖它的里程碑会建立在有问题的基础之上
阶段之间不更新 state.md崩溃会导致进度丢失,无法恢复
修改已完成的里程碑文件破坏检查点不变性,使评审结果失效
不使用 worktree 隔离并行运行里程碑文件冲突会破坏两个里程碑
遇到速率限制时自动重试浪费配额;用户可能更愿意等待
在里程碑之间暂停以请求批准违背自主执行的初衷——用户在锁定里程碑时已选择完整运行。仅在失败和范围变更时升级处理
未检查冲突便合并 worktree文件重叠时会造成无声的数据丢失
跳过跨里程碑集成检查里程碑各自通过,但在边界处彼此破坏
未经用户升级处理便无限重试 E2E 失败设置 2 次尝试上限,是为了避免在误诊问题上浪费预算

最小检查清单

  • 状态目录存在,且包含有效的 state.md 和里程碑文件
  • 已验证依赖 DAG(无环)
  • 已确定当前位置(全新开始或恢复进度)
  • 在会话开始时和每次阶段转换时发布状态报告
  • 每个里程碑都经过 plan-crafting → run-plan → review-work
  • 每次阶段转换前后都更新 State.md
  • 每个里程碑成功完成后都编写检查点
  • 失败的里程碑会阻止其依赖项
  • 并行里程碑使用 worktree 隔离
  • 每个里程碑完成后都通过跨里程碑集成检查
  • 最终 E2E Gate 在完成时通过
  • 完成时通过完整测试套件

转换

长期运行完成后:

  • 最终代码质量检查 → simplify 技能
  • 如果在完成测试中发现问题 → systematic-debugging 技能
  • 如果用户想添加更多里程碑 → milestone-planning 技能

此技能本身不会调用下一个技能。它会报告完成情况,并由用户决定下一步。

评论

支持 Markdown