--- name: spec-and-plan description: 交付期第 7 步,plan;另管交接期定约时写的 spec:spec 在定约时和人一起写,定目标、边界与可核对的验收标准;plan 在交付期开头写,把这一程切成有序切片;自带两份模板,项目有模板以项目为准。定约时、交付会话从交接信息包开工时,或人说「写 spec」「出计划」「切片」时加载,也可点名 /spec-and-plan。定义期没走完不加载;分不分程归 pass-the-baton,开工前的上下文包归 context-pack。 --- # spec 与 plan 两份文档,两个时机。spec 回答做什么、做到什么算完,它是承诺,要人认可,所以在交接期的定约时由设计会话和人一起写。plan 回答按什么顺序做、每片怎么验,它在交付期开头由交付的主代理写,计划者就是执行者。一程的承诺、大小与交出收回归交接期,由设计会话做,人在场。做法加载技能 `pass-the-baton`。 ## 顺序 先 spec 后 plan,不并行。plan 是 spec 的分解,spec 没定边界就切片,切出来的片会互相打架。两者之间隔着定程与交出:一程多大、要不要分程,在 spec 定好之后、plan 动笔之前定。 ## 写 spec(定约时) 按 Matt 的 `to-spec` 做:综合会话里已经讨论和定义期已经落盘的内容,不重新访谈;先找测试接缝,越高越好、越少越好。填 [spec 模板](spec-template.md)。本模板比 Matt 的骨架多五节,每节对应定义期的一个产出: | 节 | 来自定义期的 | 为什么要有 | | --- | --- | --- | | 依据与已定事项 | 正式落盘的文档与修订 | 让每条实施决定能追到已接受的承诺 | | 不变式对照 | 需求与不变式单 | 每条不变式写由什么守、怎么验,不留口头承诺 | | 跨域概念的五问 | 领域影响分级表 | 新增或改变跨域概念时必填,没有时写不适用 | | 失败语义 | 细化设计清单 | 正常、失败、未知、取消与清理、外部效果五行,各写行为、责任人、验证 | | 责任分级 | 领域影响分级表 | 让交付期有可核对的边界 | 验收标准每条都能用一条命令或一个文件核对,一程的完成只认它们。spec 是思维模型 `think-evidence` 在这一程的落点:写不出核对办法的标准,说明还没想清楚。 改了既有承诺时,在不变式对照下面写「- 旧字面:`<旧原因码>` `<旧状态名>`」,再跑 [`scripts/consumers.mjs --spec `](scripts/consumers.mjs)。断言旧承诺的测试与文档也是消费者:源码的调用方能按引用找到,它们只能按字面找,而且常在别的成员、在慢的那层测试里。脚本按字面在 Git 跟踪的文件里搜,标出不在责任分级里的命中;范围外的要么补进责任分级,要么确认它不受这次改动影响。交付期扩了范围后再跑一次。 待决事项先筛四层:能查、能建模、能论证的先做完,不列为待决(先答三问:应然、实然、差异。做法加载技能 `think-ought-vs-is`。);过度设计删掉;自己能定的写进已定事项;只有产品规则、范围变化、新的破坏性契约改动、须人本人做的动作才算缺口。 ## 写 plan(交付期第 7 步) 按 Matt 的 `to-tickets` 做:切成端到端的薄切片,每片能单独验证、能在一个新上下文里完成,前置的预重构先做,每片写明被谁阻塞。填 [plan 模板](plan-template.md)。起点是交接信息包的「切片大纲」:可以在本程边界内重切,不改承诺。和 Matt 原版的差别: - 写成员、文件与验收命令,因为主代理在当前仓库执行,不是发给别人的工单。 - 进度总览格式固定,哨兵与汇报件直接读它。 - 每个切片下面留开工包四节:上下文增量、技术细节设计与验证、细化的推进方案、里程碑待办清单。开工包在切片开工前填,做法归 `context-pack`。 - 每个切片带收口清单,做法归 `slice-closeout`。 - 末尾是一程交付声明,含清理已做。 - 多两处给人读的叙述:开头一节「一程目标与前后差别」,每片一项「交付这片的意义」。 - 多一节圈外发现:碰到圈外的问题记一行,进度总览带条数,收口时一次交给人。判法与处置按入口[圈外的问题](../single-session-dev-flow/SKILL.md#圈外的问题)。 - 进度总览多一行「思维模型:」,列六个思维模型技能与诤友。上下文压缩之后重读 plan,按这一行重新加载。 - 子代理表最后一列是 token:数从完成通知里抄,一程结束时看得见钱花在哪。 - 「顺序与并行」多一行「切片的轴」:切片沿用户可见的行为切,不沿技术层切;每条验收落在哪几片,没有落点的写出来。先拆出独立变化的轴,交叉成表逐格看。做法加载技能 `think-orthogonal`。 - 「预算与回看」多两行:人的验收窗口(人什么时候回来、有多少时间上手验收,从交接信息包抄)、停点与点名授权的动作。每片多一项「人怎么验」:人上手看到这片行为的办法与分钟数。 ### 交付期不谈尺寸 一程多大在定程时已经定了,交付期不再分程,也不和人谈范围。交付期只剩两件不问人的事:预计收尾滑出人的验收窗口时,按规则截程交付,在处置记录里记一行「截程交付」,跳过的切片写进交付声明;收尾时列出待人验收。交接信息包的已定事项里人说过按一程做的,开工时在处置记录里记一行「按一程做」与人的原话。看到人这一侧的风险就说一次:提醒、依据、建议、选择。做法加载技能 `candid-friend`。 ### 给人读的两处怎么写 读者是把注意力移开一两个小时后回来的人,他要靠这两处对齐上下文,不翻源码。所以:用完整的句子,不用缩略语和内部短语;产品与技术两层各至少一段;术语第一次出现时用一句话解释它是什么;先说现状与为什么不顺,再说做完之后怎样,最后说他怎么看出来变了。「交付这片的意义」分「对用户」与「对系统」两句,前者说他能看到什么或少做什么,后者说这片改了哪个环节、为什么它先做。写完自己读一遍:一个不了解这个系统的人能不能读懂这程为什么做。 ### 文档维护表与局部编辑 plan 里的「文档维护表」列出一程里每份给人看的文档:给谁看、什么时候更新、只动哪一节、怎么判断过期、最近更新。开工时照模板填上路径,之后每次更新某份文档就改它那一行的「最近更新」。更新一律局部编辑:找到对应的节或行再改,不整份重写,不改节标题与表头,新增内容进模板规定的位置。节标题、表头、进度行与处置行的格式是哨兵脚本与汇报件脚本读的契约。局部编辑用宿主的编辑工具做替换;自己写脚本改文件时先把内容读进来再写回,不要先以写模式打开再读,那样文件先被清空,读到的就是空。 [`scripts/check-plan.mjs`](scripts/check-plan.mjs) 按模板核 plan 与 spec 的骨架:必需的节在且顺序对、进度行与处置行格式对、切片表与维护表的表头齐、每片有意义段与收口清单、未收口且开工包已填的切片写齐开工包的思维模型栏、spec 的责任分级有带反引号路径的重点行。进度总览没有「思维模型:」一行的旧 plan,思维模型栏只给提示,不报缺陷,退出码不变;这一行少了模板列的技能名,也只提示。子代理表有 token 一列的 plan,状态是已合回或已结束的行 token 不能空;没有这一列的旧 plan 只给提示。有「人的验收窗口」一行的 plan,预计收尾晚于人回来的时刻时,要有截程交付或人说「按一程做」的处置,否则报缺陷;0.21.0 及以前的 plan 写了「分程建议」一节也算;切片写「人怎么验:无」给提示;没有这一行的旧 plan 只给一条提示。它在三处跑:切片收口的最后一步、哨兵每轮取事实时、汇报件生成之前。红了不算收口。 交接信息包用 `--handoff <包>` 单独核,包在工单正文里时写 `--handoff -` 从标准输入读:各节与顺序、边界里的责任分级表、起点、四问;「起点与风险」有预计收尾一行的包另核切片大纲一节、人的验收窗口与预计收尾的格式,预计收尾晚于人回来的时刻时「已定事项」要有人说按一程做的一行。没有预计收尾一行的旧包只给一条提示,退出码不变。设计会话交出前跑一次,交付会话开工时再跑一次。包的模板归 `pass-the-baton`。 Matt 的 `to-tickets` 要求人批准切分。这条流里人在定程时已经认可了切片大纲与这一程的大小,plan 在本程边界内细切与重切由主代理自己定,写进 plan 即可,不改承诺;人要看随时能看。 ## 读 Matt 正文的方式 `to-spec` 与 `to-tickets` 声明了 `disable-model-invocation: true`,宿主不让模型自动加载它们。按已安装路径直接读它们的 `SKILL.md`,并在报告里写明读取方式;路径在宿主的技能安装目录下,例如插件缓存目录里的 `mattpocock-skills/<版本>/skills/engineering/<名字>/SKILL.md`。找不到时报告缺口,用本技能的两份模板继续,不停。 ## 放哪 项目 tmp 下本程的目录,例如 `tmp/<一程名>/spec.md` 与 `plan.md`。设计与交付分在两个会话时,spec 由设计会话写,交接信息包链接它的位置。它们是过程材料:正式形状与长期契约归项目的正式文档,一程交付后按 `cleanup` 处理。 ## 外部技能 - 把任务做深不做大,写 spec 前可加载技能 `pstack:sharpen`。