sillyspec 3.29.4 → 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 (148) 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-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,38 @@
1
+ # R4 五会话全量深读·综合判读(2026-09-21,四子代理并行精读)
2
+
3
+ ## 一、「质量差距是不是小概率」的最终答案:不是,两记实锤
4
+
5
+ **实锤 1:大任务 OpenSpec 侧存在同类缺陷。** R4-O-L 的 daemon 解析器 registry 键名(`claude-code-transcript-jsonl` 等)是**按命名惯例自造的**,未与上报侧(sillyspec CLI,禁读无法对证)核验;且仓内既有测试常量 `claude-transcript-jsonl` 已经暗示了另一种命名——若不符,解析器永不触发、静默 unsupported,**流程内无任何环节能发现**。与错键(autoCompactPreCompute)同一缺陷类:**外部契约事实未经核验即落码,自洽测试掩护其穿越全部关卡**。两个独立 OpenSpec 跑、两实例——这是系统性暴露面,不是运气。
6
+
7
+ **实锤 2(最锐利):两个 agent 生成了同一个错误先验。** R4-S-Q(sillyspec)在 [3.2m] 同样猜了 `autoCompactPrecompute`、[3.9m] 甚至专门搜了这个词——**但先验证再落码**,搜出真名 `precomputeCompactionEnabled`。同模型、同先验、同错误生成;唯一差别是有无验证步。**错误生成是确定性的,拦截是结构性的。**
8
+
9
+ B 侧错键穿越了六道关卡(proposal→spec→design→tasks→测试→archive),全绿——格式校验不校验事实,文档链越长只是把同一个错复制得更体面。
10
+
11
+ ## 二、效率面的新分解(深读修正)
12
+
13
+ **R4-L(185min)**:~118min(64%)是子代理扇出等待+后台门禁+额度事故(4 路并发派发触发额度耗尽,中断 ~17min 由用户恢复);主代理自身生成 <1/3;无效功 ~28min(CLI 旗标摩擦、review.json 两次归位、Wave6 --done 因输出 tail 截断三连跑、verify-result 槽格式学费、嵌套 worktree 下 module-docs-sync 失效、重复 pnpm install)。代码层零返工、15 commit 全净;无联网核验但用本机真实数据(38 个 cursor store.db 全量实测)做了更硬的核验。
14
+
15
+ **R4-O-L(80min)快的解剖**:零子代理(省 40-60m)+ 决策链短(20-30m)+ 只跑相关测试(10-20m)+ 无视觉验收(10-15m)+ 无独立审查(10-20m)+ 探查前置零返工。反直觉:探查占 24%(快来自读得多);最大黑洞是环境(venv/转义 ~8m);最强审查者是遗留测试套件(7 处精确 toEqual 断言逼显式化契约变更)。
16
+
17
+ **R4-S-F(171min)**:verify 92min 中 **75-80min(82%)是纯门禁运行**(7 次 --done、9 次全量门禁);agent 有效工作仅 ~15m。三方拆账:CLI ≈50%、agent ≈12%、环境 ≈6%。新发现的结构性问题:① 同一 CLI 内 `gate verify`(独立跑)PASS 与 `verify --done` FAIL 并存——**两套矛盾判定路径误导诊断 16min**;② 「越正确越被罚」——agent 正确地不动并行会话归属的债文件,快照 overlay 因此永远取 HEAD 带债版,门禁结构性奖励越权改他人文件;③ 根因(快照说明+advisory 提示)一直躺在后台日志里,晚读全文多烧 20min。**重跑地板:不改工具 ~60min;修三处(lint 前置/门禁缓存/检查前置)~45min**——全流程与 quick 的合理差距应是 ~20min 仪式成本,不是本次的 130min。
18
+
19
+ **小任务对(41.2 vs 21.5)**:19.7min 差逐项对平——两轮门禁 +19.9m(纯等待)、存量债清偿 +1.9m、联网核验 +1.2m、stash 对照 +0.6m、终态观测 +1.3m,减 B 的四件套/排障/阅读 ~6.7m。**两侧纯编码测试速度等价**(5-6m)。A 的门禁误拦反而触发正向行为(清债+全量复验拿到 mypy 963 文件级保证)。
20
+
21
+ ## 三、两侧 agent 的真实面貌(修正刻板印象)
22
+
23
+ - OpenSpec 侧 agent **探索纪律很强**(真实数据探针、搜而不信、诚实披露风险)——缺陷不在 agent 能力,在流程无核验结构。
24
+ - sillyspec 侧 R4-S-F 的排障有 15min 绕路(未早读日志全文)、两次被 gate verify 的误导 PASS 带偏。
25
+ - B 侧两个真亮点值得吸收:**前端依赖后台安装与改码并行**(墙钟并行度);**三态下拉表达「键缺省 vs 显式 false」**(语义优于 A 的不对称 checkbox)。
26
+
27
+ ## 四、修复清单增量(在已办五项 + 两缺口之外,新增)
28
+
29
+ 1. **`gate verify` 与 `verify --done` 判定路径统一**(矛盾输出,16min 级误导)
30
+ 2. 门禁失败输出 tail 截断问题(Wave6 三连跑根因)——失败时给全量日志路径提示
31
+ 3. 嵌套 worktree 下 module-docs-sync 失效(24 文件全未匹配)
32
+ 4. verify-result 槽格式旧版拒收的一次性学费(--init 提示要更早)
33
+ 5. 编排层:并发派发上限感知(4 路齐发触发额度耗尽)
34
+ 6. (对 OpenSpec 的镜像建议,供对比参考):外部契约事实表 + 来源强制校验 + vendored sdk.d.ts 的 10 秒 grep 检查——错键当场现形
35
+
36
+ ## 五、方法论沉淀
37
+
38
+ 「验证全在模型侧(自愿)」与「验证全在机器侧(盲跑)」恰好各错一半——两个流程的真正差距不是仪式多少,而是**防线是否对准缺陷类**:OpenSpec 六道格式关零事实核验;sillyspec 有事实核验结构但机器门禁 40%+ 假拦+双跑浪费。
@@ -0,0 +1,38 @@
1
+ // 全量会话导出:node extract-full.mjs <session前缀> <输出文件>
2
+ // 正文全量、reasoning 截 300、工具输入截 500(命令全文)、工具输出截 700
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ import { writeFileSync } from 'node:fs';
5
+
6
+ const [prefix, outFile] = process.argv.slice(2);
7
+ const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
8
+ const sess = db.prepare('SELECT id, title, time_created FROM session WHERE id LIKE ?').get('sess_' + prefix + '%');
9
+ if (!sess) { console.error('not found'); process.exit(1); }
10
+
11
+ const parts = db.prepare(
12
+ `SELECT p.data, p.time_created tc, JSON_EXTRACT(m.data,'$.role') role
13
+ FROM part p JOIN message m ON p.message_id = m.id
14
+ WHERE p.session_id = ? ORDER BY p.time_created ASC, p.sequence ASC`
15
+ ).all(sess.id);
16
+
17
+ const t0 = Number(sess.time_created);
18
+ const lines = [`# ${sess.title}`, `# 会话 ${sess.id} 起点 ${new Date(t0).toISOString()}`, ''];
19
+ for (const row of parts) {
20
+ const d = JSON.parse(row.data);
21
+ const rel = ((Number(d.time?.created ?? row.tc) - t0) / 60000).toFixed(1);
22
+ const clean = (s, n) => String(s ?? '').replace(/\u001b\[[0-9;]*m/g, '').slice(0, n);
23
+ if (d.type === 'text') {
24
+ lines.push(`\n[${rel}m] ${String(row.role).toUpperCase()} 正文:\n${clean(d.text, 6000)}`);
25
+ } else if (d.type === 'reasoning') {
26
+ const r = clean(d.text ?? d.summary, 300);
27
+ if (r.trim()) lines.push(`[${rel}m] (思考) ${r}`);
28
+ } else if (d.type === 'tool') {
29
+ const inp = d.state?.input ?? {};
30
+ const key = inp.command ?? inp.file_path ?? inp.path ?? inp.pattern ?? inp.prompt ?? JSON.stringify(inp);
31
+ lines.push(`\n[${rel}m] 🛠 ${d.tool} ${d.state?.status === 'running' ? '(未完成)' : ''}\n 输入: ${clean(key, inp.command ? 2500 : 500)}`);
32
+ const out = clean(String(d.state?.output ?? ''), 700);
33
+ if (out.trim()) lines.push(` 输出: ${out.replace(/\n+/g, '\n ')}`);
34
+ }
35
+ }
36
+ writeFileSync(outFile, lines.join('\n'), 'utf8');
37
+ console.log(`wrote ${outFile}: ${lines.length} lines, ${(lines.join('\n').length / 1024).toFixed(0)}KB`);
38
+ db.close();
@@ -0,0 +1,43 @@
1
+ // 用法:node extract-timeline.mjs <session前缀> <输出文件>
2
+ // 从 zcode db.sqlite 提取会话时间线:文本节选 + 工具调用(名/输入头/输出头)
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ import { writeFileSync } from 'node:fs';
5
+
6
+ const [prefix, outFile] = process.argv.slice(2);
7
+ const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
8
+
9
+ const sess = db.prepare('SELECT id FROM session WHERE id LIKE ?').get('sess_' + prefix + '%');
10
+ if (!sess) { console.error('session not found'); process.exit(1); }
11
+
12
+ const parts = db.prepare(
13
+ `SELECT p.data, m.time_created mt, JSON_EXTRACT(m.data,'$.role') role
14
+ FROM part p JOIN message m ON p.message_id = m.id
15
+ WHERE p.session_id = ? ORDER BY p.sequence`
16
+ ).all(sess.id);
17
+
18
+ const t0 = parts.length ? Number(JSON.parse(parts[0].data).time?.created ?? parts[0].mt) : 0;
19
+ const lines = [];
20
+ let lastTs = t0;
21
+ for (const row of parts) {
22
+ const d = JSON.parse(row.data);
23
+ const ts = Number(d.time?.created ?? row.mt);
24
+ if (ts > lastTs) lastTs = ts;
25
+ const rel = ((ts - t0) / 60000).toFixed(1);
26
+ const one = (s, n) => String(s ?? '').replace(/\s+/g, ' ').slice(0, n);
27
+ if (d.type === 'text') {
28
+ lines.push(`[${rel}m] ${row.role?.toUpperCase()} TEXT: ${one(d.text, 200)}`);
29
+ } else if (d.type === 'reasoning') {
30
+ // 只留极短摘要,标注存在性
31
+ lines.push(`[${rel}m] ${row.role?.toUpperCase()} think: ${one(d.text ?? d.summary, 90)}`);
32
+ } else if (d.type === 'tool') {
33
+ const inp = d.state?.input ?? {};
34
+ const key = inp.file_path ?? inp.command ?? inp.path ?? inp.pattern ?? JSON.stringify(inp);
35
+ const outHead = one(String(d.state?.output ?? ''), 140);
36
+ lines.push(`[${rel}m] TOOL ${d.tool}: ${one(key, 150)}`);
37
+ if (outHead) lines.push(` → ${outHead}`);
38
+ }
39
+ }
40
+ lines.push(`\n[last-part @ +${((lastTs - t0) / 60000).toFixed(1)}m]`);
41
+ writeFileSync(outFile, lines.join('\n'), 'utf8');
42
+ console.log(`wrote ${outFile}: ${lines.length} lines, span ${((lastTs - t0) / 60000).toFixed(1)}min`);
43
+ db.close();
@@ -0,0 +1,13 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
3
+ const from = Date.parse('2026-09-20T15:00:00+08:00');
4
+ const to = Date.parse('2026-09-21T06:00:00+08:00');
5
+ console.log('window', from, '->', to, new Date(from).toISOString());
6
+ const rows = db.prepare(
7
+ 'SELECT id, title, time_created, parent_id FROM session WHERE time_created >= ? AND time_created <= ? ORDER BY time_created'
8
+ ).all(from, to);
9
+ for (const r of rows) {
10
+ const top = r.parent_id ? ' child-of-' + String(r.parent_id).slice(5, 13) : 'TOP ';
11
+ console.log(new Date(Number(r.time_created)).toISOString().slice(5, 16), top, r.id.slice(5, 13), (r.title || '').slice(0, 75));
12
+ }
13
+ db.close();