sillyspec 3.29.5 → 3.31.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 (110) hide show
  1. package/.claude/skills/sillyspec-auto/SKILL.md +1 -1
  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 +7 -105
  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-brainstorm.md +1 -1
  10. package/assets/command-cards/run-quick.md +8 -25
  11. package/package.json +2 -1
  12. package/packages/dashboard/server/executor.js +2 -1
  13. package/packages/dashboard/server/parser.js +7 -7
  14. package/r7-test-env/README-R7-TEST.md +93 -0
  15. package/r7-test-env/demo-project/lib/calc.js +6 -0
  16. package/r7-test-env/demo-project/package.json +1 -0
  17. package/r7-test-env/demo-project/test.js +10 -0
  18. package/r7-test-env/prompt-R7-SMOKE.md +41 -0
  19. package/r7-test-env/sillyspec-r7.cmd +3 -0
  20. package/round4/account.mjs +18 -5
  21. package/round4/b1-analyze-task08.mjs +40 -0
  22. package/round4/b1-b1-target-validation.md +32 -0
  23. package/round4/b3a-prompt-audit-result.md +66 -0
  24. package/round4/b3a-prompt-audit.mjs +89 -0
  25. package/round4/optimization-plan.md +165 -0
  26. package/round4/r4-final-report.html +347 -0
  27. package/round4/r5-scenario-matrix.md +46 -0
  28. package/src/change-list.js +9 -0
  29. package/src/classify-change.js +6 -0
  30. package/src/command-cards.js +2 -1
  31. package/src/commit-guard.js +2 -0
  32. package/src/config-schema.js +64 -12
  33. package/src/db.js +35 -4
  34. package/src/decision-distill.js +9 -3
  35. package/src/docs-check.js +1 -1
  36. package/src/doctor-diagnostics.js +44 -2
  37. package/src/flow-draft.js +748 -0
  38. package/src/flow-parity.js +236 -0
  39. package/src/flow-review.js +184 -0
  40. package/src/flow.js +1492 -0
  41. package/src/foreign-declared.js +17 -1
  42. package/src/fr-index.js +396 -22
  43. package/src/fs-atomic.js +5 -1
  44. package/src/git-helper.js +2 -2
  45. package/src/greenfield-bootstrap.js +98 -0
  46. package/src/handoff.js +120 -7
  47. package/src/hunk-attribution.js +191 -0
  48. package/src/index.js +570 -16
  49. package/src/knowledge-classify.js +47 -1
  50. package/src/knowledge-digest.js +162 -0
  51. package/src/knowledge-quicklog.js +246 -0
  52. package/src/machine-draft.js +128 -0
  53. package/src/machine-interface.js +107 -5
  54. package/src/mcp-server.js +1 -0
  55. package/src/module-resolve.js +3 -1
  56. package/src/preview-progress.js +160 -0
  57. package/src/progress/change-registry.js +11 -3
  58. package/src/progress/shared.js +3 -2
  59. package/src/progress.js +56 -13
  60. package/src/quicklog.js +44 -6
  61. package/src/redomain.js +147 -0
  62. package/src/review-material-pack.js +204 -1
  63. package/src/run/archive-distill.js +4 -2
  64. package/src/run/bg-sync.js +67 -0
  65. package/src/run/command.js +123 -10
  66. package/src/run/complete-handlers.js +327 -72
  67. package/src/run/complete.js +350 -71
  68. package/src/run/gate-snapshot-ledger.js +213 -0
  69. package/src/run/gate-snapshot.js +250 -34
  70. package/src/run/gates.js +370 -233
  71. package/src/run/green-cache.js +123 -0
  72. package/src/run/junction-rm.js +70 -0
  73. package/src/run/next.js +14 -0
  74. package/src/run/prompt.js +185 -55
  75. package/src/run/quick-audit.js +185 -12
  76. package/src/run/shared.js +120 -3
  77. package/src/run/stage.js +182 -216
  78. package/src/run/test-ledger.js +264 -0
  79. package/src/run/verify-quality-scan.js +84 -7
  80. package/src/scope-audit.js +6 -1
  81. package/src/sentinel-assertions.js +114 -0
  82. package/src/setup.js +3 -3
  83. package/src/spec-sync.js +41 -1
  84. package/src/stage-contract.js +26 -8
  85. package/src/stage-review-checklist.js +2 -0
  86. package/src/stage-review.js +7 -2
  87. package/src/stage-templates.js +157 -0
  88. package/src/stages/archive.js +2 -0
  89. package/src/stages/brainstorm.js +24 -106
  90. package/src/stages/execute.js +221 -84
  91. package/src/stages/knowledge.js +74 -1
  92. package/src/stages/plan-postcheck.js +352 -1
  93. package/src/stages/plan.js +23 -1
  94. package/src/stages/quick.js +10 -2
  95. package/src/stages/verify.js +4 -2
  96. package/src/sync.js +81 -23
  97. package/src/task-done.js +181 -0
  98. package/src/task-review.js +8 -55
  99. package/src/test-bindings.js +549 -0
  100. package/src/timeline.js +218 -0
  101. package/src/ui-visual.js +175 -0
  102. package/src/verify-draft.js +214 -0
  103. package/src/verify-postcheck.js +860 -158
  104. package/src/verify-probes.js +59 -3
  105. package/src/watcher.js +1031 -0
  106. package/src/worktree-apply.js +44 -4
  107. package/src/worktree-deps.js +22 -8
  108. package/src/worktree-policy.js +42 -0
  109. package/src/worktree.js +102 -15
  110. package/templates/agents-instruction.md +37 -18
@@ -0,0 +1,10 @@
1
+ import assert from 'node:assert/strict'
2
+ import { add, sub, div } from './lib/calc.js'
3
+ assert.equal(add(1, 2), 3)
4
+ console.log('test ok: add(1,2)=3')
5
+ assert.equal(sub(5, 3), 2)
6
+ console.log('test ok: sub(5,3)=2')
7
+ assert.equal(div(6, 3), 2)
8
+ console.log('test ok: div(6,3)=2')
9
+ assert.throws(() => div(1, 0), { message: 'div by zero' })
10
+ console.log('test ok: div(1,0) throws div by zero')
@@ -0,0 +1,41 @@
1
+ # R7 薄跑烟测提示词(贴给一个全新 agent 会话;30min 级小任务)
2
+
3
+ 你是一个开发会话,任务:在下面的演示项目里完成一个小功能。本项目接入了一套新的
4
+ 「2-调用」开发协议(flow),你是它的第一批真实用户——按协议干活即可,协议没让你做的事
5
+ 就不要做。
6
+
7
+ 【环境】
8
+ - 工作目录:C:\Users\qinyi\IdeaProjects\sillyspec\r7-test-env\demo-project(所有命令在此执行)
9
+ - CLI 入口(R7 版):cmd //c ..\sillyspec-r7.cmd <命令...>
10
+ (Git Bash 形态;PowerShell/cmd 形态:..\sillyspec-r7.cmd <命令...>)
11
+ - 会话标识:先执行 export SILLYSPEC_SESSION_ID=r7-smoke-1
12
+ - 项目现状:lib/calc.js 有 add;test.js 用断言风格测试;测试命令 node test.js
13
+
14
+ 【任务】
15
+ 给 calc 库增加两个函数并配套测试:
16
+ 1. sub(a,b) 减法——成功标准:sub(5,3)=2 有测试
17
+ 2. div(a,b) 除法,除零抛 Error('div by zero')——成功标准:div(6,3)=2 与除零抛错都有测试
18
+ 既有 add 测试不得回归。
19
+
20
+ 【协议契约——只有 2 次协议调用】
21
+ 1. 第一次:cmd //c ..\sillyspec-r7.cmd flow start --change r7-smoke-add-sub-div --input "<把上面任务原话贴进去>"
22
+ ——它会告诉你材料在哪、怎么干活。治理文档(提案/需求/任务清单)由 CLI 自动起草,你不要手写。
23
+ 2. 中间:正常开发。改代码、写测试、git 提交(git add -A && git commit -m "...")。
24
+ 不要跑任何 sillyspec run <stage> 命令;progress show 等只读命令也不必用——保持最小。
25
+ 如果你觉得自动起草的文档里机器写的部分说错了,唯一合法修改通道是 flow amend-draft
26
+ (命令形态在上面输出里找);不想改就直接忽略,不影响验收。
27
+ 3. 第二次:干完并提交后 cmd //c ..\sillyspec-r7.cmd flow done --change r7-smoke-add-sub-div
28
+ ——它是唯一裁决点:会真跑测试,失败会整单 FAIL(修好重跑同一条命令即可,断点自动续)。
29
+
30
+ 【边界】
31
+ - 全程协议类调用只许上述 2 次(这是被测量的数字)。
32
+ - 不要读 sillyspec 的源码或它的变更文档(.sillyspec/changes/archive/**)——你是用户不是评审。
33
+ - .sillyspec/ 目录里不要手写任何文件(这也是被测量的面)。
34
+ - 测试必须真实通过;node test.js 自己先跑绿再 flow done。
35
+
36
+ 【完成后汇报(务必按此格式,这是测试数据)】
37
+ 1. 协议调用清单:每条 sillyspec 命令原文+次数
38
+ 2. .sillyspec 写入清单:你亲手写过的文件(应为零;若用了 amend-draft 如实列出)
39
+ 3. 摩擦记录:协议该给你而没给的信息/你想做但被拦的事,逐条列(没有写「无」)
40
+ 4. flow done 是否一次通过;若失败过,失败原因与重入体验
41
+ 5. 一句话:这个流程 compared 于你平时用的开发流程,最不习惯的一点是什么
@@ -0,0 +1,3 @@
1
+ @echo off
2
+ rem R7 test build of sillyspec - runs repo checkout directly (no global install, parallel sessions on 3.29.6 unaffected)
3
+ node "C:\Users\qinyi\IdeaProjects\sillyspec\src\index.js" %*
@@ -33,8 +33,11 @@ const rows = db.prepare(
33
33
  ).all(...titleKw.map(k => '%' + k + '%'));
34
34
 
35
35
  // 2) 每会话聚合(主会话 + 递归子会话),窗口=会话创建起 48h 防 spill
36
+ // v2(2026-09-21 R5 准备):三分扩展——新鲜 input(=input−cache_read)、缓存读、输出,
37
+ // 及账单当量两界(方案 v3.2 口径:新入 1× / 缓存 0.1× / 输出 3–5×,R5 验收判法依赖)
36
38
  const aggFor = (sid) => db.prepare(
37
39
  `SELECT COUNT(*) req, SUM(computed_total_tokens) tok, SUM(input_tokens) itok, SUM(output_tokens) otok,
40
+ SUM(cache_read_input_tokens) cr,
38
41
  SUM(duration_ms) dur, MIN(started_at) mn, MAX(started_at) mx, SUM(tool_call_count) tools
39
42
  FROM model_usage WHERE session_id = ? AND started_at >= ?`
40
43
  );
@@ -53,33 +56,43 @@ for (const s of rows) {
53
56
  const self = aggFor(s.id).get(winStart > 0 ? winStart : 0);
54
57
  // 请求窗口上界也钳(started_at < winEnd)
55
58
  const inWin = (r) => { const a = db.prepare(
56
- `SELECT COUNT(*) req, SUM(computed_total_tokens) tok, SUM(duration_ms) dur FROM model_usage
59
+ `SELECT COUNT(*) req, SUM(computed_total_tokens) tok, SUM(duration_ms) dur,
60
+ SUM(input_tokens) itok, SUM(output_tokens) otok, SUM(cache_read_input_tokens) cr
61
+ FROM model_usage
57
62
  WHERE session_id = ? AND started_at >= ? AND started_at < ?`
58
63
  ).get(r, winStart, winEnd); return a; };
59
64
  const mainAgg = inWin(s.id);
60
- let kidReq = 0, kidTok = 0, kidDur = 0;
65
+ let kidReq = 0, kidTok = 0, kidDur = 0, kidIt = 0, kidCr = 0, kidOt = 0;
61
66
  for (const k of kids) {
62
67
  const a = inWin(k.id); kidReq += a.req ?? 0; kidTok += a.tok ?? 0; kidDur += a.dur ?? 0;
68
+ kidIt += a.itok ?? 0; kidCr += a.cr ?? 0; kidOt += a.otok ?? 0;
63
69
  }
64
70
  const wall = mainAgg.req > 0 || kidReq > 0 ? null : null;
65
71
  const span = db.prepare(
66
72
  `SELECT MIN(started_at) mn, MAX(started_at) mx FROM model_usage WHERE session_id = ?`
67
73
  ).get(s.id);
68
74
  const spanMs = (toMs(span.mx) ?? 0) - (toMs(span.mn) ?? 0);
75
+ // 三分与当量(新鲜 = input − cache_read,钳 ≥0 防口径倒挂;当量两界 = 输出 3×/5×)
76
+ const mIt = mainAgg.itok ?? 0, mCr = mainAgg.cr ?? 0, mOt = mainAgg.otok ?? 0;
77
+ const tIt = mIt + kidIt, tCr = mCr + kidCr, tOt = mOt + kidOt;
78
+ const fresh = Math.max(0, tIt - tCr);
79
+ const eq3 = fresh + 0.1 * tCr + 3 * tOt;
80
+ const eq5 = fresh + 0.1 * tCr + 5 * tOt;
69
81
  results.push({
70
82
  id: s.id, title: s.title, kids: kids.length,
71
83
  mainReq: mainAgg.req ?? 0, mainTok: mainAgg.tok ?? 0, mainDur: mainAgg.dur ?? 0,
72
84
  kidReq, kidTok, kidDur,
73
85
  totReq: (mainAgg.req ?? 0) + kidReq, totTok: ((mainAgg.tok ?? 0) + kidTok),
74
86
  spanMin: spanMs / 60000,
87
+ fresh, cacheR: tCr, out: tOt, eq3, eq5,
75
88
  });
76
89
  }
77
90
 
78
91
  // 3) 输出
79
- console.log(`| 会话 | 标题 | 子代 | 主会话 req/tok/model-time | 子代 req/tok | 合计 req | 合计 tok | 活动跨度 |`);
80
- console.log(`|---|---|---|---|---|---|---|---|`);
92
+ console.log(`| 会话 | 标题 | 子代 | 主会话 req/tok/model-time | 子代 req/tok | 合计 req | 合计 tok | 活动跨度 | 新鲜in | 缓存R | 输出 | 当量@3× | 当量@5× |`);
93
+ console.log(`|---|---|---|---|---|---|---|---|---|---|---|---|---|`);
81
94
  for (const r of results) {
82
- console.log(`| ${r.id} | ${(r.title ?? '').slice(0, 40).replace(/\|/g, '/')} | ${r.kids} | ${r.mainReq} / ${fmtTok(r.mainTok)} / ${fmtMin(r.mainDur)} | ${r.kidReq} / ${fmtTok(r.kidTok)} | ${r.totReq} | ${fmtTok(r.totTok)} | ${fmtMin(r.spanMs ?? r.spanMin * 60000)} |`);
95
+ console.log(`| ${r.id} | ${(r.title ?? '').slice(0, 40).replace(/\|/g, '/')} | ${r.kids} | ${r.mainReq} / ${fmtTok(r.mainTok)} / ${fmtMin(r.mainDur)} | ${r.kidReq} / ${fmtTok(r.kidTok)} | ${r.totReq} | ${fmtTok(r.totTok)} | ${fmtMin(r.spanMs ?? r.spanMin * 60000)} | ${fmtTok(r.fresh)} | ${fmtTok(r.cacheR)} | ${fmtTok(r.out)} | ${fmtTok(r.eq3)} | ${fmtTok(r.eq5)} |`);
83
96
  }
84
97
  if (results.length === 0) console.log('(无匹配会话——检查标题关键词或 --since');
85
98
  db.close();
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ // B-① 靶点验证:解剖 R4-L 的 8.6M 实现子代理——读了什么、多大、是否越界
3
+ // 用法:node b1-analyze-task08.mjs
4
+ import { DatabaseSync } from 'node:sqlite';
5
+ const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
6
+ const sid = 'sess_subagent_agent_d60364e3-c378-49b8-a715-6ac5b9d9aa4f';
7
+ const WT = 'C:\\Users\\qinyi\\IdeaProjects\\multi-agent-platform\\.sillyspec\\.runtime\\worktrees\\2026-09-20-r4-session-replay';
8
+
9
+ const parts = db.prepare(
10
+ 'SELECT data, time_created tc FROM part WHERE session_id=? ORDER BY time_created ASC, sequence ASC'
11
+ ).all(sid);
12
+ const t0 = Number(parts[0].tc);
13
+ const rows = [];
14
+ for (const row of parts) {
15
+ const d = JSON.parse(row.data);
16
+ if (d.type !== 'tool') continue;
17
+ const rel = ((Number(d.time?.created ?? row.tc) - t0) / 60000).toFixed(0);
18
+ const inp = d.state?.input ?? {};
19
+ const out = String(d.state?.output ?? '');
20
+ const kb = Math.round(out.length / 1024);
21
+ const short = (p) => String(p).split(WT + '\\').pop()?.replaceAll('\\', '/') ?? p;
22
+ let detail = '';
23
+ if (d.tool === 'Read') detail = short(inp.file_path ?? '?');
24
+ else if (d.tool === 'Grep') detail = 'q=' + String(inp.pattern ?? inp.query ?? '').slice(0, 40);
25
+ else if (d.tool === 'Bash') detail = String(inp.command ?? '').slice(0, 70);
26
+ else detail = JSON.stringify(inp).slice(0, 60);
27
+ rows.push({ rel, tool: d.tool, detail, kb, status: d.state?.status });
28
+ }
29
+ const byTool = {};
30
+ for (const r of rows) byTool[r.tool] = (byTool[r.tool] ?? 0) + r.kb;
31
+ console.log('tool calls:', rows.length, '| 按工具 KB:', JSON.stringify(byTool));
32
+ console.log('--- 全部调用(时间 | 工具 | 输出KB | 详情)---');
33
+ for (const r of rows) console.log(`${r.rel}m ${r.tool.padEnd(7)} ${String(r.kb).padStart(6)}KB ${r.detail}`);
34
+ console.log('--- Read 同文件累计 ---');
35
+ const byPath = {};
36
+ for (const r of rows) if (r.tool === 'Read') (byPath[r.detail] ??= []).push(r.kb);
37
+ const s = (a) => a.reduce((x, y) => x + y, 0);
38
+ for (const [p, arr] of Object.entries(byPath).sort((a, b) => s(b[1]) - s(a[1])))
39
+ console.log(`${String(s(arr)).padStart(6)}KB ×${arr.length} ${p}`);
40
+ db.close();
@@ -0,0 +1,32 @@
1
+ # B-① 靶点验证报告(2026-09-21,第 1 批执行产物)
2
+
3
+ > 预设判定规则(optimization-plan.md B-①):「靶子不实不立项」。
4
+ > 数据源:zcode db(C:/Users/qinyi/.zcode/cli/db/db.sqlite)sess_5cb66a7e(R4-L 主会话)及其 19 个子会话;工具 b1-analyze-task08.mjs。
5
+
6
+ ## 判定:靶子不实——「越界读」零发生,B-① 实现项按预案砍掉
7
+
8
+ ### 证据一:8.6M 的构成不是「读了 8.6M 新内容」
9
+
10
+ task-08 子代理(sess_subagent_agent_d60364e3,58 请求)账面:名义输入 8.57M / 缓存读 8.39M(98%)/ 输出 0.07M / **新鲜输入(名义−缓存)仅 186K**。
11
+
12
+ 全部 62 次工具调用的输出总量 ≈335KB(Read 297KB + Bash 34KB)——与 186K 新鲜输入同量级自洽。8.6M 名义体量 = **58 轮 × 轮均 148K 上下文的累积重发**,是轮数乘上下文的机械积,不是读取行为。
13
+
14
+ ### 证据二:读取内容全部在任务契约链内,无一次越界
15
+
16
+ 62 次调用的读取对象逐条核过:task-08.md 任务卡、CLAUDE.md、turn-timeline.tsx(被适配组件)/ agent-log-card / turn-segment-views / session-log-assembler / runtime-session-helpers(契约链组件)、agent-log-card.test.tsx(测试先例)、session-panel-page(接线单点)、api-types / query-keys / agent-logs / round-divider(类型与工具链)、design.md + prototype-agent-replay.html(变更文档)。**没有一次读声明面之外的源码**,没有 node_modules / daemon / backend 深潜。重复读是「首次全读 + 后续定向切片」模式(如 turn-timeline 62KB 全读 + 16KB 切片),本身是省 token 的正确行为。
17
+
18
+ ### 证据三:全扇出面同构——新鲜内容只占 3.2%
19
+
20
+ 19 个子代理合计:名义输入 41.77M,**新鲜输入 1.34M(3.2%)**,输出 0.49M。各角色轮均上下文 35K–92K,唯 task-08 达 148K(契约链文件大:组件 78KB + 测试先例 37KB + design 15KB + prototype 14KB 全量进上下文)。
21
+
22
+ ## 处置(按预案预设规则)
23
+
24
+ 1. **砍掉第 2 批的「B-① 读清单注入」实现项**。读上界就是 1.34M 新鲜内容,其中「本可不读」的部分即使砍半也只有 ~0.7M 名义,对 42.3M 扇出是零头;allowed_paths 工作目录约束(子代理 prompt 已有)维持现状即够。B-① 前置验证本身完成使命。
25
+ 2. **真正杠杆换位:轮数 × 上下文双乘数**。42.3M ≈ Σ(轮数 × 轮均上下文),两个乘数各有对策:
26
+ - **上下文**:B-④ 材料包治这个——task-08 型大契约链任务(design/prototype 通读 + 大组件全量进上下文)正是材料包的靶子,且比原估计更实(148K vs 同侪 45–92K 的差额就是可压空间)。
27
+ - **轮数**:**新增候选 B-⑥ 轮数纪律**(提示词级)——task-08 的 58 轮里 Edit×7(相邻同文件逐个改)+ TodoWrite×4(每条占一轮重发 148K)+ 测试 Bash 循环多次;合并相邻 Edit、TodoWrite 降频、测试合并跑,砍 1/3 轮 ≈ 砍 1/3 名义体量。此项原方案未覆盖,性价比高于已砍的 B-①。
28
+ 3. **R5 预期路径修正**:扇出 42.3M → 28–32M 的驱动从「①②③④ 并用」改为「**B-④ 上下文压缩 + B-⑥ 轮数纪律**」双轮驱动;账单当量口径下缓存重发本就计 0.1×,硬门(扇出 ≤32M)以名义口径计不受影响。
29
+
30
+ ## 复核方式
31
+
32
+ `node round4/b1-analyze-task08.mjs` 重跑可复现证据一/二;证据三的聚合查询见本报告数据源行(account.mjs 同库同表 model_usage,input−cache_read 即新鲜口径)。
@@ -0,0 +1,66 @@
1
+ # B3a prompt 审计——db 全量口径(2026-09-21,v3 修正版)
2
+
3
+ ## A. CLI 渲染体量(R4-L 主会话,129 次 sillyspec Bash,合计 204KB ≈ 60K tokens)
4
+
5
+ | 子命令 | 次数 | 累计KB | 最大单次KB |
6
+ |---|---|---|---|
7
+ | run | 53 | 98.4 | 6.7 |
8
+ | ? | 45 | 70.8 | 5.2 |
9
+ | verify-probes | 4 | 10.2 | 7.9 |
10
+ | show | 1 | 9.9 | 9.9 |
11
+ | register-stage-review | 5 | 3.1 | 1.8 |
12
+ | review | 7 | 2.8 | 0.6 |
13
+ | taskcard | 1 | 2.7 | 2.7 |
14
+ | progress | 3 | 2.4 | 1.5 |
15
+ | gate | 2 | 1.7 | 1.2 |
16
+ | module-docs-sync | 2 | 0.5 | 0.3 |
17
+ | endpoints | 1 | 0.4 | 0.4 |
18
+ | design-init | 1 | 0.3 | 0.3 |
19
+ | brainstorm | 1 | 0.3 | 0.3 |
20
+ | git | 1 | 0.2 | 0.2 |
21
+ | module-impact | 1 | 0.1 | 0.1 |
22
+ | worktree | 1 | 0.0 | 0.0 |
23
+
24
+ ## B. 近重复渲染(头部签名相同出现 >1 次——重复注入的直接瘦身候选)
25
+
26
+ | 次数 | 单次体量 | 头部签名 |
27
+ |---|---|---|
28
+ | ×2 | ~2.6KB | --- stage: brainstorm step: 7/8 stepName: Design Grill 交叉审查 project: project change: 2026- |
29
+ | ×2 | ~0.3KB | ⚠ 未匹配模块的文件 24 个(不入 sidecar): backend/app/modules/platform_sync/router.py, backend/app/modu |
30
+ | ×2 | ~0.0KB | (Bash completed with no output) |
31
+
32
+ 近重复渲染累计 ≈6KB(占 CLI 渲染总量 3%)。
33
+
34
+ ## C. 实跑措辞规则转发率(execute.js buildWavePrompt 口径 → 编排者组装的子代理 prompt)
35
+
36
+ | 规则(实跑措辞) | CLI 渲染 | 转发进子代理 prompt |
37
+ |---|---|---|
38
+ | workdir 参数是强制必传 | 2 | 0 |
39
+ | 破坏隔离 | 2 | 0 |
40
+ | 调度者 + 审查者 | 2 | 0 |
41
+ | 你不要自己写代码 | 4 | 0 |
42
+ | 禁止读 | 0 | 16 |
43
+ | 禁止 push | 0 | 12 |
44
+ | 工作目录(强制 | 0 | 12 |
45
+ | allowed_paths | 30 | 0 |
46
+ | TDD | 0 | 0 |
47
+ | 先读后写 | 0 | 0 |
48
+
49
+ Agent 派发 19 次,prompt 合计 49.8KB(均值 2.6KB,最大 5KB)。
50
+
51
+ ## D. 解读与瘦身候选(B3a 结论,2026-09-21)
52
+
53
+ **总口径**:R4-L 主会话 CLI 渲染 204KB ≈ 60K tokens(占主会话名义 56.8M 的 ~0.1%,占峰值的次要面)——CLI 渲染不是 377K 峰值的主因(主因是会话累积),但每次渲染常驻上下文参与后续所有轮次的重发,瘦身仍有正收益。
54
+
55
+ **证据性发现**:
56
+ 1. **近重复渲染只占 3%(~6KB)**——「同一指令反复整体重渲染」不是成本大头,各步渲染因进度态不同而不同。去重渲染**不是**瘦身抓手,预期收益上限低。
57
+ 2. **run 子命令是渲染大头**:53 次 / 98.4KB(步骤指令渲染,单次最大 6.7KB)。同一阶段的步骤指令在 --done 循环中被多次近似重渲染(内容 90% 相同、状态行不同)。
58
+ 3. **编排者对派发规则是「提取规范、丢弃论述」模式**:CLI 渲染的 workdir 论述段(强制必传 + 破坏隔离后果 + json 范例)转发进子代理 prompt 的字面率为 0,编排者自写成紧凑隔离块(工作目录(强制 ×12 / 禁止读 ×16 / 禁止 push ×12,每条 ~50 字)。行为合规(worktree 隔离全程成立),说明**论述段被读过但未被复述**——其价值存疑但不能仅凭字面率为 0 判死(合规可能正来自读过论述)。
59
+ 4. allowed_paths 渲染 30 次、转发 0——但审查环节逐 task 对照 allowed_paths 检查(行为消费),属「CLI ↔ 门禁」消费而非 prompt 转发,保留。
60
+
61
+ **瘦身候选(供 B3b 依审计删减,全部低风险渐进)**:
62
+ - **C1(首选)run 步骤渲染增量化**:同阶段同步骤的重复渲染只出「状态 delta + 指令不变声明」,首渲染出全量。预计砍 run 渲染体量 30–50%(≈30–50KB/大任务)。机制级(CLI 渲染器小改),不是删规则——**不动规则内容**。
63
+ - **C2(次选,低置信)派发指令论述段压缩**:workdir/隔离的后果论述段压成一行规范 + 一行后果(保留 json 范例与 workdir 值)。省 ~1–2KB/次渲染。风险:论述可能支撑合规——R5 若有隔离事故即回滚。
64
+ - **不建议动**:四律请求钳(H3 实证 PASS 承重)、隔离规范行、allowed_paths、testcase-design 段(TDD 引导,taskcard 证据链)。
65
+
66
+ **方法论修正记录**:v1 transcript 口径因提取稿 700 字截断致规则渲染面全盲(17 签名 15 个零命中假象);v2 分类正则漏多 flag 前缀;v3 修正后数据可信。B3b 删任何规则前须按本 v3 口径复跑 + 行为级合规核查(字面转发率 ≠ 遵守率,本审计已实证两者背离)。
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ // B3a prompt 审计 v3(只读,db 全量口径):
3
+ // A. R4-L 主会话 CLI 渲染体量按子命令归因(修正 v2 分类正则)
4
+ // B. 近重复渲染检测(同头签名多次渲染 = 瘦身/缓存首要候选)
5
+ // C. 实跑措辞的规则转发率(execute.js buildWavePrompt 口径)
6
+ // 用法:node b3a-prompt-audit.mjs
7
+ import { DatabaseSync } from 'node:sqlite';
8
+ import { writeFileSync } from 'node:fs';
9
+
10
+ const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
11
+ const sid = 'sess_5cb66a7e-2ba6-44f9-9916-226fc553778b';
12
+ const parts = db.prepare(
13
+ 'SELECT data, time_created tc FROM part WHERE session_id=? ORDER BY time_created ASC, sequence ASC'
14
+ ).all(sid);
15
+ const t0 = Number(parts[0].tc);
16
+
17
+ const calls = [];
18
+ const agentPrompts = [];
19
+ for (const row of parts) {
20
+ const d = JSON.parse(row.data);
21
+ if (d.type !== 'tool') continue;
22
+ const rel = ((Number(d.time?.created ?? row.tc) - t0) / 60000).toFixed(0);
23
+ const inp = d.state?.input ?? {};
24
+ if (d.tool === 'Bash') {
25
+ const cmd = String(inp.command ?? '');
26
+ if (!/sillyspec/.test(cmd)) continue;
27
+ // 子命令 = sillyspec 后跳过所有 --flag(含带引号值)后的第一个词
28
+ const m = cmd.match(/sillyspec\s+(?:--[\w-]+(?:\s+(?:"[^"]*"|\S+))?\s+)*([\w-]+)/);
29
+ calls.push({ rel, sub: m ? m[1] : '?', chars: String(d.state?.output ?? '').length, out: String(d.state?.output ?? '') });
30
+ }
31
+ if (d.tool === 'Agent' || d.tool === 'Task')
32
+ agentPrompts.push({ rel, prompt: String(inp.prompt ?? '') });
33
+ }
34
+
35
+ const by = {};
36
+ for (const c of calls) {
37
+ by[c.sub] ??= { n: 0, chars: 0, max: 0 };
38
+ by[c.sub].n++; by[c.sub].chars += c.chars; by[c.sub].max = Math.max(by[c.sub].max, c.chars);
39
+ }
40
+ const total = Object.values(by).reduce((s, v) => s + v.chars, 0);
41
+
42
+ // 近重复:输出头部 200 字(压缩空白)做签名
43
+ const sig = {};
44
+ for (const c of calls) {
45
+ const s = c.out.slice(0, 200).replace(/\s+/g, ' ').replace(/\|/g, '/');
46
+ (sig[s] ??= []).push(c);
47
+ }
48
+ const dups = Object.entries(sig).filter(([, v]) => v.length > 1).sort((a, b) => b[1].length - a[1].length);
49
+
50
+ // 实跑措辞规则转发率
51
+ const SIGS = [
52
+ 'workdir 参数是强制必传', '破坏隔离', '调度者 + 审查者', '你不要自己写代码',
53
+ '禁止读', '禁止 push', '工作目录(强制', 'allowed_paths', 'TDD', '先读后写',
54
+ ];
55
+ const cliAll = calls.map(c => c.out).join('\n');
56
+ const agentAll = agentPrompts.map(a => a.prompt).join('\n');
57
+
58
+ const L = [];
59
+ L.push('# B3a prompt 审计——db 全量口径(2026-09-21,v3 修正版)');
60
+ L.push('');
61
+ L.push(`## A. CLI 渲染体量(R4-L 主会话,${calls.length} 次 sillyspec Bash,合计 ${(total / 1024).toFixed(0)}KB ≈ ${Math.round(total / 3.5 / 1000)}K tokens)`);
62
+ L.push('');
63
+ L.push('| 子命令 | 次数 | 累计KB | 最大单次KB |');
64
+ L.push('|---|---|---|---|');
65
+ for (const [k, v] of Object.entries(by).sort((a, b) => b[1].chars - a[1].chars))
66
+ L.push(`| ${k} | ${v.n} | ${(v.chars / 1024).toFixed(1)} | ${(v.max / 1024).toFixed(1)} |`);
67
+ L.push('');
68
+ L.push('## B. 近重复渲染(头部签名相同出现 >1 次——重复注入的直接瘦身候选)');
69
+ L.push('');
70
+ L.push('| 次数 | 单次体量 | 头部签名 |');
71
+ L.push('|---|---|---|');
72
+ for (const [k, v] of dups.slice(0, 10))
73
+ L.push(`| ×${v.length} | ~${(v[0].chars / 1024).toFixed(1)}KB | ${k.slice(0, 90)} |`);
74
+ const dupChars = dups.reduce((s, [, v]) => s + v.length * v[0].chars, 0);
75
+ L.push('');
76
+ L.push(`近重复渲染累计 ≈${(dupChars / 1024).toFixed(0)}KB(占 CLI 渲染总量 ${((dupChars / total) * 100).toFixed(0)}%)。`);
77
+ L.push('');
78
+ L.push('## C. 实跑措辞规则转发率(execute.js buildWavePrompt 口径 → 编排者组装的子代理 prompt)');
79
+ L.push('');
80
+ L.push('| 规则(实跑措辞) | CLI 渲染 | 转发进子代理 prompt |');
81
+ L.push('|---|---|---|');
82
+ for (const s of SIGS)
83
+ L.push(`| ${s} | ${cliAll.split(s).length - 1} | ${agentAll.split(s).length - 1} |`);
84
+ L.push('');
85
+ L.push(`Agent 派发 ${agentPrompts.length} 次,prompt 合计 ${(agentPrompts.reduce((s, a) => s + a.prompt.length, 0) / 1024).toFixed(1)}KB(均值 ${(agentPrompts.reduce((s, a) => s + a.prompt.length, 0) / agentPrompts.length / 1024).toFixed(1)}KB,最大 ${Math.max(...agentPrompts.map(a => a.prompt.length)) / 1024 | 0}KB)。`);
86
+ const outPath = new URL('b3a-prompt-audit-result.md', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1');
87
+ writeFileSync(outPath, L.join('\n') + '\n', 'utf8');
88
+ console.log(L.join('\n'));
89
+ db.close();
@@ -0,0 +1,165 @@
1
+ # sillyspec 效率优化整体方案 v3(2026-09-21 整合版)
2
+
3
+ > 靶子(R4 实测,账单当量口径 = 新入 1× / 缓存 ~0.1× / 输出 3–5× 折算):
4
+ > **大任务账单当量 2.4×(8.04 当量差)= 缓存体量差 55%(4.45)+ 扇出冷启动 26%(2.09)+ 输出差 19%(1.50,其中 77% 是子代理代码/测试产出=交付厚度,不砍)**。
5
+ > 墙钟:大 2×、小 1.3×,差距全在非模型时间(门禁循环 + 编排等待)。
6
+ > 红线:**不动四道防线**(审查/门禁/核验/资产);不砍交付厚度(输出差是产品)。所有优化只打三样:冗余重读、冷启动、等待。
7
+
8
+ ## 战线 A:已落地,待 R5 验收(不重规划)
9
+
10
+ | 项 | 状态 |
11
+ |---|---|
12
+ | 门禁四项:模块粒度范围化 / fail-fast 前置 / lint 归属降档两门 / 超时帽 | 已提交(83d91cd4 / 2eba595c,模块粒度 v3.24 在场) |
13
+ | ~~增量复用~~ | **正式摘出(2026-09-21 R5 准备核对)**:src/ROADMAP/终报/batch2 四处查无落码与定义,承办无着落;疑即 ROADMAP 延后项「探针增量缓存」(quick-4af1acc3 D②:失效面广需独立失效契约)——按延后项处理,不计入战线 A,R5 验收不背此项 |
14
+ | gate verify lint parity / module-impact 引号+多map / Wave 并发帽 ≤3 | 已提交 61995a32 |
15
+ | 缺陷 A/B(资产尾 export + --linked-changes 管道) | 已提交 954946ae |
16
+
17
+ **R5 前置核对(2026-09-21 落盘)**:①对撞仓基线 50736b6ef / 53c67e02a 经 git cat-file 实证均在(multi-agent-platform 主树干净);Temp 残留一批 prunable gate worktree——R5 跑前 `git worktree prune`。②account.mjs 已加三分+当量列(v2),基线钉死:R4-L 当量@3× 13.89M / R4-O-L 5.87M / **比值 2.37×**(@5× 口径 2.47×,复现终报 2.4×);R5 判定一律用同脚本同口径复算,不比绝对值。③**B-④ 接线缺口**:材料包机制已落地但 execute 主链未主动生成(task-02 接线最小化,仅 options.materials 传入时渲染)——R5 的 B-④ on/off 对照前需补接线(小 quick 一项,或并入 batch2 M3 派发分组落点)。
18
+
19
+ **R5 验收点**:门禁轮次 ≤2;模块粒度下真拦率不降(用 gate-value-audit 的 12 次真拦案例回归);大任务墙钟无额度事故(并发帽生效)。前置对账(v3.2):五项中四项已核已交(模块粒度 v3.24 在场 / fail-fast+lint 归属 83d91cd4 / 超时降档 2eba595c),「增量复用」src 与终报均无落码痕迹——详 v3.2 第 4 条,R5 前与承办会话对齐状态,勿按「已在办」默认计入。
20
+
21
+ ## 战线 B:扇出账单治理(打 55%+26% 的差额)
22
+
23
+ ### B-① 读取范围引导(打冷启动 + 重读体量)——**已验靶:不实,实现项砍(2026-09-21,详 round4/b1-b1-target-validation.md)**
24
+ - **前置验证(先做,30min)**:读 task-08 的 transcript,判定 8.6M 是越界读还是任务规模相称——**靶子不实不立项**。
25
+ - **验靶结论**:越界读零发生(62 次调用全在契约链内);8.6M = 58 轮 × 148K 轮均上下文的缓存重发(新鲜输入仅 186K);全扇出 19 子代理名义 41.77M 中新鲜仅 1.34M(3.2%)。读上界太小,读清单注入无钱可省——**第 2 批实现项下线**,allowed_paths 现状约束维持。
26
+ - 杠杆换位到 **B-⑥ 轮数纪律**(见下)与 B-④。
27
+
28
+ ### B-② 调研摘要共享(打实现侧重读)
29
+ - **做法**:调研产出追加一份 CLI 盖章 digest(两页,**每条契约事实带 file:line 锚点 + 「关键契约回源核对」条款**);实现子代理读 digest 替代重读原始源码。
30
+ - **红线**:digest 转错一处 = 内部版错键正典(我们刚批判完的模式)——**走完整流程**,设计决策落盘(锚点格式 / 失效时机 / 回源义务)。
31
+ - 预期:实现侧重读降(调研段自身的 9.4M 压不动,靠 B-③ 摊)。
32
+
33
+ ### B-③ batch 默认前置到 plan(打重复重建)
34
+ - **证据**:R4-S-F 5 任务 2 batch → execute 仅 6M/17min。
35
+ - **做法**:batch 粒度决策放 **plan 阶段**(文件正交 + 无契约链的任务默认并批,2–4/批);execute 不加推力——**保 Wave 内并发 ≥3 的墙钟亮点**,不拿墙钟换 token。
36
+ - 属性:提示词级 + plan-postcheck 可加机械提醒。
37
+
38
+ ### B-④ 材料包机制扩展到 execute(打冷启动)
39
+ - 复用 `assembleStageReviewMaterials` 基建:实现子代理拿 CLI 裁好的合同摘录(design 相关节 + 接口签名 + 目标文件锚点),不自行通读全量文档。
40
+ - **加分机制**:统一材料包 = 统一前缀 → 缓存命中更稳(面值之外的真实账单收益)。
41
+ - **装配顺序契约(v3.2)**:跨任务稳定内容(design 通摘 / 接口签名)在前、任务专属内容(任务卡 / 变更面摘录)在后——统一前缀的缓存命中依赖稳定段先行,混排则任务差异打断前缀、面值收益折半。
42
+ - 可直接进(机制在,低风险)。
43
+
44
+ ### B-⑤ 子代理模型分级(打单价,不动 token)
45
+ - **必须先 A/B**:同任务双档各跑——便宜档若多轮返工(turn↑→重发↑)token 反升,且核验行为可能弱化(错键正是核验拦的)。**审查/verify 保持旗舰档是红线**。
46
+ - 只在 A/B 证实「实现档返工率不升」后启用。
47
+
48
+ ### B-⑥ 轮数纪律(打轮数乘数;B-① 验靶换位新增,2026-09-21)
49
+ - **证据**:扇出名义体量 = Σ(轮数 × 轮均上下文),新鲜内容仅 3.2%——轮数是另一半杠杆。task-08 的 58 轮里 Edit×7(相邻同文件逐个改)+ TodoWrite×4(每条占一轮重发全上下文)+ 测试 Bash 多次循环。
50
+ - **做法**(提示词级,execute 派发 prompt 两三行):① 相邻同文件的多个改动合并为一次 Edit 批量提交;② TodoWrite 降频(阶段边界用,不在实现中途连发);③ 测试验证合并跑(一次 Bash 串行多查),不逐文件跑。
51
+ - 属性:提示词级;R5 用子代理请求数验收(扇出 522req 基线)。
52
+
53
+ ### 战线 B 预期(保守)
54
+ 扇出段 42.3M → **28–32M**(上界 25M 需 ①②③ 全中且提示词被遵守);账单当量比 2.4× → **~1.7–1.9×**。到不了 parity 也不该到——剩余差额 = 上下文保险 + 独立审查 + 交付厚度的价格。
55
+
56
+ ## 战线 C:编排会话上下文治理(打主会话 56.8M 的一部分)
57
+
58
+ ### C-1(P1,quick 可落)
59
+ - **B1 子代理返回契约**:返回体 ≤25 行结构化摘要(verdict / 触碰文件数 / 测试一行 / 偏差),细节落盘按需 Read——真相由门禁对账,不靠返回体转述。
60
+ - **B2 审查回收瘦身**:verdict 回一行 + blockers + review.json 路径(稳定路径已在),主代理按需 Read 工件。
61
+ - **B3a prompt 审计先行**:只读脚本统计 R4 五份 transcript 各步 prompt 规则的「引用/遵守/从未触发」,产出瘦身候选——**测量完再删**(四律这轮刚实证有效,承重规则不动)。
62
+
63
+ ### C-2(P2,CLI 小刀)
64
+ - **B4a `sillyspec handoff --change <名>`**:进度库机械生成 ≤80 行交接包(阶段/Wave 状态/blockers/决策 ID/下一步命令)——把「任务太大爆窗」从硬墙变成操作规程。零状态机改动。
65
+ - B3b 依据 B3a 审计瘦身步骤 prompt。
66
+
67
+ ### C-3(P3,立项评估,勿直接开码)
68
+ - B4b 编排自动分段:先让 B4a 人工规程跑两个真实超大变更,再决定自动化。
69
+ - 目标:R4-L 量级任务主会话峰值 **377K → <250K**,>150K 请求占比 81% → <50%。
70
+
71
+ ## 执行顺序(依赖排序)
72
+
73
+ ```
74
+ 第 1 批(并行,本周):
75
+ B-①前置验证(30min) ──不实则砍①
76
+ B-③ plan batch 默认(提示词+postcheck 提醒)
77
+ B-④ 材料包扩展(复用基建,含装配顺序契约)
78
+ C-1 B1/B2 返回契约+回收瘦身(提示词)
79
+ C-1 B3a prompt 审计(只读脚本)
80
+ R5 探针套件:错键类+审查钳用例(verify-probes 基建增量造)──防线回归硬门的判法依赖(v3.2)
81
+ 第 2 批(依据第 1 批):
82
+ B-⑥ 轮数纪律(提示词,B-① 验靶换位顶替原「读清单注入」)
83
+ C-2 B4a handoff 命令
84
+ B-⑤ 模型分级 A/B
85
+ 第 3 批(完整流程立项):
86
+ B-② 调研 digest(锚点/失效/回源契约设计)
87
+ C-2 B3b prompt 瘦身(依据审计)
88
+ C-3 自动分段评估
89
+ ```
90
+
91
+ ## R5 验收协议(一等指标升级)
92
+
93
+ | 指标 | R4 基线 | 目标 | 判法 | 依赖批次 |
94
+ |---|---|---|---|---|
95
+ | **账单当量比(大任务)** | 2.4× | ≤1.8×(拉伸) | account.mjs 加折算列(三分已有查询) | ④ 机制 + ①②③ 概率 |
96
+ | 扇出段 tokens | 42.3M | ≤32M(硬门) | 子会话聚合 | ④ 机制 + ①③ 概率 |
97
+ | 门禁轮次 | 9(S-F 病理)/ 2(稳态) | ≤2(硬门) | 进度库 | 战线 A |
98
+ | 大任务墙钟·不劣化 | 156min | ≤156min(硬门) | 会话时间戳 | 全体——「不拿墙钟换 token」可检化 |
99
+ | 大任务墙钟·进取 | 156min | ≤120min(拉伸) | 会话时间戳 + **阶段级拆账** | ①④+C-1,概率项无机制保票 |
100
+ | 主会话峰值单请求 | 377K | <250K | MAX() 查询 | 第 3 批 B3b——R5 只记录不判罚 |
101
+ | >150K 请求占比 | 81% | <50% | 计数查询 | 第 3 批 B3b——R5 只记录不判罚 |
102
+ | 防线回归 | — | 错键类案例仍被拦;审查钳仍达标 | **探针套件(第 1 批交付)** + transcript | 第 1 批探针 |
103
+
104
+ 场景:50736b6ef / 53c67e02a 同基线重放(两 SHA 是对撞仓 multi-agent-platform 的基线、非本仓对象——跑前核那边基线与 worktree 卫生),小 ×2 + 大 ×1,版本钉死首步回显。**R5 时点 = 第 1+2 批完成后**;250K / 50% 两行押第 3 批 B3b,R5 只记录不判罚,第 3 批后复测。**2 跑取分布,不外推;提示词级项不达标即升级机制化(路径:CLI 截断注入/机械组装)。** 墙钟 ≤120min 无 per-item 机制预算——R5 必须落盘阶段级墙钟拆账(调研 / plan / execute 扇出 / verify / 归档 / 门禁等待),作为 R6 的预算基线,先测后诺(同 B3a 纪律)。
105
+
106
+ ## 诚实边界
107
+
108
+ - B-①②③⑤ 全含概率性或前提验证,百分比是方向估计,唯一承诺是 R5 可测;
109
+ - 55% 的缓存体量差不可能清零——隔离上下文的语义就是重读,治理目标是「去冗余」不是「去重读」;
110
+ - 剩余 ~1.7× 账单差 + 墙钟差里,含交付厚度(输出 19% 差额)与独立审查的固定成本——这部分是定价,不是缺陷,对外口径已按此表述。
111
+
112
+ ---
113
+
114
+ # 评审修订 v3.1(2026-09-21,外部评审采纳记录)
115
+
116
+ ## 采纳并修订的六处
117
+
118
+ 1. **B4a 改为 enrich handoff(已验证属实)**:`src/handoff.js` 已存在(113 行,`buildHandoff`/`nextStageSuggestion`),现产出为 session 导出 + 下一阶段建议的瘦包。C-2 第 2 批工作量修正为「进度库多抽几段进现有 buildHandoff」(Wave 状态 / 未决 blockers / 决策 ID / 下一步命令行,≤80 行封顶),**不是新命令立项**。
119
+ 2. **R5 验收拆硬门/拉伸**:
120
+ - **硬门**(不达标即失败):扇出 ≤32M · 门禁轮次 ≤2 · 防线回归(错键类仍被拦 + 审查钳达标)· 大任务墙钟 ≤120min(稳态口径)
121
+ - **拉伸**(①②全中才承诺):账单当量 ≤1.8×
122
+ - 对外口径维持 1.7–1.9×;不再把拉伸当硬门。
123
+ 3. **墙钟基线钉死**:比较一律用**稳态 156min**(门禁单轮重构口径),毛墙钟 185min 仅作背景。「额度事故不再发生」是并发帽的验收项(R5 零事故),不从基线剔除。
124
+ 4. **判定路径统一显式勾掉**:gate verify PASS vs verify --done FAIL 的口径矛盾**已修**(61995a32:runGate verify 补 verify-lint,与 --done 同引擎同归属降档);tail 截断→失败明细稳定路径**已修**(794529e5)。两项归战线 A 待 R5 验收,第 1 批不重开。
125
+ 5. **B-③ 加并发护栏**:plan-postcheck 增机械提醒——**并批后单 Wave 在飞子代理数 ≥ min(3, 该 Wave 任务数)**;batch 决策只在 plan 定,execute 不加推力。外推边界写明:S-F 5→2 batch/6M 是小任务证据;大任务 12 实现代理并批**收益在 token、成本在墙钟**,R5 大任务跑单独归因。
126
+ 6. **B-④ 预期收窄 + 升第 1 批必达**:材料包只压「design/合同文档通读」,压不动「要改的源码本身」——与 B-① 互补但**不得双重算账**。
127
+
128
+ ## 优先级调换(接受)
129
+
130
+ **第 1 批必达改为:B-④ 材料包扩面 + C-1(B1 返回契约 / B2 回收瘦身 / B3a 审计)+ B-③(plan 默认 + postcheck 护栏)**——机制确定收益优先于又一条 hint。**B-① 降级为仅保留 30min 验靶**,验证属实再排实现。
131
+
132
+ ## 新增纪律(三条,全部采纳)
133
+
134
+ - **prompt 注入上限**:每加一段注入必须写明「替换哪段旧文」或配 CLI 截断上限——防优化文案自己吃掉 377K→250K 指标。
135
+ - **互斥实验标签**:①②④ 都声称「少读」,R5 至少 B-④ on/off 同基线各一跑,归因可分。
136
+ - **A 先于 B**:R5 小任务两跑**先判门禁 ≤2**,再谈扇出 tokens——门禁稳态前账单优化会被墙钟噪声淹没。
137
+
138
+ ## B-⑤ 验收补一维(采纳)
139
+
140
+ A/B 双档除返工率外,加测**事实核验类工具调用密度**(联网搜真名 / 读 SDK d.ts 的次数)——错键故事里「会不会核验」比「会不会写完」更关键;便宜档核验密度显著下降即否决。
141
+
142
+ ## 对反馈的一处澄清(非驳回)
143
+
144
+ 反馈第 4 条「第 1 批缺确定 ROI 墙钟项」的时态已过:判定路径统一与 tail 稳定路径在评审前已提交(61995a32 / 794529e5),本次修订将其从隐含改为显式勾掉(见上第 4 条)。其余五处修订 + 优先级调换 + 三条纪律全部接受。
145
+
146
+ ---
147
+
148
+ # 评审修订 v3.2(2026-09-21,第二外部评审采纳记录——验收协议三硬伤修复)
149
+
150
+ 前置:本轮评审先核事实后评方案,承重声明全部属实——handoff.js 113 行(buildHandoff/nextStageSuggestion,src/handoff.js:23/48)、assembleStageReviewMaterials 复用面(review-material-pack.js,plan/execute/brainstorm 三处引用)、account.mjs 三分查询 + db.model_usage 本有 cache_creation/cache_read 列(折算列是小改)、review.json 稳定路径(src/index.js:664)、gate-value-audit 12 真拦/36 超时 34%/227 门禁、42.3M/156min 在 r4-final-report.html 落盘、三提交号(61995a32/954946ae/794529e5)在。方案地基为实,三红线与三纪律不动。与 v3.1 的纯追加不同,本次对 R5 验收表与执行顺序**就地重写**(表是操作性章节,留旧表加补丁会迫使读者自行对账),修订记录在此。
151
+
152
+ ## 三处验收协议修复
153
+
154
+ 1. **墙钟 ≤120min 从硬门降为拉伸,换入「不劣化 ≤156min」硬门**。依据:基线 156 本是门禁单轮重构口径(v3.1 第 3 条),门禁收益已折入基线;B-③ 明确不拿墙钟换 token,B-①/④/C-1 全为概率项——120 无任何 per-item 机制保票,硬门失败时无法区分「方案失效」与「归一化基线乐观」。不劣化硬门把「不拿墙钟换 token」从口号变成可检承诺;R5 落盘阶段级墙钟拆账(六段),R6 才有真预算基线。**硬门集合相应改定:扇出 ≤32M · 门禁轮次 ≤2 · 防线回归 · 墙钟不劣化 ≤156min(另:并发帽 R5 零事故维持);拉伸:账单当量 ≤1.8× + 墙钟进取 ≤120min。**对外口径同步。
155
+ 2. **防线探针套件排入第 1 批**。「探针 + transcript」判法依赖的用例集原先不在任何批次——12 次真拦来自两个月 227 次历史门禁,R5 三跑自然撞不到。基于 verify-probes 基建(src/verify-probes.js 在场)增量造错键类 + 审查钳用例,硬门才有可执行判法。错键形态以 r4-final-report「错键生产 no-op、测试全绿掩护」为准。
156
+ 3. **验收表增「依赖批次」列 + R5 时点钉死**。377K→<250K、81%→<50% 实押第 3 批 B3b(B3a 只审计不删)——R5 时点定为第 1+2 批完成后,此两行只记录不判罚,第 3 批后复测;消除「表行达标承诺」与「批次排期」的错位。
157
+
158
+ ## 两处状态对账(操作性,非方案缺陷)
159
+
160
+ 4. **战线 A「增量复用」状态存疑**:五项中四项已核已交(模块粒度 v3.24 在场 / fail-fast+lint 归属 83d91cd4 / 超时降档 2eba595c),唯「增量复用」在 src 与 r4-final-report 均无落码/定义痕迹,changes/ 亦无活跃变更;ROADMAP 登记的延后项「探针增量缓存」(quick-4af1acc3 D②:失效面广需独立失效契约)疑为同物——若同物则已延后,应从战线 A 摘出重归属。R5 前与承办会话对齐,勿按「已在办」默认计入(已同步批注到战线 A 验收点)。
161
+ 5. **重放基线在对撞仓**:50736b6ef / 53c67e02a 经 git cat-file 验证非本仓对象;worktree 路径实证基线在 multi-agent-platform 仓——R5 跑前核那边基线 SHA 与 worktree 卫生(防未来提交泄露规则沿用 R4 prompt 既有一套)。
162
+
163
+ ## 一处实现注记
164
+
165
+ 6. **B-④ 装配顺序契约**(已写入 B-④ 条目):统一前缀的缓存命中依赖稳定段先行——跨任务稳定内容(design 通摘/接口签名)在前、任务专属内容(任务卡/变更面摘录)在后;混排则任务差异打断前缀,面值收益折半。