delivery-slicing
把架构骨架切成 N 个可并行交付的砖头包(目录互斥、契约只读、自包含可交接),并按依赖分级划分批次。触发:"切成可并行的砖头"、"拆给多个对话窗并行做"、"交付切片"、"delivery slicing",或 design-craft 骨架交付后准备跨会话 / 跨 IDE 并行实现。
SKILL.mdskills/delivery-slicing/SKILL.md
GitHub交付切片(Delivery Slicing)
概述
目的:解决"需求拆完了、设计也做完了,但一个 Agent 串行做还是慢"的问题——把架构骨架切成 N 个互不干扰的交付单元(砖头),让它们能在不同对话窗 / 不同 IDE 里并行实现,最后统一拼接。
功能:
- 骨架完备性核验(阶段 0):骨架不全就不切(缺项退回
design-craft补,不硬切) - 骨架预演(阶段 0.5,★ 骨架本身的验证机制):零上下文开工预演 / 装配预演 + 数据走向预演 / 契约双向预演 / 覆盖反向预演 / 独立核验方——把骨架失效模式(漏 / 缺 / 不可实现 / 假绿 / 契约链断裂)的发现时机从拼接期提前到零成本窗口
- 落地映射:把"用户视角的子需求"映射到"代码视角的目录与文件"(识别两者不一致的情况并重切)
- 目录互斥校验:独占写集合两两无交集,交集即禁止同批
- 依赖分级:接口级 / 数据级 / 实现级三类,配 mock 可行性 5 条判据 → 定批次
- 自包含砖头包:6 件套(含窗口启动提示词),新窗口零追问可开工
使用场景:
- 骨架(接口桩 / 语义契约 / 挂载点 / 清单 / 数据模型 / mock)已交付,要分给多个窗口并行
- 用户明确要"分成几个对话窗 / IDE 同时做"
- 发现按需求拆的子需求在代码层互相踩(目录重叠 / 共享文件争抢)
定位
design-craft(架构设计 + 模块划分 + 骨架交付)
│ ← 划分与骨架都在这里产出
▼
delivery-slicing(本 skill:核验骨架 → 骨架预演 → 复核划分 → 打包砖头包 → 定批次)
│
▼
code-implement(跨会话 / 跨 IDE 并行实现,只填实现体)
│
▼
integration-merge(统一拼接:机械体检 + 验收凭证) ← 下游 skill,本 skill 不执行拼接
- 输入:模块划分(砖头清单 + 目录归属 + 依赖 DAG)+ 骨架(桩代码 / 语义契约 / 挂载点协议 / 全局清单 / 数据模型 / mock 套件 / 数据走向预演测试)
- 输出:骨架预演报告 +
sub-requirements/{SR-XX}-{名称}/砖头包 × N + 批次表 + 允许依赖矩阵 - 边界:
- 只管"核验骨架、复核划分、打成自包含包、分几批"
- 不做模块划分——划分是架构决策(
design-craft阶段 5.5.1 产出),本 skill 只复核(发现映射有误 → 退回重划,不自行改边界) - 不管"怎么设计"(
design-craft)、"怎么实现"(code-implement)、"怎么拼接"(integration-merge) - 不碰实现方案:切的是边界,不是做法
下游
integration-merge未安装时(精简安装场景):至少按下列七项完成最小合流体检,任一不过即打回、不静默合入 —— ① 越界检查(git diff --name-only {code_base}..HEAD⊂ 各包ownership.md独占写) ② 契约未改(contract/与接口目录 diff 为空) ③ 允许依赖矩阵校验(新砖头之间零边) ④ mock 按台账替换为真实实现 + 生产路径残留扫描 ⑤ 桩残留清零(生产路径无NotImplemented/ 桩占位,不依赖测试是否覆盖到) ⑥ 契约测试对真实实现重跑(不得沿用对 mock 的结果) ⑦ 挂载点测试由红转绿⚠️ 这只是最小体检,不含语义验收(契约 10 项对照 / 数据守恒质疑 / 负向场景 / 关键路径 e2e)。走这条简化路径时,必须在交付物中显式声明"未做语义验收"——完整拼接协议见
integration-merge。
核心原则
- 窗口必须独立工作副本(前置硬条件):每个窗口必须在自己的 git worktree / 独立克隆 / 独立目录中工作。多个窗口共享同一工作目录 = 本方案全线失效——文件会互相覆盖,
ownership与越界检查全部归零。不满足此条件则不得进入并行。 - 骨架不全就不切:共享面没清空就并行 = 冲突必然发生。缺项退回补骨架,比硬切便宜得多
- 目录互斥是硬约束:独占写集合两两无交集;有交集 = 禁止同批(合并或串行),不接受"小心一点"
- 自包含优先:新窗口只读本包即可开工;包外的上下文一律不允许依赖("引用不复制"只适用于同窗口,跨窗口必须复制或链接到快照)
- 契约只读:砖头包里的契约是快照,实现期一字不改;要改必须回
design-craft改骨架并在批次边界生效——代价是受影响砖头返工,因此冻结点越晚越准、越早越险 - 宁可少切:压不下去的耦合不拆;骨架成本也要算进账——并行收益吃不过"骨架 + 集成"成本时,合并或串行更划算
- 不脑补实现:只定边界与验收,不定内部做法(那是实现窗口的事)
- 骨架必须被验证,且不得自证:写骨架的(
design-craft/design-to-code)、核验的、切片的不能是同一条链上的同一个判断——阶段 0.5 的预演(尤其零上下文预演)须由独立核验方执行 - 划分不重做:本 skill 不做模块划分(那是
design-craft阶段 5.5.1 的架构决策),只复核;发现映射有误 → 退回重划,不就地改边界(否则骨架落点与边界脱节)
环境隔离(与工作副本并列的硬要求)
多窗口可能在同一台机器上跑测试,各自的"全绿"可能是假绿(互相污染)。切分时明确:
| 冲突源 | 要求 |
|---|---|
| 服务端口 | 每窗口分配独立端口段(或只在拼接期跑集成级测试) |
| 测试数据库 | 独立 schema / 独立库名(含砖头编号),禁止共用 |
| 缓存 / 队列 | 独立 key 前缀 / 独立 vhost,禁止共用 |
| 共享测试夹具 | 优先各片自建局部 fixture,不共用全局可变夹具 |
降级选项:无法做到隔离时,明确约定"同一时刻只允许一个窗口跑集成级测试",其余窗口只跑单元级。此法可行但会削弱并行度,须在交付确认中显式声明。
工作流总览
阶段 0 骨架完备性核验 → 存在性与机械项("有没有")——缺项退回 design-craft,不硬切
阶段 0.5 骨架预演 → ★ 可执行验证("对不对/够不够/可不可执行")
阶段 1 划分复核 → 确认上游"子需求 → 砖头"映射无误(不重划)
阶段 2 依赖分级 + mock 判定 → 接口级 / 数据级 / 实现级,配 5 条可行性判据
阶段 3 互斥校验 + 批次划分 → 两两查交集 + 依赖 DAG 拓扑分层
阶段 4 生成砖头包 → 6 件套,每件可独立交接
阶段 5 矩阵与交付确认 → 允许依赖矩阵 + 用户确认
阶段 0 与 0.5 分工:0 是"入场券"(存在性打勾),0.5 是"体检"(可执行验证)。两者都要,不可互相替代——只打勾会把骨架的失效模式(漏 / 缺 / 不可实现 / 假绿)全部留给并行期与拼接期去发现,而那时代价高得多。
未得到用户对当前阶段的确认前,不进入下一阶段。
快速通道
任一条件命中即不走本 skill,按 plan-track 串行实施:
| # | 条件 | 说明 |
|---|---|---|
| 1 | 可并行砖头 < 3 片 | 并行收益撑不起协调成本 |
| 2 | 骨架成本 + 公共前置 > 总工作量 50% | 见下方成本口径——骨架成本必须计入,不能只算业务前置 |
| 3 | 契约仍在探索(业务未定,骨架冻不下来) | 冻了也会改,改了就是返工 |
| 4 | 主干编译不通过(先修主干) | 常绿被破坏则所有砖头都无法验证 |
| 5 | 无法为每个窗口提供独立工作副本 | 见核心原则 1——共享目录则全线失效 |
成本口径(避免只算业务前置、漏算骨架):
并行总成本 ≈ 骨架成本 + 预演成本 + 集成成本 + 协调成本
骨架成本 ≈ 接口桩 + 语义契约(每接口 10 项)+ 挂载点预留 + 清单/模型定稿 + mock 套件
(经验上常达需求总工作量的 30%–50%,接口多、契约复杂时更高)
预演成本 ≈ 零上下文预演(可并行,低)+ 数据走向预演测试编写(中)
+ 契约双向预演 + 覆盖反向预演(低)+ 可能的往返补骨架(按轮数放大,上限 3 轮)
集成成本 ≈ 拼接体检 + 契约重跑 + 语义审查 + 冲突处理(随砖头数上升)
预演成本别漏算:它是本方案为了"把问题前移"付的保费。预演做得越足,集成期越便宜,但总成本确实上升——这也是快速通道判据要按保守判的原因。
估不准时的保守判定:骨架成本在开工前本就难估。拿不准就按中/高处理——即倾向走串行,而不是倾向并行。并行做错的代价(全链返工)远高于少并行的代价(慢一点)。
触发快速通道时输出判定理由,不进入阶段 1–5。
阶段 0:骨架完备性核验(入场券)
骨架不全就切,等于把共享面留给并行期,必然冲突。
但本阶段只回答"有没有"——它是存在性核验:清单项可机械判定、证据可查。"对不对 / 够不够 / 可不可执行"由阶段 0.5 回答,两者不可互相替代。
别把这一阶段当验证:第 5/6/7 项写的只是"声明只读",声明它只读 ≠ 它真的不被改(真正的检查在
integration-merge的拒收门②)。而"契约写得对不对""数据链能不能串"这类问题,打勾永远发现不了。
核验清单(逐项判定,缺项即退回)
☐ 1. 主干编译通过
☐ 2. 每个砖头的接口桩已合入主干(签名已锁定,抛 NotImplemented)
☐ 3. 语义契约 10 项已填,无"待定"(模板见 reference.md)
☐ 4. 挂载点协议已定,且挂载顺序已明确(大文件/接入点)
☐ 5. 全局清单已定稿并声明只读(依赖 / 配置 / 错误码 / 枚举)
☐ 6. 数据模型已定稿并声明"增不改"(schema / migration / 实体)
☐ 7. 公共代码已冻结(utils / common / shared,只增不改)
☐ 8. mock 套件就绪且支持异常路径(仅当存在实现级依赖时需要)
☐ 9. 数据走向预演测试已产出(覆盖数据链路场景,全 mock)——本阶段只查"有没有",能不能跑通由阶段 0.5 验
☐ 10. 模块划分已定稿(砖头清单 + 目录归属 + 依赖 DAG,来自 design-craft 阶段 5.5.1)
☐ 11. 横切约定 + 非功能预算已定稿(日志 / trace 传播 / 时区 / 精度 / ID / 分页 / 错误码分段;性能等预算已分配到砖头)
☐ 12. 权限模型已定稿(资源 × 操作 × 角色 + 鉴权层 + 越权错误语义)
第 11/12 项最易漏,也最贵:它们与第 5/6/7 项同类(共享面,定稿后只读),但漏掉的后果不表现为冲突,表现为"拼接期排障地狱"与"越权漏洞"——不冲突、编译能过、单测能绿。核验方式是查设计文档有无该章节(存在性),内容对错由阶段 0.5 与拼接期兜底。 第 11/12 项对应
design-craft5.5.2 骨架交付清单的第 10/11 项;本清单第 10 项(模块划分)在那边是 5.5.1 的产出,两处编号不逐项对应,以内容为准。
输出格式
🚪 骨架完备性核验(入场券)
━━━━━━━━━━━━━━━━
| # | 检查项 | 结论 | 证据 |
|---|--------|------|------|
| 2 | 接口桩已合入 | ✅ | 冻结 commit: {hash};{文件:行号} |
| 3 | 语义契约 10 项 | ⚠️ 缺 2 项 | 「并发安全」「事务边界」未填 |
| ... | ... | ... | ... |
判定:✅ 通过,进入切片 / ❌ 退回 design-craft 补骨架
【退回时列出缺项与补齐建议】
- 缺:{N} 项 → 补齐后重新核验,不进入阶段 1
硬约束:任一 P0 项(1/2/3/5/6/7/10/11/12)未通过,不得进入阶段 0.5。⚠️ 存疑项须显式标注为已知风险并写进砖头包。
冻结时机与修订代价(决定返工量)
冻结点是全流程唯一不可逆点,时机选错的两个方向:
| 时机 | 后果 |
|---|---|
| 过早(风险点未验证就冻) | 契约冻错 → 改了就是全部已开工砖头返工;越晚发现越贵 |
| 过晚(什么都做完才冻) | 没有并行收益,骨架白做 |
前置条件(冻结点之前必须已满足):
- 技术风险点已用
demo-verify(或等价手段)验证过——不确定的技术方案不该被冻进契约 - 业务侧不再探索(需求已确认,不会因业务调整改接口)
- 用户已完成"验收项覆盖"确认:确认清单上的验收项覆盖了他真正想要的东西(见下方效力边界)
修订代价必须先告知用户:在批次边界修订契约时,受影响砖头已完成的实现全部作废需重做(不是"改个签名")。因此:
- 修订前先评估影响面,把"要返工哪些砖头、多少工作量"报给用户再决定
- 修订后已完成批次必须重新对齐(见 reference.md 三·3.3),否则拼接时新旧契约混用
两级修订:划分修订 vs 契约修订(代价差一个量级)
修订有两种,不要混为一谈——它们的代价与路径完全不同:
| 级别 | 什么变了 | 代价 | 路径 |
|---|---|---|---|
| L1 契约修订 | 接口签名 / 语义契约 / 清单 / 模型细节 | 受影响砖头实现返工(其余不动) | 批次边界 → 改骨架 → 已完成后重新对齐(下方) |
| L2 划分修订 | 砖头边界本身(合并 / 拆分 / 归属变更 / 依赖 DAG 变化) | 骨架全废 → 回到 design-craft 5.5.1 重划 → 重出骨架 → 阶段 0 重核验 |
不限批次边界(成本高到不在乎边界),但必须报用户拍板 |
L2 的触发信号(出现任一条即说明当前划分不成立):
- 实现中发现两片必须共享同一段可变逻辑 / 状态机(互斥不成立)
- 某片永远 mock 不出来其他片(实现级依赖无法降级)
- 骨架预演连续 ≥3 轮仍不过,且根因是"这条链路不该跨这三片"
- 已完成的片中,两片产出的语义假设无法并存(拼接期会同型冲突)
L2 不等于失败:它是"划分需要修"的正常信号。但必须诚实报用户"要返工哪些已完成片、多少工作量"——不许悄悄合并两片了事(悄悄合并 = 其他窗口的边界约定同时失效)。
验收效力边界(诚实的软肋)
验收效力 = 「在已确认的验收项范围内达成」
需求侧(requirement-mining)
→ 5.5.1 承接映射(每条验收标准 → 哪个砖头)
→ 5.5.2 第 9 项可执行化
→ 验收测试骨架 → 实现 → 片级 / 拼接级 / 整体验收
每一层验的都是上一层给的东西。 若上游漏了一条需求点,或架构师理解偏了:
- 覆盖反向预演能抓「验收标准没有归属」✅
- 抓不到「需求验收标准本身不全」,也抓不到「理解错意图」❌
- → 全链(含验收测试)不会报警,最后交出一份全绿报告
唯一的锚点是用户。 因此:
| 要求 | 说明 |
|---|---|
| 冻结点确认必须包含"验收项覆盖" | 问的不是"技术方案行不行",而是"这些验收项覆盖了你真正想要的东西吗" |
| 认可收敛 | 把确认点从十几个压到 2 个(冻结点 + 拼接接收),代价是需求理解只在冻结点被验一次;这次确认的质量直接决定整链上限 |
| 报告措辞 | 验收报告不得写"需求已全部达成",应写"已确认的 N 条验收项全部达成" |
单批次场景:窗口发现契约不够用时怎么办
只有 1 批时,"批次边界"退化为"全部完成之后"——窗口在实现中发现契约缺口,没有可用的即时路径。不许让它干等或擅自绕过(绕过 = 漂移)。规定该场景的即时路径:
窗口发现契约不够用
│
├─ 1. 停下,不改契约、不就地绕过
├─ 2. 在 slice.md 写阻塞:缺什么 / 影响哪个验收项 / 哪些部分仍可继续
├─ 3. 继续做不受影响的部分(不空转)
└─ 4. 上报用户 → 用户三选一:
├─ A 等:等本批其他片完成后再在批次边界统一修订(返工面可控但推迟)
├─ B 改:立即修订契约 → **本批所有已开工窗口同步更新快照并重跑**(影响面最大,须逐窗确认)
└─ C 降级:该片改为串行补做(退出并行,其余片不受影响)
推荐 A:把修订攒到批次边界,返工面最小;仅在"该缺口卡住多个片"时才选 B。
阶段 0.5:骨架预演(★ 骨架本身的验证机制)
这一阶段验的是骨架,不是实现。 目的:在放行并行之前,用可执行手段证明"骨架自洽、够用、可执行"——把失效模式的发现时机从拼接期提前到零成本窗口。
为什么必须有这一阶段
骨架的失效模式与阶段 0 的覆盖情况:
| 失效模式 | 例子 | 阶段 0(打勾)能抓吗 | 本阶段 |
|---|---|---|---|
| 漏 — 共享面没识别出来 | 两片都要改同一张表,骨架没定稿数据模型 | ❌ | ④ 覆盖反向预演 |
| 缺 — 某片需要的能力没人提供 | 片 B 需要"汇率查询",骨架没这个桩 | ❌ | ① 零上下文预演 / ③ 契约双向预演 |
| 不可实现 — 签名语言层做不到 / 违架构约束 | 桩定为同步,实际必须异步 | ❌ | ③ 契约双向预演 |
| 粒度不对 — 挂载点留少了 | 只留 1 个位,实际有 3 种分发 | ❌ | ① 零上下文预演 |
| 假绿 — 桩返回看似合法的默认值 | 桩 return [] 而非 raise NotImplementedError |
❌ | ② 装配预演(红测试纪律) |
| 契约链断裂 — 某跳字段缺生产者 / 单位不一致 | A 返回"分",B 按"元"消费 | ❌ | ② 数据走向预演 |
| 错 — 契约与真实业务需求偏差 | 契约写"返回 List",业务实际要分页 | ❌ | ⚠️ 抓不到(见文末) |
① 零上下文开工预演(最硬的一条)
派一个新鲜上下文的独立执行方,只给砖头包 6 件套,让它回答四个问题(不实际实现):
1. 我要做什么?(复述目标与验收标准)
2. 我能改哪些文件?(复述 ownership 的独占写 / 只读 / 禁碰)
3. 我怎么验证我做完了?(复述 verify 路径与期望输出)
4. 哪里我不确定 / 缺什么信息?
5. ★ 你回答 1–3 时,用到了哪些"包外常识"?(逐条列出)
它提出的每一个疑问 = 一个包缺陷,而第 5 问是关键防线:核验方也是 LLM,会用先验知识脑补包外的信息,于是"它没提问"并不等于"包自包含"。所以:
- 提示词必须写明:不要用先验知识补全;凡需要包外信息才能回答的,一律报告
- 第 5 问逼它自曝用到的包外常识——每一条都是一个潜在缺陷(可能是"包该写清却没写清",也可能是"这条常识足够通用、可接受")
- 第 5 问在冷启动核验方(不带任何项目上下文)上效果最好
零追问才叫自包含——这是并行能否开工的唯一标准。可批量、可并行,成本极低。
| 疑问类型 | 处理 |
|---|---|
| 包内缺失(信息在骨架里有但没进包) | 补进包 |
| 骨架缺失(骨架里就没有) | 退回 design-craft 补骨架 |
| 表述有歧义(可推断但易错) | 改进包表述,并在砖头包标注 |
② 装配预演 + 数据走向预演(分层测试,期望值互补)
分层测试期望值(全流程判别标准,各相关文档必须一致;本阶段只看"骨架期"列):
| 测试组 | 用什么填 | 骨架期 | 窗口期(本砖头) | 拼接期 | 验什么 |
|---|---|---|---|---|---|
| 契约测试 · 本砖头组 | 桩(NotImplemented) |
红 | 绿 | 绿 | 桩是不是真桩(绿 = 假绿警报) |
| 契约测试 · 其他组 | 桩 | 红 | 不跑 | 绿 | — |
| 片级验收测试 | 桩 | 红 | 绿 | 绿 | 需求验收项是否达成(由 5.5.1 承接列派生) |
| 数据走向预演 | 全 mock | 绿 | 绿 | 绿(换真实实现) | 断言链是否完整可执行 |
| 挂载点测试 | 挂载位空实现 | 红 | 红(预期) | 绿 | 装配是否接通 |
契约测试按砖头分组(这是本阶段能成立的前提):分组口径 = 被测接口的实现方——
tests/contract/{SR-XX}/放该砖头所提供接口的契约测试。不分组则窗口的完成定义不可达(全局契约测试在窗口分支上永远红),窗口会被迫"改测试凑绿",反而制造漂移。
②A 红测试纪律(契约测试各组 + 片级验收测试 + 挂载点测试):
☐ 能跑(非语法错 / 导入错)——不能跑说明骨架本身坏了
☐ 全部红 ——「红是健康,绿是警报」:绿说明桩返回了看似合法的默认值(None / []),
拼接期也不会暴露 → 假绿
☐ 红的原因【必须是 NotImplemented】——原因不对说明是打错字 / 参数错,不是"还没实现"
☐ 契约测试【已按砖头分组】(tests/contract/{SR-XX}/)——未分组则窗口完成定义不可达
②B 数据走向预演(本阶段最重要的探针):
按业务数据流逐跳断言,用 mock 填满全链路(⚠️ 不能用 NotImplemented 桩——否则跑到第二跳就抛异常,后面的贯通断言根本执行不到):
def test_export_data_flow_shape():
"""数据走向预演(全 mock;骨架期期望【绿】,红了说明契约链有缺口)"""
req = ExportRequest(format=ExportFormat.CSV, order_ids=[1, 2, 3])
orders = mock_order.query(req.order_ids) # 用契约声明的 DTO 填
assert_shape(orders, OrderDTO) # 形状:字段齐全、类型对
rows = mock_exporter.build_rows(orders) # 也是 mock
assert_shape(rows, RowDTO)
path = mock_exporter.write(rows, ExportFormat.CSV)
assert path.endswith(".csv")
assert_fields_covered(OrderDTO, RowDTO) # ★ 抓「字段断链」
assert_units_aligned(OrderDTO.amount, RowDTO.amount) # ★ 抓单位 / 精度不一致
assert_time_semantics(OrderDTO.created_at, RowDTO.created_at) # ★ 抓时区 / 时间戳单位
产出不是"通过 / 不通过",而是「契约缺口清单」:写不出断言、写出来发现缺字段、单位/时区对不上 → 全是契约缺口 → 此时改零成本(还没开工)。
它能证明什么、不能证明什么(别夸大):
| 骨架期"全绿"能证明 | 不能证明 |
|---|---|
| 断言链完整可执行——每条断言都能被求值,说明契约的字段 / 类型 / 单位 / 时区声明完备到可断言 | ❌ 不证明"真实实现会通过"——mock 是照着契约造的,它满足断言是必然的 |
所以骨架期的绿,价值在于逼出"声明不完备"(缺字段、单位没写、断言根本写不出来),而不是给你"拼接期不会红"的保证。拼接期仍必须对真实实现重跑(
integration-merge阶段 3 第 2 项),这一点不能省。
为什么它仍比拼接期做同样的事便宜得多:
| 发现时机 | 发现的是什么 | 代价 |
|---|---|---|
| 骨架期(本阶段) | 契约声明不完备 | 改契约,零返工 |
拼接期(integration-merge 阶段 4B) |
契约实现不一致 | 受影响砖头返工,可能还要回设计改契约 |
③C 断言可写性检验:对每个接口问"能否写出断言?"——写不出断言的契约还不够具体,退回补语义契约。
③ 契约双向预演(纸面推演,可复用 scenario-rehearsal)
对每个跨砖头契约,逐项对语义契约 10 项问两句话:
- 调用方拿到这个返回值,能完成它的场景吗?(抓"不够用")
- 实现方有能力满足这个前置条件吗?(抓"不可实现")
④ 覆盖反向预演(复核,非首次检查)
从需求侧验收标准反向走:每个验收项落到哪个砖头 / 哪个契约?
| 结果 | 含义 | 处理 |
|---|---|---|
| 找不到归属 | 漏了砖头 | 退回补划分(并回查 5.5.1 为何没做到) |
| 两个砖头都声称负责 | 重叠(并行时必然冲突) | 退回重划边界 |
定位说明:这项检查的首次执行在
design-craft阶段 5.5.1(划分完成时,零成本)——它不需要骨架,放到本阶段做,一旦发现问题就是"骨架全废"的代价。 本阶段保留它是为了兜底(5.5.1 可能被跳过、或验收标准此后有调整),但若在此首次发现孤儿/重叠,说明上游那一步没做到位——除修复外还须回查原因,不能只当技术问题处理。
⑤ 独立核验方(不得自证)
写骨架的(design-craft / design-to-code)、核验的、切片的不能是同一条链上的同一个判断:
| 档 | 做法 |
|---|---|
| 子 agent 独立核验(推荐) | 给它骨架 + 砖头包,只执行 ①②④,不参与设计 |
challenger 对骨架做对抗式质疑 |
质疑"契约是否够用 / 共享面是否清空 / 是否可独立实现" |
| 用户抽查 | 重点看 ① 产出的疑问清单 |
输出格式
🎬 骨架预演
━━━━━━━━━━━━━━━━
【① 零上下文预演】独立核验方:{子 agent / challenger / 用户}
疑问 N 条 → 包内缺失 X / 骨架缺失 Y / 表述歧义 Z
{逐条列出与处理}
【② 装配预演 + 数据走向预演】
契约测试:全红 ✅(红因均为 NotImplemented)| 意外绿:0
挂载点测试:全红 ✅(N 个挂载位)
数据走向预演:全绿 ✅ / ❌ 红了 M 条 → 契约缺口清单:
- {场景} 第 {跳} 缺字段 {字段名}(生产者:无 / 消费者:SR-XX)
- {场景} 单位不一致:OrderDTO.amount 分 vs RowDTO.amount 元
断言可写性:N 个接口全部可断言 / ⚠️ M 个写不出(契约不够具体)
【③ 契约双向预演】疑问 K 条 → 已并入砖头包"已知风险"
【④ 覆盖反向预演】验收项 N 个 → 全部有归属 ✅ / 孤儿 M 个 / 重叠 K 处
【判定】
✅ 通过,进入阶段 1 / ❌ 退回(列出阻断项与补齐建议)
硬约束(任一触发即不得进入阶段 1)
| # | 触发条件 | 退回目标 |
|---|---|---|
| 1 | ②B 数据走向预演有红(契约链串不起来) | design-craft 补契约 |
| 2 | ②A 出现意外绿(桩不是真桩) | design-to-code 改桩为 NotImplemented |
| 3 | ④ 覆盖预演有孤儿或重叠 | 退回重做模块划分(阶段 5.5.1) |
| 4 | ① 零上下文预演发现骨架缺失 | design-craft 补骨架 |
| 5 | ③C 有接口写不出断言 | design-craft 补语义契约 |
不阻断(改进项):① 的包内缺失与表述歧义 → 就地补包;③ 的疑问 → 进砖头包"已知风险"。
循环上限:预演 → 退回补 → 再预演,最多 3 轮。3 轮仍不过 → 停止自动往返,把未通过项呈报用户裁定(选项:继续补 / 降级为串行 / 改需求口径)。无上限的往返会把骨架成本推高到并行彻底不划算。
本阶段的边界(诚实)
抓不到:契约与真实业务需求的偏差("业务真正要的是分页")。预演用的还是同一份骨架,没人知道业务意图。解药只有冻结点之前那一件事:demo-verify 验技术风险 + 需求侧澄清(见阶段 0 的「冻结时机与修订代价」)。骨架预演替代不了它,只验"骨架自洽 / 够用 / 可执行"。
阶段 1:划分复核
本阶段不重做划分——模块划分是架构决策,已在 design-craft 阶段 5.5.1 产出。本阶段复核它的三项正确性,发现偏差退回重划(不就地改边界)。
复核的能力边界(别把它当保证):复核是推断 + 抽样,不是穷举——它降低"归属遗漏"的概率,不能保证发现全部遗漏。真正的兜底在
integration-merge的拒收门①(越界检查):那才是"漏掉的文件"必然暴露的地方。所以本阶段的定位是"尽量早发现",不是"保证无遗漏"。
复核三项
| # | 复核项 | 查什么 | 偏差处理 |
|---|---|---|---|
| 1 | 映射无误 | 每个子需求都有砖头承接(非 1:1 处——合并 / 拆分 / 上提骨架——是否有据且说明了理由) | 退回重划 |
| 2 | 归属完整 | 独占写清单是否覆盖"改这个功能真正要动的文件"(漏一个文件,拼接期才暴露) | 退回重划 |
| 3 | 粒度合理 | 是否有砖头过大(单片仍难在一次会话内完成)或过小(碎片化) | 退回重划 |
归属完整性的取证手段(按优先级):
- 设计文档的文件路径(
design-craft阶段 4 要求每个涉及文件写明路径) code-survey调研结果的模块 / 文件清单- 现场 grep:从接口名 / 表名 / 枚举 / 事件名反查调用点与实现位置
- 都没有 → 先补调研再复核
不要低估第 2 项:映射关系的正确性直接决定切片是否成立。上游划分失准时,本阶段唯一的正确动作是退回,而不是"顺手改一下边界"——改了边界,骨架的落点就与边界脱节(桩会落在别人的独占区里)。
砖头内部分类(复核时确认)
| 类型 | 特征 | 说明 |
|---|---|---|
| 新增型 | 新增目录 / 新增文件 | 最安全,优先设计成这一型 |
| 挂载型 | 新增独立文件 + 在原文件填一个挂载位 | 挂载位由骨架预留,本型只填 |
| 修改型 | 必须改现有文件的某段逻辑 | 最危险,独占写须细到函数/行区间 |
独占写粒度要求(复核时确认)
| 写法 | 允许 | 说明 |
|---|---|---|
src/order/export/** |
✅ | 新增整目录,最干净 |
src/order/service.py :: exportOrders() |
✅ | 修改现有文件必须细到函数——越界检查才能精确定位;同时声明"该文件其余部分对我只读",防顺手重构 |
src/order/service.py |
❌ | 整文件独占:既无法定位越界,也把文件内无关函数一并锁死 |
src/order/service.py :: exportOrders(), validate() |
✅ | 一片独占同文件多个函数可以——但必须归同一片,不得拆给两片 |
铁律:同一文件被两个及以上砖头碰 → 一律不同批(不论碰的是不是同一个函数)。
函数级声明的真实作用是「精确越界检测 + 防顺手重构」,不是"让同一文件能并行"。两个砖头改同一文件的不同函数,git 或许不冲突,但两侧对同一模块的心智模型会分叉,后续必然互相绊。 唯一例外:文件足够大(数千行量级)且两处区域足够远、无共享状态 → 可同批,但须在
ownership.md注明理由并经用户确认。
输出格式
🔎 划分复核
━━━━━━━━━━━━━━━━
上游划分来源:design-craft 阶段 5.5.1(砖头 N 个)
| # | 复核项 | 结论 | 证据 |
|---|--------|------|------|
| 1 | 映射无误 | ✅ | 每个子需求都有承接;2 处非 1:1 均已说明理由 |
| 2 | 归属完整 | ⚠️ | SR-02 独占写漏了 src/order/export_registry.py(grep 命中该文件被 exportOrders 调用) |
| 3 | 粒度合理 | ✅ | 最大砖头预估 {X} 行 / {Y} 个子功能,可在一次会话内完成 |
判定:✅ 通过 / ❌ 退回 design-craft 阶段 5.5.1 重划
【❌ 退回项】(不就地改边界——改了边界骨架落点会与边界脱节)
- SR-02:独占写补 `src/order/export_registry.py`,需回 design-craft 同步骨架(该文件是否属修改型挂载点)
请确认复核结论。
阶段 2:依赖分级 + mock 可行性判定
三类依赖(决定是否形成批次)
| 依赖性质 | 判定特征 | 该在哪解决 | 分批吗 |
|---|---|---|---|
| 接口级 | 需要对方提供的能力,不需要它的真实产出 | 骨架(桩) | ❌ 不该 |
| 数据级 | 需要同一张表 / 枚举 / 状态机 | 冻结点定稿 | ❌ 不该 |
| 实现级 | 需要对方跑出来的真实数据或结果 | mock 降级 或分批 | ⚠️ 视可行性 |
判定提问(逐条问,先命中先判):
① 我能对着对方的接口桩写完自己的代码吗?
→ 能 → 接口级(不该分批)
② 我需要的只是表结构 / 枚举 / 状态定义吗?
→ 是 → 数据级(不该分批)
③ 我的代码 / 测试需要对方产生的真实数据或运行结果吗?
→ 是 → 实现级 → 进入 mock 可行性判定
mock 可行性 5 条判据(实现级依赖用)
| # | 判据 | 不合格时 |
|---|---|---|
| 1 | 对方接口现在能确定吗 | 不能 → 契约不稳,mock 无意义 → 必须分批 |
| 2 | 对方有技术未知点吗 | 有 → 先 demo-verify 验掉,再来判定 |
| 3 | 对方是新增代码还是改造现有逻辑 | 改造 → 风险高一档,倾向分批 |
| 4 | 对方依赖的第三方 / 环境 / 数据现在可用吗 | 不可用 → 对方本身有阻塞,mock 是在掩盖它 |
| 5 | 对方的契约会变吗(业务仍在探索) | 会变 → mock 作废风险高 → 分批 |
5 条全过 → 可用 mock 降级为接口级 → 不进批次(与对方同批并行) 任一条不过 → 真实现级依赖 → 必须分批
mock 由骨架提供,禁止各片自造——自造 mock = 验证自己想象中的对方。
红线:不许"互 mock"
砖头 A →(mock)→ 砖头 B
砖头 B →(mock)→ 砖头 A
双方都未实现且互相用对方的 mock = 双重赌博,风险平方。
处理:至少有一方是真的 —— ① 合并成一个砖头;或 ② 先定死一方(作为前置批做掉),另一方对真实实现开发。
输出格式
🔗 依赖分级
━━━━━━━━━━━━━━━━
| 依赖对 | 性质 | 判定依据 | mock 可行性 | 结论 |
|--------|------|---------|------------|------|
| SR-01 → SR-02 | 接口级 | 对着桩能写完 | — | 同批并行 |
| SR-03 → SR-01 | 实现级 | 需要 SR-01 产出的数据集 | 判据 3 不过(SR-01 是改造现有逻辑) | 分批 |
| SR-04 → SR-05 | 实现级 | 需要真实汇率 | 5 条全过 | mock 降级,同批并行 |
【互 mock 检查】无 / ⚠️ 发现 A↔B 互 mock,处理:{合并 / 前置一方}
阶段 3:互斥校验 + 批次划分
3.1 互斥校验(两两查交集)
对每对砖头的独占写集合做交集判定:
| 判定 | 条件 | 处理 |
|---|---|---|
| ✅ 无交集 | 独占写集合两两不相交 | 可同批 |
| ⚠️ 同文件不同区域 | 独占写落在同一文件的不同函数/行区间 | 默认不同批;仅当文件足够大、区域足够远时例外,并注明理由 |
| ❌ 有交集 | 独占写集合相交 | 合并砖头,或强制串行(禁止"分头改、后面合") |
同时校验共享面:任一砖头的独占写是否落在骨架已声明只读的区域(全局清单 / 数据模型 / 公共代码 / 契约)——命中即越界,必须退回阶段 1 重新归属。
3.2 批次划分
批次 = 依赖 DAG 的拓扑层
第 1 批 = 入度为 0 且互斥校验通过的砖头(同批并行)
第 2 批 = 仅依赖第 1 批的砖头
...
规则:
- 同批砖头互斥校验必须全过
- 有依赖的砖头必须排在其依赖方之后的批次
- 批次数告警:需要 ≥ 3 批时,先回头查骨架(是骨架缺口?还是真实现级依赖?),不要先排批次
- 同批建议 ≤ 5 片(超过则边界数爆炸,集成成本吃掉并行收益)
输出格式
🔀 批次划分
━━━━━━━━━━━━━━━━
【互斥校验】
SR-01 ↔ SR-02:✅ 无交集
SR-01 ↔ SR-03:⚠️ 同文件不同函数(order/service.py)→ 默认不同批
【批次】
第 1 批[并行]:SR-01、SR-02(互斥 ✅,均无前置)
第 2 批[依赖第 1 批]:SR-03(实现级依赖 SR-01)
【批次数告警】2 批 | 若 ≥3 批须先查骨架缺口
【检查点】(每批结束时必查)
① 上批契约测试全绿 ② 骨架是否需修订(仅此处可改契约) ③ 主干可编译可运行
请确认批次划分。
3.2b 批次基线(分批时的关键操作,漏了必出错)
问题:第 2 批的窗口从哪个 commit 拉基线?
❌ 从原冻结点 a1b2c3d 拉
→ 缺第 1 批的全部成果(装配接线、被合入的共享改动)→ 可能连编译都过不去
❌ 从主干最新拉且不核对
→ 包内契约快照可能与主干已不一致(第 1 批在边界修订过契约)→ "契约只读"约定失效,
各窗口以为在填同一个契约,实际填的是两个版本
规定(两个基线,不可合并):
【代码基线 code_base】拉工作副本、算改动 diff 的起点
= 骨架合入的 commit(冻结点)
第 N 批(N ≥ 2)= 第 N-1 批全部合入(含该批装配)且主干常绿后的 commit
★ 越界检查必须【排除 sub-requirements/ 与 .delivery/】——见下方"哪些不算越界"
【契约基线 contract_base】包内 contract/ 快照对应的冻结点
未发生契约修订 → 仍 = 原冻结点(不随批次变)
发生契约修订 → 按批次边界更新(见下方复核项 1)
⚠️ 分批场景下二者【不是同一个 commit】。合成一个字段会导致:
门①(越界,用 code_base)与 门⑤(契约基线,用 contract_base)必有一个误报——
填新 → 门⑤ 报"契约基线不一致";填旧 → 门① 把上一批的改动全算成本片越界
术语对照(全文统一):
contract_base常被称为"冻结 commit"(= 骨架冻结点)——凡见"冻结 commit",一律指契约基线,不是拉工作副本的起点。拉副本 / 算越界一律看code_base。
3.2c 哪些不算越界(不排除就每次误报)
越界检查的范围是窗口的代码产出,不是"窗口改动过的一切文件"。三类必须排除:
| 路径 / 情况 | 为什么必须排除 |
|---|---|
sub-requirements/** |
砖头包是流程产物;且窗口本就要更新自己包的 slice.md 状态标记与完成日期——不排除则每次都被判越界 |
.delivery/** |
脚手架(mock / 预检脚本产物),独立于交付物管理 |
| 出包与"记录基线"产生的提交 | 出包发生在骨架之后。若把这些算进 diff,则"code_base 取冻结点"的用法必然误报——且无解:一个提交无法在自己的内容里记录自己的 hash(hash 自指),所以不存在"既含包、又能被包准确记录"的基线 |
排除 ≠ 放任:
- 窗口改自己包的
contract/仍被门② 抓(契约快照只读,改动即拒收)- 改别人的包 靠"单一写者"约定约束(各窗口只写自己那一行 / 自己那份)
- 门① 的职责边界就是拦住代码路径的越界,不是包览一切文件变更
出包时的复核三项(缺一不得交付该批):
☐ 1. 契约快照与主干一致
第 1 批在批次边界修订过契约 → 本批包必须【重新同步快照 + 更新 contract/BASE】
未修订过 → 快照应仍与主干一致(核对 hash 即可)
☐ 2. 骨架声明的只读区未被改动
核对:全局清单 / 数据模型 / 公共代码 / 横切约定 / 权限模型(第 5/6/7/11/12 项)
被改过 → 要么违反只读约定、要么发生了未登记修订 → 回 design-craft 处理,**不在本批就地接受**
☐ 3. 主干编译通过(常绿未被破坏)
为什么必须显式规定:这条一旦漏写,实施者只能凭直觉二选一(从冻结点 or 从主干),两种直觉都会在一半场景下出错,且出错时表现为"编译不过"或"契约对不上",会误判成"骨架有问题"——实际是基线取值问题。
单批次场景不受此节影响:只有 1 批时,基线就是冻结点 commit。 装配的归属:分批拼接时,每批合入后要完成该批的装配(如挂载点接线),第 2 批的基线已包含它;但挂载点文件本身不属于任何砖头的独占写,第 2 批不得触碰。
3.3 进度可见性(N 个窗口同时开工时的看板)
用户在多个窗口之间切换,必须有一个不看对话、只看文件就能掌握全局的地方:
| 层级 | 位置 | 谁来写 |
|---|---|---|
| 权威状态 | 各砖头包 slice.md 顶部的状态标记 |
各窗口只写自己那一份(天然无并发冲突) |
| 汇总视图 | sub-requirements/INDEX.md 的状态列 |
各窗口「先读最新版再改、只改自己那一行」 |
并发写风险:多个窗口同时改 INDEX.md 会互相覆盖。因此规定:
INDEX.md只是人类可读的看板,不是权威来源;覆盖了不致命- 每个批次结束时(或拼接开始时)重扫
sub-requirements/*/slice.md,以各包实际状态为准重建INDEX.md——这是丢失更新的兜底
状态取值统一为:待开始 / 进行中 / 已完成 / 阻塞(+原因)。
阶段 4:生成砖头包
每个砖头产出一个自包含包,新窗口只读它即可开工:
sub-requirements/{SR-XX}-{名称}/
├── slice.md 目标 / 场景 / 可执行验收 / 上下游 / **划分理由** / 状态标记
├── ownership.md 独占写 | 只读 | 禁碰(含【机器可读块】,供下游预检脚本读取)
├── contract/ 冻结 commit + 契约快照(只读)
├── out-of-scope.md 不做什么 + 越界了怎么办
├── verify/ 验收脚本 + 桩数据 + 期望输出
└── handoff.md 窗口启动提示词(可直接粘贴到新对话窗)
slice.md 必须含「划分理由」一节(写进包,不留在对话里):
| 要写什么 | 为什么 |
|---|---|
| 这个砖头为什么这样切(为何独立成片 / 为何与某片合并) | 换会话 / 换人后可复现决策;否则后续无法判断"当初切得对不对" |
| 与哪些片存在不可并行的原因(互斥交集 / 实现级依赖 / 状态机共享) | 防止后人"好心"把两片合成一批跑 |
| 本片被排除在外的做法(曾考虑过但否掉的划分方式 + 否掉的理由) | 避免反复讨论同一个被否决的方案 |
划分理由不是元信息,是防退化机制:没有它,下一批 / 下一轮的人会重新怀疑划分、重新讨论,甚至不知不觉把互斥的两片放同一批。它是唯一能跨会话传递"为什么"的载体(状态传的是"是什么",理由传的是"为什么")。
包外层还有两份拼接期必需的文件(由本阶段建立,integration-merge 消费):
| 文件 | 作用 | 谁维护 |
|---|---|---|
sub-requirements/INDEX.md |
批次表 + 进度看板 + 骨架 commit 基准(记录冻结 commit,供拼接期比对"骨架是否被再修订")+ 时间戳列(见下) | 各窗口只改自己那行;批次边界重扫重建 |
sub-requirements/MOCK_LEDGER.md |
mock 台账:哪片用了谁的 mock、替换成什么、异常路径覆盖 | 本阶段建立;integration-merge 逐条核销 |
.delivery/premerge-check.sh |
预检脚本(6 项拒收门):各窗口自跑(--slice)+ 拼接期复跑 |
本阶段产出(按 integration-merge reference 的模板实例化到项目 scripts/)——不产出它,拒收门就退化为空承诺 |
MOCK_LEDGER.md是拼接期"接线"的依据,没有台账就无法在拼接时确认 mock 是否已全部换成真实实现——有 mock 降级却无台账时,拼接会被闸门退回。
周期度量(唯一能判断"这套流程值不值"的手段)
本方案的目标是缩短交付周期——但若不记录时间,永远无法判断是否达成,也无法优化。
最小代价的记录方式(不加工具,只加字段):
| 时点 | 记在哪 | 记什么 |
|---|---|---|
| 开工前 | INDEX.md |
串行预估天数(由本阶段给出,Agent 按片数 × 单片估时粗估即可,须标注「粗估」)+ 分了几批 |
| 冻结点 | INDEX.md |
冻结 commit + 日期 |
| 每片开工 / 完成 | 各片 slice.md 状态标记旁 |
日期(各窗口只写自己那片,无并发冲突) |
| 每批合入 | INDEX.md |
批次完成日期 |
| 拼接完成 | INDEX.md |
交付日期 |
必须记「串行预估」这个对照基准:只有实际耗时、没有对比,得不出"值不值"。粗估(如"串行约 8 天")就够用。
回填去向:integration-merge 阶段 6 的拼接报告含「周期对比」一节。多次使用后的真实数字,才是"该不该走并行链"的真实判据(目前该判据只能靠经验阈值:砖头数 / 骨架成本占比)。
这一条第一次用不会有价值(没有基线),但缺了它,这个流程跑十次也攒不出任何"它到底有没有用"的证据。
六件套职责
| 文件 | 作用 | 关键约束 |
|---|---|---|
(包外)tests/contract/{SR-XX}/ |
本砖头组契约测试(骨架阶段按砖头分组产出) | 窗口只管本组变绿;他组不跑 |
(包外)tests/{SR-XX}/ |
片级验收测试(骨架阶段由 5.5.1 承接的验收项派生,断言不由窗口编写) | 窗口让它变绿;断言不可改(认为判据写错 → 写阻塞上报) |
(包外)tests/data-flow/ |
数据走向预演测试(跨砖头,不分组) | 包内 slice.md 必须引用它的路径;各窗口只读不改(它对 mock 应绿);拼接期换真实实现重跑 |
slice.md |
干什么、怎么算完成 | 验收标准必须可执行(命令 + 期望输出),不写描述性文字 |
ownership.md |
边界(防冲突的第一道闸) | 独占写需细到函数级;明确"越界即停" |
contract/ |
契约快照(只读) | 记录冻结 commit hash + 接口签名 + 语义契约 10 项;实现期一字不改 |
out-of-scope.md |
反向边界 | 明确"不做什么" + 遇到边界问题怎么办(写阻塞上报,禁止自行扩大) |
verify/ |
自证工具 | 脚本可独立跑;桩数据齐备;期望输出明确 |
handoff.md |
交接协议 | 可直接粘贴的启动提示词,含能力要求与降级路径 |
模板见 reference.md。
handoff.md是跨会话的关键件——它把"用户口头交代背景"变成"复制粘贴即开工"。
能力声明(handoff.md 必含)
不同 IDE / Agent 能力不对等,砖头包必须声明最低能力要求:
【本包要求的能力】
☐ 读写文件(必须)
☐ 执行命令 / 跑测试(必须)
☐ git 分支操作(建议)
☐ 联网(不需要)
【能力缺失时的降级路径】
- 不能执行命令 → 验收降级为人工核对清单(verify/expected.md 逐条比对)
- 不能 git 分支 → 在独立目录工作,产物交回由用户搬运
阶段 5:允许依赖矩阵 + 交付确认
5.1 生成允许依赖矩阵
SR-01 SR-02 SR-03 现有代码
SR-01 - ✗ ✗ →
SR-02 ✗ - ✗ →
SR-03 mock* ✗ - →
* SR-03 对 SR-01 的依赖通过骨架 mock 满足,不产生真实代码依赖
规则:新砖头之间一律 ✗(禁止真实 import);到现有代码单向 →(只读或按契约调用)。矩阵作为 integration-merge 的机械校验输入。
5.2 交付确认清单
📦 交付切片完成
━━━━━━━━━━━━━━━━
砖头:N 个 | 批次:M 批 | 需 mock 降级:K 处
| 砖头 | 类型 | 独占写 | 批次 | 依赖处理 |
|------|------|--------|------|---------|
| SR-01 | 新增型 | src/order/export/** | 1 | — |
| SR-02 | 修改型 | order/service.py::exportOrders() | 1 | — |
| SR-03 | 新增型 | src/rate/** | 2 | 实现级(等 SR-01) |
【自检】
☐ 成本测算通过(骨架成本 + 公共前置 ≤ 总工作量 50%;估不准时已按保守判定)
☐ **骨架完备性核验通过(阶段 0)**
☐ **骨架预演通过(阶段 0.5)**:数据走向预演全绿 · 契约测试与挂载点测试全红且红因 NotImplemented · 无意外绿 · 覆盖反向无孤儿/重叠 · 零上下文预演由独立核验方执行
☐ 划分复核通过(阶段 1,三项:映射无误 / 归属完整 / 粒度合理)
☐ 独占写集合两两无交集;同文件未落在两个砖头
☐ 无越界(未侵占只读区域)
☐ 依赖分级完成,mock 判据 5 条已逐项核对
☐ 无互 mock
☐ 每个砖头包 6 件套齐备,且包内引用了**数据走向预演测试**与**片级验收测试**的路径
☐ `slice.md` 的验收标准表**来自上游**(5.5.1 承接的验收项 → 可执行化),非窗口自拟
☐ 已安排**片级验收的执行者**(独立验收方;无则显式声明"未独立验收"的降级)
☐ `.delivery/premerge-check.sh` 已生成(否则拒收门是空承诺)
☐ `sub-requirements/INDEX.md` 已记录**骨架 commit** 基准 + **时间戳列** + **串行预估天数**
☐ **用户调度清单**已随交付给出
☐ 允许依赖矩阵已生成
☐ **产出文件的「消费者」已逐个核对**(机器可读块 → `premerge-check.sh` 解析;`slice.md` → 窗口读 + `INDEX.md` 重建;`contract/` → 窗口只读 + 门② 校验;桩标记 → 两个脚本的 `STUB_PATTERN`)——**改了任何被多处消费的模板/配置,必须列出全部消费者逐个确认;且"是否真的能解析/运行"只能靠实测,不能靠阅读**
☐ 批次数 ≤ 2(≥3 已回头查骨架并说明)
☐ **每个窗口有独立工作副本**(不满足不得并行)
☐ ★ **开工须知已写明「窗口必须在自己的分支上提交」** —— 缺这条会让**所有基于分支的预检全部假绿**
☐ ★ **砖头包已被版本控制覆盖**(用 `git check-ignore` 实测)—— 不覆盖则预检门②⑤ 恒失效
☐ ★ **环境前提已写进 handoff**(见下方清单)
☐ **环境隔离已定**(端口 / 测试库 / 缓存),或已声明"同时只允许一个窗口跑集成级测试"
☐ **进度看板已建**(`sub-requirements/INDEX.md`,含状态列与重扫重建约定)
☐ **各片 `slice.md` 已含「划分理由」**(为何这样切 / 与谁不可并行 / 否掉过什么划分)
☐ **各片 verify 含桩残留检查**(生产路径无 `NotImplemented` 残留;不依赖"测试碰巧覆盖到")
☐ **分批时已标注各批基线**(第 2 批起:基线 = 上批合入后的 commit,非原冻结点;见阶段 3.2b)
【交付给用户的开工须知名(必须一起给出)】
- 每窗口独立工作副本 + 基线:**= 该包声明的 `code_base`(单批 = 冻结点 commit;分批时各批不同)**(见阶段 3.2b)
- 环境隔离方案(或降级约定)
- 契约修订的代价:受影响砖头返工重做;修订只在批次边界(单批场景见下)、须先评估返工面
- **划分修订的代价更贵**:砖头边界变了 = 骨架全废、重划重出(见阶段 0「两级修订」);出现"两片必须共享可变逻辑"等信号时必须停下报你
- 进度查看方式:看各包 slice.md 状态标记,INDEX.md 为可读看板(可能被覆盖)
- **他组契约测试红 / 挂载点测试红是预期,不是失败**(窗口不去修)
- **验收效力边界**:最终报告只保证"已确认的验收项范围内达成";冻结点那次确认请重点看"**验收项是否覆盖了你真正想要的**"
- ★ **窗口必须在自己的分支上提交**(否则基于分支的预检全部**假绿**)
---
### 环境前提清单(**必须写进 handoff**)
这些前提不写清时,窗口会以「**报错**」或「**静默失效**」两种方式踩到 —— **后者更贵**(例如 env 不生效 → 测试写进真实用户目录)。
| 前提 | 现象 | 处理 |
|------|------|------|
| **依赖目录** | 独立工作副本(worktree / 克隆)**不含** `node_modules`(它不在版本控制内) | 建**符号链接**指向主副本(只读复用,**勿重装**——重装会污染主副本) |
| **构建产物** | 工作副本不含被 ignore 的 `dist/`,而运行时**必需** | 先跑一次构建命令(通常它本来就是验收第 ① 项) |
| **端口 / socket 争用** | daemon 的 unix socket 可能被**同机他人实例**占用 | **不要杀他人进程**;改用**进程内探针**(调生产同一入口)或独立 `dataDir` / 端口 |
| **env 与配置缓存** | 配置加载有缓存,且**缓存键可能不含环境变量** → 改 env **不生效** | 测试隔离改用**临时配置文件**(而非 env);并保证设置**先于首次配置加载** |
| **相对 URL** | 某些运行时(如 Node `fetch`)**不支持相对 URL**(浏览器支持) | 测试内加垫片补 origin;**不要把被测代码改成绝对路径**——那会掩盖"同源相对路径"这个约定 |
> **一句话判据**:凡"只在窗口的工作副本里才成立的环境差异",都必须**显式写进 handoff** ——
> 因为它是**窗口唯一的启动信息来源**,缺了它,窗口只能靠猜。
【★ 用户调度清单(多窗口期,你是唯一调度者与信使)】
按时间序,每步做完再进下一步:
| # | 你的动作 | 检查点 |
|---|---------|--------|
| 1 | 为每个砖头建**独立工作副本**(git worktree / 独立克隆),基线 = 该包声明的 **`code_base`**(单批 = 冻结点;分批时第 N 批 = 上一批合入后) | 副本之间互不可见;各副本基线正确(分批用错会缺上批成果) |
| 2 | 逐窗口**粘贴 handoff.md**(每窗一个包,不给他包信息) | 每窗口只拿到自己那个包 |
| 3 | 分配**环境隔离**(端口段 / 测试库 schema / 缓存前缀) | 无窗口共用同一资源 |
| 4 | 【进行中】收阻塞上报 | 阻塞项集中处理,不逐个打断其他窗口 |
| 5 | 各窗口报完成后,**收集**:分支名 + verify 结果 + 阻塞项 | 用 INDEX.md 对齐进度,别靠记忆 |
| 6 | ★ **片级验收**:逐片交**独立验收方**(非该片实现窗口),按 `slice.md` 的验收项逐条核验 | 验收项逐条过;**只判定不修改**——不达标退回该片,不就地修 |
| 7 | 全部通过(或该批通过)→ 进入拼接(`integration-merge`) | 主干可编译 |
> **第 4 步是并行期最容易乱的地方**:N 个窗口同时要你做决定时,**攒起来集中处理**,不要来回切换——切换成本是并行度的隐形杀手。
**【★ 用户调度成本必须算给用户看】**
并行不是免费的:**并行度越高,用户的操作次数越多**。交付时必须把账摆出来(不许只说收益不说成本):
```text
用户人工动作 ≈ 建副本 N + 粘 handoff N + 配环境 N + 收片 N + 片级验收 N + 各批拼接 M + 总拼接 1
≈ 4N + M + 1 次
N=4 片、M=1 批 → 约 18 次人工动作
这不是流程缺点,是并行的固有成本——收益必须大于它才值得。若算出来"并行省 1 天、但用户多 20 次操作",应老实建议串行,而不是把流程推出去。
用户可投入的注意力也是并行度的约束:整条并行链假设"存在一个能及时响应阻塞的调度者"。用户若明确"这段很忙 / 不能随时响应",必须降并行度(减片或串行)——该假设不成立时,N 个窗口会一起停摆等一个人。
【下一步】 每批砖头 → 在新对话窗 / 新 IDE 粘贴 handoff.md 开工 全部批次完成 → integration-merge 统一拼接
请确认交付。
---
## 中止与归档(异常出口)
并行链一旦开工,**中止不是"关掉窗口就行"**——已完成的片、半成品主干、各工作副本都要归置。
| 情况 | 处理 |
|------|------|
| 需求变更(局部) | 走两级修订(L1 契约 / L2 划分),**不中止** |
| 需求变更(目标都变了) | 视为中止 + 新开一轮:本轮产物**归档**,不试图改造(改造 = 在新目标上背旧债) |
| 决定不做了 / 优先级被砍 | 按下表归档 |
**中止归档清单(逐项做完才算中止完成)**:
```text
☐ 1. 已完成且通过片级验收的片 → 单独评估「是否仍要合入主干」
能独立上线 → 按 integration-merge 合入(它可能仍有价值)
不能独立 → 保留分支,不合并(合入半个功能比不合更危险)
☐ 2. 未完成的片 → 保留分支 + 在 slice.md 写「中止原因 / 已完成到哪 / 恢复入口」
不删分支(重建成本 >> 保留成本)
☐ 3. ★ 主干检查:不得留半成品,且必须回答「桩是否可能被真实调用」
骨架是纯新增(接口 + 桩,无人调用)→ 可保留,不影响运行
骨架含挂载点接线 → 必须回退(否则生产路径会调到 NotImplemented)
☐ 4. INDEX.md 最后更新一次,标「本轮中止」+ 归档位置
☐ 5. 工作副本保留到「归档确认」后再删(副本里有未提交的 wip)
最容易做错的一条:骨架留在主干上没清。挂载点已接线、桩仍抛 NotImplemented,而需求不做了 → 它会在生产环境被调到。中止时必须显式确认桩的调用可能性,不能默认"反正是空的,放着没事"。
测试与脚手架的归属(提交 / 忽略分离)
并行交付会同时产出两类东西,混在一起会污染产品代码树(且 mock 有被生产代码误引的风险)。必须在落盘时就分开。
判据(一句话)
交付上线之后,这个文件还会因为「产品行为变化」而失败 / 需要更新吗? 会 → 产品资产,提交、进 CI;不会 → 流程脚手架,忽略。
⚠️ 按"来源"切是错的:契约测试、片级验收测试虽然由流程产出,但它们是最有价值的回归资产——尤其片级验收测试,它的断言由需求验收项派生(不是照实现写的)。误忽略它们 = 交付后没有回归保护,比误提交严重得多。
目录约定
| 归属 | 位置 | 内容 |
|---|---|---|
| ✅ 提交 | tests/{SR-XX}/ |
片级验收测试(需求验收项派生) |
| ✅ 提交 | tests/mount/ |
挂载点测试(装配) |
| ✅ 提交 | tests/contract/{SR-XX}/ |
契约测试(接口回归,按砖头分组) |
| ✅ 提交 | tests/data-flow/ |
数据走向测试(拼接期替换后的「对真实实现」版) |
| ✅ 提交 | sub-requirements/ |
砖头包(含 verify/)+ INDEX.md + MOCK_LEDGER.md + INTEGRATION.md——过程文档,与 .requirements/ 同源 |
| 🚫 忽略 | .delivery/ |
代码树过程产物统一目录:mocks/(骨架期 mock)、premerge-check.sh(预检脚本实例)、premerge.conf(生成的配置) |
为什么脚手架统一收 .delivery/:分散落点会让 .gitignore 规则零散易漏;统一目录一行忽略,且以后新增脚手架不必再想放哪。模板本身已在技能里(reference.md 与 integration-merge reference),实例产物丢了也能从模板重生。
落盘时就分开(不做"事后再搬")
| 谁 | 落什么 | 落到哪 |
|---|---|---|
design-to-code |
桩 / mock / 四类测试骨架 | mock → .delivery/mocks/;测试 → tests/ 下四类 |
| 本 skill 阶段 4 | 砖头包 + 预检脚本 + 配置 | sub-requirements/ 与 .delivery/ |
integration-merge 阶段 3 |
mock 替换后的真实实现版数据走向测试 | 就地转正(已在 tests/data-flow/) |
双向校验(交付前必做)
| 方向 | 查什么 | 漏了的后果 |
|---|---|---|
| 防误忽略(更重要) | 产品测试都在版本控制里——四类测试目录逐个 git check-ignore 应无命中 |
交付后没有回归保护 |
| 防漏忽略 | 脚手架都没进版本控制——.delivery/ 应被忽略 |
污染产品代码树;mock 可能被生产代码误引 |
# 防误忽略:四类产品测试不应被忽略(无输出 = 正确)
git check-ignore -v tests/{SR-XX}/ tests/mount/ tests/contract/ tests/data-flow/
# 防漏忽略:.delivery/ 应被忽略(有输出 = 正确)
git check-ignore -v .delivery/
还有一层比"提交"更实的隐患——被 CI 扫到并跑:pytest.ini / pyproject.toml 的 testpaths 应只含 tests/,norecursedirs 排除 .delivery/——否则 mock 替身与骨架期测试会长期造成假红。
不要做的
- ❌ 整目录忽略
tests/→ 会把产品测试一起忽略 - ❌ 把脚手架留在产品目录里"以后再说" → 迟早被提交或被 CI 扫到
- ❌ 删除脚手架 → 归档在
.delivery/即可(下轮可能还要用;模板在技能里) - ❌ 改用户已有的
.gitignore规则 → 只追加不删(同topic-teach「产物仓库卫生」约定) - ❌ 忘记 CI 层 → git 层忽略了,
pytest仍可能扫到.delivery/下的替身
.gitignore追加片段与禁止忽略清单见 reference.md 八。
与相邻 skill 的边界(谁负责划分、谁负责打包)
requirement-mining 子需求拆分 拆"用户视角的需求边界" → 子需求文档 SR-XX.md
↓
design-craft 阶段 5.5.1 ★ 拆"代码视角的交付边界" → 砖头清单 + 目录归属 + 依赖 DAG
↓ (落地映射:子需求 → 砖头,非 1:1)
design-craft 阶段 5.5.2 定骨架(落在上面这套边界上)
↓
本 skill 阶段 0–0.5 核验骨架 + 骨架预演(不碰边界)
↓
本 skill 阶段 1–5 复核划分 + 打包砖头包 + 定批次(不重划边界)
↓
work-breakdown 单个窗口内再拆实施顺序(工作项 W-XX)
| 能力 | 职责 | 产出 |
|---|---|---|
requirement-mining 子需求拆分 |
拆用户视角的需求边界 | 子需求文档 SR-XX.md |
design-craft 阶段 2.5 |
设计组织轴(复用上游划分,不重拆) | 设计子文档 |
design-craft 阶段 5.5.1 |
★ 拆代码视角的交付边界(唯一的划分点) | 砖头清单 + 目录归属 + 依赖 DAG |
| 本 skill 阶段 0.5 / 1 | 核验骨架 + 预演 + 复核划分(不划分) | 骨架预演报告 + 复核结论 |
| 本 skill 阶段 2–5 | 依赖分级 + 批次 + 打包 | 砖头包 + 批次表 + 允许矩阵 |
work-breakdown |
单个窗口内拆实施顺序 | 工作项清单 W-XX |
关键:划分只在 design-craft 阶段 5.5.1 发生一次。本 skill 若发现映射有误,退回重划而非就地修——否则骨架落点与边界脱节(桩会落在别人的独占区里)。
需求管理集成
项目配置了 .requirements/config 时,阶段 4 落盘后注册:
req update {REQ-NNN} \
--docs add sub-requirements/{SR-XX}-{名称}/slice.md,slice \
--changelog "完成交付切片(N 个砖头 / M 批)"
存储路径映射(沿用 requirement-doc-store 规范):
| 产出物 | 存储路径 | docs 类型 |
|---|---|---|
| 砖头包 | sub-requirements/{SR-XX}-{名称}/ |
slice |
| 批次表 | 写入 sub-requirements/INDEX.md |
slice |
反模式
- ❌ 多窗口共享同一工作目录 → 文件互相覆盖,
ownership与越界检查全部归零。独立工作副本是硬前提,不是建议 - ❌ 把函数级独占误读成"同一文件可以并行" → 函数级只提升越界检测精度;同一文件被两个砖头碰,一律不同批
- ❌ 只算业务前置、漏算骨架成本 → 骨架常占 30%–50% 工作量,漏算会让"值得并行"的判定整体失真
- ❌ 多窗口共用端口 / 测试库 / 缓存 → 各自"全绿"是假绿(互相污染),拼接时才暴露
- ❌ 契约修订后不重新对齐已完成批次 → 新旧契约混用,拼接时对不上;修订必须先评估返工面并报用户
- ❌ 分批时第 2 批仍从原冻结点拉基线 → 缺第 1 批成果,表现为"编译不过 / 契约对不上",会被误判成"骨架有问题"(实为基线取值错误,见阶段 3.2b)
- ❌ 只定义了契约修订、没定义划分修订 → 划分错了却按契约修订走,会出现"骨架还在、边界已变"的错位(见阶段 0「两级修订」)
- ❌ 只扫 mock 残留、不扫桩残留 → 漏实现的接口(
NotImplemented未替换)静默上线;契约测试覆盖不到的方法抓不住 - ❌ 横切约定(日志 / trace / 时区 / 精度 / ID / 分页 / 错误码分段)与权限模型留给实现窗口 → 不冲突、编译能过、单测能绿,只在拼接期与线上暴露
- ❌ 划分理由不落盘 → 换会话 / 换人后无法复现"为什么这么切",会反复讨论已否决的方案,甚至把互斥的两片放同一批
- ❌ 中止时把骨架留在主干没清 → 挂载点已接线而桩仍抛
NotImplemented,生产环境会被调到 - ❌ 只讲并行收益、不算用户调度成本 → 约
4N + M + 1次人工动作;收益吃不过它时应老实建议串行 - ❌ 不记周期 → 这个流程的目标是"缩短周期",不测就永远无法判断它是否达成,也攒不出改进依据
- ❌ 把阶段 0 的打勾当骨架验证 → 它只验"有没有",验不了漏 / 缺 / 不可实现 / 假绿 / 契约链断裂——这些只有阶段 0.5 的可执行预演能抓
- ❌ 骨架预演自证(写骨架的人自己预演) → 零上下文预演的意义就是"外部视角",自证时你已知道所有隐含前提,测不出包的自包含性
- ❌ 数据走向预演用
NotImplemented桩 → 跑到第二跳就抛异常,贯通断言根本执行不到;这组测试必须用 mock 填满全链路 - ❌ 骨架阶段契约测试出绿就放行 → 绿 = 桩返回了看似合法的默认值,是假绿警报:拼接期也不会暴露,必须归零才能进阶段 1
- ❌ 发现划分有误就地改边界 → 改了边界,骨架落点就与边界脱节(桩会落在别人的独占区里);必须退回
design-craft阶段 5.5.1 重划 - ❌ 只跑覆盖反向预演不做零上下文预演 → 前者查"有没有人负责",后者查"负责的人能不能零追问地干";两者不可互替
- ❌ 骨架不全就切 → 共享面留给并行期,冲突必然发生。缺项必须退回补骨架
- ❌ 本 skill 自行改模块边界 → 划分是架构决策(
design-craft阶段 5.5.1);本 skill 只复核,有误退回重划(见核心原则 9) - ❌ 独占写只到文件级 → 一个文件被一片独占,其余片全部无法并行,等于没切
- ❌ 同文件不同函数硬要并行 → git 未必冲突,但心智模型会分叉,后续互相绊
- ❌ 允许"小心一点"式并行 → 有交集的独占写必须合并或串行,不接受口头保证
- ❌ 各片自造 mock → 验证的是自己的想象,拼接期必然翻车
- ❌ 互 mock → 双重赌博,风险平方
- ❌ 砖头包不全(缺 ownership / out-of-scope / handoff) → 新窗口无法自包含开工,用户要在 N 个窗口重复交代背景
- ❌ 验收标准写描述性文字 → 无法机械判定,"完成"变成自我感觉
- ❌ 批次数 ≥3 不回头查骨架 → 把骨架缺口当成合理依赖,白白串行
- ❌ 在实现期改契约 → 正在跑的其他砖头全部白做(契约只能在批次边界改)
- ❌ 砖头数量贪多(>5) → 边界数爆炸,集成成本吃掉并行收益
更多资源
- 六件套模板(
ownership.md/ 语义契约 10 项 /slice.md/out-of-scope.md/verify//handoff.md)、依赖分级与 mock 判定细则、批次与检查点、允许依赖矩阵、常见冲突场景处置、完整示例,参见 reference.md - 上游:
design-craft(架构设计 + 骨架交付)、code-survey(现状调研) - 下游:
code-implement(并行实现,只填实现体)、integration-merge(统一拼接) - 相邻:
requirement-mining子需求拆分(用户视角)、work-breakdown(单窗口内分批)、plan-track(单窗口执行台账)