docs: 切换 DevHarness 新工作流 (#315)

This commit is contained in:
chengma
2026-08-26 17:04:18 +08:00
parent ac1e0b3bc9
commit c63fee157f
10 changed files with 540 additions and 567 deletions
+32
View File
@@ -0,0 +1,32 @@
## 背景
<!-- 为什么要做这个产品或长期能力。 -->
## 目标
- <!-- 填写 -->
## 非目标
- <!-- 填写 -->
## 总体方案
<!-- 只写稳定的架构和关键决策,不复制子任务细节。 -->
## 阶段路线
1. <!-- 填写 -->
## MVP 与任务索引
- [ ] # MVP 工单
## 依赖、风险和回退
- <!-- 填写 -->
## 最终验收标准
- [ ] <!-- 填写 -->
+28
View File
@@ -0,0 +1,28 @@
## 基本信息
- 所属 Epic:#
## MVP 目标
<!-- 这个版本交付后,用户能够完成什么。 -->
## 包含范围
- <!-- 填写 -->
## 排除范围
- <!-- 填写 -->
## 阶段与单元任务
- [ ] # 单元任务
## 集成风险和回退
- <!-- 填写 -->
## MVP 验收标准
- [ ] <!-- 填写 -->
+113
View File
@@ -0,0 +1,113 @@
## 基本信息
- 类型:需求 / 缺陷 / 重构
- 所属 Epic:#
- 所属 MVP / 版本:#
- 阶段:
## 依赖与并行
- 前置工单:无 / #编号
- 是否允许与前置工单并行:是 / 否
- 原因:
## 子项目影响
<!-- 单应用项目填写唯一交付单元;多应用单仓库必须明确单端、跨端和共享契约影响。 -->
- 仅影响的子项目 / 交付单元:
- 是否跨子项目:是 / 否
- 是否修改共享接口或契约:是 / 否;唯一事实来源:
- 各子项目需要执行的验证:
## 原始需求
- 来源:用户对话 / Gitea / 其他
- 提出时间:
- 关键原话或脱敏摘要:
<!-- 只保留表达用户目的、场景和限制所需的内容;不要复制完整聊天、内部推理或敏感信息。 -->
## 要解决什么
<!-- 描述现状和目标。缺陷需要写清复现步骤、实际结果和期望结果。 -->
## 做什么 / 不做什么
- 做:
- 不做:
## 已确认方案
<!-- 写清修改范围、关键设计,以及是否影响接口、数据库和安全边界。 -->
预计修改文件:
- <!-- 填写 -->
## 需求变化记录
<!-- 只记录影响范围、接口、数据、风险或验收的变化;没有变化时填写“无”。 -->
| 日期 | 变化内容 | 原因 | 用户确认 |
|---|---|---|---|
| | | | 是 / 否 |
## 设计与原型门禁
<!-- 先判断是否属于纯显示文案豁免,再选择最低成本、足以确认的设计证据。 -->
- 修改类型:纯显示文案 / 小范围 UI / 新组件 / 新页面或独立用户功能 / 重大交互或导航 / 非 UI / 恢复既有行为的 Bug
- 所需设计证据:无 / 标注截图 / 低保真图 / 已确认原型 / 架构、API、数据、状态或流程设计 / 原设计或复现证据
- 可编辑设计源、线上原型链接和访问检查:
- 审核版本、revision、复制版本或确认日期及识别方式:
- 本地 HTML 导出:未要求 / 用户明确要求 / 项目规则要求
- 本地 HTML 路径、版本和资源检查(仅显式导出时填写):
- 状态:无 / 草稿 / 已确认 / 已废弃
- 确认人、确认时间和覆盖范围:
- 无需 UI 原型或无需任何原型的原因:
<!-- 新页面、独立用户功能、重大交互或导航变化默认通过可访问且版本明确的线上原型审核;只有用户或项目规则明确要求时才导出 prototypes/<工单号>/<版本>/index.html。原型和文字需求未确认前不得编写生产代码。 -->
## 文档影响
<!-- 至少选择一项;不影响长期文档时必须写明原因。 -->
- [ ] 不影响长期文档,原因:
- [ ] 更新项目档案或本地开发与验证
- [ ] 更新架构与代码地图
- [ ] 更新业务规则与术语
- [ ] 更新常见修改或故障排查
- [ ] 更新其他 Wiki 页面:
## 交付文档影响
<!-- 至少选择一项;面向用户、客户或其他岗位的行为、配置、部署、接口或支持方式变化时,必须列出受众和页面。 -->
- [ ] 无交付文档影响,原因:
- [ ] 更新已有交付文档,受众与页面:
- [ ] 新增交付文档,受众与页面:
- [ ] 需要目标岗位或客户代表验证:是 / 否;验证方式:
## 任务记录与可选快照
- 单次任务事实来源:当前 Gitea 工单正文与评论
- [ ] 默认不创建任务快照
- [ ] 用户明确要求专项快照;用途和范围:
- [ ] 项目专用规则要求任务快照;规则入口:
<!-- 工单正文保存确认基线;重要变化、最终证据和验收结论通过评论追加。只有长期事实变化时才更新 Wiki 和同步镜像。 -->
## 验收标准
- [ ] <!-- 填写 -->
- [ ] <!-- 填写 -->
## 验证方式
<!-- 写出可复制的命令;需要真机、生产环境或人工检查时明确说明。 -->
## 风险和回退
<!-- 普通低风险任务可删除本节;涉及接口、迁移、安全或不可逆操作时必填。 -->
+268 -269
View File
@@ -1,299 +1,298 @@
# 项目协作规则
# Agent 开发规则
## 红线
本仓库采用 DevHarness 工作流:Gitea 工单是单次任务需求、变化、实现、测试、提交和验收的事实来源,Gitea Wiki 是长期开发文档的事实来源,Git 是代码与版本绑定资料的变更记录。`docs/` 默认保存核心 Wiki 的只读镜像,`docs/task/` 只保存人工明确要求的专项或历史兼容快照。人负责确认方案与验收,Agent 负责检查、实现、测试和留下证据。
下面五条**任何情况下都不要自行改动,也不要论证它的可行性**。
需要突破其中任何一条时,**停下来问用户**,不要先给方案、不要先评估成本。
开始工作前先阅读任务涉及目录中的 `AGENTS.md`。目录越深的规则越具体,但不得削弱上级安全规则。
[项目档案](docs/00-project-profile.md) 按需阅读,不作为每次任务的固定前置。出现下列情况之一时必须读:需要环境、配置或凭据来源;需要确认目录边界;需要判断子项目与交付单元划分;需要 DevHarness 来源与基线;需要项目专用验收要求。只为查命令不必打开项目档案。
## 常用命令
所有命令默认从仓库根目录执行,与项目档案保持一致。
| 用途 | 命令 |
|---|---|
| 查看工作区 | `git status --short --branch` |
| 检查模板结构 | `python dev_scripts/harness.py check --strict` |
| 运行单元测试 | `python -m unittest discover -s tests -v` |
| 导出核心 Wiki 镜像 | `python dev_scripts/harness.py sync` |
| 检查核心 Wiki 镜像 | `python dev_scripts/harness.py sync --check` |
| 创建可选任务快照 | `python dev_scripts/harness.py archive 123 "修复登录超时"` |
| 增量导出已有快照 | `python dev_scripts/harness.py export` |
| 全量导出已有快照 | `python dev_scripts/harness.py export --all` |
## 1. 永久规则
- 不把密码、令牌、Cookie、私钥、个人数据或生产数据写入代码、日志、工单、Wiki 和文档。
- 不执行未经用户明确授权的发布、付款、删除数据、破坏性迁移或其他不可逆操作。
- 保留用户已有和任务无关的工作区改动,不擅自重置、覆盖或混入提交。
- 发现需求与安全规则、已确认方案或现有数据冲突时,先停止实施并说明影响。
- 测试结果必须真实;未执行或无法覆盖的验证必须明确记录。
项目专用红线写入本文件的“项目专用规则”或对应子目录的 `AGENTS.md`,不要散落在聊天记录中。
## 2. 哪些改动需要工单
新功能、缺陷修复、重构以及任何用户可感知或改变程序行为的修改,必须先建立单元任务工单。
以下小改动可以直接提交,不要求工单:
- 只改错别字、注释或文档措辞;
- 只做格式化、导入排序或不跨文件的内部变量改名;
- 补充类型标注或文档字符串且不改变行为;
- 删除已经确认无人使用的死代码。
- 只修改用户看到的界面显示文案,并且满足本文件“工单与设计证据双门禁”的全部豁免条件。
除严格符合界面显示文案豁免的修改外,只要涉及接口、数据库、状态、权限、安全、并发、用户界面,或者无法确定是否改变行为,就必须建工单。代码组件名、类名、变量、国际化键、API 字段和数据库字段不是显示文案,不适用豁免。
## 3. 需求到实施
1. 先复述目标,阅读相关代码、日志和文档,区分事实与假设。
2. 给出目标、非目标、方案、影响范围、风险、回退方式、验证方法和文档影响。
3. 方案没有得到用户明确确认前,只做只读诊断和方案整理,不实施正式代码。
4. 方案确认后,先建立单元任务工单,再修改代码。
5. 建立新工单不要求其他工单已经完成;开始实施前检查工单声明的前置工单。真实依赖未满足时保持“待实施”,允许并行时必须写明原因。
6. 开始实施前检查分支和工作区,明确哪些现有改动不属于本任务。
7. 严格按工单范围实现;新发现的问题先记录,不顺手混入当前任务。
8. 执行与风险相称的测试,把关键结果和未验证部分更新到工单。实施过程中出现计划外、当前无法解除的问题时才标记“阻塞”。
9. 只有长期事实变化时才修改 Wiki、读取确认,再运行 `python dev_scripts/harness.py sync` 导出本地镜像;没有长期文档影响时在工单说明原因并跳过 Wiki 同步。不得直接编辑镜像后反向覆盖 Wiki。
工单正文保存用户确认的任务基线;根因、范围、方案、风险或阻塞发生重要变化时追加评论。完成实现后用一条评论集中记录最终差异、测试、未验证内容、提交哈希和文档影响;用户验收后再追加验收时间与结论,不重复覆盖或抄写已有证据。
Gitea 不可用时,输出完整工单草稿并说明阻塞。未经用户明确授权,不得默认绕过建单。
### Gitea 交互与工单最小读取
- 所有 Gitea 工单和 Wiki 的查询、创建、更新、评论、状态变更及关闭操作,优先使用项目已配置的 Gitea MCP。
- MCP 不可用或不支持所需操作时才回退 Gitea API,并在当前工单记录回退原因;初始化阶段尚无工单时记录到初始化工单草稿,建单后补回。凭据只从环境或 MCP 安全配置读取。
- 首次接手任务时读取工单确认基线和完成当前判断所需的评论,不因节省 Token 跳过范围、依赖、安全、验收或重要变更。
- 同一任务、同一会话且关键前提未变化时,复用仍有效的工单事实,优先关注当前状态、最新评论和首个未完成步骤,不重复分析已经确认且仍有效的内容。
- 会话、代码、配置、依赖、凭据、远端状态或关键前提变化,任务基线不清楚,或最新评论声明历史需求、方案、范围、风险或验收发生变化时,重新读取必要历史;无法判断影响范围时读取完整工单。
- 连接器不支持评论分页或增量读取时允许读取完整工单,但不得把“已读取全文”误当成需要重新分析全部历史,也不得为规避完整读取而新增本地工单、缓存或第二事实来源。
- 正确性、安全规则和已确认范围优先于 Token 优化;读取边界存在不确定时补读必要证据。
### 新项目 Wiki 初始化门禁
- 从本模板创建新项目时,先创建 Gitea 远端仓库并启用工单和 Wiki,再配置 `wiki-docs.json`;不得把模板自带的本地 `docs/` 当作新项目 Wiki 已初始化的证据。
- 优先使用项目已配置的 Gitea MCP 查询和写入 Wiki;MCP 不可用或不支持所需写操作时,才使用 Gitea API,并在初始化工单记录回退原因。凭据只从环境或 MCP 安全配置读取。
- 先查询线上页面列表;`Home` 不存在时必须先创建 `Home`,在线回读正文并记录 revision,然后再逐页创建或更新其他核心映射页面。
- 每个核心页面写入后必须在线回读并取得 revision。页面缺失、回读失败或没有 revision 时停止初始化,不得开始产品代码。
- 产品编码前必须运行 `python dev_scripts/harness.py sync --verify`;全部成功才表示线上 Wiki 和核心镜像初始化完成。
### 工单与设计证据双门禁
- 纯界面显示文案只有在不改变业务含义、流程、权限、状态、接口、数据、法律/安全/支付/单位等高风险含义、国际化键、程序标识符、布局和可访问性,且没有任何不确定时,才免工单和原型;修改后执行最小界面检查。
- 新页面、独立用户功能、重大交互或导航变化,必须先用 Quant-UX 或其他合适工具制作可审阅原型;用户确认原型、文字需求和覆盖范围后,才能建立或放行实现工单并编写生产代码。
- 上述完整原型形成待审核版本后,默认直接通过 Quant-UX 或其他设计工具的线上链接审核,不要求每次导出本地 HTML。工单必须记录可访问链接、版本/revision 或确认日期、审核版本识别方式、确认人、确认时间和覆盖范围;线上链接无法访问或无法区分版本时停止审核,等待用户确认等效方案。
- 只有用户明确要求 `导出原型 #N`、`导出全部原型`,或项目专用规则明确要求离线交付时,才导出到 `prototypes/<工单号>/<版本>/index.html`。已确认的本地快照不得原位覆盖;版本目录内资源使用相对路径,导出后检查入口、主要交互和资源完整性,但不自动提交。
- 现有界面的小范围样式或布局调整使用标注截图、低保真图或明确复用的现有规范;新组件记录状态、错误和边界。两者只要不符合纯文案豁免就必须建单。
- 后端、接口、数据处理和定时任务不强制 UI 原型,但必须先确认架构、API、数据、状态或流程设计;恢复既有确认行为的 Bug 可以复用原设计、截图、复现步骤或已有验收证据。
- 需要设计证据的工单记录链接或路径、版本/revision 或日期、状态、确认人、确认时间和覆盖范围;没有 UI 原型时记录替代技术设计或原因。
- 页面结构、主要流程、状态、权限、异常处理或验收结果变化时,必须更新原型或文字需求并重新确认后再继续正式编码。
- 草稿原型可以用于讨论;写入 Git/Wiki、多人协作或单独实施时建立设计任务。草稿和经明确授权的隔离技术验证都不得直接作为生产实现。
- 设计工具无法生成用户明确要求的可用 HTML 时,在工单记录限制并停止该导出或离线交付,等待用户确认等效方案;线上原型可访问且版本明确时不因此阻塞线上审核。纯显示文案、小范围 UI、非 UI 需求和恢复既有行为的 Bug 不强制建立完整线上原型或导出 HTML。
### 自然语言快捷指令
快捷指令只是本工作流的自然语言别名,不得绕过方案确认、前置依赖、安全规则、工单范围、Wiki 主源、必要验证或人工验收:
- `只分析`:只读检查并给出方案;不建单、不修改,停在等待确认。
- `建工单`:根据已确认方案创建单元任务工单;建单后停止,不修改代码。
- `执行工单 #N`:检查工单和依赖,实施、测试、提交、推送并回写证据;仅在明确要求时创建任务快照;停在“待验收”。
- `建工单并做`:依次建单和执行,`建工单,做`、`建工单,做` 含义相同;停在“待验收”。
- `继续工单 #N`:优先核对当前状态、最新评论、Git 和必要 Wiki 证据,从首个未完成步骤继续;关键前提未变化时不重复读取和分析仍有效的内容。
- `检查工单 #N`:只读核对范围、验收、测试和证据并输出报告;不自动修复。
- `同步文档`:读取 Wiki、导出核心 `docs/` 并检查一致性,不处理任务归档;不修改 Wiki、不自动提交。
- `导出原型 #N`:人工触发导出指定工单已确认的原型版本,按工单和版本写入 `prototypes/`;不扩展范围、不自动提交。
- `导出全部原型`:人工触发导出当前项目已明确范围内的全部已确认原型;不自动提交。
- `导出任务归档`:人工触发 `python dev_scripts/harness.py export`,只导出新增或 revision 已变化的任务归档;不删除本地文件、不自动提交。
- `导出全部任务归档`:人工触发 `python dev_scripts/harness.py export --all`,读取并导出全部线上任务归档;不删除本地文件、不自动提交。
- `#N 验收通过`:仅在用户明确验收后,在工单追加验收结论;按需更新真实变化的长期 Wiki,推送、同步父工单并关闭任务;不创建或导出任务归档。
方案未确认或前置依赖未满足时,实施类指令必须停在对应门禁;除 `#N 验收通过` 外,快捷指令不得关闭待验收工单。原型和任务快照的导出必须由用户明确提出或项目专用规则明确要求,其他指令不得隐式执行。Gitea 工单不导出全文,`docs/task/` 只是可能不完整的专项或历史兼容快照。详细语义见 [开发工作流](docs/01-workflow.md)。
### 需求记录与流转
- 创建单元任务工单时,记录原始需求的来源、提出时间,以及能表达用户目的、场景和限制的少量关键原话或脱敏摘要;不得臆造用户原话。
- 工单中的目标、非目标、已确认方案、验收标准和文档影响构成确认后的正式任务需求。
- 影响范围、接口、数据、风险或验收的需求变化必须记录日期、内容、原因和用户确认;会改变已确认结果时先更新工单并等待再次确认。
- 不复制完整聊天,不保存 Agent 内部推理,不写入密码、令牌、个人数据或生产数据;包含敏感信息的原话必须删除敏感部分或改写为脱敏摘要。
- 长期有效的产品需求、业务规则和系统边界进入对应 Wiki 主题页并导出核心 `docs/`;单次任务的完成结果和验收保留在工单正文与评论。只有用户明确要求专项快照或项目专用规则要求时才创建 Wiki 任务快照并按需导出 `docs/task/`。Gitea 工单全文不导出到仓库。
详细记录边界见 [开发工作流](docs/01-workflow.md) 与 [业务规则和术语](docs/03-business-rules-and-glossary.md)。
### 效率与范围控制
本节只用于减少无关工作和重复检查,不得削弱安全规则、已确认方案、工单范围、必要测试、必要的长期文档同步、Git 提交和人工验收要求。
#### 严格控制范围
- 默认严格按用户确认的目标和单元任务范围执行,不主动扩展相邻问题。
- 除非任务目标、仓库强制规则或已发现的真实阻塞需要,不新增额外文档、辅助脚本、备份文件、框架、重构或扩展性设计。
- 不执行与本次验收无关的验证;安全检查、受影响范围测试、回归测试和仓库规定的闭环验证不属于“额外验证”。
- 新发现的相邻问题最多用一句话提示或记录到独立工单,不自动修复或混入当前提交。
#### 渐进执行和修复
- 完成已知必要的安全与前置检查后,优先执行能够产生真实反馈的最小命令。
- 一次执行后先处理首个可定位、可行动的真实错误,不同时猜测并修改多个可能原因。
- 采用“执行 → 查看错误 → 最小修复 → 从失败点继续或按需重跑”的闭环。
- 不在真实证据出现前堆叠与已知风险无关的预防性检查。
- 涉及凭据、权限、安全、数据、迁移、并发、删除、发布或不可逆操作时,必须先完成相应前置检查,不得通过试错获取风险反馈。
#### 复用已验证事实
- 在同一任务和同一环境状态下,已经通过的路由、连接、恢复和环境检查不重复执行。
- 只有会话、环境、代码、配置、依赖、凭据、远端状态或关键前提发生变化时才重新检查。
- 代码修改后,受影响测试和最终验收必须重新执行;提交前工作区检查、推送前远端分支检查不得因为之前通过而省略。
- Skill 和平台规则是否需要重新读取,按当前 Agent 平台和任务触发规则执行,不自行跳过。
#### 明确停止条件
- 完成用户确认的验收标准和仓库规定的必要闭环后立即停止,不主动继续优化。
- “最小验收条件”包括当前工单要求的实现、必要测试、文档影响处理、Wiki 镜像检查、提交和证据回写,不等同于功能第一次运行成功。
- 未影响当前验收的相邻问题只提示或建单,不顺手处理。
## 4. 工单层级
- 单元任务是唯一正式实施单位,记录方案、范围、验收标准、过程和测试结果。
- Epic 和 MVP 只维护目标、风险、汇总及 `- [ ] #编号` / `- [x] #编号` 子工单索引,不复制单元任务全文。
- 新任务先建单元工单,再把编号同步到所属 MVP 和 Epic。
- 详细层级、状态和模板入口见 [开发工作流](docs/01-workflow.md) 与 [业务规则和术语](docs/03-business-rules-and-glossary.md)。
## 5. 实施中的变化
- 范围、接口、数据结构、依赖、验收标准或风险变化时,先更新单元工单。
- 变化影响 MVP 或 Epic 时,同时更新父工单。
- 会改变用户已确认结果的变化,更新工单后必须再次等待用户确认。
- 阻塞、失败方案和新发现根因不能只留在聊天或代码注释中。
- Wiki 页面删除、重命名或事实源边界变化时,必须先更新工单并等待用户确认;同步工具不得自动传播删除或重命名。
- 工单状态应使用:待确认、待实施、进行中、阻塞、待验收、已完成。
## 6. Git 与验证
- 提交只包含当前工单相关文件。
- 实现提交信息引用工单号,例如:`fix: 修复登录超时 (#123)`。
- 不为流程制造空提交。
- 优先运行项目档案中记录的格式检查、静态检查、单元测试和必要的集成测试。
- 不能验证的真机、生产、迁移或并发行为必须写入工单;存在明确要求的任务快照时再同步记录。
## 7. 完成和验收
1. 逐项完成验收、测试和实现提交,在工单追加最终证据评论,记录最终方案、差异、结果、提交、遗留问题和文档影响。
2. 工单保持“待验收”,用户没有明确验收通过前不得关闭。
3. 有长期文档影响时,读取确认 Wiki,运行 `python dev_scripts/harness.py sync --check` 检查核心镜像,并把页面 revision 和镜像提交哈希写回工单;没有长期文档影响时不运行 Wiki 同步。
4. 用户验收通过后,在工单追加验收时间和结论,关闭单元工单,并同步更新 MVP 和 Epic;没有真实变化的 Wiki 不重复更新或检查。
5. 默认不创建任务归档。只有用户明确要求专项快照或项目专用规则明确要求时,才运行 `python dev_scripts/harness.py archive <编号> "<短标题>"`;`export` 和 `export --all` 同样必须显式触发。
MVP 内所有单元任务通过后才能做 MVP 集成验收;MVP 通过后才能关闭 MVP。Epic 的全部范围完成后才能关闭 Epic。
详细证据回写、可选快照和文档同步边界见 [开发工作流](docs/01-workflow.md)。
## 8. 可维护性
- 优先使用直白、常见的实现;不要为了少写几行引入晦涩技巧。
- 类和函数保持单一职责,名称表达业务含义。
- 注释解释原因、边界和风险,不逐行翻译代码。
- 错误必须可定位,不静默吞掉失败。
- Wiki 文档先写结论和用途,再写步骤;示例命令应可直接复制,本地 `docs/` 由同步工具生成。
- 面向初级维护者说明从哪里开始读、怎样运行和怎样验证。
### 修改风险
- 低风险修改可由初级程序员在 Agent 协助下处理;接口、配置、依赖、跨模块逻辑和数据结构由 Agent 实现并验证。
- 权限、安全、并发、迁移、支付、删除数据和不可逆操作属于高风险;高风险修改必须停止,由 Agent 分析并等待人工确认。
- 风险按影响范围判断,不按代码行数判断;示例见 [常见修改指南](docs/05-common-changes.md)。
### 文档影响
- 每个单元任务必须在工单中选择“无长期文档影响并说明原因”或列出需要更新的 Wiki 页面。
- 启动、测试、部署、排错命令,模块入口、目录职责、主要调用路径,配置、API、数据结构、状态、业务规则、安全边界、日志位置发生变化时,必须更新对应 Wiki。
- 部署命令变化时,有常驻服务的项目更新自己的 `Deployment-and-Operations` 页面(由 [部署文档模板](docs/templates/deployment.md) 复制建立);没有常驻服务的项目记录为无部署文档影响,不创建空的部署页。
- 普通内部重构只有在入口、行为、配置和验证方式均未改变时,才可以记录为不影响长期文档。
- 必需核心页面及结构以 `python dev_scripts/harness.py check --strict`、[项目档案](docs/00-project-profile.md) 和 [开发工作流](docs/01-workflow.md) 为准;稳定文档与可选历史快照的分工同样以开发工作流为准。
## 9. 引导提交例外
从本模板创建全新仓库时,Gitea 远端和工单尚不存在,允许一次不带工单号的初始引导提交。该提交只能包含仓库骨架、Harness 规则和远端配置准备,不能包含产品功能。
远端建立并推送后,这个例外立即失效。
## 10. 项目专用规则
### 产品红线
下面五条任何情况下都不要自行改动,也不要论证它的可行性。需要突破其中任何一条时,停下来问用户,不要先给方案、不要先评估成本。
1. **Qt 绑定固定 PyQt5。** 不得改用 PyQt6 / PySide2 / PySide6,也不得安装其他绑定对应的 Fluent Widgets 包。
2. **Admin 新建采购任务固定为真实下单(不支付)。** Admin 提交创建表单即表示创建真实采购任务,不再重复要求风险复选框或确认短语;当前账号可见的全部 Client 都允许被指派,不得增加 Client 手工真实采购启用请求。Client 只有在身份、已选 Android 设备和真实采购执行器就绪时才自动声明 live 并领取任务,且仍须通过商品/规格/数量/价格复核、不可逆标记和单次提交门禁。
3. 不自动注册登录,不自动付款。
4. **凭据(token、Cookie、密码)不得写入** `data/`、日志、数据库、Gitea 工单和 `docs/task`。唯一例外:Client 软件更新的公开引导默认密码固定为 `chengma`,必须写入源码、Git、对应工单、基线和归档;该默认值不按生产秘密处理,其他凭据仍不得套用此例外。
4. **凭据(token、Cookie、密码)不得写入** `data/`、日志、数据库、Gitea 工单、Wiki 和文档。唯一例外:Client 软件更新的公开引导默认密码固定为 `chengma`,必须写入源码、Git、对应工单、基线和归档;该默认值不按生产秘密处理,其他凭据仍不得套用此例外。
5. **任务一旦进入不可逆阶段**(`task_runs.irreversible_action_at` 有值),**只准核对订单,绝不重新下单**。
Agent 可以读取包含姓名、手机号、收货地址等个人数据的无障碍控件树 XML,用于页面
识别、故障诊断和正常自动化。原始 XML 仅保存在本机非 Git 目录,不得提交 Git、写入
日志、Gitea 或文档;对外展示前必须脱敏。
Agent 可以读取包含姓名、手机号、收货地址等个人数据的无障碍控件树 XML,用于页面识别、故障诊断和正常自动化。原始 XML 仅保存在本机非 Git 目录,不得提交 Git、写入日志、Gitea、Wiki 或文档;对外展示前必须脱敏。
改动看起来再合理,只要碰到上面任意一条,先停下来告诉用户。
### Wiki 与历史兼容
> **动代码之前,先读对应子项目的 AGENTS.md**,那里有技术栈、分层和硬性规则,本文件不重复:
>
> | 你要改的东西在 | 先读 | 技术栈 |
> |---|---|---|
> | `client/` 桌面客户端 | [client/AGENTS.md](client/AGENTS.md) | Python + PyQt5 |
> | `admin/` 管理端 | [admin/AGENTS.md](admin/AGENTS.md) | Go + Gin + HTML 模板 |
>
> **两个子项目技术栈完全不同,规则不通用,不要拿一边的经验套另一边。**
>
> 第一次接手,先看对应的上手指南和术语表:
> [Client](docs/client/00-getting-started.md) · [Admin](docs/admin/00-getting-started.md)
- 长期开发文档以 Gitea Wiki 为事实来源,单次任务证据以 Gitea 工单为事实来源;`docs/` 保存显式映射生成的只读镜像。
- `docs/task/` 中 2026-08-26 工作流切换前的历史归档冻结保留,不删除、不重命名、不批量重写。之后只有用户明确要求或项目专用规则明确要求时才创建专项快照。
- Wiki 与镜像的固定顺序是:修改 Wiki → 在线读取确认 revision → 导出核心 `docs` → 校验差异 → 提交镜像。
- 同步配置只允许写入 `docs/` 下的 Markdown;发现映射镜像有未提交修改时必须停止。
- Gitea 凭据只通过进程环境或 MCP 安全配置提供,不得写入仓库。
- `dev_scripts/` 只存放 DevHarness 自身工具;Admin 生产部署脚本继续放在 `admin/scripts/`。
## 需求、缺陷与任务工作流
### 本仓库工单约定
本流程适用于新需求、缺陷修复、重构以及会改变程序行为的任务。正式工单采用 **史诗级大工单(Epic)→ 最小可行产品工单(MVP)→ 单元任务工单** 三级结构。Gitea 工单是实施期间的事实来源,本地 `docs/task` 是任务完成后的最终归档。
- Gitea 仓库固定为 `https://git.ilapage.cn/OPC/cmautobuy`。
- Epic 标题使用 `[Epic]` 前缀,MVP 使用 `[MVP]`;Admin 单元任务标题使用 `Admin:` 前缀,Client 单元任务不加该前缀。
- 当前不使用标签和里程碑表达层级;阶段写在 Epic/MVP 章节和 `- [ ] #编号` 清单中。
- 只要用户消息、工单、提交或文档已经出现本仓库工单链接,就说明 Gitea 地址和仓库信息已知;不得再以“Gitea 未配置”绕过建单。
- Gitea 暂时不可用时输出完整工单草稿并明确询问本次是否授权直通;不得默认直通,也不得把上一次授权沿用到下一次任务。
工单和归档直接使用 [docs/templates/task.md](docs/templates/task.md) 里的模板,不要每次自拟结构。
## 11. 面向初级程序员的开发与文档规则
### 0. 小改动直通
**不改变程序行为**的改动可以直接提交,不必建工单、不必归档,只需在提交信息里写清改了什么:
- 错别字、注释、文档措辞;
- 代码格式、导入排序、变量改名(不跨文件、不改公开接口);
- 补充类型标注、补充文档字符串;
- 删除确认无人使用的死代码。
只要满足下面任意一条,就**不属于**小改动,必须走完整流程:
- 改了数据库结构、Admin 接口、任务状态或 `pdd_data` 结构;
- 改了采购、下单、幂等、崩溃恢复或线程相关代码;
- 改了界面上用户能看出来的东西;
- 你不确定它算不算小改动。
### 0.1 Gitea 使用约定
- **地址:** <https://git.ilapage.cn>
- **仓库:** `OPC/cmautobuy`
- **工单层级靠标题前缀区分**,不使用标签和里程碑(当前两者均未启用,
也不要去建——`AGENTS.md` §1 已说明阶段用章节和清单表达,不加正式层级):
| 前缀 | 含义 |
|---|---|
| `[Epic]` | 大工单 |
| `[MVP]` | MVP 工单 |
| 无前缀 | 单元任务 |
- **跨子项目:** Admin 的工单标题加 `Admin:` 前缀;Client 的不加前缀。
### 0.2 没有工单不许改代码
`[必须]` **正式实施前必须有 Gitea 工单号。** 聊天里的工单草稿**不算工单**——
它没有编号,提交引用不了,后续也追溯不到。
`[必须]` Gitea 连不上或信息缺失时,按 §3.6 输出完整草稿并说明阻塞,
然后**每次都明确询问用户是否授权本次直通**。
- **不得默认直通。**
- **不得因为上一次直通过,就默认这次也可以。**
### 0.3 防呆:看到工单链接就说明 Gitea 可用
`[必须]` **只要在任何地方看到本仓库的 Gitea 工单链接**——用户消息、提交信息、
`docs/task` 归档、代码注释——就说明 Gitea 是通的。此时必须:
1. 立刻回填 §0.1 缺失的信息(地址和仓库名从工单 URL 里就能拿到);
2. **停止使用直通路径**,改回正常的建单流程。
**这条是有代价换来的。** 曾经发生过:用户已经给出
`https://git.ilapage.cn/OPC/cmautobuy/issues/12`,
地址和仓库名就在 URL 里,但助手没识别出那就是自己一直在要的信息,
继续拿"Gitea 未配置"当理由跳过建单,还在提交信息里写下
"Gitea 尚未配置,本次无对应工单号"——而同一个提交的标题里就引用着 `(#12)`。
`[必须]` 提交信息里**不得出现"Gitea 未配置 / 无工单号"这类说法**,
除非你在同一次回复里已经明确向用户说明阻塞并得到了直通授权。
### 1. 工单层级与职责
```text
史诗级大工单(Epic)
├── MVP 工单
│ ├── 阶段 1:单元任务工单
│ ├── 阶段 2:单元任务工单
│ └── MVP 集成验收
└── MVP 之后:后续版本的单元任务工单
```
- **大工单:**记录完整产品目标、总体范围与非目标、总体架构、阶段路线、全局风险、所有已知任务索引和最终完成标准。
- **MVP 工单:**记录首个可交付版本的范围与非范围、阶段计划、单元任务清单、集成风险和 MVP 验收标准。MVP 是大工单的可交付子集,不等同于普通开发阶段。
- **单元任务工单:**唯一的实际执行单位,记录具体问题、方案、修改范围、依赖、验收标准、实施记录和测试结果。
- **阶段:**默认使用大工单或 MVP 工单中的章节、清单或 Gitea 里程碑表达,不增加正式工单层级。只有阶段需要独立负责人、独立验收或复杂协调时才单独建工单。
- 原则上不再增加比单元任务更深的工单层级;复杂任务应拆成多个可独立验证的同级任务。
### 2. 需求讨论与总体方案确认
1. 用户提出需求、现象或缺陷,助手先复述目标并检查相关代码、日志和运行环境。
2. 助手按照软件开发规范分析并提出总体方案,明确:
- 已确认事实与仍待验证的假设;
- 根因或需求边界;
- 目标、非目标、建议方案和影响范围;
- MVP 边界以及 MVP 之后的内容;
- 阶段拆分、已知单元任务和依赖顺序;
- 风险、兼容性、回退方式和总体验证方法。
3. 用户审核总体方案,双方继续讨论和修订,直到用户明确确认最终方案。
4. 最终方案确认前默认只允许阅读、诊断、实验性验证和方案整理;不得提前实施正式代码、创建工单、提交 Git 或扩大范围,除非用户明确要求某项操作。
**这条和"类和函数骨架"的边界:** 用户自己写骨架不受本条限制,那是用户在表达需求。本条约束的是助手——方案确认前,助手不写实现代码、不提交 Git。用户已经写好骨架并要求补全时,视为该部分方案已确认,助手可以直接补全,但仍不得越出骨架范围新增功能。
### 3. 创建大工单、MVP 工单与单元任务
1. 用户确认总体方案后,先创建大工单,并写入完整目标、总体方案、阶段路线和所有已知任务索引。
2. 再创建 MVP 工单,在其中定义首个可交付范围、排除项、阶段、验收标准和 MVP 单元任务清单,同时与大工单双向关联。
3. 准备实施某个阶段前,先为其中已具备明确边界的工作创建单元任务工单,再把工单编号更新到 MVP 和大工单的任务清单。
4. 不必为尚不明确的远期工作提前创建空泛的单元工单;先在大工单中保留规划项,待范围清晰后再建单。
5. 每个 Gitea 工单必须使用自己的工单号作为唯一追踪编号,后续分支、提交、进度记录和本地归档都引用对应编号。
6. 如果 Gitea 暂时不可用,应先输出完整工单草稿并说明阻塞;未经用户同意,不得绕过建单直接进入正式实施。
### 4. 各层工单内容规范
大工单和 MVP 工单至少包含:
- 背景、目标、非目标和范围边界;
- 已确认总体方案和关键架构决策;
- 阶段或里程碑;
- 子工单清单及当前状态;
- 依赖、全局风险和回退策略;
- 集成及最终验收标准。
单元任务工单直接套用 [模板 A](docs/templates/task.md),必填项只有 6 条:
1. 基本信息(类型、父级大工单、所属 MVP/版本、阶段);
2. 要解决什么(缺陷附复现步骤);
3. 做什么 / 不做什么;
4. 已确认的实现方案(含预计修改文件);
5. 可逐项打勾的验收标准;
6. 验证方式(可复制的命令;需要真机时写明)。
"风险和回退"为选填,但改动涉及采购下单、数据库迁移或 Admin 接口时必填。
### 5. 单元任务拆分标准
单元任务不按固定数量机械拆分。每个任务应满足:
- 目标单一、边界清晰且可以独立理解;
- 具有明确输入、输出和可逐项检查的验收标准;
- 能够独立开发、测试、提交和回退;
- 修改文件和依赖范围可控,不混入顺手重构或无关修复;
- 一个提交或一组紧密相关的提交可以完成;
- 如果仍包含多个互不依赖的交付结果,应继续拆分为同级任务。
### 6. 新增工单与父工单同步
1. 出现新需求、缺陷、遗漏工作或技术债时,先判断它属于当前 MVP、MVP 后续版本,还是改变大工单总体范围。
2. 先创建新的单元任务工单,并填写父级大工单、所属 MVP/版本、阶段和依赖关系。
3. 属于当前 MVP 时,同时更新 MVP 工单和大工单的任务清单;不属于当前 MVP 时,只更新大工单和对应的后续版本/里程碑,不得擅自扩大 MVP。
4. 新工单会改变已确认范围、交付结果、验收标准或时间安排时,必须先更新父工单并交由用户重新审核,确认后才能实施。
5. 详细分析和实施记录只保存在单元工单;MVP 工单只维护交付进度和集成状态;大工单只维护总体路线和范围,避免三处复制同一正文。
### 7. Git 准备与任务实施
1. 只有单元任务工单已建立、方案和验收标准明确后,才能进入正式实施。
2. 开始前检查工作区和当前分支,保留用户已有及与任务无关的改动。
3. 严格按照单元工单范围实施;不得把其他工单、顺手重构或无关修复混入当前任务。
4. 只有存在与工单相关的实际文件变更时才提交 Git,不得为了流程创建空提交。
5. 提交信息应简洁描述变更并引用单元工单号,例如 `fix: 修复规格匹配 (#123)`。
6. 实现过程中执行与风险相称的检查和测试,把关键进度、测试结果和提交哈希记录到单元工单。
### 8. 实施中的变更管理
- 范围、技术方案、接口、数据结构、依赖、验收标准、测试计划、风险或交付时间发生变化时,必须先更新单元工单。
- 变化影响 MVP 工单或大工单时,还必须同步更新对应父工单的范围、风险、计划或任务索引。
- 会改变用户已确认方案或交付结果的实质性变化,必须先写入工单并再次交由用户审核,确认后才能继续实施。
- 不改变外部行为的普通实现细节可以继续推进,但应在单元工单的实施记录中说明重要取舍。
- 阻塞、失败方案、新发现的根因或无法完成的验收项必须及时更新工单,不得只保留在聊天记录或代码注释中。
- 工单状态必须与实际进度一致:待确认、待实施、进行中、阻塞、待验收、已完成。
### 9. 单元任务完成与本地归档
1. 完成实现后,先按单元工单的验收标准执行验证,记录实际结果和未验证内容。
2. 将实现代码按可理解、可验证的粒度提交,所有提交都引用单元工单号。
3. 更新单元工单,写明最终实现、与原方案的差异、测试结果、实现提交和遗留问题。
4. 将完整单元任务归档为 `docs/task/<工单号>-<简短名称>.md`,目录不存在时创建。
5. 本地任务文档直接套用 [模板 B](docs/templates/task.md),必填项只有 6 条:
1. 头部信息(工单号、标题、类型、父级、版本、状态、日期、Gitea 链接);
2. 背景与目标;
3. 最终方案(与建单方案有出入时写清差异和原因);
4. 改了哪些文件;
5. 验收结果(逐项);
6. 测试:执行的命令、结果、**未验证到的部分**。
第 6 条的"未验证到的部分"不允许留空,没有就写"无"。"遗留问题"为选填。
6. 单独提交本地归档文档,例如 `docs: 归档任务 #123`,并把归档提交哈希和文档路径回写到单元工单。
7. 用户验收通过或明确同意后关闭单元工单,并立即更新 MVP 工单和大工单的任务清单及汇总状态。
### 10. MVP 工单与大工单的完成顺序
1. 单元任务逐个完成、归档、验收和关闭。
2. MVP 范围内所有任务完成后执行集成、回归和 MVP 验收,记录跨任务测试结果。
3. MVP 验收通过后,在 `docs/task` 创建对应的 MVP 总结文档,提交并回写 Gitea,然后关闭 MVP 工单。
4. 大工单规划的所有版本和最终验收完成后,创建大工单总结文档,提交并回写 Gitea,最后关闭大工单。
5. 不得因为单元任务已完成而提前关闭 MVP 工单,也不得因为 MVP 已完成而提前关闭仍有后续范围的大工单。
### 11. 记录与安全原则
- Gitea 单元工单保留详细讨论、决策、进度和变更历史;MVP 工单和大工单保留汇总;`docs/task` 保存与最终代码版本对应的结论。
- 聊天记录不能替代 Gitea 工单或本地任务文档。
- 父工单使用 `- [ ] #工单号` / `- [x] #工单号` 等清单维护子工单索引,不复制子工单全文。
- 工单和归档中的命令、日志与截图必须去除密码、访问令牌、浏览器 Cookie、个人数据及其他敏感信息;仅 Client 软件更新公开默认值 `chengma` 可按红线第 4 条记录。
- 每个 Git 提交必须可理解、可验证、可追溯,且不得包含无关文件。
## 面向初级程序员的开发与文档规则
本项目默认由初级程序员阅读和维护。设计、代码、注释、文档和交付说明都应以容易理解、容易调试和容易继续修改为优先目标。
新人从这两份开始读,不要一上来啃基线文档:
- [docs/client/00-getting-started.md](docs/client/00-getting-started.md) —— 装环境、跑起来、常见报错
- [docs/client/00-glossary.md](docs/client/00-glossary.md) —— 专业术语一句话解释
本项目默认由初级程序员阅读和维护。设计、代码、注释、文档和交付说明都以容易理解、容易调试和容易继续修改为优先。
### 类和函数骨架
- 初级程序员可以先创建类或函数骨架,再由助手按照已确认工单补全实现。
- 骨架应尽量写明名称、职责、参数、返回值和可能的错误;暂未实现的部分使用清晰的 `TODO`,不得伪装成已经完成。
- 助手补全骨架前先理解原有命名和职责,能在现有边界内完成时不要随意重命名、移动文件或重做架构。
- 如果骨架存在明显职责混乱、线程错误或安全风险,先解释问题并提出最小调整方案;涉及已确认方案变化时按工单流程重新审核。
- 补全后删除已经完成的 `TODO`,保留仍未完成且有明确原因的事项。
- 初级程序员可以先创建类或函数骨架,再由 Agent 按已确认工单补全。
- 骨架应写明名称、职责、参数、返回值和可能错误;未实现部分使用清晰的 `TODO`,不得伪装完成。
- 能在现有边界内完成时不要随意重命名、移动文件或重做架构。
- 骨架存在职责混乱、线程错误或安全风险时先说明最小调整;改变已确认方案时重新审核。
### 代码可读性
- 优先使用直白、常见的 Python 写法,不为减少几行代码使用晦涩技巧、元编程或过深继承。
- 类和函数保持单一职责;函数过长或同时处理界面、网络、数据库和自动化时,应按职责拆分。
- 名称应表达业务含义,避免无意义缩写以及 `data1`、`temp2`、`handle` 等模糊名称。
- 公共类、函数和复杂业务规则应提供简短中文文档字符串,说明“做什么、输入什么、返回什么、何时失败”。
- 注释重点解释“为什么这样做”和风险约束,不逐行翻译代码。
- 使用类型标注、枚举和小型数据对象表达边界;避免到处传递结构不明的字典。
- 错误应返回或抛出明确类型和信息,不使用裸 `except`,不静默忽略失败。
- 除非确实需要扩展点,不提前设计复杂抽象;出现第二个真实实现后再考虑提取通用层。
- 修改现有代码时保持风格一致,并尽量提供一个最小调用示例或对应测试。
- 优先使用直白、常见的 Python 或 Go 写法,不为少写几行使用晦涩技巧、元编程或过深继承。
- 类和函数保持单一职责;界面、网络、数据库和自动化不要堆在同一个长函数里。
- 名称表达业务含义,避免无意义缩写和 `data1`、`temp2`、`handle` 等模糊名称。
- 公共类、函数和复杂业务规则提供简短中文说明,注释重点解释原因和风险。
- 使用类型标注、枚举和小型数据对象表达边界;错误必须明确,不使用裸 `except`,不静默忽略失败。
- 出现第二个真实实现后再考虑提取通用层,不提前设计复杂抽象。
### 文档编写
- 文档使用简洁、自然的中文,先说明用途和结论,再写必要步骤和规则。
- 一个文档只解决一个主要问题;使用短段落和短列表,避免堆叠大段理论说明。
- 专业术语统一收录在 [docs/client/00-glossary.md](docs/client/00-glossary.md)。新词要么在术语表里加一条,要么在正文用一句话解释,两者至少做一个;不能翻译的类名、字段名、命令和协议名保持原样。
- 命令和示例必须可以直接复制,并说明从哪个目录执行、预期看到什么结果。
- 数据结构、状态对应关系和接口字段优先使用小型表格或短示例;关系简单时不要绘制复杂架构图。
- 文档只记录稳定需求、使用方法和关键约束,不复制容易与代码失去同步的内部实现细节。
- 进度、临时方案和待办写入 Gitea 工单;完成记录写入 `docs/task`,不反复修改长期基线文档。
- 修改已有长文档时应顺便删除重复和过时内容,但不得为了缩短文档丢失安全、数据和验收约束。
- 文档末尾只列真正未解决、需要用户决定的问题,不添加泛化的“未来可优化”清单。
- 文档使用简洁中文,先说明用途和结论,再写必要步骤和规则。
- 一个文档解决一个主要问题;专业术语进入对应 Wiki 术语页或在正文一句话解释。
- 命令必须可复制,说明执行目录和预期结果。
- 稳定需求、使用方法和关键约束写 Wiki;进度、临时方案和单次任务证据写 Gitea 工单。
- 文档末尾只列真正未解决、需要用户决定的问题,不添加泛化“未来可优化”清单。
### 助手交付说明
- 面向初级程序员说明改了什么、为什么、从哪里开始读以及怎样运行验证。
- 优先给出最短可行操作,不一次列出大量可选方案;存在重要取舍时再解释替代方案。
- 报错分析应指出具体位置、直接原因、修复方法和验证方式,不只给出修改后的完整代码。
- 不假设维护者熟悉 Qt 线程、SQLite 事务、Admin 幂等或 uiautomator2 控件树;涉及这些概念时给出一句话背景。
- 面向初级程序员说明改了什么、为什么、从哪里开始读以及怎样验证。
- 报错分析指出具体位置、直接原因、修复方法和验证方式,不只给完整替换代码。
- 不假设维护者熟悉 Qt 线程、MySQL 迁移、Admin 幂等或 uiautomator2 控件树;首次涉及时用一句话解释。
## 子项目
## 12. 子项目与共享契约
本仓库有两个子项目,**技术栈完全不同,规则各自独立**:
动子项目代码前必须读取对应规则:
| 子项目 | 是什么 | 规则文件 | 基线文档 |
|---|---|---|---|
| `client/` | Windows 桌面客户端,控制安卓设备执行采集和采购 | [client/AGENTS.md](client/AGENTS.md) | [docs/client/](docs/client/) |
| `admin/` | 本地 Web 管理端,管理商品、订单、任务和客户端 | [admin/AGENTS.md](admin/AGENTS.md) | [docs/admin/](docs/admin/) |
| 目录 | 先读 | 技术栈 |
|---|---|---|
| `client/` | [client/AGENTS.md](client/AGENTS.md) | Python 3.10 + PyQt5 |
| `admin/` | [admin/AGENTS.md](admin/AGENTS.md) | Go 1.23 + Gin + HTML 模板 |
- 处理某个子项目下的需求、代码、测试或文档前,必须读取并遵循它的 `AGENTS.md`。
- 从仓库根目录启动时也不能跳过(本文件开头已重复提醒一次)。
- 按当前任务只读取相关文档,清单见 [文档索引](docs/README.md)。
- 子项目专用的技术栈、分层、安全和验证规则不在根文件重复维护。
### 两者的接口边界
Admin 和 Client 通过四个 HTTP 接口交互,**契约以 Client 侧文档为准**:
[docs/client/04-admin-api-contract.md](docs/client/04-admin-api-contract.md)。
改动接口时,两边的文档必须在同一个工单里同步更新,不允许只改一边。
- 两个子项目技术栈完全不同,规则不通用。
- 第一次接手按 [文档首页](docs/README.md) 进入对应上手指南和术语页。
- Admin 和 Client 的 HTTP 契约以 [Client 侧文档](docs/client/04-admin-api-contract.md) 为唯一事实来源。
- 修改共享接口时在同一个工单里同步两边文档和验证,不允许只改一边。
+22 -201
View File
@@ -1,210 +1,31 @@
# 多模型协作规则
# Claude Code 项目入口
本文件只讲**谁做什么、怎么交接、怎么审查**。
@AGENTS.md
项目本身的规则(红线、工单流程、技术栈、分层、安全)全部在
[AGENTS.md](AGENTS.md) 和各子项目的 `AGENTS.md` 里,**本文件不重复、不复述**——
复述一次就走样一次,两份文档迟早说不一样的话。
## Claude Code 专用说明
---
- 上方导入的 `AGENTS.md` 是所有编码 Agent 的共同规则事实来源,Claude Code 必须完整遵守。
- 本文件只记录 Claude Code 特有的模型路由、工具和 Agent 协作规则。
- 共同规则变化时只修改 `AGENTS.md`,不要在本文件重复维护。
## 1. 为什么这样分工
## 模型路由
不按"任务难不难"分,按**错了多久才会被发现**分:
- 目标、范围和修改位置已经明确时,默认使用 Sonnet 分析、建单和实施。
- 需求模糊、根因不明,或涉及跨模块架构、安全、权限、并发、迁移和不可逆操作时,使用 Opus 或 `opusplan` 制定方案。
- Opus 输出方案后必须等待用户确认;确认后由 Sonnet 根据方案创建工单并实施。
- Haiku 只用于范围明确的只读任务,例如查找代码入口、读取项目文档、提取日志事实和整理调用关系。
- 不让 Haiku 决定最终根因、技术方案、风险等级或验收结论。
- 当前模型足以完成任务时不升级模型,也不为了形式固定依次调用三个模型。
| 错误类型 | 什么时候暴露 | 代价 |
|---|---|---|
| 设计决策错 | 几周后,可能是买错货才发现 | 数据已经脏了,返工 + 真金白银 |
| 代码实现错 | 跑测试的那一刻 | 改掉重跑,几分钟 |
| 复述文档错 | 人一看就发现 | 重问一次 |
## Agent 交接
所以:**设计交给最强的模型,实现交给能靠测试兜住的,只读查询交给最便宜的。**
- Opus 向 Sonnet 交接目标、非目标、事实、假设、方案、修改范围、风险、回退方式和验收标准。
- Haiku 向主 Agent 交接结论、证据位置和仍不确定的内容,不返回与任务无关的大段原文。
- Sonnet 严格按照已确认方案和工单实施;发现范围变化时返回主流程重新确认。
- 不同 Agent 复用仍然有效的检查结果;会话、环境或关键前提变化时才重新检查。
## 2. 角色分工
## Haiku 只读约束
| 角色 | 模型 | 干什么 | 交付物 |
|---|---|---|---|
| **架构** | Opus | 分析需求和缺陷、定根因、设计方案、写工单、**审查实现** | 工单(模板 A) |
| **实现** | Sonnet | 按工单写代码和测试、跑验证、改对应文档 | 代码 + 测试 + 实际验证输出 |
| **查询** | Haiku | 查文档回答问题、汇总现状、检查链接、找规则出处 | 带出处的答复 |
---
## 3. 架构(Opus)
### 必须做
- 动手前**读代码和数据**确认事实,不要基于猜测设计。
本项目有过教训:靠猜写进文档的"新设备第一次 claim 必然返回 204"是错的。
- 方案里每条**看起来多余的约束,必须写清它在防什么**(见 §4)。
- 设计完**自己实跑一次关键路径**再宣布可用。本项目两个并发缺陷
(PRAGMA 没作用到连接池、事务 `BEGIN DEFERRED` 死锁)都是
单线程读代码看不出来、跑起来才炸的。
- 发现自己之前说错了,直接改正并说明,不要顺着圆。
### 不得做
- 不得在没有工单的情况下让下游改代码。
- 不得把"我认为对"当成"已验证"。没跑过就说没跑过。
---
## 4. 交接物:工单必须自足
**下游拿到工单时没有你的上下文。** 它会把理由不明的约束当成冗余优化掉。
所以每条硬性约束都要带一句"为什么":
```text
✗ sku_mappings 主键用 (shopee_sku_id, pdd_goods_id)
✓ sku_mappings 主键用 (shopee_sku_id, pdd_goods_id)
—— 只用 shopee_sku_id 的话,PDD 商品从 A 换成 B 后旧映射还在,
B 恰好有同名规格时会静默买错东西,而且事后查不出来
```
工单必须包含 [模板 A](docs/templates/task.md) 的 6 项,**一项都不能省**:
1. 基本信息
2. 要解决什么(缺陷附复现步骤)
3. **做什么 / 不做什么** ——「不做」和「做」一样重要,防止范围蔓延
4. 已确认的方案,含预计修改文件,**每条约束带理由**
5. 可逐项打勾的验收标准
6. 可直接复制的验证命令
---
## 5. 实现(Sonnet)
### 必须做
- 动手前读根 `AGENTS.md` 的红线和对应子项目的 `AGENTS.md`。
- **严格按工单的「不做」清单**,不顺手做别的。范围蔓延会让工单没法独立验收和回退。
- 每写完一部分就编译 / 跑测试,不要攒到最后。
- 完成后跑完整验证并**贴出实际输出**,不要只说"通过了"。
- 报告里必须写明三件事:
1. 哪些验收项**没做到**;
2. 你**偏离工单**的任何决定及原因;
3. **未验证到的部分**(没有就写"无",不许留空)。
### 不得做
- **不得改工单范围。** 觉得方案有问题就停下来退回架构角色,不要自作主张改设计。
- **不得删改看不懂的约束或测试。** 测试红了先想"是不是我改错了",
而不是"这个测试过时了"。本项目的测试名就是规则本身
(例如 `TestSubmitResult_任务已取消仍然接受`),删掉它等于删掉一条业务规则。
- **不得用目录级 `git add`。** 逐个文件暂存,避免把别人正在改的东西卷进提交。
- 不得提交 git,除非工单明确要求。
---
## 6. 查询(Haiku)
### 必须做
- **引用原文并给出处**(文件 + 章节号),不要转述规则。规则被转述一次就走样一次。
- 查不到就说查不到,不要推测。
### 不得做
- **不得判断设计是否合理**,那是架构角色的事。
- **不得修改任何文件**,包括文档。
- 不得回答"应该怎么做",只回答"文档里怎么写的"。
---
## 7. 审查与返工
**实现交付 ≠ 完成。** 架构角色必须逐条审查,不达标就打回让实现继续做。
### 7.1 审查五步
按顺序做,**不许跳步**:
| # | 检查 | 怎么做 |
|---|---|---|
| 1 | **自己跑验证** | 亲自执行工单里的验证命令,**不采信报告里的结论**。读代码看不出并发问题,跑一次就知道 |
| 2 | **验收标准逐条对照** | 一条条核,不许"整体看起来没问题"。没做到的要能指出是哪一条 |
| 3 | **看 diff 有没有削弱约束** | 有没有删测试、放宽 `CHECK`、去掉校验、把 `[必须]` 改成 `[建议]`。**这类改动一律先当成错的**,除非工单明确要求 |
| 4 | **看范围有没有蔓延** | 有没有做「不做」清单里的事,有没有顺手改无关文件 |
| 5 | **追问"未验证到的部分"** | 写"无"的时候要**格外怀疑**。真实的任务几乎总有没验证到的东西(真机行为、迁移、并发、边界) |
### 7.2 打回时必须说清三件事
打回不能只说"不行",否则实现只能靠猜:
1. **哪一条**验收标准没达到(引原文);
2. **当前是什么**(贴实际输出或代码片段);
3. **期望是什么**(可验证的描述,不是"改好一点")。
```text
✗ 测试不够,再补一些
✓ 验收标准「换回 A 后 A 的映射仍然可用」没有对应测试。
当前 sku_mappings 相关只有 3 个用例,都是单一 PDD 商品的场景。
需要新增:匹配 A → 换到 B → 换回 A → 断言 A 的映射直接可用、
不需要重新匹配。
```
### 7.3 不要替它改
审查发现问题,**打回让实现去改,不要自己动手改完说"我帮你修了"**。
原因有两个:架构角色的时间应该花在设计和审查上;以及实现角色下次还会犯同样的错。
例外:**只有一处、且是纯笔误**(拼错、格式)时可以直接改,并在报告里说明。
### 7.4 打回两次还不对,问题在工单
**同一个点被打回两次仍未达标,就不要再打第三次。** 这基本可以确定是
工单没写清楚,不是实现能力问题。这时架构角色要做的是:
1. 重读自己写的那条要求,**找出哪里有歧义**;
2. 改工单,把约束和理由写具体(往往是缺了"为什么");
3. 或者判断这块确实需要完整上下文,**自己接手做**。
继续打回只会来回消耗。
### 7.5 实现暴露了设计问题,架构要认
实现过程中经常会暴露设计缺陷——这是好事,说明问题在便宜的阶段被发现了。
`[必须]` 这时**改工单,不要让实现硬凑**。本项目就发生过:并发测试报
`SQLITE_BUSY`,根因是 `db.go` 里 PRAGMA 的用法错了,不是测试写得不对。
当时如果让实现"想办法让测试过去",很可能会去改测试而不是改根因。
### 7.6 通过的标准
同时满足才算完成:
- [ ] 架构角色**亲自跑过**验证命令,输出符合预期
- [ ] 验收标准逐条达成,未达成的已明确记录并有后续安排
- [ ] diff 里没有未经工单批准的约束削弱
- [ ] 没有范围蔓延
- [ ] "未验证到的部分"如实列出
---
## 8. 绝对不下放的事
碰到下面任何一条,**必须由架构角色处理,不得交给实现或查询角色**:
1. 根 `AGENTS.md` 的**五条红线**相关的任何改动
2. **金额、幂等、崩溃恢复、并发**相关的设计
3. **数据库结构变更的设计**(实现可以下放,设计不行)
4. **接口契约变更**(两个子项目之间的边界)
5. 任何**"错了要几周后才发现"**的判断
判断不了算不算,就当作算。
---
## 9. 验证是唯一的验收依据
- 说"通过了"必须附**实际命令输出**。
- 说"实现了"必须有**能跑的测试**。
- 说"验证过"必须**真的跑过**,不是读代码推断的。
- 没跑到的部分**必须明说**,不允许留空。
本项目已经证明:单线程读代码看不出并发问题,测试跑一次就抓到了——
而且抓到了两次,两次根因还不一样。
- Haiku 子 Agent 只允许使用读取、搜索和只读代码图谱工具。
- 禁止 Haiku 修改文件、创建或更新工单、提交 Git、更新 Wiki 或执行具有副作用的命令。
- 只读必须通过子 Agent 工具权限实现,不能只依赖提示语;未配置只读权限时不得调用 Haiku 处理项目内容。
+50
View File
@@ -0,0 +1,50 @@
# cmautobuy
cmautobuy 包含 Admin Web 管理端和 Client Windows/Android 执行端,用于管理蝦皮、PDD、顺运宝、采集任务和真实采购任务(只创建未付款订单,不自动付款)。
## 从哪里开始
- 项目文档:[Gitea Wiki](https://git.ilapage.cn/OPC/cmautobuy/wiki/Home)
- 项目档案:[docs/00-project-profile.md](docs/00-project-profile.md)
- Admin 规则:[admin/AGENTS.md](admin/AGENTS.md)
- Client 规则:[client/AGENTS.md](client/AGENTS.md)
- 共同规则:[AGENTS.md](AGENTS.md)
本地 `docs/` 是与代码版本绑定的 Wiki 只读镜像,不是编辑主源。
## 快速验证
从仓库根目录执行:
```powershell
python -m unittest discover -s tests -v
python dev_scripts/harness.py check --strict
python dev_scripts/harness.py sync --check
```
Admin 和 Client 的专用启动、测试与安全边界见各自 `AGENTS.md` 和上手指南。真实采购、真机、生产数据库和部署不是普通冒烟测试。
## Wiki 初始化与同步门禁
从此仓库建立新的远端项目时,顺序固定:
1. 创建 Gitea 远端仓库并推送当前引导提交,启用工单和 Wiki。
2. 优先使用已配置的 Gitea MCP 查询线上页面。
3. `Home` 不存在时先创建并回读 `Home`,记录 revision。
4. 逐页创建、回读其余映射页面。
5. 运行:
```powershell
python dev_scripts/harness.py sync --verify
```
本地 `docs/` 的存在不能证明线上 Wiki 已初始化。页面缺失、回读失败、没有 revision 或一致性检查失败时必须停止。
## 事实来源
- Gitea 工单是单次任务唯一事实来源。
- Gitea Wiki 是长期开发文档事实来源。
- Git 保存代码和与版本绑定的 Wiki 镜像。
- 默认不创建任务归档;历史 `docs/task` 冻结保留,专项快照只能显式创建或导出。
任何产品行为修改都按 [开发工作流](docs/01-workflow.md) 执行,并遵守根与子项目 `AGENTS.md`。
+5 -1
View File
@@ -173,6 +173,10 @@ ARCHIVE_HEADINGS = (
"## 测试",
"## 相关提交",
)
LOCAL_ONLY_MARKDOWN = {
# 历史链接兼容入口;真正模板在 .gitea/issue_template/。
"docs/templates/task.md",
}
def check_required_files(errors: list[str]) -> None:
@@ -425,7 +429,7 @@ def check_wiki_mirrors(errors: list[str]) -> None:
path.relative_to(ROOT).as_posix() for path in (ROOT / "docs").rglob("*.md")
if path.parent != ROOT / "docs" / "task"
}
for path in sorted(actual_paths - mapped_paths):
for path in sorted(actual_paths - mapped_paths - LOCAL_ONLY_MARKDOWN):
errors.append(f"docs 中存在未登记的 Wiki 镜像:{path}")
for mapping in config.mappings:
+4 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Development-Workflow
wiki_url: https://git.ilapage.cn/OPC/cmautobuy/wiki/Development-Workflow.-
wiki_revision: 7154bfff323bc66a4f66725ffdbc823046ccabee
synchronized_at: 2026-08-26T08:42:36Z
wiki_revision: 3c5c91353b36ed45008df6e4e7dd8a23f3d7e105
synchronized_at: 2026-08-26T09:03:16Z
<!-- gitea-wiki-mirror:end -->
# 开发工作流
@@ -15,6 +15,8 @@ synchronized_at: 2026-08-26T08:42:36Z
- Git 保存源码、与特定代码版本强绑定的文档,以及 Wiki 的本地镜像。
- 本地 `docs/` 仅供浏览和审查,不是长期文档编辑入口。
> cmautobuy 兼容说明:`docs/task/` 中 2026-08-26 流程切换前的归档冻结保留,不删除、不重命名、不批量重写;切换后的任务默认只在 Gitea 工单追加证据。
## Gitea 交互与工单最小读取
- 所有 Gitea 工单和 Wiki 的查询、创建、更新、评论、状态变更及关闭操作,优先使用项目已配置的 Gitea MCP。
+14 -94
View File
@@ -1,103 +1,23 @@
# 工单与归档模板
# 工单模板兼容入口
复制下面的模板去用,不要每次从零写。字段说明见 [AGENTS.md](../../AGENTS.md)。
本文件只为兼容历史链接,不再保存第二份可复制模板。
- **建单时**用模板 A,贴到 Gitea 工单正文里。
- **做完后**用模板 B,另存为 `docs/task/<工单号>-<简短名称>.md`。
## 当前模板
模板里带 `(选填)` 的行,没有内容就整行删掉,不要留个空标题。
- Epic:`.gitea/issue_template/epic.md`
- MVP:`.gitea/issue_template/mvp.md`
- 单元任务:`.gitea/issue_template/task.md`
- 完整流程:[开发工作流](../01-workflow.md)
---
Gitea 工单是单次任务需求、变化、实现、测试、提交和验收的事实来源。模板变化只修改 `.gitea/issue_template/` 和必要的流程 Wiki,不在这里复制正文。
## 模板 A:单元任务工单(建单时用)
## 任务快照
```markdown
## 基本信息
默认不创建本地任务归档。只有用户明确要求专项快照或项目专用规则明确要求时,才使用:
- 类型:需求 / 缺陷 / 重构
- 父级大工单:#
- 所属 MVP / 版本:
- 阶段:
## 要解决什么
<!-- 现在是什么情况,为什么要改。缺陷要写清怎么复现。 -->
## 做什么 / 不做什么
- 做:
- 不做:
## 怎么做
<!-- 已经和用户确认过的方案。写清楚改哪几个文件、动不动数据库、动不动接口。 -->
## 验收标准
<!-- 一条一条能打勾的。别写"功能正常"这种没法验证的。 -->
- [ ]
- [ ]
## 怎么验证
<!-- 具体到能复制粘贴的命令;需要真机的要写明。 -->
## 风险和回退(选填)
<!-- 可能出什么问题,出了怎么退回去。碰采购、数据库迁移、Admin 接口的必填。 -->
```powershell
python dev_scripts/harness.py archive 123 "简短标题"
python dev_scripts/harness.py export
```
---
## 模板 B:完成归档(`docs/task/` 用)
```markdown
# <工单号> <标题>
- 类型:需求 / 缺陷 / 重构
- 父级大工单:#
- 所属 MVP / 版本:
- 状态:已完成
- 日期:YYYY-MM-DD
- Gitea 工单:<链接>
## 背景与目标
<!-- 原来什么问题,这次要达到什么。 -->
## 最终方案
<!-- 实际怎么做的。和建单时的方案有出入就写清楚差在哪、为什么改。 -->
## 改了哪些
<!-- 主要文件清单 + 一句话说明各改了什么。 -->
## 验收结果
| 验收标准 | 结果 |
|---|---|
| | 通过 / 未通过 |
## 测试
- 执行的命令:
- 结果:
- **没验证到的部分**:<!-- 必填。没有就写"无"。真机行为、迁移、并发这类经常漏,漏了要写出来。 -->
## 遗留问题(选填)
## 相关提交
- `<提交哈希>` <提交说明>
```
---
## 写工单的几个提醒
1. **验收标准要能打勾。** "表格显示正常"没法验证;"1000 条数据下滚动到底能继续加载,且当前选中行不丢"可以验证。
2. **"没验证到的部分"不许留空。** 真机没跑就写真机没跑。瞒下来的风险最后都会变成事故。
3. **不确定的东西写进工单,不要只写在代码注释里。** 聊天记录和注释都不算数。
4. **一个工单只干一件事。** 顺手改的无关内容单独开工单,别混进来。
`docs/task/` 中 2026-08-26 工作流切换前的历史归档冻结保留,不删除、不重命名、不批量重写。
+4
View File
@@ -14,6 +14,7 @@ import harness # noqa: E402
from harness import ( # noqa: E402
CORE_DOCUMENT_REQUIREMENTS,
CORE_PAGE_PATHS,
LOCAL_ONLY_MARKDOWN,
REQUIRED_FILES,
check_claude_code_entry,
check_required_files,
@@ -53,6 +54,9 @@ class CoreDocumentTests(unittest.TestCase):
any(mapping.path.startswith("docs/task/") for mapping in config.mappings)
)
def test_legacy_task_template_is_explicit_local_only_pointer(self) -> None:
self.assertIn("docs/templates/task.md", LOCAL_ONLY_MARKDOWN)
def test_product_requirements_overview_is_core_document(self) -> None:
path = "docs/09-product-requirements-overview.md"
self.assertEqual(