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,1398 +0,0 @@
1
- /**
2
- * Plan Postcheck 模块
3
- *
4
- * 从 run.js 和 plan.js 拆出的确定性校验逻辑:
5
- * - 拓扑排序(topoSortWaves)
6
- * - 蓝图一致性校验(validateBlueprintConsistency)
7
- * - plan 产物校验(validatePlanArtifacts)
8
- * - 执行入口(executePlanPostcheck)
9
- *
10
- * 这些都是 noAI 步骤,不需要 LLM 参与。
11
- */
12
- import { existsSync, readFileSync as _readFileSync, readdirSync, mkdtempSync, writeFileSync, rmSync } from 'fs'
13
- // 归一化行尾为 LF:Windows 下 python/编辑器文本模式写 .md 会产生 CRLF,致本模块多处
14
- // frontmatter/字段正则(`^---\n`、`allowed_paths:\s*\n…`、`^goal:` 等)失配,报「缺 frontmatter
15
- // /缺字段」假错误(见缺陷 windows-python-crlf-taskcard)。读取时统一转 LF,一处覆盖全部正则。
16
- const readFileSync = (filePath, encoding) => _readFileSync(filePath, encoding).replace(/\r\n/g, '\n')
17
- import { join as pJoin, basename } from 'path'
18
- import { tmpdir } from 'os'
19
- import jsYaml from 'js-yaml'
20
- import { parseFileChangeList, pathMatches } from '../change-list.js'
21
- import { getRule } from '../stage-contract-spec.js'
22
- import { TASKCARD_PLACEHOLDERS } from '../taskcard-placeholders.js'
23
- import { validateScriptCommands } from './cmd-existence.js'
24
-
25
- // ═══════════════════════════════════════════════════════════════
26
- // 解析工具(从 plan.js 迁移)
27
- // ═══════════════════════════════════════════════════════════════
28
-
29
- /**
30
- * 从 task-NN.md frontmatter 解析 depends_on 字段
31
- * @param {string} content - task 文件内容
32
- * @returns {string[]}
33
- */
34
- function parseDependsOn(content) {
35
- content = content.replace(/\r\n/g, '\n') // 外部调用方(worktree-apply 等)原生 readFileSync 喂 CRLF 时 ^---\n 锚点失配
36
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
37
- if (!fmMatch) return []
38
- const fm = fmMatch[1]
39
- const inlineMatch = fm.match(/depends_on:\s*\[([^\]]*)\]/)
40
- if (inlineMatch) {
41
- return inlineMatch[1].split(',').map(s => s.trim().replace(/['"]/g, '')).filter(Boolean)
42
- }
43
- // 块列表:列表项允许顶格或缩进([ \t]*,坑6——原 \s* 贪婪吃掉换行与前导空白,
44
- // 顶格 `depends_on:\n- task-01` 标准 YAML 写法永远失配,静默判「无依赖」)
45
- const blockMatch = fm.match(/depends_on:[ \t]*\n((?:[ \t]*-[ \t]+.+\n?)+)/)
46
- if (blockMatch) {
47
- return blockMatch[1].match(/[ \t]*-[ \t]+(.+)/g)?.map(s => s.replace(/^[ \t]*-[ \t]+/, '').trim().replace(/['"]/g, '')) || []
48
- }
49
- return []
50
- }
51
-
52
- /**
53
- * 解析 task-NN.md 的 task id(从 frontmatter 或文件名)
54
- * @param {string} content - task 文件内容
55
- * @param {string} filename - 文件名
56
- * @returns {string|null}
57
- */
58
- function parseTaskId(content, filename) {
59
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
60
- if (fmMatch) {
61
- const idMatch = fmMatch[1].match(/^id:\s*(.+)/m)
62
- if (idMatch) return idMatch[1].trim()
63
- }
64
- const fileMatch = filename.match(/(task-\d+)/i)
65
- return fileMatch ? fileMatch[1] : null
66
- }
67
-
68
- /**
69
- * 解析 task-NN.md 的 allowed_paths
70
- * @param {string} content
71
- * @returns {string[]}
72
- */
73
- export function parseAllowedPaths(content) {
74
- content = content.replace(/\r\n/g, '\n') // 同 parseDependsOn:入口归一,保护喂原始 CRLF 内容的外部调用方
75
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
76
- if (!fmMatch) return []
77
- const fm = fmMatch[1]
78
- const inlineMatch = fm.match(/allowed_paths:\s*\[([^\]]*)\]/)
79
- if (inlineMatch) {
80
- return inlineMatch[1].split(',').map(s => s.trim().replace(/['"`]/g, '')).filter(Boolean)
81
- }
82
- // 块列表:列表项允许顶格或缩进(坑6①——原 `\s*\n` 的 \s 贪婪匹配换行+前导空白,
83
- // 标准 YAML 块列表 `allowed_paths:\n- src/a.js`(顶格)永远失配,静默判「缺 allowed_paths」;
84
- // 缩进式 \s+- 恰可命中是巧合幸存。改 [ \t]*(不吃换行)+ 行内 [ \t]*-[ \t]+ 顶格缩进通吃)
85
- const blockMatch = fm.match(/allowed_paths:[ \t]*\n((?:[ \t]*-[ \t]+.+\n?)+)/)
86
- if (blockMatch) {
87
- // 剥首尾成对反引号(坑7 家族:`src/a.js` 整项以反引号开头时 js-yaml/正则路径带 ` 匹配失败报未覆盖;
88
- // 与 change-list.js 的 cell 归一化同语义——剥两端包裹引号,不动路径内部字符)
89
- return blockMatch[1].match(/[ \t]*-[ \t]+(.+)/g)?.map(s => {
90
- const raw = s.replace(/^[ \t]*-[ \t]+/, '').trim()
91
- return raw.replace(/^`([^`]*)`$/, '$1').replace(/^['"]|['"]$/g, '').trim()
92
- }).filter(Boolean) || []
93
- }
94
- return []
95
- }
96
-
97
- /**
98
- * 从 task-NN.md frontmatter 解析标量字段(repo / base_commit / head_commit)。
99
- * 复用 parseTaskContracts 的 frontmatter 提取 + js-yaml load 模式(标量可选字段,正则对引号/空值脆弱)。
100
- *
101
- * design §7.2 跨仓 task 卡 frontmatter 协议:
102
- * repo: sillyspec # 可选,缺省='main'(调用方视 null 为 main)
103
- * base_commit: <sha> # 可选,CLI 锡点写入(派发前落盘 base)
104
- * head_commit: <sha> # 可选,CLI 锡点写入(回收 review 前落盘 head)
105
- *
106
- * 缺省 / 空值 / 无 frontmatter → null(向后兼容旧 task 卡)。
107
- * @param {string} content - task 文件内容
108
- * @param {string} field - frontmatter 字段名
109
- * @returns {string|null}
110
- */
111
- function parseFrontmatterScalar(content, field) {
112
- content = content.replace(/\r\n/g, '\n') // 同 parseAllowedPaths:入口归一 CRLF
113
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
114
- if (!fmMatch) return null
115
- let fm
116
- try {
117
- fm = jsYaml.load(fmMatch[1]) || {}
118
- } catch {
119
- return null
120
- }
121
- const v = fm[field]
122
- if (v == null) return null
123
- const s = String(v).trim()
124
- return s === '' ? null : s
125
- }
126
-
127
- /**
128
- * 解析 task-NN.md frontmatter 的 repo 字段(跨仓 task 声明)。
129
- * 缺省=null(=main,调用方按主仓处理)。design §7.2 / D-001。
130
- * @param {string} content
131
- * @returns {string|null}
132
- */
133
- export function parseRepo(content) {
134
- return parseFrontmatterScalar(content, 'repo')
135
- }
136
-
137
- /**
138
- * 解析 task-NN.md frontmatter 的 base_commit 字段(CLI 派发跨仓 task 前落盘的 base 锡点)。
139
- * 缺省=null(未锡点 / 单仓 task)。design §7.2 / D-010。
140
- * @param {string} content
141
- * @returns {string|null}
142
- */
143
- export function parseBaseCommit(content) {
144
- return parseFrontmatterScalar(content, 'base_commit')
145
- }
146
-
147
- /**
148
- * 解析 task-NN.md frontmatter 的 head_commit 字段(CLI 回收 review 前落盘的 head 锡点)。
149
- * 缺省=null(未锡点 / 单仓 task)。design §7.2 / D-010。
150
- * @param {string} content
151
- * @returns {string|null}
152
- */
153
- export function parseHeadCommit(content) {
154
- return parseFrontmatterScalar(content, 'head_commit')
155
- }
156
-
157
- /**
158
- * 从 local.yaml 文本解析 repos: 段(跨仓 workspace 注册表)。
159
- * 与 parseLocalYamlModules 同风格(轻量行扫描,不引 yaml 依赖),结构 Map<repoKey, absolutePath>。
160
- *
161
- * design §7.3 local.yaml repos schema:
162
- * repos:
163
- * sillyspec: C:/Users/qinyi/IdeaProjects/sillyspec
164
- * # main 不用注册(隐式 = cwd / specRoot 父目录)
165
- *
166
- * 无 repos 段 / 空段 / 入参空 → 空 Map(单仓 change 不读,向后兼容)。
167
- *
168
- * **职责边界**:本函数只 parse local.yaml 文本,不读 local.yaml 文件(文件读取入口归
169
- * execute 启动 / task-09)。本函数不校验 declaredRepos ⊆ registry(D-007 fail-closed
170
- * 校验在 MultiRepoContext 构造时做)。
171
- * @param {string} yamlText
172
- * @returns {Map<string, string>} repoKey → absolutePath
173
- */
174
- export function parseRepoRegistry(yamlText) {
175
- const reg = new Map()
176
- if (!yamlText) return reg
177
- // CRLF 归一(坑 register-repo-crlf-idempotent-loop,2026-08-23 实证:Windows 下 agent Write
178
- // 工具/编辑器写出的 local.yaml 带 \r——条目正则 `(.*)$` 的 `.` 不匹配 \r、`$` 又要求真串尾,
179
- // 行尾残留 \r 时整条失配 → 空 Map → MultiRepoContext fail-closed 报「未注册」→ register-repo
180
- // 幂等跳过不落盘 → 死循环。同文件 parseAllowedPaths/parseDependsOn/parseBaseCommit 均有此
181
- // 归一,本函数是唯一缺口)
182
- const lines = String(yamlText).replace(/\r\n?/g, '\n').split('\n')
183
- let startIdx = -1
184
- for (let i = 0; i < lines.length; i++) {
185
- if (/^repos:\s*(?:#.*)?$/.test(lines[i])) { startIdx = i; break }
186
- }
187
- if (startIdx === -1) return reg
188
- for (let i = startIdx + 1; i < lines.length; i++) {
189
- const line = lines[i]
190
- // 遇到新的顶层 key(行首非空格且非注释)→ repos 段结束
191
- if (line.length > 0 && !line.startsWith(' ') && !line.startsWith('\t') && !line.startsWith('#') && line.trim() !== '') break
192
- // 条目格式: <key>: <value>(key 限 [A-Za-z0-9_.\-],与 parseLocalYamlModules 对齐)
193
- const entry = line.match(/^\s+([A-Za-z0-9_.\-]+):\s*(.*)$/)
194
- if (!entry) continue
195
- const value = (entry[2] || '').trim()
196
- if (value === '' || value.startsWith('#')) continue
197
- // 去可选行内注释(`value # comment`)—— 注意路径不含 ` #`,注释前必带空格
198
- const cleaned = value.replace(/\s+#.*$/, '').trim()
199
- if (cleaned === '') continue
200
- // 去首尾可选引号(YAML 字符串引用),保留路径内反斜杠原样
201
- const path = cleaned.replace(/^['"]|['"]$/g, '')
202
- if (path === '') continue
203
- reg.set(entry[1], path)
204
- }
205
- return reg
206
- }
207
-
208
- /**
209
- * 检查 task-NN.md 是否包含验收标准章节
210
- * @param {string} content
211
- * @returns {boolean}
212
- */
213
- function hasAcceptanceCriteria(content) {
214
- // 新模板把 goal/implementation/acceptance/verify/constraints 放在 frontmatter
215
- // (acceptance: 作为 fm 字段),老格式或人工写的卡片可能用 body 章节。
216
- // 两种都认,避免「模板格式」与「postcheck 判定」不一致导致卡片过不了校验。
217
- if (/^acceptance:/m.test(content)) return true
218
- return /##\s*验收标准/.test(content) || /##\s*Acceptance/.test(content)
219
- }
220
-
221
- /**
222
- * 检查 task-NN.md 是否包含 TDD/验证步骤
223
- * @param {string} content
224
- * @returns {boolean}
225
- */
226
- function hasTddOrVerify(content) {
227
- // 同 hasAcceptanceCriteria:新模板用 frontmatter 的 verify: 字段,老格式用 body 章节。
228
- if (/^verify:/m.test(content)) return true
229
- return /##\s*TDD/.test(content) || /##\s*验证/.test(content) || /##\s*Verify/.test(content)
230
- }
231
-
232
- /**
233
- * 解析 task-NN.md 的跨任务契约字段 provides / expects_from
234
- * 用 js-yaml 解析 frontmatter(嵌套结构,正则不可靠)。
235
- * provides/expects_from 为可选字段;缺失或解析失败时返回空(不阻断)。
236
- * @param {string} content - task 文件内容
237
- * @returns {{ provides: Array<{contract, fields}>, expectsFrom: Record<string, Array<{contract, needs}>> }}
238
- */
239
- export function parseTaskContracts(content) {
240
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
241
- if (!fmMatch) return { provides: [], expectsFrom: {} }
242
- let fm
243
- try {
244
- fm = jsYaml.load(fmMatch[1]) || {}
245
- } catch {
246
- // frontmatter 非合法 YAML(老格式/手写不规范)—— 当作无契约字段,不阻断
247
- return { provides: [], expectsFrom: {} }
248
- }
249
-
250
- const provides = Array.isArray(fm.provides)
251
- ? fm.provides.map(p => ({
252
- contract: String(p?.contract || ''),
253
- fields: Array.isArray(p?.fields) ? p.fields.map(String) : [],
254
- })).filter(p => p.contract)
255
- : []
256
-
257
- const expectsFrom = {}
258
- if (fm.expects_from && typeof fm.expects_from === 'object' && !Array.isArray(fm.expects_from)) {
259
- for (const [providerTask, contracts] of Object.entries(fm.expects_from)) {
260
- if (!Array.isArray(contracts)) continue
261
- expectsFrom[providerTask] = contracts
262
- .map(c => ({
263
- contract: String(c?.contract || ''),
264
- needs: Array.isArray(c?.needs) ? c.needs.map(String) : [],
265
- }))
266
- .filter(c => c.contract)
267
- }
268
- }
269
-
270
- return { provides, expectsFrom }
271
- }
272
-
273
- // ═══════════════════════════════════════════════════════════════
274
- // 核心逻辑
275
- // ═══════════════════════════════════════════════════════════════
276
-
277
- /**
278
- * 拓扑排序:根据 depends_on 计算波次
279
- * @param {Map<string, string[]>} depMap - taskId → depends_on list
280
- * @returns {{ waves: string[][], error: string|null }}
281
- */
282
- export function topoSortWaves(depMap) {
283
- const tasks = [...depMap.keys()]
284
- const waves = []
285
- const assigned = new Set()
286
- const visited = new Set()
287
-
288
- // 先做循环依赖检测(DFS)
289
- function hasCycle(task, path) {
290
- if (path.has(task)) return true
291
- if (visited.has(task)) return false
292
- path.add(task)
293
- const deps = depMap.get(task) || []
294
- for (const dep of deps) {
295
- if (!depMap.has(dep)) continue // 依赖不存在(可能是外部引用),跳过
296
- if (hasCycle(dep, path)) return true
297
- }
298
- path.delete(task)
299
- visited.add(task)
300
- return false
301
- }
302
- for (const task of tasks) {
303
- if (hasCycle(task, new Set())) {
304
- return { waves: [], error: `检测到循环依赖,涉及 task: ${task}` }
305
- }
306
- }
307
-
308
- // 逐层分配 Wave
309
- while (assigned.size < tasks.length) {
310
- const currentWave = []
311
- for (const task of tasks) {
312
- if (assigned.has(task)) continue
313
- const deps = (depMap.get(task) || []).filter(d => depMap.has(d))
314
- if (deps.every(d => assigned.has(d))) {
315
- currentWave.push(task)
316
- }
317
- }
318
- if (currentWave.length === 0) {
319
- const remaining = tasks.filter(t => !assigned.has(t))
320
- return { waves: [], error: `无法解析依赖关系,剩余 task: ${remaining.join(', ')}` }
321
- }
322
- for (const task of currentWave) {
323
- assigned.add(task)
324
- }
325
- waves.push(currentWave)
326
- }
327
-
328
- return { waves, error: null }
329
- }
330
-
331
- /**
332
- * 解析 plan.md 显式 Wave 分组 → Map<taskId, waveIndex>。
333
- *
334
- * Wave 口径与 execute.js parseWavesFromPlan 一致(execute 的真实并行单元,非 topoSort 建议值):
335
- * - `## Wave N` 标题下的 task-XX checkbox 归入 Wave N;
336
- * - 非 Wave 标题行(## 自检 等)退出当前 Wave 段,避免其 checkbox 混入。
337
- * 返回 null = plan.md 不存在或无显式 Wave 标题 → execute 会把所有 task 放进单个隐式 Wave
338
- * 全并行(execute.js:402-408),调用方据此判「同文件即冲突」。
339
- *
340
- * @param {string} planPath - plan.md 绝对路径
341
- * @returns {Map<string, number>|null} taskId → waveIndex;null = 无显式 Wave
342
- */
343
- function parseTaskWavesFromPlan(planPath) {
344
- if (!existsSync(planPath)) return null
345
- const content = readFileSync(planPath, 'utf8')
346
- if (!/^#+\s*Wave\s+\d+/im.test(content)) return null
347
- const map = new Map()
348
- let currentWave = null
349
- for (const line of content.split('\n')) {
350
- const wm = line.match(/^#+\s*Wave\s+(\d+)/i)
351
- if (wm) { currentWave = parseInt(wm[1], 10); continue }
352
- if (/^#+\s/.test(line)) { currentWave = null; continue } // 非 Wave 标题退出当前 Wave 段
353
- // 2026-08-20-task-truth-unify:Wave 段下为纯 ID 引用行(- task-XX);旧 checkbox 行同收
354
- // (旧变更读侧兼容——新格式由 validatePlanForExecute 拦旧形态,此处不重复把关)
355
- const tm = line.match(/^[-*]\s+(?:\[[ x]\]\s*)?(task-\d+)\s*[::\s]*$/i)
356
- || line.match(/^[-*]\s*\[[ x]\]\s*(task-\d+)\b/i)
357
- // id 归一补零(与卡片/注册表 task-01 口径一致,坑 wave-ref-unpadded):plan.md 写
358
- // `- task-1` 时裸用捕获原文做 key,永远匹配不到卡片 id task-01 → 被判「未列入任何
359
- // Wave」,同 Wave 共享文件检测静默跳过。execute.js parseWavesFromPlan 已补零,对齐。
360
- if (tm && currentWave !== null) map.set(String(tm[1]).replace(/^task-(\d+)$/i, (_, n) => `task-${n.padStart(2, '0')}`), currentWave)
361
- }
362
- return map
363
- }
364
-
365
- /**
366
- * 收集任务卡 depends_on → Map<taskId, deps>(Wave 重排 / plan-adopt-waves 共用)。
367
- * taskId 优先取卡内 frontmatter id:(与文件名解耦——文件名 task-01 但 id 改写过时以 id 为准)。
368
- * @param {string} tasksDir - changes/<name>/tasks 目录
369
- * @returns {Map<string, string[]>}
370
- */
371
- export function collectTaskDepMap(tasksDir) {
372
- const depMap = new Map()
373
- if (!existsSync(tasksDir)) return depMap
374
- for (const file of readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))) {
375
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
376
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
377
- let taskId = file.replace('.md', '')
378
- if (fmMatch) {
379
- const idMatch = fmMatch[1].match(/^id:\s*(.+)/m)
380
- if (idMatch) taskId = idMatch[1].trim()
381
- }
382
- depMap.set(taskId, parseDependsOn(content))
383
- }
384
- return depMap
385
- }
386
-
387
- /**
388
- * 本地一致性校验器
389
- * @param {string} changeDir - 变更目录
390
- * @returns {{ ok: boolean, errors: string[], warnings: string[] }}
391
- */
392
- export function validateBlueprintConsistency(changeDir) {
393
- const errors = []
394
- const warnings = []
395
-
396
- const tasksDir = pJoin(changeDir, 'tasks')
397
- if (!existsSync(tasksDir)) {
398
- return { ok: false, errors: ['tasks/ 目录不存在'], warnings }
399
- }
400
-
401
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))
402
- if (taskFiles.length === 0) {
403
- return { ok: false, errors: ['tasks/ 目录下没有 task-NN.md 文件'], warnings }
404
- }
405
-
406
- // task 卡片基础字段文案从 manifest 同源(plan.task-card-structure);${id} 由下方 `${taskId} (${file})` 替换。
407
- const bsRule = getRule('plan.task-card-structure')
408
- const taskInfo = new Map()
409
- // pathOwners 按 (repo, path) 二元组聚合(design §5.3 约束③ / D-008):键 = `${repo}|${path}`,
410
- // repo 缺省='main'(parseRepo 返 null → main)。跨仓 task 与主仓 task 同名物理路径分属不同 repo
411
- // → 二元组键不同 → 不误判同 Wave 冲突(如主仓 src/task-review.js vs sillyspec src/task-review.js)。
412
- // ⚠️ 键分隔符 `|` 假设 repo 名与 path 均不含 `|`(repo 名约束 [A-Za-z0-9_.\-]、path 含 / \,极低概率含 |)。
413
- // value 结构 { repo, path, owners }:冲突文案对外仍显示纯 path(用户体验),内部按二元组判冲突。
414
- const pathOwners = new Map()
415
-
416
- for (const file of taskFiles) {
417
- const filePath = pJoin(tasksDir, file)
418
- const content = readFileSync(filePath, 'utf8')
419
- const taskId = parseTaskId(content, file)
420
- if (!taskId) {
421
- errors.push(`${file}: 无法解析 task id`)
422
- continue
423
- }
424
-
425
- const dependsOn = parseDependsOn(content)
426
- const allowedPaths = parseAllowedPaths(content)
427
- const hasAcceptance = hasAcceptanceCriteria(content)
428
- const hasTdd = hasTddOrVerify(content)
429
- // repo 缺省='main'(parseRepo 返 null → 单仓 task,与既有行为零回归)
430
- const repo = parseRepo(content) || 'main'
431
-
432
- taskInfo.set(taskId, { dependsOn, allowedPaths, hasAcceptance, hasTdd, file })
433
-
434
- if (allowedPaths.length === 0) {
435
- errors.push(bsRule.data.messageAllowedPaths.replaceAll('${id}', `${taskId} (${file})`))
436
- }
437
- if (!hasAcceptance) {
438
- errors.push(bsRule.data.messageAcceptance.replaceAll('${id}', `${taskId} (${file})`))
439
- }
440
- if (!hasTdd) {
441
- warnings.push(bsRule.data.messageTdd.replaceAll('${id}', `${taskId} (${file})`))
442
- }
443
-
444
- for (const p of allowedPaths) {
445
- const key = `${repo}|${p}`
446
- if (!pathOwners.has(key)) pathOwners.set(key, { repo, path: p, owners: [] })
447
- pathOwners.get(key).owners.push(taskId)
448
- }
449
- }
450
-
451
- // 路径冲突(Wave 感知):同 repo 同 Wave 内 >1 task 共享 allowed_path → execute 强制并行(execute.js:603)
452
- // 子代理会互相覆盖该文件 → error。跨 Wave 同文件 → 串行执行安全 → warning。
453
- // 按 (repo, path) 二元组判冲突(约束③):跨仓 task 与主仓 task 同名路径不误判(不同 repo → 不同键)。
454
- // Wave 口径 = plan.md 显式 `## Wave N`(parseTaskWavesFromPlan,与 execute 同源,非 topoSort 建议值);
455
- // plan.md 无显式 Wave → execute 全并行(隐式单 Wave,execute.js:402-408)→ 同 repo 同文件即冲突。
456
- const waveOfTask = parseTaskWavesFromPlan(pJoin(changeDir, 'plan.md'))
457
- for (const [, { repo, path: p, owners }] of pathOwners) {
458
- if (owners.length < 2) continue
459
- if (waveOfTask === null) {
460
- errors.push(
461
- `路径 ${p} 被 ${owners.length} 个 task 修改: ${owners.join(', ')} — plan.md 无显式 Wave 划分,` +
462
- `execute 会把它们放进同一隐式 Wave 全并行(execute.js:402-408),子代理互相覆盖。` +
463
- `解法:拆到不同 Wave(串行),或合并为单个 task。`
464
- )
465
- continue
466
- }
467
- // 显式 Wave:按 wave 分组 owners,找同 Wave 冲突
468
- const byWave = new Map()
469
- for (const t of owners) {
470
- const w = waveOfTask.get(t)
471
- if (w === undefined) continue // 未列入任何 Wave → execute 不执行,不参与冲突判定
472
- if (!byWave.has(w)) byWave.set(w, [])
473
- byWave.get(w).push(t)
474
- }
475
- for (const [w, ts] of byWave) {
476
- if (ts.length > 1) {
477
- errors.push(
478
- `路径 ${p} 被 Wave ${w} 内 ${ts.length} 个 task 修改: ${ts.join(', ')} — 同 Wave 任务 execute 强制并行(execute.js:603),` +
479
- `子代理会互相覆盖该文件。解法:把它们拆到不同 Wave(串行)。` +
480
- `(注:quick 阶段对同文件并发只提示不阻断——那是轻量流程无并行子代理、最坏后果 git 可分离;` +
481
- `此处硬拦是因并行覆盖不可自动恢复,两阶段宽严不同是设计使然)`
482
- )
483
- }
484
- }
485
- // 跨 Wave 共享:串行安全,仅提示
486
- if (byWave.size > 1) {
487
- warnings.push(`路径 ${p} 跨 Wave 被修改: ${owners.join(', ')}(不同 Wave 串行执行,安全;确认是否有意共享)`)
488
- }
489
- }
490
-
491
- // 任务声明 ↔ tasks/ 卡片双向对账(债单 D-2b;2026-08-20-task-truth-unify:声明源迁 tasks.md 注册表):
492
- // 注册表列 17 任务只出 12 卡(尾部文档同步类任务漏卡)时,无卡任务不进 Wave、
493
- // 不受 execute 审计 → 零失败信号漏做。口径与 execute.js parseTaskRegistry 一致
494
- // (`- [ ] task-NN` checkbox 行;file 命名 task-NN.md + 卡内 id task-NN 均取,缺一即漏卡)。
495
- const planMdPath = pJoin(changeDir, 'plan.md')
496
- const declaredIds = new Set()
497
- const tasksMdPath = pJoin(changeDir, 'tasks.md')
498
- if (existsSync(tasksMdPath)) {
499
- for (const line of readFileSync(tasksMdPath, 'utf8').split('\n')) {
500
- const m = line.match(/^[-*]\s*\[[ x]\]\s*(task-\d+)\b/i)
501
- if (m) declaredIds.add(m[1].toLowerCase())
502
- }
503
- }
504
- if (declaredIds.size === 0 && existsSync(planMdPath)) {
505
- // 兼容读侧:tasks.md 缺失/无声明时回退解析 plan.md 旧 checkbox 声明(旧归档变更)
506
- for (const line of readFileSync(planMdPath, 'utf8').split('\n')) {
507
- const m = line.match(/^[-*]\s*\[[ x]\]\s*(task-\d+)\b/i)
508
- if (m) declaredIds.add(m[1].toLowerCase())
509
- }
510
- }
511
- if (declaredIds.size > 0) {
512
- const tprRule = getRule('plan.task-plan-reconciliation')
513
- const cardIds = new Set([...taskInfo.keys()].map(id => id.toLowerCase()))
514
- const missing = [...declaredIds].filter(id => !cardIds.has(id))
515
- if (missing.length > 0) {
516
- errors.push(
517
- tprRule.data.messageMissingCards
518
- .replaceAll('${declared}', declaredIds.size)
519
- .replaceAll('${missing}', missing.join(', '))
520
- )
521
- }
522
- const orphans = [...cardIds].filter(id => !declaredIds.has(id))
523
- if (orphans.length > 0) {
524
- errors.push(
525
- tprRule.data.messageOrphanCards.replaceAll('${orphans}', orphans.join(', '))
526
- )
527
- }
528
- }
529
- // declaredIds.size === 0:注册表无 task 声明(极端格式)→ 跳过对账,
530
- // 由 validatePlanArtifacts/validatePlanForExecute 把关,不在此误伤。
531
-
532
- // 拓扑排序 + 循环依赖
533
- const depMap = new Map()
534
- for (const [taskId, info] of taskInfo) {
535
- depMap.set(taskId, info.dependsOn)
536
- }
537
- const { error: topoError } = topoSortWaves(depMap)
538
- if (topoError) {
539
- errors.push(topoError)
540
- }
541
-
542
- return { ok: errors.length === 0, errors, warnings }
543
- }
544
-
545
- /**
546
- * 跨任务契约校验器:对账 consumer.expects_from ↔ provider.provides
547
- *
548
- * 修复场景:consumer task 声明期望 provider 产出某 DTO 的某字段,
549
- * 但 provider 的 provides 未承诺(或字段缺失)→ plan 阶段阻断,
550
- * 避免到 execute/verify 才暴露(典型表现:前端 fallback 错误字段 → 403/500)。
551
- *
552
- * provides / expects_from 均为可选字段:未声明时不校验(向后兼容)。
553
- * @param {string} changeDir - 变更目录
554
- * @returns {{ ok: boolean, errors: string[], warnings: string[] }}
555
- */
556
- export function validateCrossTaskContracts(changeDir) {
557
- const errors = []
558
- const warnings = []
559
-
560
- const tasksDir = pJoin(changeDir, 'tasks')
561
- if (!existsSync(tasksDir)) {
562
- return { ok: true, errors, warnings }
563
- }
564
-
565
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))
566
- if (taskFiles.length === 0) {
567
- return { ok: true, errors, warnings }
568
- }
569
-
570
- // 第一遍:收集每个 task 的 provides(taskId → Map(contract → Set(fields)))
571
- const providesByTask = new Map()
572
- for (const file of taskFiles) {
573
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
574
- const taskId = parseTaskId(content, file)
575
- if (!taskId) continue
576
- const { provides } = parseTaskContracts(content)
577
- const contractMap = new Map()
578
- for (const p of provides) {
579
- contractMap.set(p.contract, new Set(p.fields))
580
- }
581
- providesByTask.set(taskId, contractMap)
582
- }
583
-
584
- // 第二遍:校验每个 consumer 的 expects_from 是否被 provider.provides 覆盖。
585
- // 3 种断裂文案(unknown-provider / undeclared / missing-fields)从 manifest 同源
586
- // (plan.cross-task-contract.data),${consumer}/${provider}/${contract}/${needs}/${available} replaceAll。
587
- const ctRule = getRule('plan.cross-task-contract')
588
- const renderCtMsg = (tmpl, consumer, provider, contract, needs, available) => tmpl
589
- .replaceAll('${consumer}', consumer)
590
- .replaceAll('${provider}', provider)
591
- .replaceAll('${contract}', contract)
592
- .replaceAll('${needs}', needs)
593
- .replaceAll('${available}', available)
594
- for (const file of taskFiles) {
595
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
596
- const consumerId = parseTaskId(content, file)
597
- if (!consumerId) continue
598
- const { expectsFrom } = parseTaskContracts(content)
599
-
600
- for (const [providerTask, contracts] of Object.entries(expectsFrom)) {
601
- if (!providesByTask.has(providerTask)) {
602
- for (const c of contracts) {
603
- errors.push(renderCtMsg(ctRule.data.messageUnknownProvider, consumerId, providerTask, c.contract, c.needs.join(', '), ''))
604
- }
605
- continue
606
- }
607
-
608
- const providerContracts = providesByTask.get(providerTask)
609
- for (const c of contracts) {
610
- const providerFields = providerContracts.get(c.contract)
611
- if (providerFields === undefined) {
612
- errors.push(renderCtMsg(ctRule.data.messageUndeclaredContract, consumerId, providerTask, c.contract, c.needs.join(', '), ''))
613
- continue
614
- }
615
- const missing = c.needs.filter(f => !providerFields.has(f))
616
- if (missing.length > 0) {
617
- errors.push(renderCtMsg(ctRule.data.messageMissingFields, consumerId, providerTask, c.contract, missing.join(', '), [...providerFields].join(', ')))
618
- }
619
- }
620
- }
621
- }
622
-
623
- return { ok: errors.length === 0, errors, warnings }
624
- }
625
-
626
- /**
627
- * 从 local.yaml 文本解析 modules 块(monorepo 子包定位)。
628
- *
629
- * 与 verify-postcheck.extractModules 同风格(轻量行扫描,不引 yaml 依赖),不复用是为避免
630
- * plan-postcheck → verify-postcheck → contract-matrix → plan-postcheck 的循环导入。
631
- * 只取 path 字段(test 字段此处用不到),结构 { name: { path } }。
632
- *
633
- * modules:
634
- * backend: { path: "backend/", test: "cd backend && uv run pytest" }
635
- *
636
- * @param {string} yamlText
637
- * @returns {Record<string, {path:string}>|null} 无 modules 块或无有效条目 → null
638
- */
639
- export function parseLocalYamlModules(yamlText) {
640
- if (!yamlText) return null
641
- const lines = yamlText.split('\n')
642
- let startIdx = -1
643
- for (let i = 0; i < lines.length; i++) {
644
- if (/^modules:\s*(?:#.*)?$/.test(lines[i])) { startIdx = i; break }
645
- }
646
- if (startIdx === -1) return null
647
- const modules = {}
648
- for (let i = startIdx + 1; i < lines.length; i++) {
649
- const line = lines[i]
650
- const entry = line.match(/^([ \t]+)([A-Za-z0-9_.\-]+):\s*(.*)$/)
651
- if (!entry) {
652
- // 遇到新的顶层 key(行首非空格且非注释)→ modules 块结束
653
- if (line.length > 0 && !line.startsWith(' ') && !line.startsWith('#') && line.trim() !== '') break
654
- continue
655
- }
656
- // 条目缩进放宽为「任意非零空白」(坑 modules-indent-hardcoded):此前硬编码恰 2 空格,
657
- // 4 空格/Tab 缩进的条目不匹配且不触发块结束 → 被静默跳过 → modules 丢失 →
658
- // validateScriptCommands 退化为只查根 package.json,monorepo 子包命令被误报不存在。
659
- const rest = entry[3] || ''
660
- // path 值:带引号或不带引号(flow mapping),取第一个匹配
661
- const pathMatch = rest.match(/path:\s*"([^"]+)"/) || rest.match(/path:\s*([^,\s}]+)/)
662
- if (pathMatch) modules[entry[2]] = { path: pathMatch[1] }
663
- }
664
- return Object.keys(modules).length > 0 ? modules : null
665
- }
666
-
667
- /**
668
- * TaskCard 命令存在性校验器(调共享 validateScriptCommands,硬阻断)。
669
- *
670
- * 修复场景(design D-04 / 问题 3):TaskCard verify/implementation 写 `pnpm gen:types`
671
- * 但根 package.json 无此 script(实际在 monorepo 子包 packages 目录下),plan 阶段零校验
672
- * → execute 子代理跑死命令。scan-postcheck 的命令校验只看 local.yaml 且维持 warning;
673
- * 本函数对 TaskCard 升 error(同 helper、严重度由调用方定)。
674
- *
675
- * modules 从 local.yaml 提取(monorepo 子包感知):无 modules 块时仅查根 package.json
676
- * (与 scan-postcheck 历史行为一致);有 modules 块时多候选子包 package.json 任一命中即通过。
677
- *
678
- * @param {string} changeDir - 变更目录
679
- * @param {string} projectRoot - 项目根目录(package.json 查找基准)
680
- * @param {object|null} modules - local.yaml modules 块({ name: { path } }),可选
681
- * @returns {{ ok: boolean, errors: string[], warnings: string[] }}
682
- */
683
- export function validateTaskCommands(changeDir, projectRoot, modules = null) {
684
- const errors = []
685
- const warnings = []
686
-
687
- const tasksDir = pJoin(changeDir, 'tasks')
688
- if (!existsSync(tasksDir)) {
689
- return { ok: true, errors, warnings }
690
- }
691
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))
692
- if (taskFiles.length === 0) {
693
- return { ok: true, errors, warnings }
694
- }
695
-
696
- for (const file of taskFiles) {
697
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
698
- const taskId = parseTaskId(content, file) || file
699
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
700
- if (!fmMatch) continue // feasibility 已报 frontmatter 缺失,不重复
701
- let fm
702
- try {
703
- fm = jsYaml.load(fmMatch[1]) || {}
704
- } catch {
705
- continue // 非法 YAML 由 feasibility 处理,不重复
706
- }
707
-
708
- // 合并 verify + implementation 文本(命令可能出现在任一字段)。
709
- // 字段两形态都收(坑 taskcard-block-list-noop):规范格式(taskcard.js 骨架 / plan 模板)的
710
- // verify/implementation 是 YAML 块列表 → js-yaml 解析为数组;此前只收 string,规范卡片
711
- // 恒落空 → 「命令存在性校验」(hard-error)对合规 TaskCard 整体 no-op,只有违规写成
712
- // 纯标量的卡片才被校验。数组按行 join 回文本,与标量同管道。
713
- const toCmdText = (v) => Array.isArray(v) ? v.map(String).join('\n') : (typeof v === 'string' ? v : '')
714
- const verifyText = toCmdText(fm.verify)
715
- const implText = toCmdText(fm.implementation)
716
- const text = `${verifyText}\n${implText}`
717
- if (!text.trim()) continue
718
-
719
- const { invalid } = validateScriptCommands(text, { projectRoot, modules })
720
- for (const inv of invalid) {
721
- errors.push(`${taskId}: ${inv.cmd} 命令不存在(${inv.reason})`)
722
- }
723
- }
724
-
725
- return { ok: errors.length === 0, errors, warnings }
726
- }
727
-
728
- // 路径容差匹配(normalizePath / globMatch / pathMatches)复用自 change-list.js,
729
- // design 清单解析与 allowed_paths 对账共用同一套匹配语义,避免两处逻辑漂移。
730
-
731
- /**
732
- * design §6 按仓分段段头识别(D-014):`## <repo> 仓变更`(如 `## sillyspec 仓变更`)。
733
- * 段头为 h2,repo 名取段头首 token(去空白/编号前缀)。容忍可选编号前缀与尾随空白/冒号。
734
- * 不命中(非仓变更段头)→ null。
735
- */
736
- const REPO_SECTION_HEADER_RE = /^#{2,3}\s+(?:\d+[.)]\s*)?([A-Za-z0-9_.\-]+)\s*仓变更\s*[::]?\s*$/
737
-
738
- /**
739
- * design §6 文件清单章节标题(与 change-list.js FILE_LIST_SECTION_RE 同源,避免 import 私有常量)。
740
- * 容忍可选编号前缀(`## 6. 文件变更清单`),与 change-list 解析口径一致。
741
- */
742
- const FILE_LIST_SECTION_RE = /^#{2,3}\s*(?:\d+[.)]\s*)?(文件变更清单|变更文件清单|文件清单|File Changes|Files to Change)/im
743
-
744
- /**
745
- * 按 repo 解析 design §6 文件清单(约束③ / D-014)。
746
- *
747
- * 支持 design §6 按仓分段:`## <repo> 仓变更` 段头下的路径归该 repo;无段头时整章节归 'main'
748
- * (向后兼容单仓 design,与原 parseFileChangeList 行为等价)。段内路径解析复用 parseFileChangeList
749
- * (表格列定位 / exclude 子段 / 占位符过滤 / CRLF 容错全部继承,零漂移)——方法是:把每段内容包成
750
- * 临时 design 文件(前置标准 `## 文件变更清单` 标题),写 OS tmp 调 parseFileChangeList,立即清理。
751
- *
752
- * 为什么不复用单次 parseFileChangeList:change-list.js 的通用 parser 把段头 `## <repo> 仓变更`
753
- * 当成「下一个 ## 章节」截断主章节(line 173 `^##\s`),跨仓段路径会丢——这正是 task-03 要修的。
754
- *
755
- * 返回值结构(与 pathOwners 二元组对齐):
756
- * Map<repo, Set<path>> —— 每个 repo 的 design 清单路径集
757
- * 外加 _hasSegmentHeader 标记(调用方据此决定是否走分段对账路径)
758
- *
759
- * @param {string} designPath - design.md 绝对路径
760
- * @returns {{ byRepo: Map<string, Set<string>>, hasSegmentHeader: boolean, allFiles: string[] }}
761
- */
762
- function parseDesignCoverageByRepo(designPath) {
763
- const byRepo = new Map()
764
- const allFiles = []
765
- if (!designPath || !existsSync(designPath)) {
766
- return { byRepo, hasSegmentHeader: false, allFiles }
767
- }
768
- const content = readFileSync(designPath, 'utf8')
769
-
770
- const sectionMatch = content.match(FILE_LIST_SECTION_RE)
771
- if (!sectionMatch) {
772
- return { byRepo, hasSegmentHeader: false, allFiles }
773
- }
774
-
775
- // 主章节起点(match index)→ 扫描到下一个非段头的 `## ` 标题或文件末尾。
776
- // 段头 `## <repo> 仓变更` 是 h2 但属本章节的子分段,不应触发章节结束。
777
- const lines = content.slice(sectionMatch.index).split('\n')
778
- // 先扫一遍:本章节内是否含至少一个段头(决定 hasSegmentHeader / 走分段路径 vs 退化路径)
779
- let hasSegmentHeader = false
780
- const sectionLines = []
781
- for (let i = 0; i < lines.length; i++) {
782
- const line = lines[i]
783
- if (i > 0 && /^##\s/.test(line) && !REPO_SECTION_HEADER_RE.test(line)) {
784
- // 遇到非段头的 h2 标题(如 `## 7. 接口定义`)→ 主章节结束
785
- break
786
- }
787
- if (REPO_SECTION_HEADER_RE.test(line)) hasSegmentHeader = true
788
- sectionLines.push(line)
789
- }
790
-
791
- if (!hasSegmentHeader) {
792
- // 无段头 → 整章节归 main(等价原 parseFileChangeList 行为)。
793
- // keepSillyspecDocs=true:.sillyspec/docs/ 模块文档 = 交付物,与 apply 阶段
794
- // resolveApplyAllowSet 口径一致(债单 D-2)——design 声明的模块文档更新必须被 task 认领。
795
- const main = new Set(parseFileChangeList(designPath, { keepSillyspecDocs: true }))
796
- if (main.size > 0) byRepo.set('main', main)
797
- for (const p of main) allFiles.push(p)
798
- return { byRepo, hasSegmentHeader: false, allFiles }
799
- }
800
-
801
- // 有段头 → 按 repo 切片,每段构造临时 design 调 parseFileChangeList
802
- // 当前 repo:段头之前的内容(主章节标题到第一个段头之间)归 'main'
803
- let currentRepo = 'main'
804
- const segments = new Map() // repo -> 行数组(含表格/列表,不含段头本身)
805
- let beforeFirstHeader = [] // 段头之前的 main 段内容
806
- let seenHeader = false
807
- for (const line of sectionLines.slice(1)) { // 跳过主章节标题行(sectionLines[0])
808
- const hdr = line.match(REPO_SECTION_HEADER_RE)
809
- if (hdr) {
810
- currentRepo = hdr[1]
811
- seenHeader = true
812
- if (!segments.has(currentRepo)) segments.set(currentRepo, [])
813
- continue
814
- }
815
- if (!seenHeader) {
816
- beforeFirstHeader.push(line)
817
- } else {
818
- segments.get(currentRepo).push(line)
819
- }
820
- }
821
-
822
- // 段头之前的 main 段(若有内容)也要对账
823
- if (beforeFirstHeader.filter(l => l.trim()).length > 0) {
824
- segments.set('main', beforeFirstHeader)
825
- }
826
-
827
- const tmpDir = mkdtempSync(pJoin(tmpdir(), 'design-cov-seg-'))
828
- try {
829
- for (const [repo, segLines] of segments) {
830
- // 把段内容包成完整 design md(前置主章节标题,让 parseFileChangeList 识别章节起点)
831
- const virtualDesign = ['## 文件变更清单', '', ...segLines, ''].join('\n')
832
- const tmpPath = pJoin(tmpDir, `${repo}.md`)
833
- writeFileSync(tmpPath, virtualDesign)
834
- const segFiles = [...parseFileChangeList(tmpPath, { keepSillyspecDocs: true })]
835
- if (segFiles.length === 0) continue
836
- const set = byRepo.get(repo) || new Set()
837
- for (const p of segFiles) { set.add(p); allFiles.push(p) }
838
- byRepo.set(repo, set)
839
- }
840
- } finally {
841
- rmSync(tmpDir, { recursive: true, force: true })
842
- }
843
-
844
- return { byRepo, hasSegmentHeader: true, allFiles }
845
- }
846
-
847
- /**
848
- * design.md 文件变更清单 → tasks allowed_paths 覆盖对账
849
- *
850
- * 修复场景:design.md 声明要改某源码文件(如 access-guide UI),但没有任何 task 的
851
- * allowed_paths 覆盖它 → execute 子代理被 allowed_paths 锁死不能碰它 → UI 没改
852
- * (「页面还是错的」),而 verify 一路对照 task 卡片循环验证照样 PASS。
853
- *
854
- * 在 plan-postcheck(execute 前)确定性拦截:design 清单中每个源码文件必须被
855
- * 至少一个 task 的 allowed_paths 覆盖(前缀 / glob 容差匹配)。
856
- *
857
- * 跨仓分段对账(约束③ / D-014):design §6 支持 `## <repo> 仓变更` 段头按仓分段,
858
- * task allowed_paths 按 (repo, path) 二元组归属——跨仓 task 的 allowed_paths 只覆盖
859
- * 对应 repo 段的 design 清单,不与主仓段交叉误判。无段头时整章节归 main(零回归)。
860
- *
861
- * fail-open 边界(不阻断):design.md 不存在、无 task 卡片(none 级别)、
862
- * task 卡片均无 allowed_paths(由 validatePlanFeasibility 把关)。
863
- * 阻断边界:有 task 卡片但 design 缺清单章节(light/full 已生成 task → design 必有清单)、
864
- * 清单文件未被任何 task 的 allowed_paths 覆盖。
865
- *
866
- * @param {string} changeDir - 变更目录
867
- * @returns {{ ok: boolean, errors: string[], warnings: string[], designFiles: string[], uncovered: string[] }}
868
- */
869
- export function validateDesignFileCoverage(changeDir) {
870
- const errors = []
871
- const warnings = []
872
-
873
- const designPath = pJoin(changeDir, 'design.md')
874
- if (!existsSync(designPath)) {
875
- return { ok: true, errors, warnings, designFiles: [], uncovered: [] }
876
- }
877
-
878
- const tasksDir = pJoin(changeDir, 'tasks')
879
- const taskFiles = existsSync(tasksDir)
880
- ? readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))
881
- : []
882
-
883
- // 无 task 卡片(plan_level=none 或老变更)→ 无对账对象,fail-open
884
- if (taskFiles.length === 0) {
885
- return { ok: true, errors, warnings, designFiles: [], uncovered: [] }
886
- }
887
-
888
- // 按仓分段解析 design §6(约束③):段头 `## <repo> 仓变更` → 段内路径归该 repo;无段头 → 全 main
889
- const { byRepo: designByRepo, hasSegmentHeader, allFiles: designFiles } = parseDesignCoverageByRepo(designPath)
890
- // 两种断裂文案(缺清单章节 / 文件未覆盖)从 manifest 同源(plan.design-file-coverage.data)。
891
- const dcRule = getRule('plan.design-file-coverage')
892
- if (designFiles.length === 0) {
893
- // 走到 plan-postcheck 说明已生成 task 卡片(light/full),brainstorm 模板规定清单必填。
894
- // 无清单 = design↔execute 偏差温床(覆盖对账无从对起),阻断,不让它静默放过。
895
- errors.push(dcRule.data.messageMissingList)
896
- return { ok: false, errors, warnings, designFiles: [], uncovered: [] }
897
- }
898
-
899
- // task allowed_paths 也按 (repo, path) 二元组收集(与 pathOwners 同口径,约束③):
900
- // 跨仓 task 的 allowed_paths 只覆盖对应 repo 的 design 段,不与主仓段交叉误判。
901
- const taskAllowedByRepo = new Map() // repo -> string[]
902
- let totalAllowed = 0
903
- for (const file of taskFiles) {
904
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
905
- const repo = parseRepo(content) || 'main'
906
- const allowed = parseAllowedPaths(content)
907
- if (allowed.length === 0) continue
908
- totalAllowed += allowed.length
909
- const arr = taskAllowedByRepo.get(repo) || []
910
- arr.push(...allowed)
911
- taskAllowedByRepo.set(repo, arr)
912
- }
913
- if (totalAllowed === 0) {
914
- return { ok: true, errors, warnings, designFiles, uncovered: [] }
915
- }
916
-
917
- // 对账:design 的每条 (repo, path) 必须被同 repo 的 task allowed_paths 覆盖。
918
- // 无分段(单仓)时 byRepo 只含 main,taskAllowedByRepo 也只含 main → 退化原扁平对账(零回归)。
919
- const uncovered = []
920
- for (const [repo, paths] of designByRepo) {
921
- const allowed = taskAllowedByRepo.get(repo) || []
922
- for (const df of paths) {
923
- // 同 repo 无 task 声明 → 整段无覆盖;或有 task 但无 pathMatches → 未覆盖
924
- if (!allowed.some(ap => pathMatches(df, ap))) {
925
- uncovered.push(hasSegmentHeader ? `[${repo}] ${df}` : df)
926
- }
927
- }
928
- }
929
- if (uncovered.length > 0) {
930
- errors.push(
931
- dcRule.data.messageUncovered
932
- .replaceAll('${count}', uncovered.length)
933
- .replaceAll('${files}', uncovered.map(f => ` • ${f}`).join('\n'))
934
- )
935
- }
936
-
937
- return { ok: errors.length === 0, errors, warnings, designFiles, uncovered }
938
- }
939
-
940
- /**
941
- * Plan 可行性校验器(本地代码证明 execute 前置条件)
942
- * 检查 TaskCard 的完整性和可行性
943
- * @param {string} changeDir - 变更目录
944
- * @param {string} projectRoot - 项目根目录(用于检查 allowed_paths 是否存在)
945
- * @returns {{ ok: boolean, errors: string[], warnings: string[] }}
946
- */
947
- export function validatePlanFeasibility(changeDir, projectRoot = null) {
948
- const errors = []
949
- const warnings = []
950
-
951
- const tasksDir = pJoin(changeDir, 'tasks')
952
- if (!existsSync(tasksDir)) {
953
- return { ok: true, errors, warnings } // none/light 可能没有 tasks/
954
- }
955
-
956
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f)).sort()
957
- if (taskFiles.length === 0) {
958
- return { ok: true, errors, warnings }
959
- }
960
-
961
- // task 卡片完整 schema 文案从 manifest 同源(plan.task-card-schema);${id} 随检查点取 ${file} / ${taskId || file} / ${taskId}。
962
- const fsRule = getRule('plan.task-card-schema')
963
- const allTaskIds = []
964
- const depMap = new Map()
965
-
966
- for (const file of taskFiles) {
967
- const content = readFileSync(pJoin(tasksDir, file), 'utf8')
968
- const fmMatch = content.match(/^---\n([\s\S]*?)\n---/)
969
- if (!fmMatch) {
970
- // 漏闭合 --- 高频坑细化:只报「缺少 YAML frontmatter」不具体,用户须逐轮试错。
971
- // 有开头 --- 无闭合 / 完全无 --- 分开报并附修复动作(manifest messageFrontmatter 保持
972
- // 基础句,细化文案内联——同 title_zh 内联先例)。骨架命令从源头保闭合 + LF。
973
- const firstLine = (content.split('\n')[0] || '').trim()
974
- errors.push(
975
- firstLine === '---'
976
- ? `${file}: frontmatter 未闭合——有开头 --- 但缺少结尾 ---。修复:补一行 --- 闭合(frontmatter 以 --- 行开始并以 --- 行结束),或 sillyspec taskcard <change> --task <task-id> 重新生成安全骨架后填充`
977
- : `${fsRule.data.messageFrontmatter.replaceAll('${id}', file)}——文件必须以 --- 行开始。修复:sillyspec taskcard <change> --task <task-id> 生成安全骨架后填充`
978
- )
979
- continue
980
- }
981
- const fm = fmMatch[1]
982
- const body = content.slice(fmMatch[0].length)
983
-
984
- // 1. 必要字段检查
985
- const taskId = (fm.match(/^id:\s*(.+)/m)?.[1] || '').trim()
986
- const title = (fm.match(/^title:\s*(.+)/m)?.[1] || '').trim()
987
- // 复用 parseAllowedPaths(认 inline [x] + 块式两种写法),与 blueprint consistency / design coverage
988
- // 三处统一,消除「feasibility 只认块式 → inline 写法被误报 allowed_paths 为空」的漂移(transcript 卡 3 轮根因)。
989
- const allowedPaths = parseAllowedPaths(content)
990
-
991
- if (!taskId) errors.push(fsRule.data.messageId.replaceAll('${id}', file))
992
- if (!title) errors.push(fsRule.data.messageTitle.replaceAll('${id}', file))
993
- // title_zh(中文标题)完整性:子代理常为压 plan.js 的 20~40 行硬上限合并 title/title_zh(静默丢失),
994
- // postcheck 不校验行数(那是 prompt 劝说)但强制 frontmatter 字段齐全(enforcement 优于放宽劝说)。
995
- // 无对应 manifest 文案,内联(其余字段文案走 fsRule.data.messageXxx)。prompt-control-debt plan-b。
996
- const titleZh = (fm.match(/^title_zh:\s*(.+)/m)?.[1] || '').trim()
997
- if (!titleZh) errors.push(`${taskId || file}: frontmatter 缺少 title_zh(中文标题)——不得为压行数合并/删除字段`)
998
- if (taskId) allTaskIds.push(taskId)
999
-
1000
- // 2. allowed_paths 不为空
1001
- if (allowedPaths.length === 0) {
1002
- errors.push(fsRule.data.messageAllowedPaths.replaceAll('${id}', taskId || file))
1003
- }
1004
-
1005
- // 3. allowed_paths 文件存在或父目录存在(仅在 projectRoot 提供时检查)
1006
- if (projectRoot && allowedPaths.length > 0) {
1007
- for (const p of allowedPaths) {
1008
- const fullPath = pJoin(projectRoot, p)
1009
- const parentDir = pJoin(fullPath, '..')
1010
- if (!existsSync(fullPath) && !existsSync(parentDir)) {
1011
- warnings.push(`${taskId}: allowed_paths 中的 ${p} 文件和父目录都不存在`)
1012
- }
1013
- }
1014
- }
1015
-
1016
- // 4. depends_on 引用存在
1017
- const dependsOn = parseDependsOn(content)
1018
- if (taskId) depMap.set(taskId, dependsOn)
1019
-
1020
- // 5. body/frontmatter 包含必要字段(TaskCard 格式中这些字段在 frontmatter 内)
1021
- const hasGoal = /^goal:/m.test(fm)
1022
- const hasImplementation = /implementation:/m.test(fm)
1023
- const hasAcceptance = /acceptance:/m.test(fm)
1024
- const hasVerify = /verify:/m.test(fm)
1025
- const hasConstraints = /constraints:/m.test(fm)
1026
-
1027
- if (!hasGoal) errors.push(fsRule.data.messageGoal.replaceAll('${id}', taskId || file))
1028
- if (!hasImplementation) errors.push(fsRule.data.messageImplementation.replaceAll('${id}', taskId || file))
1029
- if (!hasAcceptance) errors.push(fsRule.data.messageAcceptance.replaceAll('${id}', taskId || file))
1030
- if (!hasVerify) errors.push(fsRule.data.messageVerify.replaceAll('${id}', taskId || file))
1031
- if (!hasConstraints) errors.push(fsRule.data.messageConstraints.replaceAll('${id}', taskId || file))
1032
-
1033
- // 5b. 骨架占位符拦截(坑 taskcard-placeholder-slip,2026-08-24 用户实证:task 卡留成
1034
- // 空骨架、九字段「存在性」全过,直到人工审计才发现)。占位标记是 taskcard.js 生成的
1035
- // 封闭集合(TASKCARD_PLACEHOLDERS 同源导出),精确匹配;verify 字段的占位命令刻意
1036
- // 不拦(可能是真实 tsc 命令)。占位符视同缺字段,与 9 字段缺失同级 error。
1037
- // 先剥 HTML 注释再匹配——骨架尾部注释自身罗列了占位标记清单(填充指引),不剥会把
1038
- // 已填充卡的注释误判成占位残留。
1039
- const contentNoComments = content.replace(/<!--[\s\S]*?-->/g, '')
1040
- const placeholderHits = TASKCARD_PLACEHOLDERS.filter(p => contentNoComments.includes(p.marker))
1041
- if (placeholderHits.length > 0) {
1042
- errors.push(
1043
- (fsRule.data.messagePlaceholder || '${id}: task 卡仍是未填充的生成骨架')
1044
- .replaceAll('${id}', taskId || file)
1045
- .replaceAll('${fields}', placeholderHits.map(p => p.field).join('、'))
1046
- )
1047
- }
1048
-
1049
- // 6. acceptance best-effort 字段 grep(D-05 软约束,warning 不阻断)
1050
- // 从 acceptance 文本提取 snake_case/camelCase 标识符,grep allowed_paths 指向的源文件;
1051
- // 找不到 → warning(给 LLM 审查提线索,不阻断 execute)。宁漏不噪:只取 snake/camel,
1052
- // 正则天然避开命令(无 _ 或大写)/路径(无 /)/中文;glob allowed_path / 目录 / 不存在文件一律跳过。
1053
- if (projectRoot && hasAcceptance && allowedPaths.length > 0) {
1054
- let acceptanceText = ''
1055
- try {
1056
- const fmObj = jsYaml.load(fm) || {}
1057
- if (typeof fmObj.acceptance === 'string') acceptanceText = fmObj.acceptance
1058
- else if (Array.isArray(fmObj.acceptance)) acceptanceText = fmObj.acceptance.join('\n')
1059
- } catch {
1060
- // frontmatter 非法 YAML(feasibility 未对 fm 做 YAML 解析,可能字面合法但语义复杂)→ 跳过 best-effort
1061
- }
1062
- if (acceptanceText) {
1063
- const IDENT_RE = /(?<![A-Za-z])[a-z]+(?:_[a-z]+)+|(?<![A-Za-z])[a-z]+(?:[A-Z][a-z]+)+/g
1064
- const idents = [...new Set(acceptanceText.match(IDENT_RE) || [])]
1065
- if (idents.length > 0) {
1066
- const readableFiles = []
1067
- for (const ap of allowedPaths) {
1068
- if (ap.includes('*')) continue // glob,跳过(best-effort,不展开)
1069
- try {
1070
- readableFiles.push(readFileSync(pJoin(projectRoot, ap), 'utf8'))
1071
- } catch {
1072
- // 目录 / 不存在 / 不可读 → 跳过(feasibility 3 已对不存在文件提示 warning)
1073
- }
1074
- }
1075
- // 至少读到一个源文件才比对,避免「全没读到 → 全部标识符误报」噪声
1076
- if (readableFiles.length > 0) {
1077
- for (const ident of idents) {
1078
- if (!readableFiles.some(c => c.includes(ident))) {
1079
- warnings.push(`${taskId}: acceptance 提到 ${ident} 但 allowed_paths 源文件未命中`)
1080
- }
1081
- }
1082
- }
1083
- }
1084
- }
1085
- }
1086
- }
1087
-
1088
- // 4b. depends_on 引用存在性
1089
- for (const [taskId, deps] of depMap) {
1090
- for (const dep of deps) {
1091
- if (!depMap.has(dep)) {
1092
- errors.push(fsRule.data.messageDependsOnMissing.replaceAll('${id}', taskId).replaceAll('${dep}', dep))
1093
- }
1094
- }
1095
- }
1096
-
1097
- // 5b. depends_on 无环(topoSortWaves 已含循环检测)
1098
- const { error: topoError } = topoSortWaves(depMap)
1099
- if (topoError) {
1100
- errors.push(topoError)
1101
- }
1102
-
1103
- // 7. task id 连续性
1104
- if (allTaskIds.length > 0) {
1105
- const nums = allTaskIds.map(id => {
1106
- const m = id.match(/task-(\d+)/i)
1107
- return m ? parseInt(m[1], 10) : null
1108
- }).filter(n => n !== null).sort((a, b) => a - b)
1109
- // nums[0]!==1 时跳过 = 兼容旧变更编号不从 1 起(契约同 validatePlanForExecute 检查 3,
1110
- // test/plan-execute-contract.test.mjs Case 10 钉死,勿改)
1111
- if (nums.length > 0 && nums[0] === 1) {
1112
- for (let i = 0; i < nums.length; i++) {
1113
- if (nums[i] !== i + 1) {
1114
- errors.push(getRule('plan.task-id-continuity').failMessage.replaceAll('${expected}', String(i + 1).padStart(2, '0')).replaceAll('${actual}', String(nums[i]).padStart(2, '0')))
1115
- break
1116
- }
1117
- }
1118
- }
1119
- }
1120
-
1121
- // 9. plan.md 通过 validatePlanForExecute(延迟导入避免循环依赖)
1122
- // 这在 run.js 的 postcheck contract 中已检查,这里不重复
1123
-
1124
- return { ok: errors.length === 0, errors, warnings }
1125
- }
1126
-
1127
- /**
1128
- * Plan 产物校验:检查 plan.md 和 tasks/ 是否齐全
1129
- * @param {string} changeDir - 变更目录
1130
- * @returns {{ ok: boolean, errors: string[], warnings: string[], planExists: boolean, taskCount: number }}
1131
- */
1132
- export function validatePlanArtifacts(changeDir) {
1133
- const errors = []
1134
- const warnings = []
1135
-
1136
- const planPath = pJoin(changeDir, 'plan.md')
1137
- if (!existsSync(planPath)) {
1138
- return { ok: false, errors: ['plan.md 不存在'], warnings, planExists: false, taskCount: 0 }
1139
- }
1140
-
1141
- const tasksDir = pJoin(changeDir, 'tasks')
1142
- let taskCount = 0
1143
- if (existsSync(tasksDir)) {
1144
- taskCount = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f)).length
1145
- } else {
1146
- warnings.push('tasks/ 目录不存在(plan_level=none 时可接受)')
1147
- }
1148
-
1149
- return { ok: true, errors, warnings, planExists: true, taskCount }
1150
- }
1151
-
1152
- // ═══════════════════════════════════════════════════════════════
1153
- // 执行入口(从 run.js 迁移)
1154
- // ═══════════════════════════════════════════════════════════════
1155
-
1156
- /**
1157
- * Plan postcheck 主函数:Wave 重排 + 一致性校验 + 产物确认
1158
- *
1159
- * @param {{ cwd: string, specRoot?: string, resolveChangeDir: Function, progress?: object }} context
1160
- * @throws {Error} 校验失败时抛出
1161
- */
1162
- export async function executePlanPostcheck(context) {
1163
- const { cwd, specRoot, resolveChangeDir, progress } = context
1164
-
1165
- const specDir = specRoot || pJoin(cwd, '.sillyspec')
1166
- const changesDir = pJoin(specDir, 'changes')
1167
- if (!existsSync(changesDir)) {
1168
- console.warn(' ⚠️ 未找到 changes 目录,跳过 postcheck')
1169
- return
1170
- }
1171
-
1172
- // 找到当前变更目录(progress 由调用方从 SQLite 读取并传入;.runtime/progress.json 已废弃)
1173
- let changeDir = null
1174
- if (progress) {
1175
- changeDir = resolveChangeDir(cwd, progress, specDir)
1176
- }
1177
- if (!changeDir) {
1178
- // 回退:找最新的变更目录
1179
- const dirs = readdirSync(changesDir)
1180
- .filter(d => existsSync(pJoin(changesDir, d, 'plan.md')))
1181
- .sort().reverse()
1182
- if (dirs.length > 0) changeDir = pJoin(changesDir, dirs[0])
1183
- }
1184
- if (!changeDir) {
1185
- console.warn(' ⚠️ 未找到当前变更目录,跳过 postcheck')
1186
- return
1187
- }
1188
-
1189
- console.log(` 📂 变更目录: ${changeDir}`)
1190
-
1191
- // ── 报错聚合(坑6③):六个检查全部跑完后统一输出全部失败项,一轮 --done 暴露全部问题,
1192
- // 不再「失败一个抛一个、修一个冒一个」的迭代盲盒。各检查相互独立(都只读 changeDir 产物),
1193
- // 前置检查失败不使后续检查失真——唯一例外是 tasks/ 目录缺失时后续检查都无意义,仍提前短路。
1194
- const failures = [] // { name, errors, hint }
1195
- const printSectionWarnings = (label, warnings) => {
1196
- if (warnings.length > 0) {
1197
- console.warn(`\n⚠️ ${label}警告(不阻断):`)
1198
- for (const w of warnings) console.warn(` - ${w}`)
1199
- }
1200
- }
1201
-
1202
- // ── 1. 一致性校验 ──
1203
- const consistency = validateBlueprintConsistency(changeDir)
1204
- if (consistency.errors.length > 0) {
1205
- failures.push({ name: '蓝图一致性校验', errors: consistency.errors, hint: '请修复上述问题后重新完成此步骤。' })
1206
- }
1207
- printSectionWarnings('蓝图一致性', consistency.warnings)
1208
-
1209
- // ── 1b. 可行性校验 ──
1210
- const feasibility = validatePlanFeasibility(changeDir, context.cwd)
1211
- if (feasibility.errors.length > 0) {
1212
- failures.push({ name: 'Plan 可行性校验', errors: feasibility.errors, hint: null })
1213
- }
1214
- printSectionWarnings('Plan 可行性', feasibility.warnings)
1215
-
1216
- // ── 1c. 跨任务契约校验 ──
1217
- // 对账 consumer.expects_from ↔ provider.provides,拦截「consumer 期望字段
1218
- // 但 provider 未承诺」的契约断裂(避免到 execute/verify 才暴露成 403/500)
1219
- const crossTask = validateCrossTaskContracts(changeDir)
1220
- if (crossTask.errors.length > 0) {
1221
- failures.push({
1222
- name: '跨任务契约校验(consumer 期望的字段未被 provider 承诺)',
1223
- errors: crossTask.errors,
1224
- hint: '修复方式:要么在 provider task 的 provides.fields 补上缺失字段,要么修正 consumer task 的 expects_from.needs(确认依赖是否真实)。',
1225
- })
1226
- }
1227
-
1228
- // ── 1c-b. TaskCard 命令存在性校验 ──
1229
- // TaskCard verify/implementation 的 `npm|pnpm|yarn run <script>` 必须在 package.json
1230
- // scripts 中存在(monorepo 子包感知——读 local.yaml modules 块定位)。
1231
- // invalid → error 硬阻断,避免 execute 子代理跑死命令(design D-04 / 问题 3)。
1232
- // modules 块可选:无块时仅查根 package.json(与 scan-postcheck 历史行为一致)。
1233
- const localYamlPath = pJoin(specDir, 'local.yaml')
1234
- let taskModules = null
1235
- if (existsSync(localYamlPath)) {
1236
- taskModules = parseLocalYamlModules(readFileSync(localYamlPath, 'utf8'))
1237
- }
1238
- const taskCmds = validateTaskCommands(changeDir, context.cwd, taskModules)
1239
- if (taskCmds.errors.length > 0) {
1240
- failures.push({
1241
- name: 'TaskCard 命令存在性校验(verify/implementation 的 npm/pnpm/yarn run <script> 不存在)',
1242
- errors: taskCmds.errors,
1243
- hint: '修复方式:要么在 package.json scripts 补上缺失命令(monorepo 注意子包路径),要么修正 TaskCard 的 verify/implementation(确认命令是否真实、是否需 cd 子包)。',
1244
- })
1245
- }
1246
-
1247
- // ── 1d. design 文件覆盖对账 ──
1248
- // design.md 清单中的每个源码文件必须被某 task 的 allowed_paths 覆盖,
1249
- // 否则 execute 子代理无权改它 → 漏改(典型表现:「页面还是错的」)。
1250
- const coverage = validateDesignFileCoverage(changeDir)
1251
- for (const w of coverage.warnings) console.warn(`\n ⚠️ ${w}`)
1252
- if (coverage.errors.length > 0) {
1253
- failures.push({ name: 'design.md 文件覆盖对账(清单中的文件未被任何 task 覆盖)', errors: coverage.errors, hint: null })
1254
- }
1255
- if (coverage.designFiles.length > 0 && coverage.uncovered.length === 0) {
1256
- console.log(` ✅ design.md ${coverage.designFiles.length} 个文件全部被 task allowed_paths 覆盖`)
1257
- }
1258
-
1259
- // ── 1e. 阶段完成产物校验(plan stage contract)──
1260
- // plan 完成 gate 还会跑 stage-contract.validatePlanOutputs;为免「postcheck 通过 →
1261
- // stage gate 又报 module-impact 缺失/entry-point-wiring 未覆盖」的修一层撞一层,
1262
- // 在此把 stage contract 的 error/warning 也聚合进本轮输出。
1263
- const { validatePlanOutputs } = await import('../stage-contract.js')
1264
- if (typeof validatePlanOutputs === 'function') {
1265
- const contract = validatePlanOutputs(context.cwd, basename(changeDir), { specRoot })
1266
- if (contract.errors.length > 0) {
1267
- failures.push({
1268
- name: 'plan 阶段产物契约校验(stage-contract validatePlanOutputs)',
1269
- errors: contract.errors,
1270
- hint: '修复方式:补缺失产物(如 module-impact.md)、在 design.md 明示不改理由、或修正 task allowed_paths 覆盖 design.md 提及的入口文件。',
1271
- })
1272
- }
1273
- if (contract.warnings.length > 0) {
1274
- for (const w of contract.warnings) {
1275
- console.warn(`\n ⚠️ ${w}`)
1276
- }
1277
- }
1278
- }
1279
-
1280
- // ── 聚合输出:一轮 --done 暴露全部失败项(坑6③)──
1281
- if (failures.length > 0) {
1282
- console.error(`\n❌ plan postcheck 失败(${failures.length} 类问题,已全部列出——一次修复后重跑,无需逐个迭代):`)
1283
- for (const f of failures) {
1284
- console.error(`\n 【${f.name}】`)
1285
- for (const err of f.errors) console.error(` - ${err}`)
1286
- if (f.hint) console.error(` ${f.hint}`)
1287
- }
1288
- throw new Error(`planPostcheck: ${failures.length} 组校验失败(${failures.map(f => f.name).join(';')})`)
1289
- }
1290
-
1291
- // ── 2. Wave 重排 ──
1292
- const tasksDir = pJoin(changeDir, 'tasks')
1293
- if (existsSync(tasksDir)) {
1294
- const taskFiles = readdirSync(tasksDir).filter(f => /^task-\d+\.md$/.test(f))
1295
- const depMap = collectTaskDepMap(tasksDir)
1296
-
1297
- const { waves, error: topoError } = topoSortWaves(depMap)
1298
- if (topoError) {
1299
- console.error(`\n❌ Wave 重排失败: ${topoError}`)
1300
- throw new Error('planPostcheck: ' + topoError)
1301
- }
1302
-
1303
- console.log('\n 📊 Wave 分组(基于 depends_on 拓扑排序):')
1304
- waves.forEach((wave, i) => {
1305
- console.log(` Wave ${i + 1}: ${wave.join(', ')}`)
1306
- })
1307
-
1308
- // 比较 plan.md 现有 Wave 分组 + 依赖方向硬校验(坑 wave-dep-direction-unchecked,
1309
- // 2026-08-24 用户反馈二期:主控手排 Wave 与拓扑比对只警告不阻断,而真正的正确性违规
1310
- // ——depends_on 落同 Wave / 后置 Wave——此前完全没有校验)
1311
- if (taskFiles.length > 0) {
1312
- const planPath = pJoin(changeDir, 'plan.md')
1313
- if (existsSync(planPath)) {
1314
- const planContent = readFileSync(planPath, 'utf8')
1315
- if (/##\s*Wave\s+\d/i.test(planContent)) {
1316
- const existingWaves = []
1317
- const lines = planContent.split('\n')
1318
- let currentWaveTasks = null
1319
- for (const line of lines) {
1320
- const wm = line.match(/^#+\s*Wave\s+(\d+)/i)
1321
- if (wm) {
1322
- if (currentWaveTasks) existingWaves.push(currentWaveTasks)
1323
- currentWaveTasks = []
1324
- continue
1325
- }
1326
- // 非 Wave 标题行(## 自检 等)退出当前 Wave 段,避免自检 checkbox
1327
- // 被混入 task 列表导致 Wave 结构比对误判。
1328
- if (/^#+\s/.test(line)) {
1329
- if (currentWaveTasks) existingWaves.push(currentWaveTasks)
1330
- currentWaveTasks = null
1331
- continue
1332
- }
1333
- // 2026-08-20-task-truth-unify:Wave 段下纯 ID 引用行(- task-NN);旧 checkbox 行同收。
1334
- // 编号补零对齐卡片口径(坑 wave-ref-unpadded,同 parseTaskWavesFromPlan)
1335
- const tm = line.match(/^[-*]\s+(?:\[[ x]\]\s*)?task-(\d+)\s*[::\s]*$/i)
1336
- || line.match(/^[-*]\s*\[[ x]\]\s*task-(\d+)/i)
1337
- if (tm && currentWaveTasks) {
1338
- currentWaveTasks.push(`task-${String(tm[1]).padStart(2, '0')}`)
1339
- }
1340
- }
1341
- if (currentWaveTasks) existingWaves.push(currentWaveTasks)
1342
-
1343
- // ── 依赖方向硬校验 ──
1344
- // Wave 契约(execute.js Wave 要点 1):同一 Wave 的子代理强制并行;有依赖的 task
1345
- // 必须落在其依赖的后置 Wave。同 Wave / 后置 Wave 引用都是正确性违规(并行破坏依赖
1346
- // / 顺序颠倒),硬拦;仅分组数差异(手工过度串行化)合法,保留下方 warning。
1347
- const waveOf = new Map()
1348
- existingWaves.forEach((ws, i) => { for (const t of ws) waveOf.set(t, i) })
1349
- const directionViolations = []
1350
- for (const [taskId, deps] of depMap) {
1351
- const w = waveOf.get(taskId)
1352
- if (w === undefined) continue // 卡片未列入任何 Wave → 由 validatePlanForExecute 覆盖校验兜底
1353
- for (const dep of deps) {
1354
- const dw = waveOf.get(dep)
1355
- if (dw === undefined) continue // 依赖不存在的 task → feasibility depends_on 引用校验兜底
1356
- if (dw === w) directionViolations.push(`${taskId} depends_on ${dep},但两者同在 Wave ${w + 1}(同 Wave 强制并行,依赖被破坏)`)
1357
- else if (dw > w) directionViolations.push(`${taskId} depends_on ${dep},但 ${dep} 在后置 Wave ${dw + 1}(顺序颠倒)`)
1358
- }
1359
- }
1360
- if (directionViolations.length > 0) {
1361
- console.error(`\n❌ Wave 依赖方向违规(${directionViolations.length} 处):`)
1362
- for (const v of directionViolations) console.error(` ${v}`)
1363
- console.error(' 解法:sillyspec plan-adopt-waves --change <变更名> 一键按 depends_on 拓扑重排 plan.md Wave 段,或手动调整分组')
1364
- throw new Error('planPostcheck: Wave 依赖方向违规(depends_on 同 Wave / 后置 Wave)——' + directionViolations.join(';'))
1365
- }
1366
-
1367
- const sameStructure = waves.length === existingWaves.length &&
1368
- waves.every((w, i) => {
1369
- const a = [...w].sort().join(',')
1370
- const b = [...(existingWaves[i] || [])].sort().join(',')
1371
- return a === b
1372
- })
1373
-
1374
- if (sameStructure) {
1375
- console.log(' ✅ Wave 分组与拓扑排序一致,无需更新 plan.md')
1376
- } else {
1377
- console.log(' ⚠️ Wave 分组与拓扑排序不一致(依赖方向已校验合法——手工比拓扑更细的串行化是安全做法,可保持现状)')
1378
- console.log(' 标准分组见上方 📊;如需对齐:sillyspec plan-adopt-waves --change <变更名>(重排 plan.md Wave 段并同步任务总表 W 列)')
1379
- }
1380
- }
1381
- }
1382
- }
1383
- }
1384
-
1385
- // ── 3. 产物确认 ──
1386
- const artifacts = validatePlanArtifacts(changeDir)
1387
- if (!artifacts.ok) {
1388
- for (const err of artifacts.errors) console.error(`❌ ${err}`)
1389
- throw new Error('planPostcheck: artifact validation failed')
1390
- }
1391
- console.log('\n ✅ plan.md 存在')
1392
-
1393
- if (artifacts.taskCount > 0) {
1394
- console.log(` ✅ tasks/ 目录有 ${artifacts.taskCount} 个 TaskCard 文件`)
1395
- }
1396
-
1397
- console.log('\n ✅ Plan postcheck 完成')
1398
- }