sillyspec 3.27.11 → 3.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1219) hide show
  1. package/.claude/skills/sillyspec-execute/SKILL.md +1 -1
  2. package/README.md +3 -2
  3. package/package.json +1 -1
  4. package/src/agent-session-log.js +77 -10
  5. package/src/change-delete.js +181 -0
  6. package/src/config-schema.js +2 -2
  7. package/src/contract-matrix.js +15 -2
  8. package/src/docs-check.js +126 -0
  9. package/src/doctor-diagnostics.js +64 -1
  10. package/src/endpoint-extractor.js +107 -28
  11. package/src/index.js +208 -13
  12. package/src/init.js +104 -27
  13. package/src/machine-interface.js +63 -0
  14. package/src/module-changelog.js +116 -0
  15. package/src/progress/change-registry.js +28 -0
  16. package/src/progress/shared.js +6 -0
  17. package/src/progress/stage-machine.js +191 -9
  18. package/src/progress.js +6 -0
  19. package/src/run/command.js +26 -1
  20. package/src/run/complete-handlers.js +42 -4
  21. package/src/run/complete.js +12 -4
  22. package/src/run/prompt.js +12 -1
  23. package/src/run/quick-audit.js +98 -0
  24. package/src/run/shared.js +86 -0
  25. package/src/run/stage.js +18 -11
  26. package/src/spec-sync.js +191 -14
  27. package/src/stages/archive.js +5 -0
  28. package/src/stages/execute.js +7 -2
  29. package/src/sync.js +575 -21
  30. package/src/task-review.js +51 -4
  31. package/src/verify-postcheck.js +60 -8
  32. package/src/verify-probes.js +3 -0
  33. package/src/workflow.js +4 -0
  34. package/src/worktree-apply.js +4 -4
  35. package/src/worktree.js +6 -4
  36. package/{.worktrees/542c4415/templates/claude-instruction.md → templates/agents-instruction.md} +2 -2
  37. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  38. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  39. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  40. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  41. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  42. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  43. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  44. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  45. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-export/SKILL.md +0 -57
  46. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-init/SKILL.md +0 -177
  47. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  48. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  49. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  50. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  51. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  52. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-state/SKILL.md +0 -64
  53. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-status/SKILL.md +0 -54
  54. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  55. package/.claude/worktrees/sillyspec-data-model-research/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  56. package/.claude/worktrees/sillyspec-data-model-research/.gitattributes +0 -2
  57. package/.claude/worktrees/sillyspec-data-model-research/.husky/pre-push +0 -20
  58. package/.claude/worktrees/sillyspec-data-model-research/README.md +0 -203
  59. package/.claude/worktrees/sillyspec-data-model-research/SKILL.md +0 -91
  60. package/.claude/worktrees/sillyspec-data-model-research/bin/sillyspec.js +0 -2
  61. package/.claude/worktrees/sillyspec-data-model-research/logo.jpg +0 -0
  62. package/.claude/worktrees/sillyspec-data-model-research/package-lock.json +0 -977
  63. package/.claude/worktrees/sillyspec-data-model-research/package.json +0 -39
  64. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  65. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  66. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/favicon.jpg +0 -0
  67. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/index.html +0 -16
  68. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/logo.jpg +0 -0
  69. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-dashboard.html +0 -836
  70. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/dist/prototype-overview.html +0 -256
  71. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/package.json +0 -25
  72. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/executor.js +0 -95
  73. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/index.js +0 -679
  74. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/parser.js +0 -526
  75. package/.claude/worktrees/sillyspec-data-model-research/packages/dashboard/server/watcher.js +0 -357
  76. package/.claude/worktrees/sillyspec-data-model-research/src/agent-session-log.js +0 -803
  77. package/.claude/worktrees/sillyspec-data-model-research/src/change-list.js +0 -290
  78. package/.claude/worktrees/sillyspec-data-model-research/src/change-risk-profile.js +0 -270
  79. package/.claude/worktrees/sillyspec-data-model-research/src/check-primitives.js +0 -65
  80. package/.claude/worktrees/sillyspec-data-model-research/src/classify-change.js +0 -109
  81. package/.claude/worktrees/sillyspec-data-model-research/src/commit-suggest.js +0 -202
  82. package/.claude/worktrees/sillyspec-data-model-research/src/config-cat.js +0 -88
  83. package/.claude/worktrees/sillyspec-data-model-research/src/config-schema.js +0 -328
  84. package/.claude/worktrees/sillyspec-data-model-research/src/constants.js +0 -97
  85. package/.claude/worktrees/sillyspec-data-model-research/src/contract-matrix.js +0 -480
  86. package/.claude/worktrees/sillyspec-data-model-research/src/datetime.js +0 -20
  87. package/.claude/worktrees/sillyspec-data-model-research/src/db-engine.js +0 -55
  88. package/.claude/worktrees/sillyspec-data-model-research/src/db.js +0 -381
  89. package/.claude/worktrees/sillyspec-data-model-research/src/decision-distill.js +0 -517
  90. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/local-agent.js +0 -155
  91. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/backends/sillyhub-mcp.js +0 -245
  92. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/probe.js +0 -246
  93. package/.claude/worktrees/sillyspec-data-model-research/src/dispatch/strategy.js +0 -121
  94. package/.claude/worktrees/sillyspec-data-model-research/src/docs-check.js +0 -825
  95. package/.claude/worktrees/sillyspec-data-model-research/src/docs-debt.js +0 -393
  96. package/.claude/worktrees/sillyspec-data-model-research/src/docs-gate.js +0 -107
  97. package/.claude/worktrees/sillyspec-data-model-research/src/doctor-diagnostics.js +0 -1099
  98. package/.claude/worktrees/sillyspec-data-model-research/src/endpoint-extractor.js +0 -420
  99. package/.claude/worktrees/sillyspec-data-model-research/src/foreign-declared.js +0 -78
  100. package/.claude/worktrees/sillyspec-data-model-research/src/fs-atomic.js +0 -73
  101. package/.claude/worktrees/sillyspec-data-model-research/src/git-helper.js +0 -150
  102. package/.claude/worktrees/sillyspec-data-model-research/src/hooks/claude-pre-tool-use.cjs +0 -130
  103. package/.claude/worktrees/sillyspec-data-model-research/src/hooks/worktree-guard.js +0 -892
  104. package/.claude/worktrees/sillyspec-data-model-research/src/index.js +0 -2798
  105. package/.claude/worktrees/sillyspec-data-model-research/src/init.js +0 -626
  106. package/.claude/worktrees/sillyspec-data-model-research/src/knowledge-match.js +0 -231
  107. package/.claude/worktrees/sillyspec-data-model-research/src/local-detect.js +0 -128
  108. package/.claude/worktrees/sillyspec-data-model-research/src/local-register.js +0 -104
  109. package/.claude/worktrees/sillyspec-data-model-research/src/machine-interface.js +0 -543
  110. package/.claude/worktrees/sillyspec-data-model-research/src/migrate.js +0 -127
  111. package/.claude/worktrees/sillyspec-data-model-research/src/module-impact.js +0 -166
  112. package/.claude/worktrees/sillyspec-data-model-research/src/module-resolve.js +0 -222
  113. package/.claude/worktrees/sillyspec-data-model-research/src/modules.js +0 -580
  114. package/.claude/worktrees/sillyspec-data-model-research/src/progress/change-registry.js +0 -336
  115. package/.claude/worktrees/sillyspec-data-model-research/src/progress/consistency-doctor.js +0 -355
  116. package/.claude/worktrees/sillyspec-data-model-research/src/progress/shared.js +0 -36
  117. package/.claude/worktrees/sillyspec-data-model-research/src/progress/stage-machine.js +0 -594
  118. package/.claude/worktrees/sillyspec-data-model-research/src/progress/step-store.js +0 -265
  119. package/.claude/worktrees/sillyspec-data-model-research/src/progress.js +0 -1304
  120. package/.claude/worktrees/sillyspec-data-model-research/src/quick-recommend.js +0 -115
  121. package/.claude/worktrees/sillyspec-data-model-research/src/quicklog.js +0 -852
  122. package/.claude/worktrees/sillyspec-data-model-research/src/review-tier.js +0 -77
  123. package/.claude/worktrees/sillyspec-data-model-research/src/run/command.js +0 -1595
  124. package/.claude/worktrees/sillyspec-data-model-research/src/run/complete-handlers.js +0 -1552
  125. package/.claude/worktrees/sillyspec-data-model-research/src/run/complete.js +0 -1259
  126. package/.claude/worktrees/sillyspec-data-model-research/src/run/concurrent-detect.js +0 -156
  127. package/.claude/worktrees/sillyspec-data-model-research/src/run/gates.js +0 -1084
  128. package/.claude/worktrees/sillyspec-data-model-research/src/run/multi-repo-context.js +0 -208
  129. package/.claude/worktrees/sillyspec-data-model-research/src/run/next.js +0 -128
  130. package/.claude/worktrees/sillyspec-data-model-research/src/run/prompt.js +0 -843
  131. package/.claude/worktrees/sillyspec-data-model-research/src/run/quick-audit.js +0 -186
  132. package/.claude/worktrees/sillyspec-data-model-research/src/run/scan-profile.js +0 -269
  133. package/.claude/worktrees/sillyspec-data-model-research/src/run/shared.js +0 -1562
  134. package/.claude/worktrees/sillyspec-data-model-research/src/run/stage.js +0 -584
  135. package/.claude/worktrees/sillyspec-data-model-research/src/run.js +0 -23
  136. package/.claude/worktrees/sillyspec-data-model-research/src/scan-diff.js +0 -388
  137. package/.claude/worktrees/sillyspec-data-model-research/src/scan-postcheck.js +0 -512
  138. package/.claude/worktrees/sillyspec-data-model-research/src/scan-staleness.js +0 -95
  139. package/.claude/worktrees/sillyspec-data-model-research/src/setup.js +0 -414
  140. package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/client.js +0 -597
  141. package/.claude/worktrees/sillyspec-data-model-research/src/sillyhub-mcp/config.js +0 -62
  142. package/.claude/worktrees/sillyspec-data-model-research/src/spec-dir-typo.js +0 -50
  143. package/.claude/worktrees/sillyspec-data-model-research/src/spec-sync.js +0 -358
  144. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-engine.js +0 -171
  145. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract-spec.js +0 -550
  146. package/.claude/worktrees/sillyspec-data-model-research/src/stage-contract.js +0 -889
  147. package/.claude/worktrees/sillyspec-data-model-research/src/stage-review.js +0 -597
  148. package/.claude/worktrees/sillyspec-data-model-research/src/stages/archive.js +0 -199
  149. package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm-auto.js +0 -236
  150. package/.claude/worktrees/sillyspec-data-model-research/src/stages/brainstorm.js +0 -617
  151. package/.claude/worktrees/sillyspec-data-model-research/src/stages/cmd-existence.js +0 -145
  152. package/.claude/worktrees/sillyspec-data-model-research/src/stages/doctor.js +0 -540
  153. package/.claude/worktrees/sillyspec-data-model-research/src/stages/execute.js +0 -1275
  154. package/.claude/worktrees/sillyspec-data-model-research/src/stages/explore.js +0 -43
  155. package/.claude/worktrees/sillyspec-data-model-research/src/stages/index.js +0 -29
  156. package/.claude/worktrees/sillyspec-data-model-research/src/stages/knowledge.js +0 -514
  157. package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan-postcheck.js +0 -1344
  158. package/.claude/worktrees/sillyspec-data-model-research/src/stages/plan.js +0 -650
  159. package/.claude/worktrees/sillyspec-data-model-research/src/stages/quick.js +0 -167
  160. package/.claude/worktrees/sillyspec-data-model-research/src/stages/scan.js +0 -608
  161. package/.claude/worktrees/sillyspec-data-model-research/src/stages/status.js +0 -64
  162. package/.claude/worktrees/sillyspec-data-model-research/src/stages/verify.js +0 -246
  163. package/.claude/worktrees/sillyspec-data-model-research/src/sync.js +0 -1470
  164. package/.claude/worktrees/sillyspec-data-model-research/src/task-review.js +0 -1498
  165. package/.claude/worktrees/sillyspec-data-model-research/src/taskcard.js +0 -210
  166. package/.claude/worktrees/sillyspec-data-model-research/src/verify-postcheck.js +0 -1718
  167. package/.claude/worktrees/sillyspec-data-model-research/src/verify-probes.js +0 -277
  168. package/.claude/worktrees/sillyspec-data-model-research/src/version.js +0 -19
  169. package/.claude/worktrees/sillyspec-data-model-research/src/workflow.js +0 -600
  170. package/.claude/worktrees/sillyspec-data-model-research/src/workspace.js +0 -125
  171. package/.claude/worktrees/sillyspec-data-model-research/src/worktree-apply.js +0 -1446
  172. package/.claude/worktrees/sillyspec-data-model-research/src/worktree-deps.js +0 -576
  173. package/.claude/worktrees/sillyspec-data-model-research/src/worktree.js +0 -1715
  174. package/.claude/worktrees/sillyspec-data-model-research/templates/claude-instruction.md +0 -23
  175. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/taskcard-rules.md +0 -28
  176. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/testcase-design.md +0 -12
  177. package/.claude/worktrees/sillyspec-data-model-research/templates/prompts/verify-probes.md +0 -32
  178. package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/archive-impact.yaml +0 -79
  179. package/.claude/worktrees/sillyspec-data-model-research/templates/workflows/scan-docs.yaml +0 -132
  180. package/.npmrc-temp +0 -1
  181. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  182. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  183. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  184. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  185. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  186. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  187. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  188. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  189. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-export/SKILL.md +0 -57
  190. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-init/SKILL.md +0 -177
  191. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  192. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  193. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  194. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  195. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  196. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  197. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-state/SKILL.md +0 -64
  198. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-status/SKILL.md +0 -54
  199. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  200. package/.worktrees/2c37b1d7/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  201. package/.worktrees/2c37b1d7/.claude/skills/verify-per-user/SKILL.md +0 -6
  202. package/.worktrees/2c37b1d7/.gitattributes +0 -2
  203. package/.worktrees/2c37b1d7/.husky/pre-push +0 -20
  204. package/.worktrees/2c37b1d7/README.md +0 -203
  205. package/.worktrees/2c37b1d7/SKILL.md +0 -91
  206. package/.worktrees/2c37b1d7/architecture-analysis.md +0 -448
  207. package/.worktrees/2c37b1d7/bin/sillyspec.js +0 -2
  208. package/.worktrees/2c37b1d7/eval/README.md +0 -86
  209. package/.worktrees/2c37b1d7/eval/eval.config.json +0 -28
  210. package/.worktrees/2c37b1d7/eval/lib/adapters/cli.mjs +0 -63
  211. package/.worktrees/2c37b1d7/eval/lib/adapters/dryrun.mjs +0 -27
  212. package/.worktrees/2c37b1d7/eval/lib/config.mjs +0 -82
  213. package/.worktrees/2c37b1d7/eval/lib/db.mjs +0 -76
  214. package/.worktrees/2c37b1d7/eval/lib/report.mjs +0 -120
  215. package/.worktrees/2c37b1d7/eval/lib/runner.mjs +0 -157
  216. package/.worktrees/2c37b1d7/eval/lib/tasks.mjs +0 -73
  217. package/.worktrees/2c37b1d7/eval/lib/util.mjs +0 -107
  218. package/.worktrees/2c37b1d7/eval/lib/workdir.mjs +0 -30
  219. package/.worktrees/2c37b1d7/eval/run.mjs +0 -83
  220. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/files/package.json +0 -6
  221. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  222. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/task.json +0 -6
  223. package/.worktrees/2c37b1d7/eval/tasks/001-slugify/verify.mjs +0 -28
  224. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/package.json +0 -6
  225. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  226. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  227. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/task.json +0 -6
  228. package/.worktrees/2c37b1d7/eval/tasks/002-each-day/verify.mjs +0 -31
  229. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  230. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/files/package.json +0 -6
  231. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  232. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/task.json +0 -6
  233. package/.worktrees/2c37b1d7/eval/tasks/003-word-report/verify.mjs +0 -38
  234. package/.worktrees/2c37b1d7/logo.jpg +0 -0
  235. package/.worktrees/2c37b1d7/package-lock.json +0 -977
  236. package/.worktrees/2c37b1d7/package.json +0 -41
  237. package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  238. package/.worktrees/2c37b1d7/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  239. package/.worktrees/2c37b1d7/packages/dashboard/dist/favicon.jpg +0 -0
  240. package/.worktrees/2c37b1d7/packages/dashboard/dist/index.html +0 -16
  241. package/.worktrees/2c37b1d7/packages/dashboard/dist/logo.jpg +0 -0
  242. package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-dashboard.html +0 -836
  243. package/.worktrees/2c37b1d7/packages/dashboard/dist/prototype-overview.html +0 -256
  244. package/.worktrees/2c37b1d7/packages/dashboard/package.json +0 -25
  245. package/.worktrees/2c37b1d7/packages/dashboard/server/executor.js +0 -95
  246. package/.worktrees/2c37b1d7/packages/dashboard/server/index.js +0 -679
  247. package/.worktrees/2c37b1d7/packages/dashboard/server/parser.js +0 -526
  248. package/.worktrees/2c37b1d7/packages/dashboard/server/watcher.js +0 -357
  249. package/.worktrees/2c37b1d7/src/agent-session-log.js +0 -803
  250. package/.worktrees/2c37b1d7/src/change-list.js +0 -290
  251. package/.worktrees/2c37b1d7/src/change-risk-profile.js +0 -339
  252. package/.worktrees/2c37b1d7/src/check-primitives.js +0 -65
  253. package/.worktrees/2c37b1d7/src/classify-change.js +0 -109
  254. package/.worktrees/2c37b1d7/src/commit-suggest.js +0 -202
  255. package/.worktrees/2c37b1d7/src/config-cat.js +0 -88
  256. package/.worktrees/2c37b1d7/src/config-schema.js +0 -328
  257. package/.worktrees/2c37b1d7/src/constants.js +0 -97
  258. package/.worktrees/2c37b1d7/src/contract-matrix.js +0 -533
  259. package/.worktrees/2c37b1d7/src/datetime.js +0 -20
  260. package/.worktrees/2c37b1d7/src/db-engine.js +0 -55
  261. package/.worktrees/2c37b1d7/src/db.js +0 -381
  262. package/.worktrees/2c37b1d7/src/decision-distill.js +0 -517
  263. package/.worktrees/2c37b1d7/src/dispatch/backends/local-agent.js +0 -155
  264. package/.worktrees/2c37b1d7/src/dispatch/backends/sillyhub-mcp.js +0 -245
  265. package/.worktrees/2c37b1d7/src/dispatch/probe.js +0 -246
  266. package/.worktrees/2c37b1d7/src/dispatch/strategy.js +0 -121
  267. package/.worktrees/2c37b1d7/src/docs-check.js +0 -825
  268. package/.worktrees/2c37b1d7/src/docs-debt.js +0 -393
  269. package/.worktrees/2c37b1d7/src/docs-gate.js +0 -107
  270. package/.worktrees/2c37b1d7/src/doctor-diagnostics.js +0 -1099
  271. package/.worktrees/2c37b1d7/src/endpoint-extractor.js +0 -409
  272. package/.worktrees/2c37b1d7/src/foreign-declared.js +0 -155
  273. package/.worktrees/2c37b1d7/src/fs-atomic.js +0 -73
  274. package/.worktrees/2c37b1d7/src/git-helper.js +0 -150
  275. package/.worktrees/2c37b1d7/src/hooks/claude-pre-tool-use.cjs +0 -130
  276. package/.worktrees/2c37b1d7/src/hooks/worktree-guard.js +0 -892
  277. package/.worktrees/2c37b1d7/src/index.js +0 -2854
  278. package/.worktrees/2c37b1d7/src/init.js +0 -626
  279. package/.worktrees/2c37b1d7/src/knowledge-match.js +0 -231
  280. package/.worktrees/2c37b1d7/src/local-detect.js +0 -128
  281. package/.worktrees/2c37b1d7/src/local-register.js +0 -104
  282. package/.worktrees/2c37b1d7/src/machine-interface.js +0 -543
  283. package/.worktrees/2c37b1d7/src/migrate.js +0 -127
  284. package/.worktrees/2c37b1d7/src/module-impact.js +0 -166
  285. package/.worktrees/2c37b1d7/src/module-resolve.js +0 -222
  286. package/.worktrees/2c37b1d7/src/modules.js +0 -580
  287. package/.worktrees/2c37b1d7/src/plan-adopt-waves.js +0 -126
  288. package/.worktrees/2c37b1d7/src/progress/change-registry.js +0 -336
  289. package/.worktrees/2c37b1d7/src/progress/consistency-doctor.js +0 -355
  290. package/.worktrees/2c37b1d7/src/progress/shared.js +0 -36
  291. package/.worktrees/2c37b1d7/src/progress/stage-machine.js +0 -594
  292. package/.worktrees/2c37b1d7/src/progress/step-store.js +0 -265
  293. package/.worktrees/2c37b1d7/src/progress.js +0 -1304
  294. package/.worktrees/2c37b1d7/src/quick-recommend.js +0 -115
  295. package/.worktrees/2c37b1d7/src/quicklog.js +0 -883
  296. package/.worktrees/2c37b1d7/src/review-tier.js +0 -77
  297. package/.worktrees/2c37b1d7/src/run/command.js +0 -1641
  298. package/.worktrees/2c37b1d7/src/run/complete-handlers.js +0 -1552
  299. package/.worktrees/2c37b1d7/src/run/complete.js +0 -1259
  300. package/.worktrees/2c37b1d7/src/run/concurrent-detect.js +0 -156
  301. package/.worktrees/2c37b1d7/src/run/gates.js +0 -1111
  302. package/.worktrees/2c37b1d7/src/run/multi-repo-context.js +0 -208
  303. package/.worktrees/2c37b1d7/src/run/next.js +0 -128
  304. package/.worktrees/2c37b1d7/src/run/prompt.js +0 -843
  305. package/.worktrees/2c37b1d7/src/run/quick-audit.js +0 -186
  306. package/.worktrees/2c37b1d7/src/run/scan-profile.js +0 -269
  307. package/.worktrees/2c37b1d7/src/run/shared.js +0 -1562
  308. package/.worktrees/2c37b1d7/src/run/stage.js +0 -587
  309. package/.worktrees/2c37b1d7/src/run.js +0 -23
  310. package/.worktrees/2c37b1d7/src/scan-diff.js +0 -388
  311. package/.worktrees/2c37b1d7/src/scan-postcheck.js +0 -524
  312. package/.worktrees/2c37b1d7/src/scan-staleness.js +0 -95
  313. package/.worktrees/2c37b1d7/src/setup.js +0 -414
  314. package/.worktrees/2c37b1d7/src/sillyhub-mcp/client.js +0 -597
  315. package/.worktrees/2c37b1d7/src/sillyhub-mcp/config.js +0 -62
  316. package/.worktrees/2c37b1d7/src/spec-dir-typo.js +0 -50
  317. package/.worktrees/2c37b1d7/src/spec-sync.js +0 -358
  318. package/.worktrees/2c37b1d7/src/stage-contract-engine.js +0 -171
  319. package/.worktrees/2c37b1d7/src/stage-contract-spec.js +0 -551
  320. package/.worktrees/2c37b1d7/src/stage-contract.js +0 -948
  321. package/.worktrees/2c37b1d7/src/stage-review.js +0 -597
  322. package/.worktrees/2c37b1d7/src/stages/archive.js +0 -199
  323. package/.worktrees/2c37b1d7/src/stages/brainstorm-auto.js +0 -285
  324. package/.worktrees/2c37b1d7/src/stages/brainstorm.js +0 -624
  325. package/.worktrees/2c37b1d7/src/stages/cmd-existence.js +0 -145
  326. package/.worktrees/2c37b1d7/src/stages/doctor.js +0 -540
  327. package/.worktrees/2c37b1d7/src/stages/execute.js +0 -1277
  328. package/.worktrees/2c37b1d7/src/stages/explore.js +0 -43
  329. package/.worktrees/2c37b1d7/src/stages/index.js +0 -29
  330. package/.worktrees/2c37b1d7/src/stages/knowledge.js +0 -514
  331. package/.worktrees/2c37b1d7/src/stages/plan-postcheck.js +0 -1398
  332. package/.worktrees/2c37b1d7/src/stages/plan.js +0 -655
  333. package/.worktrees/2c37b1d7/src/stages/quick.js +0 -167
  334. package/.worktrees/2c37b1d7/src/stages/scan.js +0 -608
  335. package/.worktrees/2c37b1d7/src/stages/status.js +0 -64
  336. package/.worktrees/2c37b1d7/src/stages/verify.js +0 -246
  337. package/.worktrees/2c37b1d7/src/sync.js +0 -1470
  338. package/.worktrees/2c37b1d7/src/task-review.js +0 -1498
  339. package/.worktrees/2c37b1d7/src/taskcard-placeholders.js +0 -21
  340. package/.worktrees/2c37b1d7/src/taskcard.js +0 -250
  341. package/.worktrees/2c37b1d7/src/verify-postcheck.js +0 -1718
  342. package/.worktrees/2c37b1d7/src/verify-probes.js +0 -327
  343. package/.worktrees/2c37b1d7/src/version.js +0 -19
  344. package/.worktrees/2c37b1d7/src/workflow.js +0 -600
  345. package/.worktrees/2c37b1d7/src/workspace.js +0 -125
  346. package/.worktrees/2c37b1d7/src/worktree-apply.js +0 -1611
  347. package/.worktrees/2c37b1d7/src/worktree-deps.js +0 -668
  348. package/.worktrees/2c37b1d7/src/worktree.js +0 -1849
  349. package/.worktrees/2c37b1d7/templates/claude-instruction.md +0 -23
  350. package/.worktrees/2c37b1d7/templates/prompts/taskcard-rules.md +0 -29
  351. package/.worktrees/2c37b1d7/templates/prompts/testcase-design.md +0 -12
  352. package/.worktrees/2c37b1d7/templates/prompts/verify-probes.md +0 -32
  353. package/.worktrees/2c37b1d7/templates/workflows/archive-impact.yaml +0 -79
  354. package/.worktrees/2c37b1d7/templates/workflows/scan-docs.yaml +0 -132
  355. package/.worktrees/542c4415/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  356. package/.worktrees/542c4415/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  357. package/.worktrees/542c4415/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  358. package/.worktrees/542c4415/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  359. package/.worktrees/542c4415/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  360. package/.worktrees/542c4415/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  361. package/.worktrees/542c4415/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  362. package/.worktrees/542c4415/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  363. package/.worktrees/542c4415/.claude/skills/sillyspec-export/SKILL.md +0 -57
  364. package/.worktrees/542c4415/.claude/skills/sillyspec-init/SKILL.md +0 -177
  365. package/.worktrees/542c4415/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  366. package/.worktrees/542c4415/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  367. package/.worktrees/542c4415/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  368. package/.worktrees/542c4415/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  369. package/.worktrees/542c4415/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  370. package/.worktrees/542c4415/.claude/skills/sillyspec-state/SKILL.md +0 -64
  371. package/.worktrees/542c4415/.claude/skills/sillyspec-status/SKILL.md +0 -54
  372. package/.worktrees/542c4415/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  373. package/.worktrees/542c4415/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  374. package/.worktrees/542c4415/.gitattributes +0 -2
  375. package/.worktrees/542c4415/.husky/pre-push +0 -20
  376. package/.worktrees/542c4415/README.md +0 -203
  377. package/.worktrees/542c4415/SKILL.md +0 -91
  378. package/.worktrees/542c4415/architecture-analysis.md +0 -448
  379. package/.worktrees/542c4415/bin/sillyspec.js +0 -2
  380. package/.worktrees/542c4415/eval/README.md +0 -86
  381. package/.worktrees/542c4415/eval/eval.config.json +0 -28
  382. package/.worktrees/542c4415/eval/lib/adapters/cli.mjs +0 -63
  383. package/.worktrees/542c4415/eval/lib/adapters/dryrun.mjs +0 -27
  384. package/.worktrees/542c4415/eval/lib/config.mjs +0 -82
  385. package/.worktrees/542c4415/eval/lib/db.mjs +0 -76
  386. package/.worktrees/542c4415/eval/lib/report.mjs +0 -120
  387. package/.worktrees/542c4415/eval/lib/runner.mjs +0 -157
  388. package/.worktrees/542c4415/eval/lib/tasks.mjs +0 -73
  389. package/.worktrees/542c4415/eval/lib/util.mjs +0 -107
  390. package/.worktrees/542c4415/eval/lib/workdir.mjs +0 -30
  391. package/.worktrees/542c4415/eval/run.mjs +0 -83
  392. package/.worktrees/542c4415/eval/tasks/001-slugify/files/package.json +0 -6
  393. package/.worktrees/542c4415/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  394. package/.worktrees/542c4415/eval/tasks/001-slugify/task.json +0 -6
  395. package/.worktrees/542c4415/eval/tasks/001-slugify/verify.mjs +0 -28
  396. package/.worktrees/542c4415/eval/tasks/002-each-day/files/package.json +0 -6
  397. package/.worktrees/542c4415/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  398. package/.worktrees/542c4415/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  399. package/.worktrees/542c4415/eval/tasks/002-each-day/task.json +0 -6
  400. package/.worktrees/542c4415/eval/tasks/002-each-day/verify.mjs +0 -31
  401. package/.worktrees/542c4415/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  402. package/.worktrees/542c4415/eval/tasks/003-word-report/files/package.json +0 -6
  403. package/.worktrees/542c4415/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  404. package/.worktrees/542c4415/eval/tasks/003-word-report/task.json +0 -6
  405. package/.worktrees/542c4415/eval/tasks/003-word-report/verify.mjs +0 -38
  406. package/.worktrees/542c4415/logo.jpg +0 -0
  407. package/.worktrees/542c4415/package-lock.json +0 -977
  408. package/.worktrees/542c4415/package.json +0 -41
  409. package/.worktrees/542c4415/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  410. package/.worktrees/542c4415/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  411. package/.worktrees/542c4415/packages/dashboard/dist/favicon.jpg +0 -0
  412. package/.worktrees/542c4415/packages/dashboard/dist/index.html +0 -16
  413. package/.worktrees/542c4415/packages/dashboard/dist/logo.jpg +0 -0
  414. package/.worktrees/542c4415/packages/dashboard/dist/prototype-dashboard.html +0 -836
  415. package/.worktrees/542c4415/packages/dashboard/dist/prototype-overview.html +0 -256
  416. package/.worktrees/542c4415/packages/dashboard/package.json +0 -25
  417. package/.worktrees/542c4415/packages/dashboard/server/executor.js +0 -95
  418. package/.worktrees/542c4415/packages/dashboard/server/index.js +0 -679
  419. package/.worktrees/542c4415/packages/dashboard/server/parser.js +0 -526
  420. package/.worktrees/542c4415/packages/dashboard/server/watcher.js +0 -357
  421. package/.worktrees/542c4415/src/agent-session-log.js +0 -803
  422. package/.worktrees/542c4415/src/change-list.js +0 -290
  423. package/.worktrees/542c4415/src/change-risk-profile.js +0 -339
  424. package/.worktrees/542c4415/src/check-primitives.js +0 -65
  425. package/.worktrees/542c4415/src/classify-change.js +0 -109
  426. package/.worktrees/542c4415/src/commit-suggest.js +0 -202
  427. package/.worktrees/542c4415/src/config-cat.js +0 -88
  428. package/.worktrees/542c4415/src/config-schema.js +0 -328
  429. package/.worktrees/542c4415/src/constants.js +0 -97
  430. package/.worktrees/542c4415/src/contract-matrix.js +0 -533
  431. package/.worktrees/542c4415/src/datetime.js +0 -20
  432. package/.worktrees/542c4415/src/db-engine.js +0 -55
  433. package/.worktrees/542c4415/src/db.js +0 -381
  434. package/.worktrees/542c4415/src/decision-distill.js +0 -517
  435. package/.worktrees/542c4415/src/dispatch/backends/local-agent.js +0 -155
  436. package/.worktrees/542c4415/src/dispatch/backends/sillyhub-mcp.js +0 -245
  437. package/.worktrees/542c4415/src/dispatch/probe.js +0 -246
  438. package/.worktrees/542c4415/src/dispatch/strategy.js +0 -121
  439. package/.worktrees/542c4415/src/docs-check.js +0 -825
  440. package/.worktrees/542c4415/src/docs-debt.js +0 -393
  441. package/.worktrees/542c4415/src/docs-gate.js +0 -107
  442. package/.worktrees/542c4415/src/doctor-diagnostics.js +0 -1099
  443. package/.worktrees/542c4415/src/endpoint-extractor.js +0 -409
  444. package/.worktrees/542c4415/src/foreign-declared.js +0 -155
  445. package/.worktrees/542c4415/src/fs-atomic.js +0 -73
  446. package/.worktrees/542c4415/src/git-helper.js +0 -150
  447. package/.worktrees/542c4415/src/hooks/claude-pre-tool-use.cjs +0 -130
  448. package/.worktrees/542c4415/src/hooks/worktree-guard.js +0 -892
  449. package/.worktrees/542c4415/src/index.js +0 -2854
  450. package/.worktrees/542c4415/src/init.js +0 -626
  451. package/.worktrees/542c4415/src/knowledge-match.js +0 -231
  452. package/.worktrees/542c4415/src/local-detect.js +0 -128
  453. package/.worktrees/542c4415/src/local-register.js +0 -104
  454. package/.worktrees/542c4415/src/machine-interface.js +0 -543
  455. package/.worktrees/542c4415/src/migrate.js +0 -127
  456. package/.worktrees/542c4415/src/module-impact.js +0 -166
  457. package/.worktrees/542c4415/src/module-resolve.js +0 -222
  458. package/.worktrees/542c4415/src/modules.js +0 -580
  459. package/.worktrees/542c4415/src/plan-adopt-waves.js +0 -126
  460. package/.worktrees/542c4415/src/progress/change-registry.js +0 -336
  461. package/.worktrees/542c4415/src/progress/consistency-doctor.js +0 -355
  462. package/.worktrees/542c4415/src/progress/shared.js +0 -36
  463. package/.worktrees/542c4415/src/progress/stage-machine.js +0 -594
  464. package/.worktrees/542c4415/src/progress/step-store.js +0 -265
  465. package/.worktrees/542c4415/src/progress.js +0 -1304
  466. package/.worktrees/542c4415/src/quick-recommend.js +0 -115
  467. package/.worktrees/542c4415/src/quicklog.js +0 -883
  468. package/.worktrees/542c4415/src/review-tier.js +0 -77
  469. package/.worktrees/542c4415/src/run/command.js +0 -1641
  470. package/.worktrees/542c4415/src/run/complete-handlers.js +0 -1552
  471. package/.worktrees/542c4415/src/run/complete.js +0 -1259
  472. package/.worktrees/542c4415/src/run/concurrent-detect.js +0 -156
  473. package/.worktrees/542c4415/src/run/gates.js +0 -1111
  474. package/.worktrees/542c4415/src/run/multi-repo-context.js +0 -208
  475. package/.worktrees/542c4415/src/run/next.js +0 -128
  476. package/.worktrees/542c4415/src/run/prompt.js +0 -843
  477. package/.worktrees/542c4415/src/run/quick-audit.js +0 -186
  478. package/.worktrees/542c4415/src/run/scan-profile.js +0 -269
  479. package/.worktrees/542c4415/src/run/shared.js +0 -1562
  480. package/.worktrees/542c4415/src/run/stage.js +0 -587
  481. package/.worktrees/542c4415/src/run.js +0 -23
  482. package/.worktrees/542c4415/src/scan-diff.js +0 -388
  483. package/.worktrees/542c4415/src/scan-postcheck.js +0 -524
  484. package/.worktrees/542c4415/src/scan-staleness.js +0 -95
  485. package/.worktrees/542c4415/src/setup.js +0 -414
  486. package/.worktrees/542c4415/src/sillyhub-mcp/client.js +0 -597
  487. package/.worktrees/542c4415/src/sillyhub-mcp/config.js +0 -62
  488. package/.worktrees/542c4415/src/spec-dir-typo.js +0 -50
  489. package/.worktrees/542c4415/src/spec-sync.js +0 -358
  490. package/.worktrees/542c4415/src/stage-contract-engine.js +0 -171
  491. package/.worktrees/542c4415/src/stage-contract-spec.js +0 -551
  492. package/.worktrees/542c4415/src/stage-contract.js +0 -948
  493. package/.worktrees/542c4415/src/stage-review.js +0 -597
  494. package/.worktrees/542c4415/src/stages/archive.js +0 -199
  495. package/.worktrees/542c4415/src/stages/brainstorm-auto.js +0 -285
  496. package/.worktrees/542c4415/src/stages/brainstorm.js +0 -624
  497. package/.worktrees/542c4415/src/stages/cmd-existence.js +0 -145
  498. package/.worktrees/542c4415/src/stages/doctor.js +0 -540
  499. package/.worktrees/542c4415/src/stages/execute.js +0 -1277
  500. package/.worktrees/542c4415/src/stages/explore.js +0 -43
  501. package/.worktrees/542c4415/src/stages/index.js +0 -29
  502. package/.worktrees/542c4415/src/stages/knowledge.js +0 -514
  503. package/.worktrees/542c4415/src/stages/plan-postcheck.js +0 -1398
  504. package/.worktrees/542c4415/src/stages/plan.js +0 -655
  505. package/.worktrees/542c4415/src/stages/quick.js +0 -167
  506. package/.worktrees/542c4415/src/stages/scan.js +0 -608
  507. package/.worktrees/542c4415/src/stages/status.js +0 -64
  508. package/.worktrees/542c4415/src/stages/verify.js +0 -246
  509. package/.worktrees/542c4415/src/sync.js +0 -1470
  510. package/.worktrees/542c4415/src/task-review.js +0 -1498
  511. package/.worktrees/542c4415/src/taskcard-placeholders.js +0 -21
  512. package/.worktrees/542c4415/src/taskcard.js +0 -250
  513. package/.worktrees/542c4415/src/verify-postcheck.js +0 -1718
  514. package/.worktrees/542c4415/src/verify-probes.js +0 -327
  515. package/.worktrees/542c4415/src/version.js +0 -19
  516. package/.worktrees/542c4415/src/workflow.js +0 -600
  517. package/.worktrees/542c4415/src/workspace.js +0 -125
  518. package/.worktrees/542c4415/src/worktree-apply.js +0 -1611
  519. package/.worktrees/542c4415/src/worktree-deps.js +0 -668
  520. package/.worktrees/542c4415/src/worktree.js +0 -1849
  521. package/.worktrees/542c4415/templates/prompts/taskcard-rules.md +0 -29
  522. package/.worktrees/542c4415/templates/prompts/testcase-design.md +0 -12
  523. package/.worktrees/542c4415/templates/prompts/verify-probes.md +0 -32
  524. package/.worktrees/542c4415/templates/workflows/archive-impact.yaml +0 -79
  525. package/.worktrees/542c4415/templates/workflows/scan-docs.yaml +0 -132
  526. package/.worktrees/8d2d0392/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  527. package/.worktrees/8d2d0392/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  528. package/.worktrees/8d2d0392/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  529. package/.worktrees/8d2d0392/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  530. package/.worktrees/8d2d0392/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  531. package/.worktrees/8d2d0392/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  532. package/.worktrees/8d2d0392/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  533. package/.worktrees/8d2d0392/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  534. package/.worktrees/8d2d0392/.claude/skills/sillyspec-export/SKILL.md +0 -57
  535. package/.worktrees/8d2d0392/.claude/skills/sillyspec-init/SKILL.md +0 -177
  536. package/.worktrees/8d2d0392/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  537. package/.worktrees/8d2d0392/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  538. package/.worktrees/8d2d0392/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  539. package/.worktrees/8d2d0392/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  540. package/.worktrees/8d2d0392/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  541. package/.worktrees/8d2d0392/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  542. package/.worktrees/8d2d0392/.claude/skills/sillyspec-state/SKILL.md +0 -64
  543. package/.worktrees/8d2d0392/.claude/skills/sillyspec-status/SKILL.md +0 -54
  544. package/.worktrees/8d2d0392/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  545. package/.worktrees/8d2d0392/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  546. package/.worktrees/8d2d0392/.claude/skills/verify-per-user/SKILL.md +0 -6
  547. package/.worktrees/8d2d0392/.gitattributes +0 -2
  548. package/.worktrees/8d2d0392/.husky/pre-push +0 -20
  549. package/.worktrees/8d2d0392/README.md +0 -203
  550. package/.worktrees/8d2d0392/SKILL.md +0 -91
  551. package/.worktrees/8d2d0392/architecture-analysis.md +0 -448
  552. package/.worktrees/8d2d0392/bin/sillyspec.js +0 -2
  553. package/.worktrees/8d2d0392/eval/README.md +0 -86
  554. package/.worktrees/8d2d0392/eval/eval.config.json +0 -28
  555. package/.worktrees/8d2d0392/eval/lib/adapters/cli.mjs +0 -63
  556. package/.worktrees/8d2d0392/eval/lib/adapters/dryrun.mjs +0 -27
  557. package/.worktrees/8d2d0392/eval/lib/config.mjs +0 -82
  558. package/.worktrees/8d2d0392/eval/lib/db.mjs +0 -76
  559. package/.worktrees/8d2d0392/eval/lib/report.mjs +0 -120
  560. package/.worktrees/8d2d0392/eval/lib/runner.mjs +0 -157
  561. package/.worktrees/8d2d0392/eval/lib/tasks.mjs +0 -73
  562. package/.worktrees/8d2d0392/eval/lib/util.mjs +0 -107
  563. package/.worktrees/8d2d0392/eval/lib/workdir.mjs +0 -30
  564. package/.worktrees/8d2d0392/eval/run.mjs +0 -83
  565. package/.worktrees/8d2d0392/eval/tasks/001-slugify/files/package.json +0 -6
  566. package/.worktrees/8d2d0392/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  567. package/.worktrees/8d2d0392/eval/tasks/001-slugify/task.json +0 -6
  568. package/.worktrees/8d2d0392/eval/tasks/001-slugify/verify.mjs +0 -28
  569. package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/package.json +0 -6
  570. package/.worktrees/8d2d0392/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  571. package/.worktrees/8d2d0392/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  572. package/.worktrees/8d2d0392/eval/tasks/002-each-day/task.json +0 -6
  573. package/.worktrees/8d2d0392/eval/tasks/002-each-day/verify.mjs +0 -31
  574. package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  575. package/.worktrees/8d2d0392/eval/tasks/003-word-report/files/package.json +0 -6
  576. package/.worktrees/8d2d0392/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  577. package/.worktrees/8d2d0392/eval/tasks/003-word-report/task.json +0 -6
  578. package/.worktrees/8d2d0392/eval/tasks/003-word-report/verify.mjs +0 -38
  579. package/.worktrees/8d2d0392/logo.jpg +0 -0
  580. package/.worktrees/8d2d0392/package-lock.json +0 -977
  581. package/.worktrees/8d2d0392/package.json +0 -41
  582. package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  583. package/.worktrees/8d2d0392/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  584. package/.worktrees/8d2d0392/packages/dashboard/dist/favicon.jpg +0 -0
  585. package/.worktrees/8d2d0392/packages/dashboard/dist/index.html +0 -16
  586. package/.worktrees/8d2d0392/packages/dashboard/dist/logo.jpg +0 -0
  587. package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-dashboard.html +0 -836
  588. package/.worktrees/8d2d0392/packages/dashboard/dist/prototype-overview.html +0 -256
  589. package/.worktrees/8d2d0392/packages/dashboard/package.json +0 -25
  590. package/.worktrees/8d2d0392/packages/dashboard/server/executor.js +0 -95
  591. package/.worktrees/8d2d0392/packages/dashboard/server/index.js +0 -679
  592. package/.worktrees/8d2d0392/packages/dashboard/server/parser.js +0 -526
  593. package/.worktrees/8d2d0392/packages/dashboard/server/watcher.js +0 -357
  594. package/.worktrees/8d2d0392/src/agent-session-log.js +0 -803
  595. package/.worktrees/8d2d0392/src/change-list.js +0 -290
  596. package/.worktrees/8d2d0392/src/change-risk-profile.js +0 -339
  597. package/.worktrees/8d2d0392/src/check-primitives.js +0 -65
  598. package/.worktrees/8d2d0392/src/classify-change.js +0 -109
  599. package/.worktrees/8d2d0392/src/commit-suggest.js +0 -202
  600. package/.worktrees/8d2d0392/src/config-cat.js +0 -88
  601. package/.worktrees/8d2d0392/src/config-schema.js +0 -328
  602. package/.worktrees/8d2d0392/src/constants.js +0 -97
  603. package/.worktrees/8d2d0392/src/contract-matrix.js +0 -533
  604. package/.worktrees/8d2d0392/src/datetime.js +0 -20
  605. package/.worktrees/8d2d0392/src/db-engine.js +0 -55
  606. package/.worktrees/8d2d0392/src/db.js +0 -381
  607. package/.worktrees/8d2d0392/src/decision-distill.js +0 -517
  608. package/.worktrees/8d2d0392/src/dispatch/backends/local-agent.js +0 -155
  609. package/.worktrees/8d2d0392/src/dispatch/backends/sillyhub-mcp.js +0 -245
  610. package/.worktrees/8d2d0392/src/dispatch/probe.js +0 -246
  611. package/.worktrees/8d2d0392/src/dispatch/strategy.js +0 -121
  612. package/.worktrees/8d2d0392/src/docs-check.js +0 -825
  613. package/.worktrees/8d2d0392/src/docs-debt.js +0 -393
  614. package/.worktrees/8d2d0392/src/docs-gate.js +0 -107
  615. package/.worktrees/8d2d0392/src/doctor-diagnostics.js +0 -1099
  616. package/.worktrees/8d2d0392/src/endpoint-extractor.js +0 -409
  617. package/.worktrees/8d2d0392/src/foreign-declared.js +0 -78
  618. package/.worktrees/8d2d0392/src/fs-atomic.js +0 -73
  619. package/.worktrees/8d2d0392/src/git-helper.js +0 -150
  620. package/.worktrees/8d2d0392/src/hooks/claude-pre-tool-use.cjs +0 -130
  621. package/.worktrees/8d2d0392/src/hooks/worktree-guard.js +0 -892
  622. package/.worktrees/8d2d0392/src/index.js +0 -2854
  623. package/.worktrees/8d2d0392/src/init.js +0 -626
  624. package/.worktrees/8d2d0392/src/knowledge-match.js +0 -231
  625. package/.worktrees/8d2d0392/src/local-detect.js +0 -128
  626. package/.worktrees/8d2d0392/src/local-register.js +0 -104
  627. package/.worktrees/8d2d0392/src/machine-interface.js +0 -543
  628. package/.worktrees/8d2d0392/src/migrate.js +0 -127
  629. package/.worktrees/8d2d0392/src/module-impact.js +0 -166
  630. package/.worktrees/8d2d0392/src/module-resolve.js +0 -222
  631. package/.worktrees/8d2d0392/src/modules.js +0 -580
  632. package/.worktrees/8d2d0392/src/plan-adopt-waves.js +0 -126
  633. package/.worktrees/8d2d0392/src/progress/change-registry.js +0 -336
  634. package/.worktrees/8d2d0392/src/progress/consistency-doctor.js +0 -355
  635. package/.worktrees/8d2d0392/src/progress/shared.js +0 -36
  636. package/.worktrees/8d2d0392/src/progress/stage-machine.js +0 -594
  637. package/.worktrees/8d2d0392/src/progress/step-store.js +0 -265
  638. package/.worktrees/8d2d0392/src/progress.js +0 -1304
  639. package/.worktrees/8d2d0392/src/quick-recommend.js +0 -115
  640. package/.worktrees/8d2d0392/src/quicklog.js +0 -883
  641. package/.worktrees/8d2d0392/src/review-tier.js +0 -77
  642. package/.worktrees/8d2d0392/src/run/command.js +0 -1641
  643. package/.worktrees/8d2d0392/src/run/complete-handlers.js +0 -1552
  644. package/.worktrees/8d2d0392/src/run/complete.js +0 -1259
  645. package/.worktrees/8d2d0392/src/run/concurrent-detect.js +0 -156
  646. package/.worktrees/8d2d0392/src/run/gates.js +0 -1094
  647. package/.worktrees/8d2d0392/src/run/multi-repo-context.js +0 -208
  648. package/.worktrees/8d2d0392/src/run/next.js +0 -128
  649. package/.worktrees/8d2d0392/src/run/prompt.js +0 -843
  650. package/.worktrees/8d2d0392/src/run/quick-audit.js +0 -186
  651. package/.worktrees/8d2d0392/src/run/scan-profile.js +0 -269
  652. package/.worktrees/8d2d0392/src/run/shared.js +0 -1562
  653. package/.worktrees/8d2d0392/src/run/stage.js +0 -587
  654. package/.worktrees/8d2d0392/src/run.js +0 -23
  655. package/.worktrees/8d2d0392/src/scan-diff.js +0 -388
  656. package/.worktrees/8d2d0392/src/scan-postcheck.js +0 -524
  657. package/.worktrees/8d2d0392/src/scan-staleness.js +0 -95
  658. package/.worktrees/8d2d0392/src/setup.js +0 -414
  659. package/.worktrees/8d2d0392/src/sillyhub-mcp/client.js +0 -597
  660. package/.worktrees/8d2d0392/src/sillyhub-mcp/config.js +0 -62
  661. package/.worktrees/8d2d0392/src/spec-dir-typo.js +0 -50
  662. package/.worktrees/8d2d0392/src/spec-sync.js +0 -358
  663. package/.worktrees/8d2d0392/src/stage-contract-engine.js +0 -171
  664. package/.worktrees/8d2d0392/src/stage-contract-spec.js +0 -551
  665. package/.worktrees/8d2d0392/src/stage-contract.js +0 -948
  666. package/.worktrees/8d2d0392/src/stage-review.js +0 -597
  667. package/.worktrees/8d2d0392/src/stages/archive.js +0 -199
  668. package/.worktrees/8d2d0392/src/stages/brainstorm-auto.js +0 -285
  669. package/.worktrees/8d2d0392/src/stages/brainstorm.js +0 -624
  670. package/.worktrees/8d2d0392/src/stages/cmd-existence.js +0 -145
  671. package/.worktrees/8d2d0392/src/stages/doctor.js +0 -540
  672. package/.worktrees/8d2d0392/src/stages/execute.js +0 -1277
  673. package/.worktrees/8d2d0392/src/stages/explore.js +0 -43
  674. package/.worktrees/8d2d0392/src/stages/index.js +0 -29
  675. package/.worktrees/8d2d0392/src/stages/knowledge.js +0 -514
  676. package/.worktrees/8d2d0392/src/stages/plan-postcheck.js +0 -1398
  677. package/.worktrees/8d2d0392/src/stages/plan.js +0 -651
  678. package/.worktrees/8d2d0392/src/stages/quick.js +0 -167
  679. package/.worktrees/8d2d0392/src/stages/scan.js +0 -608
  680. package/.worktrees/8d2d0392/src/stages/status.js +0 -64
  681. package/.worktrees/8d2d0392/src/stages/verify.js +0 -246
  682. package/.worktrees/8d2d0392/src/sync.js +0 -1470
  683. package/.worktrees/8d2d0392/src/task-review.js +0 -1498
  684. package/.worktrees/8d2d0392/src/taskcard-placeholders.js +0 -21
  685. package/.worktrees/8d2d0392/src/taskcard.js +0 -217
  686. package/.worktrees/8d2d0392/src/verify-postcheck.js +0 -1718
  687. package/.worktrees/8d2d0392/src/verify-probes.js +0 -327
  688. package/.worktrees/8d2d0392/src/version.js +0 -19
  689. package/.worktrees/8d2d0392/src/workflow.js +0 -600
  690. package/.worktrees/8d2d0392/src/workspace.js +0 -125
  691. package/.worktrees/8d2d0392/src/worktree-apply.js +0 -1611
  692. package/.worktrees/8d2d0392/src/worktree-deps.js +0 -576
  693. package/.worktrees/8d2d0392/src/worktree.js +0 -1838
  694. package/.worktrees/8d2d0392/templates/claude-instruction.md +0 -23
  695. package/.worktrees/8d2d0392/templates/prompts/taskcard-rules.md +0 -29
  696. package/.worktrees/8d2d0392/templates/prompts/testcase-design.md +0 -12
  697. package/.worktrees/8d2d0392/templates/prompts/verify-probes.md +0 -32
  698. package/.worktrees/8d2d0392/templates/workflows/archive-impact.yaml +0 -79
  699. package/.worktrees/8d2d0392/templates/workflows/scan-docs.yaml +0 -132
  700. package/.worktrees/c1eae35e/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  701. package/.worktrees/c1eae35e/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  702. package/.worktrees/c1eae35e/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  703. package/.worktrees/c1eae35e/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  704. package/.worktrees/c1eae35e/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  705. package/.worktrees/c1eae35e/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  706. package/.worktrees/c1eae35e/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  707. package/.worktrees/c1eae35e/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  708. package/.worktrees/c1eae35e/.claude/skills/sillyspec-export/SKILL.md +0 -57
  709. package/.worktrees/c1eae35e/.claude/skills/sillyspec-init/SKILL.md +0 -177
  710. package/.worktrees/c1eae35e/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  711. package/.worktrees/c1eae35e/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  712. package/.worktrees/c1eae35e/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  713. package/.worktrees/c1eae35e/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  714. package/.worktrees/c1eae35e/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  715. package/.worktrees/c1eae35e/.claude/skills/sillyspec-state/SKILL.md +0 -64
  716. package/.worktrees/c1eae35e/.claude/skills/sillyspec-status/SKILL.md +0 -54
  717. package/.worktrees/c1eae35e/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  718. package/.worktrees/c1eae35e/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  719. package/.worktrees/c1eae35e/.gitattributes +0 -2
  720. package/.worktrees/c1eae35e/.husky/pre-push +0 -20
  721. package/.worktrees/c1eae35e/README.md +0 -203
  722. package/.worktrees/c1eae35e/SKILL.md +0 -91
  723. package/.worktrees/c1eae35e/architecture-analysis.md +0 -448
  724. package/.worktrees/c1eae35e/bin/sillyspec.js +0 -2
  725. package/.worktrees/c1eae35e/eval/README.md +0 -86
  726. package/.worktrees/c1eae35e/eval/eval.config.json +0 -28
  727. package/.worktrees/c1eae35e/eval/lib/adapters/cli.mjs +0 -63
  728. package/.worktrees/c1eae35e/eval/lib/adapters/dryrun.mjs +0 -27
  729. package/.worktrees/c1eae35e/eval/lib/config.mjs +0 -82
  730. package/.worktrees/c1eae35e/eval/lib/db.mjs +0 -76
  731. package/.worktrees/c1eae35e/eval/lib/report.mjs +0 -120
  732. package/.worktrees/c1eae35e/eval/lib/runner.mjs +0 -157
  733. package/.worktrees/c1eae35e/eval/lib/tasks.mjs +0 -73
  734. package/.worktrees/c1eae35e/eval/lib/util.mjs +0 -107
  735. package/.worktrees/c1eae35e/eval/lib/workdir.mjs +0 -30
  736. package/.worktrees/c1eae35e/eval/run.mjs +0 -83
  737. package/.worktrees/c1eae35e/eval/tasks/001-slugify/files/package.json +0 -6
  738. package/.worktrees/c1eae35e/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  739. package/.worktrees/c1eae35e/eval/tasks/001-slugify/task.json +0 -6
  740. package/.worktrees/c1eae35e/eval/tasks/001-slugify/verify.mjs +0 -28
  741. package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/package.json +0 -6
  742. package/.worktrees/c1eae35e/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  743. package/.worktrees/c1eae35e/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  744. package/.worktrees/c1eae35e/eval/tasks/002-each-day/task.json +0 -6
  745. package/.worktrees/c1eae35e/eval/tasks/002-each-day/verify.mjs +0 -31
  746. package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  747. package/.worktrees/c1eae35e/eval/tasks/003-word-report/files/package.json +0 -6
  748. package/.worktrees/c1eae35e/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  749. package/.worktrees/c1eae35e/eval/tasks/003-word-report/task.json +0 -6
  750. package/.worktrees/c1eae35e/eval/tasks/003-word-report/verify.mjs +0 -38
  751. package/.worktrees/c1eae35e/logo.jpg +0 -0
  752. package/.worktrees/c1eae35e/package-lock.json +0 -977
  753. package/.worktrees/c1eae35e/package.json +0 -41
  754. package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  755. package/.worktrees/c1eae35e/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  756. package/.worktrees/c1eae35e/packages/dashboard/dist/favicon.jpg +0 -0
  757. package/.worktrees/c1eae35e/packages/dashboard/dist/index.html +0 -16
  758. package/.worktrees/c1eae35e/packages/dashboard/dist/logo.jpg +0 -0
  759. package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-dashboard.html +0 -836
  760. package/.worktrees/c1eae35e/packages/dashboard/dist/prototype-overview.html +0 -256
  761. package/.worktrees/c1eae35e/packages/dashboard/package.json +0 -25
  762. package/.worktrees/c1eae35e/packages/dashboard/server/executor.js +0 -95
  763. package/.worktrees/c1eae35e/packages/dashboard/server/index.js +0 -679
  764. package/.worktrees/c1eae35e/packages/dashboard/server/parser.js +0 -526
  765. package/.worktrees/c1eae35e/packages/dashboard/server/watcher.js +0 -357
  766. package/.worktrees/c1eae35e/src/agent-session-log.js +0 -803
  767. package/.worktrees/c1eae35e/src/change-list.js +0 -290
  768. package/.worktrees/c1eae35e/src/change-risk-profile.js +0 -339
  769. package/.worktrees/c1eae35e/src/check-primitives.js +0 -65
  770. package/.worktrees/c1eae35e/src/classify-change.js +0 -109
  771. package/.worktrees/c1eae35e/src/commit-suggest.js +0 -202
  772. package/.worktrees/c1eae35e/src/config-cat.js +0 -88
  773. package/.worktrees/c1eae35e/src/config-schema.js +0 -328
  774. package/.worktrees/c1eae35e/src/constants.js +0 -97
  775. package/.worktrees/c1eae35e/src/contract-matrix.js +0 -533
  776. package/.worktrees/c1eae35e/src/datetime.js +0 -20
  777. package/.worktrees/c1eae35e/src/db-engine.js +0 -55
  778. package/.worktrees/c1eae35e/src/db.js +0 -381
  779. package/.worktrees/c1eae35e/src/decision-distill.js +0 -517
  780. package/.worktrees/c1eae35e/src/dispatch/backends/local-agent.js +0 -155
  781. package/.worktrees/c1eae35e/src/dispatch/backends/sillyhub-mcp.js +0 -245
  782. package/.worktrees/c1eae35e/src/dispatch/probe.js +0 -246
  783. package/.worktrees/c1eae35e/src/dispatch/strategy.js +0 -121
  784. package/.worktrees/c1eae35e/src/docs-check.js +0 -825
  785. package/.worktrees/c1eae35e/src/docs-debt.js +0 -393
  786. package/.worktrees/c1eae35e/src/docs-gate.js +0 -107
  787. package/.worktrees/c1eae35e/src/doctor-diagnostics.js +0 -1099
  788. package/.worktrees/c1eae35e/src/endpoint-extractor.js +0 -409
  789. package/.worktrees/c1eae35e/src/foreign-declared.js +0 -155
  790. package/.worktrees/c1eae35e/src/fs-atomic.js +0 -73
  791. package/.worktrees/c1eae35e/src/git-helper.js +0 -150
  792. package/.worktrees/c1eae35e/src/hooks/claude-pre-tool-use.cjs +0 -130
  793. package/.worktrees/c1eae35e/src/hooks/worktree-guard.js +0 -892
  794. package/.worktrees/c1eae35e/src/index.js +0 -2854
  795. package/.worktrees/c1eae35e/src/init.js +0 -626
  796. package/.worktrees/c1eae35e/src/knowledge-match.js +0 -231
  797. package/.worktrees/c1eae35e/src/local-detect.js +0 -128
  798. package/.worktrees/c1eae35e/src/local-register.js +0 -104
  799. package/.worktrees/c1eae35e/src/machine-interface.js +0 -543
  800. package/.worktrees/c1eae35e/src/migrate.js +0 -127
  801. package/.worktrees/c1eae35e/src/module-impact.js +0 -166
  802. package/.worktrees/c1eae35e/src/module-resolve.js +0 -222
  803. package/.worktrees/c1eae35e/src/modules.js +0 -580
  804. package/.worktrees/c1eae35e/src/plan-adopt-waves.js +0 -126
  805. package/.worktrees/c1eae35e/src/progress/change-registry.js +0 -336
  806. package/.worktrees/c1eae35e/src/progress/consistency-doctor.js +0 -355
  807. package/.worktrees/c1eae35e/src/progress/shared.js +0 -36
  808. package/.worktrees/c1eae35e/src/progress/stage-machine.js +0 -594
  809. package/.worktrees/c1eae35e/src/progress/step-store.js +0 -265
  810. package/.worktrees/c1eae35e/src/progress.js +0 -1304
  811. package/.worktrees/c1eae35e/src/quick-recommend.js +0 -115
  812. package/.worktrees/c1eae35e/src/quicklog.js +0 -883
  813. package/.worktrees/c1eae35e/src/review-tier.js +0 -77
  814. package/.worktrees/c1eae35e/src/run/command.js +0 -1641
  815. package/.worktrees/c1eae35e/src/run/complete-handlers.js +0 -1552
  816. package/.worktrees/c1eae35e/src/run/complete.js +0 -1259
  817. package/.worktrees/c1eae35e/src/run/concurrent-detect.js +0 -156
  818. package/.worktrees/c1eae35e/src/run/gates.js +0 -1111
  819. package/.worktrees/c1eae35e/src/run/multi-repo-context.js +0 -208
  820. package/.worktrees/c1eae35e/src/run/next.js +0 -128
  821. package/.worktrees/c1eae35e/src/run/prompt.js +0 -843
  822. package/.worktrees/c1eae35e/src/run/quick-audit.js +0 -186
  823. package/.worktrees/c1eae35e/src/run/scan-profile.js +0 -269
  824. package/.worktrees/c1eae35e/src/run/shared.js +0 -1562
  825. package/.worktrees/c1eae35e/src/run/stage.js +0 -587
  826. package/.worktrees/c1eae35e/src/run.js +0 -23
  827. package/.worktrees/c1eae35e/src/scan-diff.js +0 -388
  828. package/.worktrees/c1eae35e/src/scan-postcheck.js +0 -524
  829. package/.worktrees/c1eae35e/src/scan-staleness.js +0 -95
  830. package/.worktrees/c1eae35e/src/setup.js +0 -414
  831. package/.worktrees/c1eae35e/src/sillyhub-mcp/client.js +0 -597
  832. package/.worktrees/c1eae35e/src/sillyhub-mcp/config.js +0 -62
  833. package/.worktrees/c1eae35e/src/spec-dir-typo.js +0 -50
  834. package/.worktrees/c1eae35e/src/spec-sync.js +0 -358
  835. package/.worktrees/c1eae35e/src/stage-contract-engine.js +0 -171
  836. package/.worktrees/c1eae35e/src/stage-contract-spec.js +0 -551
  837. package/.worktrees/c1eae35e/src/stage-contract.js +0 -948
  838. package/.worktrees/c1eae35e/src/stage-review.js +0 -597
  839. package/.worktrees/c1eae35e/src/stages/archive.js +0 -199
  840. package/.worktrees/c1eae35e/src/stages/brainstorm-auto.js +0 -285
  841. package/.worktrees/c1eae35e/src/stages/brainstorm.js +0 -624
  842. package/.worktrees/c1eae35e/src/stages/cmd-existence.js +0 -145
  843. package/.worktrees/c1eae35e/src/stages/doctor.js +0 -540
  844. package/.worktrees/c1eae35e/src/stages/execute.js +0 -1277
  845. package/.worktrees/c1eae35e/src/stages/explore.js +0 -43
  846. package/.worktrees/c1eae35e/src/stages/index.js +0 -29
  847. package/.worktrees/c1eae35e/src/stages/knowledge.js +0 -514
  848. package/.worktrees/c1eae35e/src/stages/plan-postcheck.js +0 -1398
  849. package/.worktrees/c1eae35e/src/stages/plan.js +0 -655
  850. package/.worktrees/c1eae35e/src/stages/quick.js +0 -167
  851. package/.worktrees/c1eae35e/src/stages/scan.js +0 -608
  852. package/.worktrees/c1eae35e/src/stages/status.js +0 -64
  853. package/.worktrees/c1eae35e/src/stages/verify.js +0 -246
  854. package/.worktrees/c1eae35e/src/sync.js +0 -1470
  855. package/.worktrees/c1eae35e/src/task-review.js +0 -1498
  856. package/.worktrees/c1eae35e/src/taskcard-placeholders.js +0 -21
  857. package/.worktrees/c1eae35e/src/taskcard.js +0 -250
  858. package/.worktrees/c1eae35e/src/verify-postcheck.js +0 -1718
  859. package/.worktrees/c1eae35e/src/verify-probes.js +0 -327
  860. package/.worktrees/c1eae35e/src/version.js +0 -19
  861. package/.worktrees/c1eae35e/src/workflow.js +0 -600
  862. package/.worktrees/c1eae35e/src/workspace.js +0 -125
  863. package/.worktrees/c1eae35e/src/worktree-apply.js +0 -1611
  864. package/.worktrees/c1eae35e/src/worktree-deps.js +0 -668
  865. package/.worktrees/c1eae35e/src/worktree.js +0 -1849
  866. package/.worktrees/c1eae35e/templates/claude-instruction.md +0 -23
  867. package/.worktrees/c1eae35e/templates/prompts/taskcard-rules.md +0 -29
  868. package/.worktrees/c1eae35e/templates/prompts/testcase-design.md +0 -12
  869. package/.worktrees/c1eae35e/templates/prompts/verify-probes.md +0 -32
  870. package/.worktrees/c1eae35e/templates/workflows/archive-impact.yaml +0 -79
  871. package/.worktrees/c1eae35e/templates/workflows/scan-docs.yaml +0 -132
  872. package/.worktrees/dafc71ad/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  873. package/.worktrees/dafc71ad/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  874. package/.worktrees/dafc71ad/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  875. package/.worktrees/dafc71ad/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  876. package/.worktrees/dafc71ad/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  877. package/.worktrees/dafc71ad/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  878. package/.worktrees/dafc71ad/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  879. package/.worktrees/dafc71ad/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  880. package/.worktrees/dafc71ad/.claude/skills/sillyspec-export/SKILL.md +0 -57
  881. package/.worktrees/dafc71ad/.claude/skills/sillyspec-init/SKILL.md +0 -177
  882. package/.worktrees/dafc71ad/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  883. package/.worktrees/dafc71ad/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  884. package/.worktrees/dafc71ad/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  885. package/.worktrees/dafc71ad/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  886. package/.worktrees/dafc71ad/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  887. package/.worktrees/dafc71ad/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  888. package/.worktrees/dafc71ad/.claude/skills/sillyspec-state/SKILL.md +0 -64
  889. package/.worktrees/dafc71ad/.claude/skills/sillyspec-status/SKILL.md +0 -54
  890. package/.worktrees/dafc71ad/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  891. package/.worktrees/dafc71ad/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  892. package/.worktrees/dafc71ad/.gitattributes +0 -2
  893. package/.worktrees/dafc71ad/.husky/pre-push +0 -20
  894. package/.worktrees/dafc71ad/README.md +0 -203
  895. package/.worktrees/dafc71ad/SKILL.md +0 -91
  896. package/.worktrees/dafc71ad/analysis.md +0 -366
  897. package/.worktrees/dafc71ad/architecture-analysis.md +0 -448
  898. package/.worktrees/dafc71ad/bin/sillyspec.js +0 -2
  899. package/.worktrees/dafc71ad/eval/README.md +0 -86
  900. package/.worktrees/dafc71ad/eval/eval.config.json +0 -28
  901. package/.worktrees/dafc71ad/eval/lib/adapters/cli.mjs +0 -63
  902. package/.worktrees/dafc71ad/eval/lib/adapters/dryrun.mjs +0 -27
  903. package/.worktrees/dafc71ad/eval/lib/config.mjs +0 -82
  904. package/.worktrees/dafc71ad/eval/lib/db.mjs +0 -76
  905. package/.worktrees/dafc71ad/eval/lib/report.mjs +0 -120
  906. package/.worktrees/dafc71ad/eval/lib/runner.mjs +0 -157
  907. package/.worktrees/dafc71ad/eval/lib/tasks.mjs +0 -73
  908. package/.worktrees/dafc71ad/eval/lib/util.mjs +0 -107
  909. package/.worktrees/dafc71ad/eval/lib/workdir.mjs +0 -30
  910. package/.worktrees/dafc71ad/eval/run.mjs +0 -83
  911. package/.worktrees/dafc71ad/eval/tasks/001-slugify/files/package.json +0 -6
  912. package/.worktrees/dafc71ad/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  913. package/.worktrees/dafc71ad/eval/tasks/001-slugify/task.json +0 -6
  914. package/.worktrees/dafc71ad/eval/tasks/001-slugify/verify.mjs +0 -28
  915. package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/package.json +0 -6
  916. package/.worktrees/dafc71ad/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  917. package/.worktrees/dafc71ad/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  918. package/.worktrees/dafc71ad/eval/tasks/002-each-day/task.json +0 -6
  919. package/.worktrees/dafc71ad/eval/tasks/002-each-day/verify.mjs +0 -31
  920. package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  921. package/.worktrees/dafc71ad/eval/tasks/003-word-report/files/package.json +0 -6
  922. package/.worktrees/dafc71ad/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  923. package/.worktrees/dafc71ad/eval/tasks/003-word-report/task.json +0 -6
  924. package/.worktrees/dafc71ad/eval/tasks/003-word-report/verify.mjs +0 -38
  925. package/.worktrees/dafc71ad/logo.jpg +0 -0
  926. package/.worktrees/dafc71ad/package-lock.json +0 -977
  927. package/.worktrees/dafc71ad/package.json +0 -41
  928. package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  929. package/.worktrees/dafc71ad/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  930. package/.worktrees/dafc71ad/packages/dashboard/dist/favicon.jpg +0 -0
  931. package/.worktrees/dafc71ad/packages/dashboard/dist/index.html +0 -16
  932. package/.worktrees/dafc71ad/packages/dashboard/dist/logo.jpg +0 -0
  933. package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-dashboard.html +0 -836
  934. package/.worktrees/dafc71ad/packages/dashboard/dist/prototype-overview.html +0 -256
  935. package/.worktrees/dafc71ad/packages/dashboard/package.json +0 -25
  936. package/.worktrees/dafc71ad/packages/dashboard/server/executor.js +0 -95
  937. package/.worktrees/dafc71ad/packages/dashboard/server/index.js +0 -679
  938. package/.worktrees/dafc71ad/packages/dashboard/server/parser.js +0 -526
  939. package/.worktrees/dafc71ad/packages/dashboard/server/watcher.js +0 -357
  940. package/.worktrees/dafc71ad/src/agent-session-log.js +0 -803
  941. package/.worktrees/dafc71ad/src/change-list.js +0 -290
  942. package/.worktrees/dafc71ad/src/change-risk-profile.js +0 -339
  943. package/.worktrees/dafc71ad/src/check-primitives.js +0 -65
  944. package/.worktrees/dafc71ad/src/classify-change.js +0 -109
  945. package/.worktrees/dafc71ad/src/commit-suggest.js +0 -202
  946. package/.worktrees/dafc71ad/src/config-cat.js +0 -88
  947. package/.worktrees/dafc71ad/src/config-schema.js +0 -328
  948. package/.worktrees/dafc71ad/src/constants.js +0 -97
  949. package/.worktrees/dafc71ad/src/contract-matrix.js +0 -533
  950. package/.worktrees/dafc71ad/src/datetime.js +0 -20
  951. package/.worktrees/dafc71ad/src/db-engine.js +0 -55
  952. package/.worktrees/dafc71ad/src/db.js +0 -381
  953. package/.worktrees/dafc71ad/src/decision-distill.js +0 -517
  954. package/.worktrees/dafc71ad/src/dispatch/backends/local-agent.js +0 -155
  955. package/.worktrees/dafc71ad/src/dispatch/backends/sillyhub-mcp.js +0 -245
  956. package/.worktrees/dafc71ad/src/dispatch/probe.js +0 -246
  957. package/.worktrees/dafc71ad/src/dispatch/strategy.js +0 -121
  958. package/.worktrees/dafc71ad/src/docs-check.js +0 -825
  959. package/.worktrees/dafc71ad/src/docs-debt.js +0 -393
  960. package/.worktrees/dafc71ad/src/docs-gate.js +0 -107
  961. package/.worktrees/dafc71ad/src/doctor-diagnostics.js +0 -1099
  962. package/.worktrees/dafc71ad/src/endpoint-extractor.js +0 -409
  963. package/.worktrees/dafc71ad/src/foreign-declared.js +0 -155
  964. package/.worktrees/dafc71ad/src/fs-atomic.js +0 -73
  965. package/.worktrees/dafc71ad/src/git-helper.js +0 -150
  966. package/.worktrees/dafc71ad/src/hooks/claude-pre-tool-use.cjs +0 -130
  967. package/.worktrees/dafc71ad/src/hooks/worktree-guard.js +0 -892
  968. package/.worktrees/dafc71ad/src/index.js +0 -2854
  969. package/.worktrees/dafc71ad/src/init.js +0 -626
  970. package/.worktrees/dafc71ad/src/knowledge-match.js +0 -231
  971. package/.worktrees/dafc71ad/src/local-detect.js +0 -128
  972. package/.worktrees/dafc71ad/src/local-register.js +0 -104
  973. package/.worktrees/dafc71ad/src/machine-interface.js +0 -543
  974. package/.worktrees/dafc71ad/src/migrate.js +0 -127
  975. package/.worktrees/dafc71ad/src/module-impact.js +0 -166
  976. package/.worktrees/dafc71ad/src/module-resolve.js +0 -222
  977. package/.worktrees/dafc71ad/src/modules.js +0 -580
  978. package/.worktrees/dafc71ad/src/plan-adopt-waves.js +0 -126
  979. package/.worktrees/dafc71ad/src/progress/change-registry.js +0 -336
  980. package/.worktrees/dafc71ad/src/progress/consistency-doctor.js +0 -355
  981. package/.worktrees/dafc71ad/src/progress/shared.js +0 -36
  982. package/.worktrees/dafc71ad/src/progress/stage-machine.js +0 -594
  983. package/.worktrees/dafc71ad/src/progress/step-store.js +0 -265
  984. package/.worktrees/dafc71ad/src/progress.js +0 -1304
  985. package/.worktrees/dafc71ad/src/quick-recommend.js +0 -115
  986. package/.worktrees/dafc71ad/src/quicklog.js +0 -883
  987. package/.worktrees/dafc71ad/src/review-tier.js +0 -77
  988. package/.worktrees/dafc71ad/src/run/command.js +0 -1641
  989. package/.worktrees/dafc71ad/src/run/complete-handlers.js +0 -1552
  990. package/.worktrees/dafc71ad/src/run/complete.js +0 -1259
  991. package/.worktrees/dafc71ad/src/run/concurrent-detect.js +0 -156
  992. package/.worktrees/dafc71ad/src/run/gates.js +0 -1111
  993. package/.worktrees/dafc71ad/src/run/multi-repo-context.js +0 -208
  994. package/.worktrees/dafc71ad/src/run/next.js +0 -128
  995. package/.worktrees/dafc71ad/src/run/prompt.js +0 -843
  996. package/.worktrees/dafc71ad/src/run/quick-audit.js +0 -186
  997. package/.worktrees/dafc71ad/src/run/scan-profile.js +0 -269
  998. package/.worktrees/dafc71ad/src/run/shared.js +0 -1562
  999. package/.worktrees/dafc71ad/src/run/stage.js +0 -587
  1000. package/.worktrees/dafc71ad/src/run.js +0 -23
  1001. package/.worktrees/dafc71ad/src/scan-diff.js +0 -388
  1002. package/.worktrees/dafc71ad/src/scan-postcheck.js +0 -524
  1003. package/.worktrees/dafc71ad/src/scan-staleness.js +0 -95
  1004. package/.worktrees/dafc71ad/src/setup.js +0 -414
  1005. package/.worktrees/dafc71ad/src/sillyhub-mcp/client.js +0 -597
  1006. package/.worktrees/dafc71ad/src/sillyhub-mcp/config.js +0 -62
  1007. package/.worktrees/dafc71ad/src/spec-dir-typo.js +0 -50
  1008. package/.worktrees/dafc71ad/src/spec-sync.js +0 -358
  1009. package/.worktrees/dafc71ad/src/stage-contract-engine.js +0 -171
  1010. package/.worktrees/dafc71ad/src/stage-contract-spec.js +0 -551
  1011. package/.worktrees/dafc71ad/src/stage-contract.js +0 -948
  1012. package/.worktrees/dafc71ad/src/stage-review.js +0 -597
  1013. package/.worktrees/dafc71ad/src/stages/archive.js +0 -199
  1014. package/.worktrees/dafc71ad/src/stages/brainstorm-auto.js +0 -285
  1015. package/.worktrees/dafc71ad/src/stages/brainstorm.js +0 -624
  1016. package/.worktrees/dafc71ad/src/stages/cmd-existence.js +0 -145
  1017. package/.worktrees/dafc71ad/src/stages/doctor.js +0 -540
  1018. package/.worktrees/dafc71ad/src/stages/execute.js +0 -1277
  1019. package/.worktrees/dafc71ad/src/stages/explore.js +0 -43
  1020. package/.worktrees/dafc71ad/src/stages/index.js +0 -29
  1021. package/.worktrees/dafc71ad/src/stages/knowledge.js +0 -514
  1022. package/.worktrees/dafc71ad/src/stages/plan-postcheck.js +0 -1398
  1023. package/.worktrees/dafc71ad/src/stages/plan.js +0 -655
  1024. package/.worktrees/dafc71ad/src/stages/quick.js +0 -167
  1025. package/.worktrees/dafc71ad/src/stages/scan.js +0 -608
  1026. package/.worktrees/dafc71ad/src/stages/status.js +0 -64
  1027. package/.worktrees/dafc71ad/src/stages/verify.js +0 -246
  1028. package/.worktrees/dafc71ad/src/sync.js +0 -1470
  1029. package/.worktrees/dafc71ad/src/task-review.js +0 -1498
  1030. package/.worktrees/dafc71ad/src/taskcard-placeholders.js +0 -21
  1031. package/.worktrees/dafc71ad/src/taskcard.js +0 -250
  1032. package/.worktrees/dafc71ad/src/verify-postcheck.js +0 -1718
  1033. package/.worktrees/dafc71ad/src/verify-probes.js +0 -327
  1034. package/.worktrees/dafc71ad/src/version.js +0 -19
  1035. package/.worktrees/dafc71ad/src/workflow.js +0 -600
  1036. package/.worktrees/dafc71ad/src/workspace.js +0 -125
  1037. package/.worktrees/dafc71ad/src/worktree-apply.js +0 -1611
  1038. package/.worktrees/dafc71ad/src/worktree-deps.js +0 -668
  1039. package/.worktrees/dafc71ad/src/worktree.js +0 -1849
  1040. package/.worktrees/dafc71ad/templates/claude-instruction.md +0 -23
  1041. package/.worktrees/dafc71ad/templates/prompts/taskcard-rules.md +0 -29
  1042. package/.worktrees/dafc71ad/templates/prompts/testcase-design.md +0 -12
  1043. package/.worktrees/dafc71ad/templates/prompts/verify-probes.md +0 -32
  1044. package/.worktrees/dafc71ad/templates/workflows/archive-impact.yaml +0 -79
  1045. package/.worktrees/dafc71ad/templates/workflows/scan-docs.yaml +0 -132
  1046. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-archive/SKILL.md +0 -87
  1047. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-auto/SKILL.md +0 -93
  1048. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-brainstorm/SKILL.md +0 -114
  1049. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-commit/SKILL.md +0 -67
  1050. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-continue/SKILL.md +0 -47
  1051. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-doctor/SKILL.md +0 -76
  1052. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-execute/SKILL.md +0 -214
  1053. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-explore/SKILL.md +0 -102
  1054. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-export/SKILL.md +0 -57
  1055. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-init/SKILL.md +0 -177
  1056. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
  1057. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-plan/SKILL.md +0 -156
  1058. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-propose/SKILL.md +0 -87
  1059. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-quick/SKILL.md +0 -116
  1060. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-resume/SKILL.md +0 -70
  1061. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-scan/SKILL.md +0 -79
  1062. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-state/SKILL.md +0 -64
  1063. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-status/SKILL.md +0 -54
  1064. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-verify/SKILL.md +0 -87
  1065. package/.worktrees/e58fcc4c/.claude/skills/sillyspec-workspace/SKILL.md +0 -175
  1066. package/.worktrees/e58fcc4c/.gitattributes +0 -2
  1067. package/.worktrees/e58fcc4c/.husky/pre-push +0 -20
  1068. package/.worktrees/e58fcc4c/README.md +0 -203
  1069. package/.worktrees/e58fcc4c/SKILL.md +0 -91
  1070. package/.worktrees/e58fcc4c/architecture-analysis.md +0 -503
  1071. package/.worktrees/e58fcc4c/bin/sillyspec.js +0 -2
  1072. package/.worktrees/e58fcc4c/eval/README.md +0 -86
  1073. package/.worktrees/e58fcc4c/eval/eval.config.json +0 -28
  1074. package/.worktrees/e58fcc4c/eval/lib/adapters/cli.mjs +0 -63
  1075. package/.worktrees/e58fcc4c/eval/lib/adapters/dryrun.mjs +0 -27
  1076. package/.worktrees/e58fcc4c/eval/lib/config.mjs +0 -82
  1077. package/.worktrees/e58fcc4c/eval/lib/db.mjs +0 -76
  1078. package/.worktrees/e58fcc4c/eval/lib/report.mjs +0 -120
  1079. package/.worktrees/e58fcc4c/eval/lib/runner.mjs +0 -157
  1080. package/.worktrees/e58fcc4c/eval/lib/tasks.mjs +0 -73
  1081. package/.worktrees/e58fcc4c/eval/lib/util.mjs +0 -107
  1082. package/.worktrees/e58fcc4c/eval/lib/workdir.mjs +0 -30
  1083. package/.worktrees/e58fcc4c/eval/run.mjs +0 -83
  1084. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/files/package.json +0 -6
  1085. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/solution/src/slugify.mjs +0 -26
  1086. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/task.json +0 -6
  1087. package/.worktrees/e58fcc4c/eval/tasks/001-slugify/verify.mjs +0 -28
  1088. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/package.json +0 -6
  1089. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/files/src/dates.mjs +0 -4
  1090. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/solution/src/dates.mjs +0 -30
  1091. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/task.json +0 -6
  1092. package/.worktrees/e58fcc4c/eval/tasks/002-each-day/verify.mjs +0 -31
  1093. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/data/notes.txt +0 -5
  1094. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/files/package.json +0 -6
  1095. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/solution/bin/report.mjs +0 -36
  1096. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/task.json +0 -6
  1097. package/.worktrees/e58fcc4c/eval/tasks/003-word-report/verify.mjs +0 -38
  1098. package/.worktrees/e58fcc4c/logo.jpg +0 -0
  1099. package/.worktrees/e58fcc4c/package-lock.json +0 -977
  1100. package/.worktrees/e58fcc4c/package.json +0 -41
  1101. package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-Bq_Z2hne.js +0 -7446
  1102. package/.worktrees/e58fcc4c/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
  1103. package/.worktrees/e58fcc4c/packages/dashboard/dist/favicon.jpg +0 -0
  1104. package/.worktrees/e58fcc4c/packages/dashboard/dist/index.html +0 -16
  1105. package/.worktrees/e58fcc4c/packages/dashboard/dist/logo.jpg +0 -0
  1106. package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-dashboard.html +0 -836
  1107. package/.worktrees/e58fcc4c/packages/dashboard/dist/prototype-overview.html +0 -256
  1108. package/.worktrees/e58fcc4c/packages/dashboard/package.json +0 -25
  1109. package/.worktrees/e58fcc4c/packages/dashboard/server/executor.js +0 -95
  1110. package/.worktrees/e58fcc4c/packages/dashboard/server/index.js +0 -679
  1111. package/.worktrees/e58fcc4c/packages/dashboard/server/parser.js +0 -526
  1112. package/.worktrees/e58fcc4c/packages/dashboard/server/watcher.js +0 -357
  1113. package/.worktrees/e58fcc4c/src/agent-session-log.js +0 -803
  1114. package/.worktrees/e58fcc4c/src/change-list.js +0 -290
  1115. package/.worktrees/e58fcc4c/src/change-risk-profile.js +0 -339
  1116. package/.worktrees/e58fcc4c/src/check-primitives.js +0 -65
  1117. package/.worktrees/e58fcc4c/src/classify-change.js +0 -109
  1118. package/.worktrees/e58fcc4c/src/commit-suggest.js +0 -202
  1119. package/.worktrees/e58fcc4c/src/config-cat.js +0 -88
  1120. package/.worktrees/e58fcc4c/src/config-schema.js +0 -328
  1121. package/.worktrees/e58fcc4c/src/constants.js +0 -97
  1122. package/.worktrees/e58fcc4c/src/contract-matrix.js +0 -533
  1123. package/.worktrees/e58fcc4c/src/datetime.js +0 -20
  1124. package/.worktrees/e58fcc4c/src/db-engine.js +0 -55
  1125. package/.worktrees/e58fcc4c/src/db.js +0 -381
  1126. package/.worktrees/e58fcc4c/src/decision-distill.js +0 -517
  1127. package/.worktrees/e58fcc4c/src/dispatch/backends/local-agent.js +0 -155
  1128. package/.worktrees/e58fcc4c/src/dispatch/backends/sillyhub-mcp.js +0 -245
  1129. package/.worktrees/e58fcc4c/src/dispatch/probe.js +0 -246
  1130. package/.worktrees/e58fcc4c/src/dispatch/strategy.js +0 -121
  1131. package/.worktrees/e58fcc4c/src/docs-check.js +0 -825
  1132. package/.worktrees/e58fcc4c/src/docs-debt.js +0 -393
  1133. package/.worktrees/e58fcc4c/src/docs-gate.js +0 -107
  1134. package/.worktrees/e58fcc4c/src/doctor-diagnostics.js +0 -1099
  1135. package/.worktrees/e58fcc4c/src/endpoint-extractor.js +0 -409
  1136. package/.worktrees/e58fcc4c/src/foreign-declared.js +0 -155
  1137. package/.worktrees/e58fcc4c/src/fs-atomic.js +0 -73
  1138. package/.worktrees/e58fcc4c/src/git-helper.js +0 -150
  1139. package/.worktrees/e58fcc4c/src/hooks/claude-pre-tool-use.cjs +0 -130
  1140. package/.worktrees/e58fcc4c/src/hooks/worktree-guard.js +0 -892
  1141. package/.worktrees/e58fcc4c/src/index.js +0 -2854
  1142. package/.worktrees/e58fcc4c/src/init.js +0 -626
  1143. package/.worktrees/e58fcc4c/src/knowledge-match.js +0 -231
  1144. package/.worktrees/e58fcc4c/src/local-detect.js +0 -128
  1145. package/.worktrees/e58fcc4c/src/local-register.js +0 -104
  1146. package/.worktrees/e58fcc4c/src/machine-interface.js +0 -543
  1147. package/.worktrees/e58fcc4c/src/migrate.js +0 -127
  1148. package/.worktrees/e58fcc4c/src/module-impact.js +0 -166
  1149. package/.worktrees/e58fcc4c/src/module-resolve.js +0 -222
  1150. package/.worktrees/e58fcc4c/src/modules.js +0 -580
  1151. package/.worktrees/e58fcc4c/src/plan-adopt-waves.js +0 -126
  1152. package/.worktrees/e58fcc4c/src/progress/change-registry.js +0 -336
  1153. package/.worktrees/e58fcc4c/src/progress/consistency-doctor.js +0 -355
  1154. package/.worktrees/e58fcc4c/src/progress/shared.js +0 -36
  1155. package/.worktrees/e58fcc4c/src/progress/stage-machine.js +0 -594
  1156. package/.worktrees/e58fcc4c/src/progress/step-store.js +0 -265
  1157. package/.worktrees/e58fcc4c/src/progress.js +0 -1304
  1158. package/.worktrees/e58fcc4c/src/quick-recommend.js +0 -115
  1159. package/.worktrees/e58fcc4c/src/quicklog.js +0 -883
  1160. package/.worktrees/e58fcc4c/src/review-tier.js +0 -77
  1161. package/.worktrees/e58fcc4c/src/run/command.js +0 -1641
  1162. package/.worktrees/e58fcc4c/src/run/complete-handlers.js +0 -1552
  1163. package/.worktrees/e58fcc4c/src/run/complete.js +0 -1259
  1164. package/.worktrees/e58fcc4c/src/run/concurrent-detect.js +0 -156
  1165. package/.worktrees/e58fcc4c/src/run/gates.js +0 -1111
  1166. package/.worktrees/e58fcc4c/src/run/multi-repo-context.js +0 -208
  1167. package/.worktrees/e58fcc4c/src/run/next.js +0 -128
  1168. package/.worktrees/e58fcc4c/src/run/prompt.js +0 -843
  1169. package/.worktrees/e58fcc4c/src/run/quick-audit.js +0 -186
  1170. package/.worktrees/e58fcc4c/src/run/scan-profile.js +0 -269
  1171. package/.worktrees/e58fcc4c/src/run/shared.js +0 -1562
  1172. package/.worktrees/e58fcc4c/src/run/stage.js +0 -587
  1173. package/.worktrees/e58fcc4c/src/run.js +0 -23
  1174. package/.worktrees/e58fcc4c/src/scan-diff.js +0 -388
  1175. package/.worktrees/e58fcc4c/src/scan-postcheck.js +0 -524
  1176. package/.worktrees/e58fcc4c/src/scan-staleness.js +0 -95
  1177. package/.worktrees/e58fcc4c/src/setup.js +0 -414
  1178. package/.worktrees/e58fcc4c/src/sillyhub-mcp/client.js +0 -597
  1179. package/.worktrees/e58fcc4c/src/sillyhub-mcp/config.js +0 -62
  1180. package/.worktrees/e58fcc4c/src/spec-dir-typo.js +0 -50
  1181. package/.worktrees/e58fcc4c/src/spec-sync.js +0 -358
  1182. package/.worktrees/e58fcc4c/src/stage-contract-engine.js +0 -171
  1183. package/.worktrees/e58fcc4c/src/stage-contract-spec.js +0 -551
  1184. package/.worktrees/e58fcc4c/src/stage-contract.js +0 -948
  1185. package/.worktrees/e58fcc4c/src/stage-review.js +0 -597
  1186. package/.worktrees/e58fcc4c/src/stages/archive.js +0 -199
  1187. package/.worktrees/e58fcc4c/src/stages/brainstorm-auto.js +0 -285
  1188. package/.worktrees/e58fcc4c/src/stages/brainstorm.js +0 -624
  1189. package/.worktrees/e58fcc4c/src/stages/cmd-existence.js +0 -145
  1190. package/.worktrees/e58fcc4c/src/stages/doctor.js +0 -540
  1191. package/.worktrees/e58fcc4c/src/stages/execute.js +0 -1277
  1192. package/.worktrees/e58fcc4c/src/stages/explore.js +0 -43
  1193. package/.worktrees/e58fcc4c/src/stages/index.js +0 -29
  1194. package/.worktrees/e58fcc4c/src/stages/knowledge.js +0 -514
  1195. package/.worktrees/e58fcc4c/src/stages/plan-postcheck.js +0 -1398
  1196. package/.worktrees/e58fcc4c/src/stages/plan.js +0 -655
  1197. package/.worktrees/e58fcc4c/src/stages/quick.js +0 -167
  1198. package/.worktrees/e58fcc4c/src/stages/scan.js +0 -608
  1199. package/.worktrees/e58fcc4c/src/stages/status.js +0 -64
  1200. package/.worktrees/e58fcc4c/src/stages/verify.js +0 -246
  1201. package/.worktrees/e58fcc4c/src/sync.js +0 -1470
  1202. package/.worktrees/e58fcc4c/src/task-review.js +0 -1498
  1203. package/.worktrees/e58fcc4c/src/taskcard-placeholders.js +0 -21
  1204. package/.worktrees/e58fcc4c/src/taskcard.js +0 -250
  1205. package/.worktrees/e58fcc4c/src/verify-postcheck.js +0 -1718
  1206. package/.worktrees/e58fcc4c/src/verify-probes.js +0 -327
  1207. package/.worktrees/e58fcc4c/src/version.js +0 -19
  1208. package/.worktrees/e58fcc4c/src/workflow.js +0 -600
  1209. package/.worktrees/e58fcc4c/src/workspace.js +0 -125
  1210. package/.worktrees/e58fcc4c/src/worktree-apply.js +0 -1611
  1211. package/.worktrees/e58fcc4c/src/worktree-deps.js +0 -668
  1212. package/.worktrees/e58fcc4c/src/worktree.js +0 -1849
  1213. package/.worktrees/e58fcc4c/templates/claude-instruction.md +0 -23
  1214. package/.worktrees/e58fcc4c/templates/prompts/taskcard-rules.md +0 -29
  1215. package/.worktrees/e58fcc4c/templates/prompts/testcase-design.md +0 -12
  1216. package/.worktrees/e58fcc4c/templates/prompts/verify-probes.md +0 -32
  1217. package/.worktrees/e58fcc4c/templates/workflows/archive-impact.yaml +0 -79
  1218. package/.worktrees/e58fcc4c/templates/workflows/scan-docs.yaml +0 -132
  1219. package/templates/claude-instruction.md +0 -23
@@ -1,1552 +0,0 @@
1
- /**
2
- * run/complete-handlers.js(W6 Step5 从 run.js 抽出)。
3
- *
4
- * completeStep 的子 handler + archive 收尾(自洽叶子模块,仅被 completeStep 调用):
5
- * - handleArchiveConfirmStep:archive「确认归档」步骤 --confirm 门控 + 推荐文档校验
6
- * - handlePlanGeneratePlanStep:plan「generate_plan」完成后动态插入 coordinator + postcheck 步骤
7
- * - handleScanProjectListStep:scan step 2 完成后按项目展开 perProject 步骤(用 sanitizeProjectName/validateParsedProjects)
8
- * - archiveChangeDirectory:归档移动变更目录(6 处 process.exit(1) + worktree 清理;handleArchiveConfirmStep 内部调用)
9
- * srcDir 缺失时走 findAlreadyArchivedDir 幂等自愈(issue archive-stage-physical-tracking-desync);
10
- * archiveChangeDirectory + findAlreadyArchivedDir 已 export 供 test 直接 import
11
- * - sanitizeProjectName / validateParsedProjects:项目名清洗 + 列表校验纯函数(handleScanProjectListStep 专用)
12
- *
13
- * 安全锚:run.js 始终 barrel。3 handler 由 run.js import 回来;sanitizeProjectName + validateParsedProjects
14
- * 被 test 直接 import(run-sanitize-project-name / run-scan-project-parse),run.js barrel re-export 契约保留。
15
- * 4 目标 handler 无 test 直接 import;archiveChangeDirectory + findAlreadyArchivedDir 供自愈 test 直接 import,无需 barrel re-export。completeStep(Step7 搬)将把 import 行带走。
16
- *
17
- * 路径修正(相对 src/run/):
18
- * - resolveChangeDir 从 './shared.js';renameSyncRetry 从 '../fs-atomic.js';stageRegistry 从 '../stages/index.js'
19
- * - 动态 import './stages/plan.js' / './worktree.js' → '../'(src/ 下,退一层;真环依赖保留动态)
20
- * - 删除 archiveChangeDirectory 内死代码 `const { renameSync } = await import('fs')`(renameSync 解构未用,实际走 renameSyncRetry)
21
- *
22
- * archiveChangeDirectory 的 6 处 process.exit 全 exit(1):5 个顶层 guard 直接终止;L1325 在 catch 内主动 exit
23
- * (非被外层吞);process.exit 不可被 try 捕获 → 搬迁行为完全等价。
24
- */
25
- import { basename, join, resolve, relative, isAbsolute } from 'node:path'
26
- import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, rmSync } from 'node:fs'
27
- import { renameSyncRetry, writeAtomicSync } from '../fs-atomic.js'
28
- import { resolveChangeDir, resolveQuickSessionsDir, safeGit, auditQuickCompletion, triggerSync, isQuickMetadata, resolveRuntimeRoot, collectOtherQuickSessionDeclarations } from './shared.js'
29
- import { detectConcurrentChanges, formatConcurrentWarning, resolveConcurrentAnchor } from './concurrent-detect.js'
30
- import { stageRegistry } from '../stages/index.js'
31
- import { SCAN_STATUS, POINTER_STATUS } from '../constants.js'
32
- import { printQuickAuditReview } from './quick-audit.js'
33
- import { validateQuickResult, allocateQuicklogEntry, findQuicklogEntry, completeQuicklogEntry, extractTitleFromResult } from '../quicklog.js'
34
- import { getRule } from '../stage-contract-spec.js'
35
- import { archiveDestDirName } from '../stage-contract.js'
36
-
37
- /**
38
- * 清洗项目名:只保留 ASCII 字母/数字/横线/下划线/点,过滤中文和特殊字符。
39
- * - 必须含至少一个字母(拒绝纯数字 "0"/"7"/"07",避免 scan-projects.json 脏数据)
40
- * - 长度必须 ≥ 2(拒绝单字符 "a"/"0")
41
- * @param {string} name - 原始项目名候选
42
- * @returns {string | null} 合法项目名或 null(拒绝)
43
- */
44
- export function sanitizeProjectName(name) {
45
- if (!name) return null
46
- const clean = String(name).replace(/[^a-zA-Z0-9_\-.]/g, '').trim()
47
- if (!clean) return null
48
- if (!/[a-zA-Z]/.test(clean)) return null // 纯数字/符号拒绝("0"/"7"/"07")
49
- if (clean.length < 2) return null // 单字符拒绝("a"/"0")
50
- return clean
51
- }
52
- /**
53
- * 校验从 step 2 解析出的项目列表。
54
- * 不通过则不落盘 projects/*.yaml、不展开 perProject 步骤。
55
- *
56
- * @param {Array<{id: string, path?: string}>} projects - 项目列表(含可选 path)
57
- * @param {string} sourceRoot - 源码根目录,用于 path 安全校验
58
- */
59
- export function validateParsedProjects(projects, sourceRoot) {
60
- const errors = []
61
- if (!projects || projects.length === 0) {
62
- return { ok: false, errors: ['项目列表为空'] }
63
- }
64
- if (projects.length > 10) {
65
- return { ok: false, errors: [`项目数量 ${projects.length} 超过上限 10,疑似误解析`] }
66
- }
67
- const safeRoot = resolve(sourceRoot)
68
- const seen = new Set()
69
- for (const proj of projects) {
70
- const id = proj.id || proj
71
- if (seen.has(id)) {
72
- errors.push(`重复项目名: ${id}`)
73
- }
74
- seen.add(id)
75
- // slug 合法性:只允许 a-z 0-9 _ - .,长度 2-64
76
- if (!/^[a-zA-Z][\w\-.]{1,63}$/.test(id)) {
77
- errors.push(`项目名 "${id}" 不合法(需 slug 格式:字母开头,只含 a-zA-Z0-9_-., 长度 2-64)`)
78
- }
79
- // path 安全校验(如果提供了 path)
80
- if (proj.path) {
81
- if (proj.path.includes('..')) {
82
- errors.push(`项目 "${id}" 的 path 包含 .. ,拒绝越界`)
83
- } else {
84
- const absPath = resolve(safeRoot, proj.path)
85
- const rel = relative(safeRoot, absPath)
86
- if (rel.startsWith('..') || isAbsolute(rel)) {
87
- errors.push(`项目 "${id}" 的 path "${proj.path}" 解析后超出 source_root`)
88
- }
89
- if (!existsSync(absPath)) {
90
- errors.push(`项目 "${id}" 的 path "${proj.path}" 不存在`)
91
- }
92
- }
93
- }
94
- }
95
- if (errors.length > 0) return { ok: false, errors }
96
- return { ok: true, errors: [] }
97
- }
98
- /**
99
- * 在 changes/archive/ 下查找变更 <changeName> 是否已被归档(archive 脱钩自愈用)。
100
- *
101
- * 归档目录名 = 原变更名(直接移入 archive/,不重命名)。
102
- * 精确匹配 + 要求目录含 plan.md(归档必备产物,防止同名巧合误判)。
103
- * issue: archive-stage-physical-tracking-desync。
104
- *
105
- * @param {string} archiveDir - changes/archive 绝对路径
106
- * @param {string} changeName - 变更名(currentChange)
107
- * @returns {string|null} 命中的归档目录绝对路径,无则 null
108
- */
109
- export function findAlreadyArchivedDir(archiveDir, changeName) {
110
- if (!existsSync(archiveDir)) return null
111
- let entries
112
- try {
113
- entries = readdirSync(archiveDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
114
- } catch {
115
- return null
116
- }
117
- // 精确原名命中
118
- const exact = entries.find((e) => e === changeName && existsSync(join(archiveDir, e, 'plan.md')))
119
- if (exact) return join(archiveDir, exact)
120
- return null
121
- }
122
-
123
- /**
124
- * 归档时清理可能残留的 worktree(execute 自动清理未走到 / 有未 apply 变更被遗弃)。
125
- * 安全策略:有未 apply 变更时保留 worktree 并警告,避免误删用户未应用的代码。
126
- * 同时清理该变更的 execute / stage-review runId marker(只写不删的累积物,
127
- * 见 stage.js execute 启动固定 executeRunId / stage-review.js stageReviewMarkerPath)。
128
- * 从 archiveChangeDirectory 抽出,供正常归档 + 自愈归档复用。
129
- */
130
- export async function archiveWorktreeCleanup(cwd, archiveChangeName, specBase, platformOpts = {}) {
131
- // ── 清理 runId marker:execute(current-execute-run-id-<change>)与 stage-review
132
- // (current-stage-review-run-id-<stage>-<change>)。marker 只服务 execute→verify→archive
133
- // 期间,归档后无读者;不删则 .runtime 随变更数无限累积。runtimeRoot 解析同写入侧
134
- // (resolveRuntimeRoot 锚主仓),避免平台模式清理错位置。
135
- try {
136
- const runtimeRoot = resolveRuntimeRoot(platformOpts, specBase)
137
- if (existsSync(runtimeRoot)) {
138
- // stage-review marker 精确匹配(坑 marker-suffix-overmatch):marker 名是
139
- // current-stage-review-run-id-<stage>-<change>,按 endsWith('-'+change) 后缀匹配会在归档
140
- // 手工短名变更(如 login)时误删自动日期前缀变更(2026-08-01-login 天然以 '-login' 结尾)
141
- // 的 marker。stage 集合与写入侧 stageReviewMarkerPath 的调用方一致。
142
- const REVIEW_STAGES = ['brainstorm', 'plan', 'execute', 'verify', 'archive']
143
- const markers = readdirSync(runtimeRoot).filter((f) =>
144
- f === `current-execute-run-id-${archiveChangeName}` ||
145
- REVIEW_STAGES.some(st => f === `current-stage-review-run-id-${st}-${archiveChangeName}`),
146
- )
147
- for (const m of markers) {
148
- try { unlinkSync(join(runtimeRoot, m)) } catch {}
149
- }
150
- if (markers.length > 0) {
151
- console.log(`🧹 归档清理 ${markers.length} 个 runId marker(execute/stage-review)`)
152
- }
153
- }
154
- } catch (e) {
155
- console.warn(`⚠️ 归档 runId marker 清理失败(不阻断归档): ${e.message}`)
156
- }
157
- try {
158
- const { WorktreeManager } = await import('../worktree.js')
159
- const wm = new WorktreeManager({ cwd })
160
- const meta = wm.getMeta(archiveChangeName)
161
- if (!meta) {
162
- // 无 meta 兜底(坑 archive-cleanup-orphan-physical-dir,2026-08-21 实证):meta 已被先行
163
- // 流程注销(apply 自动 cleanup / doctor 幽灵清理)时此前直接 return——若物理目录因中途
164
- // 失败残留下就是孤儿(无 meta=无锚定基准,残留即孤儿)。force 清理(幂等:什么都不存在
165
- // 时 cleanup 返回 skipped 零副作用)。
166
- const orphan = wm.cleanup(archiveChangeName, { force: true })
167
- if (orphan.result === 'cleaned' || orphan.result === 'force-cleaned' || orphan.result === 'partial') {
168
- console.log(`🧹 归档清理孤儿 worktree 残留(meta 已注销): ${archiveChangeName}${orphan.residual?.length ? '(残留: ' + orphan.residual.join('; ') + ')' : ''}`)
169
- }
170
- return
171
- }
172
- const check = meta.mode !== 'in-place-fallback' ? wm.hasUnappliedChanges(archiveChangeName) : { hasChanges: false }
173
- if (check.hasChanges) {
174
- console.warn(`⚠️ 归档时 worktree 仍有 ${check.changedFiles.length} 个未 apply 变更,保留 worktree`)
175
- console.warn(` 确认不需要后手动清理: sillyspec worktree cleanup ${archiveChangeName} --force`)
176
- return
177
- }
178
- const cleanResult = wm.cleanup(archiveChangeName)
179
- if (cleanResult.residual?.length > 0) {
180
- console.warn(`⚠️ 归档 worktree 清理残留: ${cleanResult.residual.join('; ')}`)
181
- console.warn(` 手动处理: sillyspec worktree cleanup ${archiveChangeName} --force`)
182
- }
183
- } catch (e) {
184
- console.warn(`⚠️ 归档 worktree 清理失败(不阻断归档): ${e.message}`)
185
- }
186
- }
187
-
188
- /**
189
- * 提取 module-impact.md「更新结果」表中的未清文档同步死信行(债单 D-5)。
190
- *
191
- * 只在「## 更新结果」段内扫描表格行(| 分隔),状态判定取**末列** trim 后精确匹配
192
- * pending / 待办 / 未同步 / not-done(大小写不敏感)。不做全文 grep——
193
- * sync_manual_get_pending / pending_review / pending-leases 等代码标识符出现在
194
- * 矩阵摘要列是合法内容,不能误报(实证:archive 全量扫描唯一死信形态是末列 pending)。
195
- *
196
- * 纯函数:无 fs/git 调用,export 供 test 直接 import。
197
- * @param {string} content module-impact.md 全文(CRLF/LF 均容)
198
- * @returns {string[]} 死信行原文(去首尾空白),空数组 = 无死信
199
- */
200
- export function extractPendingDocSyncRows(content) {
201
- if (!content || typeof content !== 'string') return []
202
- const normalized = content.replace(/\r\n/g, '\n')
203
- const sectionStart = normalized.search(/^#{2,3}\s*更新结果\s*$/m)
204
- if (sectionStart === -1) return []
205
- // 跳过标题行本身(matchFirstLine 吃掉标题),再找下一个章节边界
206
- const titleMatch = normalized.slice(sectionStart).match(/^#{2,3}\s*更新结果\s*$/m)
207
- const bodyStart = sectionStart + titleMatch[0].length
208
- const afterTitle = normalized.slice(bodyStart)
209
- const nextSection = afterTitle.search(/^#{1,3}\s/m)
210
- const section = nextSection === -1 ? afterTitle : afterTitle.slice(0, nextSection)
211
- const PENDING_STATUSES = new Set(['pending', '待办', '未同步', 'not-done', 'todo'])
212
- const rows = []
213
- for (const line of section.split('\n')) {
214
- const trimmed = line.trim()
215
- if (!trimmed.startsWith('|')) continue
216
- const cells = trimmed.split('|').map(c => c.trim())
217
- // split 首尾产生空串(行首行尾的 |),真实单元格在中间;末列 = 最后一个非空单元格之后
218
- // 表格行结构 | 模块文档 | 操作 | 状态 | → cells = ['', '模块文档', '操作', '状态', '']
219
- const lastCell = cells[cells.length - 1]
220
- if (lastCell === '' && cells.length >= 2) cells.pop()
221
- const statusCell = cells[cells.length - 1]
222
- if (statusCell && PENDING_STATUSES.has(statusCell.toLowerCase())) rows.push(trimmed)
223
- }
224
- return rows
225
- }
226
-
227
- /**
228
- * 提取 module-impact.md「更新结果」表中的已完成(done)行声明的目标文档路径(债单 D-4 窄口径)。
229
- *
230
- * done 行首列是目标标识:`modules/<id>.md`(模块卡片)、`_module-map.yaml`(映射索引)、
231
- * `.sillyspec/docs/<project>/modules/<f>.md`(含仓库前缀的全路径)等。本函数提取首列里
232
- * 能解析出的文档路径 token,供调用方校验文件存在性——声明 done 但目标文件不存在 = 假申报。
233
- *
234
- * 提取规则(保守,宁可漏报不误报):
235
- * - 首列以反引号包裹或裸写的 `.md`/`.yaml` 结尾路径 token(含路径分隔符 /)
236
- * - `modules/<id>.md` 相对写法解析为 `<specBase>/docs/<project>/modules/<id>.md`——但 project
237
- * 归属需读 _module-map,此处只返回原样 token,路径解析留给调用方(有 specBase 上下文)
238
- * - `_module-map.yaml` 裸名跳过(存在性由 map 本身保证,且各项目都有)
239
- *
240
- * 纯函数:无 fs/git 调用,export 供 test 直接 import。
241
- * @param {string} content module-impact.md 全文
242
- * @returns {string[]} done 行声明的文档路径 token(去重)
243
- */
244
- export function extractDoneDocTargets(content) {
245
- if (!content || typeof content !== 'string') return []
246
- const normalized = content.replace(/\r\n/g, '\n')
247
- const sectionStart = normalized.search(/^#{2,3}\s*更新结果\s*$/m)
248
- if (sectionStart === -1) return []
249
- const titleMatch = normalized.slice(sectionStart).match(/^#{2,3}\s*更新结果\s*$/m)
250
- const bodyStart = sectionStart + titleMatch[0].length
251
- const afterTitle = normalized.slice(bodyStart)
252
- const nextSection = afterTitle.search(/^#{1,3}\s/m)
253
- const section = nextSection === -1 ? afterTitle : afterTitle.slice(0, nextSection)
254
- const targets = new Set()
255
- for (const line of section.split('\n')) {
256
- const trimmed = line.trim()
257
- if (!trimmed.startsWith('|')) continue
258
- const cells = trimmed.split('|').map(c => c.trim())
259
- if (cells.length >= 2) cells.pop() // 行尾空 cell
260
- const statusCell = cells[cells.length - 1]
261
- if (!statusCell || statusCell.toLowerCase() !== 'done') continue
262
- // 首个非空 cell(跳过 split 产生的行首空串)
263
- const firstCell = cells.slice(1).find(c => c !== '') || ''
264
- // 从首列提取 .md/.yaml 结尾且含 / 的路径 token(modules/x.md 或 a/b/c.yaml);
265
- // 反引号包裹优先,裸写次之。_module-map.yaml 无 / 跳过(见 docstring)。
266
- const m = firstCell.match(/`([^`]*\.(?:md|yaml))`/) || firstCell.match(/(^|\s|()([\w./-]+\/[\w./-]*\.(?:md|yaml))/)
267
- if (m) {
268
- const token = (m[2] !== undefined && m[2] !== null && m[1] !== '`') ? m[2] : m[1]
269
- if (token && !token.endsWith('_module-map.yaml')) targets.add(token)
270
- }
271
- }
272
- return [...targets]
273
- }
274
-
275
- export async function archiveChangeDirectory(pm, cwd, progress, specBase, platformOpts = {}) {
276
- const archiveChangeName = progress.currentChange
277
- if (!archiveChangeName) {
278
- console.error('❌ 归档失败:未找到当前变更名(currentChange)')
279
- process.exit(1)
280
- }
281
- const changesDir = join(specBase, 'changes')
282
- const archiveDir = join(changesDir, 'archive')
283
- const srcDir = join(changesDir, archiveChangeName)
284
- const date = new Date().toISOString().slice(0, 10)
285
- const destName = archiveDestDirName(date, archiveChangeName)
286
- const destDir = join(archiveDir, destName)
287
-
288
- if (!existsSync(srcDir)) {
289
- // 幂等自愈(issue archive-stage-physical-tracking-desync):源目录已不存在,但变更可能已被
290
- // 手动 / 部分流程移到 changes/archive/ 并 commit,而 --done --confirm 从未正式跑完 → 进度 DB
291
- // 卡 archive 阶段、active 列表仍列此 change。检测到已归档则回填进度(unregisterChange)并
292
- // 成功返回,让收尾流程把 archive 阶段标完成,而非 exit(1) 死路(source 已移走无法重跑 move)。
293
- const alreadyArchivedDir = findAlreadyArchivedDir(archiveDir, archiveChangeName)
294
- if (alreadyArchivedDir) {
295
- console.log(`ℹ️ 源目录不存在但变更已在 archive/(${basename(alreadyArchivedDir)}),判定已归档,自愈进度 DB`)
296
- // 终态一致化(坑 manual-archive-desync-status-only):手动搬目录绕过标准归档后,本自愈路径
297
- // 不能只翻 status——同时收尾 archive 阶段(steps/stages/current_stage),否则推送平台的终态
298
- // 是「已归档 + 归档 0/5 + 停在 execute」的矛盾体,详情页渲染成「进度丢失」
299
- pm.unregisterChange(cwd, archiveChangeName, { archiveStepNames: typeof pm.archiveStepNamesForArchive === 'function' ? pm.archiveStepNamesForArchive() : null })
300
- await archiveWorktreeCleanup(cwd, archiveChangeName, specBase, platformOpts)
301
- console.log(`📦 已自愈归档:${archiveChangeName} → archive/${basename(alreadyArchivedDir)}/`)
302
- return alreadyArchivedDir
303
- }
304
- console.error(`❌ 归档失败:源目录不存在 ${srcDir}`)
305
- console.error(` 且 changes/archive/ 下未找到该变更的归档目录。若已手动归档请核对目录名;否则先补全变更产物。`)
306
- process.exit(1)
307
- }
308
- // 移动前硬校验:变更包必须含 plan.md,否则不该归档。
309
- // 在移动前阻断(而非移动后),目录尚未动,用户可直接修复后重试。
310
- if (!existsSync(join(srcDir, 'plan.md'))) {
311
- console.error(`❌ 归档失败:变更目录缺少 plan.md(${srcDir})`)
312
- console.error(` plan.md 是归档的必需产物。请先补全 plan 阶段产出再归档。`)
313
- process.exit(1)
314
- }
315
- // 移动前硬校验(债单 D-5):module-impact.md「更新结果」表存在 pending 死信 → 阻断。
316
- // 修复场景:perf-remediation 类变更把文档同步显式推给 archive(「(execute 完成后由 archive
317
- // 阶段同步)| 待办 | pending」),archive 又没做 → 带 pending 归档且 verify 全 PASS,死信无人回填。
318
- // 只查「## 更新结果」段内表格行的状态列(末列)精确匹配 pending/待办/未同步——不做全文 grep,
319
- // 防 sync_manual_get_pending / pending_review 等代码标识符误报。
320
- const impactPath = join(srcDir, 'module-impact.md')
321
- if (existsSync(impactPath)) {
322
- const pendingRows = extractPendingDocSyncRows(readFileSync(impactPath, 'utf8'))
323
- if (pendingRows.length > 0) {
324
- console.error(`❌ 归档失败:module-impact.md「更新结果」表存在 ${pendingRows.length} 个未清 pending/待办项(死信)`)
325
- for (const row of pendingRows) console.error(` - ${row}`)
326
- console.error(` 这些文档同步项从未落地。请先完成同步并回填状态为 done/skipped(说明原因),再归档。`)
327
- process.exit(1)
328
- }
329
- }
330
- if (existsSync(destDir)) {
331
- console.error(`❌ 归档失败:目标目录已存在 ${destDir}`)
332
- process.exit(1)
333
- }
334
- mkdirSync(archiveDir, { recursive: true })
335
- try {
336
- renameSyncRetry(srcDir, destDir)
337
- } catch (e) {
338
- console.error(`❌ 归档失败:移动变更目录时出错(${e.message})`)
339
- console.error(` 常见原因:变更目录内文件被 IDE / 杀毒 / 索引占用,已重试 5 次仍失败。请关闭相关程序后重试。`)
340
- process.exit(1)
341
- }
342
-
343
- if (!existsSync(destDir) || existsSync(srcDir)) {
344
- console.error('❌ 归档校验失败:移动操作异常')
345
- process.exit(1)
346
- }
347
-
348
- // 正常路径同样走终态一致化(坑 manual-archive-desync-status-only):标准 --done --confirm 流程
349
- // 中 completeStep 随后也会逐项完成,此处先收尾是幂等写同值——保证任何走出本函数的归档终态一致
350
- pm.unregisterChange(cwd, archiveChangeName, { archiveStepNames: typeof pm.archiveStepNamesForArchive === 'function' ? pm.archiveStepNamesForArchive() : null })
351
-
352
- // CLI 下沉 git add(坑4,FR-04):确定性暂存归档目录 + 模块文档,不靠 step5 prompt 驱动。
353
- // step5 prompt 的 git add 保留作幂等兜底;POSIX 路径跨平台(git 接受正斜杠)。
354
- // safeGit 内部已 try-catch(返回 {value,error} 不抛),外层 try 兜底防御;失败不阻断归档
355
- // (目录已移动 + change 已注销),由 step5 prompt git add + agent git status 核对兜底。
356
- try {
357
- safeGit(cwd, ['add', '--', '.sillyspec/changes/archive/'])
358
- safeGit(cwd, ['add', '--', '.sillyspec/docs/'])
359
- } catch {}
360
-
361
- // ── 他者半归档残留探测(坑 archive-other-residual-rename,2026-08-21 实证)──
362
- // 并行变更的手动归档把 R 残留(源目录 rename 目标行)留在暂存区;本变更归档提交时
363
- // git status 显示它们,agent 会误判「还没提交完 / 要做第二次提交」。区分:
364
- // 本变更:未暂存的源侧移动(` D changes/<me>/...` + 未跟踪 archive/<me>/...)→ 补暂存
365
- // 让归档成单次原子提交;
366
- // 他者:已暂存的 rename(`R changes/<他人>/... -> changes/archive/<他人>/...`)→ 只 warn
367
- // 提示归属(不 stage 不动——别人的归别人的)。
368
- try {
369
- const raw = gitQuiet(cwd, ['status', '--porcelain'], { trim: false, timeout: 30000 })
370
- if (raw && raw.trim()) {
371
- const changesPrefix = '.sillyspec/changes/'
372
- const minePaths = []
373
- const othersResidual = []
374
- for (const line of raw.split('\n')) {
375
- if (!line || line.length < 4) continue
376
- const x = line[0], y = line[1]
377
- const body = line.slice(3).trim()
378
- const arrow = body.indexOf(' -> ')
379
- const src = arrow !== -1 ? body.slice(0, arrow).replace(/^"|"$/g, '') : null
380
- const dst = (arrow !== -1 ? body.slice(arrow + 4) : body).replace(/^"|"$/g, '')
381
- if (x === 'R' && y === ' ' && arrow !== -1 && dst.startsWith(changesPrefix + 'archive/')) {
382
- // 已暂存 rename → 半归档残留;按目标目录名归属他者变更
383
- const m = /^\.sillyspec\/changes\/archive\/([^/]+)\//.exec(dst)
384
- const owner = m ? m[1] : '?'
385
- if (owner !== archiveChangeName) othersResidual.push(owner)
386
- } else if (x === ' ' && (y === 'D' || y === 'A' || y === 'M')) {
387
- // 未暂存的源侧移动:源目录 D / 新位置 A——指向本变更的补暂存
388
- const p = dst || src
389
- if (p && (p.startsWith(changesPrefix + archiveChangeName + '/')
390
- || p.startsWith(changesPrefix + 'archive/' + archiveChangeName + '/'))) {
391
- minePaths.push(p)
392
- }
393
- }
394
- }
395
- if (minePaths.length > 0) {
396
- try { safeGit(cwd, ['add', '-A', '--', changesPrefix]) } catch {}
397
- console.log(`🧾 已补暂存本变更归档的源侧移动(${minePaths.length} 项,归档成单次原子提交)`)
398
- }
399
- if (othersResidual.length > 0) {
400
- const owners = [...new Set(othersResidual)].filter(Boolean)
401
- console.warn(`⚠️ 检测到「他者半归档」残留(暂存区存在其他变更的 rename 记录):${owners.join('、')}`)
402
- console.warn(` 这些是别的变更此前手动归档留下的暂存项,不属于本次归档——git status 里看到它们是正常的,`)
403
- console.warn(` 本变更归档已完成,无需为其做第二次提交;如需清理走它们自己的收尾(或 git restore --staged 后核对)。`)
404
- }
405
- }
406
- } catch { /* 探测失败不阻断归档(advisory) */ }
407
-
408
- // 归档时清理可能残留的 worktree(自愈路径也复用,见上方 srcDir 缺失分支)。
409
- await archiveWorktreeCleanup(cwd, archiveChangeName, specBase, platformOpts)
410
-
411
- console.log(`📦 已归档:${archiveChangeName} → archive/${destName}/`)
412
- return destDir
413
- }
414
- /**
415
- * archive 阶段「确认归档」步骤的收尾处理器(从 completeStep 抽出,行为保持)。
416
- *
417
- * 两件事:
418
- * 1. --confirm 门控:缺 --confirm → 回退 step 状态、提示、返回 early-return 对象(completeStep 透传)
419
- * 2. --confirm 通过 → archiveChangeDirectory 移动变更目录 + 推荐文档(design.md / module-impact.md)校验
420
- * (contracts.archive.validators 为空,两个 validator 生效窗口互斥;plan.md 已在移动前硬校验阻断)
421
- *
422
- * @returns {{stageCompleted:false,currentIdx,nextPendingIdx:number}|null}
423
- */
424
- export async function handleArchiveConfirmStep({ stageName, steps, currentIdx, confirm, outputText, pm, cwd, progress, changeName, specBase, platformOpts = {} }) {
425
- if (stageName !== 'archive' || steps[currentIdx]?.name !== '确认归档') return null
426
- if (!confirm) {
427
- steps[currentIdx].status = 'pending'
428
- steps[currentIdx].completedAt = null
429
- if (outputText) steps[currentIdx].output = null
430
- pm._write(cwd, progress, changeName)
431
- console.log('⚠️ 请添加 --confirm 确认归档,例如:sillyspec run archive --done --confirm --output "确认归档"')
432
- return { stageCompleted: false, currentIdx, nextPendingIdx: currentIdx }
433
- }
434
- // 主仓互斥锁(坑 main-repo-no-mutex 二批):archiveChangeDirectory 改主仓共享状态(目录
435
- // rename + 共享 index 的 git add + marker 删除 + worktree 清理),与并行会话的 apply/cleanup
436
- // 互踩。exit 钩子兜底:其内部 guard 失败 exit(1) 时锁也会被清(见 withMainRepoLock)。
437
- const { withMainRepoLock } = await import('../worktree-apply.js')
438
- const archivedDir = await withMainRepoLock(cwd, changeName, 'archive-finalize', () => archiveChangeDirectory(pm, cwd, progress, specBase, platformOpts))
439
- if (archivedDir && existsSync(archivedDir)) {
440
- // 内存快照同步(坑 archive-progress-show-stale,2026-08-21 实证):archiveChangeDirectory 内
441
- // unregisterChange 已在 DB 写 current_stage='archive'(终态一致化),但本进程 progress 是命令
442
- // 开始时读的旧快照——不同步的话,completeStep 后续 _write 会用旧值(如停在 verify)把
443
- // DB 覆盖回去,progress show 就一直显示归档前的阶段
444
- progress.currentStage = 'archive'
445
- const recommendedDocs = ['design.md', 'module-impact.md']
446
- const missingRecommended = recommendedDocs.filter(d => !existsSync(join(archivedDir, d)))
447
- if (missingRecommended.length > 0) {
448
- console.warn(`\n⚠️ 归档校验警告:归档目录缺少推荐文档`)
449
- for (const d of missingRecommended) console.warn(` - ${d}(${archivedDir})`)
450
- } else {
451
- console.log(`\n✅ 归档校验通过:核心文档齐全`)
452
- }
453
- // D-4 窄口径:更新结果表 done 行声明的目标文档存在性对账(warning 不阻断——
454
- // 目标路径写法多样(modules/x.md 相对/全路径)+ 语义对账推 sillyhub,此处只抓
455
- // 能确定性解析且确实不存在的假申报)。
456
- const impactContent = existsSync(join(archivedDir, 'module-impact.md'))
457
- ? readFileSync(join(archivedDir, 'module-impact.md'), 'utf8') : ''
458
- const doneTargets = extractDoneDocTargets(impactContent)
459
- if (doneTargets.length > 0) {
460
- const missing = doneTargets.filter(t => {
461
- // 相对 specBase 解析:modules/<x> → docs/<project>/modules/<x> 由 _module-map 归属,
462
- // CLI 不猜 project——只对全路径(.sillyspec/docs/ 开头或含 3+ 段路径)做存在性判定
463
- if (!t.includes('/')) return false
464
- const abs = isAbsolute(t) ? t : resolve(cwd, t)
465
- return !existsSync(abs)
466
- })
467
- if (missing.length > 0) {
468
- console.warn(`\n⚠️ 归档校验警告:module-impact「更新结果」声明 done 的文档路径不存在(假申报嫌疑)`)
469
- for (const t of missing) console.warn(` - ${t}`)
470
- console.warn(` 相对写法(modules/<id>.md)不在此校验范围;全路径声明但文件不存在请核实。`)
471
- }
472
- }
473
- }
474
- return null
475
- }
476
- /**
477
- * plan 阶段「generate_plan」步骤完成后,动态插入任务蓝图(coordinator)+ postcheck 步骤
478
- * (从 completeStep 抽出,行为保持)。使用稳定 id 匹配,不依赖中文标题。
479
- *
480
- * plan.md 已含任务时,buildPlanSteps 返回 [fixedPrefix(classify/generate_plan/review_plan),
481
- * coordinator, postcheck];本函数把 generate_plan 之后的 coordinator+postcheck 插到当前步后。
482
- */
483
- export async function handlePlanGeneratePlanStep({ stageName, steps, currentIdx, defStepsForCurrent, cwd, progress }) {
484
- if (stageName !== 'plan') return
485
- const currentStepDef = defStepsForCurrent?.[currentIdx]
486
- const currentStepEntry = steps[currentIdx]
487
- const stepId = currentStepDef?.id || currentStepEntry?.id || currentStepEntry?._stepId
488
- if (stepId !== 'generate_plan') return
489
- const changeDir = resolveChangeDir(cwd, progress)
490
- if (!changeDir) return
491
- const planFile = join(changeDir, 'plan.md')
492
- if (!existsSync(planFile)) return
493
- const planContent = readFileSync(planFile, 'utf8')
494
- const { buildPlanSteps, fixedPrefix, fixedSuffix } = await import('../stages/plan.js')
495
- const fullSteps = buildPlanSteps(changeDir, planContent)
496
- const prefixLen = fixedPrefix.length
497
- const suffixLen = fixedSuffix.length
498
- // 新结构:[...fixedPrefix, coordinatorStep?, postcheckStep?];fixedSuffix 为空,coordinator+postcheck 都在 prefix 之后
499
- const coordinatorSteps = fullSteps.slice(prefixLen, suffixLen > 0 ? -suffixLen : undefined)
500
- if (coordinatorSteps.length === 0) return
501
- for (let i = 0; i < coordinatorSteps.length; i++) {
502
- const stepDef = coordinatorSteps[i]
503
- const stepEntry = {
504
- id: stepDef.id,
505
- name: stepDef.name,
506
- status: 'pending',
507
- prompt: stepDef.prompt || '',
508
- outputHint: stepDef.outputHint,
509
- optional: stepDef.optional
510
- }
511
- // 传递 noAI / _cliAction 属性
512
- if (stepDef.noAI) stepEntry.noAI = true
513
- if (stepDef._cliAction) stepEntry._cliAction = stepDef._cliAction
514
- steps.splice(currentIdx + 1 + i, 0, stepEntry)
515
- }
516
- console.log(` 📝 已动态插入 ${coordinatorSteps.length} 个步骤(${coordinatorSteps.map(s => s.name).join(', ')})`)
517
- }
518
- /**
519
- * scan 阶段 step 2「构建扫描项目列表」完成后,按项目展开 perProject 步骤(从 completeStep 抽出,行为保持)。
520
- *
521
- * 只接受结构化输出(scan_projects YAML block 或 BEGIN_PROJECT_LIST 标记块),校验通过后
522
- * 自动注册 projects/<id>.yaml + 写 scan-projects.json + 把 perProject 步骤按项目展开。
523
- * 不展开 completeStep 提前 return(失败只记 validationError,由 completeStep 继续推进下一步)。
524
- */
525
- export async function handleScanProjectListStep({ stageName, steps, currentIdx, outputText, stageData, specBase, cwd, platformOpts }) {
526
- if (stageName !== 'scan' || steps[currentIdx]?.name !== '构建扫描项目列表') return
527
- // 解析项目列表:只接受结构化输出(YAML block 或 BEGIN_PROJECT_LIST 标记)
528
- // 不再从自由文本猜测项目名——自由文本列表的误解析会导致垃圾项目落盘
529
- let parsedProjects = [] // Array<{id, path?}>
530
- let parsedFromStructuredOutput = false
531
- if (outputText) {
532
- // 格式 A: YAML block — 匹配 scan_projects: 下所有 - id: xxx 条目(含多行属性)
533
- const yamlBlock = outputText.match(/scan_projects:\s*\n([\s\S]+?)(?=$|\n[^\s])/)
534
- if (yamlBlock) {
535
- const entries = [...yamlBlock[1].matchAll(/-\s+id:\s*(\S+)(?:[\s\S]*?)(?=\n\s+-\s+id:|$)/g)]
536
- for (const m of entries) {
537
- const id = sanitizeProjectName(m[1])
538
- if (!id) continue
539
- // 提取可选 path 字段
540
- const pathMatch = m[0].match(/path:\s*(\S+)/)
541
- const entry = pathMatch ? { id, path: pathMatch[1].trim() } : { id }
542
- parsedProjects.push(entry)
543
- }
544
- parsedFromStructuredOutput = parsedProjects.length > 0
545
- }
546
- // 格式 B: BEGIN_PROJECT_LIST ... END_PROJECT_LIST 标记块
547
- if (!parsedFromStructuredOutput) {
548
- const blockMatch = outputText.match(/BEGIN_PROJECT_LIST\s*\n([\s\S]*?)\n*END_PROJECT_LIST/)
549
- if (blockMatch) {
550
- const raw = [...blockMatch[1].matchAll(/^-\s+(\S+)/gm)].map(m => m[1])
551
- parsedProjects = raw.map(s => sanitizeProjectName(s)).filter(Boolean).map(id => ({ id }))
552
- parsedFromStructuredOutput = parsedProjects.length > 0
553
- }
554
- }
555
- }
556
-
557
- const projectNames = parsedProjects.map(p => p.id)
558
-
559
- if (parsedFromStructuredOutput) {
560
- stageData.scanMeta = stageData.scanMeta || {}
561
- stageData.scanMeta.projectListParsed = true
562
- } else {
563
- // 结构化输出未解析到 → 回退读取已有 projects/*.yaml
564
- // 读取时也校验:path 不存在的 yaml 视为垃圾,直接跳过
565
- console.warn('⚠️ step 2 未输出结构化项目列表,回退扫描已注册项目')
566
- stageData.scanMeta = stageData.scanMeta || {}
567
- stageData.scanMeta.projectListParsed = false
568
- const projectsDir = join(specBase, 'projects')
569
- if (existsSync(projectsDir)) {
570
- const yamlFiles = readdirSync(projectsDir).filter(f => f.endsWith('.yaml'))
571
- const fallbackProjects = []
572
- const fallbackSkipped = []
573
- for (const yf of yamlFiles) {
574
- const pName = yf.replace(/\.yaml$/, '')
575
- const yamlContent = readFileSync(join(projectsDir, yf), 'utf8')
576
- const pathMatch = yamlContent.match(/^path:\s*(.+)/m)
577
- const pPath = pathMatch ? pathMatch[1].trim() : pName
578
- // 校验 path 是否存在且在 source_root 内。
579
- // 用 relative 判越界(与 validateParsedProjects 同口径):startsWith 前缀比较
580
- // 无分隔符,C:\repo 会放行兄弟目录 C:\repository2(体检 BUG-13)
581
- const absPath = resolve(cwd, pPath)
582
- const rel = relative(resolve(cwd), absPath)
583
- if (rel.startsWith('..') || isAbsolute(rel)) {
584
- fallbackSkipped.push(`${pName} (path 越界: ${pPath})`)
585
- continue
586
- }
587
- if (!existsSync(absPath)) {
588
- fallbackSkipped.push(`${pName} (path 不存在: ${pPath})`)
589
- continue
590
- }
591
- fallbackProjects.push({ id: pName, path: pPath })
592
- }
593
- if (fallbackSkipped.length > 0) {
594
- console.warn(`⚠️ 跳过 ${fallbackSkipped.length} 个垃圾/过期项目配置:${fallbackSkipped.join(', ')}`)
595
- console.warn(' 建议清理 projects/ 下的无效 yaml 文件')
596
- }
597
- parsedProjects = fallbackProjects
598
- projectNames.length = 0
599
- projectNames.push(...fallbackProjects.map(p => p.id))
600
- }
601
- if (parsedProjects.length === 0) {
602
- // 无结构化输出 + 无合法已有项目 → step 2 失败
603
- console.error('❌ step 2 未输出结构化项目列表,且 projects/ 下无合法项目配置')
604
- console.error(' 请在 --output 中输出 scan_projects YAML block 或 BEGIN_PROJECT_LIST 标记块')
605
- steps[currentIdx].validationError = '未输出结构化项目列表且无合法 fallback'
606
- // 不展开 perProject 步骤,直接跳到下一步
607
- }
608
- }
609
-
610
- // 校验解析出的项目列表(原子守卫:不通过就不落盘)
611
- const validation = validateParsedProjects(parsedProjects, cwd)
612
- if (!validation.ok) {
613
- console.error(`❌ 项目列表校验失败: ${validation.errors.join('; ')}`)
614
- console.error(' step 2 完成,但不展开 perProject 步骤。请检查 --output 中的项目列表。')
615
- steps[currentIdx].validationError = validation.errors.join('; ')
616
- }
617
-
618
- // 自动注册 + 保存 runtime + 展开 perProject 步骤(仅在校验通过时)
619
- const projectsDir = join(specBase, 'projects')
620
- if (validation.ok) {
621
- for (const proj of parsedProjects) {
622
- const pName = proj.id
623
- const projYaml = join(projectsDir, `${pName}.yaml`)
624
- if (!existsSync(projYaml)) {
625
- mkdirSync(projectsDir, { recursive: true })
626
- const candidates = [
627
- join(cwd, pName),
628
- join(cwd, 'backend', pName),
629
- join(cwd, 'packages', pName),
630
- join(cwd, 'apps', pName),
631
- join(cwd, 'services', pName),
632
- ]
633
- const detected = candidates.find(c => existsSync(c))
634
- const regPath = detected || join(cwd, pName)
635
- writeFileSync(projYaml, `name: ${pName}\npath: ${regPath}\nstatus: active\n`)
636
- console.log(` 📝 自动注册子项目: ${pName} → ${regPath}`)
637
- }
638
- }
639
-
640
- // 保存 runtime 状态
641
- const scanStatePath = join(specBase, '.runtime', 'scan-projects.json')
642
- mkdirSync(join(specBase, '.runtime'), { recursive: true })
643
- let scanState = { projects: projectNames, expanded: false }
644
- if (existsSync(scanStatePath)) {
645
- try { scanState = JSON.parse(readFileSync(scanStatePath, 'utf8')) } catch {}
646
- }
647
-
648
- // 收集当前步骤之后所有 perProject 步骤
649
- const stageDef = stageRegistry[stageName]
650
- const allSteps = stageDef?.steps || []
651
- const perProjectSteps = allSteps.filter(s => s.perProject)
652
-
653
- // 防重复展开
654
- const alreadyExpanded = scanState.expanded || steps.some(s => s.name?.match(/\[.+\]\s*$/))
655
- if (!alreadyExpanded && perProjectSteps.length > 0) {
656
- // 找到当前步骤(step 2)在动态 steps 中的位置
657
- const insertBase = currentIdx + 1
658
- let insertPos = insertBase
659
- for (const pName of projectNames) {
660
- // 读取项目配置获取 projectRoot
661
- const projYaml = join(specBase, 'projects', `${pName}.yaml`)
662
- let projectRoot = '.'
663
- if (existsSync(projYaml)) {
664
- const yamlContent = readFileSync(projYaml, 'utf8')
665
- const pathMatch = yamlContent.match(/^path:\s*(.+)/m)
666
- if (pathMatch) projectRoot = pathMatch[1].trim()
667
- }
668
- const docOutputDir = platformOpts.specRoot ? `${specBase}/docs/${pName}` : `.sillyspec/docs/${pName}`
669
- const contextPrefix = `\n---\n## 当前项目\n- **项目名**: ${pName}\n- **项目路径**: ${projectRoot}\n- **文档输出**: ${docOutputDir}\n\n⚠️ 本步骤只处理上面这个项目,不要处理其他项目。\n---\n\n`
670
-
671
- for (const ppStep of perProjectSteps) {
672
- steps.splice(insertPos, 0, {
673
- name: `${ppStep.name} [${pName}]`,
674
- project: pName,
675
- status: 'pending',
676
- prompt: contextPrefix + ppStep.prompt,
677
- outputHint: ppStep.outputHint,
678
- optional: ppStep.optional
679
- })
680
- insertPos++
681
- }
682
- }
683
- // 移除原始的 perProject 步骤(未展开的版本)
684
- for (let i = steps.length - 1; i >= 0; i--) {
685
- if (steps[i].perProject && !steps[i].name?.includes('[')) {
686
- steps.splice(i, 1)
687
- }
688
- }
689
- console.log(` 📝 已按项目展开 ${perProjectSteps.length} 个步骤 × ${projectNames.length} 个项目 = ${perProjectSteps.length * projectNames.length} 个项目步骤`)
690
- console.log(` 📁 扫描项目:${projectNames.join(', ')}`)
691
- // 标记已展开,防止 resume 重复插入
692
- scanState.expanded = true
693
- writeFileSync(scanStatePath, JSON.stringify(scanState))
694
- } // end !alreadyExpanded
695
- } // end validation.ok
696
- }
697
- /**
698
- * Workflow post_check(W6 Step6 从 completeStep 内联块抽出):
699
- * - scan「深度扫描」完成 → 跑 scan-docs workflow postcheck,失败阻断推进(early-return)
700
- * - archive「extract-module-impact」完成 → 跑 archive-impact workflow postcheck(impact-analyzer 结果)
701
- * 返回 early-return 对象({stageCompleted:false,...})由 completeStep 透传;null = 放行。
702
- *
703
- * ctx 字段:stageName/steps/currentIdx/cwd/specBase/progress/platformOpts/changeName(completeStep 局部)。
704
- * 辅助函数直接 import:basename/join/existsSync/readdirSync(顶部静态);loadWorkflow/runPostCheck/
705
- * formatCheckReport/saveWorkflowRun 动态 import ../workflow.js(真环依赖保留动态)。
706
- *
707
- *搬迁清理:删除死代码 `typeof change !== 'undefined'`(completeStep 作用域无 change 变量,恒 null)。
708
- */
709
- export async function handleWorkflowPostCheck({ stageName, steps, currentIdx, cwd, specBase, progress, platformOpts, changeName }) {
710
- // Workflow post_check:scan 深度扫描完成后自动检查产物
711
- if (stageName === 'scan' && steps[currentIdx]?.name?.includes('深度扫描')) {
712
- try {
713
- const { loadWorkflow, runPostCheck, formatCheckReport, saveWorkflowRun } = await import('../workflow.js')
714
- const wf = loadWorkflow(cwd, 'scan-docs')
715
- if (wf) {
716
- // 确定当前项目(优先级链):
717
- // progress.project (dbProjectName,平台模式真实项目名,与 outputStep 占位符渲染对齐)
718
- // > change?.project (变更对象的项目字段,平台模式 change 创建时传入)
719
- // > steps[idx].project (perProject 展开标记,兼容旧模式)
720
- // > steps[idx].name 正则提取 [xxx] 后缀
721
- // > null(回退检查所有项目)
722
- // task-05 修复:日志显示项目名变 frontend 是 perProject 误展开 bug,
723
- // 用 progress.project(与 outputStep 占位符渲染路径一致)修正 myaaa/frontend 分裂。
724
- const currentProjectName = progress.project
725
- || steps[currentIdx].project
726
- || (steps[currentIdx].name.match(/\[([^\]]+)\]\s*$/) || [])[1]
727
- || null
728
-
729
- // 确定要检查的项目列表
730
- let projectsToCheck = []
731
- if (currentProjectName) {
732
- // 按项目展开模式:只检查当前项目
733
- projectsToCheck = [currentProjectName]
734
- } else {
735
- // 兼容旧模式(未展开):检查所有项目
736
- const projectsDir = join(specBase, 'projects')
737
- const projectFiles = existsSync(projectsDir)
738
- ? readdirSync(projectsDir).filter(f => f.endsWith('.yaml'))
739
- : []
740
- projectsToCheck = projectFiles.map(f => f.replace(/\.yaml$/, ''))
741
- }
742
-
743
- let anyFailed = false
744
- for (const pName of projectsToCheck) {
745
- const result = runPostCheck(wf, cwd, pName, {}, specBase)
746
- const report = formatCheckReport(result)
747
- console.log(report)
748
- if (result.status === 'fail') {
749
- anyFailed = true
750
- // retry_prompts 由 _checkWorkflow 自动生成
751
- for (const rp of (result.retry_prompts || [])) {
752
- console.log(`\n🔄 重试提示(项目 ${pName}):\n`)
753
- console.log(rp.prompt)
754
- }
755
- }
756
- const saved = saveWorkflowRun(result, {
757
- cwd,
758
- source: 'run.js',
759
- stage: 'scan',
760
- step: steps[currentIdx]?.name,
761
- ...(platformOpts.runtimeRoot ? { runtimeRoot: platformOpts.runtimeRoot } : {}),
762
- ...(platformOpts.scanRunId ? { scanRunId: platformOpts.scanRunId } : {})
763
- })
764
- if (saved) console.log(`📁 结果已归档:${saved}`)
765
- }
766
- if (anyFailed) {
767
- console.log(`\n⚠️ 存在检查失败项,请按上面的重试提示修复后再继续。`)
768
- // task-07: 阻断推进(与 task-06 平台模式 scan-postcheck 失败分支 return 结构对齐)
769
- // scan 深度扫描产物校验未通过时,不允许 clean success / 进入下一 step,
770
- // 让上层走"完成但不推进"分支,--done 被拒。
771
- return { stageCompleted: false, currentIdx, nextPendingIdx: currentIdx }
772
- }
773
- }
774
- } catch (e) {
775
- console.warn(`⚠️ workflow 检查跳过:${e.message}`)
776
- }
777
- }
778
-
779
- // Workflow post_check:archive extract-module-impact 完成后检查产物
780
- if (stageName === 'archive' && steps[currentIdx]?.name?.includes('extract-module-impact')) {
781
- try {
782
- const { loadWorkflow, runPostCheck, formatCheckReport, saveWorkflowRun } = await import('../workflow.js')
783
- const wf = loadWorkflow(cwd, 'archive-impact')
784
- if (wf && changeName) {
785
- const raw = JSON.stringify(wf)
786
- const resolved = JSON.parse(raw.replace(/<change-name>/g, changeName))
787
- const result = runPostCheck(resolved, cwd, progress.project || basename(cwd), {}, specBase)
788
- // 只报告 impact-analyzer 的结果(doc-syncer 是后续步骤)
789
- const impactResult = (result.roles || []).find(r => r.id === 'impact-analyzer')
790
- if (impactResult) {
791
- const icon = impactResult.status === 'pass' ? '✅' : '❌'
792
- console.log(`${icon} module-impact.md 检查${impactResult.status === 'pass' ? '通过' : '失败'}`)
793
- for (const f of (result.failures || []).filter(f => f.role_id === 'impact-analyzer')) {
794
- // f 是 {level,role_id,output,check,message} 对象——直接 ${f} 打印裸 [object Object](ql-20260819-006);
795
- // message 才是人类可读 detail(如「缺少章节: …」),缺字段时 stringify 兜底防再退化成不可诊断输出
796
- console.log(` └─ ${f.message ?? JSON.stringify(f)}`)
797
- }
798
- }
799
- const saved = saveWorkflowRun(result, {
800
- cwd,
801
- source: 'run.js',
802
- stage: 'archive',
803
- step: steps[currentIdx]?.name,
804
- ...(platformOpts.runtimeRoot ? { runtimeRoot: platformOpts.runtimeRoot } : {}),
805
- ...(platformOpts.scanRunId ? { scanRunId: platformOpts.scanRunId } : {})
806
- })
807
- if (saved) console.log(`📁 结果已归档:${saved}`)
808
- }
809
- } catch (e) {
810
- console.warn(`⚠️ workflow 检查跳过:${e.message}`)
811
- }
812
- }
813
- return null
814
- }
815
- /**
816
- * quick 阶段完成收尾(W6 Step6b 从 completeStep 内联块抽出):
817
- * 强校验 QUICKLOG 条目 + 审计(auditQuickCompletion)+ 结果摘要结构校验 + 翻状态/勾 tasks.md
818
- * (CLI 接管 QUICKLOG 分配/写入/收尾)。blocked → process.exit(1)(无 early-return,调用点纯 await)。
819
- *
820
- * ctx:stageName/steps/currentIdx/cwd/progress/changeName/specBase/outputText/confirm/
821
- * isForceBaseline/isAllowNew/platformOpts。辅助函数直接 import(safeGit/auditQuickCompletion ← shared,
822
- * printQuickAuditReview ← quick-audit,4 个 quicklog fns ← quicklog,unlinkSync/rmSync ← fs 静态)。
823
- */
824
- export async function handleQuickStageCompletion({ stageName, steps, currentIdx, cwd, progress, changeName, specBase, outputText, confirm, isForceBaseline, isAllowNew, isAllowDelete, platformOpts, pm }) {
825
- // quick 收尾:强校验 QUICKLOG 条目 + 翻状态 + 勾 tasks.md(CLI 接管)
826
- if (stageName === 'quick') {
827
- // §4.6 从 session guard.json 读 guard(不依赖 progress.quickGuard)。
828
- // D-003@v1:progress._write 不持久化顶层 quickGuard,跨进程 --done 时读出的 progress 无 quickGuard,
829
- // 若仍用 if (progress.quickGuard) 驱动收尾会整体跳过,导致 .runtime/quick-sessions/<sessionId>/ 残留僵尸。
830
- // 改为从文件读 guard:优先 session 目录 guard.json,回退旧单文件 quick-guard.json(task-03 前兼容)。
831
- // sessionId == changeName == quick-<uuid8>(completeStep 作用域内 changeName 已解构自 options)。
832
- // session 目录经 resolveQuickSessionsDir 单一解析(multi-agent-review Q4):与 stage.js 写入路径对齐,
833
- // 平台模式 runtimeRoot 与 specBase/.runtime 不同时不再读不到 guard。
834
- const sessionGuardFile = join(resolveQuickSessionsDir(platformOpts, specBase), changeName, 'guard.json')
835
- const legacyGuardFile = join(specBase, '.runtime', 'quick-guard.json')
836
- let guard = null
837
- try {
838
- guard = existsSync(sessionGuardFile)
839
- ? JSON.parse(readFileSync(sessionGuardFile, 'utf8'))
840
- : (existsSync(legacyGuardFile) ? JSON.parse(readFileSync(legacyGuardFile, 'utf8')) : null)
841
- } catch {}
842
-
843
- // 强校验 / 收尾:本会话必须有一条真实 QUICKLOG 条目(治「报 SAFE 但漏写」bug)。
844
- // guard 缺失(brownfield:新代码前启动的会话)不阻断——兜底补写一条记录,保住「完成必有记录」不变量。
845
- const gitUser = safeGit(cwd, ['config', 'user.name']).value || 'unknown'
846
- let qlId = guard?.quicklogId || null
847
- const linkedChanges = Array.isArray(guard?.linkedChanges) ? guard.linkedChanges : []
848
- // 审计结果(仅 guard 存在时填充)。提到 if(guard) 外声明,供下方回填 QUICKLOG 文件行复用
849
- // review.changedFiles;brownfield 无 guard 时保持 null → 文件行不回填(降级,不报错)。
850
- let review = null
851
-
852
- // 审计:仅在有 guard 时跑(brownfield 无 guard 跳过,兼容 D-003 brownfield 行为)。
853
- // task-02:mergedGuard 提升到 if 外声明,供下方并发预检钩子复用与 auditQuickCompletion
854
- // 同源的 guard 字段(baselineFiles/linkedChanges)。brownfield 无 guard 时保持 null,
855
- // 钩子 ownFiles/linkedChanges 走 ?? [] 兜底(D-003 不抛 TypeError)。
856
- let mergedGuard = null
857
- if (guard) {
858
- // --done 的 --force-baseline/--allow-new 并入 guard(与 step1 持久化值取或)。
859
- // 修复 ql-20260713-002-7628:旧代码解析了这两个 flag 但只传 {isConfirm} 给审计,
860
- // 致 --done --force-baseline 静默无效、用户被误导「重跑 --confirm」也无法解锁。
861
- mergedGuard = {
862
- ...guard,
863
- forceBaseline: guard.forceBaseline || isForceBaseline,
864
- allowNew: guard.allowNew || isAllowNew,
865
- allowDelete: guard.allowDelete || isAllowDelete,
866
- // O-1(docs-signals-o12):specBase/projectName 透传给审计——docSyncHint 模块归属用
867
- // (平台模式 resolveSpecDir(cwd) 会 miss specRoot 静默丢信号,plan 审查 gap-5)
868
- specBase,
869
- projectName: progress?.project || null,
870
- // 他者 active 会话声明索引(坑 foreign-session-declared-false-block):多 agent 并发时
871
- // 并行会话 --files 声明的文件退栈归该会话审计,不再误拦本会话。与上方 guard 读取同源
872
- // (resolveQuickSessionsDir 同参,平台模式 runtimeRoot 对齐);fail-open:采集失败 → 空
873
- // → 回到无豁免现状。
874
- otherSessionsDeclared: collectOtherQuickSessionDeclarations(platformOpts, specBase, changeName),
875
- }
876
- review = await auditQuickCompletion(cwd, mergedGuard, { isConfirm: confirm })
877
- printQuickAuditReview(review)
878
- if (review.status === 'blocked') {
879
- steps[currentIdx].status = 'pending'
880
- steps[currentIdx].completedAt = null
881
- if (outputText) steps[currentIdx].output = null
882
- process.exit(1)
883
- }
884
- progress.lastQuickReview = review
885
- }
886
-
887
- // task-02 并发预检(FR-05/FR-07,纯副作用 advisory):auditQuickCompletion 返回后、推进前
888
- // 扫工作树,识别他者未提交改动 / 他者脏变更目录,有则 console.warn。不改 status/gate、
889
- // 不 exit、不 return early(FR-07 铁律)。ownFiles 必含 baselineFiles(D-001:脏工作树 quick
890
- // 完成时本会话 baseline 不被他者误报);review/mergedGuard 均可能为 null(brownfield 无 guard,
891
- // D-003),用 ?. + ?? [] 兜底防 spread undefined 抛 TypeError(B-005)。整钩子 try/catch 隔离
892
- // ——detect 本就 fail-open,保守再包一层,任何异常只吞不 bubble,主完成流程不受影响。
893
- try {
894
- // ownFiles 锚点(2026-08-18 误归属修复):声明会话 = baselineFiles ∪ allowedFiles(声明即归属),
895
- // 不再用 changedFiles 全量——他者窗口文件已被污染进 changedFiles,旧口径自吞致预检对
896
- // ql-20260818-003 形态结构性失明。未声明会话维持旧口径(changed ∪ baseline):无声明无归属
897
- // 信息,收窄锚点会把自身未声明改动全误报他者。resolveConcurrentAnchor 纯函数(concurrent-detect)。
898
- const ownFiles = resolveConcurrentAnchor({
899
- changedFiles: review?.changedFiles ?? [],
900
- baselineFiles: mergedGuard?.baselineFiles ?? [],
901
- allowedFiles: mergedGuard?.allowedFiles ?? [],
902
- })
903
- const detected = detectConcurrentChanges(cwd, {
904
- changeName,
905
- linkedChanges: mergedGuard?.linkedChanges ?? [],
906
- ownFiles,
907
- })
908
- const warn = formatConcurrentWarning(detected)
909
- if (warn) console.warn(warn)
910
- } catch (e) {
911
- // fail-open:并发预检异常绝不阻断主完成流程(FR-07)。
912
- }
913
-
914
- // 结果摘要结构校验(最后一步、isDone 且带了 --output 时):--output 是 QUICKLOG「结果:」
915
- // 归档的唯一来源,要求按 需求/根因/方案/结果 模板给全(见 stages/quick.js step3 prompt)。
916
- // 确定性校验:只查必填字段是否齐全,不判内容质量。缺字段 → 本次不完成(回滚 step 状态 +
917
- // exit 1),保留「进行中」条目,agent 补全 --output 后重跑 --done 即可,不丢进度。
918
- // 仅 completeQuicklogEntry 会实际持久化时才校验;前两个 step 的 --done output 不入 QUICKLOG,不校验。
919
- // Q6:quick 末步 --done 必须带 --output(四字段结果是 QUICKLOG「结果:」唯一来源)。缺则回退 pending +
920
- // exit(1),不静默落空结果条目(原 if(outputText) 守卫致 outputText 为空时跳过校验,completeQuicklogEntry
921
- // 又用 outputText||'' 兜底 → 结果块为空却翻「已完成」)。handleQuickStageCompletion 仅在阶段完成(=末步)时触发。
922
- const isLastStep = currentIdx === steps.length - 1
923
- if (isLastStep && !outputText) {
924
- console.error('\n❌ quick 最后一步 --done 必须带 --output(四字段结果模板)。')
925
- console.error(' --output 是 QUICKLOG「结果:」归档的唯一来源。补全后重跑 --done(不丢进度),推荐四参数形式(CLI 自动合成,无嵌套冒号事故面):')
926
- console.error(' sillyspec run quick --done --change <changeName> --req "一句话语义化短标题" --cause "为什么这样改" --solution "怎么改的" --result "验证情况(测试数 / lint / typecheck / 部署状态)"')
927
- console.error(' 兼容旧形式:--output "需求:… 根因:… 方案:… 结果:…"')
928
- steps[currentIdx].status = 'pending'
929
- steps[currentIdx].completedAt = null
930
- process.exit(1)
931
- }
932
- if (outputText) {
933
- const resultCheck = validateQuickResult(outputText)
934
- if (!resultCheck.ok) {
935
- console.error('\n' + getRule('quick.result-labels').failMessage.replaceAll('${missing}', resultCheck.missing.join('、')))
936
- console.error(` --output 是 QUICKLOG「结果:」归档的唯一来源,四个标签必须放在 --output 里(不是 --input)。`)
937
- console.error(` 补全后重跑 --done(不丢进度)。推荐四参数形式(CLI 自动合成结构化模板,避免旧形式嵌套全角冒号被拆分判定缺字段):`)
938
- console.error(` sillyspec run quick --done --change <changeName> --req "一句话语义化短标题(即 QUICKLOG 条目标题)" --cause "为什么这样改(纯新增/样式则写「无,纯新增/纯样式」)" --solution "怎么改的" --result "验证情况(测试数 / lint / typecheck / 部署状态)"`)
939
- console.error(` 或照抄旧形式模板:`)
940
- console.error(` sillyspec run quick --done --change <changeName> --output "需求:用户/任务要什么`)
941
- console.error(` 根因:为什么这样改(纯新增/样式则写「无,纯新增/纯样式」)`)
942
- console.error(` 方案:怎么改的`)
943
- console.error(` 结果:验证情况(测试数 / lint / typecheck / 部署状态)"`)
944
- steps[currentIdx].status = 'pending'
945
- steps[currentIdx].completedAt = null
946
- if (outputText) steps[currentIdx].output = null
947
- process.exit(1)
948
- }
949
- }
950
-
951
- if (!qlId) {
952
- // 无 ql-ID(guard 缺失或 brownfield 无 quicklogId):补分配后立即完成,不阻断。
953
- try {
954
- const alloc = await allocateQuicklogEntry(specBase, gitUser, {
955
- description: guard?.taskDescription || '(补分配)',
956
- linkedChanges,
957
- allowedFiles: Array.isArray(guard?.allowedFiles) ? guard.allowedFiles : [],
958
- })
959
- qlId = alloc.qlId
960
- console.log(`📝 QUICKLOG 兜底补写: ${qlId}(guard 缺失/brownfield 会话)`)
961
- } catch (e) {
962
- console.error(`\n❌ QUICKLOG 补分配失败: ${e.message}`)
963
- steps[currentIdx].status = 'pending'
964
- steps[currentIdx].completedAt = null
965
- if (outputText) steps[currentIdx].output = null
966
- process.exit(1)
967
- }
968
- }
969
- if (!findQuicklogEntry(specBase, gitUser, qlId)) {
970
- console.error(`\n❌ quick 阶段完成校验失败:QUICKLOG 条目 ${qlId} 不存在。`)
971
- console.error(` 会话期间记录被删除或从未写入。请检查 .sillyspec/quicklog/ 后重跑 --done。`)
972
- steps[currentIdx].status = 'pending'
973
- steps[currentIdx].completedAt = null
974
- if (outputText) steps[currentIdx].output = null
975
- process.exit(1)
976
- }
977
- // 翻状态进行中→已完成 + 追加结果 + 勾选关联 tasks.md
978
- // resultText 不再截断:结构化结果块(需求/根因/方案/结果)完整落盘,多行写成字段化块。
979
- try {
980
- // 回填实际改动文件:review.changedFiles 含 quick 自身元数据(quicklog/.runtime/modules 等),
981
- // 用 isQuickMetadata 过滤掉,只留真实业务文件。brownfield 无 review → 空数组,文件行不动。
982
- // 归属口径(2026-08-18 误归属修复):声明会话优先 attributedFiles(窗口∩声明∪同文件并发命中),
983
- // 他者窗口文件不进文件行;未声明会话/旧 review 无 attributedFiles → 兜底 changedFiles 全量。
984
- const auditFiles = Array.isArray(review?.attributedFiles)
985
- ? review.attributedFiles
986
- : (Array.isArray(review?.changedFiles) ? review.changedFiles : [])
987
- const realFiles = auditFiles.filter(f => !isQuickMetadata(f, linkedChanges))
988
- // D-8 落盘(2026-08-18 修):advisory 欠账信号从「纯打印」升级为「随条目落盘」——修复
989
- // 「欠账已记录(QUICKLOG reasons)」的不实承诺(交叉审查实证 reasons 纯 stdout,事后不可审计)。
990
- // 两周实测(2026-08-31 裁决,doc-consistency-debt §七)需要分母:信号触发次数必须可追溯。
991
- const auditNotes = []
992
- if (review?.docSyncHint && review.docSyncHint.touchedSource > 0 && review.docSyncHint.docFiles.length === 0) {
993
- const mods = Array.isArray(review.docSyncHint.modules) && review.docSyncHint.modules.length > 0
994
- ? `(涉及模块:${review.docSyncHint.modules.map((m) => m.id).join(' · ')})` : ''
995
- auditNotes.push(`📝 文档欠账(D-8):${review.docSyncHint.touchedSource} 个源码文件改动未同步任何模块文档${mods}`)
996
- }
997
- if (review?.docsCheckHint && review.docsCheckHint.invalid > 0) {
998
- auditNotes.push(`📎 文档引用失效:${review.docsCheckHint.invalid}/${review.docsCheckHint.total} 处 file:line 失效(sillyspec docs check 可复现)`)
999
- }
1000
- // 归属切分注(2026-08-18 误归属修复):窗口内未声明脏文件不进「文件:」行,但必须落盘可追溯
1001
- // (多 agent 并发仓他者窗口改动 / 本会话漏声明均可能),防真实改动被静默挤走。
1002
- if (Array.isArray(review?.undeclaredFiles) && review.undeclaredFiles.length > 0) {
1003
- const undeclared = review.undeclaredFiles.filter(f => !isQuickMetadata(f, linkedChanges))
1004
- if (undeclared.length > 0) {
1005
- auditNotes.push(`⚖️ 归属切分:${undeclared.length} 个窗口内未声明脏文件未计入文件行(并行会话改动或本会话漏声明):${undeclared.join(', ')}`)
1006
- }
1007
- }
1008
- await completeQuicklogEntry(specBase, gitUser, qlId, {
1009
- resultText: outputText || '',
1010
- linkedChanges,
1011
- changedFiles: realFiles,
1012
- auditNotes,
1013
- })
1014
- console.log(`📝 QUICKLOG 条目 ${qlId} 已标记完成`)
1015
- // 刷新 DB title:从 step3「需求:」提取(agent 可改 title 的途径),覆盖启动时的兜底快照。
1016
- // 与 QUICKLOG 标题刷新(flipEntryInContent 内 extractTitleFromResult)同源,保持 DB↔QUICKLOG 一致。
1017
- try {
1018
- const refinedTitle = extractTitleFromResult(outputText || '');
1019
- if (refinedTitle) pm.updateChangeMeta(cwd, changeName, { title: refinedTitle });
1020
- } catch { /* title 刷新失败不阻断完成 */ }
1021
- } catch (e) {
1022
- console.warn(`⚠️ QUICKLOG 完成态写入失败: ${e.message}`)
1023
- }
1024
-
1025
- // 轻量归档任务已全勾选的关联真实变更
1026
- try {
1027
- const closeResult = await closeQuickLinkedChanges({ pm, cwd, specBase, linkedChanges, platformOpts })
1028
- if (closeResult.closed.length > 0) {
1029
- console.log(`📦 已自动归档 ${closeResult.closed.length} 个关联变更:${closeResult.closed.join(', ')}`)
1030
- }
1031
- if (closeResult.skipped.length > 0) {
1032
- for (const s of closeResult.skipped) {
1033
- console.log(`⏭️ 关联变更 ${s.name} 未归档:${s.reason}`)
1034
- }
1035
- }
1036
- } catch (e) {
1037
- console.warn(`⚠️ 关联变更轻量归档失败(不阻断 quick 完成): ${e.message}`)
1038
- }
1039
-
1040
- // 清理 session 目录(rmSync/unlinkSync 容忍不存在)。路径与写入对齐(Q4 resolveQuickSessionsDir)。
1041
- try {
1042
- if (changeName) {
1043
- const sessionDir = join(resolveQuickSessionsDir(platformOpts, specBase), changeName)
1044
- rmSync(sessionDir, { recursive: true, force: true })
1045
- }
1046
- if (existsSync(legacyGuardFile)) unlinkSync(legacyGuardFile)
1047
- } catch {}
1048
-
1049
- // 注销 quick 会话注册的 changes 行(quick-<uuid8>),避免 active 行随每次 quick 单调累积污染
1050
- // listChanges / doctor / resolveQuickLinkedChanges(multi-agent-review Q1)。quick 是收尾型会话,
1051
- // 不走 archive,旧代码从不调 unregisterChange → DB 里 active 的 quick-<hex> 行只增不减。
1052
- // 仅对 quick-<8hex> sessionId 注销——非 sessionId 形态的变更名是旧兼容路径/真实关联变更,
1053
- // 误注销会把用户真实变更标 archived(与 command.js:569 sessionId 守卫同形正则)。
1054
- if (changeName && /^quick-[0-9a-f]{8}$/.test(changeName)) {
1055
- try {
1056
- pm.unregisterChange(cwd, changeName)
1057
- } catch (e) {
1058
- console.warn(`⚠️ 注销 quick 会话 changes 行失败(不阻断完成): ${e.message}`)
1059
- }
1060
- }
1061
- }
1062
-
1063
- return null
1064
- }
1065
-
1066
- /**
1067
- * 判定变更 tasks.md 是否全部勾选完成。
1068
- * 无 tasks.md 或有未勾选项均返回 false(保守策略)。
1069
- *
1070
- * @param {string} specBase - .sillyspec 根目录
1071
- * @param {string} changeName - 变更名
1072
- * @returns {boolean}
1073
- */
1074
- function isChangeTasksComplete(specBase, changeName) {
1075
- const tasksPath = join(specBase, 'changes', changeName, 'tasks.md')
1076
- if (!existsSync(tasksPath)) return false
1077
- try {
1078
- const content = readFileSync(tasksPath, 'utf8').replace(/\r\n/g, '\n')
1079
- return !/^-\s*\[\s*\]\s+/m.test(content)
1080
- } catch {
1081
- return false
1082
- }
1083
- }
1084
-
1085
- /**
1086
- * 对单个已完成的关联真实变更执行轻量归档(不校验 plan.md/module-impact.md)。
1087
- *
1088
- * @param {Object} opts
1089
- * @param {ProgressManager} opts.pm
1090
- * @param {string} opts.cwd
1091
- * @param {string} opts.specBase
1092
- * @param {string} opts.changeName
1093
- * @param {Object} [opts.platformOpts]
1094
- * @returns {Promise<{closed:boolean, destDir?:string, reason?:string}>}
1095
- */
1096
- async function closeSingleQuickLinkedChange({ pm, cwd, specBase, changeName, platformOpts = {} }) {
1097
- const srcDir = join(specBase, 'changes', changeName)
1098
- if (!existsSync(srcDir)) {
1099
- return { closed: false, reason: '源目录不存在' }
1100
- }
1101
- const changesDir = join(specBase, 'changes')
1102
- const archiveDir = join(changesDir, 'archive')
1103
- const date = new Date().toISOString().slice(0, 10)
1104
- const destName = archiveDestDirName(date, changeName)
1105
- const destDir = join(archiveDir, destName)
1106
-
1107
- // 幂等:目标目录已存在或已在 archive/ 中
1108
- if (existsSync(destDir) || findAlreadyArchivedDir(archiveDir, changeName)) {
1109
- return { closed: false, reason: `目标目录已存在(${destName})` }
1110
- }
1111
-
1112
- mkdirSync(archiveDir, { recursive: true })
1113
- try {
1114
- renameSyncRetry(srcDir, destDir)
1115
- } catch (e) {
1116
- return { closed: false, reason: `移动目录失败:${e.message}` }
1117
- }
1118
-
1119
- // 终态一致化同标准归档(坑 manual-archive-desync-status-only):轻量归档路径不能只翻 status
1120
- pm.unregisterChange(cwd, changeName, { archiveStepNames: typeof pm.archiveStepNamesForArchive === 'function' ? pm.archiveStepNamesForArchive() : null })
1121
- await archiveWorktreeCleanup(cwd, changeName, specBase, platformOpts)
1122
- safeGit(cwd, ['add', '--', `.sillyspec/changes/archive/${destName}/`])
1123
-
1124
- console.log(`📦 关联变更已自动归档:${changeName} → archive/${destName}/`)
1125
- return { closed: true, destDir }
1126
- }
1127
-
1128
- /**
1129
- * quick 轻量归档的阶段闸允许集:仅「从未进入完整流程」的变更可被 quick --done 自动归档
1130
- * (d192f89 原始场景:评估 small 转 quick、停在 brainstorm 的僵尸变更)。execute 完成后
1131
- * tasks.md 必然全勾选而流程未收尾——不看 current_stage 会把 verify/中途的完整流程变更
1132
- * 绕过 verify/archive 校验直接归档注销(quick-close-midflight 缺陷)。
1133
- *
1134
- * 阶段名允许集之外还有「阶段完成态」闸(ql-20260819-010,quick-done-autoarchive-misfire
1135
- * 缺陷①):current_stage=brainstorm 但该阶段 status=completed(brainstorm 收尾到 plan
1136
- * 开始之间的空窗)≠ 僵尸变更——此时关联 quick --done 会把即将进 plan 的进行中变更误
1137
- * 轻量归档。stage_status=completed 一律走原流程收尾。
1138
- */
1139
- const QUICK_CLOSE_ALLOWED_STAGES = new Set(['', 'scan', 'brainstorm'])
1140
-
1141
- /**
1142
- * quick --done 完成后,自动关闭任务已全部完成的关联真实变更。
1143
- * quick-<hex> sessionId 自身不在此处理(由调用方单独注销)。
1144
- * 单个归档失败 catch warn,不阻断 quick 完成。
1145
- *
1146
- * 阶段闸(fail-closed):先查 changes.current_stage——无 DB 记录(未注册目录桩)或停在
1147
- * scan/brainstorm 才继续 tasks 判定;plan/execute/verify/archive 一律 skip 走原流程收尾。
1148
- * pm 缺 getChangeStage 接口或查询抛错同样 skip,不静默放行。
1149
- *
1150
- * @param {Object} opts
1151
- * @param {ProgressManager} opts.pm
1152
- * @param {string} opts.cwd
1153
- * @param {string} opts.specBase
1154
- * @param {string[]} [opts.linkedChanges]
1155
- * @param {Object} [opts.platformOpts]
1156
- * @returns {Promise<{closed:string[], skipped:{name:string,reason:string}[]}>}
1157
- */
1158
- export async function closeQuickLinkedChanges({ pm, cwd, specBase, linkedChanges = [], platformOpts = {} }) {
1159
- const closed = []
1160
- const skipped = []
1161
- // 只处理真实变更,跳过 quick 会话 sessionId
1162
- const realChanges = linkedChanges.filter((name) => !/^quick-[0-9a-f]{8}$/.test(name))
1163
- for (const changeName of realChanges) {
1164
- try {
1165
- if (typeof pm.getChangeStage !== 'function') {
1166
- skipped.push({ name: changeName, reason: '进度库接口缺失(getChangeStage),无法判定流程阶段,不自动归档' })
1167
- continue
1168
- }
1169
- const stageInfo = pm.getChangeStage(cwd, changeName)
1170
- if (stageInfo !== null && !QUICK_CLOSE_ALLOWED_STAGES.has(stageInfo.current_stage || '')) {
1171
- skipped.push({
1172
- name: changeName,
1173
- reason: `变更处于完整流程「${stageInfo.current_stage}」阶段(tasks.md 全勾不等于流程收尾),不自动归档——请走原流程收尾(sillyspec progress show 查看进度)`,
1174
- })
1175
- continue
1176
- }
1177
- // ql-20260819-010(quick-done-autoarchive-misfire 缺陷①):当前阶段已完成 ≠
1178
- // 从未进入完整流程的僵尸。brainstorm 收尾到 plan 开始之间的空窗里 current_stage
1179
- // 仍读 brainstorm,只看阶段名会把即将进 plan 的变更误轻量归档(propose 骨架
1180
- // tasks.md 除 quick 追加的 ql 行外没有任务行,「无未勾选框=全勾」恒真)。
1181
- // stage_status=completed 一律原流程收尾;null(无阶段行/brownfield)与旧调用方
1182
- // mock 缺字段(undefined)均按未完成放行,僵尸逃生通道行为不变。
1183
- if (stageInfo !== null && stageInfo.stage_status === 'completed') {
1184
- skipped.push({
1185
- name: changeName,
1186
- reason: `变更当前阶段「${stageInfo.current_stage || '(空)'}」已完成(推进/收尾中,非僵尸变更),不自动归档——请走原流程收尾(sillyspec progress show 查看进度)`,
1187
- })
1188
- continue
1189
- }
1190
- if (!isChangeTasksComplete(specBase, changeName)) {
1191
- skipped.push({ name: changeName, reason: 'tasks.md 未全勾选或不存在' })
1192
- continue
1193
- }
1194
- const result = await closeSingleQuickLinkedChange({ pm, cwd, specBase, changeName, platformOpts })
1195
- if (result.closed) {
1196
- closed.push(changeName)
1197
- } else {
1198
- skipped.push({ name: changeName, reason: result.reason || '未知原因' })
1199
- }
1200
- } catch (e) {
1201
- console.warn(`⚠️ 关联变更 ${changeName} 轻量归档失败(不阻断 quick 完成): ${e.message}`)
1202
- skipped.push({ name: changeName, reason: e.message })
1203
- }
1204
- }
1205
- return { closed, skipped }
1206
- }
1207
-
1208
- /**
1209
- * execute「Wave N 执行」步骤完成后扫 worktree 提取 provider endpoint artifact(W6 Step6c 从
1210
- * completeStep 内联块抽出)。供 verify 阶段 parity 对账 + consumer task 上游契约注入。
1211
- * 接线自 contract-matrix pipeline。step 级(每个 Wave 执行步骤后跑),无 early-return(try/catch warn)。
1212
- *
1213
- * ctx:stageName/steps/currentIdx/changeName/specBase/cwd。extractArtifactsForChange ← 动态 ../contract-matrix.js,
1214
- * WorktreeManager ← 动态 ../worktree.js(真环依赖保留动态)。
1215
- */
1216
- export async function handleExecuteWaveArtifact({ stageName, steps, currentIdx, changeName, specBase, cwd }) {
1217
- if (stageName === 'execute' && /^Wave \d+ 执行$/.test(steps[currentIdx]?.name || '')) {
1218
- try {
1219
- const { extractArtifactsForChange } = await import('../contract-matrix.js')
1220
- let worktreePath = null
1221
- try {
1222
- const { WorktreeManager } = await import('../worktree.js')
1223
- const meta = new WorktreeManager({ cwd }).getMeta(changeName)
1224
- if (meta?.worktreePath && existsSync(meta.worktreePath)) worktreePath = meta.worktreePath
1225
- } catch {}
1226
- const msg = extractArtifactsForChange({ changeDir: join(specBase, 'changes', changeName), specBase, changeName, worktreePath })
1227
- if (msg) console.log(msg)
1228
- } catch (e) { console.warn(`⚠️ 契约 artifact 提取跳过: ${e?.message || e}`) }
1229
- }
1230
- return null
1231
- }
1232
-
1233
- /**
1234
- * 聚合最新 execute run 各 task review.json 的 changedFiles(主仓 repo 过滤)。
1235
- *
1236
- * 复用 resolveLatestExecuteRunIdWithTasks(task-review.js:684,规避 marker 漂移)+ readReview。
1237
- * 仅主仓 repo(review.repo 缺省或 'main')的 changedFiles 参与主仓核验;跨仓 repo 的 task 文件
1238
- * 由跨仓仓独立落地,不在主仓 worktree/分支,混入会误报 missing(Grill M11)。
1239
- *
1240
- * @param {{ runtimeRoot: string, changeName: string }} opts
1241
- * @returns {Promise<string[]>} 主仓 changedFiles 聚合(去重保序);无 run / 无 tasks / 读取失败 → []
1242
- */
1243
- export async function collectExecuteChangedFiles({ runtimeRoot, changeName }) {
1244
- if (!runtimeRoot || !changeName) return []
1245
- const { resolveLatestExecuteRunIdWithTasks, readReview, normalizeRepoKey } = await import('../task-review.js')
1246
- // changeName 透传:run 解析按 change 戳优先归属(坑 worktree-cleanup-marker-chain),
1247
- // 避免 marker 断裂后聚合到其他变更 run 的 changedFiles 误报 missing
1248
- const runId = resolveLatestExecuteRunIdWithTasks({ runtimeRoot, changeName })
1249
- if (!runId) return []
1250
- const tasksDir = join(runtimeRoot, 'execute-runs', runId, 'tasks')
1251
- if (!existsSync(tasksDir)) return []
1252
- let taskIds
1253
- try {
1254
- taskIds = readdirSync(tasksDir)
1255
- } catch {
1256
- return []
1257
- }
1258
- const files = []
1259
- for (const taskId of taskIds) {
1260
- const r = readReview(join(tasksDir, taskId, 'review.json'))
1261
- if (!r.ok || !r.review) continue
1262
- // 跨仓 repo 过滤:仅主仓(repo 缺省视 'main')参与主仓核验,避免误报
1263
- if (normalizeRepoKey(r.review.repo) !== 'main') continue
1264
- if (Array.isArray(r.review.changedFiles)) {
1265
- for (const f of r.review.changedFiles) {
1266
- // 交付物过滤(与 worktree.js hasUnappliedChanges isDeliverable 同口径):.sillyspec/ 蓝图/
1267
- // runtime 产物与 meta.json 不参与落盘核验——它们随主仓/并行 session 维护,不在 worktree 分支,
1268
- // 混入会误报 missing
1269
- if (typeof f !== 'string' || f.trim() === '') continue
1270
- if (f.startsWith('.sillyspec/') || f === 'meta.json') continue
1271
- files.push(f)
1272
- }
1273
- }
1274
- }
1275
- return [...new Set(files)]
1276
- }
1277
-
1278
- /**
1279
- * execute 阶段级核验(防空跑谎报,D-002@v1 / FR-04/05/06):聚合最新 execute run 各 task review 声称的
1280
- * 交付文件,用 findMissingDeliverables 核验其存在于 worktree 分支 tree 或 worktree 工作区。
1281
- *
1282
- * - missing 文件 → console.warn 列清单,提示"apply 将无源可复制"(宽松非阻断,不 exit 不 throw)。
1283
- * - checked:false(worktree 目录 / 分支不存在)→ 保守提示"无法核验,请人工确认"。
1284
- * - 与 Task Review Gate 既有校验(零改动伪造 / 不相交伪造,task-review.js:590-623)互补不重复拦截:
1285
- * 本核验的真实增量窗口是「review 通过后文件被删且未 commit」+「无法核验时给人工确认提示」。
1286
- *
1287
- * 由 handleExecuteWorktreeCleanup 开头调用:核验发生在 worktree cleanup 之前,目录被清前先判定
1288
- * 交付文件是否落盘。整个钩子 try/catch 兜底——任何异常只 warn,绝不影响 execute 完成(FR-07)。
1289
- *
1290
- * ctx:stageName/changeName/cwd。WorktreeManager + findMissingDeliverables ← 动态 ../worktree.js;
1291
- * task-review 读取 ← 动态 ../task-review.js。runtimeRoot 用本地 specBase 解析(无 platformOpts 传入
1292
- * 时平台 runtimeRoot 不在本函数作用域,降级为本仓 .runtime,读不到 review 则跳过,零误报)。
1293
- */
1294
- export async function handleExecuteDeliverableCheck({ stageName, changeName, cwd }) {
1295
- if (stageName !== 'execute' || !changeName) return null
1296
- try {
1297
- const { WorktreeManager, findMissingDeliverables } = await import('../worktree.js')
1298
- const wm = new WorktreeManager({ cwd })
1299
- const meta = wm.getMeta(changeName)
1300
- if (!meta) return null // 无 worktree meta(非 worktree execute / 已清),无需核验
1301
- const specBase = join(cwd, '.sillyspec')
1302
- const runtimeRoot = resolveRuntimeRoot({}, specBase)
1303
- const changedFiles = await collectExecuteChangedFiles({ runtimeRoot, changeName })
1304
- if (changedFiles.length === 0) return null
1305
- const { missing, checked } = findMissingDeliverables({
1306
- worktreePath: meta.worktreePath,
1307
- branch: meta.branch,
1308
- changedFiles,
1309
- })
1310
- if (!checked) {
1311
- console.warn('⚠️ execute 阶段级核验:无法核验(worktree 目录或分支不存在),请人工确认交付文件已落盘。')
1312
- return null
1313
- }
1314
- if (missing.length > 0) {
1315
- console.warn(`⚠️ execute 阶段级核验:以下 ${missing.length} 个声称实现的交付文件既不在分支也不在工作区,疑似空跑/从未落盘:`)
1316
- for (const f of missing) console.warn(` ${f}`)
1317
- console.warn(' 请检查子代理是否真实实现,或先 commit 到分支;apply 将无源可复制。')
1318
- }
1319
- } catch (e) {
1320
- console.warn(`⚠️ execute 阶段级核验跳过: ${e?.message || e}`)
1321
- }
1322
- return null
1323
- }
1324
-
1325
- /**
1326
- * execute 阶段完成时条件性清理 worktree(W6 Step6c 从 completeStep 完成路径内联块抽出)。
1327
- * 不依赖 AI agent 的完成确认步骤:有未 apply 变更 → 保留 worktree;否则 cleanup(含 in-place 安全清理)。
1328
- * stage 级(execute 阶段全部完成时跑),无 early-return(try/catch warn)。
1329
- *
1330
- * ctx:stageName/changeName/cwd。WorktreeManager ← 动态 ../worktree.js。
1331
- */
1332
- export async function handleExecuteWorktreeCleanup({ stageName, changeName, cwd }) {
1333
- // 阶段级核验(D-002@v1,防空跑谎报):cleanup 之前判定 review 声称实现的交付文件是否落盘。
1334
- // 宽松非阻断:缺失 warn / 无法核验保守提示 / 异常只 warn,均不影响下方 cleanup 与 execute 完成。
1335
- await handleExecuteDeliverableCheck({ stageName, changeName, cwd })
1336
- if (stageName === 'execute' && changeName) {
1337
- try {
1338
- const { WorktreeManager } = await import('../worktree.js');
1339
- const wm = new WorktreeManager({ cwd });
1340
- const meta = wm.getMeta(changeName);
1341
- if (!meta) {
1342
- console.log('🔗 Worktree: n/a (no meta)');
1343
- } else if (meta.mode === 'native-worktree') {
1344
- console.log('🔗 Worktree: kept (外部隔离环境)');
1345
- } else {
1346
- // in-place 模式不再短路:cleanup 现在能安全处理 in-place(只清 meta,不碰主工作区)。
1347
- // 主仓互斥锁(坑 main-repo-no-mutex 二批):检查+清理与并行会话的 apply/cleanup 互斥
1348
- // (防 TOCTOU:检查时他者正在 apply → 判定漂移)。best-effort:锁超时不阻断 execute
1349
- // 完成,降级为保留 worktree + 手动清理指引。
1350
- try {
1351
- const { withMainRepoLock } = await import('../worktree-apply.js')
1352
- const cleanResult = await withMainRepoLock(cwd, changeName, 'execute-cleanup', () => {
1353
- const check = wm.hasUnappliedChanges(changeName);
1354
- if (check.hasChanges) {
1355
- return { kept: true, check }
1356
- }
1357
- return { kept: false, result: wm.cleanup(changeName) }
1358
- })
1359
- if (cleanResult.kept) {
1360
- console.log(`🔗 Worktree: pending apply (${cleanResult.check.changedFiles.length} 个未应用变更)`);
1361
- console.log(` 下一步: sillyspec worktree apply ${changeName}`);
1362
- } else {
1363
- console.log(`🔗 Worktree: ${cleanResult.result.result}`);
1364
- if (cleanResult.result.residual?.length > 0) {
1365
- console.warn(` ⚠️ 清理残留: ${cleanResult.result.residual.join('; ')}`);
1366
- console.warn(` 手动处理: sillyspec worktree cleanup ${changeName} --force`);
1367
- } else if (cleanResult.result.details?.length > 0) {
1368
- for (const d of cleanResult.result.details) {
1369
- if (d.startsWith('⚠️')) console.log(` ${d}`);
1370
- }
1371
- }
1372
- }
1373
- } catch (lockErr) {
1374
- if (/互斥锁被占用/.test(String(lockErr.message))) {
1375
- console.log(`🔗 Worktree 自动清理跳过(主仓互斥锁被他者会话持有)——稍后手动: sillyspec worktree cleanup ${changeName}`);
1376
- } else {
1377
- console.warn(`⚠️ worktree 清理异常(不阻断): ${lockErr.message}`);
1378
- }
1379
- }
1380
- }
1381
- } catch (e) {
1382
- console.warn(`🔗 Worktree: check failed — ${e.message}`);
1383
- }
1384
- }
1385
- return null
1386
- }
1387
- /**
1388
- * scan 阶段完成后处理(W6 Step6d 从 completeStep 完成路径内联块抽出):
1389
- * - 平台模式(specRoot/runtimeRoot):写 manifest.json + 跑 scan-postcheck + 结构化结果 +
1390
- * 更新平台指针(SCAN_COMPLETED)+ failed_post_check 阻断(exit 1 / early-return)
1391
- * - 非平台模式:轻量 postcheck + 结构化结果写 .runtime/
1392
- * 返回 early-return 对象(platform failed_post_check 非 exit 路径)由 completeStep 透传;null = 放行。
1393
- *
1394
- * ctx:stageName/currentIdx/cwd/progress/pm/stageData/changeName/outputText/platformOpts。
1395
- * safeGit/triggerSync ← shared;writeAtomicSync ← fs-atomic;SCAN_STATUS/POINTER_STATUS ← constants;
1396
- * mkdirSync/writeFileSync/readFileSync/unlinkSync/join ← 顶部静态;runScanPostCheck 等 ← 动态 ../scan-postcheck.js。
1397
- *
1398
- * 搬迁清理:删 4 个冗余动态 builtin import(fs/path/child_process,execSync 死代码)+ _readFileSync 别名改回 readFileSync。
1399
- */
1400
- export async function handleScanStageCompleted({ stageName, currentIdx, cwd, progress, pm, stageData, changeName, outputText, platformOpts }) {
1401
- // 平台模式:scan 完成后生成 manifest.json + post-check
1402
- if (stageName === 'scan' && (platformOpts.specRoot || platformOpts.runtimeRoot)) {
1403
- if (!platformOpts.specRoot) {
1404
- // 只传 runtimeRoot 无 specRoot(command.js 允许的组合):manifest 无处落盘。
1405
- // 显式 fail-closed 报错——此前 mkdirSync(null) 抛 TypeError 被外层 catch 吞掉,
1406
- // postcheck/指针升级/阻断全部静默跳过,scan 失败也"干净成功"(体检 BUG-12)
1407
- console.error(`❌ 平台模式缺少 --spec-root,无法写 manifest.json(scan postcheck 中止)`)
1408
- stageData.scanMeta = stageData.scanMeta || {}; stageData.scanMeta.manifestWritten = false
1409
- stageData.scanMeta.manifestError = 'missing specRoot'
1410
- return
1411
- }
1412
- try {
1413
- stageData.scanMeta = stageData.scanMeta || {}; stageData.scanMeta.manifestWritten = false; // 默认失败
1414
- const manifestDir = platformOpts.specRoot
1415
- mkdirSync(manifestDir, { recursive: true })
1416
- let sourceCommit = null
1417
- let sourceCommitError = null
1418
- try {
1419
- const gitResult = safeGit(cwd, ['rev-parse', 'HEAD'])
1420
- sourceCommit = gitResult.value
1421
- sourceCommitError = gitResult.error
1422
- } catch (e) {
1423
- sourceCommitError = e.message
1424
- }
1425
- const manifest = {
1426
- workspace_id: platformOpts.workspaceId || null,
1427
- scan_run_id: platformOpts.scanRunId || null,
1428
- source_root: cwd,
1429
- spec_root: platformOpts.specRoot || null,
1430
- runtime_root: platformOpts.runtimeRoot || null,
1431
- source_commit: sourceCommit,
1432
- source_commit_error: sourceCommit === null ? (sourceCommitError || 'unknown') : undefined,
1433
- generated_at: new Date().toISOString(),
1434
- schema_version: 1,
1435
- scan_profile: stageData.scanProfile
1436
- ? { mode: stageData.scanProfile.mode, reason: stageData.scanProfile.reason }
1437
- : null,
1438
- postcheck_result_path: null,
1439
- workflow_runs_dir: platformOpts.runtimeRoot
1440
- ? join(platformOpts.runtimeRoot, 'scan-runs', platformOpts.scanRunId || 'unknown', 'workflow-runs')
1441
- : null,
1442
- platform_pointer_path: join(cwd, '.sillyspec-platform.json'),
1443
- platform_pointer_status: POINTER_STATUS.ACTIVE,
1444
- }
1445
- const manifestPath = join(manifestDir, 'manifest.json')
1446
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n')
1447
- console.log(`📄 manifest.json 已写入: ${manifestPath}`)
1448
- stageData.scanMeta = stageData.scanMeta || {}; stageData.scanMeta.manifestWritten = true;
1449
- if (!sourceCommit) {
1450
- console.log(`⚠️ source_commit 无法获取(可能非 git 目录),已设为 null`)
1451
- }
1452
- // 清理平台参数临时文件
1453
- const platformOptsFile = join(manifestDir, '.runtime', 'platform-scan.json')
1454
- try { unlinkSync(platformOptsFile) } catch {}
1455
-
1456
- // CLI 层 post-check(替代旧的简单检查)
1457
- const { runScanPostCheck, printScanPostCheckResult, formatStructuredResult, writeStructuredResult } = await import('../scan-postcheck.js')
1458
- const postResult = runScanPostCheck({
1459
- cwd,
1460
- specDir: platformOpts.specRoot,
1461
- outputText,
1462
- scanMeta: {
1463
- projectListParsed: stageData.scanMeta?.projectListParsed ?? null,
1464
- manifestWritten: stageData.scanMeta?.manifestWritten ?? null,
1465
- },
1466
- scanProfile: stageData.scanProfile || null,
1467
- })
1468
- printScanPostCheckResult(postResult)
1469
-
1470
- // 生成结构化 JSON 并写入 runtime(供 SillyHub 消费)
1471
- const structured = formatStructuredResult(postResult, {
1472
- workspace_id: platformOpts.workspaceId,
1473
- scan_run_id: platformOpts.scanRunId,
1474
- source_root: cwd,
1475
- spec_root: platformOpts.specRoot,
1476
- runtime_root: platformOpts.runtimeRoot,
1477
- })
1478
- const postcheckJsonPath = writeStructuredResult(structured, platformOpts.specRoot, {
1479
- runtimeRoot: platformOpts.runtimeRoot,
1480
- scanRunId: platformOpts.scanRunId,
1481
- })
1482
- if (postcheckJsonPath) {
1483
- console.log(`📄 postcheck-result.json 已写入: ${postcheckJsonPath}`)
1484
- manifest.postcheck_result_path = postcheckJsonPath
1485
- }
1486
-
1487
- // 将 post-check 结果写入 manifest
1488
- manifest.scan_post_check = {
1489
- status: postResult.status,
1490
- checks: postResult.checks,
1491
- }
1492
- // 更新 manifest
1493
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n')
1494
- console.log(`📄 manifest.json 已更新(含 post-check 结果)`)
1495
-
1496
- // 更新平台指针状态为 scan_completed
1497
- const pointerPath = join(cwd, '.sillyspec-platform.json')
1498
- try {
1499
- const pointer = JSON.parse(readFileSync(pointerPath, 'utf8'))
1500
- pointer.status = POINTER_STATUS.SCAN_COMPLETED
1501
- pointer.completedAt = new Date().toISOString()
1502
- pointer.scanStatus = postResult.status
1503
- writeAtomicSync(pointerPath, JSON.stringify(pointer, null, 2) + '\n')
1504
- } catch (e) {
1505
- // 不阻断 scan 主流程,但暴露失败——pointer 写失败会让平台看不到 scan_completed,
1506
- // 与项目 fail-loud 原则一致:宁可可见地 warn,也不静默吞错。
1507
- console.warn(`⚠️ 更新平台指针状态失败(scan_completed 可能未落盘): ${e.message}`)
1508
- }
1509
-
1510
- // failed_post_check 时强制阻止 clean success
1511
- if (postResult.status === 'failed_post_check') {
1512
- stageData.status = SCAN_STATUS.FAILED_POST_CHECK
1513
- stageData.completedAt = new Date().toLocaleString('zh-CN',{hour12:false})
1514
- pm._write(cwd, progress, changeName)
1515
- triggerSync(cwd, changeName, platformOpts)
1516
- console.error(`\n❌ scan post-check 失败,状态设为 failed_post_check。不允许 clean success。`)
1517
- console.error(` 请检查上方错误信息并修复后重新 scan。`)
1518
- // 平台模式:exit(1) 让 daemon/SillyHub 感知非 0 退出码(manifest.json 已落盘,不会被撤销)
1519
- if (platformOpts.specRoot || platformOpts.runtimeRoot) {
1520
- console.error(' 平台模式:CLI 将以 exit code 1 退出,通知 SillyHub scan 失败。')
1521
- process.exit(1)
1522
- }
1523
- // 接口与 plan contract (run.js:2551 附近 plan 失败分支) 对齐:
1524
- // 返回 { stageCompleted:false, currentIdx, nextPendingIdx: currentIdx }
1525
- // 让上层 runStage 走"完成但不推进"分支,--done 被拒
1526
- return { stageCompleted: false, currentIdx, nextPendingIdx: currentIdx }
1527
- } else if (postResult.status === 'completed_with_warnings') {
1528
- // 警告不阻止完成,但记录
1529
- stageData.status = 'completed'
1530
- stageData.completedAt = new Date().toLocaleString('zh-CN',{hour12:false})
1531
- pm._write(cwd, progress, changeName)
1532
- }
1533
- } catch (e) {
1534
- console.warn(`⚠️ manifest.json 写入失败: ${e.message}`)
1535
- }
1536
- }
1537
-
1538
- // 非 platform 模式 scan 也做轻量 post-check + 结构化输出
1539
- if (stageName === 'scan' && !platformOpts.specRoot && !platformOpts.runtimeRoot) {
1540
- const { runScanPostCheck, printScanPostCheckResult, formatStructuredResult, writeStructuredResult } = await import('../scan-postcheck.js')
1541
- const postResult = runScanPostCheck({ cwd, specDir: null, outputText, scanProfile: stageData.scanProfile || null })
1542
- printScanPostCheckResult(postResult)
1543
- // 结构化结果写入 .sillyspec/.runtime/
1544
- const structured = formatStructuredResult(postResult, { source_root: cwd })
1545
- const postcheckJsonPath = writeStructuredResult(structured, join(cwd, '.sillyspec'))
1546
- if (postcheckJsonPath) {
1547
- console.log(`📄 postcheck-result.json 已写入: ${postcheckJsonPath}`)
1548
- }
1549
- }
1550
- return null
1551
- }
1552
-