sillyspec 3.29.4 → 3.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/.claude/skills/sillyspec-auto/SKILL.md +54 -54
  2. package/.claude/skills/sillyspec-brainstorm/SKILL.md +2 -2
  3. package/.claude/skills/sillyspec-commit/SKILL.md +1 -1
  4. package/.claude/skills/sillyspec-flow/SKILL.md +57 -0
  5. package/.claude/skills/sillyspec-quick/SKILL.md +18 -116
  6. package/AGENTS.md +38 -20
  7. package/SKILL.md +9 -3
  8. package/assets/command-cards/flow.md +32 -0
  9. package/assets/command-cards/run-archive.md +26 -0
  10. package/assets/command-cards/run-brainstorm.md +33 -0
  11. package/assets/command-cards/run-execute.md +29 -0
  12. package/assets/command-cards/run-plan.md +27 -0
  13. package/assets/command-cards/run-quick.md +17 -0
  14. package/assets/command-cards/run-verify.md +29 -0
  15. package/assets/command-cards/status.md +27 -0
  16. package/package.json +2 -1
  17. package/packages/dashboard/server/executor.js +2 -1
  18. package/packages/dashboard/server/parser.js +7 -7
  19. package/r7-test-env/README-R7-TEST.md +93 -0
  20. package/r7-test-env/demo-project/lib/calc.js +6 -0
  21. package/r7-test-env/demo-project/package.json +1 -0
  22. package/r7-test-env/demo-project/test.js +10 -0
  23. package/r7-test-env/prompt-R7-SMOKE.md +41 -0
  24. package/r7-test-env/sillyspec-r7.cmd +3 -0
  25. package/round4/account.mjs +98 -0
  26. package/round4/b1-analyze-task08.mjs +40 -0
  27. package/round4/b1-b1-target-validation.md +32 -0
  28. package/round4/b3a-prompt-audit-result.md +66 -0
  29. package/round4/b3a-prompt-audit.mjs +89 -0
  30. package/round4/brief-autocompact.md +34 -0
  31. package/round4/brief-session-replay.md +50 -0
  32. package/round4/deep-read-synthesis.md +38 -0
  33. package/round4/extract-full.mjs +38 -0
  34. package/round4/extract-timeline.mjs +43 -0
  35. package/round4/find-sessions.mjs +13 -0
  36. package/round4/full-r4-l.md +4707 -0
  37. package/round4/full-r4-o-l.md +4300 -0
  38. package/round4/full-r4-os.md +1681 -0
  39. package/round4/full-r4-sf.md +4255 -0
  40. package/round4/full-r4-sq.md +1734 -0
  41. package/round4/gate-audit-relay-receipt.md +30 -0
  42. package/round4/gate-value-audit.md +52 -0
  43. package/round4/optimization-plan.md +165 -0
  44. package/round4/prereg.md +67 -0
  45. package/round4/prompt-R4-L.md +63 -0
  46. package/round4/prompt-R4-O-L.md +59 -0
  47. package/round4/prompt-R4-O-S.md +56 -0
  48. package/round4/prompt-R4-S-F.md +60 -0
  49. package/round4/prompt-R4-S-Q.md +66 -0
  50. package/round4/r4-final-report.html +347 -0
  51. package/round4/r4-os-timeline.txt +297 -0
  52. package/round4/r4-sf-timeline.txt +738 -0
  53. package/round4/r4-sq-timeline.txt +322 -0
  54. package/round4/r4l-timeline.txt +793 -0
  55. package/round4/r4ol-timeline.txt +729 -0
  56. package/round4/r4sf-timeline.txt +852 -0
  57. package/round4/r5-scenario-matrix.md +46 -0
  58. package/round4/result-S.md +171 -0
  59. package/round4/result-final.md +46 -0
  60. package/round4/result-quality.md +63 -0
  61. package/src/change-list.js +9 -0
  62. package/src/classify-change.js +6 -0
  63. package/src/command-cards.js +74 -0
  64. package/src/commit-guard.js +2 -0
  65. package/src/config-schema.js +64 -12
  66. package/src/contract-matrix.js +26 -5
  67. package/src/db.js +35 -4
  68. package/src/decision-distill.js +9 -3
  69. package/src/diagnostic-codes.js +2 -1
  70. package/src/docs-check.js +1 -1
  71. package/src/doctor-diagnostics.js +44 -2
  72. package/src/flow-draft.js +748 -0
  73. package/src/flow-parity.js +236 -0
  74. package/src/flow-review.js +184 -0
  75. package/src/flow.js +1492 -0
  76. package/src/foreign-declared.js +17 -1
  77. package/src/fr-index.js +396 -22
  78. package/src/fs-atomic.js +5 -1
  79. package/src/git-helper.js +2 -2
  80. package/src/greenfield-bootstrap.js +98 -0
  81. package/src/handoff.js +120 -7
  82. package/src/hunk-attribution.js +191 -0
  83. package/src/index.js +602 -21
  84. package/src/init.js +25 -8
  85. package/src/knowledge-classify.js +47 -1
  86. package/src/knowledge-digest.js +162 -0
  87. package/src/knowledge-quicklog.js +246 -0
  88. package/src/machine-draft.js +128 -0
  89. package/src/machine-interface.js +194 -7
  90. package/src/mcp-server.js +1 -0
  91. package/src/module-impact.js +51 -22
  92. package/src/module-resolve.js +3 -1
  93. package/src/preview-progress.js +160 -0
  94. package/src/progress/change-registry.js +11 -3
  95. package/src/progress/shared.js +3 -2
  96. package/src/progress.js +56 -13
  97. package/src/quicklog.js +44 -6
  98. package/src/redomain.js +147 -0
  99. package/src/review-material-pack.js +204 -1
  100. package/src/run/archive-distill.js +4 -2
  101. package/src/run/bg-sync.js +67 -0
  102. package/src/run/command.js +127 -10
  103. package/src/run/complete-handlers.js +363 -73
  104. package/src/run/complete.js +356 -74
  105. package/src/run/gate-snapshot-ledger.js +213 -0
  106. package/src/run/gate-snapshot.js +260 -38
  107. package/src/run/gates.js +482 -268
  108. package/src/run/green-cache.js +123 -0
  109. package/src/run/junction-rm.js +70 -0
  110. package/src/run/next.js +14 -0
  111. package/src/run/prompt.js +185 -55
  112. package/src/run/quick-audit.js +213 -14
  113. package/src/run/shared.js +123 -4
  114. package/src/run/stage.js +182 -216
  115. package/src/run/test-ledger.js +264 -0
  116. package/src/run/verify-quality-scan.js +84 -7
  117. package/src/scope-audit.js +6 -1
  118. package/src/sentinel-assertions.js +114 -0
  119. package/src/setup.js +3 -3
  120. package/src/spec-sync.js +41 -1
  121. package/src/stage-contract.js +26 -8
  122. package/src/stage-review-checklist.js +2 -0
  123. package/src/stage-review.js +7 -2
  124. package/src/stage-templates.js +157 -0
  125. package/src/stages/archive.js +2 -0
  126. package/src/stages/brainstorm.js +24 -106
  127. package/src/stages/execute.js +222 -85
  128. package/src/stages/knowledge.js +74 -1
  129. package/src/stages/plan-postcheck.js +385 -20
  130. package/src/stages/plan.js +23 -1
  131. package/src/stages/quick.js +10 -2
  132. package/src/stages/verify.js +4 -2
  133. package/src/sync.js +81 -23
  134. package/src/task-done.js +181 -0
  135. package/src/task-review.js +8 -55
  136. package/src/taskcard-frontmatter.js +57 -0
  137. package/src/test-bindings.js +549 -0
  138. package/src/timeline.js +218 -0
  139. package/src/ui-visual.js +175 -0
  140. package/src/verify-draft.js +214 -0
  141. package/src/verify-postcheck.js +919 -159
  142. package/src/verify-probes.js +103 -25
  143. package/src/watcher.js +1031 -0
  144. package/src/worktree-apply.js +44 -4
  145. package/src/worktree-deps.js +22 -8
  146. package/src/worktree-policy.js +42 -0
  147. package/src/worktree.js +102 -15
  148. package/templates/agents-instruction.md +37 -18
@@ -0,0 +1,46 @@
1
+ # R5 场景矩阵与执行协议(2026-09-21 落盘,依据 optimization-plan.md v3.2 + 第 1 批交付态)
2
+
3
+ ## 场景与臂
4
+
5
+ | 场景 | 基线(对撞仓 multi-agent-platform) | 跑法 | 备注 |
6
+ |---|---|---|---|
7
+ | 大任务(session-replay 同款) | 53c67e02a | ×2 跑 | 一跑 B-④ 材料包 OFF(缺省)、一跑 ON——互斥归因标签(v3.2 纪律二) |
8
+ | 小任务全流程(autocompact 同款) | 50736b6ef | ×2 跑 | |
9
+ | 小任务 quick(同款) | 50736b6ef | ×1 跑 | 门禁轮次 ≤2 判定主力场景(A 先于 B 纪律) |
10
+ | (可选)B-⑤ A/B | 50736b6ef | 小任务便宜档 ×1 | 与旗舰档同任务对照;返工率+核验密度双维否决线;审慎起见可推迟 R6 |
11
+
12
+ 版本钉死首步回显:受试会话第一步输出回显 sillyspec 版本 + 已落地批次(batch1 e49a7ce0 前序 / batch2 若已入库记录其 HEAD)——**M3(派发分组预计算)若在 R5 前落地,B-③ 归因必须与 M3 分开记**(提示词级 vs 机制化,v3.2 换位说明)。
13
+
14
+ ## 跑前清单(按序)
15
+
16
+ 1. `git -C multi-agent-platform worktree prune`(Temp 残留 prunable gate worktree 清理;基线 SHA 50736b6ef/53c67e02a 已 2026-09-21 cat-file 实证在场,主树干净)。
17
+ 2. **B-④ 接线补齐**:execute 主链材料包生成未接(batch1 task-02 接线最小化)——小 quick 一项(assembleExecuteTaskMaterials 调用点 + options.materials 装配)或并入 batch2 M3;不接则 ON 臂无法跑,矩阵降级为 OFF-only。
18
+ 3. R4 prompt 卫生沿用:受试会话任务书钉死「禁捞未来提交/版本首步回显/全流程勿降级」三律(prompt-R4-*.md 直接复用改版本号)。
19
+ 4. 探针套件预跑:`node --test test/probe-suite/wrong-key.test.mjs` 在受试 sillyspec 版本上绿——防线敏感性前置自证。
20
+
21
+ ## 指标判法(account.mjs v2 同口径,只比比值不比绝对值)
22
+
23
+ | 硬门 | 判法 | R4 基线(2026-09-21 钉死) |
24
+ |---|---|---|
25
+ | 扇出 tokens ≤32M | account.mjs 子会话聚合 totTok(子代列) | 42.26M |
26
+ | 门禁轮次 ≤2 | 进度库 gate 记录计数 | 9(S-F 病理)/ 2(稳态) |
27
+ | 防线回归 | probe-suite 绿 + 受试 transcript 错键类仍被拦 | — |
28
+ | 墙钟不劣化 ≤156min | 会话时间戳(跨度列) | 184.5min 毛口径 / 156min 稳态重构口径 |
29
+ | 额度零事故 | 受试过程无整 Wave 中断 | R4-L 有(并发帽前) |
30
+
31
+ 拉伸(不判罚):账单当量比 ≤1.8× —— `node round4/account.mjs --title R5-<臂> --since <日>` 的 当量@3× 列对同名对照臂取比;基线 2.37×(@3×)/2.47×(@5×),R4-L 13.89M / R4-O-L 5.87M。记录不判罚行:主会话峰值单请求 <250K(MAX 查询)、>150K 占比 <50%(计数查询)——依赖第 3 批 B3b,R5 只落基线。
32
+
33
+ **阶段级墙钟拆账(每跑必落)**:用 round4/extract-timeline.mjs 抽受试主会话时间线,按 CLI 阶段标记切六段(调研/plan/execute 扇出/verify/归档/门禁等待),落 r5-wall-accounting 表——R6 per-item 时间预算的唯一数据源(v3.2 先测后诺)。
34
+
35
+ ## 归因标签(防混账)
36
+
37
+ - B-④ ON/OFF 臂差 = 材料包贡献(上下文乘数)。
38
+ - 门禁轮次改善归战线 A(已提交四项),**不记 B-③ 提示词**;M3 若在场单列。
39
+ - 轮数纪律(B-⑥)效果看子代理请求数列(基线大任务 522req),与扇出 tokens 分列记录。
40
+ - batch2 M1(指令指纹增量)若在场:主会话 CLI 渲染体量单列(B3a 口径复跑),不并入扇出账。
41
+
42
+ ## 诚实边界
43
+
44
+ - 2 跑取分布不外推;提示词级项不达标即升级机制化(路径:CLI 截断注入/机械组装)。
45
+ - B-⑤ 若推迟,对外口径维持「模型分级未启用」。
46
+ - 墙钟 156min 为重构口径,毛口径 184.5min 一并记录防口径混用。
@@ -0,0 +1,171 @@
1
+ # R4 小任务对撞结果:R4-S-Q(sillyspec quick 3.29.4)vs R4-O-S(OpenSpec 1.13.1)
2
+
3
+ > 同任务(claude autocompact 三键)、同基线 50736b6ef、同机同模型、全新本地 zcode 会话、零子代理。
4
+ > 会话:R4-S-Q = sess_3c71e652(标题「R4 对照实验:autocompact 小任务 sillyspec quick 通道」,用户手起标题 `R4 ` 带空格致 `R4-` LIKE 漏配,按 id 补归);R4-O-S = sess_b818b681。
5
+
6
+ ## 硬账(zcode db,epoch-ms 数值比较)
7
+
8
+ | 指标 | R4-S-Q sillyspec quick | R4-O-S OpenSpec | 比 |
9
+ |---|---|---|---|
10
+ | 墙钟(创建→最后活动) | **41.2min** | **21.5min** | 1.92× |
11
+ | 请求 数 | 87 | 85 | ≈平 |
12
+ | tokens(computed_total) | **8.97M** | 9.33M | sillyspec 略优 |
13
+ | model-time(Σduration) | 13.3min | 13.1min | 平 |
14
+ | 子代理 | 0 | 0 | 平 |
15
+ | 模型利用率(model-time/墙钟) | 32% | 61% | 差在空闲 |
16
+
17
+ **墙钟差 19.7min ≈ 非模型时间差**(27.9 vs 8.4min)——模型算力完全同量级,差距全在本地命令等待。
18
+
19
+ ## 非模型时间去向(R4-S-Q 账面证据)
20
+
21
+ 1. quick --done 门禁**隔离快照全量测试 545.5s(9.1min)**(quicklog 结果段自述 + 提交信息双证)
22
+ 2. 全仓 lint 门(ruff check/format 1288 文件 + mypy 963 文件)——且因全仓口径被存量 format 债卡住,agent 被迫**顺手清偿两文件范围外 ruff 债**才过门
23
+ 3. 定向测试(daemon 31/31 + 相邻 93/93、frontend 35/35 + 相邻 46/46)+ 新工作树依赖安装
24
+
25
+ ## 预注册判定(prereg.md H4/H6)
26
+
27
+ - H6 墙钟 ≤20min:**FAIL**(41.2min)
28
+ - H6 --done 一次过零返工:**PASS**(steps 零 wait_round、门禁双 PASS 一次过)
29
+ - H4 quick 资产尾:**FAIL——CLI 缺陷,非 agent 违令**(细读更正:db 原始命令实证两次 `--done` 均带 `--linked-changes 2026-09-20-r4-linked-parent`)。两个独立缺陷:①②见「细读补正」节。
30
+
31
+ ## 意外发现:第 3 轮 OpenSpec 参照值是 fork 污染值
32
+
33
+ OpenSpec 全新会话实测 **9.33M**,第 3 轮参照「33.3M」是 **fork 继承胖上下文**(该跑 db 标题「Fork of …」实证)——**3.6× 虚高**。真实对比下两边 token 成本几乎相同;此前「OpenSpec 小任务更费 token」的印象不成立。sillyspec quick 8.97M 也只有第 3 轮 sillyspec 全流程 17.2M 的一半。
34
+
35
+ ## 质量面(非对称交付)
36
+
37
+ - sillyspec:隔离快照全量 + 定向 31/35 + 相邻 139 例 + 双侧 tsc + lint 全绿;资产落盘(quicklog 四参数结构化条目 + patch 双件 + 模块文档增量段 + 范围快照 sha256 锚定)
38
+ - OpenSpec:自愿跑测试 27/27 + 32/32(无门禁强制);规格库合入 5 requirement + archive
39
+
40
+ ## 结论与下一刀
41
+
42
+ 轻通道的「省 token」目标已达成(与 OpenSpec 持平且略优、较自家全流程减半);剩余墙钟差距是**机制级可修的**:quick --done 门禁的测试/lint 范围化(按 touched-files 定范围或信任 agent 定向实测 + 差量校验),预计可砍 10–15min 墙钟——这是 3.29.5 的明确候选工作项。
43
+
44
+ ## 细读补正(2026-09-21,逐条从会话正文/原始命令核出)
45
+
46
+ ### 更正记录
47
+
48
+ 前版「agent 未按提示词声明 --linked-changes」为**误判**:db 原始 Bash 命令显示两次 --done(首跑 22:29 与 lint 债修复后重跑 22:35)均带 `--linked-changes 2026-09-20-r4-linked-parent`。agent 行为完全合规。
49
+
50
+ ### 新发现的 CLI 缺陷(3.29.4,均 R4-S-Q 实证)
51
+
52
+ **缺陷 A(② changelog 边车死路)**:会话控制台实录 `⚠️ [资产尾] changelog 追加异常(fail-open):loadQuickModuleIndex is not a function`。源码定位:`src/run/shared.js:1294` 的 `loadQuickModuleIndex` 是内部函数**缺 `export`**,`complete-handlers.js:1430` 动态 import 解构得 undefined → 调用即 TypeError → fail-open 吞掉。§7 单测没抓到是因为直接模拟 join 语义、没走真实 import。
53
+
54
+ **缺陷 B(① 蒸馏尾未触发 + quicklog「关联变更:(无)」同根)**:tail 块读 `mergedGuard?.linkedChanges`,但 `--linked-changes` 在 --done 时解析后未并入该结构(manualLinked 空列表 → distill 干净跳过、零警告);quicklog 条目的关联变更字段渲染源同链。flag→guard 的接线断点需在修复任务中定位(command.js:645-666 解析后进入完成路径的通道缺失)。
55
+
56
+ ### 墙钟 41.2min 的精确分解(时间线实测)
57
+
58
+ | 阶段 | 时间 | 内容 |
59
+ |---|---|---|
60
+ | 0–1.6m | 1.6min | 引导+身份+CLAUDE.md;**worktree 守卫摩擦 3 次失败**后才用 `--allow-worktree-cwd --spec-dir` 放行 |
61
+ | 1.6–6.3m | 4.7min | Step1 理解:读码 + **5 次联网核键名**(precomputeCompactionEnabled 官方文档实证,任务简报未给键名) |
62
+ | 7.2–16.2m | 9.0min | 实现+定向测试全绿(daemon 31/31+相邻 93/93、前端 35/35+相邻 46/46、双侧 tsc、lint 基线对照)+ 依赖安装 + 模块文档增量 |
63
+ | 16.2–26.1m | 9.9min | **--done #1**:隔离快照全量测试 545.5s + lint → **被 2 个未触碰的存量 ruff format 债文件拦下** |
64
+ | 26.1–28.3m | 2.2min | agent 清偿范围外存量债 + 边界重声明 |
65
+ | 28.3–39.0m | 10.7min | **--done #2**:门禁全量重跑(test 539.3s + lint 62.7s)→ PASS |
66
+ | 39.0–41.2m | 2.2min | quicklog 核对 + 显式 pathspec 提交 + 报告 |
67
+
68
+ **门禁双跑 ≈ 20.7min,占墙钟一半**。其中第二跑对纯 lint 修复重跑全部测试是纯浪费(~9min);首跑被存量债拦截是 lint 全仓口径的结构问题。CLAUDE.md 规则 0(禁全量测试、留给 CI)与门禁的模块全量口径直接矛盾——工具门禁违反了仓规。
69
+
70
+ ### OpenSpec 侧行为细读(21.5min 分解)
71
+
72
+ - 0–3.5m 引导:init 即生成 `.zcode/commands/opsx/*` 流程说明书(propose/apply/archive),agent 读模板即上手——**工具自带教学**;
73
+ - 3.5–7.0m 只读探索(与 sillyspec 同量);
74
+ - 7.3–9.8m proposal 阶段:CLI 脚手架+instructions 模板引导,agent 写四件套(proposal/specs delta/design/tasks 8 任务),strict 校验过;
75
+ - 10.1–19.7m apply:8 任务推进,**前端依赖后台安装与表单编辑并行**(墙钟并行度);测试 3 轮修复迭代(2 处 esbuild 语法 + 1 处选择器逻辑);daemon 27/27 + 前端 32/32 定向绿;
76
+ - 20.0–21.1m archive:CLI 把 delta 合入活规格(5 requirement)+ 提交。
77
+ - **零强制门禁**:agent 自选验证深度(比 sillyspec 少 7 个新测试用例、不跑 lint、不清存量债、不跑全量回归);键名**未联网核验**(凭先验写 precomputeCompactionEnabled,碰巧对——sillyspec 花了 2.5min 实证)。
78
+
79
+ ### 质量不对称的本质
80
+
81
+ sillyspec 的 20.7min 门禁买到:模块级全量回归×2、全仓 lint、强制清偿存量债、22 个新测试。OpenSpec 买到:15 个新测试 + 自愿 typecheck。差距不是「sillyspec 浪费」而是**质量执行深度 2× 于对手**——但当前实现里约 11min(第二跑全量测试 + 存量债拦截处理)是可消除的纯损耗,且模块全量口径违反仓规(规则 0)。
82
+
83
+ ### 3.29.5 候选工作项(按 ROI 排序)
84
+
85
+ 1. **门禁增量复用**:纯 lint 失败重试时跳过测试重跑(按树 hash 缓存测试结论)——省 ~9min;
86
+ 2. **lint 范围化**:quick 门禁 lint 限 touched-files(或存量债基线快照豁免)——消除范围外拦截与「顺手清债」连带;
87
+ 3. **缺陷 A 修复**:shared.js:1294 补 export + 用真实 import 的回归测试;
88
+ 4. **缺陷 B 修复**:--linked-changes → mergedGuard.linkedChanges 接线 + quicklog 关联变更字段同修;
89
+ 5. 测试口径与 CLAUDE.md 规则 0 对齐(模块全量→touched 模块,全量留 CI)。
90
+
91
+ # R4 大任务+小任务全流程结果(2026-09-21 终态核算)
92
+
93
+ ## 硬账总表(五跑全终态,zcode db epoch-ms 口径)
94
+
95
+ | 跑 | 墙钟 | 请求 | tokens | 子代理 | 终态 |
96
+ |---|---|---|---|---|---|
97
+ | R4-L sillyspec 大·全流程 | 184.5min | 767 | 99.07M | 19 | 归档 01:14 verify PASS |
98
+ | R4-O-L OpenSpec 大 | 79.8min | 251 | 52.00M | 0 | archive 23:53(17 Requirement) |
99
+ | R4-S-F sillyspec 小·全流程 | 170.2min | 298 | 53.64M | 2 | 归档 01:00 |
100
+ | R4-S-Q sillyspec 小·quick | 41.2min | 87 | 8.97M | 0 | 已析(前节) |
101
+ | R4-O-S OpenSpec 小 | 21.3min | 85 | 9.33M | 0 | 已析(前节) |
102
+
103
+ 对照臂:大任务旧 sillyspec 重做 269min/681req/104.13M/12 子代(Fork 续跑);OpenSpec 旧跑 177.8min/288req/80.03M(同为 Fork)——**fork 污染双向坐实:OpenSpec 全新会话 79.8min/52M,比它自己的 fork 跑快 2.2×、省 35% token**。
104
+
105
+ ## 预注册判定(prereg.md)
106
+
107
+ - **H1 大任务墙钟 ≤150min:FAIL**(184.5min;较对照臂 269min 降 31%;vs OpenSpec 同条件 2.3×)
108
+ - **H2 机制五点:5/5 全中 → PASS**
109
+ - a 波次并发:15:22 双并发、15:34 **四并发**实证(对照第 3 轮全串行——拓扑守卫生效)
110
+ - b 无假红循环:无「同 gate 无变化重试」旧病(PASS);但见「新病」——隔离快照 lint 环境差异无诊断线索(见新发现)
111
+ - c verify 批量补完:batch completion 生效(R4-S-F 61.4m 实录"batch completion kicked in")
112
+ - d 审查请求钳(四律):设计 11/12 ✓、计划 6/10 ✓、QA 6/15 ✓——**三阶段全达标**
113
+ - e plan 零卡片填充子代理:19 个子代全是调研/取证/审查/实现,无 TaskCard 生成器 ✓
114
+ - **H3 提示词级可靠性:PASS**——四律请求钳本次被遵守(单样本,不可外推为「已解决」)
115
+ - **H5 小任务全流程 ≤30min:FAIL**(170.2min;分解见下)
116
+
117
+ ## R4-S-F 170min 去向(时间线分解)
118
+
119
+ 1. 0–61min:brainstorm+plan+execute 五任务(两个 batch 子代理,实现与测试全绿)——**净仪式+实现成本约 60min**
120
+ 2. 67.5–97.3min:**额度中断 ~30min**(会话被限额卡停,用户"继续,额度已恢复")
121
+ 3. 69–141min:**verify 隔离快照 lint 法证 ~70min**——CLI 实测隔离快照根在临时目录:mypy/ruff 缓存全冷(每次 --done 全速重跑 ~7min)+ known_failures 豁免环境差异 → agent 侧复现恒绿、门禁恒红,agent 被迫做缓存 mtime 考古 + WAL db 探测定位(131.2m "FOUND IT")
122
+ 4. 141–170min:module-impact 死信回填 + 槽格式学习 + archive
123
+
124
+ **剔除额度中断与快照法证后净成本 ~60-70min**——仍超 39.5min 旧臂(服务器侧条件不可比),但数量级合理。
125
+
126
+ ## 新发现(本轮最大 actionable)
127
+
128
+ **verify 隔离快照的 lint 环境差**:快照根(%TEMP%)无 mypy/ruff 缓存、known_failures 豁免随行性存疑 → 门禁失败无诊断线索,fresh agent 花 70min 法证。修法候选:①快照 lint 失败输出一行诊断(快照根路径+「与工作区差异可能原因:缓存冷/豁免不随行」);②快照复用工作区 lint 缓存目录;③lint 结论按树 hash 缓存(ROADMAP 已登记的 parity 增量缓存同族)。
129
+
130
+ ## 结论
131
+
132
+ - **结构性修复全部生效**(波次并发/审查钳/批量补完/零填卡/无假红——H2 5/5),token 效率大任务 99M vs 旧 104M(fork 臂不可比,OpenSpec fresh 52M 仍是 1.9×——子代理架构的固有税)
133
+ - **剩余墙钟差距的三块**:①额度中断(环境非工具);②隔离快照 lint 法证(工具缺陷,可修);③严格档槽格式学习曲线(fresh agent 每次重付——流程命令卡的 verify 卡应预载槽格式要点,2026-09-21-flow-command-cards 的 run-verify 卡已有此意,可强化)
134
+ - 产品级判断:小任务路由 quick(41min)正确;全流程通道的修复方向已从「结构」转移到「门禁环境差诊断」与「槽格式先验」
135
+
136
+ ## 五会话细读分析(2026-09-21 补)
137
+
138
+ ### 交付物对照(大任务,分支内 diff,排除 spec 产物)
139
+
140
+ | | R4-L sillyspec | R4-O-L OpenSpec |
141
+ |---|---|---|
142
+ | 代码文件/插入 | 24 文件 / 7241 行 | 25 文件 / 3396 行 |
143
+ | 其中测试 | 2909 行(40%) | 1193 行(35%) |
144
+ | 提交数 | 15 | 5 |
145
+ | 审查面 | 13 task review.json + 3 阶段独立审查 | schema-only strict validate |
146
+
147
+ ### 关键出入(可比性)
148
+
149
+ **三个大跑撞了同一个 5h 额度墙**:R4-O-L 74.5m、R4-S-F 97.3m、R4-L 97.5m 各有一次「继续,额度已恢复」——恢复时延取决于用户何时看到(O-L 仅 ~3.5min,S-F ~30min,L 未知)。**所有墙钟绝对值被污染,趋势方向可信**。
150
+
151
+ ### OpenSpec 快的解剖(79.8min)
152
+
153
+ 0–19m 探查(含 4 个真实数据探针脚本:zcode sqlite part.data/cursor transcript ×3,96 份样本实证格式)→ 19–22m proposal 四件套+strict validate+提交(3min)→ 22–43m daemon(自测 129 绿,6 轮小修)→ 43–57m backend(20 绿+gen:types)→ 57–71m 前端+测试 → 74–79 archive。**单上下文 251 请求零子代理、零外部门禁、所有验证自跑即时反馈(vitest 13s/pytest 17s)、archive 1min 机械合并**。
154
+
155
+ ### sillyspec 慢的解剖(184.5min,含额度中断)
156
+
157
+ 0–14m 三调研子代理并发 → 14:30 取证 → 14:50–15:07 设计+计划审查串行(11+6 req,均达标)→ 15:22–16:52 execute 五波(2/4/2/2/1 并发,编排者波间 TaskOutput 阻塞)→ 其余为 verify/archive 的槽格式学习(module-impact 缺失重建、step --done 不推进 ×2、结论枚举/探针 7 矩阵/死信回填)。
158
+
159
+ ### 慢的归因排序(可修性)
160
+
161
+ 1. **子代理重序列化税**(token 1.9× 主因)——架构固有,缩法:execute 子代理 prompt 瘦身(只给 task 卡+模块摘要不给全量上下文)
162
+ 2. **隔离快照 lint 冷缓存法证**(S-F 70min)——可修(诊断行/缓存随行)
163
+ 3. **槽格式学习曲线**(每 fresh agent 重付 ~20min)——可修(run-verify 卡强化)
164
+ 4. **编排者波间空闲**(execute 90min 中编排者大多在等)——可修(波间做 verify 前置准备)
165
+ 5. 审查串行 ~17min——已钳住,量小
166
+
167
+ ### 别的问题
168
+
169
+ - TodoWrite reminder 噪声:R4-O-L 26 条系统提醒纯 token 浪费(harness 层,非工具账)
170
+ - OpenSpec 质量下限依赖 agent 自觉:本跑 agent 勤奋(真实探针+129 测试)但无独立审查面——若遇懒 agent 无兜底
171
+ - R4-S-F 的 brainstorm+plan 仪式(0–38m)与其实现(38–61m)等长——小任务走全流程的仪式/实现比 ≈1:1,路由 quick 正确
@@ -0,0 +1,46 @@
1
+ # R4 对照实验·终局核算(2026-09-21,五跑全终态)
2
+
3
+ ## 终表(全部本地 zcode 新会话、同机同模型)
4
+
5
+ | 跑 | 工具/通道 | 墙钟 | 合计请求 | 合计 tokens | 子代理 | 终态 |
6
+ |---|---|---|---|---|---|---|
7
+ | R4-L | sillyspec 3.29.4 大任务全流程 | **185min** | 767 | 99.1M | 19 | verify PASS + archived |
8
+ | R4-O-L | OpenSpec 1.13.1 大任务 | **80min** | 251 | 52.0M | 0 | archived |
9
+ | R4-S-F | sillyspec 全流程(小任务) | **171min** | 298 | 53.6M | 2 | archived |
10
+ | R4-S-Q | sillyspec quick(小任务) | 41.2min | 87 | 8.97M | 0 | --done 落账 |
11
+ | R4-O-S | OpenSpec(小任务) | 21.5min | 85 | 9.33M | 0 | archived |
12
+
13
+ ## 预注册判定(H1–H6 收口)
14
+
15
+ | # | 假设 | 判定 | 证据 |
16
+ |---|---|---|---|
17
+ | H1 | 大任务墙钟 ≤150min | **FAIL** | 185min(vs 老版 269min 降 31%,但超线 23%) |
18
+ | H2 | 机制 ≥3/5 生效 | **PASS(4/5 确认)** | 见下 |
19
+ | H3 | 提示词级四律可靠 | **PASS(本跑)** | 审查钳 3/3 阶段达标:Design Grill 11req(≤12)/ plan 6req(≤10)/ QA 6req(≤15)——四律首次实证能被遵守 |
20
+ | H4 | quick 资产尾 | **FAIL** | CLI 缺陷 A(export 缺失)+ B(--linked-changes 管道断),已列修 |
21
+ | H5 | 小任务全流程 ≤30min | **FAIL** | 171min,其中 ≥3 轮全量门禁循环(存量债→advisory→死信逐层暴露) |
22
+ | H6 | 小任务 quick ≤20min | 墙钟 **FAIL**(41.2)/ 一次过 **PASS** | 零等待轮零返工 |
23
+
24
+ ## H2 机制点明细(R4-L 19 个子会话时间窗实证)
25
+
26
+ - **波次并发 ✅**:Wave1 两个实现子代理 72~81min 并行;Wave2 四个实现子代理 85~95min 并行(3.29.3 拓扑守卫生效的直接证据)
27
+ - **无假红循环 ✅**:工作树 friction-tally 零 gate_rollback、verify 一次过(review_rejected×3 属 S2 审查正常否决)
28
+ - **审查请求钳 ✅**:三阶段 11/6/6,全部在 12/10/15 帽内
29
+ - **零卡片填充子代理 ✅**:19 子 = 3 只读调研 + 1 取证 + 2 审查 + 12 实现 + 1 QA,无 TaskCard 生成器(第 3 轮的老病灶消失)
30
+ - 批量补完:未单独确认(verify 163~185min 含门禁,一次通过)
31
+
32
+ ## R4-L 的 185min 分解(子会话窗口)
33
+
34
+ 引导+brainstorm 调研 0–20(3 调研代理并发)→ 四件套+原型 20–40 → 设计审查+计划审查 40–57(合计仅 17min,四律生效)→ 计划定稿 57–72 → **execute 72–162(90min,6 波,波内并发)** → verify+归档 163–185。
35
+
36
+ ## 三层对比结论
37
+
38
+ 1. **纵向**(修复前后):大任务 269→185min(-31%)、tokens 104→99M(平);小任务全流程表面 39.5→171 恶化,但 39.5 是服务器侧+fork 条件不可比,171 是门禁病理特异值(非正常流)。
39
+ 2. **横向**(同条件对撞):大任务 sillyspec/OpenSpec = 墙钟 2.3×、tokens 1.9×、请求 3.1×;小任务 = 墙钟 1.9×、tokens 0.96×(持平)。**fork 混杂再次证实**:OpenSpec 大任务全新会话 80min/52M vs 第 3 轮 fork 跑 177.8min/80M(fork 虚高 ~2×)。
40
+ 3. **机制层**:全部主要结构修复在真实运行中生效(串行波→并发、审查失控→钳内、填卡子代理→零、假红→零)。**墙钟未同比例改善的原因**:(a) 子代理扇出的固有成本——19 个子会话重读上下文吃掉 42.3M/522req(占总 tokens 43%/总请求 68%);(b) 门禁病理(R4-S-F 171min 几乎全是门禁循环);(c) ceremony 总厚度。
41
+
42
+ ## 后续(已在办)
43
+
44
+ - 门禁三件套 + 缺陷 A/B + 模块粒度范围化(已安排,gate-value-audit.md 拍板 touched-modules 粒度)
45
+ - 3.29.5 发版后 R5 小任务 ×2 重放验收(同基线、2 跑取分布)
46
+ - 子代理扇出的 token 倍增是产品定位问题(质量换成本),不是缺陷——是否优化(如实现子代理共享预载上下文)待单独立项评估
@@ -0,0 +1,63 @@
1
+ # R4 代码质量与项目资产对比(2026-09-21)
2
+
3
+ ## 一、小任务(autocompact):一个决定性的质量分野
4
+
5
+ 两侧 daemon 白名单实现**工艺等价**(同构值守护:window 正整数 + 开关布尔、坏键不拖累同批、非法静默跳过;注释都引了各自的设计决策号)。分歧在**域事实**:
6
+
7
+ | | sillyspec(R4-S-Q) | OpenSpec(R4-O-S) |
8
+ |---|---|---|
9
+ | 第三键名 | `precomputeCompactionEnabled` | `autoCompactPreCompute` |
10
+ | 依据 | 5 次联网核验官方文档(settings reference + /config) | 凭先验,零核验 |
11
+ | 交叉验证 | 与第 3 轮主仓独立实现(c1ce37e9e,同样经文档核验)一致 | 与两轮独立核验**都不一致** |
12
+
13
+ **OpenSpec 侧是错键:第三个开关(预计算)在生产是 no-op。** 其 27/27 测试全绿(断言的是自己写的错键)、干净归档——单测验证的是实现自洽,不能发现域事实错误;无任何门禁对外部真值复核。sillyspec 多花的 2.5 分钟联网核验,就是这道防线。
14
+
15
+ 前端行为差异(都合理):sillyspec 坏值静默不进提交体;OpenSpec 即时校验 + alert 拦提交。
16
+
17
+ ## 二、大任务(session-replay):范围对齐、测试体量 2.4×
18
+
19
+ - 范围:两侧都交付解析器矩阵(claude-code / cursor-agent / zcode model-io / zcode-sqlite)+ AgentReplayBody 回放主体,提案成功标准覆盖对齐。
20
+ - 测试:sillyspec 2,909 行 vs OpenSpec 1,193 行(回放主体 806 vs 380 行测试)。
21
+ - 行数差(18,126 vs 3,999)主要来自生成物(api-types/gen)与文档,**不作为质量依据**。
22
+
23
+ ## 三、项目资产盘点(大任务终态实录)
24
+
25
+ **sillyspec**(归档提交触达):
26
+ - 变更归档 15 件(四件套 + plan/tasks + decisions + module/symbol-impact + verify-facts/result + scope-audit + 原型)
27
+ - **决策提炼 4 条**入 `knowledge/decisions/unmapped.md`(+36 行)
28
+ - **FR 索引 7 条**入 `knowledge/fr/host-fs-handler.md`(+73 行)+ INDEX
29
+ - **ROADMAP 里程碑** + 模块文档增量(daemon.md / platform_sync.md)
30
+
31
+ **OpenSpec**:
32
+ - 归档变更夹 + **活规格库 3 个 capability**(agent-log-messages-schema / parsers / session-replay,215 行 WHEN/SHALL 契约)
33
+
34
+ 两种资产形态不同但都是真可检索资产:sillyspec 是「决策 + FR + 路线图」(按域索引的特性真相),OpenSpec 是「活规格」(按能力组织的行为契约,后续变更以 delta 修改)。
35
+
36
+ **资产的正确性风险不对称**:OpenSpec 小任务的活规格把**错键写进了 5 条 requirement**——错误被典藏为权威事实,后续变更信任并传播它。sillyspec 的 FR 来自文档核验后的 requirements。
37
+
38
+ ## 四、结论
39
+
40
+ 1. 工艺层面(代码风格/守护逻辑/测试写法)两侧**无可观差距**——LLM 同源,写代码不是分歧点。
41
+ 2. 分歧点在**认识论**:域事实要不要对外部真值核验。本轮唯一一个硬缺陷(错键 no-op)恰好出在无核验侧,且被其全绿测试和干净归档完美掩盖。
42
+ 3. sillyspec 的结构价值在这轮得到具体化:联网核验习惯(agent 行为,部分归功流程提示词的「实证」文化)+ 门禁对外部口径的复核对这类缺陷是防线;OpenSpec 的「赋能不门禁」在域事实类错误上无防线。
43
+ 4. 局限:错键是 n=1 的硬案例;「sillyspec 的流程必然导致核验」不成立(R4-O-S 侧的核验缺失是 agent 行为方差,第 3 轮 OpenSpec 跑也可能核验)。可防御的表述是:**门禁+实证文化提供的是概率性防线,OpenSpec 连概率都不提供**。
44
+
45
+ ## 五、补遗(2026-09-21):R4-L 审查链实际拦下的东西(非随机实例)
46
+
47
+ - **Design Grill 首轮 REJECT(阻断项 B1)**:初版设计把 cursor-agent-store 读取器注册进 registry——审查员独立核了源码事实(registry 契约为 content 字符串,registry.ts:53-56;zcode SQLite 恰是绕过 registry 的 handler 专用分支先例),判定设计自相矛盾,强制改为专用分发分支 + `~/.cursor/chats/` 目录门(design.md:49-50 落地)。**这是代码写出来之前拦下的集成级缺陷**——不拦的话 cursor-agent 解析链路接错调度面,集成期才爆,返工一轮。
48
+ - G1(三态枚举补 409,对照 router.py 真实行为)、G2(命名口径统一)两条非阻断同轮闭合。
49
+ - **QA 终审独立复跑全部测试**(daemon 165/165 + backend 247 + frontend 46/46,6 个请求内完成)并做了四跳字段契约核对(daemon→RPC→backend→api-types→前端逐层比对)。
50
+ - 对照组:OpenSpec 全流程无任何独立审查环节,B1 类设计-源码矛盾无人核。
51
+
52
+ ## 六、质量差距的诚实总结(回应「是不是就一个小概率事件」)
53
+
54
+ 四条防线、每条都有本周实证,全部属于「没有该机制就必然带病落盘」类别:
55
+
56
+ | 防线 | 机制 | 本周实例 | OpenSpec 对应物 |
57
+ |---|---|---|---|
58
+ | 域事实核验 | 实证文化+流程提示词 | 错键(R4-O-S 生产 no-op) | **无**(n=1 但防线是结构性的:流程里没有任何核验步骤) |
59
+ | 设计-源码一致性 | 独立 Design Grill | B1(R4-L,改设计于写码前) | 无 |
60
+ | 声明-现实对账 | 测试门禁 | 主仓 2 个月 12 次真拦(gate-value-audit) | 无(pre-commit 只查格式) |
61
+ | 资产正典正确性 | 文档同步义务+FR 实证来源 | 规格库典藏错键(对照侧) vs sillyspec FR 经核验 | 无 |
62
+
63
+ 同时如实记录防线的漏检面:sillyspec 自己的缺陷 A/B(export 缺失/管道断)25 个单测+S2 审查都没拦住,是靠 R4 实测暴露的——**仪式是概率盾,本样本内拦 3 漏 2**。
@@ -316,6 +316,15 @@ function _parseFileListDetailed(designMdPath, { keepSillyspecDocs = false, repoK
316
316
  const head = rawItem.slice(0, colonIdx).trim()
317
317
  if (looksLikePath(head)) rawItem = head
318
318
  }
319
+ // 「路径 ——尾注」同族(坑 thin-flow-freeze-foreign-declared-hijack 建议1,2026-09-25
320
+ // 实测:`- path ——说明` 整行 looksLikePath 不过被丢弃 → 自声明缺失 → 冻结面被他侧
321
+ // 陈旧声明劫持)。同冒号剥的口径:仅列表分支、前段须 looksLikePath(合法路径不含
322
+ // 双 em-dash,误伤面为零)。
323
+ const dashIdx = rawItem.search(/——/)
324
+ if (dashIdx > 0) {
325
+ const head = rawItem.slice(0, dashIdx).trim()
326
+ if (looksLikePath(head)) rawItem = head
327
+ }
319
328
  }
320
329
  const itemNorm = normalizePath(rawItem)
321
330
  const itemCross = preCross || splitCrossRepoPrefix(itemNorm, repoKeys)
@@ -26,6 +26,12 @@ const FORCE_QUICK_PATTERNS = [
26
26
  /更新文案|改文案|文案修改/i,
27
27
  /样式调整|style.*tweak/i,
28
28
  /修复.*\s*\bbug\b.*\bfix\b/i,
29
+ // R16 减负批次(2026-09-24,R5R 对撞实证 quick≈OS:8.3M vs 6.4M——判规模选道倾向 quick):
30
+ // 补充明确无设计决策密度的常规任务面
31
+ /补注释|加注释|注释补充/i,
32
+ /重命名|rename\s+(变量|函数|文件|目录)/i,
33
+ /升级依赖|依赖升级|bump\s+(版本|deps|dependencies)/i,
34
+ /配置微调|配置小改|改配置项/i,
29
35
  ]
30
36
 
31
37
  /**
@@ -0,0 +1,74 @@
1
+ // 流程命令卡注入器(2026-09-21-flow-command-cards)——init 按 --tools 把包内
2
+ // assets/command-cards/*.md 落到工具命令目录(zcode/claude),尾部锚行三态幂等。
3
+ // 基准(Grill P1-3 修订):锚行记录「剥离锚行后的落盘正文 sha」,重跑剥离重算比对
4
+ // ——检测的是用户手改正文;「锚行 vs 包资产」字面比对检测不到正文手改(已否决)。
5
+ import { readdirSync, readFileSync, mkdirSync } from 'fs'
6
+ import { join } from 'path'
7
+ import { fileURLToPath } from 'url'
8
+ import { createHash } from 'crypto'
9
+ import { writeAtomicSync } from './fs-atomic.js'
10
+
11
+ export const COMMAND_CARD_TARGETS = { zcode: '.zcode/commands/sillyspec', claude: '.claude/commands/sillyspec' }
12
+ // flow=轻量变更默认道入口卡(2026-09-25-quick-channel-retire 配套:quick 退役后快道首次有卡)
13
+ export const COMMAND_CARD_NAMES = ['flow', 'run-brainstorm', 'run-plan', 'run-execute', 'run-verify', 'run-archive', 'run-quick', 'status']
14
+
15
+ const ANCHOR_TAIL_RE = /\n?<!-- sillyspec-card: v(\S+) sha256=([0-9a-f]{64}) -->\s*$/
16
+ const sha256 = (s) => createHash('sha256').update(s, 'utf8').digest('hex')
17
+ // 尾换行对称归一(首版 bug 实证:锚行正则 \n? 吞掉正文末换行,重算侧 replace(/\s+$/,'\n')
18
+ // 对无尾随空白的串是 no-op 换行补不回 → 完好文件恒判「手改」。先全剥尾随空白再统一补单个 \n,
19
+ // 两侧(资产读取/落盘重解析)同函数 → 对称。
20
+ const canonical = (raw) => raw.replace(/\r\n/g, '\n').replace(/\s+$/, '') + '\n'
21
+
22
+ /** 读包内卡资产(import.meta.url 相对——npm 全局安装/本地 checkout 双形态同源)。 */
23
+ export function readCardAssets() {
24
+ const dir = fileURLToPath(new URL('../assets/command-cards/', import.meta.url))
25
+ const assets = new Map()
26
+ for (const f of readdirSync(dir).filter((x) => x.endsWith('.md')).sort()) {
27
+ assets.set(f.replace(/\.md$/, ''), canonical(readFileSync(join(dir, f), 'utf8')))
28
+ }
29
+ return assets
30
+ }
31
+
32
+ /**
33
+ * 三态四分支注入(判据源唯一=尾部锚行;frontmatter 不承载管理面):
34
+ * 1 目标不存在 → 写(正文+锚行)
35
+ * 2 锚行在且剥离重算正文 sha 一致(完好):与包资产一致 → no-op(mtime 不动);不一致(CLI 更新)→ 覆盖
36
+ * 3 锚行缺失(外来同名文件)或重算 sha 不符(用户手改正文)→ warn 跳过,force 才覆盖
37
+ * @returns {Promise<{written:string[], updated:string[], skipped:string[], warnings:string[]}>}(元素为相对目标目录的卡名)
38
+ */
39
+ export async function injectCommandCards(projectDir, { tools = [], force = false, version = '' } = {}) {
40
+ const written = [], updated = [], skipped = [], warnings = []
41
+ const assets = readCardAssets()
42
+ if (assets.size === 0) {
43
+ warnings.push('包内 assets/command-cards/ 为空——npm 发布是否漏 assets/(白屏防线:npm pack --dry-run | grep assets/command-cards)')
44
+ return { written, updated, skipped, warnings }
45
+ }
46
+ for (const name of COMMAND_CARD_NAMES) {
47
+ if (!assets.has(name)) warnings.push(`资产缺失:${name}.md 不在包内 assets/command-cards/`)
48
+ }
49
+ for (const tool of [...new Set(tools)].filter((t) => COMMAND_CARD_TARGETS[t])) {
50
+ const dir = join(projectDir, COMMAND_CARD_TARGETS[tool])
51
+ mkdirSync(dir, { recursive: true })
52
+ for (const [name, body] of assets) {
53
+ const file = join(dir, `${name}.md`)
54
+ const out = `${body}<!-- sillyspec-card: v${version} sha256=${sha256(body)} -->\n`
55
+ let landed = null
56
+ try { landed = readFileSync(file, 'utf8') } catch { /* 不存在走分支 1 */ }
57
+ if (landed === null) { writeAtomicSync(file, out); written.push(name); continue }
58
+ const m = landed.match(ANCHOR_TAIL_RE)
59
+ if (!m) {
60
+ if (force) { writeAtomicSync(file, out); updated.push(name); warnings.push(`${tool}/${name}:外来同名文件被 --force 覆盖`) }
61
+ else { skipped.push(name); warnings.push(`${tool}/${name}:无锚行(外来同名文件),跳过——确认后删它重跑 init 或 --force`) }
62
+ continue
63
+ }
64
+ const bodyNow = canonical(landed.slice(0, m.index))
65
+ if (sha256(bodyNow) === m[2]) {
66
+ if (bodyNow === body) { skipped.push(name); continue } // 完好且同资产:no-op(mtime 不动)
67
+ writeAtomicSync(file, out); updated.push(name); continue // 完好且新资产:版本更新
68
+ }
69
+ if (force) { writeAtomicSync(file, out); updated.push(name); warnings.push(`${tool}/${name}:手改正文被 --force 覆盖(原改动已丢)`) }
70
+ else { skipped.push(name); warnings.push(`${tool}/${name}:正文与锚行记录不符(用户手改),跳过——保留改动;--force 可覆盖`) }
71
+ }
72
+ }
73
+ return { written, updated, skipped, warnings }
74
+ }
@@ -85,6 +85,8 @@ function main() {
85
85
  // stderr 必须管道化:execFileSync 默认把子进程 stderr 透传给父进程——非 git 目录下
86
86
  // git 落 --no-index 模式报 unknown option 的 usage 长文会漏进守卫 stderr(噪声)。
87
87
  stdio: ['ignore', 'pipe', 'pipe'],
88
+ windowsHide: true,
89
+ stdio: ['ignore', 'pipe', 'pipe'],
88
90
  })
89
91
  .split(/\r?\n/)
90
92
  .map((s) => s.trim())
@@ -68,8 +68,10 @@ export const LOCAL_YAML_SCHEMA = {
68
68
  note: 'detect 核验 package.json(或对应构建文件) scripts 存在性后才写对应键;缺失则不写。agent 可改。',
69
69
  keys: [
70
70
  { path: 'commands.build', type: 'string', optional: true, status: 'live', readers: ['detectLocalYaml (src/local-detect.js)', 'validateCommands (src/scan-postcheck.js)'], desc: '构建命令。', example: 'npm run build' },
71
- { path: 'commands.test', type: 'string', optional: true, status: 'live', readers: ['extractTestCommand (src/verify-postcheck.js)', 'runQuickTestLintGate (src/run/quick-audit.js)', 'validateCommands (src/scan-postcheck.js)'], desc: '测试命令——verify 阶段 CLI 亲自执行此命令与 verify-result.md 对账,实测失败即阻断;quick --done 触及 src/test 时同款实测(P0-2 门禁)。', example: 'npm test' },
71
+ { path: 'commands.test', type: 'string', optional: true, status: 'deprecated', readers: ['extractTestCommand (src/verify-postcheck.js)', 'validateCommands (src/scan-postcheck.js)'], desc: '【2026-09-26-dynamic-test-inference 退役为全量逃生阀】仅显式 test_strategy: full 时生效——测试面缺省按变更动态推断(本变更测试 ∪ FR 关联回归 ∪ import 依赖,runner 自项目结构推断),不再依赖此配置;未配置且显式 full 时按 package.json scripts.test / pyproject 结构推断全量命令。', example: 'npm test' },
72
72
  { path: 'commands.lint', type: 'string', optional: true, status: 'live', readers: ['detectLocalYaml (src/local-detect.js)', 'runQuickTestLintGate (src/run/quick-audit.js)', 'validateCommands (src/scan-postcheck.js)'], desc: 'lint 命令——quick --done 触及 src/test 时 CLI 亲自执行(P0-2 门禁,失败阻断完成)。', example: 'npm run lint' },
73
+ { path: 'commands.test_timeout_sec', type: 'number', optional: true, status: 'live', readers: ['resolveTestTimeoutMs (src/verify-postcheck.js)'], desc: 'commands.test 超时秒数(R9 实证 2026-09-23:全量套件实测可达 27min,固定 600s 帽必杀)——优先级 local.yaml 本键 > env SILLYSPEC_TEST_TIMEOUT_MS > 缺省 600。慢仓在此提帽,防真慢套件被当超时失败。', example: '2400' },
74
+ { path: 'commands.lint_timeout_sec', type: 'number', optional: true, status: 'live', readers: ['runVerifyLintCheck (src/verify-postcheck.js)'], desc: 'commands.lint 超时秒数——优先级 显式调用参 > 本键 > env SILLYSPEC_LINT_TIMEOUT_MS > 缺省 180(快照内 junction I/O 慢,快照路径调用侧显式传 300)。', example: '600' },
73
75
  { path: 'commands.smoke', type: 'string', optional: true, status: 'live', readers: ['executeVerifyQualityScan (src/run/verify-quality-scan.js)'], desc: '接口冒烟命令——verify 阶段 CLI 亲跑(脚本自理服务生命周期:后台起服+轮询就绪+finally 杀),300s 超时帽,失败/超时只记失败态不阻断本步、触发 PASS 封顶(D-002);指纹含此键,未变不重跑。', example: 'node scripts/smoke.mjs' },
74
76
  { path: 'commands.install', type: 'string', optional: true, status: 'live', readers: ['extractInstallCommand (src/worktree-deps.js)'], desc: '依赖安装命令(worktree 依赖 provisioning 用)。', example: 'npm install' },
75
77
  ],
@@ -110,7 +112,7 @@ export const LOCAL_YAML_SCHEMA = {
110
112
  note: 'test_strategy: module 时,按 git diff 命中的模块子集收窄测试。只支持 inline flow 形态(extractModules 不解析嵌套展开式)。',
111
113
  keys: [
112
114
  { path: 'modules.<name>.path', type: 'string', optional: true, status: 'live', readers: ['extractModules (src/verify-postcheck.js)', 'parseLocalYamlModules (src/plan-postcheck.js)', 'extractModulePaths (src/worktree-deps.js)'], desc: '子模块目录路径(相对仓库根)。', example: 'frontend/' },
113
- { path: 'modules.<name>.test', type: 'string', optional: true, status: 'live', readers: ['extractModules (src/verify-postcheck.js)'], desc: '该子模块的测试命令。', example: 'cd frontend && pnpm test' },
115
+ { path: 'modules.<name>.test', type: 'string', optional: true, status: 'deprecated', readers: ['extractModules (src/verify-postcheck.js,退役提示用)'], desc: '【2026-09-26-dynamic-test-inference 退役,不再消费】测试面按变更动态推断、runner 自项目结构(pyproject/uv.lock/package.json 就近祖先)推断。模块级 flaky 处置迁 known_failures。块在场时 CLI 打印退役指引。', example: 'cd frontend && pnpm test' },
114
116
  ],
115
117
  },
116
118
  {
@@ -118,7 +120,7 @@ export const LOCAL_YAML_SCHEMA = {
118
120
  title: '测试策略',
119
121
  note: 'verify 阶段 CLI 对账的收窄策略(D-005@v2:skip 接线兑现 + evidence-auto 新增,full/module 语义不变)。',
120
122
  keys: [
121
- { path: 'test_strategy', type: 'enum', values: ['full', 'module', 'skip', 'evidence-auto'], optional: true, status: 'live', readers: ['extractTestStrategy (src/verify-postcheck.js)', 'resolveTestStrategy (src/verify-postcheck.js)'], desc: 'full=全量 commands.test;module=按 git diff 命中 modules 子集收窄(需配 modules);skip=真跳过测试(不回退全量,verify 输出显式标注留审计痕迹,R-07);evidence-auto=按变更目录 module-impact.md 影响类型推荐检查组合(行为→module 聚焦测试、文档/prompt→docs-check、门禁契约→gate;缺失/不可解析降级 module 并注记)。缺省:配了 modules: 块 → module(v3.29.3 起缺省收窄,ql-20260920-010);未配 modules → 全量。', example: 'full' },
123
+ { path: 'test_strategy', type: 'enum', values: ['full', 'module', 'skip', 'evidence-auto'], optional: true, status: 'live', readers: ['extractTestStrategy (src/verify-postcheck.js)', 'resolveTestStrategy (src/verify-postcheck.js)'], desc: '【2026-09-26-dynamic-test-inference 起】full=全量(commands.test 在场生效,否则结构推断);module=已退役折算动态子集(超集覆盖:变更文件面收窄 + FR 关联回归 + import 依赖);skip=真跳过(R-07 不变);evidence-auto=按 module-impact.md 推荐(行为→动态子集、文档/门禁→skip)。缺省=动态子集:三源并集非空实测、空则不硬跑全量(防超时/预存失败面)。', example: 'full' },
122
124
  ],
123
125
  },
124
126
  {
@@ -127,6 +129,8 @@ export const LOCAL_YAML_SCHEMA = {
127
129
  note: '变更前就失败的测试行,豁免后不计入 verify 阻断。支持块列表或 inline 数组。务必定期复核,避免误豁免本变更引入的真实失败。',
128
130
  keys: [
129
131
  { path: 'known_failures', type: 'array', optional: true, status: 'live', readers: ['extractKnownFailures (src/verify-postcheck.js)'], desc: '失败行模式列表(匹配测试输出失败行)。', example: 'tests/some-old-test' },
132
+ { path: 'ui_visual_gate', type: 'string', optional: true, status: 'live', readers: ['runUiVisualProbe (src/ui-visual.js)'], desc: '【2026-09-27-ui-visual-guidance】UI 视觉证据分级门档位:warn(默认,缺 visual-evidence.md 仅警告)/ error(缺证据即阻断)/ off(探针整体关闭,含降级硬规则)。视觉降级无用户裁决留痕时无论档位恒阻断。', example: 'warn' },
133
+ { path: 'hunk_gate', type: 'string', optional: true, status: 'live', readers: ['runHunkAttributionGate (src/hunk-attribution.js)'], desc: '【2026-09-27-hunk-attribution-gate】提交面行级归属门档位:warn(默认,未归因文件/跨变更竞争/在途残留仅警告)/ error(未归因与跨变更竞争任一在场阻断收口;在途残留恒仅警告——并发 WIP 弱信号不硬拦)/ off(关闭)。', example: 'warn' },
130
134
  ],
131
135
  },
132
136
  {
@@ -151,6 +155,9 @@ export const LOCAL_YAML_SCHEMA = {
151
155
  note: 'gitignore 生成物(如构建期产出的 src/build-id.ts)不在 git 树也不进 untracked overlay(ls-files --others --exclude-standard 尊重 .gitignore),worktree 缺失致构建炸 Failed to load url——create 期按本清单从主仓复制供给(2026-09-15-worktree-dual-truth-gates 坑③,D-003@v1)。块列表或 inline flow 数组均可解析。',
152
156
  keys: [
153
157
  { path: 'worktree.supplyFiles', type: 'array', optional: true, status: 'live', readers: ['readSupplyFilesConfig + _supplyGeneratedFiles (src/worktree.js — create step 5.9 供给步)'], desc: '随 worktree create 从主仓复制的生成物清单:精确路径或 glob(* 单层 / ** 多层),相对仓根。展开上限 200 文件超出截断警告;实供清单记 meta.supplyFiles;缺省 [] = 供给步空转零行为变化。', example: 'src/build-id.ts' },
158
+ { path: 'worktree.policy.adopt_branch', type: 'boolean', optional: true, status: 'live', readers: ['readWorktreePolicy (src/worktree-policy.js) → WorktreeManager.create 分支冲突守卫 (src/worktree.js)'], desc: '分支已存在冲突的选择记忆:true = 自动收编既有分支(等效常备 --adopt-branch,meta 记 adoptViaPolicy 留痕)。缺省 false = 既有三选一 fail-closed 菜单。显式 flag 优先于 policy。', example: 'true' },
159
+ { path: 'worktree.policy.apply_overlap', type: 'enum', values: ['manual', 'force', 'skip'], optional: true, status: 'live', readers: ['readWorktreePolicy (src/worktree-policy.js) → applyWorktree guard 相交拦截 (src/worktree-apply.js)'], desc: 'apply 与活跃 quick 会话在途声明相交时的处置记忆:manual(缺省)= 既有 fail-closed 报错;force = 放行并留痕(overlapForced.via 记 policy 来源);skip = 无人值守软跳过(同 autoApply 路径)。--force 显式 flag 优先。', example: 'manual' },
160
+ { path: 'worktree.policy.stash_dirty', type: 'boolean', optional: true, status: 'live', readers: ['readWorktreePolicy (src/worktree-policy.js) → applyWorktree 4.4 stash 段 (src/worktree-apply.js)'], desc: '主仓在途改动自动 stash 的选择记忆:true = 等效常备 --stash-dirty(stash SHA 显著打印 + 失败绝不 drop)。缺省 false = 显式 flag opt-in。', example: 'false' },
154
161
  ],
155
162
  },
156
163
  {
@@ -162,6 +169,25 @@ export const LOCAL_YAML_SCHEMA = {
162
169
  { path: 'gate_snapshot.commands', type: 'array', optional: true, status: 'live', readers: ['parseGateSnapshotCommands + runGateSnapshotCommands (src/run/gate-snapshot.js — createGateSnapshot 环境预检后 copy 面前)'], desc: '门禁隔离快照的命令面(元素 string):快照构建期在环境目录链接后、copy 面前于快照根逐条执行(cwd=快照根、300s/条超时帽、非零退出/超时只 warn 继续——fail-open 不作废快照),产出「本仓应然态」生成物,收口主仓生成物缺失/过期(fresh clone 未跑 postinstall / build-id 类产物)时快照内全量 lint/test 必挂的坑(D-002@v2,2026-09-17-feedback-hardening FR-01)。⚠️ 环境目录(node_modules/venv)是活链接,命令写它们会穿透主仓——只放生成物命令(npm run gen:build-id 类),不放 install/build 全家桶。未配置 = 全段空转零行为。', example: 'npm run gen:build-id' },
163
170
  ],
164
171
  },
172
+ {
173
+ id: 'flow',
174
+ title: '2-调用轻量协议(R7 切片二)',
175
+ note: 'flow start/done 协议形状开关与路由参数。design 措辞 flow: thin|legacy 落地为单键 flow.mode(YAML 单键形态,语义一致)。',
176
+ keys: [
177
+ { path: 'flow.mode', type: 'enum', values: ['thin', 'legacy'], optional: true, status: 'live', readers: ['readFlowConfig (src/flow.js)'], desc: '2-调用轻量协议开关:thin(缺省——2026-09-25-thin-default-flip 翻转,入口归一:常规变更默认轻量跑道,需求不清晰 CLI 拦下指路头脑风暴预段,实测失败自动升厚)= flow start/done 轻量跑道;legacy = 显式回旧道(run <stage> 全族行为逐字不动,flow start 拒跑并指路)。切回一行 yaml。', example: 'thin' },
178
+ { path: 'flow.edit_ratio_threshold', type: 'number', optional: true, status: 'live', readers: ['readFlowConfig (src/flow.js)'], desc: '机器稿改写比例路由阈值(amend 通道计算的行级 editRatio 超阈 → 厚档提示 route_hint)。缺省 0.5。', example: '0.5' },
179
+ { path: 'flow.edit_ratio_enforcement', type: 'enum', values: ['advisory', 'block'], optional: true, status: 'live', readers: ['readFlowConfig (src/flow.js)'], desc: 'editRatio 超阈的执行档:advisory(缺省——测绿可轻量档过,只提示+遥测)| block(超阈阻断 flow done)。用户裁定 advisory 定案,dogfood 后可按遥测翻 block。', example: 'advisory' },
180
+ ],
181
+ },
182
+ {
183
+ id: 'stage',
184
+ title: '阶段说明书下发与会话墙',
185
+ note: 'run <stage> 渲染与阶段边界行为开关。burst 管「一次下发多少说明书」;wall 管「阶段边界要不要强制换会话」(瘦会话模式强制力)。',
186
+ keys: [
187
+ { path: 'stage.burst', type: 'boolean', optional: true, status: 'live', readers: ['readStageBurst (src/run/shared.js)'], desc: 'burst 模式:一次渲染阶段内全部剩余步骤说明书、一次 --done 收口(CLI 内部循环逐步推进)。R13 对撞实测:CLI 往返锐减(×19→×4)但 token 反创系列新高(单次载荷变肥 + 逐轮全量回放)——只减往返不减 token,非默认推荐(体验项)。env SILLYSPEC_STAGE_BURST=0/1 强制。', example: 'false' },
188
+ { path: 'stage.wall', type: 'enum', values: ['advisory', 'hard'], optional: true, status: 'live', readers: ['readStageWall (src/run/shared.js) + runStage 入口墙 (src/run/stage.js)'], desc: '阶段边界会话墙:advisory(缺省)= 阶段完成时提示可 handoff 换会话,不阻断;hard = 同一会话(SILLYSPEC_SESSION_ID 相同)刚收口前驱阶段后硬续墙后阶段(execute/verify)→ run <stage> 拒启动(exit 1),指引 sillyspec handoff 生成交接块换新会话续跑;--same-session 显式逃生口(应急/平台编排)。墙后阶段 = execute/verify(上下文最贵两段:R15 实测 execute 均轮 263K,断崖拆会话后回落 120-170K)。stage-session ledger 缺失/会话标识不可判定 → 放行(fail-open,与账本 best-effort 一致)。', example: 'hard' },
189
+ ],
190
+ },
165
191
  {
166
192
  id: 'auto_mode',
167
193
  title: '变更规模自动分类',
@@ -334,6 +360,8 @@ commands:
334
360
  lint: npm run lint
335
361
  # smoke: node scripts/smoke.mjs # verify 冒烟命令(可选;脚本自理服务生命周期,失败只封顶 PASS 不阻断)
336
362
  # install: npm install # worktree 依赖安装命令
363
+ # test_timeout_sec: 2400 # commands.test 超时秒数(慢仓提帽;缺省 600,env SILLYSPEC_TEST_TIMEOUT_MS 同效)
364
+ # lint_timeout_sec: 600 # commands.lint 超时秒数(缺省 180)
337
365
 
338
366
  # ── SillyHub MCP 客户端凭据(派发到 worker 用)──
339
367
  # agent 手填,或 sillyspec platform connect 在 mcp 段缺失时同源自动填。
@@ -355,17 +383,41 @@ dispatch:
355
383
  # poll_interval_ms: 15000 # ⚠ 路径A 预留·未落地,配了暂不生效
356
384
  # worker_timeout_ms: 60000 # ⚠ 路径A 预留·未落地,配了暂不生效
357
385
 
358
- # ── monorepo 子模块映射(test_strategy: module 时按 git diff 命中模块收窄测试)──
359
- # 只支持 inline flow 形态(嵌套展开式解析不出):
360
- modules:
361
- frontend: { path: "frontend/", test: "cd frontend && pnpm test" }
362
- backend: { path: "backend/", test: "cd backend && npm test" }
386
+ # ── 2-调用轻量协议(R7 切片二;缺省 thin 即轻量跑道,无需配置)──
387
+ # flow:
388
+ # mode: thin # thin=flow start/done 轻量跑道(协议必需交互=2)| legacy=既有 run <stage> 全族(回滚一行)
389
+ # edit_ratio_threshold: 0.5 # 机器稿改写比例路由阈值(超阈提示厚档;缺省 0.5)
390
+ # edit_ratio_enforcement: advisory # advisory=测绿可轻量过只提示(缺省)| block=超阈阻断
391
+
392
+ # ── 阶段说明书下发与会话墙(R16 减负批次)──
393
+ # stage:
394
+ # # burst: true # 一次下发全阶段说明书(R13 实测:往返↓ token↑,体验项非默认)
395
+ # # wall: hard # 阶段边界会话墙(hard=同会话硬续 execute/verify 拒启动,指引 handoff;缺省 advisory 提示不阻断)
396
+
397
+ # ── worktree 守卫选择记忆(R16 减负批次;显式 flag > policy > fail-closed 缺省)──
398
+ # worktree:
399
+ # policy:
400
+ # # adopt_branch: true # 分支已存在冲突自动收编(等效常备 --adopt-branch)
401
+ # # apply_overlap: manual # manual=fail-closed(缺省)| force=放行留痕 | skip=软跳过
402
+ # # stash_dirty: false # true=主仓在途改动自动 stash(等效常备 --stash-dirty)
363
403
 
364
- # ── 测试策略(verify 实测收窄;full/module 语义不变,skip/evidence-auto 为 2026-08-23 新增)──
365
- # full=全量 commands.test | module=按命中模块收窄(需配 modules)
404
+ # ── 测试策略(2026-09-26-dynamic-test-inference 起)──
405
+ # 缺省=动态子集:本变更测试 ∪ FR 关联回归(active FR 覆盖面∩触碰文件→绑定 tests)∪ import 依赖,
406
+ # runner 自项目结构推断(pyproject/uv.lock/package.json 就近祖先)——modules.*.test 与 commands.test
407
+ # 均不再需要(后者仅显式 full 时作全量逃生阀)。三源空(doc-only)不硬跑全量。
408
+ # full=全量(commands.test 在场生效,否则按 package.json scripts.test / pyproject 推断)
366
409
  # skip=真跳过测试(不回退全量,verify 输出显式标注留审计痕迹)
367
- # evidence-auto=按变更 module-impact.md 影响面推荐检查组合(行为→module 聚焦测试、文档→docs-check、门禁→gate;缺失降级 module)
368
- test_strategy: full
410
+ # evidence-auto=按变更 module-impact.md 影响面推荐(行为→动态子集、文档→docs-check、门禁→gate)
411
+ # test_strategy: full # 缺省注释态=动态子集(评审 P3-5 清偿:复制即全量道的自相矛盾陷阱——缺省注释才与上方「缺省=动态子集」一致);确要全量再解注释
412
+
413
+ # ── 证据门档位(2026-09-27-ui-visual-guidance / 2026-09-27-hunk-attribution-gate;注释态=缺省档位生效)──
414
+ # ui_visual_gate: warn # UI 视觉证据分级门:warn(缺省,缺 visual-evidence.md 仅警告)| error(缺证据即阻断)| off(探针整体关闭;视觉降级无用户裁决留痕时无论档位恒阻断)
415
+ # hunk_gate: warn # 提交面行级归属门:warn(缺省)| error(未归因文件/跨变更竞争任一在场阻断收口;在途残留恒仅警告——并发 WIP 弱信号不硬拦)| off(关闭)
416
+
417
+ # ── monorepo 子模块路径映射(.path 仍被 plan/worktree-deps 消费;.test 已退役勿再配)──
418
+ modules:
419
+ frontend: { path: "frontend/" }
420
+ backend: { path: "backend/" }
369
421
 
370
422
  # ── 决策库 behind 复核阈值(docs-check 决策规则:源码在「最近确认」后前进超阈值 → 待复核提示;缺省 10)──
371
423
  decisions: