# KB 外部同步契约（registry / notifications）

> 本文件定义 **与具体 IM/表格无关** 的外部同步事件、manifest 幂等字段与 dispatcher 用法。  
> provider 实现与回写细则见 [kb-external-writeback.md](kb-external-writeback.md)（若业务仓或扩展插件已提供）。

## 1. 设计原则

1. **核心 KB 流程不绑定任何外部系统**：无 `integrations` 或 provider 未启用时，propose/archive/verify 仍须落盘 `01`～`05` 与 manifest，**不得**因未配置外部集成而阻断 design/apply/archive。
2. **登记（registry）与通知（notifications）可拆分**：例如只写任务表不发群，或仅 Webhook 广播。
3. **子 Agent 只调统一入口**：`node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event <event> --scan-id <14位前缀>`；禁止在命令正文硬编码 provider 脚本路径。
4. **幂等以 manifest 为准**：主 Agent 复核须 shell 读磁盘；回写字段约定见 [kb-external-writeback.md](kb-external-writeback.md)（若存在）。

## 2. 业务仓配置（kb.project.json）

```json
{
  "integrations": {
    "registry": { "enabled": true, "provider": "<name>", "handler": ".kb/providers/<name>.mjs" },
    "notifications": { "enabled": true, "provider": "<name>", "handler": ".kb/providers/<name>-notify.mjs" }
  }
}
```

| 字段 | 含义 |
|------|------|
| `integrations.registry` | 外部登记：在线 PRD、任务表、验收报告文档等 |
| `integrations.notifications` | 群/Webhook 广播 |
| `handler` | 业务仓内 provider 脚本路径；由扩展插件 bootstrap 写入，**不在 marketplace 源仓内置** |

未启用对应 integration 时，dispatcher **退出码 0** 且 stdout 含 `SKIP`（非错误）。

## 3. 事件目录

| 事件 | KB 命令步骤 | 需要 integration | 幂等键（manifest） |
|------|-------------|------------------|-------------------|
| `registry.propose` | `/kb-propose` 外部登记（可选） | registry | `external.registry_record_id`、阶段内各字段 |
| `notify.propose_created` | `/kb-propose` 创建通知（可选） | notifications | `external.notified_events` 含 `created` |
| `sync.archive_completed` | `/kb-archive` 步骤 10 | registry 或 notifications | `external.notified_events` 含 `completed` |
| `registry.verify_issue_report` | `/kb-verify-issue` 步骤 3 | registry | 本轮 `report_doc_url` |
| `sync.verify_issue` | `/kb-verify-issue` 步骤 4 | registry 或 notifications | 本轮 `acceptance.rounds[].notified` |

### 3.1 Dispatcher 用法

```bash
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event registry.propose --scan-id 20260602193852
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event notify.propose_created --scan-id 20260602193852
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event sync.archive_completed --scan-id 20260602193852
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event registry.verify_issue_report --scan-id 20260602193852 --round 1
node "${PI_KB_ROOT}/scripts/kb-external-sync.mjs" --event sync.verify_issue --scan-id 20260602193852 --round 1
```

- 未启用对应 integration 时：**退出码 0**，stdout 含 `SKIP`（非错误）。
- `registry.propose` 可透传 provider 自定义参数（如 `--stop-after-stage 6`、`--resync`）。
- 调试：`--dry-run` 只打印将执行的命令。

## 4. manifest.external 约定

- **当前**：扁平字段（`prd_doc_url`、`registry_record_id`、`registry_record_url`、`notified_events` 等）由 provider adapter 维护；schema 已 `additionalProperties: true`。
- **演进**：可选增加 `external.providers.<name>.*` 命名空间；读盘时 flat 与 namespaced 并存，新 provider 只写自己的 namespace。
- **acceptance.rounds[]**：与 provider 无关，由 `/kb-verify-issue` 维护。

## 5. 扩展新 provider

1. 在业务仓或扩展插件中实现 provider 脚本，并在 `kb.project.json` 的 `integrations.*.handler` 登记（建议 `.kb/providers/`）。
2. 在 `plugin/skills/kb-workflow/references/` 增加 provider 细则 Markdown（**不**单独拆 Skill 目录，保持 `kb-workflow` 单 Skill 同步）。
3. 在 `bootstrap/kb.project.json` 补充 `provider` 说明；**不**修改核心状态机顺序。

## 6. 与命令的衔接（文案口径）

| 命令 | 无 integration | 有 integration |
|------|----------------|----------------|
| `/kb-propose` | 仅 `01-proposal.md` + manifest | PRD 确认后调 `registry.propose`；通知调 `notify.propose_created` 或含在 register 脚本内 |
| `/kb-archive` | `mv` → commit+push → 知识库更新 | push 成功后调 `sync.archive_completed` |
| `/kb-verify-issue` | 目录回退 + 归因 + 本地 `08` | 报告与 sync 步骤调对应 event |

主 Agent：**不得**在未读 `kb.project.json` 的情况下假定必须进行外部登记。
