fix(design): §17 Review 反馈修复(M1+S1-S3+姜维关注点)
CI / lint (pull_request) Successful in 7s
CI / test (pull_request) Successful in 8s
CI / notify-on-failure (pull_request) Successful in 0s

This commit is contained in:
cfdaily
2026-06-13 21:37:11 +08:00
parent 5bc53192d6
commit 6a7fe37d93
+45 -5
View File
@@ -238,6 +238,13 @@ action verify 失败时的处理逻辑与 request 一致:
2. 通过 `mail_notify.notify_mail_failed` 通知发件人
3. reason = `"no_action_report"`(收件人未执行动作)
### API 端点兼容性确认
action_report 提交使用的 `POST /api/projects/_mail/tasks/{task_id}/comments` 端点:
- `_mail` 已在 `_VIRTUAL_PROJECTS` 中支持(`blackboard_routes.py` L23
- `comment_type` 参数已支持(`add_comment` endpoint: `body.get("comment_type", "general")`
- **无需 API 改动**,现有端点完全兼容 action_report 提交
---
## §4. 场景分类与 type 分配
@@ -538,6 +545,19 @@ comment_type TEXT NOT NULL DEFAULT 'general' CHECK (
或者更简单的方式:**去掉 CHECK 约束**。现有 CHECK 约束主要是文档作用,去掉不影响功能。
#### 5.1.6 `src/daemon/mail_notify.py`
**改动:`_REASON_MAP` 新增 `no_action_report` 条目**
action Mail verify 失败时,reason 为 `no_action_report``mail_notify.py``_REASON_MAP` 需新增此 reason 的人话翻译,以便通知邮件内容清晰。
```python
_REASON_MAP = {
# ... 现有条目 ...
"no_action_report": "收件人未执行操作(未提交 action report",
}
```
### 5.2 模板文件改动(`templates/toolchain/`
**全部 8 个 action 场景模板必须重写**。这不是"在现有模板上打补丁"——现有模板是按 inform 语义写的纯通知体,信息量薄。§15.5 原始流程强约束模板(含编号步骤和 API 调用指令)从未真正落地,被简化成了纯文本一句话。
@@ -578,8 +598,9 @@ comment_type TEXT NOT NULL DEFAULT 'general' CHECK (
| `src/daemon/spawner.py` | ~8 行 | 修改 |
| `src/api/toolchain_routes.py` | ~120 行 | 修改 |
| `src/blackboard/db.py` | ~5 行 | 修改 |
| `src/daemon/mail_notify.py` | ~3 行 | 修改 |
| `templates/toolchain/*.md` | ~200 行 | 重写(8 个文件) |
| **总计** | **~420 行** | |
| **总计** | **~425 行** | |
---
@@ -675,6 +696,8 @@ def _render_action(context: PromptContext) -> str:
)
# [L3] 完成报告层
# ⚠️ 实现注意:curl JSON 中的花括号需用 {{ }} 转义(f-string),
# 或单独构造 JSON 部分拼接,避免 SyntaxError
report_block = (
"--- 完成后必须提交执行报告 ---\n"
"执行完上述所有步骤后,必须提交 action report\n\n"
@@ -1000,10 +1023,11 @@ PR: http://192.168.2.154:3000/{repo}/pulls/{pr_number}
```python
steps = [
f"确认 CI 已通过: curl -s http://192.168.2.154:3000/api/v1/repos/{repo}/commits/{sha}/status "
f" -H 'Authorization: token {PAT}' → 检查 .state == 'success'",
f"如果 CI 未通过,先修复 CI 问题再合并",
f"合并 PR: curl -s -X POST http://192.168.2.154:3000/api/v1/repos/{repo}/pulls/{pr_number}/merge "
f"确认 CI 状态: curl -s http://192.168.2.154:3000/api/v1/repos/{repo}/commits/{sha}/status "
f" -H 'Authorization: token {PAT}' → 检查 .state",
f"如果 CI 还在 pendingstate='pending'),等待 2-5 分钟后重新检查",
f"如果 CI 失败(state='failure'),先修复 CI 问题再合并",
f"CI 通过后(state='success'),合并 PR: curl -s -X POST http://192.168.2.154:3000/api/v1/repos/{repo}/pulls/{pr_number}/merge "
f" -H 'Authorization: token {PAT}' -H 'Content-Type: application/json' "
f" -d '{{\"Do\": \"merge\", \"merge_title_field\": \"Merge PR #{pr_number}\"}}'",
f"确认合并成功: 检查返回的 PR 状态 .merged == true",
@@ -1290,6 +1314,8 @@ steps = [
| `issue_comment` | `created` (含 @mention) | @mention | 被@者 | action | 场景 8 |
| `deployment_status` | `failure` | 部署失败 | 庞统+姜维 | action | 场景 7 |
> **注**PR #60 后 Gitea 也可通过 `X-Gitea-Event: pull_request_sync` header 直接路由,不走 `pull_request` action 分发。两种路由路径(`pull_request + synchronize` 和 `pull_request_sync`)都指向同一 Action 场景(场景 5)。
**未覆盖的 Gitea Event**(评估后排除):
| Event | 说明 | 排除理由 |
@@ -1540,6 +1566,20 @@ def check_completion(self, task_id: str, db_path: Path) -> bool:
action verify 失败时,复用 request 的 `on_failure` 逻辑(标 failed + 通知发件人)。reason 传 `"no_action_report"``mail_notify``_REASON_MAP` 新增此 reason 的人话翻译。
### 9.3 action 与 ticker 超时的交互
action Mail 投递后 Agent 进入 working 状态。`_check_timeouts` 检查所有 working 任务(不区分
performative),因此 action 类型同样受 `default_task_timeout_minutes`(默认 30 分钟)保护。
| 场景 | 处理 |
|------|------|
| Agent 正常执行完 → verify 通过 | 正常 done |
| Agent crash → 无 action_report | verify 标 failed |
| Agent 执行超时(>30分钟) | _check_timeouts 标 failedworking 超时兜底) |
| Agent 30 分钟内 crash 3 次 | crash_limit 标 failed |
这是正确行为——action 步骤如果需要超长时间(如审查大 PR),应在 deadline 中调整。
---
## §10. 设计决策记录