-
起因:增量改一个功能仍会跑全量 e2e——用户改的功能与被跑的用例(如打印按钮那条) 毫无关系。实测 test-gate 占全流程墙钟 13.3%,且后端每个模块的 scripts/test.mjs 内部还会各跑一遍全量 playwright。 coding.mjs 新增 args.testScope(缺省 'affected',逃生口 'full'): - **只收窄 e2e 段**。build / lint / 后端单测+集成 / 前端 vitest 一律仍全量——它们是 分钟级的,却是编译期与逻辑回归的第一道网,砍掉省不下多少却漏掉最常见的连带破坏。 - 前端阶段 test-gate:范围 = 本轮待跑 FE 各自 plan 里 `测试先行类型 = e2e` 的 test_file 并集(verify 段早有同款推导,line 659);取不到则退冒烟集。 - 后端模块 test-gate(本轮无 FE 改动):退到 frontend/e2e/__smoke__/ 冒烟集。 不跳过 e2e 段——它同时是起栈健康检查。 - 首跑(全新项目)时「本轮待跑 FE」天然等于全部 FE,affected 与 full 重合;收窄只在 /add-req 后的增量重跑里真的生效,这正是它存在的场景。 载体是 env ERP_E2E_SCOPE,**scripts/test.mjs 一个字未动**——它的 setup→build→lint→ test→e2e→promote→drop 是迁移晋升链路的契约,且模板改动不落已生成项目(见 preflight 硬门);env 经 spawnSync 天然继承到 playwright 进程,前后端两条路径同一个开关。 消费端由 fe-skeleton 生成的 playwright.config 实现(未设=全量,绝不默认收窄), 同时生成与业务解耦的冒烟集;state 判据同步加严,存量项目会重跑一次骨架 stage 补齐。 防假绿(收窄的唯一真风险):范围推导错的表现是「0 条用例 + exit 0」,与真绿不可区分。 GATE_SCHEMA 加 e2eScope/e2ePassed,编排层 guardEmptyE2e() 硬判——green 且明确 0 条一律 翻 red 走既有 retry/仲裁链。module-report 被要求如实记录本次范围,禁止拔高成「全量回归」。 新增 /erp-workflow:full-test(skills/coding/full-test):跑 scripts/test.mjs 全链 + 显式清空 ERP_E2E_SCOPE 的全量 e2e,出 full-regression-<日期>.md 证据并提交。 前置硬门:工作树干净(绿后会晋升迁移到源库)、不与正在跑的 coding 流程撞端口。 后台子进程 + 回合内轮询;只跑测试、不改源码、红了只报告不修复。 代价明说:增量轮里跨功能连带回归(改共享组件 / router / 全局状态 / API 契约 / DB 迁移 打破没动过的功能)不再有网,由 /full-test 按需兜底。逃生口 testScope: "full"。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-
步骤 5 原本只处理 changed 单元("new 单元无 tag,跳过"),但新单元挂靠的 模块可能已 done: routerPrompt 判 done = 里程碑字段匹配 且 tag 存在 → 模块已 done 时 reqs 为 空数组 → coding.mjs 的 todo = routed.modules.filter(m => !m.done) 把该模块 整个剔出待跑列表 于是新 REQ 挂进已有模块时不报错、不 halt,就是永远不跑。新 FE 行挂进已打 milestone/frontend-phase 的前端阶段同理。 步骤 5 改为六个显式分支:changed 处理功能级 tag + 里程碑,new 只处理里程碑; kind=proto(new) 显式声明为基线建立、不作废任何 tag(原先只在步骤 3 旁注里)。 kind=proto(changed) 另收窄重跑范围:__prototype__ 是聚合单元,只能说明"原型变了", 原先据此删全部 req-done/FE-*,改一个原型文件就重跑整个前端阶段。改为先用 git log -1 -- .req-ledger.json 取上次台账 commit 作基线、git diff --name-only 还原到文件级,再经 AskUserQuestion 确认映射到受影响 FE,只删这些 tag;取不到 基线/diff 为空/用户选"说不准"一律回退整体重跑,语义同改动前。 coding.mjs 无需改动——runPrototypePreview / featureLoop / runBehaviorGate 本就按 feItems 伸缩,粗粒度完全来自 add-req 删 tag 的范围。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-
与 quick-field 成对:纯前端直改 frontend/(lint/类型检查 + grep 自检, 不起栈、不跑行为门/e2e),可见布局变化同步 prototype/、按需更新 docs/08 §三 FE 行文字,台账重基线但绝不作废 req-done/milestone tag——前端阶段 不重跑。硬边界:只消费 docs/05 既有端点、不新增页面/路由/FE 行,超界 回落 /add-req。 同步:docs/08 §四 标题泛化为「微改待验清单(quick-field / quick-ui)」 两通道共用(quick-ui 含旧标题迁移指令);quick-field/add-req 分流提示 互指;plugin.json 注册(10→11 skill);README 目录树/入口表(4→5)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
保 schema SSoT 不缩水(V_n ALTER + docs/03 同步 + validate-ddl fail-closed), 代码主会话直改 + grep 清单/轻量编译自检;台账 req-ledger 重基线但绝不作废 req-done/milestone tag——Router 视一切已完成,不冷起栈、不跑测试门/行为门。 未过行为验收的字段登记 docs/08 §四 待验清单,攒批人工勾销。 硬护栏:仅追加式 ADD COLUMN(可空/带 DEFAULT)+ 既有链路多带一个字段, 超界回落 /add-req;步骤 0 要求台账干净(防全量重基线吞掉其他待处理增量); 禁手动灌库(源库 Flyway 托管,绕 history 会重复 apply 报错)。 同步:plugin.json 注册(9→10 skill)、README 目录树/入口表、add-req 顶部分流提示。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
add-req 的变更检测只哈希 docs/01 REQ 卡片与 docs/08 §三 FE 行文字,从不读 prototype/,而原型才是前端布局/页面/交互的权威。改原型但 FE 行文字不变时 台账无变化 → Router 跳过前端 → 原型改动永不重编。 - req-ledger.mjs:collectProtoUnit 把全部 prototype/**/*.html 聚成单一 __prototype__ 单元(kind=proto),relpath 归一+排序保证跨平台哈希稳定; 无 .html 不产生该单元。接入 computeUnits。 - add-req SKILL:步骤 1 说明 kind=proto + 老项目升级建基线语义;步骤 5 新增 proto 作废分支(删全部 req-done/FE-* + milestone/frontend-phase + 复位 §三里程碑,整体重跑前端阶段);横幅与 frontmatter 同步。 - README:lib 说明加 prototype。 - 测试:新增两用例证明改/删原型内容能被 diff 识别(FE 行文字不变也检测到)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-
- bestEffortAction(prompt, {label, phase, okMsg, failTag, errTag}):收敛 recordResume / ensureLedgerBaseline 逐行同构的 try/catch 包裹(失败/异常只 log 绝不阻断主流程; ≠ runAction:不经 adjudicate、绝不 halt)。日志文案与重构前逐字一致(errTag 区分 失败/异常两条前缀),返回布尔供水位线判断。 - decisionDigestMd helper 消除决策摘要模板的字节级双份拷贝;flushedCount 水位线 (仅 per-module flush 成功才推进)使 loop-end 条目只补「未被逐模块条目覆盖的增量」 ——N 模块全绿不再每条决策在 RESUME.md 写两遍;flush 失败时 loop-end 兜底补记保留。 - add-req 步骤 0/1 合并为单次 scan(scan 输出本就同时含 ledgerExists 与 new/changed/removed,重复扫描纯冗余);删步骤 6 无操作性说明尾句。 -
- mergeAlterStatements 对 MODIFY/CHANGE/RENAME/ALTER/DROP(除 DROP FOREIGN KEY, 外键维度已移除故对称放行)登记 unsupportedAlters;CLI 非空即 exit 1 并列出子句。 此前静默跳过导致「migration 改了列但 docs/03 未同步」绿灯假阳性——恰是闸门最该抓 的场景。未 CREATE 的表同样登记(检测先于 if(!t) 跳过)。parseDDL(text, opts) 不传 收集器时行为不变(向后兼容)。 - parseDDL 三遍扫描统一单一抹除底稿(剥注释+抹字面量一次完成,REGEX-3 全覆盖; blankStringLiterals 长度不变故偏移可复用);顺带修掉第一遍在未抹除底稿上扫描、 字面量内 "CREATE TABLE ghost(...)" 产出幽灵表的缺口。 - 测试 52→58:全部拒绝臂参数化覆盖(RENAME/ALTER COLUMN/DROP INDEX/DROP PRIMARY KEY)、混合 ADD+MODIFY(ADD 仍并入且登记)、CLI exit-1 冒烟(spawnSync)、幽灵表 回归、DROP FOREIGN KEY 容忍。 - add-req SKILL.md 闸门说明同步硬拒语义,消掉悬空的「见 P2」引用。
-
- auto-continue.sh:sentinel 检测只认 transcript 的 assistant 行(修自匹配 bug—— block reason 自带 [ERP-HALT] 字面量、下次 Stop 命中自己,钩子实际只能续跑一次); 窗口 60→200 行,兜住「横幅在前、诊断在后」的回合;删 4000B 字节增长启发式 (与 PostToolUse 清零重复且方向性错误——纯文字空转一轮也超 4000B,上限永远到不了); reason 文案去掉对已删 skill 链的指挥与 [ERP-HALT] 字面量。 - [ERP-HALT] 补全到全部刻意停下点(合计 12 处打印点):add-req 4 处(前置拦截/ 基线停下/空增量/完成横幅)、coding-start 步骤 1/2、plan 阶段 5 处(plan-start 终结闸 / downstream-gen A5 / db-design-gen 审阅 / scope-lock 骨架 / project-init 安装失败);coding-start :130 说明文字去字面量防误触发。 - StopFailure:官方语义为「输出与退出码被忽略、无 decision 控制」(无法在钩子层 自动续跑;核实于 2026-06-11 code.claude.com/docs/en/hooks.md)。接线 log-stop-failure.sh:记录中断时间与 error_type 到 $TMPDIR/erp-stopfailure.log, 供人工/外部 watcher 据此续跑。 - coding.mjs preflight:起跑线按 docs/04 § 零探测 node/JDK/DB 客户端/测试入口, 工具链缺失带安装/配置命令的诊断 halt——不再拖到 test-gate 才爆、白跑几十分钟编码。
-
P1#2 — validate-ddl 支持增量 migration: - parseDDL 新增第三遍 mergeAlterStatements:ALTER TABLE ADD COLUMN / ADD [UNIQUE] INDEX|KEY / ADD PRIMARY KEY 并入对应表(仅追加式, MODIFY/CHANGE/DROP/RENAME 不处理;并集与文件顺序无关)。 - CLI 接受多个 DDL 文件:node validate-ddl docs/03 sql/migrations/V*.sql, CREATE + 各 V_n 的 ALTER ADD 并集 ↔ docs/03 累积 SSoT 做 4 维比对。 - add-req SKILL 新增「增量 DDL 校验(fail-closed)」闸门,替换原「多 migration 不适用」说明。 - 7 个新测试(含 DEFAULT 字面量里的 ALTER 文本不被误吃);52/52 通过。 P1#3 — coding 首跑自动建需求台账基线: - coding-start 透传 pluginRoot;coding.mjs ensureLedgerBaseline() 首跑若 .req-ledger.json 缺失则 commit 基线(幂等、best-effort、缺 pluginRoot 静默跳过), 使日后 /add-req 能识别增量、免空跑。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-
P0 — add-req 从不 git-commit 自己的产物,导致工作树脏、coding-start 起 coding.mjs 时撞「工作树必须干净」前置(HALT 或被误并进功能分支): - 步骤 0 基线:写 .req-ledger.json 后 git add+commit - 步骤 6:把本次全部增量产物(docs/01/02/03/05/08 + sql/migrations/V_n + .req-ledger.json) 在当前(默认)分支统一 git commit,并用 status --porcelain 复核工作树干净 P1#1 — RESUME.md 原先只在主循环末尾写,硬中断(进程被杀)到不了写入点 → 本次运行零 handoff: - 每个模块 runMilestone 落定后即 best-effort 追加一条「✅ 模块完成」(含本模块自主决策摘要), 按 decStart 水位线切出本模块决策;使硬中断也能复盘已完成到哪、各模块做过哪些假设 - loop-end 的 halt / 全完成汇总条目保留(halt 原因是 per-milestone 无法捕获的) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-
初始 Plan 完结后追加/修改需求时,只跑增量、不必整仓重跑。 - lib/req-ledger.mjs(+单测):对 docs/01 REQ 卡 + docs/08 §三 FE 行算 sha256 内容哈希, 对比 .req-ledger.json,scan/commit 出 new/changed/removed/unchanged - skills/plan/add-req:新增 user-invocable 增量入口。基线→检测→校验真实数据→ A3-delta(写 V_n migration + 同步 docs/03,永不改 V1)→A5-delta(docs/05/02/08)→ 作废 changed 单元的 req-done/milestone tag→提交台账。Router 无需改动,缺 tag 即重跑 - 变更识别靠内容哈希(非仅 tag 缺失):改过的老 REQ 也能认出并作废其 req-done, 否则 Router 会跳过它——OpenSpec delta 思路的零依赖落地 - 首跑无台账则先建基线,避免把存量误当新增重跑整仓 - plugin.json 注册第 9 个 skill + 版本 0.2.0→0.3.0;CLAUDE 模板 Schema 演化补增量 V_n 规约 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>