sillyspec 3.27.12 → 3.28.2

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 (1234) hide show
  1. package/.claude/skills/sillyspec-execute/SKILL.md +214 -214
  2. package/.claude/skills/sillyspec-plan/SKILL.md +156 -156
  3. package/.claude/skills/sillyspec-quick/SKILL.md +116 -116
  4. package/package.json +1 -1
  5. package/src/agent-session-log.js +77 -10
  6. package/src/archive-delta.js +419 -0
  7. package/src/config-schema.js +2 -2
  8. package/src/contract-matrix.js +15 -2
  9. package/src/design-facts.js +354 -0
  10. package/src/docs-check.js +79 -8
  11. package/src/doctor-diagnostics.js +75 -3
  12. package/src/endpoint-baseline.js +109 -0
  13. package/src/endpoint-extractor.js +100 -24
  14. package/src/git-helper.js +31 -0
  15. package/src/index.js +248 -8
  16. package/src/machine-interface.js +63 -0
  17. package/src/modules.js +41 -12
  18. package/src/progress/change-registry.js +20 -0
  19. package/src/progress/consistency-doctor.js +124 -5
  20. package/src/progress/stage-machine.js +118 -2
  21. package/src/progress.js +6 -0
  22. package/src/quicklog.js +51 -0
  23. package/src/run/command.js +71 -2
  24. package/src/run/complete-handlers.js +84 -7
  25. package/src/run/complete.js +58 -5
  26. package/src/run/gates.js +333 -2
  27. package/src/run/prompt.js +70 -0
  28. package/src/run/quick-audit.js +98 -0
  29. package/src/run/scan-profile.js +98 -6
  30. package/src/run/shared.js +66 -1
  31. package/src/run/stage.js +25 -12
  32. package/src/scan-diff.js +54 -1
  33. package/src/scan-facts.js +173 -0
  34. package/src/scan-postcheck.js +110 -3
  35. package/src/spec-sync.js +210 -16
  36. package/src/stage-review.js +62 -3
  37. package/src/stages/archive.js +5 -5
  38. package/src/stages/brainstorm.js +10 -10
  39. package/src/stages/execute.js +21 -15
  40. package/src/stages/plan-postcheck.js +194 -1
  41. package/src/stages/plan.js +6 -2
  42. package/src/stages/scan.js +44 -102
  43. package/src/stages/verify.js +9 -7
  44. package/src/sync.js +122 -4
  45. package/src/task-review.js +51 -4
  46. package/src/taskcard.js +8 -1
  47. package/src/verify-postcheck.js +670 -10
  48. package/src/verify-probes.js +92 -10
  49. package/src/workflow.js +30 -0
  50. package/templates/agents-instruction.md +1 -1
  51. package/templates/prompts/taskcard-rules.md +5 -0
  52. package/templates/workflows/scan-docs.yaml +6 -0
  53. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  54. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  55. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  56. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  57. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  58. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  59. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  60. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  61. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-export/SKILL.md +0 -57
  62. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-init/SKILL.md +0 -177
  63. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  64. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  65. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  66. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  67. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  68. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-state/SKILL.md +0 -64
  69. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-status/SKILL.md +0 -54
  70. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  71. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  72. package/.claude/worktrees/sillyspec-data-model-research/.gitattributes +0 -2
  73. package/.claude/worktrees/sillyspec-data-model-research/.husky/pre-push +0 -20
  74. package/.claude/worktrees/sillyspec-data-model-research/README.md +0 -203
  75. package/.claude/worktrees/sillyspec-data-model-research/SKILL.md +0 -91
  76. package/.claude/worktrees/sillyspec-data-model-research/bin/sillyspec.js +0 -2
  77. package/.claude/worktrees/sillyspec-data-model-research/logo.jpg +0 -0
  78. package/.claude/worktrees/sillyspec-data-model-research/package-lock.json +0 -977
  79. package/.claude/worktrees/sillyspec-data-model-research/package.json +0 -39
  80. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  81. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  82. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/favicon.jpg +0 -0
  83. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/index.html +0 -16
  84. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/logo.jpg +0 -0
  85. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-dashboard.html +0 -836
  86. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-overview.html +0 -256
  87. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/package.json +0 -25
  88. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/executor.js +0 -95
  89. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/index.js +0 -679
  90. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/parser.js +0 -526
  91. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/watcher.js +0 -357
  92. package/.claude/worktrees/sillyspec-data-model-research/src/agent-session-log.js +0 -803
  93. package/.claude/worktrees/sillyspec-data-model-research/src/change-list.js +0 -290
  94. package/.claude/worktrees/sillyspec-data-model-research/src/change-risk-profile.js +0 -270
  95. package/.claude/worktrees/sillyspec-data-model-research/src/check-primitives.js +0 -65
  96. package/.claude/worktrees/sillyspec-data-model-research/src/classify-change.js +0 -109
  97. package/.claude/worktrees/sillyspec-data-model-research/src/commit-suggest.js +0 -202
  98. package/.claude/worktrees/sillyspec-data-model-research/src/config-cat.js +0 -88
  99. package/.claude/worktrees/sillyspec-data-model-research/src/config-schema.js +0 -328
  100. package/.claude/worktrees/sillyspec-data-model-research/src/constants.js +0 -97
  101. package/.claude/worktrees/sillyspec-data-model-research/src/contract-matrix.js +0 -480
  102. package/.claude/worktrees/sillyspec-data-model-research/src/datetime.js +0 -20
  103. package/.claude/worktrees/sillyspec-data-model-research/src/db-engine.js +0 -55
  104. package/.claude/worktrees/sillyspec-data-model-research/src/db.js +0 -381
  105. package/.claude/worktrees/sillyspec-data-model-research/src/decision-distill.js +0 -517
  106. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/local-agent.js +0 -155
  107. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/sillyhub-mcp.js +0 -245
  108. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/probe.js +0 -246
  109. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/strategy.js +0 -121
  110. package/.claude/worktrees/sillyspec-data-model-research/src/docs-check.js +0 -825
  111. package/.claude/worktrees/sillyspec-data-model-research/src/docs-debt.js +0 -393
  112. package/.claude/worktrees/sillyspec-data-model-research/src/docs-gate.js +0 -107
  113. package/.claude/worktrees/sillyspec-data-model-research/src/doctor-diagnostics.js +0 -1099
  114. package/.claude/worktrees/sillyspec-data-model-research/src/endpoint-extractor.js +0 -420
  115. package/.claude/worktrees/sillyspec-data-model-research/src/foreign-declared.js +0 -78
  116. package/.claude/worktrees/sillyspec-data-model-research/src/fs-atomic.js +0 -73
  117. package/.claude/worktrees/sillyspec-data-model-research/src/git-helper.js +0 -150
  118. package/.claude/worktrees/sillyspec-data-model-research/src/hooks/claude-pre-tool-use.cjs +0 -130
  119. package/.claude/worktrees/sillyspec-data-model-research/src/hooks/worktree-guard.js +0 -892
  120. package/.claude/worktrees/sillyspec-data-model-research/src/index.js +0 -2798
  121. package/.claude/worktrees/sillyspec-data-model-research/src/init.js +0 -626
  122. package/.claude/worktrees/sillyspec-data-model-research/src/knowledge-match.js +0 -231
  123. package/.claude/worktrees/sillyspec-data-model-research/src/local-detect.js +0 -128
  124. package/.claude/worktrees/sillyspec-data-model-research/src/local-register.js +0 -104
  125. package/.claude/worktrees/sillyspec-data-model-research/src/machine-interface.js +0 -543
  126. package/.claude/worktrees/sillyspec-data-model-research/src/migrate.js +0 -127
  127. package/.claude/worktrees/sillyspec-data-model-research/src/module-impact.js +0 -166
  128. package/.claude/worktrees/sillyspec-data-model-research/src/module-resolve.js +0 -222
  129. package/.claude/worktrees/sillyspec-data-model-research/src/modules.js +0 -580
  130. package/.claude/worktrees/sillyspec-data-model-research/src/progress/change-registry.js +0 -336
  131. package/.claude/worktrees/sillyspec-data-model-research/src/progress/consistency-doctor.js +0 -355
  132. package/.claude/worktrees/sillyspec-data-model-research/src/progress/shared.js +0 -36
  133. package/.claude/worktrees/sillyspec-data-model-research/src/progress/stage-machine.js +0 -594
  134. package/.claude/worktrees/sillyspec-data-model-research/src/progress/step-store.js +0 -265
  135. package/.claude/worktrees/sillyspec-data-model-research/src/progress.js +0 -1304
  136. package/.claude/worktrees/sillyspec-data-model-research/src/quick-recommend.js +0 -115
  137. package/.claude/worktrees/sillyspec-data-model-research/src/quicklog.js +0 -852
  138. package/.claude/worktrees/sillyspec-data-model-research/src/review-tier.js +0 -77
  139. package/.claude/worktrees/sillyspec-data-model-research/src/run/command.js +0 -1595
  140. package/.claude/worktrees/sillyspec-data-model-research/src/run/complete-handlers.js +0 -1552
  141. package/.claude/worktrees/sillyspec-data-model-research/src/run/complete.js +0 -1259
  142. package/.claude/worktrees/sillyspec-data-model-research/src/run/concurrent-detect.js +0 -156
  143. package/.claude/worktrees/sillyspec-data-model-research/src/run/gates.js +0 -1084
  144. package/.claude/worktrees/sillyspec-data-model-research/src/run/multi-repo-context.js +0 -208
  145. package/.claude/worktrees/sillyspec-data-model-research/src/run/next.js +0 -128
  146. package/.claude/worktrees/sillyspec-data-model-research/src/run/prompt.js +0 -843
  147. package/.claude/worktrees/sillyspec-data-model-research/src/run/quick-audit.js +0 -186
  148. package/.claude/worktrees/sillyspec-data-model-research/src/run/scan-profile.js +0 -269
  149. package/.claude/worktrees/sillyspec-data-model-research/src/run/shared.js +0 -1562
  150. package/.claude/worktrees/sillyspec-data-model-research/src/run/stage.js +0 -584
  151. package/.claude/worktrees/sillyspec-data-model-research/src/run.js +0 -23
  152. package/.claude/worktrees/sillyspec-data-model-research/src/scan-diff.js +0 -388
  153. package/.claude/worktrees/sillyspec-data-model-research/src/scan-postcheck.js +0 -512
  154. package/.claude/worktrees/sillyspec-data-model-research/src/scan-staleness.js +0 -95
  155. package/.claude/worktrees/sillyspec-data-model-research/src/setup.js +0 -414
  156. package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/client.js +0 -597
  157. package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/config.js +0 -62
  158. package/.claude/worktrees/sillyspec-data-model-research/src/spec-dir-typo.js +0 -50
  159. package/.claude/worktrees/sillyspec-data-model-research/src/spec-sync.js +0 -358
  160. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-engine.js +0 -171
  161. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-spec.js +0 -550
  162. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract.js +0 -889
  163. package/.claude/worktrees/sillyspec-data-model-research/src/stage-review.js +0 -597
  164. package/.claude/worktrees/sillyspec-data-model-research/src/stages/archive.js +0 -199
  165. package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm-auto.js +0 -236
  166. package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm.js +0 -617
  167. package/.claude/worktrees/sillyspec-data-model-research/src/stages/cmd-existence.js +0 -145
  168. package/.claude/worktrees/sillyspec-data-model-research/src/stages/doctor.js +0 -540
  169. package/.claude/worktrees/sillyspec-data-model-research/src/stages/execute.js +0 -1275
  170. package/.claude/worktrees/sillyspec-data-model-research/src/stages/explore.js +0 -43
  171. package/.claude/worktrees/sillyspec-data-model-research/src/stages/index.js +0 -29
  172. package/.claude/worktrees/sillyspec-data-model-research/src/stages/knowledge.js +0 -514
  173. package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan-postcheck.js +0 -1344
  174. package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan.js +0 -650
  175. package/.claude/worktrees/sillyspec-data-model-research/src/stages/quick.js +0 -167
  176. package/.claude/worktrees/sillyspec-data-model-research/src/stages/scan.js +0 -608
  177. package/.claude/worktrees/sillyspec-data-model-research/src/stages/status.js +0 -64
  178. package/.claude/worktrees/sillyspec-data-model-research/src/stages/verify.js +0 -246
  179. package/.claude/worktrees/sillyspec-data-model-research/src/sync.js +0 -1470
  180. package/.claude/worktrees/sillyspec-data-model-research/src/task-review.js +0 -1498
  181. package/.claude/worktrees/sillyspec-data-model-research/src/taskcard.js +0 -210
  182. package/.claude/worktrees/sillyspec-data-model-research/src/verify-postcheck.js +0 -1718
  183. package/.claude/worktrees/sillyspec-data-model-research/src/verify-probes.js +0 -277
  184. package/.claude/worktrees/sillyspec-data-model-research/src/version.js +0 -19
  185. package/.claude/worktrees/sillyspec-data-model-research/src/workflow.js +0 -600
  186. package/.claude/worktrees/sillyspec-data-model-research/src/workspace.js +0 -125
  187. package/.claude/worktrees/sillyspec-data-model-research/src/worktree-apply.js +0 -1446
  188. package/.claude/worktrees/sillyspec-data-model-research/src/worktree-deps.js +0 -576
  189. package/.claude/worktrees/sillyspec-data-model-research/src/worktree.js +0 -1715
  190. package/.claude/worktrees/sillyspec-data-model-research/templates/claude-instruction.md +0 -23
  191. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/taskcard-rules.md +0 -28
  192. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/testcase-design.md +0 -12
  193. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/verify-probes.md +0 -32
  194. package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/archive-impact.yaml +0 -79
  195. package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/scan-docs.yaml +0 -132
  196. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  197. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  198. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  199. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  200. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  201. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  202. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  203. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  204. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-export/SKILL.md +0 -57
  205. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-init/SKILL.md +0 -177
  206. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  207. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  208. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  209. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  210. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  211. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  212. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-state/SKILL.md +0 -64
  213. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-status/SKILL.md +0 -54
  214. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  215. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  216. package/.worktrees/2c37b1d7/.claude/skills/verify-per-user/SKILL.md +0 -6
  217. package/.worktrees/2c37b1d7/.gitattributes +0 -2
  218. package/.worktrees/2c37b1d7/.husky/pre-push +0 -20
  219. package/.worktrees/2c37b1d7/README.md +0 -203
  220. package/.worktrees/2c37b1d7/SKILL.md +0 -91
  221. package/.worktrees/2c37b1d7/architecture-analysis.md +0 -448
  222. package/.worktrees/2c37b1d7/bin/sillyspec.js +0 -2
  223. package/.worktrees/2c37b1d7/eval/README.md +0 -86
  224. package/.worktrees/2c37b1d7/eval/eval.config.json +0 -28
  225. package/.worktrees/2c37b1d7/eval/lib/adapters/cli.mjs +0 -63
  226. package/.worktrees/2c37b1d7/eval/lib/adapters/dryrun.mjs +0 -27
  227. package/.worktrees/2c37b1d7/eval/lib/config.mjs +0 -82
  228. package/.worktrees/2c37b1d7/eval/lib/db.mjs +0 -76
  229. package/.worktrees/2c37b1d7/eval/lib/report.mjs +0 -120
  230. package/.worktrees/2c37b1d7/eval/lib/runner.mjs +0 -157
  231. package/.worktrees/2c37b1d7/eval/lib/tasks.mjs +0 -73
  232. package/.worktrees/2c37b1d7/eval/lib/util.mjs +0 -107
  233. package/.worktrees/2c37b1d7/eval/lib/workdir.mjs +0 -30
  234. package/.worktrees/2c37b1d7/eval/run.mjs +0 -83
  235. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/files/package.json +0 -6
  236. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  237. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/task.json +0 -6
  238. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/verify.mjs +0 -28
  239. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/package.json +0 -6
  240. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  241. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  242. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/task.json +0 -6
  243. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/verify.mjs +0 -31
  244. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  245. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/package.json +0 -6
  246. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  247. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/task.json +0 -6
  248. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/verify.mjs +0 -38
  249. package/.worktrees/2c37b1d7/logo.jpg +0 -0
  250. package/.worktrees/2c37b1d7/package-lock.json +0 -977
  251. package/.worktrees/2c37b1d7/package.json +0 -41
  252. package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  253. package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  254. package/.worktrees/2c37b1d7/packages/dashboard/dist/favicon.jpg +0 -0
  255. package/.worktrees/2c37b1d7/packages/dashboard/dist/index.html +0 -16
  256. package/.worktrees/2c37b1d7/packages/dashboard/dist/logo.jpg +0 -0
  257. package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-dashboard.html +0 -836
  258. package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-overview.html +0 -256
  259. package/.worktrees/2c37b1d7/packages/dashboard/package.json +0 -25
  260. package/.worktrees/2c37b1d7/packages/dashboard/server/executor.js +0 -95
  261. package/.worktrees/2c37b1d7/packages/dashboard/server/index.js +0 -679
  262. package/.worktrees/2c37b1d7/packages/dashboard/server/parser.js +0 -526
  263. package/.worktrees/2c37b1d7/packages/dashboard/server/watcher.js +0 -357
  264. package/.worktrees/2c37b1d7/src/agent-session-log.js +0 -803
  265. package/.worktrees/2c37b1d7/src/change-list.js +0 -290
  266. package/.worktrees/2c37b1d7/src/change-risk-profile.js +0 -339
  267. package/.worktrees/2c37b1d7/src/check-primitives.js +0 -65
  268. package/.worktrees/2c37b1d7/src/classify-change.js +0 -109
  269. package/.worktrees/2c37b1d7/src/commit-suggest.js +0 -202
  270. package/.worktrees/2c37b1d7/src/config-cat.js +0 -88
  271. package/.worktrees/2c37b1d7/src/config-schema.js +0 -328
  272. package/.worktrees/2c37b1d7/src/constants.js +0 -97
  273. package/.worktrees/2c37b1d7/src/contract-matrix.js +0 -533
  274. package/.worktrees/2c37b1d7/src/datetime.js +0 -20
  275. package/.worktrees/2c37b1d7/src/db-engine.js +0 -55
  276. package/.worktrees/2c37b1d7/src/db.js +0 -381
  277. package/.worktrees/2c37b1d7/src/decision-distill.js +0 -517
  278. package/.worktrees/2c37b1d7/src/dispatch/backends/local-agent.js +0 -155
  279. package/.worktrees/2c37b1d7/src/dispatch/backends/sillyhub-mcp.js +0 -245
  280. package/.worktrees/2c37b1d7/src/dispatch/probe.js +0 -246
  281. package/.worktrees/2c37b1d7/src/dispatch/strategy.js +0 -121
  282. package/.worktrees/2c37b1d7/src/docs-check.js +0 -825
  283. package/.worktrees/2c37b1d7/src/docs-debt.js +0 -393
  284. package/.worktrees/2c37b1d7/src/docs-gate.js +0 -107
  285. package/.worktrees/2c37b1d7/src/doctor-diagnostics.js +0 -1099
  286. package/.worktrees/2c37b1d7/src/endpoint-extractor.js +0 -409
  287. package/.worktrees/2c37b1d7/src/foreign-declared.js +0 -155
  288. package/.worktrees/2c37b1d7/src/fs-atomic.js +0 -73
  289. package/.worktrees/2c37b1d7/src/git-helper.js +0 -150
  290. package/.worktrees/2c37b1d7/src/hooks/claude-pre-tool-use.cjs +0 -130
  291. package/.worktrees/2c37b1d7/src/hooks/worktree-guard.js +0 -892
  292. package/.worktrees/2c37b1d7/src/index.js +0 -2854
  293. package/.worktrees/2c37b1d7/src/init.js +0 -626
  294. package/.worktrees/2c37b1d7/src/knowledge-match.js +0 -231
  295. package/.worktrees/2c37b1d7/src/local-detect.js +0 -128
  296. package/.worktrees/2c37b1d7/src/local-register.js +0 -104
  297. package/.worktrees/2c37b1d7/src/machine-interface.js +0 -543
  298. package/.worktrees/2c37b1d7/src/migrate.js +0 -127
  299. package/.worktrees/2c37b1d7/src/module-impact.js +0 -166
  300. package/.worktrees/2c37b1d7/src/module-resolve.js +0 -222
  301. package/.worktrees/2c37b1d7/src/modules.js +0 -580
  302. package/.worktrees/2c37b1d7/src/plan-adopt-waves.js +0 -126
  303. package/.worktrees/2c37b1d7/src/progress/change-registry.js +0 -336
  304. package/.worktrees/2c37b1d7/src/progress/consistency-doctor.js +0 -355
  305. package/.worktrees/2c37b1d7/src/progress/shared.js +0 -36
  306. package/.worktrees/2c37b1d7/src/progress/stage-machine.js +0 -594
  307. package/.worktrees/2c37b1d7/src/progress/step-store.js +0 -265
  308. package/.worktrees/2c37b1d7/src/progress.js +0 -1304
  309. package/.worktrees/2c37b1d7/src/quick-recommend.js +0 -115
  310. package/.worktrees/2c37b1d7/src/quicklog.js +0 -883
  311. package/.worktrees/2c37b1d7/src/review-tier.js +0 -77
  312. package/.worktrees/2c37b1d7/src/run/command.js +0 -1641
  313. package/.worktrees/2c37b1d7/src/run/complete-handlers.js +0 -1552
  314. package/.worktrees/2c37b1d7/src/run/complete.js +0 -1259
  315. package/.worktrees/2c37b1d7/src/run/concurrent-detect.js +0 -156
  316. package/.worktrees/2c37b1d7/src/run/gates.js +0 -1111
  317. package/.worktrees/2c37b1d7/src/run/multi-repo-context.js +0 -208
  318. package/.worktrees/2c37b1d7/src/run/next.js +0 -128
  319. package/.worktrees/2c37b1d7/src/run/prompt.js +0 -843
  320. package/.worktrees/2c37b1d7/src/run/quick-audit.js +0 -186
  321. package/.worktrees/2c37b1d7/src/run/scan-profile.js +0 -269
  322. package/.worktrees/2c37b1d7/src/run/shared.js +0 -1562
  323. package/.worktrees/2c37b1d7/src/run/stage.js +0 -587
  324. package/.worktrees/2c37b1d7/src/run.js +0 -23
  325. package/.worktrees/2c37b1d7/src/scan-diff.js +0 -388
  326. package/.worktrees/2c37b1d7/src/scan-postcheck.js +0 -524
  327. package/.worktrees/2c37b1d7/src/scan-staleness.js +0 -95
  328. package/.worktrees/2c37b1d7/src/setup.js +0 -414
  329. package/.worktrees/2c37b1d7/src/sillyhub-mcp/client.js +0 -597
  330. package/.worktrees/2c37b1d7/src/sillyhub-mcp/config.js +0 -62
  331. package/.worktrees/2c37b1d7/src/spec-dir-typo.js +0 -50
  332. package/.worktrees/2c37b1d7/src/spec-sync.js +0 -358
  333. package/.worktrees/2c37b1d7/src/stage-contract-engine.js +0 -171
  334. package/.worktrees/2c37b1d7/src/stage-contract-spec.js +0 -551
  335. package/.worktrees/2c37b1d7/src/stage-contract.js +0 -948
  336. package/.worktrees/2c37b1d7/src/stage-review.js +0 -597
  337. package/.worktrees/2c37b1d7/src/stages/archive.js +0 -199
  338. package/.worktrees/2c37b1d7/src/stages/brainstorm-auto.js +0 -285
  339. package/.worktrees/2c37b1d7/src/stages/brainstorm.js +0 -624
  340. package/.worktrees/2c37b1d7/src/stages/cmd-existence.js +0 -145
  341. package/.worktrees/2c37b1d7/src/stages/doctor.js +0 -540
  342. package/.worktrees/2c37b1d7/src/stages/execute.js +0 -1277
  343. package/.worktrees/2c37b1d7/src/stages/explore.js +0 -43
  344. package/.worktrees/2c37b1d7/src/stages/index.js +0 -29
  345. package/.worktrees/2c37b1d7/src/stages/knowledge.js +0 -514
  346. package/.worktrees/2c37b1d7/src/stages/plan-postcheck.js +0 -1398
  347. package/.worktrees/2c37b1d7/src/stages/plan.js +0 -655
  348. package/.worktrees/2c37b1d7/src/stages/quick.js +0 -167
  349. package/.worktrees/2c37b1d7/src/stages/scan.js +0 -608
  350. package/.worktrees/2c37b1d7/src/stages/status.js +0 -64
  351. package/.worktrees/2c37b1d7/src/stages/verify.js +0 -246
  352. package/.worktrees/2c37b1d7/src/sync.js +0 -1470
  353. package/.worktrees/2c37b1d7/src/task-review.js +0 -1498
  354. package/.worktrees/2c37b1d7/src/taskcard-placeholders.js +0 -21
  355. package/.worktrees/2c37b1d7/src/taskcard.js +0 -250
  356. package/.worktrees/2c37b1d7/src/verify-postcheck.js +0 -1718
  357. package/.worktrees/2c37b1d7/src/verify-probes.js +0 -327
  358. package/.worktrees/2c37b1d7/src/version.js +0 -19
  359. package/.worktrees/2c37b1d7/src/workflow.js +0 -600
  360. package/.worktrees/2c37b1d7/src/workspace.js +0 -125
  361. package/.worktrees/2c37b1d7/src/worktree-apply.js +0 -1611
  362. package/.worktrees/2c37b1d7/src/worktree-deps.js +0 -668
  363. package/.worktrees/2c37b1d7/src/worktree.js +0 -1849
  364. package/.worktrees/2c37b1d7/templates/claude-instruction.md +0 -23
  365. package/.worktrees/2c37b1d7/templates/prompts/taskcard-rules.md +0 -29
  366. package/.worktrees/2c37b1d7/templates/prompts/testcase-design.md +0 -12
  367. package/.worktrees/2c37b1d7/templates/prompts/verify-probes.md +0 -32
  368. package/.worktrees/2c37b1d7/templates/workflows/archive-impact.yaml +0 -79
  369. package/.worktrees/2c37b1d7/templates/workflows/scan-docs.yaml +0 -132
  370. package/.worktrees/542c4415/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  371. package/.worktrees/542c4415/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  372. package/.worktrees/542c4415/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  373. package/.worktrees/542c4415/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  374. package/.worktrees/542c4415/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  375. package/.worktrees/542c4415/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  376. package/.worktrees/542c4415/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  377. package/.worktrees/542c4415/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  378. package/.worktrees/542c4415/.claude/skills/sillyspec-export/SKILL.md +0 -57
  379. package/.worktrees/542c4415/.claude/skills/sillyspec-init/SKILL.md +0 -177
  380. package/.worktrees/542c4415/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  381. package/.worktrees/542c4415/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  382. package/.worktrees/542c4415/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  383. package/.worktrees/542c4415/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  384. package/.worktrees/542c4415/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  385. package/.worktrees/542c4415/.claude/skills/sillyspec-state/SKILL.md +0 -64
  386. package/.worktrees/542c4415/.claude/skills/sillyspec-status/SKILL.md +0 -54
  387. package/.worktrees/542c4415/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  388. package/.worktrees/542c4415/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  389. package/.worktrees/542c4415/.gitattributes +0 -2
  390. package/.worktrees/542c4415/.husky/pre-push +0 -20
  391. package/.worktrees/542c4415/README.md +0 -203
  392. package/.worktrees/542c4415/SKILL.md +0 -91
  393. package/.worktrees/542c4415/architecture-analysis.md +0 -448
  394. package/.worktrees/542c4415/bin/sillyspec.js +0 -2
  395. package/.worktrees/542c4415/eval/README.md +0 -86
  396. package/.worktrees/542c4415/eval/eval.config.json +0 -28
  397. package/.worktrees/542c4415/eval/lib/adapters/cli.mjs +0 -63
  398. package/.worktrees/542c4415/eval/lib/adapters/dryrun.mjs +0 -27
  399. package/.worktrees/542c4415/eval/lib/config.mjs +0 -82
  400. package/.worktrees/542c4415/eval/lib/db.mjs +0 -76
  401. package/.worktrees/542c4415/eval/lib/report.mjs +0 -120
  402. package/.worktrees/542c4415/eval/lib/runner.mjs +0 -157
  403. package/.worktrees/542c4415/eval/lib/tasks.mjs +0 -73
  404. package/.worktrees/542c4415/eval/lib/util.mjs +0 -107
  405. package/.worktrees/542c4415/eval/lib/workdir.mjs +0 -30
  406. package/.worktrees/542c4415/eval/run.mjs +0 -83
  407. package/.worktrees/542c4415/eval/tasks/001-slugify/files/package.json +0 -6
  408. package/.worktrees/542c4415/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  409. package/.worktrees/542c4415/eval/tasks/001-slugify/task.json +0 -6
  410. package/.worktrees/542c4415/eval/tasks/001-slugify/verify.mjs +0 -28
  411. package/.worktrees/542c4415/eval/tasks/002-each-day/files/package.json +0 -6
  412. package/.worktrees/542c4415/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  413. package/.worktrees/542c4415/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  414. package/.worktrees/542c4415/eval/tasks/002-each-day/task.json +0 -6
  415. package/.worktrees/542c4415/eval/tasks/002-each-day/verify.mjs +0 -31
  416. package/.worktrees/542c4415/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  417. package/.worktrees/542c4415/eval/tasks/003-word-report/files/package.json +0 -6
  418. package/.worktrees/542c4415/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  419. package/.worktrees/542c4415/eval/tasks/003-word-report/task.json +0 -6
  420. package/.worktrees/542c4415/eval/tasks/003-word-report/verify.mjs +0 -38
  421. package/.worktrees/542c4415/logo.jpg +0 -0
  422. package/.worktrees/542c4415/package-lock.json +0 -977
  423. package/.worktrees/542c4415/package.json +0 -41
  424. package/.worktrees/542c4415/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  425. package/.worktrees/542c4415/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  426. package/.worktrees/542c4415/packages/dashboard/dist/favicon.jpg +0 -0
  427. package/.worktrees/542c4415/packages/dashboard/dist/index.html +0 -16
  428. package/.worktrees/542c4415/packages/dashboard/dist/logo.jpg +0 -0
  429. package/.worktrees/542c4415/packages/dashboard/dist/prototype-dashboard.html +0 -836
  430. package/.worktrees/542c4415/packages/dashboard/dist/prototype-overview.html +0 -256
  431. package/.worktrees/542c4415/packages/dashboard/package.json +0 -25
  432. package/.worktrees/542c4415/packages/dashboard/server/executor.js +0 -95
  433. package/.worktrees/542c4415/packages/dashboard/server/index.js +0 -679
  434. package/.worktrees/542c4415/packages/dashboard/server/parser.js +0 -526
  435. package/.worktrees/542c4415/packages/dashboard/server/watcher.js +0 -357
  436. package/.worktrees/542c4415/src/agent-session-log.js +0 -803
  437. package/.worktrees/542c4415/src/change-list.js +0 -290
  438. package/.worktrees/542c4415/src/change-risk-profile.js +0 -339
  439. package/.worktrees/542c4415/src/check-primitives.js +0 -65
  440. package/.worktrees/542c4415/src/classify-change.js +0 -109
  441. package/.worktrees/542c4415/src/commit-suggest.js +0 -202
  442. package/.worktrees/542c4415/src/config-cat.js +0 -88
  443. package/.worktrees/542c4415/src/config-schema.js +0 -328
  444. package/.worktrees/542c4415/src/constants.js +0 -97
  445. package/.worktrees/542c4415/src/contract-matrix.js +0 -533
  446. package/.worktrees/542c4415/src/datetime.js +0 -20
  447. package/.worktrees/542c4415/src/db-engine.js +0 -55
  448. package/.worktrees/542c4415/src/db.js +0 -381
  449. package/.worktrees/542c4415/src/decision-distill.js +0 -517
  450. package/.worktrees/542c4415/src/dispatch/backends/local-agent.js +0 -155
  451. package/.worktrees/542c4415/src/dispatch/backends/sillyhub-mcp.js +0 -245
  452. package/.worktrees/542c4415/src/dispatch/probe.js +0 -246
  453. package/.worktrees/542c4415/src/dispatch/strategy.js +0 -121
  454. package/.worktrees/542c4415/src/docs-check.js +0 -825
  455. package/.worktrees/542c4415/src/docs-debt.js +0 -393
  456. package/.worktrees/542c4415/src/docs-gate.js +0 -107
  457. package/.worktrees/542c4415/src/doctor-diagnostics.js +0 -1099
  458. package/.worktrees/542c4415/src/endpoint-extractor.js +0 -409
  459. package/.worktrees/542c4415/src/foreign-declared.js +0 -155
  460. package/.worktrees/542c4415/src/fs-atomic.js +0 -73
  461. package/.worktrees/542c4415/src/git-helper.js +0 -150
  462. package/.worktrees/542c4415/src/hooks/claude-pre-tool-use.cjs +0 -130
  463. package/.worktrees/542c4415/src/hooks/worktree-guard.js +0 -892
  464. package/.worktrees/542c4415/src/index.js +0 -2854
  465. package/.worktrees/542c4415/src/init.js +0 -626
  466. package/.worktrees/542c4415/src/knowledge-match.js +0 -231
  467. package/.worktrees/542c4415/src/local-detect.js +0 -128
  468. package/.worktrees/542c4415/src/local-register.js +0 -104
  469. package/.worktrees/542c4415/src/machine-interface.js +0 -543
  470. package/.worktrees/542c4415/src/migrate.js +0 -127
  471. package/.worktrees/542c4415/src/module-impact.js +0 -166
  472. package/.worktrees/542c4415/src/module-resolve.js +0 -222
  473. package/.worktrees/542c4415/src/modules.js +0 -580
  474. package/.worktrees/542c4415/src/plan-adopt-waves.js +0 -126
  475. package/.worktrees/542c4415/src/progress/change-registry.js +0 -336
  476. package/.worktrees/542c4415/src/progress/consistency-doctor.js +0 -355
  477. package/.worktrees/542c4415/src/progress/shared.js +0 -36
  478. package/.worktrees/542c4415/src/progress/stage-machine.js +0 -594
  479. package/.worktrees/542c4415/src/progress/step-store.js +0 -265
  480. package/.worktrees/542c4415/src/progress.js +0 -1304
  481. package/.worktrees/542c4415/src/quick-recommend.js +0 -115
  482. package/.worktrees/542c4415/src/quicklog.js +0 -883
  483. package/.worktrees/542c4415/src/review-tier.js +0 -77
  484. package/.worktrees/542c4415/src/run/command.js +0 -1641
  485. package/.worktrees/542c4415/src/run/complete-handlers.js +0 -1552
  486. package/.worktrees/542c4415/src/run/complete.js +0 -1259
  487. package/.worktrees/542c4415/src/run/concurrent-detect.js +0 -156
  488. package/.worktrees/542c4415/src/run/gates.js +0 -1111
  489. package/.worktrees/542c4415/src/run/multi-repo-context.js +0 -208
  490. package/.worktrees/542c4415/src/run/next.js +0 -128
  491. package/.worktrees/542c4415/src/run/prompt.js +0 -843
  492. package/.worktrees/542c4415/src/run/quick-audit.js +0 -186
  493. package/.worktrees/542c4415/src/run/scan-profile.js +0 -269
  494. package/.worktrees/542c4415/src/run/shared.js +0 -1562
  495. package/.worktrees/542c4415/src/run/stage.js +0 -587
  496. package/.worktrees/542c4415/src/run.js +0 -23
  497. package/.worktrees/542c4415/src/scan-diff.js +0 -388
  498. package/.worktrees/542c4415/src/scan-postcheck.js +0 -524
  499. package/.worktrees/542c4415/src/scan-staleness.js +0 -95
  500. package/.worktrees/542c4415/src/setup.js +0 -414
  501. package/.worktrees/542c4415/src/sillyhub-mcp/client.js +0 -597
  502. package/.worktrees/542c4415/src/sillyhub-mcp/config.js +0 -62
  503. package/.worktrees/542c4415/src/spec-dir-typo.js +0 -50
  504. package/.worktrees/542c4415/src/spec-sync.js +0 -358
  505. package/.worktrees/542c4415/src/stage-contract-engine.js +0 -171
  506. package/.worktrees/542c4415/src/stage-contract-spec.js +0 -551
  507. package/.worktrees/542c4415/src/stage-contract.js +0 -948
  508. package/.worktrees/542c4415/src/stage-review.js +0 -597
  509. package/.worktrees/542c4415/src/stages/archive.js +0 -199
  510. package/.worktrees/542c4415/src/stages/brainstorm-auto.js +0 -285
  511. package/.worktrees/542c4415/src/stages/brainstorm.js +0 -624
  512. package/.worktrees/542c4415/src/stages/cmd-existence.js +0 -145
  513. package/.worktrees/542c4415/src/stages/doctor.js +0 -540
  514. package/.worktrees/542c4415/src/stages/execute.js +0 -1277
  515. package/.worktrees/542c4415/src/stages/explore.js +0 -43
  516. package/.worktrees/542c4415/src/stages/index.js +0 -29
  517. package/.worktrees/542c4415/src/stages/knowledge.js +0 -514
  518. package/.worktrees/542c4415/src/stages/plan-postcheck.js +0 -1398
  519. package/.worktrees/542c4415/src/stages/plan.js +0 -655
  520. package/.worktrees/542c4415/src/stages/quick.js +0 -167
  521. package/.worktrees/542c4415/src/stages/scan.js +0 -608
  522. package/.worktrees/542c4415/src/stages/status.js +0 -64
  523. package/.worktrees/542c4415/src/stages/verify.js +0 -246
  524. package/.worktrees/542c4415/src/sync.js +0 -1470
  525. package/.worktrees/542c4415/src/task-review.js +0 -1498
  526. package/.worktrees/542c4415/src/taskcard-placeholders.js +0 -21
  527. package/.worktrees/542c4415/src/taskcard.js +0 -250
  528. package/.worktrees/542c4415/src/verify-postcheck.js +0 -1718
  529. package/.worktrees/542c4415/src/verify-probes.js +0 -327
  530. package/.worktrees/542c4415/src/version.js +0 -19
  531. package/.worktrees/542c4415/src/workflow.js +0 -600
  532. package/.worktrees/542c4415/src/workspace.js +0 -125
  533. package/.worktrees/542c4415/src/worktree-apply.js +0 -1611
  534. package/.worktrees/542c4415/src/worktree-deps.js +0 -668
  535. package/.worktrees/542c4415/src/worktree.js +0 -1849
  536. package/.worktrees/542c4415/templates/claude-instruction.md +0 -23
  537. package/.worktrees/542c4415/templates/prompts/taskcard-rules.md +0 -29
  538. package/.worktrees/542c4415/templates/prompts/testcase-design.md +0 -12
  539. package/.worktrees/542c4415/templates/prompts/verify-probes.md +0 -32
  540. package/.worktrees/542c4415/templates/workflows/archive-impact.yaml +0 -79
  541. package/.worktrees/542c4415/templates/workflows/scan-docs.yaml +0 -132
  542. package/.worktrees/8d2d0392/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  543. package/.worktrees/8d2d0392/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  544. package/.worktrees/8d2d0392/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  545. package/.worktrees/8d2d0392/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  546. package/.worktrees/8d2d0392/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  547. package/.worktrees/8d2d0392/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  548. package/.worktrees/8d2d0392/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  549. package/.worktrees/8d2d0392/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  550. package/.worktrees/8d2d0392/.claude/skills/sillyspec-export/SKILL.md +0 -57
  551. package/.worktrees/8d2d0392/.claude/skills/sillyspec-init/SKILL.md +0 -177
  552. package/.worktrees/8d2d0392/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  553. package/.worktrees/8d2d0392/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  554. package/.worktrees/8d2d0392/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  555. package/.worktrees/8d2d0392/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  556. package/.worktrees/8d2d0392/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  557. package/.worktrees/8d2d0392/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  558. package/.worktrees/8d2d0392/.claude/skills/sillyspec-state/SKILL.md +0 -64
  559. package/.worktrees/8d2d0392/.claude/skills/sillyspec-status/SKILL.md +0 -54
  560. package/.worktrees/8d2d0392/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  561. package/.worktrees/8d2d0392/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  562. package/.worktrees/8d2d0392/.claude/skills/verify-per-user/SKILL.md +0 -6
  563. package/.worktrees/8d2d0392/.gitattributes +0 -2
  564. package/.worktrees/8d2d0392/.husky/pre-push +0 -20
  565. package/.worktrees/8d2d0392/README.md +0 -203
  566. package/.worktrees/8d2d0392/SKILL.md +0 -91
  567. package/.worktrees/8d2d0392/architecture-analysis.md +0 -448
  568. package/.worktrees/8d2d0392/bin/sillyspec.js +0 -2
  569. package/.worktrees/8d2d0392/eval/README.md +0 -86
  570. package/.worktrees/8d2d0392/eval/eval.config.json +0 -28
  571. package/.worktrees/8d2d0392/eval/lib/adapters/cli.mjs +0 -63
  572. package/.worktrees/8d2d0392/eval/lib/adapters/dryrun.mjs +0 -27
  573. package/.worktrees/8d2d0392/eval/lib/config.mjs +0 -82
  574. package/.worktrees/8d2d0392/eval/lib/db.mjs +0 -76
  575. package/.worktrees/8d2d0392/eval/lib/report.mjs +0 -120
  576. package/.worktrees/8d2d0392/eval/lib/runner.mjs +0 -157
  577. package/.worktrees/8d2d0392/eval/lib/tasks.mjs +0 -73
  578. package/.worktrees/8d2d0392/eval/lib/util.mjs +0 -107
  579. package/.worktrees/8d2d0392/eval/lib/workdir.mjs +0 -30
  580. package/.worktrees/8d2d0392/eval/run.mjs +0 -83
  581. package/.worktrees/8d2d0392/eval/tasks/001-slugify/files/package.json +0 -6
  582. package/.worktrees/8d2d0392/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  583. package/.worktrees/8d2d0392/eval/tasks/001-slugify/task.json +0 -6
  584. package/.worktrees/8d2d0392/eval/tasks/001-slugify/verify.mjs +0 -28
  585. package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/package.json +0 -6
  586. package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  587. package/.worktrees/8d2d0392/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  588. package/.worktrees/8d2d0392/eval/tasks/002-each-day/task.json +0 -6
  589. package/.worktrees/8d2d0392/eval/tasks/002-each-day/verify.mjs +0 -31
  590. package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  591. package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/package.json +0 -6
  592. package/.worktrees/8d2d0392/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  593. package/.worktrees/8d2d0392/eval/tasks/003-word-report/task.json +0 -6
  594. package/.worktrees/8d2d0392/eval/tasks/003-word-report/verify.mjs +0 -38
  595. package/.worktrees/8d2d0392/logo.jpg +0 -0
  596. package/.worktrees/8d2d0392/package-lock.json +0 -977
  597. package/.worktrees/8d2d0392/package.json +0 -41
  598. package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  599. package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  600. package/.worktrees/8d2d0392/packages/dashboard/dist/favicon.jpg +0 -0
  601. package/.worktrees/8d2d0392/packages/dashboard/dist/index.html +0 -16
  602. package/.worktrees/8d2d0392/packages/dashboard/dist/logo.jpg +0 -0
  603. package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-dashboard.html +0 -836
  604. package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-overview.html +0 -256
  605. package/.worktrees/8d2d0392/packages/dashboard/package.json +0 -25
  606. package/.worktrees/8d2d0392/packages/dashboard/server/executor.js +0 -95
  607. package/.worktrees/8d2d0392/packages/dashboard/server/index.js +0 -679
  608. package/.worktrees/8d2d0392/packages/dashboard/server/parser.js +0 -526
  609. package/.worktrees/8d2d0392/packages/dashboard/server/watcher.js +0 -357
  610. package/.worktrees/8d2d0392/src/agent-session-log.js +0 -803
  611. package/.worktrees/8d2d0392/src/change-list.js +0 -290
  612. package/.worktrees/8d2d0392/src/change-risk-profile.js +0 -339
  613. package/.worktrees/8d2d0392/src/check-primitives.js +0 -65
  614. package/.worktrees/8d2d0392/src/classify-change.js +0 -109
  615. package/.worktrees/8d2d0392/src/commit-suggest.js +0 -202
  616. package/.worktrees/8d2d0392/src/config-cat.js +0 -88
  617. package/.worktrees/8d2d0392/src/config-schema.js +0 -328
  618. package/.worktrees/8d2d0392/src/constants.js +0 -97
  619. package/.worktrees/8d2d0392/src/contract-matrix.js +0 -533
  620. package/.worktrees/8d2d0392/src/datetime.js +0 -20
  621. package/.worktrees/8d2d0392/src/db-engine.js +0 -55
  622. package/.worktrees/8d2d0392/src/db.js +0 -381
  623. package/.worktrees/8d2d0392/src/decision-distill.js +0 -517
  624. package/.worktrees/8d2d0392/src/dispatch/backends/local-agent.js +0 -155
  625. package/.worktrees/8d2d0392/src/dispatch/backends/sillyhub-mcp.js +0 -245
  626. package/.worktrees/8d2d0392/src/dispatch/probe.js +0 -246
  627. package/.worktrees/8d2d0392/src/dispatch/strategy.js +0 -121
  628. package/.worktrees/8d2d0392/src/docs-check.js +0 -825
  629. package/.worktrees/8d2d0392/src/docs-debt.js +0 -393
  630. package/.worktrees/8d2d0392/src/docs-gate.js +0 -107
  631. package/.worktrees/8d2d0392/src/doctor-diagnostics.js +0 -1099
  632. package/.worktrees/8d2d0392/src/endpoint-extractor.js +0 -409
  633. package/.worktrees/8d2d0392/src/foreign-declared.js +0 -78
  634. package/.worktrees/8d2d0392/src/fs-atomic.js +0 -73
  635. package/.worktrees/8d2d0392/src/git-helper.js +0 -150
  636. package/.worktrees/8d2d0392/src/hooks/claude-pre-tool-use.cjs +0 -130
  637. package/.worktrees/8d2d0392/src/hooks/worktree-guard.js +0 -892
  638. package/.worktrees/8d2d0392/src/index.js +0 -2854
  639. package/.worktrees/8d2d0392/src/init.js +0 -626
  640. package/.worktrees/8d2d0392/src/knowledge-match.js +0 -231
  641. package/.worktrees/8d2d0392/src/local-detect.js +0 -128
  642. package/.worktrees/8d2d0392/src/local-register.js +0 -104
  643. package/.worktrees/8d2d0392/src/machine-interface.js +0 -543
  644. package/.worktrees/8d2d0392/src/migrate.js +0 -127
  645. package/.worktrees/8d2d0392/src/module-impact.js +0 -166
  646. package/.worktrees/8d2d0392/src/module-resolve.js +0 -222
  647. package/.worktrees/8d2d0392/src/modules.js +0 -580
  648. package/.worktrees/8d2d0392/src/plan-adopt-waves.js +0 -126
  649. package/.worktrees/8d2d0392/src/progress/change-registry.js +0 -336
  650. package/.worktrees/8d2d0392/src/progress/consistency-doctor.js +0 -355
  651. package/.worktrees/8d2d0392/src/progress/shared.js +0 -36
  652. package/.worktrees/8d2d0392/src/progress/stage-machine.js +0 -594
  653. package/.worktrees/8d2d0392/src/progress/step-store.js +0 -265
  654. package/.worktrees/8d2d0392/src/progress.js +0 -1304
  655. package/.worktrees/8d2d0392/src/quick-recommend.js +0 -115
  656. package/.worktrees/8d2d0392/src/quicklog.js +0 -883
  657. package/.worktrees/8d2d0392/src/review-tier.js +0 -77
  658. package/.worktrees/8d2d0392/src/run/command.js +0 -1641
  659. package/.worktrees/8d2d0392/src/run/complete-handlers.js +0 -1552
  660. package/.worktrees/8d2d0392/src/run/complete.js +0 -1259
  661. package/.worktrees/8d2d0392/src/run/concurrent-detect.js +0 -156
  662. package/.worktrees/8d2d0392/src/run/gates.js +0 -1094
  663. package/.worktrees/8d2d0392/src/run/multi-repo-context.js +0 -208
  664. package/.worktrees/8d2d0392/src/run/next.js +0 -128
  665. package/.worktrees/8d2d0392/src/run/prompt.js +0 -843
  666. package/.worktrees/8d2d0392/src/run/quick-audit.js +0 -186
  667. package/.worktrees/8d2d0392/src/run/scan-profile.js +0 -269
  668. package/.worktrees/8d2d0392/src/run/shared.js +0 -1562
  669. package/.worktrees/8d2d0392/src/run/stage.js +0 -587
  670. package/.worktrees/8d2d0392/src/run.js +0 -23
  671. package/.worktrees/8d2d0392/src/scan-diff.js +0 -388
  672. package/.worktrees/8d2d0392/src/scan-postcheck.js +0 -524
  673. package/.worktrees/8d2d0392/src/scan-staleness.js +0 -95
  674. package/.worktrees/8d2d0392/src/setup.js +0 -414
  675. package/.worktrees/8d2d0392/src/sillyhub-mcp/client.js +0 -597
  676. package/.worktrees/8d2d0392/src/sillyhub-mcp/config.js +0 -62
  677. package/.worktrees/8d2d0392/src/spec-dir-typo.js +0 -50
  678. package/.worktrees/8d2d0392/src/spec-sync.js +0 -358
  679. package/.worktrees/8d2d0392/src/stage-contract-engine.js +0 -171
  680. package/.worktrees/8d2d0392/src/stage-contract-spec.js +0 -551
  681. package/.worktrees/8d2d0392/src/stage-contract.js +0 -948
  682. package/.worktrees/8d2d0392/src/stage-review.js +0 -597
  683. package/.worktrees/8d2d0392/src/stages/archive.js +0 -199
  684. package/.worktrees/8d2d0392/src/stages/brainstorm-auto.js +0 -285
  685. package/.worktrees/8d2d0392/src/stages/brainstorm.js +0 -624
  686. package/.worktrees/8d2d0392/src/stages/cmd-existence.js +0 -145
  687. package/.worktrees/8d2d0392/src/stages/doctor.js +0 -540
  688. package/.worktrees/8d2d0392/src/stages/execute.js +0 -1277
  689. package/.worktrees/8d2d0392/src/stages/explore.js +0 -43
  690. package/.worktrees/8d2d0392/src/stages/index.js +0 -29
  691. package/.worktrees/8d2d0392/src/stages/knowledge.js +0 -514
  692. package/.worktrees/8d2d0392/src/stages/plan-postcheck.js +0 -1398
  693. package/.worktrees/8d2d0392/src/stages/plan.js +0 -651
  694. package/.worktrees/8d2d0392/src/stages/quick.js +0 -167
  695. package/.worktrees/8d2d0392/src/stages/scan.js +0 -608
  696. package/.worktrees/8d2d0392/src/stages/status.js +0 -64
  697. package/.worktrees/8d2d0392/src/stages/verify.js +0 -246
  698. package/.worktrees/8d2d0392/src/sync.js +0 -1470
  699. package/.worktrees/8d2d0392/src/task-review.js +0 -1498
  700. package/.worktrees/8d2d0392/src/taskcard-placeholders.js +0 -21
  701. package/.worktrees/8d2d0392/src/taskcard.js +0 -217
  702. package/.worktrees/8d2d0392/src/verify-postcheck.js +0 -1718
  703. package/.worktrees/8d2d0392/src/verify-probes.js +0 -327
  704. package/.worktrees/8d2d0392/src/version.js +0 -19
  705. package/.worktrees/8d2d0392/src/workflow.js +0 -600
  706. package/.worktrees/8d2d0392/src/workspace.js +0 -125
  707. package/.worktrees/8d2d0392/src/worktree-apply.js +0 -1611
  708. package/.worktrees/8d2d0392/src/worktree-deps.js +0 -576
  709. package/.worktrees/8d2d0392/src/worktree.js +0 -1838
  710. package/.worktrees/8d2d0392/templates/claude-instruction.md +0 -23
  711. package/.worktrees/8d2d0392/templates/prompts/taskcard-rules.md +0 -29
  712. package/.worktrees/8d2d0392/templates/prompts/testcase-design.md +0 -12
  713. package/.worktrees/8d2d0392/templates/prompts/verify-probes.md +0 -32
  714. package/.worktrees/8d2d0392/templates/workflows/archive-impact.yaml +0 -79
  715. package/.worktrees/8d2d0392/templates/workflows/scan-docs.yaml +0 -132
  716. package/.worktrees/c1eae35e/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  717. package/.worktrees/c1eae35e/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  718. package/.worktrees/c1eae35e/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  719. package/.worktrees/c1eae35e/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  720. package/.worktrees/c1eae35e/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  721. package/.worktrees/c1eae35e/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  722. package/.worktrees/c1eae35e/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  723. package/.worktrees/c1eae35e/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  724. package/.worktrees/c1eae35e/.claude/skills/sillyspec-export/SKILL.md +0 -57
  725. package/.worktrees/c1eae35e/.claude/skills/sillyspec-init/SKILL.md +0 -177
  726. package/.worktrees/c1eae35e/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  727. package/.worktrees/c1eae35e/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  728. package/.worktrees/c1eae35e/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  729. package/.worktrees/c1eae35e/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  730. package/.worktrees/c1eae35e/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  731. package/.worktrees/c1eae35e/.claude/skills/sillyspec-state/SKILL.md +0 -64
  732. package/.worktrees/c1eae35e/.claude/skills/sillyspec-status/SKILL.md +0 -54
  733. package/.worktrees/c1eae35e/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  734. package/.worktrees/c1eae35e/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  735. package/.worktrees/c1eae35e/.gitattributes +0 -2
  736. package/.worktrees/c1eae35e/.husky/pre-push +0 -20
  737. package/.worktrees/c1eae35e/README.md +0 -203
  738. package/.worktrees/c1eae35e/SKILL.md +0 -91
  739. package/.worktrees/c1eae35e/architecture-analysis.md +0 -448
  740. package/.worktrees/c1eae35e/bin/sillyspec.js +0 -2
  741. package/.worktrees/c1eae35e/eval/README.md +0 -86
  742. package/.worktrees/c1eae35e/eval/eval.config.json +0 -28
  743. package/.worktrees/c1eae35e/eval/lib/adapters/cli.mjs +0 -63
  744. package/.worktrees/c1eae35e/eval/lib/adapters/dryrun.mjs +0 -27
  745. package/.worktrees/c1eae35e/eval/lib/config.mjs +0 -82
  746. package/.worktrees/c1eae35e/eval/lib/db.mjs +0 -76
  747. package/.worktrees/c1eae35e/eval/lib/report.mjs +0 -120
  748. package/.worktrees/c1eae35e/eval/lib/runner.mjs +0 -157
  749. package/.worktrees/c1eae35e/eval/lib/tasks.mjs +0 -73
  750. package/.worktrees/c1eae35e/eval/lib/util.mjs +0 -107
  751. package/.worktrees/c1eae35e/eval/lib/workdir.mjs +0 -30
  752. package/.worktrees/c1eae35e/eval/run.mjs +0 -83
  753. package/.worktrees/c1eae35e/eval/tasks/001-slugify/files/package.json +0 -6
  754. package/.worktrees/c1eae35e/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  755. package/.worktrees/c1eae35e/eval/tasks/001-slugify/task.json +0 -6
  756. package/.worktrees/c1eae35e/eval/tasks/001-slugify/verify.mjs +0 -28
  757. package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/package.json +0 -6
  758. package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  759. package/.worktrees/c1eae35e/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  760. package/.worktrees/c1eae35e/eval/tasks/002-each-day/task.json +0 -6
  761. package/.worktrees/c1eae35e/eval/tasks/002-each-day/verify.mjs +0 -31
  762. package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  763. package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/package.json +0 -6
  764. package/.worktrees/c1eae35e/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  765. package/.worktrees/c1eae35e/eval/tasks/003-word-report/task.json +0 -6
  766. package/.worktrees/c1eae35e/eval/tasks/003-word-report/verify.mjs +0 -38
  767. package/.worktrees/c1eae35e/logo.jpg +0 -0
  768. package/.worktrees/c1eae35e/package-lock.json +0 -977
  769. package/.worktrees/c1eae35e/package.json +0 -41
  770. package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  771. package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  772. package/.worktrees/c1eae35e/packages/dashboard/dist/favicon.jpg +0 -0
  773. package/.worktrees/c1eae35e/packages/dashboard/dist/index.html +0 -16
  774. package/.worktrees/c1eae35e/packages/dashboard/dist/logo.jpg +0 -0
  775. package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-dashboard.html +0 -836
  776. package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-overview.html +0 -256
  777. package/.worktrees/c1eae35e/packages/dashboard/package.json +0 -25
  778. package/.worktrees/c1eae35e/packages/dashboard/server/executor.js +0 -95
  779. package/.worktrees/c1eae35e/packages/dashboard/server/index.js +0 -679
  780. package/.worktrees/c1eae35e/packages/dashboard/server/parser.js +0 -526
  781. package/.worktrees/c1eae35e/packages/dashboard/server/watcher.js +0 -357
  782. package/.worktrees/c1eae35e/src/agent-session-log.js +0 -803
  783. package/.worktrees/c1eae35e/src/change-list.js +0 -290
  784. package/.worktrees/c1eae35e/src/change-risk-profile.js +0 -339
  785. package/.worktrees/c1eae35e/src/check-primitives.js +0 -65
  786. package/.worktrees/c1eae35e/src/classify-change.js +0 -109
  787. package/.worktrees/c1eae35e/src/commit-suggest.js +0 -202
  788. package/.worktrees/c1eae35e/src/config-cat.js +0 -88
  789. package/.worktrees/c1eae35e/src/config-schema.js +0 -328
  790. package/.worktrees/c1eae35e/src/constants.js +0 -97
  791. package/.worktrees/c1eae35e/src/contract-matrix.js +0 -533
  792. package/.worktrees/c1eae35e/src/datetime.js +0 -20
  793. package/.worktrees/c1eae35e/src/db-engine.js +0 -55
  794. package/.worktrees/c1eae35e/src/db.js +0 -381
  795. package/.worktrees/c1eae35e/src/decision-distill.js +0 -517
  796. package/.worktrees/c1eae35e/src/dispatch/backends/local-agent.js +0 -155
  797. package/.worktrees/c1eae35e/src/dispatch/backends/sillyhub-mcp.js +0 -245
  798. package/.worktrees/c1eae35e/src/dispatch/probe.js +0 -246
  799. package/.worktrees/c1eae35e/src/dispatch/strategy.js +0 -121
  800. package/.worktrees/c1eae35e/src/docs-check.js +0 -825
  801. package/.worktrees/c1eae35e/src/docs-debt.js +0 -393
  802. package/.worktrees/c1eae35e/src/docs-gate.js +0 -107
  803. package/.worktrees/c1eae35e/src/doctor-diagnostics.js +0 -1099
  804. package/.worktrees/c1eae35e/src/endpoint-extractor.js +0 -409
  805. package/.worktrees/c1eae35e/src/foreign-declared.js +0 -155
  806. package/.worktrees/c1eae35e/src/fs-atomic.js +0 -73
  807. package/.worktrees/c1eae35e/src/git-helper.js +0 -150
  808. package/.worktrees/c1eae35e/src/hooks/claude-pre-tool-use.cjs +0 -130
  809. package/.worktrees/c1eae35e/src/hooks/worktree-guard.js +0 -892
  810. package/.worktrees/c1eae35e/src/index.js +0 -2854
  811. package/.worktrees/c1eae35e/src/init.js +0 -626
  812. package/.worktrees/c1eae35e/src/knowledge-match.js +0 -231
  813. package/.worktrees/c1eae35e/src/local-detect.js +0 -128
  814. package/.worktrees/c1eae35e/src/local-register.js +0 -104
  815. package/.worktrees/c1eae35e/src/machine-interface.js +0 -543
  816. package/.worktrees/c1eae35e/src/migrate.js +0 -127
  817. package/.worktrees/c1eae35e/src/module-impact.js +0 -166
  818. package/.worktrees/c1eae35e/src/module-resolve.js +0 -222
  819. package/.worktrees/c1eae35e/src/modules.js +0 -580
  820. package/.worktrees/c1eae35e/src/plan-adopt-waves.js +0 -126
  821. package/.worktrees/c1eae35e/src/progress/change-registry.js +0 -336
  822. package/.worktrees/c1eae35e/src/progress/consistency-doctor.js +0 -355
  823. package/.worktrees/c1eae35e/src/progress/shared.js +0 -36
  824. package/.worktrees/c1eae35e/src/progress/stage-machine.js +0 -594
  825. package/.worktrees/c1eae35e/src/progress/step-store.js +0 -265
  826. package/.worktrees/c1eae35e/src/progress.js +0 -1304
  827. package/.worktrees/c1eae35e/src/quick-recommend.js +0 -115
  828. package/.worktrees/c1eae35e/src/quicklog.js +0 -883
  829. package/.worktrees/c1eae35e/src/review-tier.js +0 -77
  830. package/.worktrees/c1eae35e/src/run/command.js +0 -1641
  831. package/.worktrees/c1eae35e/src/run/complete-handlers.js +0 -1552
  832. package/.worktrees/c1eae35e/src/run/complete.js +0 -1259
  833. package/.worktrees/c1eae35e/src/run/concurrent-detect.js +0 -156
  834. package/.worktrees/c1eae35e/src/run/gates.js +0 -1111
  835. package/.worktrees/c1eae35e/src/run/multi-repo-context.js +0 -208
  836. package/.worktrees/c1eae35e/src/run/next.js +0 -128
  837. package/.worktrees/c1eae35e/src/run/prompt.js +0 -843
  838. package/.worktrees/c1eae35e/src/run/quick-audit.js +0 -186
  839. package/.worktrees/c1eae35e/src/run/scan-profile.js +0 -269
  840. package/.worktrees/c1eae35e/src/run/shared.js +0 -1562
  841. package/.worktrees/c1eae35e/src/run/stage.js +0 -587
  842. package/.worktrees/c1eae35e/src/run.js +0 -23
  843. package/.worktrees/c1eae35e/src/scan-diff.js +0 -388
  844. package/.worktrees/c1eae35e/src/scan-postcheck.js +0 -524
  845. package/.worktrees/c1eae35e/src/scan-staleness.js +0 -95
  846. package/.worktrees/c1eae35e/src/setup.js +0 -414
  847. package/.worktrees/c1eae35e/src/sillyhub-mcp/client.js +0 -597
  848. package/.worktrees/c1eae35e/src/sillyhub-mcp/config.js +0 -62
  849. package/.worktrees/c1eae35e/src/spec-dir-typo.js +0 -50
  850. package/.worktrees/c1eae35e/src/spec-sync.js +0 -358
  851. package/.worktrees/c1eae35e/src/stage-contract-engine.js +0 -171
  852. package/.worktrees/c1eae35e/src/stage-contract-spec.js +0 -551
  853. package/.worktrees/c1eae35e/src/stage-contract.js +0 -948
  854. package/.worktrees/c1eae35e/src/stage-review.js +0 -597
  855. package/.worktrees/c1eae35e/src/stages/archive.js +0 -199
  856. package/.worktrees/c1eae35e/src/stages/brainstorm-auto.js +0 -285
  857. package/.worktrees/c1eae35e/src/stages/brainstorm.js +0 -624
  858. package/.worktrees/c1eae35e/src/stages/cmd-existence.js +0 -145
  859. package/.worktrees/c1eae35e/src/stages/doctor.js +0 -540
  860. package/.worktrees/c1eae35e/src/stages/execute.js +0 -1277
  861. package/.worktrees/c1eae35e/src/stages/explore.js +0 -43
  862. package/.worktrees/c1eae35e/src/stages/index.js +0 -29
  863. package/.worktrees/c1eae35e/src/stages/knowledge.js +0 -514
  864. package/.worktrees/c1eae35e/src/stages/plan-postcheck.js +0 -1398
  865. package/.worktrees/c1eae35e/src/stages/plan.js +0 -655
  866. package/.worktrees/c1eae35e/src/stages/quick.js +0 -167
  867. package/.worktrees/c1eae35e/src/stages/scan.js +0 -608
  868. package/.worktrees/c1eae35e/src/stages/status.js +0 -64
  869. package/.worktrees/c1eae35e/src/stages/verify.js +0 -246
  870. package/.worktrees/c1eae35e/src/sync.js +0 -1470
  871. package/.worktrees/c1eae35e/src/task-review.js +0 -1498
  872. package/.worktrees/c1eae35e/src/taskcard-placeholders.js +0 -21
  873. package/.worktrees/c1eae35e/src/taskcard.js +0 -250
  874. package/.worktrees/c1eae35e/src/verify-postcheck.js +0 -1718
  875. package/.worktrees/c1eae35e/src/verify-probes.js +0 -327
  876. package/.worktrees/c1eae35e/src/version.js +0 -19
  877. package/.worktrees/c1eae35e/src/workflow.js +0 -600
  878. package/.worktrees/c1eae35e/src/workspace.js +0 -125
  879. package/.worktrees/c1eae35e/src/worktree-apply.js +0 -1611
  880. package/.worktrees/c1eae35e/src/worktree-deps.js +0 -668
  881. package/.worktrees/c1eae35e/src/worktree.js +0 -1849
  882. package/.worktrees/c1eae35e/templates/claude-instruction.md +0 -23
  883. package/.worktrees/c1eae35e/templates/prompts/taskcard-rules.md +0 -29
  884. package/.worktrees/c1eae35e/templates/prompts/testcase-design.md +0 -12
  885. package/.worktrees/c1eae35e/templates/prompts/verify-probes.md +0 -32
  886. package/.worktrees/c1eae35e/templates/workflows/archive-impact.yaml +0 -79
  887. package/.worktrees/c1eae35e/templates/workflows/scan-docs.yaml +0 -132
  888. package/.worktrees/dafc71ad/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  889. package/.worktrees/dafc71ad/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  890. package/.worktrees/dafc71ad/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  891. package/.worktrees/dafc71ad/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  892. package/.worktrees/dafc71ad/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  893. package/.worktrees/dafc71ad/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  894. package/.worktrees/dafc71ad/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  895. package/.worktrees/dafc71ad/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  896. package/.worktrees/dafc71ad/.claude/skills/sillyspec-export/SKILL.md +0 -57
  897. package/.worktrees/dafc71ad/.claude/skills/sillyspec-init/SKILL.md +0 -177
  898. package/.worktrees/dafc71ad/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  899. package/.worktrees/dafc71ad/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  900. package/.worktrees/dafc71ad/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  901. package/.worktrees/dafc71ad/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  902. package/.worktrees/dafc71ad/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  903. package/.worktrees/dafc71ad/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  904. package/.worktrees/dafc71ad/.claude/skills/sillyspec-state/SKILL.md +0 -64
  905. package/.worktrees/dafc71ad/.claude/skills/sillyspec-status/SKILL.md +0 -54
  906. package/.worktrees/dafc71ad/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  907. package/.worktrees/dafc71ad/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  908. package/.worktrees/dafc71ad/.gitattributes +0 -2
  909. package/.worktrees/dafc71ad/.husky/pre-push +0 -20
  910. package/.worktrees/dafc71ad/README.md +0 -203
  911. package/.worktrees/dafc71ad/SKILL.md +0 -91
  912. package/.worktrees/dafc71ad/analysis.md +0 -366
  913. package/.worktrees/dafc71ad/architecture-analysis.md +0 -448
  914. package/.worktrees/dafc71ad/bin/sillyspec.js +0 -2
  915. package/.worktrees/dafc71ad/eval/README.md +0 -86
  916. package/.worktrees/dafc71ad/eval/eval.config.json +0 -28
  917. package/.worktrees/dafc71ad/eval/lib/adapters/cli.mjs +0 -63
  918. package/.worktrees/dafc71ad/eval/lib/adapters/dryrun.mjs +0 -27
  919. package/.worktrees/dafc71ad/eval/lib/config.mjs +0 -82
  920. package/.worktrees/dafc71ad/eval/lib/db.mjs +0 -76
  921. package/.worktrees/dafc71ad/eval/lib/report.mjs +0 -120
  922. package/.worktrees/dafc71ad/eval/lib/runner.mjs +0 -157
  923. package/.worktrees/dafc71ad/eval/lib/tasks.mjs +0 -73
  924. package/.worktrees/dafc71ad/eval/lib/util.mjs +0 -107
  925. package/.worktrees/dafc71ad/eval/lib/workdir.mjs +0 -30
  926. package/.worktrees/dafc71ad/eval/run.mjs +0 -83
  927. package/.worktrees/dafc71ad/eval/tasks/001-slugify/files/package.json +0 -6
  928. package/.worktrees/dafc71ad/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  929. package/.worktrees/dafc71ad/eval/tasks/001-slugify/task.json +0 -6
  930. package/.worktrees/dafc71ad/eval/tasks/001-slugify/verify.mjs +0 -28
  931. package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/package.json +0 -6
  932. package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  933. package/.worktrees/dafc71ad/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  934. package/.worktrees/dafc71ad/eval/tasks/002-each-day/task.json +0 -6
  935. package/.worktrees/dafc71ad/eval/tasks/002-each-day/verify.mjs +0 -31
  936. package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  937. package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/package.json +0 -6
  938. package/.worktrees/dafc71ad/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  939. package/.worktrees/dafc71ad/eval/tasks/003-word-report/task.json +0 -6
  940. package/.worktrees/dafc71ad/eval/tasks/003-word-report/verify.mjs +0 -38
  941. package/.worktrees/dafc71ad/logo.jpg +0 -0
  942. package/.worktrees/dafc71ad/package-lock.json +0 -977
  943. package/.worktrees/dafc71ad/package.json +0 -41
  944. package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  945. package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  946. package/.worktrees/dafc71ad/packages/dashboard/dist/favicon.jpg +0 -0
  947. package/.worktrees/dafc71ad/packages/dashboard/dist/index.html +0 -16
  948. package/.worktrees/dafc71ad/packages/dashboard/dist/logo.jpg +0 -0
  949. package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-dashboard.html +0 -836
  950. package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-overview.html +0 -256
  951. package/.worktrees/dafc71ad/packages/dashboard/package.json +0 -25
  952. package/.worktrees/dafc71ad/packages/dashboard/server/executor.js +0 -95
  953. package/.worktrees/dafc71ad/packages/dashboard/server/index.js +0 -679
  954. package/.worktrees/dafc71ad/packages/dashboard/server/parser.js +0 -526
  955. package/.worktrees/dafc71ad/packages/dashboard/server/watcher.js +0 -357
  956. package/.worktrees/dafc71ad/src/agent-session-log.js +0 -803
  957. package/.worktrees/dafc71ad/src/change-list.js +0 -290
  958. package/.worktrees/dafc71ad/src/change-risk-profile.js +0 -339
  959. package/.worktrees/dafc71ad/src/check-primitives.js +0 -65
  960. package/.worktrees/dafc71ad/src/classify-change.js +0 -109
  961. package/.worktrees/dafc71ad/src/commit-suggest.js +0 -202
  962. package/.worktrees/dafc71ad/src/config-cat.js +0 -88
  963. package/.worktrees/dafc71ad/src/config-schema.js +0 -328
  964. package/.worktrees/dafc71ad/src/constants.js +0 -97
  965. package/.worktrees/dafc71ad/src/contract-matrix.js +0 -533
  966. package/.worktrees/dafc71ad/src/datetime.js +0 -20
  967. package/.worktrees/dafc71ad/src/db-engine.js +0 -55
  968. package/.worktrees/dafc71ad/src/db.js +0 -381
  969. package/.worktrees/dafc71ad/src/decision-distill.js +0 -517
  970. package/.worktrees/dafc71ad/src/dispatch/backends/local-agent.js +0 -155
  971. package/.worktrees/dafc71ad/src/dispatch/backends/sillyhub-mcp.js +0 -245
  972. package/.worktrees/dafc71ad/src/dispatch/probe.js +0 -246
  973. package/.worktrees/dafc71ad/src/dispatch/strategy.js +0 -121
  974. package/.worktrees/dafc71ad/src/docs-check.js +0 -825
  975. package/.worktrees/dafc71ad/src/docs-debt.js +0 -393
  976. package/.worktrees/dafc71ad/src/docs-gate.js +0 -107
  977. package/.worktrees/dafc71ad/src/doctor-diagnostics.js +0 -1099
  978. package/.worktrees/dafc71ad/src/endpoint-extractor.js +0 -409
  979. package/.worktrees/dafc71ad/src/foreign-declared.js +0 -155
  980. package/.worktrees/dafc71ad/src/fs-atomic.js +0 -73
  981. package/.worktrees/dafc71ad/src/git-helper.js +0 -150
  982. package/.worktrees/dafc71ad/src/hooks/claude-pre-tool-use.cjs +0 -130
  983. package/.worktrees/dafc71ad/src/hooks/worktree-guard.js +0 -892
  984. package/.worktrees/dafc71ad/src/index.js +0 -2854
  985. package/.worktrees/dafc71ad/src/init.js +0 -626
  986. package/.worktrees/dafc71ad/src/knowledge-match.js +0 -231
  987. package/.worktrees/dafc71ad/src/local-detect.js +0 -128
  988. package/.worktrees/dafc71ad/src/local-register.js +0 -104
  989. package/.worktrees/dafc71ad/src/machine-interface.js +0 -543
  990. package/.worktrees/dafc71ad/src/migrate.js +0 -127
  991. package/.worktrees/dafc71ad/src/module-impact.js +0 -166
  992. package/.worktrees/dafc71ad/src/module-resolve.js +0 -222
  993. package/.worktrees/dafc71ad/src/modules.js +0 -580
  994. package/.worktrees/dafc71ad/src/plan-adopt-waves.js +0 -126
  995. package/.worktrees/dafc71ad/src/progress/change-registry.js +0 -336
  996. package/.worktrees/dafc71ad/src/progress/consistency-doctor.js +0 -355
  997. package/.worktrees/dafc71ad/src/progress/shared.js +0 -36
  998. package/.worktrees/dafc71ad/src/progress/stage-machine.js +0 -594
  999. package/.worktrees/dafc71ad/src/progress/step-store.js +0 -265
  1000. package/.worktrees/dafc71ad/src/progress.js +0 -1304
  1001. package/.worktrees/dafc71ad/src/quick-recommend.js +0 -115
  1002. package/.worktrees/dafc71ad/src/quicklog.js +0 -883
  1003. package/.worktrees/dafc71ad/src/review-tier.js +0 -77
  1004. package/.worktrees/dafc71ad/src/run/command.js +0 -1641
  1005. package/.worktrees/dafc71ad/src/run/complete-handlers.js +0 -1552
  1006. package/.worktrees/dafc71ad/src/run/complete.js +0 -1259
  1007. package/.worktrees/dafc71ad/src/run/concurrent-detect.js +0 -156
  1008. package/.worktrees/dafc71ad/src/run/gates.js +0 -1111
  1009. package/.worktrees/dafc71ad/src/run/multi-repo-context.js +0 -208
  1010. package/.worktrees/dafc71ad/src/run/next.js +0 -128
  1011. package/.worktrees/dafc71ad/src/run/prompt.js +0 -843
  1012. package/.worktrees/dafc71ad/src/run/quick-audit.js +0 -186
  1013. package/.worktrees/dafc71ad/src/run/scan-profile.js +0 -269
  1014. package/.worktrees/dafc71ad/src/run/shared.js +0 -1562
  1015. package/.worktrees/dafc71ad/src/run/stage.js +0 -587
  1016. package/.worktrees/dafc71ad/src/run.js +0 -23
  1017. package/.worktrees/dafc71ad/src/scan-diff.js +0 -388
  1018. package/.worktrees/dafc71ad/src/scan-postcheck.js +0 -524
  1019. package/.worktrees/dafc71ad/src/scan-staleness.js +0 -95
  1020. package/.worktrees/dafc71ad/src/setup.js +0 -414
  1021. package/.worktrees/dafc71ad/src/sillyhub-mcp/client.js +0 -597
  1022. package/.worktrees/dafc71ad/src/sillyhub-mcp/config.js +0 -62
  1023. package/.worktrees/dafc71ad/src/spec-dir-typo.js +0 -50
  1024. package/.worktrees/dafc71ad/src/spec-sync.js +0 -358
  1025. package/.worktrees/dafc71ad/src/stage-contract-engine.js +0 -171
  1026. package/.worktrees/dafc71ad/src/stage-contract-spec.js +0 -551
  1027. package/.worktrees/dafc71ad/src/stage-contract.js +0 -948
  1028. package/.worktrees/dafc71ad/src/stage-review.js +0 -597
  1029. package/.worktrees/dafc71ad/src/stages/archive.js +0 -199
  1030. package/.worktrees/dafc71ad/src/stages/brainstorm-auto.js +0 -285
  1031. package/.worktrees/dafc71ad/src/stages/brainstorm.js +0 -624
  1032. package/.worktrees/dafc71ad/src/stages/cmd-existence.js +0 -145
  1033. package/.worktrees/dafc71ad/src/stages/doctor.js +0 -540
  1034. package/.worktrees/dafc71ad/src/stages/execute.js +0 -1277
  1035. package/.worktrees/dafc71ad/src/stages/explore.js +0 -43
  1036. package/.worktrees/dafc71ad/src/stages/index.js +0 -29
  1037. package/.worktrees/dafc71ad/src/stages/knowledge.js +0 -514
  1038. package/.worktrees/dafc71ad/src/stages/plan-postcheck.js +0 -1398
  1039. package/.worktrees/dafc71ad/src/stages/plan.js +0 -655
  1040. package/.worktrees/dafc71ad/src/stages/quick.js +0 -167
  1041. package/.worktrees/dafc71ad/src/stages/scan.js +0 -608
  1042. package/.worktrees/dafc71ad/src/stages/status.js +0 -64
  1043. package/.worktrees/dafc71ad/src/stages/verify.js +0 -246
  1044. package/.worktrees/dafc71ad/src/sync.js +0 -1470
  1045. package/.worktrees/dafc71ad/src/task-review.js +0 -1498
  1046. package/.worktrees/dafc71ad/src/taskcard-placeholders.js +0 -21
  1047. package/.worktrees/dafc71ad/src/taskcard.js +0 -250
  1048. package/.worktrees/dafc71ad/src/verify-postcheck.js +0 -1718
  1049. package/.worktrees/dafc71ad/src/verify-probes.js +0 -327
  1050. package/.worktrees/dafc71ad/src/version.js +0 -19
  1051. package/.worktrees/dafc71ad/src/workflow.js +0 -600
  1052. package/.worktrees/dafc71ad/src/workspace.js +0 -125
  1053. package/.worktrees/dafc71ad/src/worktree-apply.js +0 -1611
  1054. package/.worktrees/dafc71ad/src/worktree-deps.js +0 -668
  1055. package/.worktrees/dafc71ad/src/worktree.js +0 -1849
  1056. package/.worktrees/dafc71ad/templates/claude-instruction.md +0 -23
  1057. package/.worktrees/dafc71ad/templates/prompts/taskcard-rules.md +0 -29
  1058. package/.worktrees/dafc71ad/templates/prompts/testcase-design.md +0 -12
  1059. package/.worktrees/dafc71ad/templates/prompts/verify-probes.md +0 -32
  1060. package/.worktrees/dafc71ad/templates/workflows/archive-impact.yaml +0 -79
  1061. package/.worktrees/dafc71ad/templates/workflows/scan-docs.yaml +0 -132
  1062. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  1063. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  1064. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  1065. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  1066. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  1067. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  1068. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  1069. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  1070. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-export/SKILL.md +0 -57
  1071. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-init/SKILL.md +0 -177
  1072. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  1073. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  1074. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  1075. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  1076. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  1077. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  1078. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-state/SKILL.md +0 -64
  1079. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-status/SKILL.md +0 -54
  1080. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  1081. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  1082. package/.worktrees/e58fcc4c/.gitattributes +0 -2
  1083. package/.worktrees/e58fcc4c/.husky/pre-push +0 -20
  1084. package/.worktrees/e58fcc4c/README.md +0 -203
  1085. package/.worktrees/e58fcc4c/SKILL.md +0 -91
  1086. package/.worktrees/e58fcc4c/architecture-analysis.md +0 -503
  1087. package/.worktrees/e58fcc4c/bin/sillyspec.js +0 -2
  1088. package/.worktrees/e58fcc4c/eval/README.md +0 -86
  1089. package/.worktrees/e58fcc4c/eval/eval.config.json +0 -28
  1090. package/.worktrees/e58fcc4c/eval/lib/adapters/cli.mjs +0 -63
  1091. package/.worktrees/e58fcc4c/eval/lib/adapters/dryrun.mjs +0 -27
  1092. package/.worktrees/e58fcc4c/eval/lib/config.mjs +0 -82
  1093. package/.worktrees/e58fcc4c/eval/lib/db.mjs +0 -76
  1094. package/.worktrees/e58fcc4c/eval/lib/report.mjs +0 -120
  1095. package/.worktrees/e58fcc4c/eval/lib/runner.mjs +0 -157
  1096. package/.worktrees/e58fcc4c/eval/lib/tasks.mjs +0 -73
  1097. package/.worktrees/e58fcc4c/eval/lib/util.mjs +0 -107
  1098. package/.worktrees/e58fcc4c/eval/lib/workdir.mjs +0 -30
  1099. package/.worktrees/e58fcc4c/eval/run.mjs +0 -83
  1100. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/files/package.json +0 -6
  1101. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  1102. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/task.json +0 -6
  1103. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/verify.mjs +0 -28
  1104. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/package.json +0 -6
  1105. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  1106. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  1107. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/task.json +0 -6
  1108. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/verify.mjs +0 -31
  1109. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  1110. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/package.json +0 -6
  1111. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  1112. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/task.json +0 -6
  1113. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/verify.mjs +0 -38
  1114. package/.worktrees/e58fcc4c/logo.jpg +0 -0
  1115. package/.worktrees/e58fcc4c/package-lock.json +0 -977
  1116. package/.worktrees/e58fcc4c/package.json +0 -41
  1117. package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  1118. package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  1119. package/.worktrees/e58fcc4c/packages/dashboard/dist/favicon.jpg +0 -0
  1120. package/.worktrees/e58fcc4c/packages/dashboard/dist/index.html +0 -16
  1121. package/.worktrees/e58fcc4c/packages/dashboard/dist/logo.jpg +0 -0
  1122. package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-dashboard.html +0 -836
  1123. package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-overview.html +0 -256
  1124. package/.worktrees/e58fcc4c/packages/dashboard/package.json +0 -25
  1125. package/.worktrees/e58fcc4c/packages/dashboard/server/executor.js +0 -95
  1126. package/.worktrees/e58fcc4c/packages/dashboard/server/index.js +0 -679
  1127. package/.worktrees/e58fcc4c/packages/dashboard/server/parser.js +0 -526
  1128. package/.worktrees/e58fcc4c/packages/dashboard/server/watcher.js +0 -357
  1129. package/.worktrees/e58fcc4c/src/agent-session-log.js +0 -803
  1130. package/.worktrees/e58fcc4c/src/change-list.js +0 -290
  1131. package/.worktrees/e58fcc4c/src/change-risk-profile.js +0 -339
  1132. package/.worktrees/e58fcc4c/src/check-primitives.js +0 -65
  1133. package/.worktrees/e58fcc4c/src/classify-change.js +0 -109
  1134. package/.worktrees/e58fcc4c/src/commit-suggest.js +0 -202
  1135. package/.worktrees/e58fcc4c/src/config-cat.js +0 -88
  1136. package/.worktrees/e58fcc4c/src/config-schema.js +0 -328
  1137. package/.worktrees/e58fcc4c/src/constants.js +0 -97
  1138. package/.worktrees/e58fcc4c/src/contract-matrix.js +0 -533
  1139. package/.worktrees/e58fcc4c/src/datetime.js +0 -20
  1140. package/.worktrees/e58fcc4c/src/db-engine.js +0 -55
  1141. package/.worktrees/e58fcc4c/src/db.js +0 -381
  1142. package/.worktrees/e58fcc4c/src/decision-distill.js +0 -517
  1143. package/.worktrees/e58fcc4c/src/dispatch/backends/local-agent.js +0 -155
  1144. package/.worktrees/e58fcc4c/src/dispatch/backends/sillyhub-mcp.js +0 -245
  1145. package/.worktrees/e58fcc4c/src/dispatch/probe.js +0 -246
  1146. package/.worktrees/e58fcc4c/src/dispatch/strategy.js +0 -121
  1147. package/.worktrees/e58fcc4c/src/docs-check.js +0 -825
  1148. package/.worktrees/e58fcc4c/src/docs-debt.js +0 -393
  1149. package/.worktrees/e58fcc4c/src/docs-gate.js +0 -107
  1150. package/.worktrees/e58fcc4c/src/doctor-diagnostics.js +0 -1099
  1151. package/.worktrees/e58fcc4c/src/endpoint-extractor.js +0 -409
  1152. package/.worktrees/e58fcc4c/src/foreign-declared.js +0 -155
  1153. package/.worktrees/e58fcc4c/src/fs-atomic.js +0 -73
  1154. package/.worktrees/e58fcc4c/src/git-helper.js +0 -150
  1155. package/.worktrees/e58fcc4c/src/hooks/claude-pre-tool-use.cjs +0 -130
  1156. package/.worktrees/e58fcc4c/src/hooks/worktree-guard.js +0 -892
  1157. package/.worktrees/e58fcc4c/src/index.js +0 -2854
  1158. package/.worktrees/e58fcc4c/src/init.js +0 -626
  1159. package/.worktrees/e58fcc4c/src/knowledge-match.js +0 -231
  1160. package/.worktrees/e58fcc4c/src/local-detect.js +0 -128
  1161. package/.worktrees/e58fcc4c/src/local-register.js +0 -104
  1162. package/.worktrees/e58fcc4c/src/machine-interface.js +0 -543
  1163. package/.worktrees/e58fcc4c/src/migrate.js +0 -127
  1164. package/.worktrees/e58fcc4c/src/module-impact.js +0 -166
  1165. package/.worktrees/e58fcc4c/src/module-resolve.js +0 -222
  1166. package/.worktrees/e58fcc4c/src/modules.js +0 -580
  1167. package/.worktrees/e58fcc4c/src/plan-adopt-waves.js +0 -126
  1168. package/.worktrees/e58fcc4c/src/progress/change-registry.js +0 -336
  1169. package/.worktrees/e58fcc4c/src/progress/consistency-doctor.js +0 -355
  1170. package/.worktrees/e58fcc4c/src/progress/shared.js +0 -36
  1171. package/.worktrees/e58fcc4c/src/progress/stage-machine.js +0 -594
  1172. package/.worktrees/e58fcc4c/src/progress/step-store.js +0 -265
  1173. package/.worktrees/e58fcc4c/src/progress.js +0 -1304
  1174. package/.worktrees/e58fcc4c/src/quick-recommend.js +0 -115
  1175. package/.worktrees/e58fcc4c/src/quicklog.js +0 -883
  1176. package/.worktrees/e58fcc4c/src/review-tier.js +0 -77
  1177. package/.worktrees/e58fcc4c/src/run/command.js +0 -1641
  1178. package/.worktrees/e58fcc4c/src/run/complete-handlers.js +0 -1552
  1179. package/.worktrees/e58fcc4c/src/run/complete.js +0 -1259
  1180. package/.worktrees/e58fcc4c/src/run/concurrent-detect.js +0 -156
  1181. package/.worktrees/e58fcc4c/src/run/gates.js +0 -1111
  1182. package/.worktrees/e58fcc4c/src/run/multi-repo-context.js +0 -208
  1183. package/.worktrees/e58fcc4c/src/run/next.js +0 -128
  1184. package/.worktrees/e58fcc4c/src/run/prompt.js +0 -843
  1185. package/.worktrees/e58fcc4c/src/run/quick-audit.js +0 -186
  1186. package/.worktrees/e58fcc4c/src/run/scan-profile.js +0 -269
  1187. package/.worktrees/e58fcc4c/src/run/shared.js +0 -1562
  1188. package/.worktrees/e58fcc4c/src/run/stage.js +0 -587
  1189. package/.worktrees/e58fcc4c/src/run.js +0 -23
  1190. package/.worktrees/e58fcc4c/src/scan-diff.js +0 -388
  1191. package/.worktrees/e58fcc4c/src/scan-postcheck.js +0 -524
  1192. package/.worktrees/e58fcc4c/src/scan-staleness.js +0 -95
  1193. package/.worktrees/e58fcc4c/src/setup.js +0 -414
  1194. package/.worktrees/e58fcc4c/src/sillyhub-mcp/client.js +0 -597
  1195. package/.worktrees/e58fcc4c/src/sillyhub-mcp/config.js +0 -62
  1196. package/.worktrees/e58fcc4c/src/spec-dir-typo.js +0 -50
  1197. package/.worktrees/e58fcc4c/src/spec-sync.js +0 -358
  1198. package/.worktrees/e58fcc4c/src/stage-contract-engine.js +0 -171
  1199. package/.worktrees/e58fcc4c/src/stage-contract-spec.js +0 -551
  1200. package/.worktrees/e58fcc4c/src/stage-contract.js +0 -948
  1201. package/.worktrees/e58fcc4c/src/stage-review.js +0 -597
  1202. package/.worktrees/e58fcc4c/src/stages/archive.js +0 -199
  1203. package/.worktrees/e58fcc4c/src/stages/brainstorm-auto.js +0 -285
  1204. package/.worktrees/e58fcc4c/src/stages/brainstorm.js +0 -624
  1205. package/.worktrees/e58fcc4c/src/stages/cmd-existence.js +0 -145
  1206. package/.worktrees/e58fcc4c/src/stages/doctor.js +0 -540
  1207. package/.worktrees/e58fcc4c/src/stages/execute.js +0 -1277
  1208. package/.worktrees/e58fcc4c/src/stages/explore.js +0 -43
  1209. package/.worktrees/e58fcc4c/src/stages/index.js +0 -29
  1210. package/.worktrees/e58fcc4c/src/stages/knowledge.js +0 -514
  1211. package/.worktrees/e58fcc4c/src/stages/plan-postcheck.js +0 -1398
  1212. package/.worktrees/e58fcc4c/src/stages/plan.js +0 -655
  1213. package/.worktrees/e58fcc4c/src/stages/quick.js +0 -167
  1214. package/.worktrees/e58fcc4c/src/stages/scan.js +0 -608
  1215. package/.worktrees/e58fcc4c/src/stages/status.js +0 -64
  1216. package/.worktrees/e58fcc4c/src/stages/verify.js +0 -246
  1217. package/.worktrees/e58fcc4c/src/sync.js +0 -1470
  1218. package/.worktrees/e58fcc4c/src/task-review.js +0 -1498
  1219. package/.worktrees/e58fcc4c/src/taskcard-placeholders.js +0 -21
  1220. package/.worktrees/e58fcc4c/src/taskcard.js +0 -250
  1221. package/.worktrees/e58fcc4c/src/verify-postcheck.js +0 -1718
  1222. package/.worktrees/e58fcc4c/src/verify-probes.js +0 -327
  1223. package/.worktrees/e58fcc4c/src/version.js +0 -19
  1224. package/.worktrees/e58fcc4c/src/workflow.js +0 -600
  1225. package/.worktrees/e58fcc4c/src/workspace.js +0 -125
  1226. package/.worktrees/e58fcc4c/src/worktree-apply.js +0 -1611
  1227. package/.worktrees/e58fcc4c/src/worktree-deps.js +0 -668
  1228. package/.worktrees/e58fcc4c/src/worktree.js +0 -1849
  1229. package/.worktrees/e58fcc4c/templates/claude-instruction.md +0 -23
  1230. package/.worktrees/e58fcc4c/templates/prompts/taskcard-rules.md +0 -29
  1231. package/.worktrees/e58fcc4c/templates/prompts/testcase-design.md +0 -12
  1232. package/.worktrees/e58fcc4c/templates/prompts/verify-probes.md +0 -32
  1233. package/.worktrees/e58fcc4c/templates/workflows/archive-impact.yaml +0 -79
  1234. package/.worktrees/e58fcc4c/templates/workflows/scan-docs.yaml +0 -132
@@ -1,1498 +0,0 @@
1
- /**
2
- * SillySpec Task Review Gate — execute 阶段任务级评审校验
3
- *
4
- * execute 阶段每个 task 完成后,controller 必须写入 review.json。
5
- * execute --done 时 CLI 硬校验:缺失 review 或 verdict 不通过则阻断。
6
- *
7
- * 目录结构:
8
- * .sillyspec/.runtime/execute-runs/<runId>/tasks/<taskId>/review.json
9
- */
10
-
11
- import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync, statSync } from 'fs'
12
- import { join, resolve } from 'path'
13
- import { git, unquoteGitPath } from './git-helper.js'
14
- import { pathMatches } from './change-list.js'
15
- import { parseAllowedPaths, parseRepo, parseBaseCommit, parseHeadCommit } from './stages/plan-postcheck.js'
16
- import { resolveVerifyChangedFiles } from './verify-postcheck.js'
17
- import { WorktreeManager } from './worktree.js'
18
- import { resolveRuntimeRoot } from './run/shared.js'
19
-
20
- // ── review.json schema version ──
21
- //
22
- // design §7.4 / R-07:task-review 的 review.json schemaVersion 1→2(新增可选 repo 字段),
23
- // 旧 v1(无 repo)向后兼容视 'main',不阻断既有 change archive。
24
- //
25
- // 关于常量与"1→2":REVIEW_SCHEMA_VERSION 常量被 stage-review.js(文档型阶段评审)共享——
26
- // stage-review.test.mjs:358 + register.test.mjs:40 断言其值 === 1,且 stage-review.js 不在本次
27
- // 变更的 allowed_paths 内。两个 schema(task code-review / stage doc-review)逻辑独立,但历史共享
28
- // 同一常量。本期保持 REVIEW_SCHEMA_VERSION=1 作 stage-review 写侧默认值(不破坏 stage-review),
29
- // 同时用 REVIEW_SCHEMA_VERSIONS_ACCEPTED=[1,2] 表达"读侧接受两版"——validateReviewSchema 兼容 v1/v2,
30
- // 跨仓 task 写 review.json 可用 v2 带 repo 字段,单仓/旧 change 仍用 v1。后续可拆分 stage-review 专用
31
- // 常量,本期遵循 allowed_paths 约束不扩散到 stage-review.js。
32
- export const REVIEW_SCHEMA_VERSION = 1
33
- const REVIEW_SCHEMA_VERSIONS_ACCEPTED = [1, 2]
34
- // repo 缺省值(review.repo / task 卡 repo 缺省时统一按 'main' 处理)。design §7.2 / §7.4。
35
- const DEFAULT_REPO_KEY = 'main'
36
-
37
- /**
38
- * 规范化 review.repo / task 卡 repo 字段为有效 repoKey。
39
- * 缺省 / 非字符串 / 空串 → 'main'(向后兼容旧 v1 review + 无 repo 声明的单仓 task)。
40
- * @param {any} repo
41
- * @returns {string}
42
- */
43
- export function normalizeRepoKey(repo) {
44
- if (typeof repo !== 'string' || repo.trim() === '') return DEFAULT_REPO_KEY
45
- return repo.trim()
46
- }
47
-
48
- // ── 合法 verdict 枚举 ──
49
- export const VALID_VERDICTS = ['pass', 'fail', 'cannot_verify']
50
-
51
- /**
52
- * 解析 plan.md 中的 task 列表
53
- * @param {string} planContent - plan.md 文件内容
54
- * @returns {string[]} task id 列表,如 ['task-01', 'task-02']
55
- */
56
- function parseTaskIdsFromPlan(planContent) {
57
- if (!planContent) return []
58
- const ids = new Set()
59
- const re = /^\s*[-*]\s*\[[ x]\]\s*task-(\d+)/gim
60
- for (const m of planContent.matchAll(re)) {
61
- ids.add(`task-${m[1].padStart(2, '0')}`)
62
- }
63
- return [...ids].sort()
64
- }
65
-
66
- /**
67
- * 统计 plan.md/tasks.md 中 task-NN checkbox 的勾选情况(降级口径)。
68
- * 与 progress.js readPlanCheckboxStatus 同语义,但纯函数、无类依赖,供 summarizeTaskCompletion 降级复用。
69
- */
70
- function countPlanCheckboxes(planContent) {
71
- const re = /^\s*[-*]\s+\[([ xX])\]\s+task-\d+/gm
72
- let total = 0
73
- let checked = 0
74
- let m
75
- while ((m = re.exec(planContent)) !== null) {
76
- total++
77
- if (m[1] === 'x' || m[1] === 'X') checked++
78
- }
79
- return { total, checked }
80
- }
81
-
82
- /**
83
- * 汇总变更的任务完成度 —— archive Step1「任务完成度检查」的客观真相源。
84
- *
85
- * 以 execute 阶段产出的 review.json verdict 为准(task-NN 的 specVerdict + qualityVerdict 均 ≠ fail
86
- * 视为完成),而非 plan.md checkbox。原因:plan.md checkbox 依赖 autoCheckPlanFromReviews 回填,
87
- * 而 runId marker / review.json 缺失时回填静默 no-op,checkbox 会停在未勾态,导致完成度失真
88
- * (archive 误判「全未完成」)。review.json 是 task 级客观 verdict,不受回填断裂影响。
89
- *
90
- * runId 解析:优先 current-execute-run-id-<changeName> marker(最新一次 execute run);
91
- * marker 缺失则扫描 execute-runs/ 下子目录、取 mtime 最新的,尽力定位。
92
- *
93
- * fail-safe:无 plan / 无 runId / review 全缺等任何异常,降级到 plan.md checkbox 统计 + 标注 source,
94
- * 绝不抛错、绝不阻断 archive(最坏退回「数 checkbox」现状,不比修复前差)。
95
- *
96
- * @param {{ changeDir: string, runtimeRoot: string, changeName: string }} opts
97
- * @returns {{ source: string, total: number, completed: number, pending: Array<{id:string,reason:string}>, report: string }}
98
- * source: 'review.json'(客观源可用)/ 'plan-checkbox-fallback'(降级)/ 'no-plan' / 'no-tasks'
99
- * report: 人类可读报告,供 prompt {TASK_COMPLETION_REPORT} 注入
100
- */
101
- export function summarizeTaskCompletion({ changeDir, runtimeRoot, changeName }) {
102
- const noPlan = {
103
- source: 'no-plan', total: 0, completed: 0, pending: [],
104
- report: '⚠️ 未找到 plan.md/tasks.md,无法计算任务完成度。请确认变更目录完整。'
105
- }
106
- if (!changeDir) return noPlan
107
-
108
- // 2026-08-20-task-truth-unify:任务清单唯一真相在 tasks.md,优先读注册表;plan.md 回退
109
- // (旧归档变更兼容读侧——新契约 plan.md 为纯 ID 引用行,无 checkbox 可解析)
110
- const planPath = join(changeDir, 'plan.md')
111
- const tasksPath = join(changeDir, 'tasks.md')
112
- let planContent = null
113
- if (existsSync(tasksPath)) planContent = readFileSync(tasksPath, 'utf8')
114
- else if (existsSync(planPath)) planContent = readFileSync(planPath, 'utf8')
115
- else return noPlan
116
-
117
- const taskIds = parseTaskIdsFromPlan(planContent)
118
- if (taskIds.length === 0) {
119
- return { source: 'no-tasks', total: 0, completed: 0, pending: [],
120
- report: '⚠️ tasks.md 未解析出任何 task-NN 条目(任务注册表可能未按规范写 checkbox 列表)。' }
121
- }
122
-
123
- // runId 解析(坑 worktree-cleanup-marker-chain 根治):归属化解析 resolveExecuteRunForChange——
124
- // marker 优先但校验覆盖度;marker 断裂(worktree cleanup / 归档清理 / 并行误删)时按 change 戳
125
- // 精确归属,旧 run 退覆盖度启发。不再盲目 mtime 最新(曾把其他变更的 run 错配给本变更 →
126
- // 全部 task 误报「review.json 缺失」→ 手工回填 7 份实际存在于正确 run 里的 review)。
127
- const resolved = resolveExecuteRunForChange({ runtimeRoot, changeName, taskIds })
128
- const runId = resolved ? resolved.runId : null
129
- if (resolved && resolved.relocated) {
130
- console.warn(`[sillyspec] execute run 归属修正:marker 指向的 run 对变更 ${changeName} 零覆盖,改用 ${resolved.origin === 'stamp' ? 'change 戳' : '覆盖度'}命中的 run ${runId}(真实 review 所在)`)
131
- }
132
-
133
- // 无归属 run → 降级 plan.md checkbox 统计;报告区分「无法归属」与「没跑过 execute」,
134
- // 避免把定位失败误导成「review 全缺、需手工回填」
135
- if (!runId) {
136
- const { total, checked } = countPlanCheckboxes(planContent)
137
- let runsNote = '无 execute-runs 目录(本变更未跑过 execute?)'
138
- try {
139
- const runsDir = join(runtimeRoot, 'execute-runs')
140
- if (existsSync(runsDir)) {
141
- const n = readdirSync(runsDir).filter(e => { try { return statSync(join(runsDir, e)).isDirectory() } catch { return false } }).length
142
- if (n > 0) runsNote = `execute-runs/ 有 ${n} 个 run 但无一能归属到本变更(无 change 戳且零覆盖——marker 链断裂且 review 可能从未生成)`
143
- }
144
- } catch {}
145
- return {
146
- source: 'plan-checkbox-fallback', total, completed: checked,
147
- pending: taskIds.slice(0, Math.max(0, total - checked)).map(id => ({ id, reason: 'checkbox 未勾(降级口径)' })),
148
- report:
149
- '⚠️ 客观源不可用(execute run 无法归属到本变更:' + runsNote + ')→ 降级用 plan.md checkbox。\n' +
150
- `- 总任务:${total}\n- plan.md 已勾选:${checked}\n` +
151
- '⚠️ checkbox 可能因 autoCheckPlanFromReviews 回填断裂而失真,务必交叉核对 .runtime/execute-runs/*/tasks/task-NN/review.json 的 verdict 再下结论。'
152
- }
153
- }
154
-
155
- // 有 runId → 读 review.json verdict;cannot_verify 草稿单列(不是真正复核,归档前应可见)
156
- const completed = []
157
- const pending = []
158
- let cannotVerifyCount = 0
159
- for (const id of taskIds) {
160
- const reviewPath = join(runtimeRoot, 'execute-runs', runId, 'tasks', id, 'review.json')
161
- const r = readReview(reviewPath)
162
- if (r.ok && r.review && r.review.specVerdict !== 'fail' && r.review.qualityVerdict !== 'fail') {
163
- completed.push(id)
164
- if (r.review.specVerdict === 'cannot_verify' || r.review.qualityVerdict === 'cannot_verify') cannotVerifyCount++
165
- } else if (r.ok && r.review) {
166
- pending.push({ id, reason: `verdict 未通过(spec=${r.review.specVerdict}, quality=${r.review.qualityVerdict})` })
167
- } else {
168
- pending.push({ id, reason: 'review.json 缺失(task 未走完 execute 评审)' })
169
- }
170
- }
171
-
172
- const pendingLines = pending.length > 0
173
- ? pending.map(p => ` - ${p.id}: ${p.reason}`).join('\n')
174
- : ' (无)'
175
- const draftLines = cannotVerifyCount > 0
176
- ? `- cannot_verify 草稿(未真正复核): ${cannotVerifyCount}\n` +
177
- ' ⚠️ 这些 task 的 review 是 cannot_verify(含自动草稿兜底)而非 pass——归档前应确认 verify 阶段已兑现其 requiredEvidence,否则派独立子代理对照 task brief + git diff 补真实复核,勿静默放行\n'
178
- : ''
179
- return {
180
- source: 'review.json', total: taskIds.length, completed: completed.length, pending, cannotVerify: cannotVerifyCount, runId,
181
- report:
182
- `客观任务完成度(真相源 = review.json verdict,runId=${runId}${resolved.origin !== 'marker' ? `,归属=${resolved.origin}` : ''}):\n` +
183
- `- 总任务:${taskIds.length}\n` +
184
- `- 已通过(spec + quality verdict 均非 fail):${completed.length}\n` +
185
- draftLines +
186
- `- 未通过 / 缺失:${pending.length}\n` +
187
- `- 未完成列表:\n${pendingLines}\n` +
188
- '注:以 review.json verdict 为准;plan.md checkbox 仅作显示态(回填断裂时会与客观 verdict 不一致,以下方客观点为准)。'
189
- }
190
- }
191
-
192
- /**
193
- * 校验单个 review.json 文件
194
- *
195
- * schema 版本(design §7.4 / R-07):接受 v1(无 repo,单仓向后兼容)+ v2(新增可选 repo 字段,
196
- * 跨仓 task 标记 repo: <key>)。repo 缺省 / 非字符串 → 视 'main'(normalizeRepoKey),不阻断。
197
- * repo 的真实存在性(local.yaml repos 注册)由 MultiRepoContext 约束② fail-closed 兜底,schema 层
198
- * 只做"非字符串时不阻断"的宽松类型校验(review.json 是 agent 手写产物,宽松避免误杀)。
199
- *
200
- * @param {object} review - 解析后的 JSON 对象
201
- * @returns {{ ok: boolean, errors: string[] }}
202
- */
203
- export function validateReviewSchema(review) {
204
- const errors = []
205
- if (!review || typeof review !== 'object') {
206
- errors.push('review.json 不是有效 JSON 对象')
207
- return { ok: false, errors }
208
- }
209
-
210
- if (!REVIEW_SCHEMA_VERSIONS_ACCEPTED.includes(review.schemaVersion)) {
211
- errors.push(`schemaVersion 应为 ${REVIEW_SCHEMA_VERSIONS_ACCEPTED.join(' 或 ')},实际为 ${review.schemaVersion}`)
212
- }
213
-
214
- if (!review.task || typeof review.task !== 'string') {
215
- errors.push('缺少 task 字段(应为 "task-XX" 格式)')
216
- }
217
-
218
- // repo(可选,v2 新增):类型宽松校验。非字符串 / 空串 → 视 'main',不阻断 schema。
219
- // 跨仓 repo 的注册存在性由 MultiRepoContext 构造时 fail-closed 校验(约束②)。
220
- if (review.repo !== undefined && typeof review.repo !== 'string') {
221
- errors.push(`repo 字段(若提供)应为字符串,实际类型为 ${typeof review.repo}`)
222
- }
223
-
224
- if (!VALID_VERDICTS.includes(review.specVerdict)) {
225
- errors.push(`specVerdict 无效:${review.specVerdict}(应为 ${VALID_VERDICTS.join('/')})`)
226
- }
227
-
228
- if (!VALID_VERDICTS.includes(review.qualityVerdict)) {
229
- errors.push(`qualityVerdict 无效:${review.qualityVerdict}(应为 ${VALID_VERDICTS.join('/')})`)
230
- }
231
-
232
- // cannot_verify 必须提供 requiredEvidence
233
- if (review.specVerdict === 'cannot_verify' || review.qualityVerdict === 'cannot_verify') {
234
- if (!Array.isArray(review.requiredEvidence) || review.requiredEvidence.length === 0) {
235
- errors.push('cannot_verify 的 verdict 必须提供非空的 requiredEvidence 数组')
236
- }
237
- }
238
-
239
- // base/head 非空检查
240
- if (!review.base || typeof review.base !== 'string') {
241
- errors.push('缺少 base 字段(git commit hash)')
242
- }
243
- if (!review.head || typeof review.head !== 'string') {
244
- errors.push('缺少 head 字段(git commit hash)')
245
- }
246
-
247
- return { ok: errors.length === 0, errors }
248
- }
249
-
250
- /**
251
- * 增强 JSON.parse 失败的定位:从 V8 的 "at position N" 算出 line:col + 出错行上下文,
252
- * 并对常见非法转义(正则的反斜杠序列误入 JSON 字符串)给针对性修复指引。
253
- * @param {string} raw 原始文件内容
254
- * @param {string} message V8 抛出的错误消息
255
- * @returns {string} 增强后的可读消息
256
- */
257
- export function enrichJsonParseError(raw, message) {
258
- const m = /at position (\d+)/.exec(message)
259
- if (!m) return message
260
- const pos = Math.min(Number(m[1]), raw.length)
261
- let line = 1, col = 1
262
- for (let i = 0; i < pos; i++) {
263
- if (raw[i] === '\n') { line++; col = 1 } else { col++ }
264
- }
265
- const lineStart = raw.lastIndexOf('\n', pos - 1) + 1
266
- const nlAfter = raw.indexOf('\n', pos)
267
- const lineEnd = nlAfter === -1 ? raw.length : nlAfter
268
- const snippet = raw.slice(lineStart, lineEnd)
269
- const caret = ' '.repeat(Math.max(0, col - 1)) + '^'
270
- // 单行注释内的反斜杠序列是纯文本,不触发块注释终止;正则字面量在函数体内正常解析。
271
- let out = message + '\n → 第 ' + line + ' 行第 ' + col + ' 列:\n ' + snippet + '\n ' + caret
272
- // 先移除合法的成对反斜杠(JSON 中 \\ 表字面 \),否则 "\\z" 会被逐字符正则误判为 "\z" 非法转义
273
- const hasBadEscape = message.includes('Bad escaped character') || /\\[^"\\/bfnrtu]/.test(snippet.replace(/\\\\/g, ''))
274
- if (hasBadEscape) {
275
- out += '\n → 疑似正则转义(如 \\s \\d \\w)混入 JSON 字符串。修复:双写反斜杠(\\\\s),或用 JSON.stringify(obj) 重写 review.json。'
276
- }
277
- return out
278
- }
279
-
280
- /**
281
- * 读取单个 task 的 review.json
282
- * @param {string} reviewPath - review.json 文件路径
283
- * @returns {{ ok: boolean, review: object|null, errors: string[] }}
284
- */
285
- export function readReview(reviewPath) {
286
- if (!existsSync(reviewPath)) {
287
- return { ok: false, review: null, errors: ['review.json 不存在'] }
288
- }
289
-
290
- let raw
291
- try {
292
- raw = readFileSync(reviewPath, 'utf8')
293
- } catch (e) {
294
- return { ok: false, review: null, parseError: true, errors: [`review.json 读取失败: ${e.message}`] }
295
- }
296
-
297
- let parsed
298
- try {
299
- parsed = JSON.parse(raw)
300
- } catch (e) {
301
- // 文件存在但 JSON 非法:review 设为 null 但标记 parseError=true,错误消息带行列定位 + 转义修复指引
302
- return { ok: false, review: null, parseError: true, errors: [`review.json 解析失败: ${enrichJsonParseError(raw, e.message)}`] }
303
- }
304
-
305
- const schemaResult = validateReviewSchema(parsed)
306
- if (!schemaResult.ok) {
307
- return { ok: false, review: parsed, schemaError: true, errors: schemaResult.errors }
308
- }
309
-
310
- return { ok: true, review: parsed, errors: [] }
311
- }
312
-
313
- /**
314
- * 校验 plan.md 里所有「已勾选 [x]」task 的 review.json 是否 schema 完整(坑 review-json-field-gap)。
315
- *
316
- * Task Review Gate(validateTaskReviews)只在 execute 整阶段完成时跑,单 task --done 不校验 →
317
- * 子代理勾了 checkbox 却漏写/漏字段 review.json,要到收尾才暴露,用户被迫事后批量补。本函数供
318
- * enforceReviewJsonGate 在每次 execute --done 调用:已勾 [x] = 声称完成 = 必有完整 review.json;
319
- * 未勾 task 不校验(还没做)。readReview 已区分 missing/parseError/schemaError,这里只聚合。
320
- *
321
- * @param {{ planContent: string, runtimeRoot: string, executeRunId: string }} opts
322
- * @returns {{ ok: boolean, failures: Array<{ taskId:string, reviewPath:string, kind:string, errors:string[] }> }}
323
- * kind ∈ missing(review.json 不存在)/ parseError(JSON 坏)/ schemaError(字段缺)
324
- */
325
- export function validateCheckedTaskReviews({ planContent, runtimeRoot, executeRunId }) {
326
- const failures = []
327
- const re = /^\s*[-*]\s*\[x\]\s*task-(\d+)/gim
328
- let m
329
- while ((m = re.exec(planContent)) !== null) {
330
- const taskId = `task-${m[1].padStart(2, '0')}`
331
- const reviewPath = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks', taskId, 'review.json')
332
- const r = readReview(reviewPath)
333
- if (!r.ok) {
334
- const kind = r.parseError ? 'parseError' : (r.schemaError ? 'schemaError' : 'missing')
335
- failures.push({ taskId, reviewPath, kind, errors: r.errors })
336
- }
337
- }
338
- return { ok: failures.length === 0, failures }
339
- }
340
-
341
- /**
342
- * execute --done 时的 task review 总校验
343
- *
344
- * 规则:
345
- * - 每个 plan task 必须有 review.json
346
- * - specVerdict 或 qualityVerdict 为 fail → 整体 fail
347
- * - specVerdict 或 qualityVerdict 为 cannot_verify → warning(requiredEvidence 非空)
348
- * - cannot_verify + requiredEvidence 为空 → fail(agent 逃避判断)
349
- * - cannot_verify 的 requiredEvidence 汇总到 requiredEvidence 字段,供 verify 阶段消费
350
- *
351
- * @param {object} opts
352
- * @param {string} opts.planContent - plan.md 内容
353
- * @param {string} opts.runtimeRoot - .sillyspec/.runtime 的绝对路径
354
- * @param {string} opts.executeRunId - execute run id(如 'exec-2026-06-23-131400')
355
- * @param {boolean} [opts.allowCannotVerify=true] - 是否允许 cannot_verify(默认允许,给 warning)
356
- * @param {string} [opts.changeDir] - change 目录(读 task-NN.md frontmatter 判 low_risk)
357
- * @param {string} [opts.gitDir] - 主仓 git 工作目录(单仓 review 真实性校验 cwd;无 ctx 时用此)
358
- * @param {object} [opts.ctx] - MultiRepoContext 实例(D-013:缺省/null → 走 opts.gitDir 单仓零回归;
359
- * 有 ctx 时按 review.repo(缺省 'main')从 ctx.resolve(repo).gitDir 取每条 review 的校验 cwd,
360
- * 跨仓 gitDir=跨仓仓根,使 base..head diff 在正确仓跑——design §6 task-review A1 行)
361
- * @returns {{ ok: boolean, errors: string[], warnings: string[], requiredEvidence: Array<{task: string, verdict: string, evidence: string[]}> }}
362
- */
363
- /**
364
- * 读取 task-XX.md frontmatter,判断是否声明 low_risk: true(type-only/机械迁移等低逻辑风险)。
365
- * 声明 low_risk 的 task 缺 review.json 时只 warning 不 error(B2:免逐个评审仪式)。
366
- */
367
- function isTaskLowRisk(changeDir, taskId) {
368
- if (!changeDir) return false
369
- const taskFile = join(changeDir, 'tasks', `${taskId}.md`)
370
- if (!existsSync(taskFile)) return false
371
- try {
372
- const content = readFileSync(taskFile, 'utf8')
373
- const fm = content.match(/^---\n([\s\S]*?)\n---/)
374
- if (!fm) return false
375
- return /^low_risk:\s*true\s*$/im.test(fm[1])
376
- } catch {
377
- return false
378
- }
379
- }
380
-
381
- /**
382
- * 纯验证 task 判定(坑 verification-task-zero-diff,2026-08-21 实证):task-10/11 类
383
- * 「跑测试/部署验证/观测确认」型任务无代码 diff 是本质属性而非伪造——emptyDiff 判伪造
384
- * 对它们必误杀,此前只能引用验证区间并手工披露归属绕过。task 卡 frontmatter 显式声明
385
- * `task_type: verification`(或 `verification_only: true`)即走合法零 diff 通道:
386
- * emptyDiff 不判伪造(转 warning),但 review 必须带非空 requiredEvidence(披露验证
387
- * 区间/结论出处)——不能拿声明逃掉披露义务。
388
- * @returns {boolean}
389
- */
390
- function isTaskVerification(changeDir, taskId) {
391
- if (!changeDir) return false
392
- const taskFile = join(changeDir, 'tasks', `${taskId}.md`)
393
- if (!existsSync(taskFile)) return false
394
- try {
395
- const content = readFileSync(taskFile, 'utf8')
396
- const fm = content.match(/^---\r?\n([\s\S]*?)\r?\n---/)
397
- if (!fm) return false
398
- return /^task_type:\s*['"]?verification['"]?\s*$/im.test(fm[1])
399
- || /^verification_only:\s*true\s*$/im.test(fm[1])
400
- } catch {
401
- return false
402
- }
403
- }
404
-
405
- export function validateTaskReviews(opts) {
406
- const { planContent, runtimeRoot, executeRunId, allowCannotVerify = true, changeDir = null, gitDir = null, ctx = null } = opts
407
-
408
- const taskIds = parseTaskIdsFromPlan(planContent)
409
-
410
- // 如果 plan 里没有 task,跳过校验(向后兼容)
411
- if (taskIds.length === 0) {
412
- return { ok: true, errors: [], warnings: [], requiredEvidence: [] }
413
- }
414
-
415
- const errors = []
416
- const warnings = []
417
- const requiredEvidence = []
418
- // PERF-01:整个循环共享一份 git 结果缓存(同 gitDir 的探测/status、同 (base,head) 的
419
- // diff 在多 task 间高度重复;N task 从 5N 个 git 子进程降到 ~2+去重后数量)
420
- const evidenceCache = {}
421
-
422
- for (const taskId of taskIds) {
423
- const reviewDir = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks', taskId)
424
- const reviewPath = join(reviewDir, 'review.json')
425
-
426
- const result = readReview(reviewPath)
427
-
428
- if (!result.ok) {
429
- if (result.parseError) {
430
- // review.json 存在但 JSON 非法
431
- errors.push(`${taskId}: review.json 解析失败 — ${result.errors.join('; ')}`)
432
- } else if (result.schemaError) {
433
- // review.json 存在且 JSON 合法,但 schema 校验失败
434
- errors.push(`${taskId}: review.json 校验失败 — ${result.errors.join('; ')}`)
435
- } else {
436
- // review.json 不存在:声明 low_risk 的 task 豁免(B2:type-only/机械迁移免逐个评审)
437
- if (isTaskLowRisk(changeDir, taskId)) {
438
- warnings.push(`${taskId}: 缺少 review.json — task 声明 low_risk: true,已豁免评审(type-only/机械迁移)`)
439
- } else {
440
- errors.push(`${taskId}: 缺少 review.json — task 未经过评审(期望路径:${reviewPath},execute run ID: ${executeRunId})`)
441
- }
442
- }
443
- continue
444
- }
445
-
446
- const review = result.review
447
-
448
- // 检查 review.task 是否与 plan 中的 taskId 一致
449
- if (review.task && review.task !== taskId) {
450
- errors.push(`${taskId}: review.json 中的 task 字段为 "${review.task}",与 plan 不一致(应为 "${taskId}")— agent 可能复制模板未修改`)
451
- continue
452
- }
453
-
454
- // 检查 fail verdict
455
- if (review.specVerdict === 'fail' || review.qualityVerdict === 'fail') {
456
- errors.push(`${taskId}: review 未通过 — spec: ${review.specVerdict}, quality: ${review.qualityVerdict}`)
457
- if (review.reviewerNotes) {
458
- errors.push(`${taskId}: ${review.reviewerNotes}`)
459
- }
460
- continue
461
- }
462
-
463
- // ── git 真实性交叉校验:base/head 必须是真实 commit,diff 不能为空 ──
464
- // D-013 + design §6 A1:有 ctx 时按 review.repo(缺省 'main')切 gitDir——跨仓 review 的
465
- // base/head 是跨仓仓 commit,必须在跨仓仓根跑 rev-parse/diff,否则判伪造误杀。无 ctx 时退回
466
- // opts.gitDir(单仓零回归)。reviewGitDir 为 null 则跳过证据校验(与原逻辑一致)。
467
- let reviewGitDir = gitDir
468
- if (ctx) {
469
- const repoKey = normalizeRepoKey(review.repo)
470
- const entry = ctx.resolve(repoKey)
471
- if (entry && entry.gitDir) {
472
- reviewGitDir = entry.gitDir
473
- } else if (repoKey !== 'main') {
474
- // 跨仓 repo 在 ctx 中未注册 → 不应发生(MultiRepoContext 构造已 fail-closed 拦截未注册),
475
- // 防御性降级为 warning 提示,不阻断(review.json schema 已过,仓库解析交给 ctx 上游负责)。
476
- // 坑7 教训:此分支发生时后续主仓校验必报「疑似伪造」,文案须直接指向真实排查方向。
477
- warnings.push(`${taskId}: review.repo="${repoKey}" 在 MultiRepoContext 未解析到 entry,退回主仓 gitDir 校验——下方若报 commit 不真实/疑似伪造,先查 repo 声明(plan.md 内联块或 tasks/task-NN.md 的 repo:)与 local.yaml repos: 注册,非 review 伪造`)
478
- }
479
- }
480
- if (reviewGitDir) {
481
- const evidence = verifyReviewGitEvidence(review, reviewGitDir, evidenceCache)
482
- for (const w of evidence.warnings) warnings.push(`${taskId}: ${w}`)
483
- if (!evidence.ok) {
484
- for (const err of evidence.errors) errors.push(`${taskId}: ${err}`)
485
- continue
486
- }
487
- if (evidence.emptyDiff) {
488
- if (isTaskLowRisk(changeDir, taskId)) {
489
- warnings.push(`${taskId}: base..head 无代码变更(task 声明 low_risk: true,不阻断)`)
490
- } else if (isTaskVerification(changeDir, taskId)) {
491
- // 纯验证 task 零 diff 通道(坑 verification-task-zero-diff):声明 task_type: verification
492
- // 的「跑测试/部署验证/观测」型任务无代码 diff 是本质属性——不判伪造,但披露义务不豁免:
493
- // requiredEvidence 为空 → error(声明不能替代证据)
494
- if (Array.isArray(review.requiredEvidence) && review.requiredEvidence.length > 0) {
495
- warnings.push(`${taskId}: base..head 无代码变更 — task 声明 task_type: verification(纯验证任务),零 diff 合法;requiredEvidence 已披露验证区间/结论出处`)
496
- } else {
497
- errors.push(`${taskId}: 纯验证 task(task_type: verification)零 diff 合法,但 review 缺 requiredEvidence(须披露验证区间/命令/结论出处)——声明不能替代披露`)
498
- }
499
- } else {
500
- errors.push(`${taskId}: base..head(${review.base.slice(0, 8)}..${review.head.slice(0, 8)})无任何代码变更 — 评审了一个零改动的任务,review 疑似伪造`)
501
- continue
502
- }
503
- }
504
- }
505
-
506
- // 检查 cannot_verify
507
- if (review.specVerdict === 'cannot_verify' || review.qualityVerdict === 'cannot_verify') {
508
- if (!allowCannotVerify) {
509
- errors.push(`${taskId}: cannot_verify 不被允许 — 必须提供评审结果`)
510
- continue
511
- }
512
-
513
- if (review.requiredEvidence && review.requiredEvidence.length > 0) {
514
- const verdicts = []
515
- if (review.specVerdict === 'cannot_verify') verdicts.push('spec')
516
- if (review.qualityVerdict === 'cannot_verify') verdicts.push('quality')
517
- warnings.push(`${taskId}: ${verdicts.join('+')}=cannot_verify,requiredEvidence 必须在 verify 阶段满足`)
518
- requiredEvidence.push({
519
- task: taskId,
520
- verdict: verdicts.join('+'),
521
- evidence: review.requiredEvidence,
522
- })
523
- } else {
524
- // cannot_verify + 空 requiredEvidence = agent 逃避判断
525
- errors.push(`${taskId}: cannot_verify 但 requiredEvidence 为空 — 这是无效评审`)
526
- }
527
- }
528
- }
529
-
530
- // 额外检查:扫描 execute-runs/<runId>/tasks/ 下是否有 plan 里没有的 task review
531
- // (agent 可能写错了 task id)
532
- try {
533
- const tasksDir = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks')
534
- if (existsSync(tasksDir)) {
535
- const taskDirs = readdirSync(tasksDir, { withFileTypes: true })
536
- .filter(e => e.isDirectory())
537
- .map(e => e.name)
538
- const taskIdSet = new Set(taskIds)
539
- for (const dirName of taskDirs) {
540
- if (!taskIdSet.has(dirName) && existsSync(join(tasksDir, dirName, 'review.json'))) {
541
- warnings.push(`${dirName}: 存在 review.json 但不在 plan.md 的 task 列表中(可能是多余文件)`)
542
- }
543
- }
544
- }
545
- } catch (e) {
546
- warnings.push(`task review extra-check 异常: ${e.message}`)
547
- }
548
-
549
- return {
550
- ok: errors.length === 0,
551
- errors,
552
- warnings,
553
- requiredEvidence,
554
- }
555
- }
556
-
557
- // ── Git 真实性交叉校验 ──
558
-
559
- // QUAL-01 收口:原为本地 execFileSync('git')(无 safe.directory、与 git-helper 口径分裂),
560
- // 现走统一入口;抛错/trim 语义不变,timeout 15000 保留(rev-parse/diff 大仓余量)
561
- function runGit(gitDir, args, opts = {}) {
562
- return git(gitDir, args, { timeout: 15000, ...opts })
563
- }
564
-
565
- // porcelain 状态行 → 变更文件路径(对齐 shared.js:343 parsePorcelainPath:`XY path`、引号包裹、
566
- // rename `R old -> new` 取箭头后)。未 commit 的 working-tree 改动对账用。
567
- // ⚠️ 入参必须是【未 trim】的原始输出(git(..., {trim:false}))——porcelain 行首空格是状态码
568
- // 一部分,git() 默认 trim 会把 ' M feature.js' 削成 'M feature.js',slice(3) 再咬掉路径首字符
569
- // (实测 'eature.js')→ 未提交文件对账全错位(verifyReviewGitEvidence 相交比对误判「完全不相交」)。
570
- function parsePorcelainFiles(statusOut) {
571
- const files = []
572
- for (const line of String(statusOut).split('\n')) {
573
- if (line.trim() === '') continue
574
- let p = line.slice(3).trim()
575
- if (p.length >= 2 && p.startsWith('"') && p.endsWith('"')) p = unquoteGitPath(p.slice(1, -1))
576
- const arrow = p.indexOf(' -> ')
577
- if (arrow !== -1) p = p.slice(arrow + 4)
578
- if (p) files.push(p.replace(/\\/g, '/'))
579
- }
580
- return files
581
- }
582
-
583
- /**
584
- * 校验 review.json 的 base/head 是否指向真实 git 提交,且 diff 非空。
585
- *
586
- * 历史漏洞:base/head 只做非空字符串检查,agent 可以填任意假 hash 批量伪造
587
- * review.json 通过 Task Review Gate。此函数用 git 做客观交叉校验:
588
- * 1. base/head 必须是仓库中可解析的真实 commit
589
- * 2. base..head 的 diff 不能为空(评审一个零改动的"任务"无意义)
590
- * 3. review.changedFiles(如提供)必须与实际 diff 文件有交集
591
- *
592
- * git 环境不可用(非 git 仓库 / git 缺失)时返回 unavailable,由调用方降级为
593
- * warning——不因环境问题误杀,但记录在输出中。
594
- *
595
- /**
596
- * @param {object} review - 已通过 schema 校验的 review 对象
597
- * @param {string} gitDir - 执行 git 命令的目录(worktree 优先,回退主仓库)
598
- * @param {object} [cache] - 进程内单次校验批的共享缓存(体检 PERF-01:N task × 5 个 git
599
- * 子进程去重——gitDir 探测与 status --porcelain 结果按 gitDir 恒同,commit 校验按
600
- * (gitDir,hash)、diff 按 (gitDir,base,head) 在多 task 间高度重复。validateTaskReviews
601
- * 整个循环传同一份;不传则退化为逐次执行(单测/独立调用零回归)。缓存生命周期 =
602
- * 一次校验批:working-tree status 是快照语义,跨批复用会读到陈旧状态。
603
- * @returns {{ ok: boolean, emptyDiff: boolean, errors: string[], warnings: string[], unavailable: boolean }}
604
- */
605
- export function verifyReviewGitEvidence(review, gitDir, cache = null) {
606
- const errors = []
607
- const warnings = []
608
- const c = cache || (cache = {})
609
- c.gitOk = c.gitOk || new Map()
610
- c.verified = c.verified || new Set()
611
- c.diffs = c.diffs || new Map()
612
- c.wtStatus = c.wtStatus || new Map()
613
-
614
- // git 环境探测:失败即 unavailable,交由调用方降级(同 gitDir 结果恒同,批内缓存)
615
- if (!c.gitOk.has(gitDir)) {
616
- try {
617
- runGit(gitDir, ['rev-parse', '--git-dir'])
618
- c.gitOk.set(gitDir, true)
619
- } catch (e) {
620
- c.gitOk.set(gitDir, false)
621
- return {
622
- ok: true,
623
- emptyDiff: false,
624
- errors: [],
625
- warnings: [`git 环境不可用(${gitDir}),跳过 review 真实性交叉校验: ${e.message?.split('\n')[0] || e.message}`],
626
- unavailable: true,
627
- }
628
- }
629
- } else if (c.gitOk.get(gitDir) === false) {
630
- return {
631
- ok: true,
632
- emptyDiff: false,
633
- errors: [],
634
- warnings: [`git 环境不可用(${gitDir}),跳过 review 真实性交叉校验(批内缓存判定)`],
635
- unavailable: true,
636
- }
637
- }
638
-
639
- for (const field of ['base', 'head']) {
640
- const hash = review[field]
641
- const vkey = `${gitDir}\u0000${hash}`
642
- if (c.verified.has(vkey)) continue
643
- try {
644
- runGit(gitDir, ['rev-parse', '--verify', '--quiet', `${hash}^{commit}`])
645
- c.verified.add(vkey)
646
- } catch {
647
- // 可执行指引(坑 review-head-real-commit-late,2026-08-22 实证:head 必须真实 commit 的
648
- // 要求撞门才知道——报错直接给操作序列:worktree 改动先 commit,取 HEAD 作 head)
649
- errors.push(`${field} "${hash}" 不是仓库中的真实 commit — review.json 疑似伪造。` +
650
- `head/base 必须是 git rev-parse 可解析的 commit hash:worktree 内先 git add -A && git commit -m "<task>",` +
651
- `再取 git rev-parse HEAD 作 head(base 用 task 卡锡点或基线 commit);不要填分支名/伪 hash/working-tree 描述`)
652
- }
653
- }
654
- if (errors.length > 0) {
655
- return { ok: false, emptyDiff: false, errors, warnings, unavailable: false }
656
- }
657
-
658
- let diffFiles = []
659
- const dkey = `${gitDir}\u0000${review.base}\u0000${review.head}`
660
- if (c.diffs.has(dkey)) {
661
- diffFiles = c.diffs.get(dkey)
662
- } else {
663
- try {
664
- const out = runGit(gitDir, ['diff', '--name-only', `${review.base}..${review.head}`])
665
- diffFiles = out ? out.split('\n').filter(Boolean) : []
666
- c.diffs.set(dkey, diffFiles)
667
- } catch (e) {
668
- warnings.push(`git diff ${review.base}..${review.head} 执行失败,跳过 diff 校验: ${e.message?.split('\n')[0] || e.message}`)
669
- return { ok: true, emptyDiff: false, errors, warnings, unavailable: false }
670
- }
671
- }
672
-
673
- // 并入 working-tree 未提交改动(execute 复盘 a):子代理默认不 commit,base..head 无 commit diff 时
674
- // diffFiles 留空 → 下方交叉比对拿空集对非空 changedFiles 必判「完全不相交」伪造,逼 agent 强制 commit
675
- // + 改 7 个 review head。对齐 checkExecuteCodeEvidence(stage-contract.js 同时查 working-tree)语义,
676
- // 未提交改动也算有效对账源。working-tree 有改动时无条件并入(覆盖「部分 commit + 未提交」)。
677
- // PERF-01:同 gitDir 的 status 快照按批缓存(单次校验批内恒同,跨批复用会读到陈旧状态)
678
- const commitDiffFiles = diffFiles.slice()
679
- try {
680
- let wtStatus = c.wtStatus.get(gitDir)
681
- if (wtStatus === undefined) {
682
- wtStatus = runGit(gitDir, ['status', '--porcelain', '--untracked-files=all'], { trim: false })
683
- c.wtStatus.set(gitDir, wtStatus)
684
- }
685
- if (wtStatus && wtStatus.trim().length > 0) {
686
- const wtFiles = parsePorcelainFiles(wtStatus)
687
- if (wtFiles.length > 0) diffFiles = diffFiles.concat(wtFiles)
688
- if (commitDiffFiles.length === 0) {
689
- warnings.push(`base..head 无 commit diff(${review.base.slice(0, 8)}..${review.head.slice(0, 8)}),交叉对账并入 working-tree 未提交改动 ${wtFiles.length} 个文件 —— 按有效改动处理,不判零改动伪造`)
690
- }
691
- }
692
- } catch {}
693
- diffFiles = [...new Set(diffFiles)].filter(Boolean)
694
-
695
- const emptyDiff = diffFiles.length === 0
696
-
697
- // changedFiles 交叉比对:完全不相交 = review 描述的改动与实际 diff 无关(diffFiles 已含 working-tree)
698
- if (!emptyDiff && Array.isArray(review.changedFiles) && review.changedFiles.length > 0) {
699
- // 注记剥离(坑 changedfiles-annotation-suffix-mismatch,2026-08-22 实证:changedFiles 带
700
- // 「src/a.js(新增)」类注记后缀被判完全不相交,agent 用正则修还贪婪吞了路径段两轮才对)。
701
- // 结构化剥法:只剥「路径尾部」的注记形态——全角/半角括号注记、// 与 # 行内注释、空白后的
702
- // 说明文字;注记本身不参与匹配(想写说明放 reviewerNotes/requiredEvidence)。
703
- const normalize = (p) => String(p)
704
- .replace(/^\.\//, '')
705
- .replace(/[((][^(())]*[))]\s*$/, '') // 尾部(注记)/(note)——中段括号(路径段)不动
706
- .replace(/\s+(\/\/|#).*$/, '') // 空格后的 // 或 # 注释
707
- .trim()
708
- const diffSet = new Set(diffFiles.map(normalize))
709
- const hasOverlap = review.changedFiles.some(f => {
710
- const nf = normalize(f)
711
- if (!nf) return false
712
- // 兼容 review 写相对/部分路径:前后缀匹配即可
713
- return diffSet.has(nf) || diffFiles.some(d => d.endsWith(nf) || nf.endsWith(d))
714
- })
715
- if (!hasOverlap) {
716
- errors.push(`changedFiles 与实际 git diff(${review.base.slice(0, 8)}..${review.head.slice(0, 8)},${diffFiles.length} 个文件)完全不相交 — review 内容与代码变更无关。` +
717
- `检查:changedFiles 必须是纯文件路径(注记/说明写 reviewerNotes,不拼进路径数组);路径拼写与 diff 对照`)
718
- }
719
- }
720
-
721
- return { ok: errors.length === 0, emptyDiff, errors, warnings, unavailable: false }
722
- }
723
-
724
- /**
725
- * 将 cannot_verify 的 requiredEvidence 写入 change 目录
726
- * 供 verify 阶段消费
727
- *
728
- * @param {string} changeDir - 变更目录(.sillyspec/changes/<name>)
729
- * @param {Array<{task: string, verdict: string, evidence: string[]}>} requiredEvidence
730
- * @returns {string|null} 写入的文件路径,null 表示无需写入
731
- */
732
- export function writeVerifyRequiredEvidence(changeDir, requiredEvidence) {
733
- if (!requiredEvidence || requiredEvidence.length === 0) return null
734
-
735
- const filePath = join(changeDir, 'verify-required-evidence.json')
736
- const data = {
737
- generatedAt: new Date().toISOString(),
738
- schemaVersion: 1,
739
- items: requiredEvidence,
740
- }
741
-
742
- mkdirSync(changeDir, { recursive: true })
743
- writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n')
744
-
745
- return filePath
746
- }
747
-
748
- /**
749
- * 生成 execute run id
750
- * @returns {string} 如 'exec-2026-06-23-131400'
751
- */
752
- export function generateExecuteRunId() {
753
- const now = new Date()
754
- const pad = (n) => String(n).padStart(2, '0')
755
- return `exec-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
756
- }
757
-
758
- /**
759
- * execute run id 格式校验:exec-YYYY-MM-DD-HHMMSS。
760
- * marker 文件是 agent 可写内容,读回后既注入 prompt({EXECUTE_RUN_ID})又拼进
761
- * join(runtimeRoot, 'execute-runs', runId) 路径——格式校验同时防提示词注入与路径穿越
762
- * (对齐 stage-review marker 的 review- 前缀校验范式)。
763
- * @param {string} runId
764
- * @returns {boolean}
765
- */
766
- export function isValidExecuteRunId(runId) {
767
- return typeof runId === 'string' && /^exec-\d{4}-\d{2}-\d{2}-\d{6}$/.test(runId)
768
- }
769
-
770
- /**
771
- * 解析最新 execute run id:优先 current-execute-run-id-<changeName> marker;
772
- * marker 缺失/为空则扫描 execute-runs/ 下子目录、取 mtime 最新的(尽力定位已有 run)。
773
- *
774
- * 与 getLatestStageReviewRunId 的目录扫描兜底同语义——避免 marker 丢失(cleanup/并行/手删)
775
- * 而 agent 已用旧 runId 落了 execute-runs/<旧ID>/ 时,调用方直接 generate 新 ID 找不到旧 review、
776
- * 误判缺 review.json(gates.js execute 完成门坑)。返回 null 表示既无 marker 也无既有 run 目录。
777
- *
778
- * @param {{ runtimeRoot: string, changeName: string }} opts
779
- * @returns {string|null} runId(exec- 前缀),无则 null
780
- */
781
- /**
782
- * 扫描 execute-runs/,返回 mtime 最新且真正含 tasks/ 子目录的 runId。
783
- *
784
- * 专治 execute run marker 漂移(prompt-control-debt.md gate-atom-a):generateExecuteRunId 只写
785
- * marker 字符串、run 目录由 ensureTaskReviewDir 在写 review.json 时才建,marker 漂到「尚未建目录 /
786
- * 未写任何 task review」的新 run 后,旧 run 里齐备的 review.json 全部失联。resolveLatestExecuteRunId
787
- * 见 marker 非空即原样返回(不校验目录),接不住这种漂移;本函数无视 marker、只看真实目录内容,
788
- * 供 enforceReviewJsonGate 在 marker 指向的 run 缺 tasks/ 时兜底重定位,避免误报「review.json 不存在」。
789
- * 全部 run 都无 tasks/(真没写 review)返回 null——调用方维持原阻断,不误放行。
790
- *
791
- * @param {{ runtimeRoot: string }} opts
792
- * @returns {string|null} 含 tasks/ 的最新 runId,无则 null
793
- */
794
- export function resolveLatestExecuteRunIdWithTasks({ runtimeRoot, changeName = null }) {
795
- try {
796
- const runsDir = join(runtimeRoot, 'execute-runs')
797
- if (!existsSync(runsDir)) return null
798
- const entries = readdirSync(runsDir)
799
- .map(e => ({ e, p: join(runsDir, e) }))
800
- .filter(x => { try { return statSync(x.p).isDirectory() } catch { return false } })
801
- .filter(x => { try { return statSync(join(x.p, 'tasks')).isDirectory() } catch { return false } })
802
- .map(x => ({ e: x.e, mtime: statSync(x.p).mtimeMs }))
803
- .sort((a, b) => b.mtime - a.mtime)
804
- if (entries.length === 0) return null
805
- // changeName 给定时优先 change 戳等值的 run(坑 worktree-cleanup-marker-chain:mtime 最新
806
- // 会错拿其他变更的 run);无戳命中退回 mtime 最新(向后兼容,调用方多为 marker 漂移兜底,
807
- // 宁可拿最新 run 也不空手而归——覆盖度由调用方 validateTaskReviews 复校验)
808
- if (changeName) {
809
- for (const x of entries) {
810
- try {
811
- const c = readFileSync(join(runsDir, x.e, 'change'), 'utf8').trim()
812
- if (c === changeName) return x.e
813
- } catch {}
814
- }
815
- }
816
- return entries[0].e
817
- } catch {
818
- return null
819
- }
820
- }
821
-
822
- export function resolveLatestExecuteRunId({ runtimeRoot, changeName }) {
823
- const marker = join(runtimeRoot, `current-execute-run-id-${changeName}`)
824
- try {
825
- if (existsSync(marker)) {
826
- const c = readFileSync(marker, 'utf8').trim()
827
- if (c && !isValidExecuteRunId(c)) console.warn(`[sillyspec] execute run marker 内容非法(期望 exec-YYYY-MM-DD-HHMMSS,实得 ${JSON.stringify(c.slice(0, 60))}),忽略并回退目录扫描`)
828
- if (isValidExecuteRunId(c)) return c
829
- }
830
- } catch {}
831
- // marker 缺失(worktree cleanup / 归档清理 / 并行会话误删——坑 worktree-cleanup-marker-chain)
832
- // 时不再盲目取 mtime 最新(会拿到其他变更的 run):先按 change 归属戳过滤,命中才返回;
833
- // 无戳(旧 run)退回 mtime 最新保持向后兼容。
834
- try {
835
- const candidates = listExecuteRunCandidates(runtimeRoot, changeName)
836
- if (candidates.stamped.length > 0) return candidates.stamped[0]
837
- if (candidates.all.length > 0) return candidates.all[0]
838
- } catch {}
839
- return null
840
- }
841
-
842
- // ── execute run 的 change 归属戳(坑 worktree-cleanup-marker-chain 根治)──
843
- //
844
- // 背景:run 目录 execute-runs/<runId>/ 本身不带变更身份,change→run 的唯一链接是
845
- // current-execute-run-id-<change> marker;worktree cleanup / 归档 marker 清理 / 并行会话
846
- // 误删后链即断,各 fallback(mtime 最新)会错拿其他变更的 run → archive 完成度报告把
847
- // 已实现 task 全报「review.json 缺失」,只能手工回填。
848
- // 修法:marker 写入点同步在 run 目录落 `change` 戳;marker 断裂后按戳精确归属,
849
- // 旧 run(无戳)退回覆盖度启发式(run 的 tasks/ 含本变更 task-NN review 才算命中)。
850
-
851
- /**
852
- * 在 run 目录写入 change 归属戳(execute-runs/<runId>/change,内容为 changeName)。
853
- * 与 marker 写入点同步调用(stage.js 主点 + gates.js/task-review.js 补写点)。
854
- * best-effort:失败仅 warn 不抛(戳是归属优化的载体,缺了退回覆盖度启发式,不阻断主流程)。
855
- * @param {string} runtimeRoot
856
- * @param {string} runId
857
- * @param {string} changeName
858
- */
859
- export function stampExecuteRunChange(runtimeRoot, runId, changeName) {
860
- if (!runtimeRoot || !runId || !changeName) return
861
- try {
862
- // run 目录可能尚未创建(本 helper 先于 review 落盘调用的路径)——mkdir 保证自洽
863
- mkdirSync(join(runtimeRoot, 'execute-runs', runId), { recursive: true })
864
- writeFileSync(join(runtimeRoot, 'execute-runs', runId, 'change'), changeName + '\n')
865
- } catch (e) {
866
- console.warn(`[sillyspec] execute run change 戳写入失败(归属 fallback 退回覆盖度启发式,不阻断): ${e.message}`)
867
- }
868
- }
869
-
870
- /**
871
- * 读 run 目录的 change 归属戳。
872
- * @returns {string|null} 戳内容(trim 后非空),无戳/读失败返回 null
873
- */
874
- function readExecuteRunChangeStamp(runtimeRoot, runId) {
875
- try {
876
- const c = readFileSync(join(runtimeRoot, 'execute-runs', runId, 'change'), 'utf8').trim()
877
- return c || null
878
- } catch { return null }
879
- }
880
-
881
- /**
882
- * 扫描 execute-runs/ 候选 run(mtime 最新优先),按 change 归属戳分组。
883
- * @returns {{ stamped: string[], all: string[] }} stamped=戳等 changeName 的 runId(新→旧);
884
- * all=全部 runId(新→旧,含无戳旧 run,供覆盖度启发式与向后兼容 fallback)
885
- */
886
- function listExecuteRunCandidates(runtimeRoot, changeName) {
887
- const runsDir = join(runtimeRoot, 'execute-runs')
888
- const out = { stamped: [], all: [] }
889
- if (!existsSync(runsDir)) return out
890
- const entries = readdirSync(runsDir)
891
- .map(e => ({ e, p: join(runsDir, e) }))
892
- .filter(x => { try { return statSync(x.p).isDirectory() } catch { return false } })
893
- .map(x => ({ e: x.e, mtime: statSync(x.p).mtimeMs }))
894
- .sort((a, b) => b.mtime - a.mtime)
895
- for (const x of entries) {
896
- out.all.push(x.e)
897
- if (changeName && readExecuteRunChangeStamp(runtimeRoot, x.e) === changeName) out.stamped.push(x.e)
898
- }
899
- return out
900
- }
901
-
902
- /**
903
- * 判定 run 对本变更 taskIds 的覆盖度:tasks/ 下存在多少个 task-NN/review.json ∈ taskIds。
904
- * taskIds 为空时退化为「tasks/ 下存在任意 task-NN/review.json」(保守启发)。
905
- * @returns {number} 命中的 review 数
906
- */
907
- function executeRunCoverage(runtimeRoot, runId, taskIds) {
908
- try {
909
- const tasksDir = join(runtimeRoot, 'execute-runs', runId, 'tasks')
910
- if (!existsSync(tasksDir)) return 0
911
- const entries = readdirSync(tasksDir).filter(e => /^task-\d+$/.test(e))
912
- if (taskIds.length > 0) return entries.filter(e => taskIds.includes(e) && existsSync(join(tasksDir, e, 'review.json'))).length
913
- return entries.filter(e => existsSync(join(tasksDir, e, 'review.json'))).length
914
- } catch { return 0 }
915
- }
916
-
917
- /**
918
- * 归属化解析本变更的 execute run(marker 链断裂的根治入口)。
919
- *
920
- * 解析顺序:
921
- * 1. marker(格式校验)指向的 run,若其对本变更有覆盖(tasks/ 有本变更 review)或戳匹配 → 用它;
922
- * 2. marker 缺失/非法/零覆盖(坑10 型漂移:marker 指向空 run)→ 扫描候选:
923
- * a. change 戳等值的最新的 run;
924
- * b.(旧 run 无戳)覆盖度 ≥1 的最新 run;
925
- * 3. 都不命中 → null(调用方降级,报告明确「run 无法归属」而非「review 全缺」)。
926
- *
927
- * fail-safe:任何异常 → null,绝不抛。
928
- * @param {{ runtimeRoot: string, changeName: string, taskIds?: string[] }} opts
929
- * @returns {{ runId: string, origin: 'marker'|'stamp'|'coverage', relocated?: boolean }|null}
930
- */
931
- export function resolveExecuteRunForChange({ runtimeRoot, changeName, taskIds = [] }) {
932
- try {
933
- // 1. marker
934
- let markerRunId = null
935
- try {
936
- const marker = join(runtimeRoot, `current-execute-run-id-${changeName}`)
937
- if (existsSync(marker)) {
938
- const c = readFileSync(marker, 'utf8').trim()
939
- if (c && !isValidExecuteRunId(c)) console.warn(`[sillyspec] execute run marker 内容非法(期望 exec-YYYY-MM-DD-HHMMSS,实得 ${JSON.stringify(c.slice(0, 60))}),忽略并回退归属扫描`)
940
- if (isValidExecuteRunId(c)) markerRunId = c
941
- }
942
- } catch {}
943
- if (markerRunId) {
944
- const stamped = readExecuteRunChangeStamp(runtimeRoot, markerRunId) === changeName
945
- const covered = executeRunCoverage(runtimeRoot, markerRunId, taskIds)
946
- if (stamped || covered > 0) return { runId: markerRunId, origin: 'marker' }
947
- // marker 零覆盖且无戳:疑似漂移(坑10:marker 在、真实 review 在别的 run),下探扫描
948
- }
949
-
950
- // 2. 扫描:戳优先 → 覆盖度启发(旧 run)。
951
- // 覆盖度启发跳过「戳属他变更」的 run:task-NN 命名跨变更同构(都从 task-01 起),只看覆盖度
952
- // 会把他变更 run 的 task-01 review 误配给本变更;戳存在且不等值 = 该 run 有明确主人,排除。
953
- const candidates = listExecuteRunCandidates(runtimeRoot, changeName)
954
- if (candidates.stamped.length > 0) {
955
- return { runId: candidates.stamped[0], origin: 'stamp', relocated: markerRunId ? markerRunId !== candidates.stamped[0] : true }
956
- }
957
- for (const runId of candidates.all) {
958
- const stamp = readExecuteRunChangeStamp(runtimeRoot, runId)
959
- if (stamp && stamp !== changeName) continue
960
- if (executeRunCoverage(runtimeRoot, runId, taskIds) > 0) {
961
- return { runId, origin: 'coverage', relocated: markerRunId ? markerRunId !== runId : true }
962
- }
963
- }
964
- return null
965
- } catch {
966
- return null
967
- }
968
- }
969
-
970
- /**
971
- * worktree execute「主 agent 直接实现」模式收尾兜底:per-task review.json 缺失时,
972
- * 据 git diff base..head 按 task allowed_paths 归属,自动落盘 cannot_verify 草稿。
973
- *
974
- * 根因(坑 worktree-execute-apply-friction 坑2):per-task review.json 无程序化 writer,
975
- * 全靠子代理手写;主 agent 统一实现强依赖链/机械 task 时不走子代理 review 流程 →
976
- * review.json 全缺,execute --done 的 Task Review Gate 报「task-XX 缺少 review.json」阻断。
977
- *
978
- * 复用(与 Task Review Gate / verify 同源,单一真相):
979
- * - resolveVerifyChangedFiles(worktree-aware,meta.json 为权威)→ base..head diff 文件集
980
- * - WorktreeManager.getMeta → baseHash(base)+ worktreePath(决定 head/gitDir,同 gates.js reviewGitDir)
981
- * - parseAllowedPaths + pathMatches(同 worktree-apply Gate2 口径)→ task 文件归属
982
- * - exec-id 解析同 gates.js:269 / autoCheckPlanFromReviews:current-execute-run-id-<change> marker,
983
- * 缺失则 generateExecuteRunId + 落盘(保证草稿与后续 gate 读同一 run 目录)
984
- *
985
- * 行为:
986
- * - 仅 review.json 不存在时写(幂等,已有人工/子代理 verdict 一律跳过,绝不覆盖)
987
- * - changedFiles 为空的 task 不生成(verifyReviewGitEvidence 判空 diff 伪造,留给 agent)
988
- * - 草稿 verdict=cannot_verify + 非空 requiredEvidence(过 schema,流转 verify 阶段兑现)
989
- * - 不属任何 task 的文件累计 unattributed(顺带修复/非源码),不强塞某 task
990
- *
991
- * fail-open:任何异常 → 返回统计,仅 console.warn,不阻断 execute 完成(草稿是兜底,
992
- * 缺了也只是退回原状——gate 报缺 review.json,agent 手补,不比修复前差)。
993
- *
994
- * @param {{ changeName: string, cwd: string, platformOpts?: object, ctx?: object|null }} opts
995
- * @returns {Promise<{ generated: number, skipped: number, unattributed: string[], reason?: string, executeRunId?: string }>}
996
- */
997
- export async function generateTaskReviewDrafts({ changeName, cwd, platformOpts = {}, ctx = null }) {
998
- const specBase = platformOpts.specRoot || join(cwd, '.sillyspec')
999
- const runtimeRoot = resolveRuntimeRoot(platformOpts, specBase)
1000
- const changeDir = join(specBase, 'changes', changeName)
1001
- const tasksDir = join(changeDir, 'tasks')
1002
-
1003
- if (!changeName) {
1004
- return { generated: 0, skipped: 0, unattributed: [], reason: '无 changeName' }
1005
- }
1006
- // 无 task 卡片目录 → 非多 task 变更,无需补草稿
1007
- if (!existsSync(tasksDir)) {
1008
- return { generated: 0, skipped: 0, unattributed: [], reason: '无 tasks/ 目录' }
1009
- }
1010
-
1011
- // exec-id:与 Task Review Gate(gates.js:269)/ autoCheckPlanFromReviews 同源
1012
- const runIdFile = join(runtimeRoot, 'current-execute-run-id-' + changeName)
1013
- let executeRunId = ''
1014
- try {
1015
- if (existsSync(runIdFile)) {
1016
- const c = readFileSync(runIdFile, 'utf8').trim()
1017
- if (c && !isValidExecuteRunId(c)) console.warn(`[sillyspec] execute run marker 内容非法(期望 exec-YYYY-MM-DD-HHMMSS,实得 ${JSON.stringify(c.slice(0, 60))}),视为缺失重新生成`)
1018
- if (isValidExecuteRunId(c)) executeRunId = c
1019
- }
1020
- } catch {}
1021
- if (!executeRunId) {
1022
- executeRunId = generateExecuteRunId()
1023
- // D-001#1 fallback 写入点:mkdir execute-runs/<runId>/tasks 先于 marker(不变量:marker 在则目录在)。
1024
- // 保留 fail-open 契约(调用方 catch 降级)——只去静默:失败 console.error 留痕,不 throw
1025
- //(草稿兜底缺了也只是退回 gate 报缺 review.json,不比修复前差)。
1026
- try {
1027
- mkdirSync(join(runtimeRoot, 'execute-runs', executeRunId, 'tasks'), { recursive: true })
1028
- writeFileSync(runIdFile, executeRunId + '\n')
1029
- stampExecuteRunChange(runtimeRoot, executeRunId, changeName)
1030
- } catch (e) {
1031
- console.error(`[sillyspec] execute run marker/目录写入失败(降级继续,草稿落盘仍尝试): ${e.message}`)
1032
- }
1033
- }
1034
-
1035
- // base..head diff 文件集(worktree-aware;null=git 不可用,[]=无 commit diff)
1036
- let diffFiles = resolveVerifyChangedFiles(cwd, changeName)
1037
- // ⚠️ 并入 worktree 未提交改动(坑 draft-attribution-uncommitted-worktree,2026-08-21 实证):
1038
- // 子代理默认不 commit(execute 复盘 a 同源事实),真实改动全在 worktree working-tree——只看
1039
- // base..HEAD commit diff 时归属恒空,9/9 草稿全成「无归属」靠主代理手写升级。与
1040
- // verifyReviewGitEvidence 的 working-tree 并入口径同源:status --porcelain 文件(排除
1041
- // .sillyspec/ 运行时产物)并入归属集,按 allowed_paths 正常路径归属;review.head 仍为 HEAD
1042
- // commit——evidence 校验对「commit diff 空 + working-tree 有改动」明示不判伪造,语义一致。
1043
- try {
1044
- const wm = new WorktreeManager({ cwd })
1045
- const meta = wm.getMeta(changeName)
1046
- if (meta) {
1047
- const wtGitDir = (meta.worktreePath && meta.mode !== 'in-place-fallback' && existsSync(meta.worktreePath))
1048
- ? meta.worktreePath
1049
- : cwd
1050
- const wtStatus = runGit(wtGitDir, ['status', '--porcelain', '--untracked-files=all'], { trim: false })
1051
- const wtFiles = parsePorcelainFiles(wtStatus)
1052
- .map(p => String(p).replace(/\\/g, '/'))
1053
- .filter(p => p !== '.sillyspec' && !p.startsWith('.sillyspec/'))
1054
- if (wtFiles.length > 0) {
1055
- diffFiles = [...new Set([...(Array.isArray(diffFiles) ? diffFiles : []), ...wtFiles])]
1056
- console.log(`[sillyspec] 草稿归属并入 ${wtFiles.length} 个 worktree 未提交文件(子代理未 commit 的改动按 allowed_paths 归属)`)
1057
- }
1058
- }
1059
- } catch { /* working-tree 并入失败退回 commit diff 口径(fail-open,不阻断草稿) */ }
1060
- // 单仓模式(无 ctx):主仓无 diff 即无任何 task 可生成 → 提前返回(原逻辑零回归)。
1061
- // 有 ctx:主仓无 diff 不阻断——跨仓 task 的 diff 在跨仓仓根独立取(per-task),主仓 task 自然跳过(空 changedFiles)。
1062
- if (!ctx && (!diffFiles || diffFiles.length === 0)) {
1063
- return { generated: 0, skipped: 0, unattributed: [], executeRunId, reason: 'base..head 无代码 diff(改动未 commit?)' }
1064
- }
1065
-
1066
- // base/head + gitDir:与 gates.js reviewGitDir 同源(worktree 优先,in-place 回退 cwd)
1067
- // 有 ctx 时主仓 base/head 仅供主仓 task 用;ctx 主仓 entry 也可提供 base(meta.baseHash 同源)。
1068
- // 主仓 base/head 解析失败 + 无 ctx → 提前返回(原逻辑);有 ctx → 仅记 null,主仓 task 后续跳过(不阻断跨仓 task)。
1069
- let base = null
1070
- let head = null
1071
- let reviewGitDir = cwd
1072
- try {
1073
- const wm = new WorktreeManager({ cwd })
1074
- const meta = wm.getMeta(changeName)
1075
- base = (meta && (meta.baselineCommit || meta.baseHash)) || null
1076
- if (meta && meta.worktreePath && meta.mode !== 'in-place-fallback' && existsSync(meta.worktreePath)) {
1077
- reviewGitDir = meta.worktreePath
1078
- }
1079
- } catch {}
1080
- if (!base) {
1081
- if (!ctx) {
1082
- return { generated: 0, skipped: 0, unattributed: diffFiles, executeRunId, reason: '无 worktree meta.baseHash(无法定 base/head)' }
1083
- }
1084
- // 有 ctx:主仓 base 缺失(主仓无 worktree / 单纯跨仓 change)→ 主仓 task 后续跳过,跨仓 task 照常
1085
- } else {
1086
- try {
1087
- head = runGit(reviewGitDir, ['rev-parse', 'HEAD'])
1088
- } catch {
1089
- if (!ctx) {
1090
- return { generated: 0, skipped: 0, unattributed: diffFiles, executeRunId, reason: 'git rev-parse HEAD 失败(' + reviewGitDir + ')' }
1091
- }
1092
- // 有 ctx:主仓 HEAD 失败不阻断跨仓 task;head 留 null,主仓 task 后续按空 changedFiles 跳过
1093
- }
1094
- }
1095
-
1096
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f)).sort()
1097
- let generated = 0
1098
- let skipped = 0
1099
- let noAttributionCount = 0
1100
- const attributed = new Set()
1101
-
1102
- for (const tf of taskFiles) {
1103
- const taskId = tf.replace(/\.md$/, '')
1104
- const reviewDir = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks', taskId)
1105
- const reviewPath = join(reviewDir, 'review.json')
1106
-
1107
- // 幂等:review.json 已存在(无论合法/解析错/schema 错)一律跳过,绝不覆盖人工/子代理 verdict
1108
- const existing = readReview(reviewPath)
1109
- if (existing.ok || existing.parseError || existing.schemaError) {
1110
- skipped++
1111
- continue
1112
- }
1113
-
1114
- const content = readFileSync(join(tasksDir, tf), 'utf8')
1115
- const allowedPaths = parseAllowedPaths(content)
1116
-
1117
- // ── 多仓分支(design §6 A2 / D-006 / D-010):跨仓 task 用 task 卡双锡点 + 跨仓仓 diff ──
1118
- const taskRepo = normalizeRepoKey(parseRepo(content))
1119
- const crossEntry = (ctx && taskRepo !== DEFAULT_REPO_KEY) ? ctx.resolve(taskRepo) : null
1120
- let taskBase = base
1121
- let taskHead = head
1122
- let taskChangedFiles
1123
- let draftRepo
1124
-
1125
- if (crossEntry) {
1126
- // 跨仓 task:base/head 必须读 task 卡锡点(跨仓仓无 meta.json)。缺任一 → 跳过留给 agent。
1127
- const baseCommit = parseBaseCommit(content)
1128
- const headCommit = parseHeadCommit(content)
1129
- if (!baseCommit || !headCommit) {
1130
- skipped++
1131
- continue
1132
- }
1133
- taskBase = baseCommit
1134
- taskHead = headCommit
1135
- draftRepo = taskRepo
1136
- // 跨仓 diff 在跨仓仓根跑(base..head 锡点锚定,非瞬时 HEAD——D-010 head 精度)
1137
- let crossDiffFiles = []
1138
- try {
1139
- const out = runGit(crossEntry.gitDir, ['diff', '--name-only', `${baseCommit}..${headCommit}`])
1140
- crossDiffFiles = out ? out.split('\n').filter(Boolean).map(p => p.replace(/\\/g, '/')) : []
1141
- } catch {
1142
- // git diff 失败(锡点非真实 commit 等)→ 不生成伪造草稿,留给 agent 手补
1143
- skipped++
1144
- continue
1145
- }
1146
- taskChangedFiles = allowedPaths.length > 0
1147
- ? crossDiffFiles.filter(f => allowedPaths.some(p => pathMatches(f, p)))
1148
- : crossDiffFiles
1149
- } else {
1150
- // 主仓 task(taskRepo='main' 或无 ctx 跨仓解析失败 → 退单仓口径)
1151
- // diffFiles 可能为 null(git 不可用)——有 ctx 时主仓 git 异常不阻断跨仓 task,主仓 task 自然跳过。
1152
- const mainDiff = Array.isArray(diffFiles) ? diffFiles : []
1153
- taskChangedFiles = allowedPaths.length > 0
1154
- ? mainDiff.filter(f => allowedPaths.some(p => pathMatches(f, p)))
1155
- : []
1156
- }
1157
-
1158
- // 主仓 task 缺 base/head(meta 缺失 / HEAD 解析失败,见上方 :968-981 注释承诺的"后续跳过"):
1159
- // 跳过留给 agent 手补。此前 null.slice(0,8) 直接 TypeError 崩掉整个草稿生成(体检 BUG-06)
1160
- if (!crossEntry && (!taskBase || !taskHead)) {
1161
- skipped++
1162
- continue
1163
- }
1164
- // unattributed 只统计主仓 diff(跨仓 diff 路径相对跨仓仓根,与主仓 unattributed 语义无关)
1165
- if (!crossEntry) {
1166
- taskChangedFiles.forEach(f => attributed.add(f))
1167
- }
1168
-
1169
- // 空 changedFiles 的 task 也生成「无归属」草稿(坑 task-review-draft-skip-leak,2026-08-21
1170
- // 实证:task-08/task-10 两次都因 allowed_paths 未命中 diff 被静默跳过,--done gate 拦截后
1171
- // agent 只能从零手写 review.json)。cannot_verify 草稿本就待复核(verify 阶段兑现
1172
- // requiredEvidence),空 changedFiles 不触发 emptyDiff 伪造误判(该判定看真实 git diff 而非
1173
- // review.changedFiles),shouldAutoCheckTask 零 diff 守卫也保证不会被自动勾选——草稿从
1174
- // 「漏了让 agent 从零写」变成「给了骨架让 agent 升级 verdict」。
1175
- if (taskChangedFiles.length === 0) {
1176
- const draft = {
1177
- schemaVersion: REVIEW_SCHEMA_VERSION,
1178
- task: taskId,
1179
- base: taskBase,
1180
- head: taskHead,
1181
- changedFiles: [],
1182
- specVerdict: 'cannot_verify',
1183
- qualityVerdict: 'cannot_verify',
1184
- requiredEvidence: ['auto-generated draft (no-attributed-diff): ' + taskId +
1185
- ' 的 allowed_paths 未命中本次 diff 任何文件(task 未实现 / 改动与他人同文件 / 路径不匹配 / 纯验证任务)——' +
1186
- '需人工确认实际改动后升级 verdict,确属未实现则回 fail;若是纯验证任务(跑测试/部署验证/观测,无代码 diff 是本质属性),' +
1187
- 'task 卡 frontmatter 声明 task_type: verification + review 披露验证区间即走合法零 diff 通道'],
1188
- reviewerNotes: 'auto-generated draft from git diff ' + taskBase.slice(0, 8) + '..' + taskHead.slice(0, 8) +
1189
- ';verdict=未评审(无归属 diff 兜底草稿,坑 task-review-draft-skip-leak)',
1190
- }
1191
- if (draftRepo) draft.repo = draftRepo
1192
- // fail-open(对齐函数头契约 + execute-run-dir-fail-loud 测试锁定的「写失败返回统计不抛」):
1193
- // 无归属草稿写入失败(如 tasks/ 被普通文件占位 ENOTDIR)降级 skipped,不崩整个草稿生成
1194
- try {
1195
- mkdirSync(reviewDir, { recursive: true })
1196
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\n')
1197
- generated++
1198
- noAttributionCount++
1199
- } catch (e) {
1200
- console.error(`[sillyspec] task ${taskId} 无归属草稿落盘失败(降级留给 agent 手补): ${e.message}`)
1201
- skipped++
1202
- }
1203
- continue
1204
- }
1205
-
1206
- const draft = {
1207
- schemaVersion: REVIEW_SCHEMA_VERSION,
1208
- task: taskId,
1209
- base: taskBase,
1210
- head: taskHead,
1211
- changedFiles: taskChangedFiles,
1212
- specVerdict: 'cannot_verify',
1213
- qualityVerdict: 'cannot_verify',
1214
- requiredEvidence: ['auto-generated draft: 待 agent 对照 ' + taskId + ' brief + diff 复核后升级为 pass/fail'],
1215
- reviewerNotes: 'auto-generated draft from git diff ' + taskBase.slice(0, 8) + '..' + taskHead.slice(0, 8) + ';verdict=未评审(worktree execute 主 agent 实现模式兜底,坑2)',
1216
- }
1217
- if (draftRepo) draft.repo = draftRepo
1218
- mkdirSync(reviewDir, { recursive: true })
1219
- writeFileSync(reviewPath, JSON.stringify(draft, null, 2) + '\n')
1220
- generated++
1221
- }
1222
-
1223
- const unattributed = (Array.isArray(diffFiles) ? diffFiles : []).filter(f => !attributed.has(f))
1224
- return { generated, skipped, noAttribution: noAttributionCount, unattributed, executeRunId }
1225
- }
1226
-
1227
- /**
1228
- * adoptTaskReviewMechanics —— 已存在 review.json 的 mechanics 字段一键重算代填(保 verdict)。
1229
- *
1230
- * 背景(2026-08-21 agent-手工产出审计项①):review.json 里 schemaVersion/task/base/head/
1231
- * changedFiles(/repo) 全部可由 CLI 从 git + task 卡机械推导(generateTaskReviewDrafts 已证明),
1232
- * agent/子代理手算 hash、手抄 diff 清单是纯错误面——而 gate(verifyReviewGitEvidence)校验的
1233
- * 恰是这些字段。与草稿生成互补:草稿只补「缺失」,adopt 修「已存在但 mechanics 错/缺」——
1234
- * 保留人工语义字段(specVerdict/qualityVerdict/requiredEvidence/reviewerNotes),只重写 mechanics。
1235
- *
1236
- * verdict 保护策略(不猜 agent 本意):
1237
- * - 合法 verdict(VALID_VERDICTS)原样保留;
1238
- * - 非法/缺失 verdict 降级 cannot_verify,reviewerNotes 追加标记,requiredEvidence 缺失补占位
1239
- * (schema 要求 cannot_verify 必带非空 requiredEvidence);
1240
- * - JSON 解析失败的 review 不救(无法可信保留任何字段),报出来留给 agent 修 JSON 后重跑。
1241
- *
1242
- * fail-open:与草稿生成同契约——缺数据返回统计与 reasons,不抛。
1243
- *
1244
- * @param {{ changeName: string, cwd: string, platformOpts?: object, ctx?: object|null }} opts
1245
- * @returns {Promise<{ adopted: number, unchanged: number, skipped: number, missing: number,
1246
- * downgraded: string[], reasons: string[], executeRunId?: string }>}
1247
- */
1248
- export async function adoptTaskReviewMechanics({ changeName, cwd, platformOpts = {}, ctx = null }) {
1249
- const specBase = platformOpts.specRoot || join(cwd, '.sillyspec')
1250
- const runtimeRoot = resolveRuntimeRoot(platformOpts, specBase)
1251
- const tasksDir = join(specBase, 'changes', changeName, 'tasks')
1252
- const reasons = []
1253
-
1254
- if (!changeName) {
1255
- return { adopted: 0, unchanged: 0, skipped: 0, missing: 0, downgraded: [], reasons: ['无 changeName'] }
1256
- }
1257
- if (!existsSync(tasksDir)) {
1258
- return { adopted: 0, unchanged: 0, skipped: 0, missing: 0, downgraded: [], reasons: ['无 tasks/ 目录'] }
1259
- }
1260
-
1261
- // executeRunId:与草稿/gate 同源 marker。缺 marker 不新建 run——adopt 修的是当前 run 里
1262
- // 已存在的 review,marker 丢失说明无「当前 run」语义,无对象可修(gate 对 marker 缺失放行,
1263
- // 下游 Task Review Gate 兜底,这里同口径不造 run)。
1264
- const runIdFile = join(runtimeRoot, 'current-execute-run-id-' + changeName)
1265
- let executeRunId = ''
1266
- try {
1267
- if (existsSync(runIdFile)) {
1268
- const c = readFileSync(runIdFile, 'utf8').trim()
1269
- if (isValidExecuteRunId(c)) executeRunId = c
1270
- }
1271
- } catch {}
1272
- if (!executeRunId) {
1273
- return { adopted: 0, unchanged: 0, skipped: 0, missing: 0, downgraded: [], reasons: ['无 execute run marker——无当前 run,adopt 无对象'] }
1274
- }
1275
-
1276
- // base/head + diff:与 generateTaskReviewDrafts 同源口径(meta 锡点 + worktree rev-parse +
1277
- // resolveVerifyChangedFiles),保证 adopt 产物与 gate 校验输入一致。
1278
- const diffFiles = resolveVerifyChangedFiles(cwd, changeName)
1279
- let base = null
1280
- let head = null
1281
- let reviewGitDir = cwd
1282
- try {
1283
- const wm = new WorktreeManager({ cwd })
1284
- const meta = wm.getMeta(changeName)
1285
- base = (meta && (meta.baselineCommit || meta.baseHash)) || null
1286
- if (meta && meta.worktreePath && meta.mode !== 'in-place-fallback' && existsSync(meta.worktreePath)) {
1287
- reviewGitDir = meta.worktreePath
1288
- }
1289
- } catch {}
1290
- if (base) {
1291
- try {
1292
- head = runGit(reviewGitDir, ['rev-parse', 'HEAD'])
1293
- } catch {
1294
- head = null
1295
- }
1296
- }
1297
-
1298
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f)).sort()
1299
- let adopted = 0
1300
- let unchanged = 0
1301
- let skipped = 0
1302
- let missing = 0
1303
- const downgraded = []
1304
-
1305
- for (const tf of taskFiles) {
1306
- const taskId = tf.replace(/\.md$/, '')
1307
- const reviewPath = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks', taskId, 'review.json')
1308
- if (!existsSync(reviewPath)) {
1309
- missing++
1310
- continue
1311
- }
1312
-
1313
- const existing = readReview(reviewPath)
1314
- if (existing.parseError) {
1315
- skipped++
1316
- reasons.push(`${taskId}: JSON 解析失败,adopt 不猜字段——先修 JSON 再重跑`)
1317
- continue
1318
- }
1319
- const prev = existing.review || {}
1320
-
1321
- const content = readFileSync(join(tasksDir, tf), 'utf8')
1322
- const allowedPaths = parseAllowedPaths(content)
1323
- const taskRepo = normalizeRepoKey(parseRepo(content))
1324
- const crossEntry = (ctx && taskRepo !== DEFAULT_REPO_KEY) ? ctx.resolve(taskRepo) : null
1325
- let taskBase = base
1326
- let taskHead = head
1327
- let taskChangedFiles
1328
- let draftRepo
1329
-
1330
- if (crossEntry) {
1331
- const baseCommit = parseBaseCommit(content)
1332
- const headCommit = parseHeadCommit(content)
1333
- if (!baseCommit || !headCommit) {
1334
- skipped++
1335
- reasons.push(`${taskId}: 跨仓 task 卡缺 base/head 锡点,无法 adopt`)
1336
- continue
1337
- }
1338
- taskBase = baseCommit
1339
- taskHead = headCommit
1340
- draftRepo = taskRepo
1341
- let crossDiffFiles = []
1342
- try {
1343
- const out = runGit(crossEntry.gitDir, ['diff', '--name-only', `${baseCommit}..${headCommit}`])
1344
- crossDiffFiles = out ? out.split('\n').filter(Boolean).map(p => p.replace(/\\/g, '/')) : []
1345
- } catch {
1346
- skipped++
1347
- reasons.push(`${taskId}: 跨仓 git diff 失败(${crossEntry.gitDir})`)
1348
- continue
1349
- }
1350
- taskChangedFiles = allowedPaths.length > 0
1351
- ? crossDiffFiles.filter(f => allowedPaths.some(p => pathMatches(f, p)))
1352
- : crossDiffFiles
1353
- } else {
1354
- const mainDiff = Array.isArray(diffFiles) ? diffFiles : []
1355
- taskChangedFiles = allowedPaths.length > 0
1356
- ? mainDiff.filter(f => allowedPaths.some(p => pathMatches(f, p)))
1357
- : []
1358
- }
1359
-
1360
- if (!crossEntry && (!taskBase || !taskHead)) {
1361
- skipped++
1362
- reasons.push(`${taskId}: 主仓缺 worktree meta base/head,无法 adopt`)
1363
- continue
1364
- }
1365
-
1366
- const merged = { ...prev }
1367
- merged.schemaVersion = REVIEW_SCHEMA_VERSION
1368
- merged.task = taskId
1369
- merged.base = taskBase
1370
- merged.head = taskHead
1371
- merged.changedFiles = taskChangedFiles
1372
- if (draftRepo) merged.repo = draftRepo
1373
-
1374
- let verdictTouched = false
1375
- for (const v of ['specVerdict', 'qualityVerdict']) {
1376
- if (!VALID_VERDICTS.includes(merged[v])) {
1377
- merged[v] = 'cannot_verify'
1378
- verdictTouched = true
1379
- }
1380
- }
1381
- if (verdictTouched) downgraded.push(taskId)
1382
- let evidenceFilled = false
1383
- if ((merged.specVerdict === 'cannot_verify' || merged.qualityVerdict === 'cannot_verify')
1384
- && (!Array.isArray(merged.requiredEvidence) || merged.requiredEvidence.length === 0)) {
1385
- merged.requiredEvidence = [`adopt 代填:原 review 缺 requiredEvidence(verdict=${merged.specVerdict}/${merged.qualityVerdict}),待人工复核补证据`]
1386
- evidenceFilled = true
1387
- }
1388
- if (verdictTouched) {
1389
- merged.reviewerNotes = String(merged.reviewerNotes || '') + (merged.reviewerNotes ? '; ' : '')
1390
- + 'adopt: 原 verdict 非法/缺失已降级 cannot_verify(不猜本意)'
1391
- }
1392
-
1393
- const mechanicsChanged = prev.schemaVersion !== merged.schemaVersion
1394
- || prev.base !== merged.base
1395
- || prev.head !== merged.head
1396
- || JSON.stringify(prev.changedFiles ?? null) !== JSON.stringify(merged.changedFiles)
1397
- || prev.repo !== merged.repo
1398
-
1399
- try {
1400
- if (mechanicsChanged || verdictTouched || evidenceFilled) {
1401
- writeFileSync(reviewPath, JSON.stringify(merged, null, 2) + '\n')
1402
- adopted++
1403
- } else {
1404
- unchanged++
1405
- }
1406
- } catch (e) {
1407
- skipped++
1408
- reasons.push(`${taskId}: 写回失败 ${e.message}`)
1409
- }
1410
- }
1411
-
1412
- return { adopted, unchanged, skipped, missing, downgraded, reasons, executeRunId }
1413
- }
1414
-
1415
- /**
1416
- * 获取当前(或最新)execute run id
1417
- * 从 runtime 目录下查找 execute-runs/ 子目录
1418
- *
1419
- * @param {string} runtimeRoot - .sillyspec/.runtime 路径
1420
- * @returns {string|null} 最新 run id,null 表示无任何 run
1421
- */
1422
- /**
1423
- * 获取当前 execute run id
1424
- * 优先从 current-execute-run-id 标记文件读取(execute 阶段启动时写入),
1425
- * fallback 到 execute-runs/ 下最新的 exec- 前缀目录。
1426
- *
1427
- * @param {string} runtimeRoot - .sillyspec/.runtime 路径
1428
- * @returns {string|null} 当前 run id,null 表示无任何 run
1429
- */
1430
- export function getLatestExecuteRunId(runtimeRoot) {
1431
- // 优先读标记文件(execute 阶段启动时由 run.js 写入,生命周期内不变)
1432
- const markerPath = join(runtimeRoot, 'current-execute-run-id')
1433
- try {
1434
- if (existsSync(markerPath)) {
1435
- const content = readFileSync(markerPath, 'utf8').trim()
1436
- if (content && !isValidExecuteRunId(content)) console.warn(`[sillyspec] execute run marker 内容非法(期望 exec-YYYY-MM-DD-HHMMSS,实得 ${JSON.stringify(content.slice(0, 60))}),忽略并回退目录扫描`)
1437
- if (isValidExecuteRunId(content)) return content
1438
- }
1439
- } catch {}
1440
-
1441
- // fallback:扫描 execute-runs/ 目录
1442
- const runsDir = join(runtimeRoot, 'execute-runs')
1443
- if (!existsSync(runsDir)) return null
1444
-
1445
- try {
1446
- const entries = readdirSync(runsDir, { withFileTypes: true })
1447
- .filter(e => e.isDirectory() && e.name.startsWith('exec-'))
1448
- .map(e => e.name)
1449
- .sort()
1450
- .reverse()
1451
- return entries[0] || null
1452
- } catch {
1453
- return null
1454
- }
1455
- }
1456
-
1457
- /**
1458
- * 确保 task review 目录存在
1459
- * @param {string} runtimeRoot
1460
- * @param {string} executeRunId
1461
- * @param {string} taskId
1462
- * @returns {string} task review 目录路径
1463
- */
1464
- export function ensureTaskReviewDir(runtimeRoot, executeRunId, taskId) {
1465
- const dir = join(runtimeRoot, 'execute-runs', executeRunId, 'tasks', taskId)
1466
- mkdirSync(dir, { recursive: true })
1467
- return dir
1468
- }
1469
-
1470
- /**
1471
- * 打印校验结果
1472
- * @param {{ ok: boolean, errors: string[], warnings: string[], requiredEvidence: Array }} result
1473
- */
1474
- export function printReviewResult(result, context = {}) {
1475
- if (result.ok && result.warnings.length === 0) {
1476
- console.log('\n✅ Task Review Gate — 所有任务评审通过')
1477
- return
1478
- }
1479
-
1480
- if (result.errors.length > 0) {
1481
- console.error('\n🚫 Task Review Gate — FAILED')
1482
- for (const err of result.errors) {
1483
- console.error(` - ${err}`)
1484
- }
1485
- const hint = context.runtimeRoot && context.executeRunId
1486
- ? `期望路径:${context.runtimeRoot}/execute-runs/${context.executeRunId}/tasks/<task-XX>/review.json`
1487
- : '为缺失/失败的任务补充 review.json'
1488
- console.error(`\n 提示:${hint},然后重新 --done`)
1489
- }
1490
-
1491
- if (result.warnings.length > 0) {
1492
- console.warn('\n⚠️ Task Review Gate — WARNING')
1493
- for (const w of result.warnings) {
1494
- console.warn(` - ${w}`)
1495
- }
1496
- console.warn('\n cannot_verify 的 requiredEvidence 将在 verify 阶段校验')
1497
- }
1498
- }