13 KiB
七月迭代 AI 实施与验收操作手册
适用范围:
.scratch/<feature-slug>/PRD.md及其issues/的拆票、实现、评审和验收。
权威约束:AGENTS.md、父 PRD、Issue 和docs/7月迭代/独立方案/基础规范/DDD规范.md。
核心原则:按依赖 frontier 工作;小需求可整目录执行,高风险需求优先逐票执行;测试强度由 PRD 风险和已确认接缝决定。
一、完整流程总览
已评审 PRD
↓
/to-tickets:草拟纵向切片和阻塞边
↓ 用户确认拆分
发布 .scratch/<feature-slug>/issues/*.md
↓
记录实现基线 commit
↓
/implement:逐票或整目录实现
├─ 在已确认接缝上按 TDD 做 red → green
├─ 开发中持续运行局部测试和编译检查
├─ 本组工作结束时运行一次全量测试
├─ 对基线至 HEAD 的累计 diff 执行 /code-review
└─ 中文 commit
↓
独立验收:PRD、Issues、代码、测试证据和外部验收矩阵
↓
跨 PRD 联调与 INT-01~08 发布验收
二、每个需求开始前的固定检查
假设当前需求目录为:
.scratch/<feature-slug>/
├── PRD.md
└── issues/
开始前检查:
PRD.md状态为ready-for-agent。- PRD 已完成评审,没有尚未决定的业务问题。
- 工作区没有来源不明的未提交修改。
- 当前需求的跨 PRD 前置能力已经发布为具体 Issue;不能只写“依赖公共基础”。
- 记录拆票前或实现前的 commit,供后续双轴评审使用:
git status --short --branch
git rev-parse HEAD
将第二条命令输出记作 BASE_COMMIT。不要依赖 HEAD~N 猜测基线。
三、生成 Issues
3.1 通用命令
在一个新会话中执行:
/to-tickets .scratch/<feature-slug>/PRD.md
AGENTS.md 已要求规划会话自动读取 DDD 规范,因此无需每次重复粘贴 DDD 提示词。
3.2 拆票确认
/to-tickets 应先展示草稿,而不是直接写文件。确认每张票都具备:
- 一个可独立演示或验证的纵向行为;
- 明确的
Blocked by; - 可观察的验收标准;
- 适用的 DDD 架构通道;
- 当前票收口的完整业务边界;
- 明确不迁移的旧代码范围。
出现以下拆法时应要求重拆:
- “先建表 → 再写 Service → 再写 Handler”的水平分层;
- 一张票包含多个相互独立的业务流程;
- 阻塞项只写“公共基础设施”而没有具体 Issue;
- 为简单 Query 或单表写操作强行创建聚合、工厂或多层接口;
- 在拆票阶段改变已评审 PRD 的业务或架构决定。
确认草稿后回复:
拆分粒度和阻塞关系确认,可以发布 Issues。
3.3 拆票完成检查
发布后检查:
find .scratch/<feature-slug>/issues -maxdepth 1 -type f -name '*.md' -print | sort
逐票确认 Status: ready-for-agent、验收条件和阻塞边存在。父 PRD 不应被关闭或改写。
四、七月迭代建议拆票顺序
拆票顺序用于让后续 PRD 能引用已经存在的具体上游 Issue。它不代表所有票必须拆完后才能开始实现;没有阻塞的 frontier 可以先做。
第一批:独立小需求
UR#60 店铺联系电话精确查询
UR#45 换货资产标识与独立搜索
UR#86 资产详情换货链
UR#55 套餐生效条件与购买快照
UR#46 预计最终到期时间(依赖 UR#55)
第二批:公共基础
TECH 七月迭代公共开发基础
TECH 全局多视角审计与外部集成追踪
TECH 公共站内通知与受控跳转
第三批:共享业务核心
UR#94 卡状态公共写入、事件触发与运营商回调
UR#37 企业微信审批公共能力
UR#38 代理主钱包信用额度与统一钱包边界
第四批:依赖公共基础的中小需求
UR#40 下架套餐历史用户续费
UR#43 代理系列套餐批量授权
UR#47 卡片手动限速
UR#48 按资产类型限制 C 端支付方式
UR#49 设备 CSV 批量分配
UR#96 店铺业务员归属
UR#98 换货新资产继承店铺
第五批:卡状态、钱包与临期链
UR#73 按运营商实名能力控制复机
UR#53 卡和设备实名状态筛选
UR#62 H5 购买与实名顺序配置
UR#97 代理主钱包低余额预警
UR#33 套餐临期查询与提醒
主要依赖链:
UR#94 → UR#73、UR#53、UR#62
UR#38 + UR#96 + 公共通知 → UR#97
UR#55 → UR#46
UR#40 + UR#46 + UR#96 + 公共通知 → UR#33
第六批:复杂核心业务
UR#35 退款企微审批与整单终结
UR#57 活跃退款资产禁止换货
UR#34 代理扫码充值与平台线下代充值
UR#36 批量订购套餐
UR#44 提交人和审批摘要
UR#42 统一导出与字段权限
主要依赖链:
UR#37 + UR#38 + 审计 + 通知 → UR#35
UR#35 → UR#57
UR#37 + UR#38 + 审计 + 通知 → UR#34
UR#38 + UR#40 + 公共异步任务 → UR#36
UR#37 + UR#34 + UR#35 → UR#44
UR#33 + UR#46 + UR#44 + UR#37 → UR#42
最终以发布后的具体 Issue 阻塞边为准;上述关系只是跨 PRD 排序基线。
五、让 AI 实现 Issues
5.1 标准模式:一张票一个新会话
这是 /to-tickets 推荐的默认方式,适合复杂写、资金、状态机、外部系统、宽范围迁移和单票改动较大的需求:
/implement .scratch/<feature-slug>/issues/<NN>-<ticket-slug>.md
优点是上下文干净、范围稳定、失败容易定位。完成后选择下一个所有 blocker 均已完成的 ticket。
5.2 省事模式:整目录执行
对于票数少、改动集中、依赖链清晰的小需求,可以执行:
/implement .scratch/<feature-slug>/issues/
/implement 支持一组 tickets,但整目录模式不改变依赖规则。AI 必须先读取全部票,只执行 blocker 已完成的 frontier,并按依赖顺序推进。
可附加以下通用说明;它不包含任何特定需求内容:
完整实现该目录下所有当前可执行的 tickets。先读取父 PRD、全部 tickets、AGENTS.md 和 CONTEXT.md,建立依赖图,只处理 Blocked by 已完成的 frontier,不跳过、不合并、不改变已评审范围。
使用父 PRD 或 ticket 中已经确认的测试接缝;如果没有确认测试接缝,在写测试前先询问。开发中持续运行最相关的局部测试和编译检查,整组工作完成后运行一次全量测试,再对实现前固定基线到 HEAD 的累计 diff 执行 code-review,最后按项目规范提交。
如果上下文不足、外部 blocker 未完成、必须改变 PRD/架构或无法安全继续,请停在 ticket 边界,报告已完成项和下一张可执行 ticket,不要猜测或跨范围实现。
5.3 何时不要整目录执行
出现任一情况时,改用逐票模式:
- 涉及金额、余额、退款、充值或佣金;
- 涉及复杂状态机、并发不变量或可靠事件;
- 涉及企微、支付、Gateway、运营商等外部副作用;
- 涉及全局审计切换或 expand–migrate–contract;
- issues 较多,无法合理放进一个清晰上下文;
- 多张票会同时大范围修改同一模块;
- AI 已出现遗忘前置条件、重复实现或范围漂移。
若整目录会话因上下文或阻塞停止,不需要从头再跑。新会话指定剩余 ticket 或再次指定目录,并要求先识别已经完成的票。
六、正确的测试节奏
测试要求以 /tdd、父 PRD 的 Testing Decisions、ticket 验收条件和项目现有测试方式为准。
6.1 开始实现前
- 使用 PRD/ticket 已经确认的公共测试接缝。
- 如果没有确认接缝,AI 必须在写测试前询问一次。
- 测试面向公共行为,不测试私有函数或内部调用次数。
- 不为了满足 TDD 给简单字段映射制造无价值的内部单元测试。
6.2 实现过程中
按纵向切片执行:
一个失败测试 → 最小实现 → 测试通过 → 下一个行为
持续运行最相关的包测试或指定测试,例如:
go test ./internal/<package>/...
go test ./internal/<package>/... -run TestName
Go 的相关包测试同时承担本范围的编译检查。不要每修改一个文件就运行 go test ./...,也不要先写完全部测试再集中实现。
6.3 本组实现结束时
在提交前运行一次全量测试:
go test ./...
如果全量测试失败,必须区分:
- 本次修改引入的失败:修复后才能完成;
- 可复现的存量失败:记录命令、失败测试和与本次 diff 无关的证据,不得谎报全绿;
- 缺少数据库、Redis 或外部配置:标记为环境阻塞,并执行仍可运行的测试。
只有项目或 ticket 明确要求时才额外运行迁移、真实接口、生成文档或专项静态检查。不要凭空增加仓库没有约定的通用门禁。
七、Code Review 与提交
7.1 固定评审起点
使用实现前记录的 BASE_COMMIT:
/code-review <BASE_COMMIT>
如果自动识别不到规格来源,同时提供:
规格来源是 .scratch/<feature-slug>/PRD.md 和 .scratch/<feature-slug>/issues/。
/code-review 分开检查:
- Standards:是否符合
AGENTS.md、DDD 规范和代码标准; - Spec:是否完整实现父 PRD 和 tickets,是否遗漏或越界。
阻断性问题修复后,应重新运行受影响的局部测试;若修复可能影响全局,重新运行全量测试。修复后的 diff 需要再次复核相关发现。
7.2 提交粒度
/implement 的硬要求是完成工作后提交当前分支,并不强制每张 ticket 都单独提交。选择原则:
- 逐票模式:通常一票一个中文 commit,便于回溯;
- 整目录模式:可以按独立可回滚切片提交,也可以在整个小需求完成后统一提交;
- 不要为了形式制造无法单独构建或测试的中间 commit;
- 不要把其他需求或用户已有修改混入提交。
八、独立验证
实现会话结束后,推荐开启一个新会话做只读验证,避免实现上下文影响判断。
8.1 通用验证提示词
请独立验证 .scratch/<feature-slug>/PRD.md 及其 issues/ 的实现结果。固定评审起点是 <BASE_COMMIT>。
本轮先只审查和验证,不修改代码。完整读取 AGENTS.md、父 PRD、全部 tickets、相关 commits 和从基线到 HEAD 的累计 diff。
核对父 PRD、每张 ticket、DDD 架构通道、迁移边界和测试证据;运行最能证明验收条件的相关测试。确认实现会话已经在最终代码上成功运行过 go test ./...;如果没有可信证据、最终代码后来又变化,或本次验证发现可能影响全局的问题,再运行全量测试。
输出:通过项及证据、未通过项、范围外问题、环境或外部阻塞、仍需人工验收的项目,以及最终结论(通过/未通过/外部阻塞)。不要把代码存在当作行为验证,也不要把未执行的外部联调标记为通过。
8.2 验证失败后的处理
- 实现遗漏:回到对应 ticket,用
/implement <ticket-path>修复。 - 拆票遗漏:新增补救 ticket,确认后实现;不要静默扩大旧票。
- PRD 发生变化:先更新并重新评审 PRD,再调整 tickets。
- 纯环境阻塞:保留自动化证据,列入联调或发布前验收,不伪造完成。
九、完成状态判定
9.1 Ticket 完成
- 所有 blocker 已完成;
- 验收条件有行为或测试证据;
- 没有擅自改变架构或扩大迁移范围;
- 相关测试通过,或存量/环境失败已准确记录。
9.2 PRD 完成
- 该 PRD 的所有 tickets 完成;
- PRD 的 User Stories、Implementation Decisions 和 Testing Decisions 无遗漏;
- 累计 diff 通过 Standards + Spec 双轴 review;
- 最终代码已经完成约定的全量测试;
- 文档、迁移和人工验收项按 PRD 处理。
9.3 七月迭代完成
单个仓库代码完成不等于整轮迭代完成。所有 PRD 完成后,还需按标准评审稿执行:
INT-01 资产实名、复机与状态同步
INT-02 换货完整链路
INT-03 套餐授权、购买、续费、到期与临期
INT-04 CSV 批量任务与导出
INT-05 支付、代理钱包、信用和余额预警
INT-06 企业微信审批、退款和线下充值
INT-07 Gateway 卡限速
INT-08 七月迭代全链路与停机发布验收
最终结论必须区分:
- 本地自动化完成;
- 后端实现完成;
- 前后端联调完成;
- 外部测试环境验收完成;
- 存量数据回填和停机发布演练完成。
只有标准评审稿要求的全部门禁通过,才能标记“七月迭代完成”。
十、日常最简操作卡
生成 Issues
/to-tickets .scratch/<feature-slug>/PRD.md
确认草稿后:
拆分粒度和阻塞关系确认,可以发布 Issues。
实现单票
/implement .scratch/<feature-slug>/issues/<NN>-<ticket-slug>.md
实现整个小需求
/implement .scratch/<feature-slug>/issues/
双轴评审
/code-review <BASE_COMMIT>
独立验收
使用第八章的通用验证提示词,将 <feature-slug> 和 <BASE_COMMIT> 替换为实际值。