[moz] docs(§22): v1.5 采纳司马懿 S1-S4+P1-P3 审查建议

This commit is contained in:
2026-06-25 07:45:26 +08:00
parent a376fdadbc
commit c19286eb5b
+81 -14
View File
@@ -1,9 +1,10 @@
---
title: "End-to-End Flow — 端到端任务流程设计"
created: 2026-06-22
version: v1.4
version: v1.5
status: draft
changelog: v1.4 §22.6/§22.8 设计补足:基础设施排除、定向讨论简化为单spawn自主模式、迁移策略、TC数据源/round_count分流通透
changelog: v1.5 采纳司马懿 S1-S4+P1-P3:判断逻辑补 infrastructure 分支、flow/discuss deprecated、定向讨论 fallback、task_state.status 完整生命周期、parent_status 查表不硬编码
v1.4 §22.6/§22.8 设计补足:基础设施排除、定向讨论简化为单spawn自主模式、迁移策略、TC数据源/round_count分流通透
v1.3 §22.6 重构为「所有 TC 流程第一步走 Discuss」+ §22.8 TC Round Review Gitea 适配设计
v1.2 §22.3/§22.4 更新 Phase 1 为 ✅ 已实现(PR #124
v1.1 补充轻量路径设计(§22.6)、数据流澄清(§22.7)、修正设计原则3、统一Phase编号、Phase 1标注
@@ -292,7 +293,8 @@ issue_assigned:
```
parent Issue 创建
├─ 有 flow/direct label?→ Direct 路径(→ Phase 2,跳过讨论)
├─ 有 assignee?→ 定向 Discussionassignee + reviewer 讨论
├─ 有 type/infrastructure label?→ Direct 路径(→ executor,运维排障
├─ 有 assignee(非 infrastructure)?→ 定向 Discussionassignee 自主模式)
└─ 无 assignee(默认)→ 广播 Discussion(所有空闲 agent
```
@@ -322,6 +324,21 @@ Issue assigned webhook
- 广播讨论:assignee=None → ticker 归入 broadcast_tasks → 广播所有空闲 agent
- 定向讨论:assignee=该 agent → ticker 归入 deterministic_tasks → 确定性路由 spawn 单人
### 定向讨论 fallbackassignee 无响应)
> **v1.4 补充(司马懿 S4)**:广播讨论有「3 轮无 taker → 升级庞统」机制,定向讨论也需要 fallback。
单 spawn assignee 后,如果 assignee NO_REPLY 或 session 超时:
```
ticker 定期 check(复用现有 broadcast _broadcast_tracker 机制)
→ discussion task 仍 pending/working 且超过 3 轮 check 未终态
→ 升级庞统(escalated 状态)
→ 庞统判断:重新分配 / 转为广播讨论 / 直接关闭
```
复用现有 `_broadcast_tracker``round_number >= 3 → escalated` 逻辑,不引入新机制。
### 广播讨论流程(无 assignee
```
@@ -337,7 +354,7 @@ Issue opened webhook
| 路径 | 适用场景 | 示例 |
|------|---------|------|
| 广播讨论 | 需求不明确、跨模块协作、无人认领 | 新功能设计、架构变更 |
| 广播讨论 | 需求不明确、跨模块协作、涉及 3+ agent、无人认领 | 新功能设计、架构变更 |
| 定向讨论 | 需求明确但需要方案确认 | 有明确 assignee 的 Issue |
| Direct | 改 typo、改配置值等极小改动 | `flow/direct` label |
@@ -366,6 +383,8 @@ Discussion 进行中,如果所有 agent 都认为任务足够简单只涉及
`_ACTION_HINTS` / YAML steps / `ToolchainContextSection` 中的 `issue_assigned` 相关逻辑**保留**infrastructure/flow-direct 还用),新增 `issue_review_discussion` action_type。
> **`flow/discuss` label deprecated**v1.2 曾设计 `flow/discuss` label(强制 Discussion 即使有 assignee),v1.4 废弃。所有有 assignee 的 Issue(非 infrastructure)默认走定向讨论,无需显式 label。Gitea 上 `flow/discuss` labelid=101)保留但不影响路由。
### 实现方案
**toolchain_routes.py**
@@ -473,17 +492,65 @@ task_state 表创建前,`_check_round_complete` 仍扫 `tasks.parent_task`。
### task_state.status 更新机制
> **v1.4 补充**:当前 `_ensure_task_state` 只做 `INSERT OR IGNORE`status 初始为 `pending`,后续没有任何代码更新。需补充。
> **v1.4 补充(司马懿 S3**:当前 `_ensure_task_state` 只做 `INSERT OR IGNORE`status 初始为 `pending`,后续没有任何代码更新。需补充。
**更新来源**Gitea Issue closed webhook → 更新 `task_state.status = 'done'`
**状态生命周期**
```
_handle_issues: action == "closed"
→ UPDATE task_state SET status='done', updated_at=datetime('now')
WHERE issue_number = ?
| 状态 | 触发来源 | 更新位置 |
|------|---------|----------|
| `pending` | `_ensure_task_state` 初始插入 | `toolchain_routes.py` assigned 分支 |
| `done` | Gitea Issue closed webhook | `toolchain_routes.py` closed 分支 |
| `failed` | executor task 验证失败且未重试 | `toolchain_handler.py` `post_complete``_update_task_state_status()` |
**关键路径说明**
1. **sub Issue 创建**`_ensure_task_state` 写入 `status='pending'`
2. **sub Issue 对应的 executor task 完成** → ToolchainHandler 通过 @mention 指引 agent 创建 PR(含 `Closes #N`)→ PR 合并时 Gitea 自动关闭 Issue → webhook `issues/closed` → 更新 `status='done'`
3. **executor task 失败**`ToolchainHandler.post_complete()` 中检测 verify 失败且 retry_count 达上限 → 调用 `_update_task_state_status(issue_number, 'failed')`
**`post_complete` 何时触发**spawner 完成 session 后(agent exit),ticker 在下个 tick 检测到 session 终态 → 调用 `handler.post_complete(task_id, agent_id, outcome, db_path)`。此时 handler 可以:
- 检查 verify 结果
- 如果 failed 且不可 retry → 查 task_state 找到对应 issue_number → 更新 status='failed'
**新增方法**
```python
# toolchain_handler.py
def _update_task_state_status(self, issue_number: int, status: str):
"""更新 task_state.statusexecutor 失败时调用)"""
tc_db = _toolchain_db_path()
conn = get_connection(tc_db)
try:
conn.execute(
"UPDATE task_state SET status=?, updated_at=datetime('now') "
"WHERE issue_number=?",
(status, issue_number)
)
conn.commit()
finally:
conn.close()
```
后续如需更精细状态(failed/retry),通过 ToolchainHandler.post_complete 补充更新。
**toolchain_routes.py closed 分支补充**
```python
elif action == "closed":
# 更新 task_state status='done'
tc_db = _toolchain_db_path()
conn = get_connection(tc_db)
try:
conn.execute(
"UPDATE task_state SET status='done', updated_at=datetime('now') "
"WHERE issue_number=?",
(issue_number,)
)
conn.commit()
finally:
conn.close()
# ... 现有通知逻辑
```
> **注意**`get_tc_subtask_summary` 中的 `all_terminal` 只依赖 `done` 和 `failed` 两种终态。`pending`/`working` 计入 `other`,确保未完成的 sub 不会误触发 round review。
### 分流方案(全链路)
@@ -580,7 +647,7 @@ TC 版本的 Round Review prompt。核心区别:
1. **Handler 分流**`_check_round_complete` 通过 `TaskTypeRegistry.get_by_project(project_id)` 判断。普通项目(无 handler)走 `_build_review_prompt`(黑板版本不变)
2. **数据隔离**TC review 读 `task_state` 表 + Gitea API;黑板 review 读 `tasks` 表 + `outputs` / `comments`
3. **prompt 隔离**TC prompt 只含 Gitea API 指引;黑板 prompt 只含黑板 API 指引
4. **`_dispatch_reviews` 已有先例**L1379 `if handler: return []` 已经用 Handler 分流跳过 handler 项目的 review 流程
4. **Handler 分流模式已在 `_dispatch_reviews` 中验证可行**L1379 `if handler: return []` 用 Handler 分流跳过 handler 项目的 PR Review 流程TC Round Review 采用相同模式
### 实现方案
@@ -599,7 +666,7 @@ def get_tc_subtask_summary(tc_db: Path, parent_issue: int) -> Optional[dict]:
conn = get_connection(tc_db)
try:
parent_row = conn.execute(
"SELECT round_count FROM task_state WHERE issue_number = ?",
"SELECT round_count, status FROM task_state WHERE issue_number = ?",
(parent_issue,)
).fetchone()
if not parent_row:
@@ -615,7 +682,7 @@ def get_tc_subtask_summary(tc_db: Path, parent_issue: int) -> Optional[dict]:
summary = {
"parent_id": str(parent_issue),
"parent_status": "done", # TC 路径 parent 是 Gitea Issue
"parent_status": parent_row["status"], # 从 task_state 读取实际状态
"round_count": parent_row["round_count"],
"total": 0, "done": 0, "failed": 0, "cancelled": 0, "other": 0,
}