---
name: retro-catchup
description: 为项目中所有已完成但缺少复盘笔记的 M/L 任务卡补写历史复盘笔记，并通过 MCP append_project_note 写入炼境。Use when a project has completed M/L tasks but zero or few retrospective notes.
allowed-tools: Read, Glob, Grep, Bash(git log *), Bash(git diff *), Bash(python *), Bash(python3 *), mcp__lian*
---

# 复盘笔记补写（Retro Catch-Up）

为已完成的 M/L 任务卡补写事后重建版复盘笔记，推动飞轮数据积累。

> ⚠️ 这些笔记是**事后重建**，基于任务卡内容 + git 历史推断，比实时记录精度低。但对识别高频模式仍然有价值。

## 写入通道（三级降级）

每次调用 `append_project_note` 时，按以下顺序尝试，成功即停止：

**① 原生 MCP**：若 `append_project_note` 工具可用，直接调用。

**② Python HTTP 直调**：若原生 MCP 不可用（Claude Code 与炼境握手失败的已知问题），读取项目 `.claude/settings.json`，提取 group_id，用 Python 直接 POST 炼境 API：

```python
import urllib.request, json, sys

# 从 .claude/settings.json 提取 group_id
with open('.claude/settings.json') as f:
    cfg = json.load(f)
group_id = None
for key in cfg.get('mcpServers', {}):
    if key.startswith('lian-jing:group-'):
        group_id = key.split('lian-jing:group-')[1]
        break

# project_id 通过先调用 list_group_projects 获得
url = f'http://localhost:27190/mcp/group/{group_id}'

def mcp_call(method, params={}):
    payload = json.dumps({'jsonrpc':'2.0','id':1,'method':method,'params':params}).encode()
    req = urllib.request.Request(url, data=payload, method='POST')
    req.add_header('Content-Type', 'application/json')
    req.add_header('Accept', 'application/json')
    with urllib.request.urlopen(req, timeout=10) as r:
        return json.loads(r.read().decode('utf-8', errors='replace'))

# 调用示例
result = mcp_call('tools/call', {
    'name': 'append_project_note',
    'arguments': {'project_id': PROJECT_ID, 'content': NOTE_CONTENT}
})
```

**③ 本地文件兜底**：若炼境未运行（连接超时），将所有笔记追加写入 `.blueprint/retro-notes.md`，格式与正式笔记相同，头部加注 `<!-- 待炼境恢复后手动同步 -->`。

## 步骤

### 1. 确认写入通道 + 项目 ID

按以下顺序确定：

1. 检测 `append_project_note` 是否在可用工具中 → 是则用**通道①**
2. 否则检测 `localhost:27190` 是否可达（`curl -s --max-time 2 http://localhost:27190` 或 Python urlopen）→ 可达则用**通道②**，同时读取 `.claude/settings.json` 提取 `group_id`，再调用 `list_group_projects` 获取当前项目 `project_id`
3. 均不可达 → 用**通道③**，无需 project_id

告知用户当前使用哪个通道，例如：`使用通道②（Python HTTP 直调）`。

### 2. 扫描所有已完成 M/L 任务卡

遍历 `.blueprint/modules/*.md`，收集满足以下条件的任务卡：
- 前缀为 ✅（status: done）
- complexity 为 `M` 或 `L`

输出扫描结果：共找到 N 张，列出标题 + 所属模块。

### 3. 逐卡重建复盘笔记

对每张任务卡按顺序处理：

**3a. 读取证据**
- 读取任务卡的 `files` 字段列出的所有文件（当前代码状态）
- 执行 `git log --oneline -- <file>` 查看相关文件的提交历史
- 若提交数 > 1，执行 `git diff <first_commit>^..<last_commit> -- <file>` 了解变更量

**3b. 推断执行情况**
根据证据推断：
- **实际轮数**：相关文件的提交次数（粗估）
- **是否返工**：若同一文件有多次修改且 message 含 fix/修复/重新/又 等关键词
- **返工原因**：从 commit message 或代码变更中推断
- **有效策略**：从最终实现方式中提取关键设计决策

**3c. 写入笔记**

按步骤 1 确定的通道调用 `append_project_note`，内容格式：

```
【复盘·重建】<任务标题>
任务类型: 后端命令 | 前端组件 | 数据层 | MCP工具 | 架构调整
复杂度: M | L
实际轮数: N轮（事后推断，基于 git 提交数）
是否返工: 是/否/不确定
返工原因: <若返工，从 commit message 推断>
有效策略: <从最终实现中提取的关键做法>
遗留风险: <若代码中有明显 TODO 或边界情况未处理>
备注: 此笔记为事后重建，非实时记录
```

每写完一张，告知用户"✅ 已写入：<任务标题>"。

### 4. 输出汇总

```
## 复盘补写完成

共处理 N 张 M/L 任务卡：
- ✅ 成功写入：X 张
- ⏭️ 跳过（无足够证据）：Y 张

飞轮状态：累计复盘笔记 Z 条
```

## 跳过条件

以下情况跳过该任务卡，不强行写入：
- `files` 字段为空，且 git 中找不到相关提交
- 任务卡内容过于简单（S 级错标为 M 的情况）

## 原则

- 笔记头部必须标注 `【复盘·重建】` 与 `备注: 此笔记为事后重建`，与实时笔记区分
- 宁可跳过，不要捏造。证据不足时注明"信息不足，无法推断"
- 每张卡独立处理，写入失败不影响后续
