---
description: 处理产品验收反馈：按变更id定位读manifest→归档回退进行中→归因(需求/代码)→生成问题报告→commit+push→可选外部 sync
argument-hint: <issue 链接或 ID> [round]
---

> Pi 包 `@suwenguang/pi-kb`：运行时包根为环境变量 `PI_KB_ROOT`（由 `extensions/kb-root.ts` 注入）。
> 工种子 Agent 通过 **pi-subagents** 派发（已 bundled）；agent 定义见本包 `agents/`。
> 脚本调用示例：`node "$PI_KB_ROOT/scripts/<name>.mjs"`。

## 用户输入

${@:-（未附带参数；结合当前对话上下文执行，缺信息时向用户澄清。）}

---
处理**产品验收阶段反馈的问题**。产品验收发现问题时，只需提供**变更id**（变更目录前缀 `<YYYYMMDDHHMMSS>`）和**问题描述**，触发本命令；命令自行按 id 定位变更目录、读取 `00-manifest.json` 获取需求文档链接 / 任务记录 / 归档路径等信息，无需再粘贴群通知原文。

本命令是 KB 闭环的「验收打回」环节，紧接 `/kb-archive` 之后；它会把已归档变更**回退为进行中**，给出归因结论，并把结果**可选**同步到外部系统。

**标准收尾顺序（必遵，与 `/kb-archive` 对齐）**：① 目录回退进行中 → ② 归因 → ③ 落地 `08-verify-issue.md` + 可选 `registry.verify_issue_report` → ④ 可选 `sync.verify_issue`（原子 sync）→ ⑤ 按白名单 **commit + push（仅一次）**。

> **防重复通知**：禁止拆步手写 provider API + 单独发通知 + follow-up push；integration 已启用时统一用 `sync.verify_issue` 单命令（见步骤 4），且 **全程仅一次 git push**。

**输入**：① **变更id**（变更目录的时间戳前缀 `<YYYYMMDDHHMMSS>`）；② 产品反馈的验收问题描述。

**细则**：[kb-external-sync.md](../skills/kb-workflow/references/kb-external-sync.md)、[kb-external-writeback.md](../skills/kb-workflow/references/kb-external-writeback.md)

## 外部 sync 幂等（integration 已启用时必遵）

**本轮** = `external.acceptance.rounds` 中 `round` 最大的一条。同一 `round` 的群/Webhook 通知**只允许发送一次**。

### 单点发送原则

- **步骤 4（外部 sync）必须由同一个子 Agent 在一次派发内、只调用一次** `node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event sync.verify_issue --scan-id <14位前缀> --round <N>`；dispatcher **原子完成**：读盘幂等闸门 → provider 写登记态 → 写盘 `status_set` → 发通知 → 写盘 `notified: true`（细则见 kb-external-writeback.md）。
- **禁止**在同轮验收中拆步调 provider API + 再单独发通知；**禁止**主 Agent 与子 Agent 各调一次 sync。
- 主 Agent 收到回报后**只 shell 读盘核对** `notified`；已为 `true` 时**禁止**重派任何会发通知的子 Agent。

### 发送结果三态分类

子 Agent 调 sync 后，必须按响应判定为以下三态之一，**不得笼统当作失败盲目重试**：

| 结果 | 判定 | 动作 |
|------|------|------|
| **明确成功** | dispatcher 退出码 0 且业务成功 | **同进程下一步**写盘 `notified: true`，结束 |
| **明确未送达** | 连接被拒 / 限流（服务端未接收） | 按 provider 节流重试；重试成功即写盘 `notified: true` |
| **不确定（可能已送达）** | 请求已发出但响应未知 | **禁止自动重发**；写盘 `notify_attempted: true`（**不**写 `notified`），由用户确认后再决定 |

### 读盘闸门

步骤 4 子 Agent 调 sync **之前**、回报后主 Agent 复核时，**均须 shell 读磁盘** `00-manifest.json`：

| 条件 | 动作 |
|------|------|
| 本轮 `notified === true` | **跳过**外部 sync；报告注明「通知：已发送（幂等跳过）」 |
| 本轮 `notified` 缺失或为 `false`，且步骤 3 报告已就绪 | 子 Agent 执行步骤 4 **一次** |
| 本轮 `notify_attempted === true` 但 `notified` 非 `true` | **禁止**自动重发；用户确认后再决定 |
| 子 Agent 称已发但磁盘 `notified` 仍为 `false` | 重派**仅补写 manifest**，**不得**再调 sync |
| `integrations` 未启用 | **SKIP** sync；本地步骤 1～3、5 仍须完成 |

```bash
python3 -c "import json,sys; r=json.load(open(sys.argv[1]+'/00-manifest.json')).get('external',{}).get('acceptance',{}).get('rounds',[]); last=max(r,key=lambda x:x.get('round',0)) if r else {}; print('round',last.get('round'),'notified',last.get('notified'),'notify_attempted',last.get('notify_attempted'))" "<进行中目录>"
```

## Bootstrap 门禁（硬阻断）

本命令要求业务仓已完成 KB 初始化（`/kb-init` / `kb-bootstrap`）。开始前**必须**先跑机器门禁；失败则**立即停止**，禁止继续（含禁止用 `mkdir -p knowledge/...` 绕过建目录）。执行：

`node "${PI_KB_ROOT}/scripts/kb-bootstrap-check.mjs" --target "$(pwd)"`

未通过时按脚本输出指引执行 `/kb-init`，或：

`node "${PI_KB_ROOT}/scripts/kb-bootstrap.mjs" --target "$(pwd)"`

## CodeGraph 门禁（硬阻断）

本命令依赖 CodeGraph。开始前**必须**先跑机器门禁；失败则停止并输出脚本指引，禁止继续。执行：

`node "${PI_KB_ROOT}/scripts/kb-codegraph-check.mjs" --target "$(pwd)"`

门禁通过后，再确认 MCP 工具 `codegraph_*`（至少能调用 `codegraph_explore`（或 `codegraph_status`））可用。若工具不可用：阻断，并指引用户从插件示例复制项目级 MCP 配置：

按 [kb-codegraph.md](../skills/kb-workflow/references/kb-codegraph.md) §一，从 `${PI_KB_ROOT}/bootstrap/examples/mcp/` **只写当前宿主**对应文件（Claude/其他 → 根 `.mcp.json`；Cursor → `.cursor/mcp.json`；禁止无脑双写），配置后 Reload / 重启会话，再重试本命令。

## 约束

- 变更名称必须为中文；目录格式 `<YYYYMMDDHHMMSS>-<中文名称>`。
- **定位先行**：按变更id 在 `knowledge/变更/归档/`（兼容 `进行中/`）唯一匹配目录；匹配不到或匹配到多个即停并提示确认；`00-manifest.json` 不可读即停。
- **不修业务代码**：本命令只做校验、目录回退、归因报告、可选外部回写；代码修复交给 `/kb-apply`、`/kb-revise-apply`，需求调整交给 `/kb-revise`。
- integration 已启用时：**不静默写错状态**；provider 缺状态选项时停止并提示，不退化为近似值。

## 子 Agent 编排（必遵）

- 主 Agent：解析输入（变更id + 问题描述）、推动闸门、审核归因结论、向用户确认；**不**直接写文件、**不**直接调用 provider API。
- 子 Agent：按 id 定位目录读 manifest、目录回退与 `00-manifest.json` 回写、归因分析（CodeGraph + PRD 对照）、撰写 `08-verify-issue.md`、外部 sync（经 `kb-external-sync.mjs`）、commit + push 均由子 Agent 执行。
- 归因子 Agent 必须先用 `codegraph_explore` / `codegraph_impact` 核对实际实现，再对照 `01-proposal.md` 判定。
- **顺序硬约束**：本地 `08-verify-issue.md` 必须先于 `registry.verify_issue_report`；外部 sync 必须在唯一一次 commit + push **之前**完成（integration 已启用时）。

## 执行步骤

### 1. 按变更id 定位目录并读取 manifest

主 Agent 从用户输入取得**变更id**与**问题描述**，派子 Agent 定位目录：

- 优先在 `knowledge/变更/归档/<id>-*` 唯一匹配；未命中再回退到 `knowledge/变更/进行中/<id>-*`。
- 读取 `00-manifest.json`，提取：`external.prd_doc_url`、`external.registry_record_url` / 登记记录 ID、`external.task_type`、变更中文名称、当前 `external.acceptance.rounds`。

定位与读取规则（任一不满足即停止并报告）：

1. 按 id 在两个目录下匹配；匹配不到或匹配到多个目录时停止。
2. 命中目录下 `00-manifest.json` 必须存在且可读。
3. integration **已启用**且 manifest 缺关键 external 字段时停止并报告；未启用 integration 时缺 external **不阻断**本地回退与归因。

```bash
dir=$(ls -d knowledge/变更/归档/<id>-* 2>/dev/null || ls -d knowledge/变更/进行中/<id>-* 2>/dev/null); echo "$dir"
python3 -c "import json,sys; e=json.load(open(sys.argv[1]+'/00-manifest.json')).get('external',{}); print(e.get('prd_doc_url'), e.get('registry_record_url'), e.get('registry_record_id'), e.get('task_type'))" "$dir"
```

### 2. 归档目录回退为进行中

校验通过后，由子 Agent 执行：

```bash
mv "knowledge/变更/归档/<YYYYMMDDHHMMSS>-<中文名称>" "knowledge/变更/进行中/"

test ! -d "knowledge/变更/归档/<YYYYMMDDHHMMSS>-<中文名称>"
test -d "knowledge/变更/进行中/<YYYYMMDDHHMMSS>-<中文名称>"
```

门禁失败则停止后续步骤，先 `/kb-repair`。细则见 [kb-archive-migrate.md](../skills/kb-workflow/references/kb-archive-migrate.md)。

更新 `00-manifest.json`（位于回退后的进行中目录）：

- `stage` → `acceptance_reopened`
- 移除或忽略 `archived_at`
- `external.acceptance.rounds[]` 追加本轮：`round`（递增）、`feedback`（问题摘要）、`created_at`；**不**预设 `notified: true`
- `updated_at` 刷新

### 3. 归因分析（需求问题 / 代码问题）

| 归因 | 判定标准 | `reason` |
|------|----------|----------|
| 原需求(产品)问题 | 代码已按 PRD 实现，问题源于 PRD 定义缺失/有误/口径不清 | `requirement` |
| 代码实现问题 | 代码未按 PRD 实现，存在偏差或缺陷 | `code` |

主 Agent 审核归因结论并向用户确认。

### 4. 生成问题报告 + 落地 08 履历

1. 子 Agent 写入/追加 `08-verify-issue.md`（**文件工具**写入，不经命令行内联中文）：
   - 本轮内容置于 `## 第 N 轮` 小节下：反馈问题、归因结论、判定依据、影响范围、后续处理路径。
   - 后续路径：`requirement` → `/kb-revise`；`code` → `/kb-apply` 或 `/kb-revise-apply`。
2. integration 已启用时，调外部报告登记：

```bash
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event registry.verify_issue_report --scan-id <14位前缀> --round <N>
```

- 从 `08-verify-issue.md` 读取「## 第 N 轮」；成功后回写 `report_doc_url` / `report_document_id` 到本轮 round（细则见 kb-external-writeback.md）。
- 幂等：本轮已有 `report_doc_url` 时 SKIP。
- integration 未启用：仅保留本地 `08`，跳过本命令。

### 5. 外部原子 sync（可选，`sync.verify_issue`）

**前置（integration 已启用，缺一即停）**：

1. 步骤 4 已完成或本轮已有 `report_doc_url`（本地 08 必须存在）。
2. shell 读磁盘确认本轮 `notified !== true`。
3. 本轮 `notify_attempted === true` 且 `notified !== true`：**禁止**自动重跑。

**执行**：

```bash
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event sync.verify_issue --scan-id <14位前缀> --round <N>
```

- integration 未启用：SKIP，直接进入步骤 6。
- 失败处理：sync 失败时**不**进入步骤 6 push；修复后从本步重试。

### 6. 白名单 commit + push（全程仅一次）

由子 Agent 按 `/kb-commit <中文名称>` 白名单**一次性**提交并推送：

1. `git status --short` 确认无未归属改动。
2. 确认 `manifest.stage` 为 `acceptance_reopened`；本轮含本地 08；integration 已启用且 sync 成功时含 `status_set` 与 `notified=true`。
3. 按白名单逐文件 `git add`（禁止 `git add .`）：目录迁移、`00-manifest.json`、`08-verify-issue.md`。
4. 提交信息示例：`docs(kb): <中文名称> 验收打回回退进行中并同步外部`。
5. `git commit` → **`git push`**。

**禁止**：步骤 6 之后再调 sync；**禁止**为 `notified` 单独 follow-up push。

### 7. 输出验收处理报告

```markdown
## 验收问题处理报告

| 项目 | 内容 |
|------|------|
| 变更名称 | <中文名称> |
| 归因结论 | 原需求问题 / 代码实现问题 |
| 目录状态 | 已回退至 knowledge/变更/进行中/<dir>/ |
| manifest 阶段 | acceptance_reopened |
| 验收报告 | <本地 08 / 外部报告链接> |
| Git 推送 | 已推送 / 失败待重试 |
| 外部 sync | 已同步 / SKIP / 失败(原因) |
| 下一步 | /kb-revise 或 /kb-apply、/kb-revise-apply |
```

## 失败处理

- 变更id 定位失败或 manifest 不可读：停止，不回退目录。
- 步骤 4 报告失败（integration 已启用）：停止，**不**进入步骤 5 sync / 步骤 6 push。
- 步骤 5 sync 失败：**不** push；修复后从步骤 5 重试。
- 步骤 6 push 失败：**禁止**为补 push 而重跑 sync。
- 子 Agent 称 sync 成功但磁盘无 `notified=true`：重派**仅补写 manifest** 再 push。
