起因:实测发现 Codex 不会主动把 338 行的规则手册当判断依据—— 问“能用 PySide6 吗”答“可以评估”,问“加个 emoji 图标”直接给改法, 问“改错别字要建工单吗”结论对但依据是通用常识、不是 §0 的实际条件。 三次都表现为“知道代码事实,但不应用项目规则”。 对策一:红线上收 - 根 AGENTS.md 开头新增 5 条红线(Qt 绑定、下单开关、风控、凭据、 不可逆阶段),并明确“不要论证其可行性,先停下来问用户” 对策二:把约束放到 agent 必然会打开的文件里 - pdd_ui.py / pdd_ui_event.py / settings_ui.py / settings_ui_event.py 写入模块 docstring,说明各自职责和最易踩的硬性规则 - 四个文件目前只有 docstring,无实现 同步修正 - ui_event.py 已拆成按页面分的四个文件,更新 client/AGENTS.md 的代码分层规则和 02 §3.1 的现状差异表 未包含:ui_main.py 和 demo1/auto_v1.py 的同类 docstring, 这两个文件承载尚未提交的代码,留待代码提交时一并处理。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
17 KiB
项目协作规则
红线
下面五条任何情况下都不要自行改动,也不要论证它的可行性。 需要突破其中任何一条时,停下来问用户,不要先给方案、不要先评估成本。
- Qt 绑定固定 PyQt5。 不得改用 PyQt6 / PySide2 / PySide6,也不得安装其他绑定对应的 Fluent Widgets 包。
- 真实下单开关默认关闭。 不得通过调试参数、默认配置或界面误操作打开;未通过采购安全门禁前一律走演练模式。
- 不绕过拼多多的验证码、风控和安全机制,不自动注册登录,不自动付款。
- 凭据(token、Cookie、密码)不得写入
data/、日志、数据库、Gitea 工单和docs/task。 - 任务一旦进入不可逆阶段(
task_runs.irreversible_action_at有值),只准核对订单,绝不重新下单。
改动看起来再合理,只要碰到上面任意一条,先停下来告诉用户。
动
client/下任何东西之前,先读 client/AGENTS.md。 那里有技术栈、代码分层、线程、采购安全和界面的硬性规则,本文件不重复。 本项目的代码目前全部在client/下,所以基本上只要是写代码,就必须先读它。
需求、缺陷与任务工作流
本流程适用于新需求、缺陷修复、重构以及会改变程序行为的任务。正式工单采用 史诗级大工单(Epic)→ 最小可行产品工单(MVP)→ 单元任务工单 三级结构。Gitea 工单是实施期间的事实来源,本地 docs/task 是任务完成后的最终归档。
工单和归档直接使用 docs/templates/task.md 里的模板,不要每次自拟结构。
0. 小改动直通
不改变程序行为的改动可以直接提交,不必建工单、不必归档,只需在提交信息里写清改了什么:
- 错别字、注释、文档措辞;
- 代码格式、导入排序、变量改名(不跨文件、不改公开接口);
- 补充类型标注、补充文档字符串;
- 删除确认无人使用的死代码。
只要满足下面任意一条,就不属于小改动,必须走完整流程:
- 改了数据库结构、Admin 接口、任务状态或
pdd_data结构; - 改了采购、下单、幂等、崩溃恢复或线程相关代码;
- 改了界面上用户能看出来的东西;
- 你不确定它算不算小改动。
Gitea 使用约定(首次使用前需由项目负责人补全):
- Gitea 地址:
<待填写> - 仓库:
<待填写> - 工单标签:
<待填写> - 里程碑命名:
<待填写>
在补全之前,按 §3.6 处理:输出完整工单草稿并说明阻塞,不要跳过建单直接实施。
1. 工单层级与职责
史诗级大工单(Epic)
├── MVP 工单
│ ├── 阶段 1:单元任务工单
│ ├── 阶段 2:单元任务工单
│ └── MVP 集成验收
└── MVP 之后:后续版本的单元任务工单
- **大工单:**记录完整产品目标、总体范围与非目标、总体架构、阶段路线、全局风险、所有已知任务索引和最终完成标准。
- **MVP 工单:**记录首个可交付版本的范围与非范围、阶段计划、单元任务清单、集成风险和 MVP 验收标准。MVP 是大工单的可交付子集,不等同于普通开发阶段。
- **单元任务工单:**唯一的实际执行单位,记录具体问题、方案、修改范围、依赖、验收标准、实施记录和测试结果。
- **阶段:**默认使用大工单或 MVP 工单中的章节、清单或 Gitea 里程碑表达,不增加正式工单层级。只有阶段需要独立负责人、独立验收或复杂协调时才单独建工单。
- 原则上不再增加比单元任务更深的工单层级;复杂任务应拆成多个可独立验证的同级任务。
2. 需求讨论与总体方案确认
- 用户提出需求、现象或缺陷,助手先复述目标并检查相关代码、日志和运行环境。
- 助手按照软件开发规范分析并提出总体方案,明确:
- 已确认事实与仍待验证的假设;
- 根因或需求边界;
- 目标、非目标、建议方案和影响范围;
- MVP 边界以及 MVP 之后的内容;
- 阶段拆分、已知单元任务和依赖顺序;
- 风险、兼容性、回退方式和总体验证方法。
- 用户审核总体方案,双方继续讨论和修订,直到用户明确确认最终方案。
- 最终方案确认前默认只允许阅读、诊断、实验性验证和方案整理;不得提前实施正式代码、创建工单、提交 Git 或扩大范围,除非用户明确要求某项操作。
这条和"类和函数骨架"的边界: 用户自己写骨架不受本条限制,那是用户在表达需求。本条约束的是助手——方案确认前,助手不写实现代码、不提交 Git。用户已经写好骨架并要求补全时,视为该部分方案已确认,助手可以直接补全,但仍不得越出骨架范围新增功能。
3. 创建大工单、MVP 工单与单元任务
- 用户确认总体方案后,先创建大工单,并写入完整目标、总体方案、阶段路线和所有已知任务索引。
- 再创建 MVP 工单,在其中定义首个可交付范围、排除项、阶段、验收标准和 MVP 单元任务清单,同时与大工单双向关联。
- 准备实施某个阶段前,先为其中已具备明确边界的工作创建单元任务工单,再把工单编号更新到 MVP 和大工单的任务清单。
- 不必为尚不明确的远期工作提前创建空泛的单元工单;先在大工单中保留规划项,待范围清晰后再建单。
- 每个 Gitea 工单必须使用自己的工单号作为唯一追踪编号,后续分支、提交、进度记录和本地归档都引用对应编号。
- 如果 Gitea 暂时不可用,应先输出完整工单草稿并说明阻塞;未经用户同意,不得绕过建单直接进入正式实施。
4. 各层工单内容规范
大工单和 MVP 工单至少包含:
- 背景、目标、非目标和范围边界;
- 已确认总体方案和关键架构决策;
- 阶段或里程碑;
- 子工单清单及当前状态;
- 依赖、全局风险和回退策略;
- 集成及最终验收标准。
单元任务工单直接套用 模板 A,必填项只有 6 条:
- 基本信息(类型、父级大工单、所属 MVP/版本、阶段);
- 要解决什么(缺陷附复现步骤);
- 做什么 / 不做什么;
- 已确认的实现方案(含预计修改文件);
- 可逐项打勾的验收标准;
- 验证方式(可复制的命令;需要真机时写明)。
"风险和回退"为选填,但改动涉及采购下单、数据库迁移或 Admin 接口时必填。
5. 单元任务拆分标准
单元任务不按固定数量机械拆分。每个任务应满足:
- 目标单一、边界清晰且可以独立理解;
- 具有明确输入、输出和可逐项检查的验收标准;
- 能够独立开发、测试、提交和回退;
- 修改文件和依赖范围可控,不混入顺手重构或无关修复;
- 一个提交或一组紧密相关的提交可以完成;
- 如果仍包含多个互不依赖的交付结果,应继续拆分为同级任务。
6. 新增工单与父工单同步
- 出现新需求、缺陷、遗漏工作或技术债时,先判断它属于当前 MVP、MVP 后续版本,还是改变大工单总体范围。
- 先创建新的单元任务工单,并填写父级大工单、所属 MVP/版本、阶段和依赖关系。
- 属于当前 MVP 时,同时更新 MVP 工单和大工单的任务清单;不属于当前 MVP 时,只更新大工单和对应的后续版本/里程碑,不得擅自扩大 MVP。
- 新工单会改变已确认范围、交付结果、验收标准或时间安排时,必须先更新父工单并交由用户重新审核,确认后才能实施。
- 详细分析和实施记录只保存在单元工单;MVP 工单只维护交付进度和集成状态;大工单只维护总体路线和范围,避免三处复制同一正文。
7. Git 准备与任务实施
- 只有单元任务工单已建立、方案和验收标准明确后,才能进入正式实施。
- 开始前检查工作区和当前分支,保留用户已有及与任务无关的改动。
- 严格按照单元工单范围实施;不得把其他工单、顺手重构或无关修复混入当前任务。
- 只有存在与工单相关的实际文件变更时才提交 Git,不得为了流程创建空提交。
- 提交信息应简洁描述变更并引用单元工单号,例如
fix: 修复规格匹配 (#123)。 - 实现过程中执行与风险相称的检查和测试,把关键进度、测试结果和提交哈希记录到单元工单。
8. 实施中的变更管理
- 范围、技术方案、接口、数据结构、依赖、验收标准、测试计划、风险或交付时间发生变化时,必须先更新单元工单。
- 变化影响 MVP 工单或大工单时,还必须同步更新对应父工单的范围、风险、计划或任务索引。
- 会改变用户已确认方案或交付结果的实质性变化,必须先写入工单并再次交由用户审核,确认后才能继续实施。
- 不改变外部行为的普通实现细节可以继续推进,但应在单元工单的实施记录中说明重要取舍。
- 阻塞、失败方案、新发现的根因或无法完成的验收项必须及时更新工单,不得只保留在聊天记录或代码注释中。
- 工单状态必须与实际进度一致:待确认、待实施、进行中、阻塞、待验收、已完成。
9. 单元任务完成与本地归档
-
完成实现后,先按单元工单的验收标准执行验证,记录实际结果和未验证内容。
-
将实现代码按可理解、可验证的粒度提交,所有提交都引用单元工单号。
-
更新单元工单,写明最终实现、与原方案的差异、测试结果、实现提交和遗留问题。
-
将完整单元任务归档为
docs/task/<工单号>-<简短名称>.md,目录不存在时创建。 -
本地任务文档直接套用 模板 B,必填项只有 6 条:
- 头部信息(工单号、标题、类型、父级、版本、状态、日期、Gitea 链接);
- 背景与目标;
- 最终方案(与建单方案有出入时写清差异和原因);
- 改了哪些文件;
- 验收结果(逐项);
- 测试:执行的命令、结果、未验证到的部分。
第 6 条的"未验证到的部分"不允许留空,没有就写"无"。"遗留问题"为选填。
-
单独提交本地归档文档,例如
docs: 归档任务 #123,并把归档提交哈希和文档路径回写到单元工单。 -
用户验收通过或明确同意后关闭单元工单,并立即更新 MVP 工单和大工单的任务清单及汇总状态。
10. MVP 工单与大工单的完成顺序
- 单元任务逐个完成、归档、验收和关闭。
- MVP 范围内所有任务完成后执行集成、回归和 MVP 验收,记录跨任务测试结果。
- MVP 验收通过后,在
docs/task创建对应的 MVP 总结文档,提交并回写 Gitea,然后关闭 MVP 工单。 - 大工单规划的所有版本和最终验收完成后,创建大工单总结文档,提交并回写 Gitea,最后关闭大工单。
- 不得因为单元任务已完成而提前关闭 MVP 工单,也不得因为 MVP 已完成而提前关闭仍有后续范围的大工单。
11. 记录与安全原则
- Gitea 单元工单保留详细讨论、决策、进度和变更历史;MVP 工单和大工单保留汇总;
docs/task保存与最终代码版本对应的结论。 - 聊天记录不能替代 Gitea 工单或本地任务文档。
- 父工单使用
- [ ] #工单号/- [x] #工单号等清单维护子工单索引,不复制子工单全文。 - 工单和归档中的命令、日志与截图必须去除密码、访问令牌、浏览器 Cookie、个人数据及其他敏感信息。
- 每个 Git 提交必须可理解、可验证、可追溯,且不得包含无关文件。
面向初级程序员的开发与文档规则
本项目默认由初级程序员阅读和维护。设计、代码、注释、文档和交付说明都应以容易理解、容易调试和容易继续修改为优先目标。
新人从这两份开始读,不要一上来啃基线文档:
- docs/client/00-getting-started.md —— 装环境、跑起来、常见报错
- docs/client/00-glossary.md —— 专业术语一句话解释
类和函数骨架
- 初级程序员可以先创建类或函数骨架,再由助手按照已确认工单补全实现。
- 骨架应尽量写明名称、职责、参数、返回值和可能的错误;暂未实现的部分使用清晰的
TODO,不得伪装成已经完成。 - 助手补全骨架前先理解原有命名和职责,能在现有边界内完成时不要随意重命名、移动文件或重做架构。
- 如果骨架存在明显职责混乱、线程错误或安全风险,先解释问题并提出最小调整方案;涉及已确认方案变化时按工单流程重新审核。
- 补全后删除已经完成的
TODO,保留仍未完成且有明确原因的事项。
代码可读性
- 优先使用直白、常见的 Python 写法,不为减少几行代码使用晦涩技巧、元编程或过深继承。
- 类和函数保持单一职责;函数过长或同时处理界面、网络、数据库和自动化时,应按职责拆分。
- 名称应表达业务含义,避免无意义缩写以及
data1、temp2、handle等模糊名称。 - 公共类、函数和复杂业务规则应提供简短中文文档字符串,说明“做什么、输入什么、返回什么、何时失败”。
- 注释重点解释“为什么这样做”和风险约束,不逐行翻译代码。
- 使用类型标注、枚举和小型数据对象表达边界;避免到处传递结构不明的字典。
- 错误应返回或抛出明确类型和信息,不使用裸
except,不静默忽略失败。 - 除非确实需要扩展点,不提前设计复杂抽象;出现第二个真实实现后再考虑提取通用层。
- 修改现有代码时保持风格一致,并尽量提供一个最小调用示例或对应测试。
文档编写
- 文档使用简洁、自然的中文,先说明用途和结论,再写必要步骤和规则。
- 一个文档只解决一个主要问题;使用短段落和短列表,避免堆叠大段理论说明。
- 专业术语统一收录在 docs/client/00-glossary.md。新词要么在术语表里加一条,要么在正文用一句话解释,两者至少做一个;不能翻译的类名、字段名、命令和协议名保持原样。
- 命令和示例必须可以直接复制,并说明从哪个目录执行、预期看到什么结果。
- 数据结构、状态对应关系和接口字段优先使用小型表格或短示例;关系简单时不要绘制复杂架构图。
- 文档只记录稳定需求、使用方法和关键约束,不复制容易与代码失去同步的内部实现细节。
- 进度、临时方案和待办写入 Gitea 工单;完成记录写入
docs/task,不反复修改长期基线文档。 - 修改已有长文档时应顺便删除重复和过时内容,但不得为了缩短文档丢失安全、数据和验收约束。
- 文档末尾只列真正未解决、需要用户决定的问题,不添加泛化的“未来可优化”清单。
助手交付说明
- 面向初级程序员说明改了什么、为什么、从哪里开始读以及怎样运行验证。
- 优先给出最短可行操作,不一次列出大量可选方案;存在重要取舍时再解释替代方案。
- 报错分析应指出具体位置、直接原因、修复方法和验证方式,不只给出修改后的完整代码。
- 不假设维护者熟悉 Qt 线程、SQLite 事务、Admin 幂等或 uiautomator2 控件树;涉及这些概念时给出一句话背景。
Client 子项目
- 处理
client/下的需求、代码、测试或文档前,必须读取并遵循 client/AGENTS.md。 - 从仓库根目录启动时也不能跳过该文件(本文件开头已重复提醒一次)。
- Client 的详细需求和技术基线位于 docs/client/;按当前任务只读取相关文档,清单见 文档索引。
- Client 专用技术栈、线程、自动化安全、界面和验证规则不在根文件重复维护。