panqiwei/pqw-skills
A development flow for large changes: define with the human, hand off one run at a time, let the agent deliver in slices, then verify. 25 skills plus six thinking models.
pqw-skills
每一版一节,写法见 DEVELOPMENT.md 的「发版」。「细节」之前的部分就是 GitHub Release 的正文。
0.24.1 · 发版说明有了模板
Release notes now follow one template: what you get, what you must do, what changed.
要你动手的: 不用,直接升级。 接入约定: version 1,没变。
变了什么
- 发版说明的模板:每一版先一句英文说它给你什么,再写要不要你动手、接入约定变没变,然后逐条列变化;长的来龙去脉放「细节」。
scripts/release-notes.mjs:从本文件取出某一版的 Release 标题与正文,发版时直接喂给gh release。check-repo:最新一节不合模板,或节的版本号与清单不一致,就报。- 历史:0.22.0 到 0.24.0 的五节与对应的 GitHub Release 按新模板重写。
0.24.0 · 接入约定有了版本
The consumer contract is now versioned: a project pins one integer and no longer has to follow every release.
要你动手的: 不用,直接升级。想少跟版本的项目可以改成只钉接入约定的 version。
接入约定: version 1,首次引入。
变了什么
- 新增
design/consumer-contract.json:列全消费项目要跟着改的三样(接入节的槽位名、交接信息包的节名、常驻卡片的哈希),带一个整数version。 check-repo新增「接入约定」一项:三样任何一样与约定文件对不上就报;与上一个发行 tag 相比,内容变了version必须涨,内容没变不许动。teach-pqw-skills:「接到自己的项目」说明了只钉version的做法。
细节
接入约定有了版本,消费项目不必每一版都跟着动。
消费项目要跟着 pqw-skills 改的只有三样:接入节的槽位名、交接信息包的节名、常驻卡片。新文件 design/consumer-contract.json 把它们列全,带一个整数 version,现在是 1。项目只钉这个 version:它不变的发行版直接换用;它涨了,才回来改接入节、工单模板或卡片。
check-repo 新增「接入约定」一项:槽位表、交接信息包模板的二级标题、常驻卡片任何一样与约定文件对不上就报;再拿约定文件和上一个带约定文件的发行 tag 比,内容变了 version 必须涨,内容没变 version 不许动。教学技能的「接到自己的项目」说明了这个钉法。
0.23.0 · 少等、少往返
Less waiting and fewer round trips: long verification leaves the subagent, and independent reads go out in one step.
要你动手的: 不用,直接升级。 接入约定: 没变。
变了什么
delegate-brief:长验证不留在子代理里,列成「待验证」交回,由派发者跑;子代理交回前结束自己起的后台进程;互不依赖的读取在同一步里一起发出。简报模板相应多三行。slice-closeout:结构读数与差分变异跑得久时放后台,等的时候只做下一片的开工包。context-pack:主代理自己读时,互不依赖的读取一步发出。
细节
少等、少往返。依据是一个真实项目一个月的会话计时:轮询等待 26 小时里有 22 小时发生在子代理内;子代理交回后被自己留下的后台进程叫醒,空转近 40 小时;84% 的步只带一个工具调用;主会话闲等后台验证约 28 小时。
delegate-brief:多一条「长验证不留在子代理里」。子代理结束回合就等于交回,等不了完成通知,只能占着位置循环等;跑得久的验证让它列成「待验证」交回,派发者合回后自己跑;它起的后台进程在交回前结束。「框住读量」加一句:互不依赖的读取在同一步里一起发出。简报模板的「信息包」多「读法」一行,「环境」多「长命令」「后台进程」两行。
slice-closeout:结构读数与差分变异跑得久时放后台,等完成通知;等的时候只做下一片的开工包,不动下一片的代码,读数有要处置的先回来处置完这一片。
context-pack:主代理自己读时,互不依赖的读取在同一步里一起发出。
0.22.2 · Kimi Code 与 DSH
Two more hosts are supported natively: Kimi Code and DeepSeek Harness (DSH).
要你动手的: 不用,直接升级。 接入约定: 没变。
变了什么
- Kimi Code:新增根
kimi.plugin.json;会话里/plugins install https://github.com/PanQiWei/pqw-skills装全套。在 Kimi Code 2.5.3 的真实会话里装过。 - DSH:README 写了装进它的技能目录的两行命令。没有在真实 DSH 里跑过。
one-lesson-rule:宿主表加这两家。- 图标与社交预览图:按 kami 规范重画,由
assets/gen-icons.sh生成。
细节
多两个原生支持的宿主:Kimi Code 与 DeepSeek Harness(DSH)。技能正文没有变。
Kimi Code:新增根 kimi.plugin.json,是 Kimi Code 自己的插件清单。在会话里 /plugins install https://github.com/PanQiWei/pqw-skills 就装上全套,它取最新的发行版;地址换成发行页可以固定版本。在 Kimi Code 2.5.3 的真实会话里装过:装的是 v0.22.2,25 个技能以 /skill:pqw-skills:<名字> 出现。
DSH:它没有安装技能的命令,从固定目录发现技能。README 写了装进 ~/.dsh/skills 的两行命令,以及项目级的 .agents/skills。目录与规则照 DSH 官方的技能子系统文档;没有在真实 DSH 里跑过。
one-lesson-rule 的宿主表加这两行。check-repo 把 kimi.plugin.json 也纳入版本一致性。图标与社交预览图按 kami 规范重画(Charter 字、细线、象牙色卡片),由 assets/gen-icons.sh 生成。
0.22.1 · 找得到、装得上
Easier to find and to install: install commands on the first screen, manifests for Codex and Cursor, a plugin icon.
要你动手的: 不用,直接升级。在本仓库里开发的人把 npm ci 换成 npm install。
接入约定: 没变。
变了什么
- README 首屏:标题下先一句话,接着两行安装命令。中英两份同步。
- 清单与图标:新增根
plugin.json(给 Codex 与 Cursor);Claude 的清单加displayName、homepage、icon;新增图标与社交预览图。 - 根目录不再提交
package-lock.json:插件根的锁文件会让用户安装时装上本仓库的测试依赖。 check-repo:核各份清单的版本一致。
细节
让人找得到、装得上。技能正文没有变。
README 首屏:标题下先一句话说它给你什么,接着就是两行安装命令,再是徽章与故事图。以前安装在第 135 行。中英两份同步。
清单与图标:新增根 plugin.json,Agent Plugins 格式,给 Codex 与 Cursor 用,带 Codex 的展示字段;.claude-plugin/plugin.json 加 displayName、homepage、icon,描述改成中英各一句。新增 assets/icon.png(1024 见方)与 assets/social-preview.png(1280×640)。check-repo 多核一条:根 plugin.json 的版本与 .claude-plugin/plugin.json 一致。
根目录不再提交 package-lock.json。仓库根就是插件根,Claude Code 在用户安装插件时会安装插件根锁文件里的包,官方目录的提交检查也会因此留审;这些包只有本仓库的测试用。package.json 里的版本本来就写死,开发时改用 npm install。
0.22.0 · 交接期与交棒
Handoff becomes a stage, not a point: the design session sets the spec, sizes one run, hands it off and takes it back.
要你动手的: 接入节加一格「跨会话协调用什么」;「交接信息包放哪」改名「交接信息包与路线图放哪」;项目自己的工单模板加「切片大纲」一节与预计收尾一行。 接入约定: 变了(当时还没有版本号)。
变了什么
- 新技能
pass-the-baton(交棒):交接期四件事,定约、定程、交出、收回。设计会话是编排者,交付会话只知道自己这一程。 - 交接信息包:多一节「切片大纲」,「起点与风险」多一行预计收尾;包里只有这一程。
spec-and-plan:spec 在定约时写,plan 在交付期开头写;尺寸核对挪到定程。candid-friend:四个时机都在设计会话里:接需求、定程、交出之前、收回。check-plan:--handoff -从标准输入读;新模板的包另核切片大纲与预计收尾。
细节
交接从一个点变成一个阶段,叫交接期。到 0.21.0 为止,流程表里交接是一行不带编号的「交接点」,写 spec 与 plan 的第 7 环节整个排在它后面,尺寸核对排在「plan 写完之后、第一个切片动手之前」,「分程建议」是 plan 模板的一节。实际分会话交接时看到两处毛病:交付会话拿到一份过大的包,人不在场,它只能回头找人商量分程,或者一直做下去;交接点核对单与交接信息包已经假定交接时 spec 写好了(「按 spec 的旧字面搜过」「责任分级照抄 spec」),流程表却把写 spec 排在交接之后,设计会话没法交出一份照抄 spec 的包。要人拍板的事,应该在人在场的时候,由持有上下文的那个会话来谈。
新技能 pass-the-baton(交棒),流程轴上的阶段技能,不是编号的环节,也不是思维模型。交接期像接力赛的接力区:棒要在区里交完,接棒的人只跑自己这一棒。它由设计会话做,人在场,有四件事:定约,和人一起写这一程的 spec;定程,写切片大纲、问人的验收窗口、做尺寸核对,不过就给分程建议,分程时写路线图;交出,走交接点核对单、写交接信息包;收回,这一程交回来之后人上手验收,结果记进路线图,打回的与截下来的变成下一程的输入或修订包,再修订后面各程的边界。两条规矩:设计会话是编排者,分不分程、次序与路线图只归它;交付会话只知道自己这一程,包里不出现别的程,它不和人谈范围,包答不出四问或与正式文档对不上就退包。一次只交出一程。13 个环节的编号不动,四件事用名字,因为收回发生在交付之后;第 7 环节改名「plan」。正文 60 行以内,展开页三份:交接点核对单与交接信息包模板(从 single-session-dev-flow/ 搬来)、新的路线图模板、用 GitHub issue 协调。设计与交付分在两个会话时缺省用 GitHub issue:一程一张 issue,正文就是包;父 issue 放路线图,交付会话不读它;交付声明、退包与打回写成评论,第一行是固定开头;验过了关 issue。项目接入点多一个槽位「跨会话协调用什么」,填了别的工单系统就用它的正文、评论与开关;没有 GitHub 又没约定别的,退回到文件。一个会话走完时不开 issue,包与路线图写在这一程的工作目录里,槽位「交接信息包放哪」改成「交接信息包与路线图放哪」。
交接信息包多一节「切片大纲」,放在验收标准之后:每片交付什么行为、对应哪条验收、人怎么验、验几分钟、预计做多久,只写到够估时;「起点与风险」多一行预计收尾。包里只有这一程,「范围外」只说不做什么,不说归哪一程。spec-and-plan 写明两个时机:spec 在定约时写,plan 在交付期开头写,从切片大纲起步,可以在本程边界内重切,不改承诺;尺寸核对一节挪走,plan 模板去掉「分程建议」一节与「尺寸核对」一行。candid-friend 的时机表改成接需求时、定程时、交出之前、收回时,四个时机都在设计会话里;交付期只剩两件不问人的事:预计收尾滑出窗口时按规则截程交付,收尾时列出待人验收。「上一程验过没有」从入口的开工动作挪到收回,交付中追加的范围记成下一程的输入。截程交付跳过的切片写进交付声明,由设计会话收回时定去处。入口技能的流程表把「交接点」一行换成交接期四行(收回排在 13 之后),「怎样走」「不可商量的」「边界」改写;think-closed-loop 里「设计会话转给交付会话」一行指到本技能;正式落盘、一堂课法则、清理与教学跟着改,教学的「为什么分两期一点」改成「两期一区」,人该做的事多一条:验收之后回到设计会话。
check-plan:--handoff - 从标准输入读,好接 gh issue view <号> --json body -q .body,缺陷里的文件名记「标准输入」,只有一个参数能这样写。「起点与风险」有预计收尾一行的包是新模板,另核切片大纲一节与表头、表里写了、人的验收窗口与预计收尾的格式;预计收尾晚于人回来的时刻时,「已定事项」要有人说按一程做的一行。尺寸规则从 plan 挪到包:plan 的预计收尾晚于窗口时,处置记录里有截程交付或按一程做就不报。兼容:没有预计收尾一行的 0.19.0 到 0.21.0 的包只给一条提示;带「分程建议」一节的旧 plan 照样认;退出码不变。上下文地图:「交接点」一行换成「交接期」,spec 的两格(找差异的指路行、证为主)随 spec 挪到这一行,第 7 行改名「7 plan」;诤友的格同样改;新增 stages 一项登记 pass-the-baton 的指路行,check-repo 与 crosscut 同样逐格核,另核正文不超过 60 行、入口与两份 README 点到它。两张全景图重跑,环节列表在 6 与 7 之间多交接期一行;故事图第二幕的交接点菱形换成一小段交接期,写出定约、定程、交出,收回写在「你回来」一侧,技能数改成 25。tests/ 新增 7 条:check-plan 6 条(新模板包的模板钉住、缺切片大纲与表头不对、尺寸与按一程做、旧包只提示、切片大纲人怎么验写无、标准输入),check-repo 1 条(阶段技能的指路行、行数与入口可达)。
仓库文档(0.21.0 之后,不改技能行为,不升版本)
README 改成以两张信息图为主:assets/story.svg 用三幕讲用这套流能得到什么,assets/map.svg 用两条轴的矩阵列出全部技能与自带脚本,矩阵由 assets/gen-map.mjs 从 design/context-map.json 生成。两张图用 kami 的视觉规范。技能细目的表格收进折叠块。README_EN.md 同样重排,英文图是 assets/story-en.svg 与 assets/map-en.svg,各由脚本生成。旧的 assets/flow.svg 删掉。两份 README 不再设「状态」节,每一版改了什么只记在本文件。
0.21.0
主代理知道什么该自己做,派出去花多少钱。到 0.20.0 为止,delegate-brief 的派发门三条理由都在说上下文:主上下文退化了、需要新鲜的并行上下文、主代理选不对工具。它说了「默认自己做」,没说清为什么,也没算过钱。实际派发里看到的失败有三类:要用到人纠正过的分寸的活派了出去,子代理不知道那句纠正,照常做错;带着几十万 token 的上下文分叉,半路撞了额度上限,换成新开的子代理加一份规格文件才做完;子代理交回几千字的长报告,进了主上下文之后每一轮都要再读一遍。
新的思维模型 think-closed-loop(闭环),第六个,回答这件事该由谁做、一次做多大、多久看一次。另外五个模型讲一件事本身怎么想,它讲事情在人和代理之间怎么转手。三句动作:转手会丢信息,做对它要用到的写不下来的上下文多就不转;回路越紧越稳,决定后面很多步的事放在每一步都看得见的回路里,放手跑的一段写停止条件;一块多大由接的一方验得完多少定,人对主代理、主代理对子代理、今天的自己对压缩后的自己都是这一条。骨架与另外五个相同,正文 41 行,四页展开:转手会丢信息(数据处理不等式)、回路越紧越稳(延迟、窄传感器、开环、必要多样性)、一块多大、七处转手。上下文地图多一列与一行「交接点」:派发与哨兵回看为主,细化设计、正式落盘、交接点、切片开工包、汇报放指路行,压缩之后是 plan「思维模型:」一行的空位「转手 think-closed-loop」。标志词是「转手」「回路」。搬家:诤友讲验收产能是瓶颈的道理、派发讲为什么默认自己做的道理、入口讲交接点为什么是物理条件的道理,都搬进这个技能,原处留结论与指路行。另外五个模型的「相邻的模型」各加一句。
delegate-brief 重写判据与花费的部分。派发门之前加两个判据:做对它用到多少说不出来的上下文;中间过程是不是又大又用完就扔。两个判据交叉成二乘二的表,只有「说得清、验得了,中间过程又大又用完就扔」一格整件派出去,另一格拆开派体力、自己做判断;三问保留,成为两个判据的具体情形。列出主代理自己上手做的六类事,每条一句为什么。档位表按活重写:找东西与读很多文件用最便宜档,规格完整的单模块实现与独立对照用经济档,跨很多文件的改动用默认档,长时间盯测量不派、用后台任务;顶档不当子代理,例外是规格写得清的内核级难题;档位仍先从项目接入点取政策。怎么派才便宜八条:规格写进文件、不分叉大上下文、框住读量、小活不派、原始结果写文件且报告限行、派出去之后接着干别的、续用还是新开看缓存还在不在、记 token 账。新的一页「钱是怎么花的」按 Anthropic 的报价(缓存日期 2026-11-03,用前按现价核对)算主上下文里一个 token 的陪跑价、子代理的开工费与三个坑;订阅额度是否按同样比例消耗没有明文,按报价比例推断。交回改成原始结果写进交回目录的文件,报告 30 行以内只带结论、提交号、证据文件路径、偏离规格处与只有人能定的事;防自报成功的意图不变,报告是指针,不是证据。「等待与追加」多缓存寿命两条。加一处指到 candid-friend:派出去的一块多大由主代理验得完多少定,与一程多大由人验得完多少定是同一个结构,地图 crosscut 登记这一格。
简报模板多三栏:规格文件、读量上限、报告行数上限(缺省 30 行);交回格式分报告五样与交回文件六样。check-brief:三栏有任一栏的是新模板,缺哪栏报哪栏,规格文件要存在(相对路径先按当前目录、再按简报所在目录找),读量上限要填,报告行数上限要写行数;三栏都没有的旧简报只给一条提示,退出码不变。plan 模板的子代理表最后加一列 token,数从完成通知里抄;check-plan 按表头名取「状态」与「token」两列,有 token 一列时状态是已合回或已结束的行 token 不能空,没有这一列的旧 plan 只提示;「思维模型:」一行少了模板列的技能名也只提示,0.19.0 与 0.20.0 写的 plan 不报新缺陷。token 一列加在最后,哨兵按位置读的开始与状态两列不变。常驻卡片多一行「转手」,放在「证」之后、「对人」之前。教学技能的两条轴从五个改成六个,纠偏表多一行「这件事你自己做」,「为什么默认不派子代理」改成两个判据与新的交回规则。tests/ 新增 8 条:check-brief 4 条(模板与核对器钉在一起、新模板三栏各报、规格文件的路径解析、0.20.0 简报只提示),check-plan 4 条(模板与核对器钉在一起、token 报与不报、按表头名取列、0.20.0 与 0.19.0 的 plan 只提示)。
0.20.0
代理也防人的失败。到 0.19.0 为止,这套流防的都是代理的失败:偏离、过度设计、自报成功、上下文腐化。人在回路里出的错没有人防:需求没想清、要的是机制不是结果、为想象中的用户做功能、一程大过自己验得完的量、做到一半又加、上一程没验就开下一程。代理一夜能做十个切片,人早上只有一小时验收,剩下的就是没验收的库存,方向一错全是沉没成本。新技能 candid-friend(诤友,直言一次,然后听你的)在流程轴上横切,与 one-lesson-rule 同类:那边是代理回头看自己,这边是代理回头看人。它不是第六个思维模型。立场四条:说出来是职责;说一次,带依据,给建议;只提醒,然后服从,人听完仍要做就照做,不打折扣、不附加条件、不因此收紧哨兵或加检查、不反复提,只有新证据才再提;不拿它当拒绝的理由。说的格式固定四行:提醒、依据、建议、你可以。人的决定在处置记录里记一行。正文 46 行,四页展开:值不值得做、一程的大小、途中与收尾、夜间一程。
接需求时先问值不值得做,排在复述目标之后、grilling 之前:先查三件(已经有了吗、以前拒绝或推迟过吗、有没有既有的决定),按需求的种类选问题,四问(需求证据、现状、具体的人、最窄切口)一轮问齐、每问带代理查到或猜的答案,前提逐条确认,给四种结论之一(照做、缩小到最窄切口、先取证再做、建议不做)并说什么证据会让自己改主意,只对决定结论的回答追问一次。问法综合自 gstack 的 office-hours、plan-ceo-review 与 ETHOS(只是思想来源,不加载),以及 Matt 的 grilling、triage、to-questionnaire、prototype、wayfinder;to-questionnaire 声明了 disable-model-invocation,按已安装路径读,登记进依赖表。需求单加「值不值得做(质疑与答复)」一节,接入点多一个槽位「不做与推迟的记录放哪」。
一程的大小由人在验收窗口里验得完多少决定。交接点问人两个数:什么时候回来看,有多少时间上手验收;人不答按「当天回来,验收一小时」。它写进交接信息包「起点与风险」与 plan「预算与回看」。plan 写完、动手之前做尺寸核对:做得完吗、验得完吗、每片都验得了吗;任何一件不过就停在动手之前,给「分程建议」一节:每一程自己有价值、人能上手验,最可能改方向的排第一程,后面的程只定到边界。切片多一项「人怎么验」。途中预计收尾滑出窗口时,哨兵脚本出「超出验收窗口」信号,人说过按一程做时不报;出口表多「截程交付」:停在当前切片的边界上交付已收口的,剩下的挪进下一程。人途中追加范围,代理回一次后果。交付声明加必填的「待人验收」一节,入口开新一程前先看它勾完没有。夜间一程:六样防法、睡前交接四样(停点、点名授权的动作、只有人能定的事、早上的验收时间)与晨间交付;交接信息包多「停点」「点名授权的动作」两行。汇报件骨架多「没验收的库存」一栏。
check-plan:plan 有「- 人的验收窗口:」一行的是新模板,预计收尾晚于回来的时刻时,要么有写了的「分程建议」(表里至少一行不是占位),要么处置记录里有人说「按一程做」的一行,都没有报缺陷;切片写「人怎么验:无」给提示;窗口一行与预计收尾一样不受「不晚于时钟」约束。没有这一行的旧 plan 只给一条提示,不报缺陷,退出码不变,0.19.0 模板写的 plan 照样通过。上下文地图加 crosscut 一项,登记横切技能的指路行「看到人这一侧的风险就说一次:提醒、依据、建议、选择。做法加载技能 candid-friend。」放在哪些文件、模板里有哪些空位,check-repo 按与模型同样的核法逐格核,并核正文行数与入口可达。plan 进度总览的「思维模型:」一行末尾加「对人 candid-friend」。
常驻卡片:五个思维模型各一句加诤友一句,每句末尾是技能名,发行在 skills/single-session-dev-flow/resident-card.md。消费项目把它原样放进自己的常驻入口文件,升级后重新同步,不手写第二份;它取代接入点原来的「研发品味」一行。check-repo 核卡片点到地图登记的每个模型与横切技能,每行末尾的技能名存在。教学技能多一节心智模型「你的验收产能是瓶颈」、人该做的事、一句话开关(少问:「这一程我定了,照做」;多说:「有顾虑就直说」)与纠偏表四行。仓库根 AGENTS.md 开头与结尾各加一段所有权的事实。tests/ 新增 9 条:check-plan 4 条(模板与核对器钉在一起、超出窗口报与不报、0.19.0 模板只提示、人怎么验写无的提示),哨兵 1 条,check-repo 4 条(横切技能的格、正文行数、常驻卡片、入口可达)。
0.19.0
思维模型成了第二条轴。以前这套技能只有一条轴:13 个环节回答「现在走到哪一步」。核心的想法散在各环节的正文和入口的「写代码的四条」里,没有自己的家:入口技能只在一程开头读一次,上下文一长、一压缩,代理忘了就回不来,人也没法一句话点名。现在加一条与环节正交的思维轴,五个横切技能各回答一个别的模型推不出的问题:think-orthogonal(这个问题的空间怎么拆)、think-ought-vs-is(这件事的工作到底是什么)、think-model-first(代码该长成什么形状)、think-right-then-well(按什么顺序建,怎样算好)、think-evidence(怎么知道它是真的)。五个长成同一副骨架:description 以「思维模型:」领头并把三句动作压进去,正文一个问题、三句动作、按工作类型的表、写在哪、什么时候必须重做、相邻的模型,50 行以内,细节放至多五页展开。「不过度设计、不提前优化、不变式排除的不处理、圈外的不修」能从应然与实然的第三问推出来,并进 think-ought-vs-is 的「不多做」一页,不单立。
两条轴交叉出上下文地图,唯一源是 design/context-map.json:15 行(13 个环节、不够格的小活、压缩之后)乘 5 列,36 格有内容。「主」是环节的产出本身就是模型的成果,环节技能点名模型;「行」是在要用到的那一步上放一句一字不差的指路行,形如「<动作一句>。做法加载技能 <名>。」;「空」是模板里的固定空位。check-repo 第 10 段按地图逐格核,并核五个技能的骨架与行数、别处一行同时出现某个模型的两个标志词时要点技能名(防复述,指向写代码的四条的行除外)、README 的矩阵表与地图逐行一致、入口技能、教学技能与两份 README 都点到五个技能。三个定时入口把模型送回上下文:切片开工包的空位(应然、实然、差异、全化表、做对、做好一轮),哨兵的固定提醒改成点技能名(局部兜圈点 think-ought-vs-is,实现比本质复杂的(甲)加点 think-right-then-well,(乙)按 think-ought-vs-is 的「不多做」删掉;不加新信号),plan 进度总览固定一行「思维模型:」按拆、找差异、定形、建、证列五个技能名。plan 的「顺序与并行」多一行「切片的轴」。
搬家:「写代码的四条」的标题与锚点保留,四句各变成一句结论加所属技能的指路行;先做对与做好一轮的道理搬进 think-right-then-well,形式化与细化设计里「为什么先建模」的道理搬进 think-model-first,「证真交给证明、证伪交给测试」的道理搬进 think-evidence;环节自己的做法不搬。check-repo 第 8 段改成守四条只有一处索引:别处提到「先做对」「再做好」「找本质解」的行要链到入口那一节,或点名某个思维模型技能。
两处行为改变。一、全化表碰到状态与操作就做,写进细化设计清单新的「全化表」一节或开工包的「全化表」一栏,不需要人确认;模型检查与证明仍按四类触发,代理建议、人确认。formal-guard 的描述、正文与触发建议单,detailed-domain-design 的正文与模板,入口的「不可商量的」与「容易混的环节」同步。二、做好一轮多一份品味核对单:架构位置、领域边界、SOLID 五条各一问,共七问,每问用代码位置作答,答「没有可改的」也要指到看过的位置;主代理自己核,不派评审。核对单在 think-right-then-well/taste-checklist.md,收口清单的「做好一轮」下面有七行空位。
check-plan 核未收口(不是已完成或跳过)且开工包已填的切片:开工包要有应然、实然、差异、全化表、做对、做好一轮六栏,各有内容且不是整条尖括号占位;照抄模板没改的开工包算没填。进度总览没有「思维模型:」一行的旧 plan 按旧模板核,这六栏不报缺陷,只给一条提示,列出加上这一行之后要补的栏,退出码不变;--format json 多 hints 数组,哨兵与汇报件仍只读 ok 与 defects。教学技能的心智模型页多一节「两条轴:流程与思维」,纠偏表多五行现成的话(「先写应然」「先找轴」「先建模」「证据呢」等);接入说明多一个槽位「研发品味」,项目 AGENTS.md 里放一行指向五个技能,不走这条流的会话也看得到它们。README 与 README_EN 的技能表多「思维模型」一组并放矩阵表,徽章改成 0.19.0 与 22 个技能。tests/ 196 个用例,新增 10 条:check-plan 3 条(模板与核对器钉在一起、未收口且已填的切片逐栏报、旧模板只提示),check-repo 7 条(指路行与空位、复述、骨架、地图外的 think- 技能与 kind、「主」格点名、README 矩阵、入口可达)。
0.18.0
差分变异缺省只变异改动的行。差分变异回答「这次的改动有没有被测试守住」;以前缺省把范围扩到改动行所在单元自己的全部行,函数里没改的行变异出来测的是改动之前的代码,存活是旧欠账,按收口规则要逐条处置,就把圈外的活推给了这次改动,冷缓存的 CPU 也随之翻倍。第十四程 omne 的 B1 考题上,扩到单元时一个成员 193 个变异体、冷缓存 CPU 是旧工具的 1.9 倍;只打改动行后变异体与存活都与旧工具相同,CPU 0.97 倍。新参数 --whole-units 恢复原来的范围,给想顺手还一个函数旧账的人用;--unit-max-lines 只在给了 --whole-units 时起作用,JSON 的 narrowed 只在那时有内容。slice-closeout 第 4 步与 metrics-model.md 的「范围」一条写明缺省、理由与什么时候给 --whole-units;按单元写的端到端用例显式带 --whole-units,缺省范围由新加的两条断言守。
0.17.0
设计段加两件事。一是形式化产物不直接拿来写代码:formal-guard 原来写「全化的结果直接是类型与契约的形状」,照着全化表写出来的是一个按状态分支的大函数,对但难维护。现在 formal-guard 产出一张形式化交接表(状态与不变式、定义域、全化规则、环境假设,名字取自统一语言),detailed-domain-design 新增「从形式化交接表翻译」一节,把它们分别翻译成聚合与值对象、边界上解析出的窄类型、显式结果类型、按状态分开的类型或表、端口,并留一张精化对照表,证明转契约测试按这张表落到用例上,收口按它逐行核。同一节写明领域决定结构、SOLID 管依赖,全化后的纯函数不硬拆成类。二是风险前置:领域建模与 SOLID 的对象建模每次设计都做,做不做形式化都一样;设计做完先论证再写代码,detailed-domain-design 新增「方案论证」一节(在类型与签名上走一遍主场景与失败语义、对一遍不变式落点、工作量大时比两个候选、说不准的点做原型),深度跟工作量走,论证不过不进下一步。总入口加「风险前置」一节;切片开工包的「技术细节设计与验证」拆出领域模型、对象模型、精化对照表、方案论证四行,论证不过不动手;细化设计清单加精化对照表与方案论证两节。来由:第十四程试走里收工钩子因为简报把实现手段当成不变式,转了三轮才找到本质解;负责人据此要求设计段与切片开工前都先论证设计再写代码。
0.16.0
两轮真卡试走查出的问题,按「兜底放在事实上,不放在步骤上」修成脚本与检查:只规定要成立的结果,能由脚本判出的做成检查或信号,判断与处置仍归代理。哨兵:改动文件只取本分支第一父链上的非合并提交,合入单列次数,合进来的文件不再被报成圈外改动或兜圈;子代理「在跑」只按状态格开头的状态词判,「第 3/5 轮后终止」不再被当成在跑;新增三条文档陈旧信号:切片收口了而汇报件没有在那之后生成、预计收尾已过、plan 连续两轮没改而有新提交(主代理可能在写另一份 plan)。check-plan:进度总览要有「预计收尾」;子代理表状态以状态词开头;收口要有「改动成员的合入检查」;每条验收写明经过的成员,路径都在责任分级里,落不进的在写 spec 时就写「按范围验收」;不许有晚于时钟的时刻(预计收尾除外),新增 --now。新脚本 spec-and-plan/scripts/consumers.mjs:按 spec「旧字面」一行全仓搜断言旧承诺的测试与文档,标出范围外的命中;delegate-brief/scripts/check-brief.mjs:派发简报九节齐,评审者与验收者要有「允许的动作」「不做的事」,对抗式要求只能写在「不做的事」里,项目自带的评审角色也用这份简报。结构读数:同名单元按名字加序号配基线,配不上记「拿不准」;--crap <warn>,<alert> 有提醒线;认类型测试与同一文件里辅助函数中的断言;--lcov a,b,c 合并几份覆盖文件。差分变异:变异前沙箱预检,没跑通时成员测量无效并列出文件;--vitest-config 只跑某一层;--unit-max-lines(缺省 200)以上的单元只变异改动行与最小嵌套函数;增量指纹含测试配置内容与构建产物(--build-output);--recheck-limit(缺省 8)给超时复核封顶;运行时报错使成员测量无效。收口第 1 步加「改动成员的合入检查」,第 2 步写明证据要能检出错误的结果;清理前核对证据已贴到验收处;宿主限流的限制与按干活时间计预算写进 one-lesson-rule/hosts.md 与 plan 模板;formal-docs-landing 的下层违背上层含持久化形态。接入槽位多三格:改动成员的合入检查、验收处、文档写作规则。clear-writing 与 write-agents-md 从元技能改为随插件发行,项目的文档写作规则从接入点读。测试整轮共用一个临时根,跑完删掉,系统临时目录不再留目录。
0.15.0
结构读数与差分变异分两个尺度,和信息包的节奏正好反过来。信息包开工前整理一次全量,之后每个切片只补增量;读数以前却是每个切片都按本片的全部改动函数做,差分变异的「热点」也包括本片全部改动行所在的函数,同一批函数被一片一片地重算,算的大多又不是错了代价大的地方,推进被拖慢。现在 slice-closeout 开头一节「两个尺度」:切片收口只守关键位置,即本切片碰到的判据与不变式守护点、状态转移、并发、失败与清理分支、对外契约边界,开工包「技术细节设计与验证」写明路径与为什么关键,结构读数用 --scope 收窄到这些路径里的改动函数,差分变异用 --scope 加 --files 点名关键文件;本片没有关键位置时写「无关键位置:理由」,第 3、4 步写「本片不需要」。新一节「一程全量读数」:全部切片收口之后、交付声明之前,在最终头上以 spec 抬头的起点提交为基线,按整程改动跑一次结构读数与差分变异(多包仓库按改动的成员各一次),关键位置之外的存活三选一:补用例、判为等价、记「不变式排除」,改了代码的在新头上复跑改动的行;项目的合入检查已经按整程改动跑同样的读数时贴它的结果,不跑第二遍。收口清单末尾加「一程全量读数」记录模板,plan 与 cleanup 的交付声明各多一项指向它,spec 模板「检查与命令」两行的「何时跑」改写,开工包模板加「关键位置」一行,入口技能第 11 环节的产出与「怎样走」第 4 步、教学心智模型、接入槽位(多一格「项目合入检查已跑的全量读数」)同步。两件工具都不改:--scope、--files、--base 已经够用。check-plan 不加新的必需项,按 0.14.0 模板写的 spec 与 plan 照常通过。tests/ 147 个用例,没有新增。
0.14.0
责任分级接通到交付期:长程交付不再被圈外的问题带偏。以前定义期第 2 步把受影响的领域分成重点、次要、连带三级,但这张表停在定义期,spec 里没有它,交付期没有可核对的边界,没有任何地方说「三级之外怎么办」,哨兵也不认这几级;主代理与子代理碰到别的模块已有的缺陷、产品写了还没做的机制、无关的红用例、别人文档里不一致的说法,常被当成本程的职责或必须先解决的冲突,越挖越深或停下来问人。现在入口技能新增唯一正文「圈外的问题」:三级按与本程改动的关系定义(本程改动的承诺的消费者,表里没列也是连带,补进 spec 并升修订),三级之外是圈外;处置表五行:重点修;次要、连带只做 spec 写定的那类改动;未列出的消费者照连带同步;圈外不挡验收就在 plan「圈外发现」记一行继续,不调查、不修、不停、不问人;圈外挡住验收先找圈内绕法,没有绕法只停依赖它的切片,收口时一次交给人。spec 模板加必需节「责任分级」(重点、次要、连带三行,按成员或目录给路径;圈外一行带上「本程改动的消费者不在圈外」这条例外,上下文压缩后只剩 spec 也不丢),plan 模板加必需节「圈外发现」(时刻、位置、现象、证据、挡住的验收、处置)与进度总览的条数行,交接信息包的「边界」带同一张表并由它派生写范围;check-plan 对缺这些节的文件报缺陷并写明加什么,老的 spec 与 plan 会被报出(不加宽限)。哨兵:sentinel.mjs 新增 --spec(缺省取 plan 同目录的 spec.md),按责任分级的路径把上次唤醒以来提交与未提交改动中落在路径外的文件报为「圈外改动」(plan、spec 自身与 Git 忽略的不算),spec 缺这一节报「责任分级缺失」,「圈外发现」条数与挡住验收的条数进汇报并与上一轮比差;第一问「有没有偏离」加第二类证据「在圈外做功」,带固定提醒(写出「圈外」与「本程改动带出的消费者」两种可能,由主代理判);常规出口加「回到圈内」;缺省间隔改为一程总预算的六分之一,下限 10 分钟、上限 45 分钟,规则只在 one-lesson-rule「节拍」一节。简报模板要求把入口那一节与责任分级表贴给写者,交回多一项「圈外发现」;教学技能加心智模型「三级与圈外」;回看记录模板补齐「删掉不可能的路径」「回到建模」两个出口。哨兵的「兜圈」判据收紧到本质:一直在改却没有进展。原来脚本只要一轮有提交、当前行没变就报「可能兜圈」,判据表还写着「连续提交改同一处」,先实现、再补用例这样的正常推进也会命中(评测里新简报两次都多报了这一条)。现在脚本记下每轮的进度标记(当前行、勾上的里程碑数、切片状态),一轮有提交而标记没动只算停住的一轮;连续两轮停住、两轮又改了同一批文件才报,信号列出这些文件。one-lesson-rule 判据表与哨兵简报模板同步,写明顺着推进的连续提交不算。check-repo 第 9 段:入口那一节必须在且带表,skills 下提到「圈外发现」「圈外的问题」的正文行必须链到它(标题行与进度行豁免)。tests/ 147 个用例。攻防评测(虚构项目,十三个场景,新旧技能与「只有 spec 与 plan」共六种配置,上档模型,盲评):单步决策上模型本身大多答对,新规则没有压掉该做的(重点缺陷照修、未列出的消费者照同步、圈外挡住验收时只停一片);评测找出并修掉一处回归(spec 的圈外一行原先不带消费者例外,压缩后有一次把消费者当圈外);哨兵对照里新简报两次都给出「记一行,继续」的正确提醒,旧简报两次都没有。
0.13.0
哨兵从已经定义的不变式出发回看。以前「实现是不是比本质复杂」只看做久了的迹象(用时超预算、提交多、读数变差、改动面大),而为不可能发生的状态写处理与用例往往做得很快,用时看不出。现在这一问有两类证据,各配一行固定提醒。(甲)做久了,提醒照旧。(乙)为不变式排除的路径做功:plan、提交信息、子代理交回件尾部,或进行中切片开工包的「技术细节设计与验证」一节里,主代理或它派出的设计、开发子代理在给 spec 不变式对照或整程包不变式表写明不会出现的状态写处理、分支、用例或补变异用例;证据写不变式编号加提交号或 plan 行,提醒写明这是过度设计、也从根上违背了对不变式的守护,按入口「写代码的四条」第三条删掉。为判(乙),哨兵可以读进行中切片的那一节技术细节,源码与测试仍不读。第三条多几句:可能性以已经定义的不变式为准,不以类型或逻辑写得出来为准;不变式排除的状态不写处理、不写用例,因为那要么是死代码,要么把别处对不变式的违反悄悄兜住;类型强迫时只写最小的一行,差分变异在这一行上存活记「不变式排除」,不补用例;契约声明的正常答复照常处理。one-lesson-rule 的常规出口多一行「删掉不可能的路径」,哨兵看错不变式时主代理在处置里写明哪条不变式允许这个状态。原来正文与模板用「第六问」指这一问,与表里的位置(第五行)对不上,现在一律按问题名称指。哨兵简报模板、回看记录模板、one-lesson-rule/SKILL.md 与 sentinel.mjs 汇报末段同步。tests/ 138 个用例,没有新增:脚本只改了汇报末段的说明文字。
0.12.1
第十三程:pnpm 多包仓库(omne-harness-lite)上试用 0.12.0 时发现的五处缺陷,每处一条先红后绿的用例。一、大仓库:sh() 用 execFileSync 跑 git,缺省 maxBuffer 是 1 MB,changedLines 对整个仓库跑 git diff,基线往前几个提交(跨过几次合并)就报 ENOBUFS,结构读数与差分变异都崩。现在缓冲上限是 1 GiB;给了 --scope(差分变异再加 --project)时,范围作为 pathspec 交给 git diff 与未跟踪文件的列表,只取需要的部分;--scope 仍是字符串前缀,pathspec 把前缀转义后补 *,读出之后照旧按前缀过滤,口径不变。差分变异的「成员外改动 N 个文件」另取文件名(git diff --name-only,输出很小)来数,不因收窄而变。二、Stryker 找不到 runner:被测项目用 pnpm 装 Stryker 时(隔离布局,node_modules/.pnpm/...),Stryker 只在 @stryker-mutator/core 真实位置旁边找 @stryker-mutator/* 插件,找不到 vitest runner,初跑失败(Cannot find TestRunner plugin "vitest")。现在工具写配置时用已解析到的 runner 入口文件的绝对路径写 plugins: [<路径>](Stryker 对绝对路径走 import(),所以写入口文件,不是包目录),入口取包的 exports 的「.」项,没有取 main。三、typescript 7:结构读数与差分变异用 typescript 的 JS 接口按行找函数,7 起是原生实现,npm 包里没有 JS 接口;成员里有 7.0.2、pnpm 存储里有 6.0.3 时每次都得 --ts 指过去。现在没给 --ts 时依次找 Git 根(含往上各级)、--project 成员目录(只有差分变异有这个选项)、Git 根的 node_modules/.pnpm/typescript@*/node_modules/typescript,每处只收有 JS 接口的,存储里按数字分量取最高版本;没有接口的记下继续往后找,不拦住后面的候选(成员里装的是 7.x、存储里有 6.x 时才能自动找到),都没有时退出 2,消息写出找到的路径与版本,说明用 --ts 指到一个 6.x。四、覆盖率报告:被测成员下生成了 coverage/ 的 HTML 报告(prettify.js 等)又没被 .gitignore 忽略时,结构读数把它们当成改动文件。现在改动文件缺省排除任意层级 coverage/ 目录下未跟踪的文件(已跟踪的是源码,照常算;目录名只是带 coverage 的不排除),metrics-model.md 写明覆盖率报告应写到工作树之外或只用 lcovonly。五、check-plan --handoff:四问的答案写成 <待只读核对后填> 仍退出 0,按 0.11.0 占位算没答,实际只认字面的 <>;起点一行把分支和提交号写在反引号里报格式错,报错也没给正确写法。现在整条答案是 <...> 形式都算没答(答案里夹着尖括号的不算占位);起点一行容许分支与提交号各自带一对反引号,报错消息改为「起点一行应为「- 起点:<分支>@<提交号>」,提交号至少 7 位十六进制;分支与提交号可各自带反引号,例如「- 起点:main@0123abc」」。metrics-model.md 与两处 --help 同步。tests/ 138 个用例(0.12.0 是 118,新增 20);真起 Stryker 的 pnpm 布局用例用复制出来的核心造一个核心旁边没有 runner 的存储,修前报 Cannot find TestRunner plugin "vitest"。
0.12.0
第十二程:差分变异支持多包仓库。以前 mutation.mjs 只认 Git 根下的一个 vitest 项目,在根下起 Stryker;pnpm 一类多包仓库的根下常常没有 vitest 配置,每个成员各有一份,工具一跑就退出 2。现在给 --project <成员目录>(Git 根相对或绝对路径,须在根内、是目录)就在成员里认 vitest、找依赖(成员 node_modules、Git 根 node_modules、--stryker-modules、技能目录依次找)、起 Stryker,工作目录与增量指纹按成员;改动行照旧从 Git 根算,只收成员下的文件,抬头写「项目:<成员目录>」,成员外的改动写「成员外改动 N 个文件,不在本轮」。路径只在 Stryker 边界换算:写配置时 mutate 去掉成员前缀,读报告时给文件键加回前缀;抬头、表格、存活清单与 JSON(含 mutate)的路径都相对 Git 根,JSON 顶层多 project(不给为 null)。改动跨几个成员时由调用方按成员各调一次。成员在 Git 根下两层及更深时,Stryker 的容器放成员上两级、名为 .stryker-tmp-<成员目录>-<8 位散列>,沙箱与成员同深度,成员配置与用例里往上走两层及以上的相对路径在沙箱里照样成立,几个成员同时跑也不撞名;只深一层时容器放根下,抬头提醒沙箱深一层;容器跑完与收到信号时都删,没被忽略时提醒按实际名字写。成员的用例导入自己的构建产物(如 dist/)时给 --build-command <命令>:Stryker 10.1.1 建沙箱是复制文件、跑构建、再链 node_modules,构建时还没有依赖,所以工具关掉 Stryker 的链接,把自带的 scripts/sandbox-build.mjs 写成 buildCommand,它先把成员的 node_modules 链进沙箱,再经 shell 跑给的命令;构建失败退出 1,抬头写「测量无效(构建失败)」,JSON baseline.buildFailed。不给这两个选项时行为与 0.11.0 一样。不给 --build-command 时由 Stryker 链 node_modules,它只链实目录,整个 node_modules 是软链时链不进去;给了时包装脚本只链项目顶层的那一个;metrics-model.md 写明。slice-closeout 第 4 步、metrics-model.md「变异」一节与接入槽位「差分变异」一行三处同步。omne 那套工具里另外几条与多包无关的修正(关 vitest preParse、沙箱预检文件级失败、拦 Stryker 对拒绝的重试)不在本版。tests/ 118 个用例。
0.11.0
第十一程:交接点可以跨会话,十条中心思想进教学技能。以前入口「边界」写着这条流只服务一个会话,定义期和交付期默认在同一个会话里走完,交接点核对单的四问只在定义期末尾自问,答案没有落成能交给别人的东西。现在定义期与交付期可以在两个会话里顺序完成:设计会话在交接点核对单过了之后,照新模板 single-session-dev-flow/handoff-pack-template.md 写一份交接信息包,九节(目标、依据、不变式、验收标准、边界、起点与风险、已定事项、只有人能定的待决、四问),只放钉在一个提交上的正式文档指针和当场可核的几项,四问的答案写在包里;交付会话从包开工,开工动作第 4 条写先核包、对照包答四问、从第 7 步开工,包里答不出的地方就地提问、其余先做。仍不做多会话并行协作。接入槽位多一格「交接信息包放哪」,没填时放项目 tmp 下本程目录的 handoff.md,上下文包模板、教学技能与设计文档三处同步。check-plan 多 --handoff <文件>:核抬头、九节在且顺序对、起点一行是「分支@至少七位十六进制提交号」、四问四条都有答案(<> 占位算没答),缺陷格式与退出码和 --plan、--spec 一样,三个选项可以任意组合,至少给 --plan 或 --handoff;用例把模板实例化后核一次,模板与核对器钉在一起。teach-pqw-skills/mental-models.md 末节「AI 主导研发交付的心智」:出自 Anthropic 2026 年 10 月的两篇文章,主线是人主导时的流程防人、AI 主导时的流程要防代理,十条讲人的注意力最贵、按失败模式配检查、防代理的检查留而协调物件删、风险由改动决定、人做五件事、审查前移且两轮封顶、合入前只拦确定性检查并跑在合并结果上、合入后靠回退兜底、少全局状态少分支、教训进结构;写代码那一层链到入口的四条,不另写。tests/ 101 个用例。
0.10.0
第十程:写代码的四条进入口。ub-mode 的核心心智以前散在五处、每处半句,而且都离入口远:「先做对再做好」在收口技能里,实现写完才读到;「做好」没有单独一轮的位置;「需要优化时不回避」没有写;「找本质解」只在哨兵报警时出现;派出去的写者一条都看不到。现在 single-session-dev-flow 开头一节「写代码的四条」是唯一正文:先做对;再做好一轮(不加能力,只改实现,spec 写明的性能要求不退化);不过度设计、不提前优化,但 spec 有性能要求或测量显示不满足时优化属于做对;找本质解(同一前提下两次修补都失败就写出前提并推翻它,切片做久了先怀疑建模)。入口的 description 追加一句点出四条,宿主注入技能描述时就看得到,加载条件不变。切片循环写成开工包、做对、做好一轮、收口、汇报、切片清理;plan 模板的开工包与收口、开工包模板、收口记录模板各有「做好一轮」一项;check-plan 多一类缺陷「切片 NN 收口缺「做好一轮」」,所以 0.9.0 及以前写的 plan 会各报若干条,补一行即可。第四条接到两个出口:哨兵判「局部兜圈」时结论带固定提醒,slice-closeout 的两轮不收敛与 delegate-brief 的升级都先按第四条做;简报模板「规格」节要求把四条原文贴给写者。其他提到这几条的地方(slice-closeout、teach-pqw-skills 四处、spec 模板)改成一句加链接,check-repo 第 8 段核:入口以外的技能正文里提到「先做对」「再做好」「找本质解」的行必须链到入口那一节。tests/ 98 个用例。
0.9.0
第九程:收尾小事。结构读数多两处看得见:改动的测试文件里改动行所在、回调体内没有断言调用的用例列在表后一节「没有断言的用例」,JSON testsWithoutAssertions,用例认 test/it 链的调用、断言认被调用者最左标识符匹配 ^(assert|expect)$,--assert-pattern 可换,认法只在 TypeScript 适配器里;只改了顶层声明、改动行不在任何函数里的源码文件进「未覆盖的改动文件」,原因写明。插件校验的两条警告(根 CLAUDE.md 不作插件上下文、没有图标)在 DEVELOPMENT 写成预期并给了理由;旧引擎的 TRIVIAL_LINE_RE、--no-tests-pattern 实现与 SIGINT 用例已随 0.8.0 删除,本程只确认残留为零。
0.8.0
第八程:Stryker 成为唯一的变异引擎。slice-closeout 的 mutation.mjs 删掉内建引擎与它的位点生成、预算、覆盖门控、历史沿用、运行中自适应:--test、--engine、--lcov、--budget、--history、--no-tests-pattern、--load-ceiling 退役,给了退出 2 并写原因;项目不是 vitest 或找不到 Stryker 退出 2 并写装法,不再回退。超时复核:第一轮有 Timeout 的变异体时再起一轮,只打它们所在的整行,一个进程、时限放宽(缺省第一轮 timeoutMS 的 4 倍且至少 60 秒,--recheck-timeout 可改)、不进增量,结果按位点 id 并回(两轮之间 Stryker 重新编号),Killed、Survived 改裁定、原因记 recheck,仍超时保持;抬头在计数后写「复核 N(超时转杀死 a、存活 b、仍超时 c)」,JSON 顶层 recheck,--no-recheck 不起第二轮,第二轮失败写「复核未完成」且第一轮裁定不动。顺手修了单元表没有 <module> 时顶层变异体映射崩掉。本仓库自己的测试从 node:test 迁到 vitest(根 package.json 钉 vitest 4.1.11、覆盖率插件、Stryker 10.1.1 与 typescript,npm ci 后 npx vitest run,--coverage 出 coverage/lcov.info),收口的差分变异由本工具自己跑。量前后(同一仓库、同一范围 skills/slice-closeout/scripts):0.7.0 内建引擎一个切片 106 个位点、15 分钟预算只跑完 36 个;0.8.0 的 Stryker 切片 02 308 个变异体 70 秒分数 90%,切片 03 233 个变异体 47 秒加复核 43.5 秒分数 89%,复核 1 仍超时 1。命令面文件只在子进程里跑,Stryker 与 lcov 都看不见它的覆盖,一多半变异体无覆盖:命令面要薄、逻辑进 lib。哨兵多一问「实现是不是比本质复杂」:切片用时超预算、同一切片提交过多、新函数读数变差或改动面远大于交付的一句时,消息带一行固定提醒,各切片的实现本质上都简单,做久了是没找到本质解,先问过度设计、不优雅、缺的数理建模、形式化建模、领域设计、OOP 建模(SOLID);主代理多一个出口「回到建模」。cleanup 正文重写:清理只判断还要不要,不要的直接删、要的原地留,Git 历史与汇报件就是留痕,所以不打包、不在文档里写「待删」「已删」、不先汇报再删;清单模板收成一程交付声明五项,slice-closeout 的收口清单与正文同口径。metrics-model.md「变异」「资源」两节只写一种引擎,slice-closeout/SKILL.md 第 4 步、两处接入槽位、DEVELOPMENT、STRUCTURE、两份 README 同步。tests/ 91 个用例,npm ci 后不设环境变量全部执行。
0.7.0
第七程:差分变异换 Stryker 引擎,用 vitest 的项目一轮耗时从「位点数乘整套测试一遍」降到「初跑一遍加每个变异体只跑碰到它的用例」。slice-closeout 的 mutation.mjs 多 --engine auto|stryker|builtin(缺省 auto)与 --stryker-modules <目录>(也读 PQW_STRYKER_MODULES):项目有 vitest 配置或声明了 vitest、且按「项目根 node_modules、指定目录、技能 scripts/node_modules」的顺序找得到 @stryker-mutator/core 与 vitest runner 时用 Stryker 引擎,否则用内建引擎,抬头在基线说明之后写一行「引擎:Stryker <版本>(vitest)」或「引擎:内建(<原因>)」,JSON 顶层加 engine;显式要 Stryker 而条件不满足退出 2 并写装法。新 scripts/lib/stryker.mjs:范围变 mutate 条目(改动行所在单元自己的全部行写成 路径:起-止,与内建引擎的范围一致;点名文件整份)与配置(vitest runner、related: false、逐条覆盖、并行度写进 concurrency、JSON 报告器),在项目根起 Stryker,输出进系统临时目录工作目录的日志、进度行转到标准错误,读 JSON 报告映射回同一个位点模型(单元按行找、原文按位置切、类别取变异器名去后缀;Killed→杀死、Timeout→杀死(timeout)、Survived→存活、NoCoverage→无覆盖、RuntimeError 等→未跑带原因),抬头、表格、存活清单、测量无效、未覆盖段与 JSON 字段两种引擎一致。Stryker 引擎不改项目文件,只写 .stryker-tmp(没被项目忽略时抬头提醒;跑完删,被 SIGINT、SIGHUP、SIGTERM 结束也删,只有被强杀时留下)与系统临时目录;报告里出现映射表没有的状态时测量无效;baseline.seconds 是初跑用时,从 Stryker 日志取;初跑失败退出 1,抬头写「测量无效(Stryker 初跑失败)」并给日志尾;--test 可省略,--budget 不适用(抬头写明)。增量:配置开 incremental,增量文件与指纹记录(工具版本、「vitest@<版本> + <配置文件>」、测试文件摘要、Stryker 版本)在工作目录,指纹变了 force 整轮重跑,抬头写「沿用 N」或「增量:已开,本轮没有沿用」,--history 在 Stryker 引擎下写不适用。依赖钉在 skills/slice-closeout/scripts/package.json(Stryker 10.1.1、vitest-runner 10.1.1、vitest 4.1.11、typescript 6.0.3),npm ci --prefix 装到技能目录,check-repo 的扫描跳过 node_modules。量前后(同一基线、同一范围,三条用例的 vitest 小项目改两行):内建 5 个位点 3.5 秒分数 40%,Stryker 20 个变异体 4.3 秒分数 75%(增量第二轮 2.6 秒、沿用 20);小项目上两种引擎耗时相当,差距随测试时长与位点数放大:本仓库自己整套测试约 50 秒,一个切片 106 个位点内建引擎 15 分钟只跑完 36 个。两种引擎的变异器不同,位点数与分数不能跨引擎比。本仓库自己的测试仍是 node:test,自跑用内建引擎。第六程顺手的优化:汇报件渲染「一程目标与前后差别」节开头的说明段;哨兵在 check-plan 给出结果时不再重复报「处置编号断号」;plan 模板进度更新规则第 7 条「时刻取自时钟」;spec-and-plan 正文写改文件先读后写。metrics-model.md「变异」「资源」两节、slice-closeout/SKILL.md 第 4 步、两处接入槽位、DEVELOPMENT、STRUCTURE、两份 README 同步。tests/ 120 个用例,真起 Stryker 的用例在 PQW_STRYKER_MODULES 指向装好的模块时执行。
0.6.0
第六程:plan 与汇报件讲人话,文档不过期。plan 模板多两层给人读的叙述:开头一节「一程目标与前后差别」,产品层写用的人得到什么、以前为什么不顺、现在怎样,技术层写系统哪一块的工作方式变了、以前怎么跑现在怎么跑;每个切片一项「交付这片的意义」,分对用户与对系统两句。写法是展开的完整句子,不缩略,术语第一次出现要解释。plan 多一节「文档维护表」:一程里每份给人看的文档给谁看、什么时候更新、只动哪一节、怎么判断过期、最近更新;两条新规则:结构是契约、更新一律局部编辑不整份重写,每次更新文档改维护表该行的最近更新。spec-and-plan 新脚本 check-plan.mjs 按模板核 plan 与 spec 的骨架(必需节与顺序、进度行与处置行格式、切片表与维护表表头、每片的意义段与开工包与收口、处置编号连续),退出 0/1/2 并逐条列「文件:行 缺陷」,收口最后一步、哨兵每轮、汇报件生成前各跑一次。哨兵脚本 sentinel.mjs 多算「文档陈旧」信号:进度行 head 不是 HEAD、处置断号、汇报件早于最近提交、plan 结构不合模板、维护表某行最近更新落后而最近提交改了它,汇报多一节「文档」;回看记录、哨兵简报与正文的四问变五问「给人看的文档有没有过期」。汇报件 build-report.mjs 把 plan 的两层叙述渲染到网页开头「这程为什么做」,切片行下面带该片的意义,顶部写结构核对结果;plan 没写时写明而不是留空。收口清单最后一步改成「按文档维护表逐份核对并更新,跑 check-plan」。tests/ 101 个用例。
0.5.0
第五程。读数口径:测试文件与声明文件不进改动函数表,列进「未覆盖的改动文件」带原因;覆盖率三态(有值、未提供、无数据),coverage 为 null 时带 coverageReason,不再把「不知道」写成 0;报告里找文件照 crapper,全等优先、整段后缀匹配恰一个才取,多个候选不猜;抬头与 JSON warnings 记三条可信度警告:报告早于改动文件、改动函数全部零命中、多个文件匹配。与基线比:每个改动函数带基线版本的圈复杂度与认知复杂度和趋势(new、up、down、same),变差 = 过线且 new 或 up;表格全列、变差标「!」排前,表尾写「要交代 n 个变差;另有 n 个过线但没有变差,照列不解释」,slice-closeout 正文与收口清单改成只逐条交代变差的。变异不说错:基线不通过或一个位点都没执行时 valid 为 false,抬头写「测量无效(原因)」且不出四类计数;改动了却没有位点的段(模块级语句、没有可替换位点的单元)单列「没有位点的改动段(不进分数)」,空行与注释行不算。历史沿用:位点 id 改为 文件:单元:单元内偏移:类别:替换,文件上方加行不影响沿用;结果 JSON 带 fingerprint(工具版本、测试命令、测试文件摘要),历史的指纹任一项不同或没有指纹整份不沿用并写明原因,抬头写「沿用 N」;新 scripts/lib/version.mjs 的 TOOL_VERSION 由 check-repo 第 7 段核与 plugin.json 一致。改写保护:写入变异体前先把原文与变异体落到系统临时目录的还原日志,还原后删,被 SIGKILL 或断电留下的日志在下次启动先还原并打印,文件在那之后被人改过就不覆盖、退出 1;写入前核文件仍是原文、还原前核文件仍是变异体,不是就不覆盖,打印「文件在变异期间被改动」退出 1;SIGHUP 与 SIGINT 一样先还原,退出 129。热点点名:--files <路径,…> 让点名文件的全部有名单元出位点,不论改没改,抬头写「(点名 N 个文件)」,位点带 pinned;slice-closeout 第 4 步写修复轮用 --base <上一轮收口头> 收窄、判据与状态机文件用 --files 点名,接入槽位两行同步。汇报件 report.mjs 函数表加带位、原 → 现、变差三列,变异段写测量无效、超时与未覆盖段。tests/ 91 个用例。
0.4.0
第四程。哨兵改成便宜档的只读子代理:持有 spec、plan 与整程上下文包,每 45 分钟自己醒来取工作树事实,判偏离、兜圈、腐化与子代理健康,写回看记录并给主代理发十行以内的消息,主代理在停顿点写「处置 n」回 plan;one-lesson-rule 正文、hosts.md 三宿主派法(Claude Code 一条在本程真实验证)、回看记录模板、delegate-brief 的哨兵简报模板与 scripts/sentinel.mjs 的增量摘要和无处置信号一起落地。技能正文宿主无关:35 处「调用 Skill 工具加载」改成「加载技能」,check-repo 反向核宿主工具名,只有 hosts.md 例外。差分变异有了资源模型:按 CPU 数、可用内存与 --other-heavy-tasks 算份额与并行度,交给测试命令的 PQW_TEST_WORKERS 与 VITEST_MAX_WORKERS,子进程 nice 10,运行中按负载比降升档并记机器繁忙,JSON resources 节记容量、份额、自适应与自身开销,--help 是教程。读数可信:纯删除也算改动行,显式基线不是 HEAD 祖先时改用合并点并记 baseGiven,git 只认 --repo;「没跑测试」模式带词界并在基线上自检,被信号结束记 notRun(crashed),类型位置不出位点,超时单列,存活清单只陈述事实;认知复杂度链尾 else 补记 1,适配器头注释钉上 crapper 6fd92c4 与 mutator a5a0cb8,读数每个函数带 band(缺省 CC 10/12、CRAP 30,--cc、--crap 可覆盖),JSON 记 thresholds。tests/ 76 个用例。
0.3.1
第三程。四个 CLI(metrics.mjs、mutation.mjs、build-report.mjs、demo-append.mjs)的逻辑拆进各自 scripts/lib/ 的具名函数,命令面只剩参数、装载、信号与退出码,模块级圈复杂度从 17 到 74 降到 7 到 8;行为逐字节不变,原用例未改。拆完用变异工具打自己:三组 lib 的分数 97%、90%、83%,存活项逐个写了等价说明。新增 tests/*-lib.test.mjs 直打函数的用例,共 51 个。check-repo.mjs 的禁词与破折号扫描扩到 .mjs 与 .html(tests/ 与它自身免检)。适配器 sites 补一条用例:只有逻辑非是 negation 位点。DEVELOPMENT.md 写上覆盖率与自量命令。
0.3.0
第二程。slice-closeout 自带结构读数与差分变异工具:先写与语言无关的模型 metrics-model.md(单元、判定、覆盖、CRAP、位点、裁定,取自 unclebob/crapper 与 mutator,0BSD),核心 lib/core.mjs 只认模型对象,lib/adapter-typescript.mjs 把 TypeScript 与 JavaScript 源码变成单元与位点。metrics.mjs 只摘改动函数的圈复杂度、认知复杂度与 CRAP,基线只认 Git ref;mutation.mjs 只打改动单元的位点,覆盖门控、历史沿用、时间预算、「没跑测试」复跑、SIGINT 还原。progress-artifacts 自带 build-report.mjs 网页汇报件与 demo-append.mjs 增量 demo。新增 tests/。接入槽位的「结构读数」「差分变异」两行改为只填覆盖率文件、测试命令与范围。已知整理项:三个 CLI 的逻辑写在模块层,模块级圈复杂度 67 到 74,下一程拆成函数。
0.2.0
新增 teach-pqw-skills:教人用这套流的技能,自带心智模型与哲学、谁做什么、提示怎么写三份参考。全部 description 按 pstack 与 Matt 的指针写法重写:环节号领头、人会说的原话作触发、一条不加载、容易混的互指,学习结论在 design/description-and-entry-study.md。入口技能加开工动作:复述目标、把 13 个环节写进会话任务清单并给跳过留理由、「新任务」重判;规则按主题分组,末尾加容易混的环节。
仓库文档:README 的流程图改为 assets/flow.svg,加徽章;新增 README_EN.md、CONTRIBUTING.md、DEVELOPMENT.md、SECURITY.md、CODE_OF_CONDUCT.md 与 .github/ 的 PR、issue 模板。技能行为无变化,版本不动。
0.1.0
第一程:十四个发行技能补全正文;十七份模板与三个脚本(哨兵、汇报件目录、清理)随技能发行;clear-writing 与 write-agents-md 两个元技能迁自 omne-harness-lite;新增 scripts/check-repo.mjs 一致性检查。确定性验收品味写进收口、落盘与派发三个技能,不做对抗性评审。外部依赖钉 pstack 0.9.132、Matt 1.3.2、ub-mode 3da62bf。本程自身按这条流 self-dogfood,spec 与 plan 用本仓库模板写成。
0.0.0
初始化:总入口技能与十三个环节技能的骨架,另有两个元技能,正文待逐环节确认。