基于 onesystem 项目(matt-pocock 技能集 + Claude Code)的真实开发实践总结。每个阶段讲清四件事:练什么核心能力、用什么技能、产物规约有什么用、审查什么——正反案例全部来自本项目,可直接对照。
AI 原生开发的前提认知(来自 Anthropic SDLC Playbook):agent 写代码的速度已经超过传统流程的承载力,于是三件事随之成立——
本项目走通的主链路(也是本文的章节骨架):
本项目 48 条有效输入里有 16 条(33%)是「按你推荐的来」式批准。执行层放手是对的,但决策层橡皮图章会让判断力长不出来。按风险分三级:
| 级别 | 决策类型 | 规矩 | 本项目实例 |
|---|---|---|---|
| L1 放手 | 执行层:跑什么命令、先改哪个文件、怎么提交、测试怎么补 | 可以直接说「按推荐的来」 | 「git commit」「按你的推荐来」(拆分粒度) |
| L2 复述 | 方案层:模块形态、测试面怎么切、票据怎么拆、迁移方式 | 批准前先用一句话复述取舍和"什么情况下它会错",复述不出就继续问(可用 /wait-what /teach) | 票据 01 的 10 问决策(ReviewProgress 值对象、单步重构 vs 双轨) |
| L3 绝不橡皮图章 | 约束层:ADR(技术栈、状态机策略、数据模型镜像)、grilling 里不懂的选项 | 必须理解到能向别人解释,再批准;不懂就追问到懂 | 反面案例见下 |
grilling Q4:「"显式状态机,不引引擎"我没有很好地理解」→ 几分钟后「按推荐的来」。ADR-0002 就此定案。后果:后面四轮架构深化(状态机收口)全部围绕这个当初没读懂的决策展开,理解债连本带息偿还。
L3 决策写进 ADR 前,要求 agent 用「备选方案 + 否决理由」格式呈现(本项目票据 07 后来就是这样记的:删透传留残值,含两案否决理由)。你能复述备选方案为什么被否,才算真懂了选中的方案。
练的核心能力:知道自己不知道什么——在正确的阶段入口开始,而不是拿着锤子找钉子。
技能集自带的路由器。每个阶段边界(切片完成、深化轮结束、backlog 清空)问它一句"接下来该做什么",它会按技能地图给出带理由的下一步。它的回答值得保存——阶段边界判断本身就是 L2 级决策。
| 产物 | 作用 |
|---|---|
CLAUDE.md(仓库根) | 每个会话开局必读的项目级指令:issue tracker 在哪、领域文档怎么消费。它是"新入职者第一天需要的一切",版本化、可评审。规矩:agent 犯两次的错,修正就写进这里;保持一页以内。 |
docs/agents/*.md | 告诉技能"本仓库的 issue tracker 是什么、领域文档怎么读"——技能是通用的,这份适配层让通用技能长在本仓库的土壤里。 |
.scratch/<effort>/ 下的看板与票据(见阶段 5 的教训)。2026-10-01 切片完成后问 ask-matt"接下来做什么",得到标准答案:先 /clear 清上下文(状态都在仓库里)→ 空档跑 /improve-codebase-architecture → 下一切片从 /grill-with-docs 重新开始。阶段边界的判断完全交给"仓库状态 + 路由器",不依赖会话记忆。
练的核心能力:在写任何代码之前,把"业务在说什么"和"技术定什么调"变成人机都能读的共识文件。这一阶段花的时间是整个生命周期里杠杆最大的。
/research 调研老系统/代码库,产出报告 | /grill-with-docs grilling(拷问式决策访谈)→ 术语表 + ADR | /domain-modeling 在 grilling 中惰性补术语缺口 | /to-questionnaire 把悬而未决的业务问题变成给业务人员的问卷
| 产物 | 规约要点 | 审查什么 |
|---|---|---|
docs/research/*.md |
调研报告:老系统模块、数据表、流程、发现的疑点清单 | 疑点是否显式编号列出(本项目列了 12 项)——它们是问卷和后续 ADR 的输入 |
CONTEXT.md |
术语表:每个业务名词给定义 + _Avoid_ 反义词标注(老系统叫法/易混词) |
每个术语有没有 Avoid;新增概念时反问"这是项目已有的词,还是我在造词"——造词是信号,要么重审要么留给 domain-modeling |
docs/adr/*.md |
架构决策记录:0001 技术栈 / 0002 显式状态机 / 0003 SQLite 切片期 Postgres 生产 / 0004 镜像老数据模型 | 是否记录了备选方案与否决理由;是否与既有 ADR 冲突(冲突要显式标注,不许默默覆盖) |
to-questionnaire-*.md |
业务问卷:把"调研疑点 + 需要业务拍板的问题"翻译成业务人员能答的形式 | 每个悬而未决项是否都有归处:问卷、ADR 注明"切片期取值"、或明确留到下一切片 |
to-questionnaire 生成的 12 项业务疑点(工作流真实节点、码表全集等)至今未找业务确认,而架构深化已经基于"5 节点审批"等假设做了四轮收口。假设固化越深,业务答案回来时返工越贵。下一步切片(大概率销售合同)开工前必须先把问卷吃掉。
CONTEXT.md 的 _Avoid_ 标注是本阶段最有价值的习惯:如「分标 Avoid: 标段」「包 Avoid: 包件、Bag」。它保证后续所有产物(票据标题、代码命名、测试名)使用同一套词汇,人和 agent 对话不串词。写 spec、写票据时引用术语表,是 domain.md 里"使用词汇表词汇"规约的落地。
练的核心能力:把共识压缩成一份"人和 agent 都能读、都能执行"的 spec,再切成每张可独立验证的 tracer-bullet 票据。拆票质量决定后面所有实现会话的顺畅度。
to-spec 把决策变成用户故事 + 实现/测试决策(本项目:40 条故事)。to-tickets 把 spec 切成票据并 quiz 粒度与阻塞边(本项目:8 张线性阻塞链,第 8 张是端到端冒烟 + 种子数据)。
| 产物 | 规约要点 | 审查什么 |
|---|---|---|
.scratch/<effort>/spec.md |
一功能一目录;故事编号贯穿后续票据引用 | 每条故事可测试吗;票据覆盖了哪些故事要能对上号 |
.scratch/<effort>/issues/NN-slug.md |
一票一文件,从 01 编号;What to build 写用户视角的端到端行为;Blocked by 只写真正挡路的前置 |
① 票据是否切穿全层(schema+actions+UI+测试,tracer-bullet);② 验收项里不得写具体文件路径——它们很快腐烂;③ Blocked by 是真实依赖还是虚假的先后关系 |
票据 04 的 What to build:从"部门操作员可创建经济评审"的完整行为写到"覆盖 spec 故事 19–24",一句话能审、能测、能追溯。8 张票构成 01→08 线性阻塞链,每张只依赖真正挡它的前一张。
票据 01 验收项写着「Playwright 冒烟测试(e2e/smoke.spec.ts,端口 3200)」——该文件后来改名 happy-path.spec.ts,验收项里的路径腐烂了。这正是 to-tickets 模板"avoid specific file paths"规约的活样本。教训:写完票据自查一遍,把路径从验收项里清出去,路径只配留在 Comments 的实现记录里。
练的核心能力:把判断全部前置到阶段 1–2,实现阶段只负责盯着 agent 执行。每张票据一个会话、一条红线:先红后绿,测试和实现同 commit。
implement 驱动单票实现,内部要求提交前跑 code-review;tdd 强制先写失败测试再实现。执行层全面放手(L1),人在这一阶段的职责只剩两个:票据选对、偏离拦截。
| 产物 | 规约要点 | 审查什么 |
|---|---|---|
| 代码 + 测试 | 测试与实现同一 commit;票据内所有验收项可勾选 | 是否先红后绿(让 agent 展示红灯再绿灯);测试是否真的断言行为而非镜像实现 |
票据 ## Comments |
实现记录:模块落点、关键决策、评审处置、测试口径 | 票据 04 是黄金标准:6 条关键决策 + 评审与 refactor 处置 + 测试数字(18 例 + 5 例,全套 72 绿) |
| git commit | 一票一 commit(或实现 + 勾选两个 commit),信息引用票据号 | 「票据 04:经济评审…(实现见 bebd30a)」这种格式——任何一行变更都能反查到票 |
「技术评审 + 双完成自动建项」把"经济评审已确认 且 技术评审已评审"的自动建项逻辑和覆盖式维护、同事务约束一次切穿,Comments 记录了 dsh/yps 两态与 yqr+yps 同事务建项的决策。测试从 72 例一路涨到 133 例全绿。
练的核心能力:让评审结论成为仓库里的证据,而不是聊天记录里的口头承诺。评审不可审计 = 没评审。
implement 提交前内部跑逐票评审;阶段边界可以整切片再审一次——它的独有增量是逐票视角看不到的:spec 完整性端到端核对(跨故事缝隙)和跨票据渐进漂移(同类模式重复实现、命名惯例偏移)。
2026-10-01 问"不需要对整个切片跑一次 code-review?"时,agent 的回答暴露了一个事实:提交历史里无法证实每张票是否真跑了双轴评审——"这点你比我清楚"。流程的正确性依赖人的记忆而非仓库证据,这是本项目目前最大的审计缺口。
把"评审结论落 Comments"写进 DoD(上面的清单),写进 CLAUDE.md。票据 04 已有这个形态——把它从"做得好"变成"每票必须"。
双轴评审发现「initialProgress 曾被两轴同指为死导出」→ 已接入 saveEconomyReview 新建分支,语义闭环;Spec 轴指出验收项字面偏差 → 修订表述并记录理由;"准入两行式重复 6 处"→ 采纳评审者"不改可接受"的判断并写明理由(seam 的统一消费形状)。每条发现都有处置和理由,这就是可审计的样子。
练的核心能力:识别"什么时候该停下来体检",并把体检产出管理成一个有看板、有纪律的待办池,而不是一脑子浆糊。
/improve-codebase-architecture 体检切片(13 条发现 → 8 张候选卡是本项目实例)| /grill-with-docs 每张深化票动工前敲定形状决策 | /wayfinder 多票并行的地图协议(map / frontier / claim)| /codebase-design 模块形态设计
| 产物 | 规约要点 | 审查什么 |
|---|---|---|
| 架构评审报告 | 发现按 Strong / Worth exploring / Speculative 分级,标注与既有 ADR 是否冲突 | 每条发现有没有证据(文件、行为),分级是否诚实 |
深化票据 issues/NN-*.md |
诊断(问题是什么)与方案(怎么做)分离:发布时只冻结"问题 + 验收项",动工前的 grilling 才冻结"方案" | 决策记录是否完整:模块形态 + 红线 + 测试面 + 备选方案否决理由;第一个 checkbox"动工前完成 grilling"是否已勾 |
map.md / effort 看板 |
一张 backlog 表:票号 / 一句话 / Status / 阻塞;会话结束必须更新 | 是否存在(本项目长期缺失!);Status 词汇是否全仓库统一 |
/clear 而不是 /compact——状态都在仓库里,窗口内容没有保留价值;跨夜长会话要切分。/wayfinder 在 09-30 启用 1 分钟后被放弃,此后再没用过;.scratch/ 下没有任何 map.md。结果 10-02 出现真实崩溃:"03–06 的票据还没有实现?这又有 07/08 需要实现,我都不知道应该怎么办了。"加上 Status 词汇不统一(done / resolved / ready-for-agent 混用)、06/08 完成后 Status 没关门——三个小缺口叠加成一次流程信任危机。
① 每个 effort 目录放一个极简看板(README.md 或正式启用 wayfinder 的 map.md),会话结束时让 agent 更新;② 全仓库统一 Status 词汇;③ Status 关门并入票据 DoD(阶段 4 清单)。agent 当时现场补的那张 01–08 状态一览表就是正确形态——问题在于它只存在于聊天里,没落盘。
2026-10-02 票据 07/08 实施后,Comments 里只写了一行摘要,而 01/02 有完整的 ## 决策记录(三轮 12 问逐条可查)。被当场抓出后补记(commit febffcd)。教训:先例即标准——每轮 grilling 的产出形态要对齐本 effort 已落地的最佳先例,agent 图省事时人要拦住。
练的核心能力:让流程离开会话记忆也能自立。所有"agent 自报"的东西,都要有仓库里的确定性证据兜底。
| 项 | 规矩 | 本项目现状 |
|---|---|---|
.gitignore |
数据库、构建产物、系统文件全部忽略 | 缺口:只有 old-src/ 一行,local.db、e2e.db、test-results/、tsconfig.tsbuildinfo、.DS_Store 均未忽略,一次 git add . 就会把二进制数据库提交进去 |
| git remote | 至少一份异地备份 | 缺口:纯本地仓库,两周工作量只有一份拷贝 |
| 验证脚本 | 一条命令重跑全部验证(tsc + lint + 单测 + build),CLAUDE.md 写明健康输出示例 | 命令分散在多个脚本里;agent 每次都自报"全绿",但阶段边界没有"人亲自跑一遍"的记录 |
| 提交纪律 | 一逻辑一 commit,信息引用票据号,历史即审计链 | 优秀:双 commit 模式(实现 + 验收勾选),票据号贯穿 |
补全 .gitignore → 建 remote → package.json 加 verify 脚本 → 把"阶段边界亲自跑 verify"写进 CLAUDE.md。四件事半天内完成,直接把"评审是否真跑了、测试是否真绿了"的信任问题变成可复核事实。
| 反模式 | 出处 | 一句话改正 |
|---|---|---|
| 没读懂的 ADR 也批准 | grilling Q4 显式状态机 | L3 决策必须能复述备选方案的否决理由 |
| 33% 的输入是「按推荐的来」 | 全部会话统计 | 先分清 L1/L2/L3,L2 起必须复述取舍 |
| 路由技能(wayfinder)启用即弃 | 09-30 会话 | backlog 超过 3 张就必须有持久化看板 |
| 评审结论只留在聊天里 | code-review 覆盖质疑 | 评审记录是票据 DoD 的一环,落 Comments |
| 票据完成后 Status 不关门 | 票据 06/08 | Status 更新并入 DoD,词汇全仓库统一 |
| 验收项写文件路径 | 票据 01 的 smoke.spec.ts | 路径只进 Comments,验收项写可验证行为 |
| 摘要式决策记录 | 票据 07/08 被抓(febffcd) | 对齐本 effort 最佳先例:形态/红线/测试面/否决理由 |
| 业务问卷无限期悬置 | 12 项疑点未确认 | 下一切片开工前先吃掉问卷,冲突记新 ADR |
| 21 小时跨夜会话 + 困惑中 compact | 827a1ac1 / 1dad3ee8 | 每 effort 开新会话,边界 /clear |
| gitignore 一行 + 无 remote | 仓库现状 | 见阶段 6 行动项 |
| 你在哪 | 用哪个技能 | 产出落盘 | 人必须做什么 |
|---|---|---|---|
| 有想法,不知从何开始 | /ask-matt | — | L2:判断它的下一步建议是否合理 |
| 要懂老系统 / 业务 | /research → /grill-with-docs | 调研报告、CONTEXT.md、ADR、问卷 | L3:每个 ADR 读懂再批;疑点全列出来 |
| 要开工写功能 | /to-spec → /to-tickets | spec.md、票据链 | L2:quiz 粒度;审验收项无路径 |
| 逐票实现 | /implement + /tdd | 代码+测试、Comments 实现记录 | L1 放手;拦范围蔓延 |
| 票做完了 | /code-review | Comments 评审结论、Status 关门 | 核对 DoD 四件套齐活 |
| 切片做完了 | /clear → /improve-codebase-architecture | 评审报告、深化票、更新看板 | 趁热 grill 1–2 票;亲跑 verify |
| 票动工(深化) | /grill-with-docs | 票据决策记录(对齐先例) | L2/L3:形态、红线、测试面逐条过 |
| 任何时候 | — | CLAUDE.md 累积修正 | agent 犯两次的错 → 写进 CLAUDE.md |