From 12f6ac3b1f160347132177104c81301364ade9eb Mon Sep 17 00:00:00 2001 From: cfdaily Date: Sat, 20 Jun 2026 22:47:04 +0800 Subject: [PATCH] =?UTF-8?q?[moz]=20feat(prompt):=20toolchain=20steps=20?= =?UTF-8?q?=E5=8A=A0=E6=96=87=E6=A1=A3=E5=90=8C=E6=AD=A5=20+=20=E5=8F=B8?= =?UTF-8?q?=E9=A9=AC=E6=87=BF/=E5=BA=9E=E7=BB=9F=20review=20=E5=8A=A0?= =?UTF-8?q?=E9=9C=80=E6=B1=82-=E8=AE=BE=E8=AE=A1-=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改动: - toolchain_routes.py: issue_assigned/review_result/ci_failure steps 加文档同步 step - toolchain_handler.py: ToolchainConstraintsSection 加 §6 文档同步约束 + Red Flag - bootstrap.py: reviewer 硬约束加需求-设计-编码一致性检查 - ticker.py: 庞统 round review 三问第 2 问加 docs/design 同步确认 - prompt_composer.py: DeliveryChecklistSection 从弱提醒改为强制步骤 Closes #105 --- .gitignore | 1 + src/api/toolchain_routes.py | 11 +++++++---- src/daemon/bootstrap.py | 1 + src/daemon/prompt_composer.py | 9 +++++---- src/daemon/ticker.py | 2 +- src/daemon/toolchain_handler.py | 6 ++++++ 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 8c4e4b2..f3af793 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ inbox/*.jsonl # E2E test data data/e2e-*/ +data/_mail/ diff --git a/src/api/toolchain_routes.py b/src/api/toolchain_routes.py index 3ec70f6..e727ef4 100644 --- a/src/api/toolchain_routes.py +++ b/src/api/toolchain_routes.py @@ -650,9 +650,10 @@ async def _handle_pull_request_review(payload: Dict[str, Any]) -> None: else: # REQUEST_CHANGES tc_steps = [ "按审查意见逐条修改代码", + "文档同步:如审查涉及设计/接口变更,同步更新 docs/design/ 对应文档", "push 到原分支 → CI 自动跑", "CI 通过后等重新 Review", - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)", + "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中必须说明文档是否需要更新及处理结果", ] _send_toolchain_task( to_agent=pr_author, @@ -1034,10 +1035,11 @@ async def _handle_issues(payload: Dict[str, Any]) -> None: steps=[ f"在开发目录执行 git 操作:\n a. git checkout main && git pull origin main\n b. git checkout -b fix/{issue_number}-{brief}", "编码 + 写 UT", + "文档同步:如果本次改动涉及设计变更或接口变更,在同一分支更新 docs/design/ 对应文档。如无需更新,在 action report 中说明「文档无需更新」", f"git add -A && git commit -m \"[moz] fix: {issue_title[:30]}\" && git push origin fix/{issue_number}-{brief}", - f"CI 通过后创建 PR(Gitea API: POST /repos/{repo}/pulls,head: fix/{issue_number}-{brief}, base: main)", + f"CI 通过后创建 PR(Gitea API: POST /repos/{repo}/pulls,head: fix/{issue_number}-{brief}, base: main)— PR body 必须含 Closes #{issue_number}", "等 Review", - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)", + "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中必须说明文档是否需要更新及处理结果", ], context_data={ "issue_number": issue_number, @@ -1153,7 +1155,8 @@ async def _handle_issue_comment(payload: Dict[str, Any]) -> None: steps=[ "查看完整 CI 日志(PR 页面或 Gitea Actions 页面)", "根据 CI 日志判断失败原因类型:\n a. 代码问题(lint/test 失败)→ 修复失败的测试 → push 到原分支 → CI 自动重跑\n b. 基础设施问题(runner 环境/Python/venv/Gitea/网络故障)→ 在该仓库创建 Issue 指派 jiangwei-infra(见下方「需要创建 Issue 时」),label 必须包含 type/infrastructure", - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中说明判断的原因类型和执行的操作", + "文档同步:如修复涉及设计/接口变更,同步更新 docs/design/ 对应文档", + "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中说明判断的原因类型和执行的操作,以及文档是否需要更新", ], context_data={ "pr_number": issue_number, diff --git a/src/daemon/bootstrap.py b/src/daemon/bootstrap.py index ee2498c..c06707d 100644 --- a/src/daemon/bootstrap.py +++ b/src/daemon/bootstrap.py @@ -152,6 +152,7 @@ class BootstrapBuilder: constraints.extend([ "- 审查结果必须明确 pass/fail", "- 评审意见须附证据(文件:行号)", + "- 需求-设计-编码一致性:PR 改动是否和 Issue/设计文档描述一致?如改了实现但 docs/design 未同步更新,在 Review 中指出", ]) elif role == "planner": constraints.extend([ diff --git a/src/daemon/prompt_composer.py b/src/daemon/prompt_composer.py index 10705de..1a03030 100644 --- a/src/daemon/prompt_composer.py +++ b/src/daemon/prompt_composer.py @@ -186,10 +186,11 @@ class DeliveryChecklistSection: priority: int = 55 # CONSTRAINTS(50) 和 EXTENSION(60) 之间 CHECKLIST_TEXT = ( - "## 交付检查\n" - "完成代码改动前确认:\n" - "- 改了实现 → docs/design/ 对应设计文档是否需要更新\n" - "- 改了实现 → tests/ 是否有对应测试脚本需要更新\n" + "## 交付检查(强制)\n" + "⚠️ 这是必须执行的步骤,不是提醒。代码改动完成后,以下检查每一项都要有明确结论:\n" + "- 改了实现 → docs/design/ 对应设计文档是否需要更新?需要则在同一 PR 中更新\n" + "- 改了实现 → tests/ 是否有对应测试脚本需要更新?需要则在同一 PR 中更新\n" + "- action report 中必须逐项说明上述检查结果(如「文档无需更新」「测试已补充」)\n" "- 所有成果物变更通过 PR 流程:PR review 把关设计合理性,CI 把关代码质量,CD 把关部署正确性\n" ) diff --git a/src/daemon/ticker.py b/src/daemon/ticker.py index cf28dce..b6a4933 100644 --- a/src/daemon/ticker.py +++ b/src/daemon/ticker.py @@ -513,7 +513,7 @@ class Ticker: ### 三问 1. Goal 还清晰吗?(是否有 goal drift) -2. 成果物覆盖 goal 了吗?(逐条检查验收标准) +2. 成果物覆盖 goal 了吗?(逐条检查验收标准 + 确认 docs/design 是否同步更新) 3. 下一轮需要做什么?(创建新 sub tasks / 标记完成 / 调整方向) ### 失败处理 diff --git a/src/daemon/toolchain_handler.py b/src/daemon/toolchain_handler.py index 9ae18e4..2a0cb6a 100644 --- a/src/daemon/toolchain_handler.py +++ b/src/daemon/toolchain_handler.py @@ -248,6 +248,11 @@ class ToolchainConstraintsSection: '- 不要使用 Mail API(飞鸽传书)发送消息', '- 你的所有操作都在 toolchain 流程内,通过 Gitea 留痕', "", + "### 6. 文档同步(涉及代码改动时)", + '- 改了实现 → 检查 docs/design/ 对应设计文档是否需要更新', + '- 改了实现 → 检查 tests/ 是否有对应测试脚本需要更新', + '- action report 中必须说明文档是否需要更新及处理结果(如「文档无需更新」)', + "", "### Red Flags(如果脑海中出现以下想法,说明你错了)", "", '| Agent 想法 | Red Flag 驳回 |', @@ -259,6 +264,7 @@ class ToolchainConstraintsSection: '| “步骤太多了,选几个做就行” | ❌ 错!必须逐条执行,不可跳过 |', '| “这个步骤不适用于当前情况” | ❌ 如果确实不适用,在 action report 中说明原因,但其他步骤必须执行 |', '| “CI/部署失败不是我代码的问题,我什么也不用做” | ❌ 错!即使是基础设施问题,你也必须创建 Issue 指派 jiangwei-infra(body 含错误来源链接 + 日志 + 判断依据),并在 action report 中说明。不能只报告“不是我的问题”就完事 |', + '| "文档以后再说" | ❌ 错!文档同步和代码改动在同一 PR 中完成,action report 中必须说明文档处理情况 |', "", ] return "\n".join(lines) -- 2.45.4