sillyspec 3.28.8 → 3.28.10

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 (69) hide show
  1. package/.claude/full.json +1 -0
  2. package/.claude/skills/sillyspec-execute/SKILL.md +222 -224
  3. package/.claude/skills/sillyspec-plan/SKILL.md +156 -156
  4. package/.claude/skills/sillyspec-quick/SKILL.md +118 -117
  5. package/AGENTS.md +3 -2
  6. package/README.md +35 -11
  7. package/SKILL.md +24 -10
  8. package/SillySpec-/350/203/275/345/212/233/344/272/256/347/202/271/345/205/250/346/231/257-2026-09-14.pptx +0 -0
  9. package/package.json +1 -1
  10. package/src/change-list.js +73 -20
  11. package/src/change-risk-profile.js +20 -0
  12. package/src/config-schema.js +62 -0
  13. package/src/contract-matrix.js +84 -5
  14. package/src/cross-repo-reconcile.js +134 -0
  15. package/src/db.js +11 -3
  16. package/src/decision-distill.js +15 -3
  17. package/src/design-facts.js +89 -20
  18. package/src/docs-gate.js +105 -6
  19. package/src/doctor-diagnostics.js +224 -2
  20. package/src/friction-ledger.js +171 -0
  21. package/src/hooks/worktree-guard.js +13 -1
  22. package/src/index.js +206 -18
  23. package/src/knowledge-classify.js +382 -0
  24. package/src/knowledge-hits.js +74 -0
  25. package/src/knowledge-stats.js +180 -0
  26. package/src/probe7-anchor-check.js +69 -0
  27. package/src/progress/change-registry.js +183 -8
  28. package/src/progress/shared.js +3 -2
  29. package/src/progress.js +100 -8
  30. package/src/quick-gate-profile.js +251 -0
  31. package/src/quicklog.js +164 -18
  32. package/src/review-dispatch.js +2 -1
  33. package/src/run/command.js +131 -13
  34. package/src/run/complete-handlers.js +511 -21
  35. package/src/run/complete.js +123 -23
  36. package/src/run/concurrent-detect.js +98 -0
  37. package/src/run/gate-snapshot.js +110 -2
  38. package/src/run/gates.js +141 -16
  39. package/src/run/prompt.js +221 -11
  40. package/src/run/quick-audit.js +111 -13
  41. package/src/run/shared.js +147 -11
  42. package/src/run/stage.js +6 -0
  43. package/src/scan-diff.js +61 -30
  44. package/src/scan-postcheck.js +74 -0
  45. package/src/scan-refresh.js +477 -0
  46. package/src/scan-staleness.js +25 -13
  47. package/src/scope-audit.js +456 -56
  48. package/src/stage-contract.js +185 -2
  49. package/src/stage-review.js +23 -7
  50. package/src/stages/brainstorm.js +6 -0
  51. package/src/stages/cmd-existence.js +9 -3
  52. package/src/stages/execute.js +85 -3
  53. package/src/stages/knowledge.js +76 -6
  54. package/src/stages/plan-postcheck.js +32 -5
  55. package/src/stages/quick.js +1 -1
  56. package/src/stages/verify.js +1 -0
  57. package/src/sync-noise.js +170 -6
  58. package/src/sync.js +141 -9
  59. package/src/task-review.js +366 -46
  60. package/src/verify-postcheck.js +212 -55
  61. package/src/verify-probes.js +727 -16
  62. package/src/worktree-apply.js +685 -48
  63. package/src/worktree-deps.js +124 -3
  64. package/src/worktree.js +391 -15
  65. package/templates/agents-instruction.md +2 -2
  66. package/templates/prompts/testcase-design.md +2 -1
  67. package/templates/prompts/verify-probes.md +4 -1
  68. package/.patch16-tmp.mjs +0 -169
  69. package/sa-rename-probe/src/new.js +0 -4
package/.patch16-tmp.mjs DELETED
@@ -1,169 +0,0 @@
1
- import { readFileSync, writeFileSync, rmSync } from 'node:fs'
2
-
3
- // ── ① task-review.js:四 writer provenance 戳 + emptyDiff 报错直显 ──
4
- {
5
- const f = 'src/task-review.js'
6
- let t = readFileSync(f, 'utf8')
7
-
8
- // helper(放 REVIEW_SCHEMA_VERSION 常量后)
9
- const a0 = "export const REVIEW_SCHEMA_VERSION = 1"
10
- const b0 = `export const REVIEW_SCHEMA_VERSION = 1
11
-
12
- /**
13
- * review.json 写入溯源戳(坑 review-json-mystery-overwrite,2026-09-12 驾驭第十七批①,
14
- * 用户实证 task-04 review 被覆写成空壳、gate 报零改动伪造重写恢复——四个 writer 均有
15
- * 覆盖守卫,无堆栈钉不死覆写者):每次写入附 writtenBy(写入通道 + PID)+ writtenAt,
16
- * emptyDiff 伪造 error 直显两字段——下次复现自曝身份,事后可归因。
17
- */
18
- export function reviewProvenanceStamp(channel) {
19
- return { writtenBy: \`\${channel}#pid\${process.pid}\`, writtenAt: new Date().toISOString() }
20
- }`
21
- if (!t.includes(a0)) { console.error('a0 missing'); process.exit(1) }
22
- t = t.replace(a0, b0)
23
-
24
- // writer 1/2:两处 draft(reviewerNotes 行后追加 stamp 到对象)——draft 对象构造尾
25
- const a1 = ` if (draftRepo) draft.repo = draftRepo
26
- // fail-open(对齐函数头契约 + execute-run-dir-fail-loud 测试锁定的「写失败返回统计不抛」):
27
- // 无归属草稿写入失败(如 tasks/ 被普通文件占位 ENOTDIR)降级 skipped,不崩整个草稿生成
28
- try {
29
- mkdirSync(reviewDir, { recursive: true })
30
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\\n')`
31
- const b1 = ` if (draftRepo) draft.repo = draftRepo
32
- Object.assign(draft, reviewProvenanceStamp('generateTaskReviewDrafts:no-attribution'))
33
- // fail-open(对齐函数头契约 + execute-run-dir-fail-loud 测试锁定的「写失败返回统计不抛」):
34
- // 无归属草稿写入失败(如 tasks/ 被普通文件占位 ENOTDIR)降级 skipped,不崩整个草稿生成
35
- try {
36
- mkdirSync(reviewDir, { recursive: true })
37
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\\n')`
38
- if (!t.includes(a1)) { console.error('a1 missing'); process.exit(1) }
39
- t = t.replace(a1, b1)
40
-
41
- const a2 = ` if (draftRepo) draft.repo = draftRepo
42
- mkdirSync(reviewDir, { recursive: true })
43
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\\n')
44
- generated++
45
- }`
46
- const b2 = ` if (draftRepo) draft.repo = draftRepo
47
- Object.assign(draft, reviewProvenanceStamp('generateTaskReviewDrafts'))
48
- mkdirSync(reviewDir, { recursive: true })
49
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\\n')
50
- generated++
51
- }`
52
- if (!t.includes(a2)) { console.error('a2 missing'); process.exit(1) }
53
- t = t.replace(a2, b2)
54
-
55
- // writer 3:adopt(merged 写回前)
56
- const a3 = ` try {
57
- if (mechanicsChanged || verdictTouched || evidenceFilled) {
58
- writeFileSync(reviewPath, JSON.stringify(merged, null, 2) + '\\n')`
59
- const b3 = ` try {
60
- if (mechanicsChanged || verdictTouched || evidenceFilled) {
61
- Object.assign(merged, reviewProvenanceStamp('adoptTaskReviewMechanics'))
62
- writeFileSync(reviewPath, JSON.stringify(merged, null, 2) + '\\n')`
63
- if (!t.includes(a3)) { console.error('a3 missing'); process.exit(1) }
64
- t = t.replace(a3, b3)
65
-
66
- // writer 4:writeTaskReview(schema 自检前)
67
- const a4 = ` const schemaResult = validateReviewSchema(review)
68
- if (!schemaResult.ok) {
69
- return { ok: false, errors: schemaResult.errors, warnings }
70
- }
71
- try {
72
- mkdirSync(reviewDir, { recursive: true })
73
- writeFileSync(reviewPath, JSON.stringify(review, null, 2) + '\\n')`
74
- const b4 = ` Object.assign(review, reviewProvenanceStamp('writeTaskReview' + (force ? ':force' : '')))
75
- const schemaResult = validateReviewSchema(review)
76
- if (!schemaResult.ok) {
77
- return { ok: false, errors: schemaResult.errors, warnings }
78
- }
79
- try {
80
- mkdirSync(reviewDir, { recursive: true })
81
- writeFileSync(reviewPath, JSON.stringify(review, null, 2) + '\\n')`
82
- if (!t.includes(a4)) { console.error('a4 missing'); process.exit(1) }
83
- t = t.replace(a4, b4)
84
-
85
- // emptyDiff 报错直显 provenance(validateTaskReviews 两处 emptyDiff error)
86
- const a5 = ` errors.push(\`\${taskId}: base..head(\${review.base.slice(0, 8)}..\${review.head.slice(0, 8)})无任何代码变更 — 评审了一个零改动的任务,review 疑似伪造\${scopeNote}\`)`
87
- const b5 = ` const prov = (review.writtenBy || review.writtenAt) ? \`[写入溯源:\${review.writtenBy || '?'} @ \${review.writtenAt || '?'}]\` : '[无写入溯源—— older writer 产物]'
88
- errors.push(\`\${taskId}: base..head(\${review.base.slice(0, 8)}..\${review.head.slice(0, 8)})无任何代码变更 — 评审了一个零改动的任务,review 疑似伪造\${scopeNote}\${prov}\`)`
89
- if (!t.includes(a5)) { console.error('a5 missing'); process.exit(1) }
90
- t = t.replace(a5, b5)
91
-
92
- writeFileSync(f, t)
93
- console.log('provenance ok')
94
- }
95
-
96
- // ── ② gate-snapshot.js:symlink-store 布局探测 → null 回退 ──
97
- {
98
- const f = 'src/run/gate-snapshot.js'
99
- let t = readFileSync(f, 'utf8')
100
- const a = `export function createGateSnapshot({ cwd, files, sourceRoot = null }) {
101
- let snapshotRoot = null
102
- try {
103
- // 前置:主仓须是 git 仓且有 HEAD(无 git 环境回退主仓现行为)
104
- git(cwd, ['rev-parse', 'HEAD'])`
105
- const b = `export function createGateSnapshot({ cwd, files, sourceRoot = null }) {
106
- let snapshotRoot = null
107
- try {
108
- // 前置:主仓须是 git 仓且有 HEAD(无 git 环境回退主仓现行为)
109
- git(cwd, ['rev-parse', 'HEAD'])
110
-
111
- // symlink-store 布局探测(坑 gate-snapshot-pnpm-store-break,2026-09-12 驾驭第十七批②,
112
- // 用户第三次踩「lint 沙箱临时目录跑 pnpm 必假败」):pnpm/bun/lerna 的 node_modules 内部
113
- // 是指向 store 的相对/绝对符号链接网——junction 进临时目录后跨根解析失效,实测必假败。
114
- // 与其让沙箱报无关错误逼 advisory,不如布局命中即作废快照回退主仓(宁可主仓口径)。
115
- const layoutHit = detectSymlinkStoreLayout(cwd)
116
- if (layoutHit) {
117
- console.warn(\`⚠️ 门禁快照对 \${layoutHit} 布局不可靠(node_modules 符号链接 store 经 junction 跨根失效,实测必假败)——跳过快照回退主仓实测;主仓失败再做污染归属鉴定\`)
118
- return null
119
- }`
120
- if (!t.includes(a)) { console.error('layout anchor missing'); process.exit(1) }
121
- t = t.replace(a, b)
122
-
123
- const helper = `
124
- /** symlink-store 包管理布局探测:命中即 junction 快照不可靠。返回布局名或 null。 */
125
- export function detectSymlinkStoreLayout(cwd) {
126
- try {
127
- if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm'
128
- if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) return 'bun'
129
- if (existsSync(join(cwd, 'lerna.json'))) return 'lerna'
130
- try {
131
- const pkg = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'))
132
- const pm = pkg && pkg.packageManager ? String(pkg.packageManager) : ''
133
- if (/pnpm@/.test(pm)) return 'pnpm(packageManager)'
134
- if (/yarn@/.test(pm)) return 'yarn(packageManager)'
135
- if (/bun@/.test(pm)) return 'bun(packageManager)'
136
- } catch { /* 无 package.json/损坏 → 仅锁文件判据 */ }
137
- return null
138
- } catch { return null }
139
- }
140
- `
141
- const anchor = '/**\n * 环境目录名集(根与子包通用) */'
142
- if (!t.includes(anchor)) { console.error('helper2 anchor missing'); process.exit(1) }
143
- t = t.replace(anchor, helper + '\n' + anchor)
144
- writeFileSync(f, t)
145
- console.log('layout ok')
146
- }
147
-
148
- // ── ③ verify-probes.js:probe1 剥 NEW: 前缀 ──
149
- {
150
- const f = 'src/verify-probes.js'
151
- let t = readFileSync(f, 'utf8')
152
- const a = ` let abs = join(cwd, e.path)
153
- if (!existsSync(abs)) {
154
- const wtAbs = wtRoot ? join(wtRoot, e.path) : null`
155
- const b = ` // NEW: 待建前缀剥离(坑 probe1-new-prefix-miss,2026-09-12 驾驭第十七批③,用户实证
156
- // 「NEW: 前缀文件已合入主仓」时 existsSync(join(cwd,'NEW:src/x')) 恒 miss 落 skippedFiles
157
- // 留 ⚠️ 噪声):design 清单的 NEW: 是「新建意图」标记,文件 apply 后已是无前缀实体——
158
- // 探针按目标文件扫(与 pathMatches 比对侧剥除同源)。
159
- const probePath = String(e.path).replace(/^NEW:\\s*/, '')
160
- let abs = join(cwd, probePath)
161
- if (!existsSync(abs)) {
162
- const wtAbs = wtRoot ? join(wtRoot, probePath) : null`
163
- if (!t.includes(a)) { console.error('probe anchor missing'); process.exit(1) }
164
- t = t.replace(a, b)
165
- writeFileSync(f, t)
166
- console.log('probe ok')
167
- }
168
-
169
- rmSync('.patch16-tmp.mjs', { force: true })
@@ -1,4 +0,0 @@
1
- a
2
- b
3
- c
4
- d