---
description: harness-plan 的阶段检查清单和覆盖检查列表。仅在执行完整需求规划时读取。
---

# harness-plan 检查清单

## 阶段 0：工作区变更检查 ⚠️ 强制检查

> 有未提交业务变更（排除 `.harness/`）→ **默认 baseline 隔离**，append `decision` 事件，**不 blocking user confirmation**，继续规划。PowerShell 失败 → ❌ 停止。

**固定命令**：`powershell.exe -Command "git -C '<项目路径>' status --porcelain"`

**判定**：stdout 为空 → ✅ 继续；stdout 非空 → baseline 隔离 + `decision`（note 含变更文件列表）；Bash 被拒 → PowerShell 重试。

## 阶段 0.5：一次性引导与知识查询

- [ ] 定好 change-name（kebab-case）与中文展示标题后，运行一次 `harness_context.py bootstrap-plan --project . --change <cn> --executor <tool> --title "<中文标题>" --json`
- [ ] 引导返回 `code:"PLAN_BOOTSTRAPPED"`，记下 `runId`/`attempt`/`tier`/`defaultPhases`/`changeBase`；后续 finalize 必须复用同一 `runId`/`attempt`
- [ ] 不再手工生成 run-id、不再单独跑 doctor/prepare/capture/classify/append；需要单步排查时才用 SKILL.md 阶段 0.5b 的等价分解
- [ ] 引导失败时按返回的 `code` 处理（`PROJECT_ROOT_INVALID` → 该项目未 init），**不得**跳过引导直接写产物
- [ ] 触发条件成立（涉及历史取舍/兼容边界/疑似重复问题/用户要求延续）才执行一次远端 knowledge `query`，全新独立需求跳过；不另跑前置 sync，不创建本地索引
- [ ] 查询失败追加 `issue`，不得回退本地 archive/SQLite、重跑“sync + query”循环或假装已读取历史

## 阶段 2：歧义优先检查与复杂度分级

- [ ] 否定、对比、动作对象、范围或保留/删除关系不存在未确认的多义解释
- [ ] 若存在歧义，仅完成最小取证后一次一问，并给出推荐理解
- [ ] **需求里引用了外部设计文档/章节（贴了段落、给了 `xxx.md` 的 `### Bn` 小节、说"之前设计的时候如…"）时，必须确认该章节本次是否纳入**——引用不等于纳入，也不等于排除。把它列进 `in_scope` 或 `out_of_scope` 后再进入阶段 4；漏判会导致计划发布后整体作废重来（republish），是本流程最贵的返工
- [ ] 简单修复探索预算：最多 1 次合并 CodeGraph 查询 + 1 次定向补查、1 个澄清问题
- [ ] 无关发现只记非阻断 `issue`，未扩展当前方案或问题列表

## 设计审批包字段：Worktree

> worktree 不再单独询问。阶段 4 **设计审批包** 一次 blocking user confirmation 含 worktree 选项（推荐值读 `harness.json` `defaultWorktree`）。确认后写入 `meta/worktree.json`。

- [ ] 审批包确认后写入 worktree.json（`requested` true/false）
- [ ] 阶段 8 检查 worktree.json 存在

## 阶段 3：代码探索确认（含 Agent/CodeGraph 降级记录）

阶段 3 执行完成后，确认以下事项：

```
□ 已按复杂度选择 `executionMode=inline|delegated`；默认 inline
□ inline 时主会话直接使用 CodeGraph/Read，并返回结构化设计概要
□ 仅高复杂度且准备委派固定 agent 时，才运行一次 `check-agents --agent harness-explorer`
□ 只有预检 `executionMode=delegated` 才委派；`inline` 静默继续，不显示不可用告警
□ spawn 失败、空返回、0 tool uses、仅 "Done"/元数据 → 主会话探索，**不 retry 委派**
□ 执行日志记录 executionMode、委派原因（如有）、只读约束和核心结论
```

> 正常 inline 只记 `decision`，不是降级或故障。如果已尝试委派但未返回有效输出（0 tool uses / 空返回 / 仅 "Done"），必须：
> - 追加一次 `issue` 事件并在 note 写明：子代理未返回有效输出，改为主会话只读探索
> - 主会话直接使用 codegraph MCP 工具（`mcp__codegraph__codegraph_explore`）和 Read 探索代码（只读，不执行写操作）
> - 不得在主会话中执行任何写操作
> - CodeGraph 如通过 MCP 调用，必须优先用 MCP 工具，不允许通过普通 Bash 调 codegraph 命令
> - 禁止把子代理未经工具验证的文本结论当作"详尽报告"或代码证据采纳

## 影响面检查（远程客户端路径）

变更涉及 HTTP/RPC 客户端时，在设计/任务拆分前完成路径静态比对：

- [ ] 变更涉及 HTTP/RPC 客户端（Feign/RestTemplate/SDK 封装）时：取客户端注解路径（类级 + 方法级拼接），与服务提供方 controller 的 `@RequestMapping` + 方法级注解**完整拼接路径**逐一比对，在计划/执行记录中列出比对结果。只看方法级注解不算完成。

## 阶段 4：设计审批包 ⚠️ 强制阻断（一次 blocking user confirmation）

> 合并原「设计审核 + worktree + 场景表预览 + change-name」。推荐 worktree 读 `harness.json` `defaultWorktree`。

**展示内容**：

1. 设计摘要 + 关键证据 + 风险 + 变更清单
2. **本次做什么（in_scope）/ 本次不做什么（out_of_scope）** — 两个列表都必须显式列出，不得只展示"做什么"。用户看到"不做"清单才有机会当场纠正范围误判；`out_of_scope` 为空时写"无"，不得省略该行。这两个列表随后原样进入 `plan-evidence-input.json` 的 `intent` 与 `approval.content`（两处必须集合相等）
3. 测试场景表摘要 + 8 维度覆盖检查
4. worktree 选项（是/否，含推荐理由）
5. change-name（自动生成，可修改）
6. 确认进入任务拆分

确认后立即追加 decision 事件，并写入 `meta/worktree.json`。设计文档按路径分流：

- 审批内容写进 `meta/plan-evidence-input.json` 的 `approval.content`（含 `approver_id`），
  `plans/<change>-design.md` 由 finalize 从审批内容派生——**不要**手写它，手写的会被覆盖

- [ ] 确认事件早于 approved 设计文档；未获确认时不得先落盘 `status: approved`

展示可审核包后，使用 `blocking user confirmation` 询问用户：
- **确认**：设计方向正确，继续任务拆分
- **修改**：某个部分需要调整，修改后再审核
- **取消**：方向不对，回到需求澄清阶段

### 设计文档自审清单

写完设计文档后，用以下清单自检，**并将自审结果展示给用户**：

```
□ 无"TBD"/"TODO"/未完成章节
□ 各节之间无矛盾
□ 范围聚焦，无不相关内容
□ 无歧义需求（可被两种方式解读的，已选一种并明确说明）
□ 自审结果已展示给用户
```

> 展示格式示例：
> ```
> ### 设计文档自审
> - ✅ 无 TBD/TODO/未完成章节
> - ✅ 各节之间无矛盾
> - ✅ 范围聚焦，无不相关内容
> - ⚠️ 第3.2节"枚举删除"与第4节变更清单中"标记@Deprecated"有矛盾，已修正为"删除"
> ```

## 测试场景覆盖检查表（8 维度覆盖检查表，强制输出）

> 注意：覆盖检查表是 8 维度，与 4 维度场景表（单元/接口/数据兼容/集成）是两个不同制品。

生成场景表后，逐项确认是否覆盖，**必须输出覆盖检查表展示给用户确认**。未覆盖的维度必须标记为缺口（⚠️ 缺口），不得全部标记为 ✅：

| 覆盖维度 | 状态 | 说明 |
|---|---|---|
| 正常路径 | ✅/🟡/❌ | 每个接口 ≥ 1 个正常场景 |
| 参数校验 | ✅/🟡/❌ | 必填缺失、格式非法、类型错误 |
| 业务规则 | ✅/🟡/❌ | 唯一性、范围约束、状态机 |
| 权限/组织边界 | ✅/🟡/❌ | 无权限、跨组织、角色限制 |
| 数据兼容 | ✅/🟡/❌ | 旧数据无新字段 |
| 错误码 | ✅/🟡/❌ | 每个异常对应明确错误码 |
| 集成影响 | ✅/🟡/❌ | 跨模块调用、端到端流程 |
| 并发/幂等 | ✅/🟡/❌ | 重复提交、并发修改 |

> 展示格式示例：
> ```
> ### 场景覆盖检查表
> | 覆盖维度 | 状态 | 说明 |
> |---|---|---|
> | 正常路径 | ✅ | 5 个接口各 ≥ 1 个正常场景 |
> | 参数校验 | ✅ | 必填缺失、格式非法已覆盖 |
> | 业务规则 | ✅ | 唯一性、状态机已覆盖 |
> | 权限/组织边界 | 🟡 | ⚠️ 缺口：未覆盖跨组织场景，需补充 |
> | 数据兼容 | ✅ | 旧数据 scene_code 迁移场景已覆盖 |
> | 错误码 | ✅ | 3 个错误码均有对应场景 |
> | 集成影响 | 🟡 | ⚠️ 缺口：未覆盖端到端流程，需部署后验证 |
> | 并发/幂等 | ❌ | ⚠️ 缺口：未覆盖重复提交场景，需补充 |
> ```

## 阶段 7.5：计划对抗评审（可选）确认

> 仅在用户选择启用对抗评审时执行本节检查。默认不启用（高风险构建 auth/支付/迁移/并发 才启用）。

阶段 7.5 执行完成后，确认以下事项：

```
□ 已用 **设计审批包** 一次 blocking user confirmation（设计 + 场景表摘要 + worktree + change-name）
□ **未**单独询问 worktree 或对抗评审（对抗评审仅 `--adversarial`）
□ 已按宿主能力选择隔离 evaluator 或主会话对抗自审；正常 inline 不记故障
□ 若委派，已使用隔离上下文且校验 tool uses > 0
□ 若委派返回 0/空/Done/元数据，已立即 inline 自审且未 retry
□ 已产出 VERDICT(APPROVED/REVISE) + 结构化问题清单（RED/YELLOW）
□ 评审报告已写入 .harness/changes/<change-name>/reports/plan-review/plan-review-YYYYMMDD-HHmm.md
□ VERDICT 和问题清单已展示给用户（不得仅记"已评审"）
□ REVISE 时已询问用户是否修订；修订后可选再审
□ 评审为参考性，未阻塞阶段8
□ 执行日志记录了 evaluator 调用状态（委派成功/降级原因）+ VERDICT 摘要
□ 如为主会话自审降级，已标注"⚠️ 同会话自审，回音壁风险"
```

## 原生规划协议检查

### 阶段 4：clarification + decision-grilling

阶段 4 执行完成后，确认以下事项：

```
□ 已读取 protocols.md，并按 clarification-protocol / decision-grilling-protocol 执行
□ 输入包含需求摘要 + 阶段1 context pack（如有）+ 阶段3代码探索结果 + 项目架构约束
□ 已用 decision / issue 事件 note 记录五类输出：风险识别 / 复用机会 / 替代方案 / 推荐方案 / 关键决策
□ 已叠加项目架构约束（分层规范、数据模型、接口规范）
□ 需求澄清结论已追加到 events.ndjson，阶段结束后执行日志由渲染器生成
□ 提问方式与问题预算符合 protocols.md 的 decision-grilling-protocol（预算数值以那份为准，此处不复述）
□ 能由 context pack / 阶段3代码探索 / CodeGraph 自答的问题已自答，未打扰用户
□ 每个需要用户决策的问题，AI 先给出了推荐答案、理由和取舍，用户仅确认或修正
□ 高风险/业务语义决策（范围、权限、安全、支付、迁移、删除、API契约、用户可见行为）已显式等待用户确认
```

> 不再检查 Superpowers brainstorming 是否安装或调用；阶段 4 是 harness 原生协议，不存在外部 skill 降级分支。

### 阶段 6：implementation-planning

阶段 6 执行完成后，确认以下事项：

```
□ 已读取 protocols.md，并按 implementation-planning-protocol 执行
□ 输入为阶段4已审核设计文档
□ 已用 artifact 事件 note 记录任务拆分摘要
□ 已叠加项目层序依赖（数据/契约→业务层→接口层）
□ 已生成 4 维度场景表（单元/接口/数据兼容/集成）
□ 每个自动化场景均标注执行层级、预计时长、资源预算、超时、可复用证据；快速反馈不默认扫描全仓库
□ 已确定变更名（kebab-case）
□ implementation-detail.md 按复杂度自适应：简单任务不过度展开，复杂任务写清接口/数据/顺序/风险/测试策略
□ plan / implementation-detail / test-scenarios 三件套互相引用一致，无 TBD/TODO/空泛占位
```

> 产物是否齐全、任务表与场景表是否非空、优先级与 ownerPhase 取值是否合法，由 finalizer
> fail-closed 判定（`PLAN_ARTIFACT_MISSING` / `PLAN_TASKS_EMPTY` / `PLAN_SCENARIOS_EMPTY` /
> `PLAN_SCENARIO_PRIORITY_INVALID`），此处不重复勾选。上面留下的都是机器判不了的：
> 层序依赖是否合理、维度是否真被覆盖、详略是否配得上复杂度、三件套是否自洽。

> 不再检查 Superpowers writing-plans 是否安装或调用；阶段 6 是 harness 原生协议，不存在 `docs/superpowers/` 同步分支。

## 阶段 8：结束前产物完整性检查 ⚠️ 强制

> **先认路径**：新 change 只走 v2；legacy 产物（历史 change）只读。必需文件清单 → `reference.md`「阶段 8」。

文件是否齐全、哈希是否一致、身份是否匹配、计数是否对得上——这些 **finalizer 与 verify 已经 fail-closed 判定**，逐条复述不产生新结论，只会把一份事实变成两份。命令失败时按返回的 `code` 查 `reference.md`，不要对着清单猜。

下面三条不在机器判定范围内，必须自己守：

- [ ] **v2**：只手写 `meta/plan-evidence-input.json`。`plans/*.md` 由 finalize 派生，手写的会被渲染覆盖，只是白写
- [ ] 任何缺失**都不得手工补写**（包括 `phase.end`）；回到对应阶段改自然输入/staging 后重跑
- [ ] **phase.start/end 事件对完整**：plan 不经 gate close，0.4.11 起 `context close`/`handoff` 会自动补齐缺失的 `phase.end`（返回体 `phaseEndPair.code=PHASE_END_AUTO_PAIRED`）；发现平台 Run 监控计时不停时先查这对事件，而不是手工写事件
- [ ] v2 过渡期**不写** `meta/plan-finalization.json` 与 `logs/execution-log.md`；缺这两项不算失败，不得为凑表手工补


## 关键原则

- **产物路径唯一性**：正式 `.harness/changes/<change-name>/` 是唯一真相源；plan 只写 staging，由 finalizer 原子发布，禁止先写正式目录再补 staging
- **原生规划协议**：阶段 4/6 使用 clarification、decision-grilling、implementation-planning 三段内置协议，不运行时依赖 Superpowers/grill-me/writing-plans
- **阶段 4 是强制阻断检查点**——展示设计审批包后必须停下来问用户，收到回复后才能写 approved 设计文档。不要跳过
- 代码探索只读不写——这个阶段的目标是理解，不是修改
- 场景表是后续所有步骤的真相源——宁可多花时间打磨，不要草草了事
- 如果需求不明确，优先提问而不是猜测后继续设计
- 任务拆分粒度按复杂度调整——plan 简表保持可追踪，implementation-detail 按风险和复杂度自适应展开

> Plan 的结束行为（禁止询问执行模式、只提示 `/harness-execute`）由 `SKILL.md` 的关键规则表定义，
> 详细规则见 `reference.md`「Plan 结束行为规则」。此处不再复述。

## 事件记录（前置规则）

- [ ] 确定 change-name 后立即用稳定且可复用的 `--run-id` / `--attempt` append `phase.start` 事件；各阶段用 `harness_events.py append` 写入 `decision` / `issue` / `artifact`
- [ ] 阶段 0 在 change-name 确定前可不写事件；阶段 0.5 确定 change-name 后必须开始记录

## 需求范围缩减后的 change-name 检查 ⚠️

- [ ] 阶段 4 澄清后，检查最终需求范围是否和 change-name 一致
- [ ] 如果用户取消某个需求，但 change-name 仍包含该需求关键词，必须建议重命名
- [ ] 重命名后同步目录名、spec/plan/scenarios 文件名、frontmatter、logs/execution-log、events.ndjson、meta/worktree.json
- [ ] 如果用户选择不重命名，记录 🟡WARN 到 events.ndjson（`issue` 或 `decision` 事件）
