@jokerized/getresearchdone 0.4.1

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 (711) hide show
  1. package/.claude-plugin/plugin.json +103 -0
  2. package/README.md +211 -0
  3. package/agents/grd-baseline-assessor.md +684 -0
  4. package/agents/grd-code-reviewer.md +300 -0
  5. package/agents/grd-codebase-mapper.md +355 -0
  6. package/agents/grd-critique-agent.md +119 -0
  7. package/agents/grd-debugger.md +519 -0
  8. package/agents/grd-deep-diver.md +737 -0
  9. package/agents/grd-eval-planner.md +913 -0
  10. package/agents/grd-eval-reporter.md +717 -0
  11. package/agents/grd-executor.md +683 -0
  12. package/agents/grd-feasibility-analyst.md +624 -0
  13. package/agents/grd-integration-checker.md +367 -0
  14. package/agents/grd-knowledge-miner.md +81 -0
  15. package/agents/grd-migrator.md +88 -0
  16. package/agents/grd-phase-researcher.md +697 -0
  17. package/agents/grd-plan-checker.md +443 -0
  18. package/agents/grd-planner.md +1532 -0
  19. package/agents/grd-product-owner.md +562 -0
  20. package/agents/grd-project-researcher.md +513 -0
  21. package/agents/grd-research-synthesizer.md +273 -0
  22. package/agents/grd-roadmapper.md +798 -0
  23. package/agents/grd-surveyor.md +566 -0
  24. package/agents/grd-verifier.md +893 -0
  25. package/bin/gd.js +4 -0
  26. package/bin/gd.ts +227 -0
  27. package/bin/grd-manifest.js +4 -0
  28. package/bin/grd-manifest.ts +286 -0
  29. package/bin/grd-mcp-server.js +4 -0
  30. package/bin/grd-mcp-server.ts +124 -0
  31. package/bin/grd-tools.js +4 -0
  32. package/bin/grd-tools.ts +2471 -0
  33. package/bin/postinstall.js +4 -0
  34. package/bin/postinstall.ts +80 -0
  35. package/commands/add-phase.md +123 -0
  36. package/commands/add-todo.md +87 -0
  37. package/commands/assess-baseline.md +289 -0
  38. package/commands/autopilot.md +100 -0
  39. package/commands/autoplan.md +55 -0
  40. package/commands/check-todos.md +87 -0
  41. package/commands/compare-methods.md +262 -0
  42. package/commands/complete-milestone.md +225 -0
  43. package/commands/debug.md +372 -0
  44. package/commands/deep-dive.md +288 -0
  45. package/commands/discover.md +281 -0
  46. package/commands/discuss-phase.md +188 -0
  47. package/commands/discuss.md +55 -0
  48. package/commands/eval-report.md +310 -0
  49. package/commands/evolve.md +79 -0
  50. package/commands/execute-phase.md +1017 -0
  51. package/commands/feasibility.md +292 -0
  52. package/commands/help.md +407 -0
  53. package/commands/init.md +1508 -0
  54. package/commands/insert-phase.md +113 -0
  55. package/commands/iterate.md +327 -0
  56. package/commands/list-phase-assumptions.md +217 -0
  57. package/commands/long-term-roadmap.md +202 -0
  58. package/commands/map-codebase.md +111 -0
  59. package/commands/migrate.md +159 -0
  60. package/commands/new-milestone.md +169 -0
  61. package/commands/pause-work.md +83 -0
  62. package/commands/plan-milestone-gaps.md +373 -0
  63. package/commands/plan-phase.md +655 -0
  64. package/commands/principles.md +328 -0
  65. package/commands/product-plan.md +319 -0
  66. package/commands/progress.md +481 -0
  67. package/commands/quick.md +167 -0
  68. package/commands/reapply-patches.md +154 -0
  69. package/commands/remove-phase.md +97 -0
  70. package/commands/requirement.md +96 -0
  71. package/commands/resume-project.md +113 -0
  72. package/commands/settings.md +1144 -0
  73. package/commands/survey.md +242 -0
  74. package/commands/sync.md +246 -0
  75. package/commands/tracker-setup.md +322 -0
  76. package/commands/update.md +202 -0
  77. package/commands/verify-phase.md +335 -0
  78. package/commands/verify-work.md +701 -0
  79. package/commands/wireup.md +29 -0
  80. package/dist/bin/gd.d.ts +3 -0
  81. package/dist/bin/gd.d.ts.map +1 -0
  82. package/dist/bin/gd.js +178 -0
  83. package/dist/bin/gd.js.map +1 -0
  84. package/dist/bin/grd-manifest.d.ts +3 -0
  85. package/dist/bin/grd-manifest.d.ts.map +1 -0
  86. package/dist/bin/grd-manifest.js +202 -0
  87. package/dist/bin/grd-manifest.js.map +1 -0
  88. package/dist/bin/grd-mcp-server.d.ts +3 -0
  89. package/dist/bin/grd-mcp-server.d.ts.map +1 -0
  90. package/dist/bin/grd-mcp-server.js +71 -0
  91. package/dist/bin/grd-mcp-server.js.map +1 -0
  92. package/dist/bin/grd-tools.d.ts +3 -0
  93. package/dist/bin/grd-tools.d.ts.map +1 -0
  94. package/dist/bin/grd-tools.js +1680 -0
  95. package/dist/bin/grd-tools.js.map +1 -0
  96. package/dist/bin/postinstall.d.ts +3 -0
  97. package/dist/bin/postinstall.d.ts.map +1 -0
  98. package/dist/bin/postinstall.js +61 -0
  99. package/dist/bin/postinstall.js.map +1 -0
  100. package/dist/lib/autopilot-milestone.d.ts +2 -0
  101. package/dist/lib/autopilot-milestone.d.ts.map +1 -0
  102. package/dist/lib/autopilot-milestone.js +94 -0
  103. package/dist/lib/autopilot-milestone.js.map +1 -0
  104. package/dist/lib/autopilot-pipeline.d.ts +2 -0
  105. package/dist/lib/autopilot-pipeline.d.ts.map +1 -0
  106. package/dist/lib/autopilot-pipeline.js +830 -0
  107. package/dist/lib/autopilot-pipeline.js.map +1 -0
  108. package/dist/lib/autopilot-waves.d.ts +2 -0
  109. package/dist/lib/autopilot-waves.d.ts.map +1 -0
  110. package/dist/lib/autopilot-waves.js +266 -0
  111. package/dist/lib/autopilot-waves.js.map +1 -0
  112. package/dist/lib/autopilot.d.ts +2 -0
  113. package/dist/lib/autopilot.d.ts.map +1 -0
  114. package/dist/lib/autopilot.js +1314 -0
  115. package/dist/lib/autopilot.js.map +1 -0
  116. package/dist/lib/autoplan.d.ts +2 -0
  117. package/dist/lib/autoplan.d.ts.map +1 -0
  118. package/dist/lib/autoplan.js +198 -0
  119. package/dist/lib/autoplan.js.map +1 -0
  120. package/dist/lib/autoresearch.d.ts +2 -0
  121. package/dist/lib/autoresearch.d.ts.map +1 -0
  122. package/dist/lib/autoresearch.js +626 -0
  123. package/dist/lib/autoresearch.js.map +1 -0
  124. package/dist/lib/backend.d.ts +2 -0
  125. package/dist/lib/backend.d.ts.map +1 -0
  126. package/dist/lib/backend.js +1036 -0
  127. package/dist/lib/backend.js.map +1 -0
  128. package/dist/lib/benchmark.d.ts +99 -0
  129. package/dist/lib/benchmark.d.ts.map +1 -0
  130. package/dist/lib/benchmark.js +278 -0
  131. package/dist/lib/benchmark.js.map +1 -0
  132. package/dist/lib/citations.d.ts +2 -0
  133. package/dist/lib/citations.d.ts.map +1 -0
  134. package/dist/lib/citations.js +642 -0
  135. package/dist/lib/citations.js.map +1 -0
  136. package/dist/lib/cleanup.d.ts +2 -0
  137. package/dist/lib/cleanup.d.ts.map +1 -0
  138. package/dist/lib/cleanup.js +1222 -0
  139. package/dist/lib/cleanup.js.map +1 -0
  140. package/dist/lib/cli/adapters.d.ts +10 -0
  141. package/dist/lib/cli/adapters.d.ts.map +1 -0
  142. package/dist/lib/cli/adapters.js +27 -0
  143. package/dist/lib/cli/adapters.js.map +1 -0
  144. package/dist/lib/cli/agent.d.ts +17 -0
  145. package/dist/lib/cli/agent.d.ts.map +1 -0
  146. package/dist/lib/cli/agent.js +53 -0
  147. package/dist/lib/cli/agent.js.map +1 -0
  148. package/dist/lib/cli/index.d.ts +21 -0
  149. package/dist/lib/cli/index.d.ts.map +1 -0
  150. package/dist/lib/cli/index.js +264 -0
  151. package/dist/lib/cli/index.js.map +1 -0
  152. package/dist/lib/cli/output.d.ts +20 -0
  153. package/dist/lib/cli/output.d.ts.map +1 -0
  154. package/dist/lib/cli/output.js +22 -0
  155. package/dist/lib/cli/output.js.map +1 -0
  156. package/dist/lib/cli/scan-dispatch.d.ts +9 -0
  157. package/dist/lib/cli/scan-dispatch.d.ts.map +1 -0
  158. package/dist/lib/cli/scan-dispatch.js +107 -0
  159. package/dist/lib/cli/scan-dispatch.js.map +1 -0
  160. package/dist/lib/cli/tools.d.ts +16 -0
  161. package/dist/lib/cli/tools.d.ts.map +1 -0
  162. package/dist/lib/cli/tools.js +168 -0
  163. package/dist/lib/cli/tools.js.map +1 -0
  164. package/dist/lib/commands/_dashboard-parsers.d.ts +2 -0
  165. package/dist/lib/commands/_dashboard-parsers.d.ts.map +1 -0
  166. package/dist/lib/commands/_dashboard-parsers.js +192 -0
  167. package/dist/lib/commands/_dashboard-parsers.js.map +1 -0
  168. package/dist/lib/commands/analysis.d.ts +2 -0
  169. package/dist/lib/commands/analysis.d.ts.map +1 -0
  170. package/dist/lib/commands/analysis.js +1418 -0
  171. package/dist/lib/commands/analysis.js.map +1 -0
  172. package/dist/lib/commands/assumptions.d.ts +2 -0
  173. package/dist/lib/commands/assumptions.d.ts.map +1 -0
  174. package/dist/lib/commands/assumptions.js +166 -0
  175. package/dist/lib/commands/assumptions.js.map +1 -0
  176. package/dist/lib/commands/blame.d.ts +2 -0
  177. package/dist/lib/commands/blame.d.ts.map +1 -0
  178. package/dist/lib/commands/blame.js +133 -0
  179. package/dist/lib/commands/blame.js.map +1 -0
  180. package/dist/lib/commands/budget.d.ts +2 -0
  181. package/dist/lib/commands/budget.d.ts.map +1 -0
  182. package/dist/lib/commands/budget.js +100 -0
  183. package/dist/lib/commands/budget.js.map +1 -0
  184. package/dist/lib/commands/check-plans.d.ts +2 -0
  185. package/dist/lib/commands/check-plans.d.ts.map +1 -0
  186. package/dist/lib/commands/check-plans.js +190 -0
  187. package/dist/lib/commands/check-plans.js.map +1 -0
  188. package/dist/lib/commands/config.d.ts +2 -0
  189. package/dist/lib/commands/config.d.ts.map +1 -0
  190. package/dist/lib/commands/config.js +188 -0
  191. package/dist/lib/commands/config.js.map +1 -0
  192. package/dist/lib/commands/dashboard.d.ts +2 -0
  193. package/dist/lib/commands/dashboard.d.ts.map +1 -0
  194. package/dist/lib/commands/dashboard.js +466 -0
  195. package/dist/lib/commands/dashboard.js.map +1 -0
  196. package/dist/lib/commands/estimate.d.ts +2 -0
  197. package/dist/lib/commands/estimate.d.ts.map +1 -0
  198. package/dist/lib/commands/estimate.js +148 -0
  199. package/dist/lib/commands/estimate.js.map +1 -0
  200. package/dist/lib/commands/eval-diff.d.ts +2 -0
  201. package/dist/lib/commands/eval-diff.d.ts.map +1 -0
  202. package/dist/lib/commands/eval-diff.js +213 -0
  203. package/dist/lib/commands/eval-diff.js.map +1 -0
  204. package/dist/lib/commands/freshness.d.ts +2 -0
  205. package/dist/lib/commands/freshness.d.ts.map +1 -0
  206. package/dist/lib/commands/freshness.js +163 -0
  207. package/dist/lib/commands/freshness.js.map +1 -0
  208. package/dist/lib/commands/health.d.ts +2 -0
  209. package/dist/lib/commands/health.d.ts.map +1 -0
  210. package/dist/lib/commands/health.js +435 -0
  211. package/dist/lib/commands/health.js.map +1 -0
  212. package/dist/lib/commands/index.d.ts +2 -0
  213. package/dist/lib/commands/index.d.ts.map +1 -0
  214. package/dist/lib/commands/index.js +128 -0
  215. package/dist/lib/commands/index.js.map +1 -0
  216. package/dist/lib/commands/install.d.ts +56 -0
  217. package/dist/lib/commands/install.d.ts.map +1 -0
  218. package/dist/lib/commands/install.js +214 -0
  219. package/dist/lib/commands/install.js.map +1 -0
  220. package/dist/lib/commands/knowhow-aggregator.d.ts +2 -0
  221. package/dist/lib/commands/knowhow-aggregator.d.ts.map +1 -0
  222. package/dist/lib/commands/knowhow-aggregator.js +279 -0
  223. package/dist/lib/commands/knowhow-aggregator.js.map +1 -0
  224. package/dist/lib/commands/knowledge-search.d.ts +2 -0
  225. package/dist/lib/commands/knowledge-search.d.ts.map +1 -0
  226. package/dist/lib/commands/knowledge-search.js +113 -0
  227. package/dist/lib/commands/knowledge-search.js.map +1 -0
  228. package/dist/lib/commands/long-term-roadmap.d.ts +2 -0
  229. package/dist/lib/commands/long-term-roadmap.d.ts.map +1 -0
  230. package/dist/lib/commands/long-term-roadmap.js +272 -0
  231. package/dist/lib/commands/long-term-roadmap.js.map +1 -0
  232. package/dist/lib/commands/patterns.d.ts +91 -0
  233. package/dist/lib/commands/patterns.d.ts.map +1 -0
  234. package/dist/lib/commands/patterns.js +391 -0
  235. package/dist/lib/commands/patterns.js.map +1 -0
  236. package/dist/lib/commands/phase-info.d.ts +2 -0
  237. package/dist/lib/commands/phase-info.d.ts.map +1 -0
  238. package/dist/lib/commands/phase-info.js +509 -0
  239. package/dist/lib/commands/phase-info.js.map +1 -0
  240. package/dist/lib/commands/plan-lint.d.ts +56 -0
  241. package/dist/lib/commands/plan-lint.d.ts.map +1 -0
  242. package/dist/lib/commands/plan-lint.js +481 -0
  243. package/dist/lib/commands/plan-lint.js.map +1 -0
  244. package/dist/lib/commands/plan-phase.d.ts +53 -0
  245. package/dist/lib/commands/plan-phase.d.ts.map +1 -0
  246. package/dist/lib/commands/plan-phase.js +288 -0
  247. package/dist/lib/commands/plan-phase.js.map +1 -0
  248. package/dist/lib/commands/progress.d.ts +2 -0
  249. package/dist/lib/commands/progress.d.ts.map +1 -0
  250. package/dist/lib/commands/progress.js +266 -0
  251. package/dist/lib/commands/progress.js.map +1 -0
  252. package/dist/lib/commands/quality.d.ts +2 -0
  253. package/dist/lib/commands/quality.d.ts.map +1 -0
  254. package/dist/lib/commands/quality.js +80 -0
  255. package/dist/lib/commands/quality.js.map +1 -0
  256. package/dist/lib/commands/rollback.d.ts +2 -0
  257. package/dist/lib/commands/rollback.d.ts.map +1 -0
  258. package/dist/lib/commands/rollback.js +145 -0
  259. package/dist/lib/commands/rollback.js.map +1 -0
  260. package/dist/lib/commands/scan.d.ts +25 -0
  261. package/dist/lib/commands/scan.d.ts.map +1 -0
  262. package/dist/lib/commands/scan.js +28 -0
  263. package/dist/lib/commands/scan.js.map +1 -0
  264. package/dist/lib/commands/search.d.ts +2 -0
  265. package/dist/lib/commands/search.d.ts.map +1 -0
  266. package/dist/lib/commands/search.js +212 -0
  267. package/dist/lib/commands/search.js.map +1 -0
  268. package/dist/lib/commands/select-candidate.d.ts +128 -0
  269. package/dist/lib/commands/select-candidate.d.ts.map +1 -0
  270. package/dist/lib/commands/select-candidate.js +518 -0
  271. package/dist/lib/commands/select-candidate.js.map +1 -0
  272. package/dist/lib/commands/singularity.d.ts +2 -0
  273. package/dist/lib/commands/singularity.d.ts.map +1 -0
  274. package/dist/lib/commands/singularity.js +185 -0
  275. package/dist/lib/commands/singularity.js.map +1 -0
  276. package/dist/lib/commands/slug-timestamp.d.ts +2 -0
  277. package/dist/lib/commands/slug-timestamp.d.ts.map +1 -0
  278. package/dist/lib/commands/slug-timestamp.js +54 -0
  279. package/dist/lib/commands/slug-timestamp.js.map +1 -0
  280. package/dist/lib/commands/tail.d.ts +2 -0
  281. package/dist/lib/commands/tail.d.ts.map +1 -0
  282. package/dist/lib/commands/tail.js +100 -0
  283. package/dist/lib/commands/tail.js.map +1 -0
  284. package/dist/lib/commands/todo.d.ts +2 -0
  285. package/dist/lib/commands/todo.d.ts.map +1 -0
  286. package/dist/lib/commands/todo.js +200 -0
  287. package/dist/lib/commands/todo.js.map +1 -0
  288. package/dist/lib/commands/watch.d.ts +2 -0
  289. package/dist/lib/commands/watch.d.ts.map +1 -0
  290. package/dist/lib/commands/watch.js +72 -0
  291. package/dist/lib/commands/watch.js.map +1 -0
  292. package/dist/lib/complexity.d.ts +55 -0
  293. package/dist/lib/complexity.d.ts.map +1 -0
  294. package/dist/lib/complexity.js +80 -0
  295. package/dist/lib/complexity.js.map +1 -0
  296. package/dist/lib/context/agents.d.ts +2 -0
  297. package/dist/lib/context/agents.d.ts.map +1 -0
  298. package/dist/lib/context/agents.js +344 -0
  299. package/dist/lib/context/agents.js.map +1 -0
  300. package/dist/lib/context/base.d.ts +2 -0
  301. package/dist/lib/context/base.d.ts.map +1 -0
  302. package/dist/lib/context/base.js +81 -0
  303. package/dist/lib/context/base.js.map +1 -0
  304. package/dist/lib/context/execute.d.ts +2 -0
  305. package/dist/lib/context/execute.d.ts.map +1 -0
  306. package/dist/lib/context/execute.js +753 -0
  307. package/dist/lib/context/execute.js.map +1 -0
  308. package/dist/lib/context/index.d.ts +2 -0
  309. package/dist/lib/context/index.d.ts.map +1 -0
  310. package/dist/lib/context/index.js +88 -0
  311. package/dist/lib/context/index.js.map +1 -0
  312. package/dist/lib/context/progress.d.ts +2 -0
  313. package/dist/lib/context/progress.d.ts.map +1 -0
  314. package/dist/lib/context/progress.js +178 -0
  315. package/dist/lib/context/progress.js.map +1 -0
  316. package/dist/lib/context/project.d.ts +2 -0
  317. package/dist/lib/context/project.d.ts.map +1 -0
  318. package/dist/lib/context/project.js +413 -0
  319. package/dist/lib/context/project.js.map +1 -0
  320. package/dist/lib/context/research.d.ts +2 -0
  321. package/dist/lib/context/research.d.ts.map +1 -0
  322. package/dist/lib/context/research.js +466 -0
  323. package/dist/lib/context/research.js.map +1 -0
  324. package/dist/lib/dead-ends.d.ts +28 -0
  325. package/dist/lib/dead-ends.d.ts.map +1 -0
  326. package/dist/lib/dead-ends.js +451 -0
  327. package/dist/lib/dead-ends.js.map +1 -0
  328. package/dist/lib/deps.d.ts +2 -0
  329. package/dist/lib/deps.d.ts.map +1 -0
  330. package/dist/lib/deps.js +630 -0
  331. package/dist/lib/deps.js.map +1 -0
  332. package/dist/lib/discussion.d.ts +2 -0
  333. package/dist/lib/discussion.d.ts.map +1 -0
  334. package/dist/lib/discussion.js +1041 -0
  335. package/dist/lib/discussion.js.map +1 -0
  336. package/dist/lib/drift.d.ts +36 -0
  337. package/dist/lib/drift.d.ts.map +1 -0
  338. package/dist/lib/drift.js +481 -0
  339. package/dist/lib/drift.js.map +1 -0
  340. package/dist/lib/evolve/_dimensions-features.d.ts +2 -0
  341. package/dist/lib/evolve/_dimensions-features.d.ts.map +1 -0
  342. package/dist/lib/evolve/_dimensions-features.js +369 -0
  343. package/dist/lib/evolve/_dimensions-features.js.map +1 -0
  344. package/dist/lib/evolve/_dimensions.d.ts +2 -0
  345. package/dist/lib/evolve/_dimensions.d.ts.map +1 -0
  346. package/dist/lib/evolve/_dimensions.js +358 -0
  347. package/dist/lib/evolve/_dimensions.js.map +1 -0
  348. package/dist/lib/evolve/_product-ideation.d.ts +2 -0
  349. package/dist/lib/evolve/_product-ideation.d.ts.map +1 -0
  350. package/dist/lib/evolve/_product-ideation.js +281 -0
  351. package/dist/lib/evolve/_product-ideation.js.map +1 -0
  352. package/dist/lib/evolve/_prompts.d.ts +2 -0
  353. package/dist/lib/evolve/_prompts.d.ts.map +1 -0
  354. package/dist/lib/evolve/_prompts.js +153 -0
  355. package/dist/lib/evolve/_prompts.js.map +1 -0
  356. package/dist/lib/evolve/cli.d.ts +2 -0
  357. package/dist/lib/evolve/cli.d.ts.map +1 -0
  358. package/dist/lib/evolve/cli.js +224 -0
  359. package/dist/lib/evolve/cli.js.map +1 -0
  360. package/dist/lib/evolve/discovery.d.ts +2 -0
  361. package/dist/lib/evolve/discovery.d.ts.map +1 -0
  362. package/dist/lib/evolve/discovery.js +391 -0
  363. package/dist/lib/evolve/discovery.js.map +1 -0
  364. package/dist/lib/evolve/index.d.ts +2 -0
  365. package/dist/lib/evolve/index.d.ts.map +1 -0
  366. package/dist/lib/evolve/index.js +88 -0
  367. package/dist/lib/evolve/index.js.map +1 -0
  368. package/dist/lib/evolve/orchestrator.d.ts +2 -0
  369. package/dist/lib/evolve/orchestrator.d.ts.map +1 -0
  370. package/dist/lib/evolve/orchestrator.js +851 -0
  371. package/dist/lib/evolve/orchestrator.js.map +1 -0
  372. package/dist/lib/evolve/scoring.d.ts +2 -0
  373. package/dist/lib/evolve/scoring.d.ts.map +1 -0
  374. package/dist/lib/evolve/scoring.js +118 -0
  375. package/dist/lib/evolve/scoring.js.map +1 -0
  376. package/dist/lib/evolve/state.d.ts +2 -0
  377. package/dist/lib/evolve/state.d.ts.map +1 -0
  378. package/dist/lib/evolve/state.js +264 -0
  379. package/dist/lib/evolve/state.js.map +1 -0
  380. package/dist/lib/evolve/types.d.ts +249 -0
  381. package/dist/lib/evolve/types.d.ts.map +1 -0
  382. package/dist/lib/evolve/types.js +3 -0
  383. package/dist/lib/evolve/types.js.map +1 -0
  384. package/dist/lib/frontmatter.d.ts +2 -0
  385. package/dist/lib/frontmatter.d.ts.map +1 -0
  386. package/dist/lib/frontmatter.js +513 -0
  387. package/dist/lib/frontmatter.js.map +1 -0
  388. package/dist/lib/gates.d.ts +2 -0
  389. package/dist/lib/gates.d.ts.map +1 -0
  390. package/dist/lib/gates.js +578 -0
  391. package/dist/lib/gates.js.map +1 -0
  392. package/dist/lib/genome.d.ts +10 -0
  393. package/dist/lib/genome.d.ts.map +1 -0
  394. package/dist/lib/genome.js +368 -0
  395. package/dist/lib/genome.js.map +1 -0
  396. package/dist/lib/got.d.ts +2 -0
  397. package/dist/lib/got.d.ts.map +1 -0
  398. package/dist/lib/got.js +280 -0
  399. package/dist/lib/got.js.map +1 -0
  400. package/dist/lib/invariants.d.ts +2 -0
  401. package/dist/lib/invariants.d.ts.map +1 -0
  402. package/dist/lib/invariants.js +298 -0
  403. package/dist/lib/invariants.js.map +1 -0
  404. package/dist/lib/knowledge.d.ts +2 -0
  405. package/dist/lib/knowledge.d.ts.map +1 -0
  406. package/dist/lib/knowledge.js +658 -0
  407. package/dist/lib/knowledge.js.map +1 -0
  408. package/dist/lib/long-term-roadmap.d.ts +2 -0
  409. package/dist/lib/long-term-roadmap.d.ts.map +1 -0
  410. package/dist/lib/long-term-roadmap.js +602 -0
  411. package/dist/lib/long-term-roadmap.js.map +1 -0
  412. package/dist/lib/markdown-split.d.ts +2 -0
  413. package/dist/lib/markdown-split.d.ts.map +1 -0
  414. package/dist/lib/markdown-split.js +199 -0
  415. package/dist/lib/markdown-split.js.map +1 -0
  416. package/dist/lib/mcp-server.d.ts +2 -0
  417. package/dist/lib/mcp-server.d.ts.map +1 -0
  418. package/dist/lib/mcp-server.js +2424 -0
  419. package/dist/lib/mcp-server.js.map +1 -0
  420. package/dist/lib/metrics.d.ts +16 -0
  421. package/dist/lib/metrics.d.ts.map +1 -0
  422. package/dist/lib/metrics.js +48 -0
  423. package/dist/lib/metrics.js.map +1 -0
  424. package/dist/lib/overstory.d.ts +2 -0
  425. package/dist/lib/overstory.d.ts.map +1 -0
  426. package/dist/lib/overstory.js +211 -0
  427. package/dist/lib/overstory.js.map +1 -0
  428. package/dist/lib/parallel.d.ts +2 -0
  429. package/dist/lib/parallel.d.ts.map +1 -0
  430. package/dist/lib/parallel.js +349 -0
  431. package/dist/lib/parallel.js.map +1 -0
  432. package/dist/lib/paths.d.ts +2 -0
  433. package/dist/lib/paths.d.ts.map +1 -0
  434. package/dist/lib/paths.js +254 -0
  435. package/dist/lib/paths.js.map +1 -0
  436. package/dist/lib/phase-complete-llm.d.ts +22 -0
  437. package/dist/lib/phase-complete-llm.d.ts.map +1 -0
  438. package/dist/lib/phase-complete-llm.js +331 -0
  439. package/dist/lib/phase-complete-llm.js.map +1 -0
  440. package/dist/lib/phase-complete.d.ts +46 -0
  441. package/dist/lib/phase-complete.d.ts.map +1 -0
  442. package/dist/lib/phase-complete.js +278 -0
  443. package/dist/lib/phase-complete.js.map +1 -0
  444. package/dist/lib/phase-io.d.ts +2 -0
  445. package/dist/lib/phase-io.d.ts.map +1 -0
  446. package/dist/lib/phase-io.js +126 -0
  447. package/dist/lib/phase-io.js.map +1 -0
  448. package/dist/lib/phase.d.ts +2 -0
  449. package/dist/lib/phase.d.ts.map +1 -0
  450. package/dist/lib/phase.js +1344 -0
  451. package/dist/lib/phase.js.map +1 -0
  452. package/dist/lib/plan-tournament.d.ts +63 -0
  453. package/dist/lib/plan-tournament.d.ts.map +1 -0
  454. package/dist/lib/plan-tournament.js +353 -0
  455. package/dist/lib/plan-tournament.js.map +1 -0
  456. package/dist/lib/refinement.d.ts +74 -0
  457. package/dist/lib/refinement.d.ts.map +1 -0
  458. package/dist/lib/refinement.js +283 -0
  459. package/dist/lib/refinement.js.map +1 -0
  460. package/dist/lib/requirements.d.ts +2 -0
  461. package/dist/lib/requirements.d.ts.map +1 -0
  462. package/dist/lib/requirements.js +355 -0
  463. package/dist/lib/requirements.js.map +1 -0
  464. package/dist/lib/research-bundle.d.ts +2 -0
  465. package/dist/lib/research-bundle.d.ts.map +1 -0
  466. package/dist/lib/research-bundle.js +246 -0
  467. package/dist/lib/research-bundle.js.map +1 -0
  468. package/dist/lib/roadmap.d.ts +2 -0
  469. package/dist/lib/roadmap.d.ts.map +1 -0
  470. package/dist/lib/roadmap.js +541 -0
  471. package/dist/lib/roadmap.js.map +1 -0
  472. package/dist/lib/sample.d.ts +16 -0
  473. package/dist/lib/sample.d.ts.map +1 -0
  474. package/dist/lib/sample.js +20 -0
  475. package/dist/lib/sample.js.map +1 -0
  476. package/dist/lib/scaffold.d.ts +2 -0
  477. package/dist/lib/scaffold.d.ts.map +1 -0
  478. package/dist/lib/scaffold.js +355 -0
  479. package/dist/lib/scaffold.js.map +1 -0
  480. package/dist/lib/scan/_utils.d.ts +11 -0
  481. package/dist/lib/scan/_utils.d.ts.map +1 -0
  482. package/dist/lib/scan/_utils.js +36 -0
  483. package/dist/lib/scan/_utils.js.map +1 -0
  484. package/dist/lib/scan/base64.d.ts +15 -0
  485. package/dist/lib/scan/base64.d.ts.map +1 -0
  486. package/dist/lib/scan/base64.js +66 -0
  487. package/dist/lib/scan/base64.js.map +1 -0
  488. package/dist/lib/scan/ignorefile.d.ts +30 -0
  489. package/dist/lib/scan/ignorefile.d.ts.map +1 -0
  490. package/dist/lib/scan/ignorefile.js +101 -0
  491. package/dist/lib/scan/ignorefile.js.map +1 -0
  492. package/dist/lib/scan/injection.d.ts +14 -0
  493. package/dist/lib/scan/injection.d.ts.map +1 -0
  494. package/dist/lib/scan/injection.js +39 -0
  495. package/dist/lib/scan/injection.js.map +1 -0
  496. package/dist/lib/scan/patterns.d.ts +17 -0
  497. package/dist/lib/scan/patterns.d.ts.map +1 -0
  498. package/dist/lib/scan/patterns.js +123 -0
  499. package/dist/lib/scan/patterns.js.map +1 -0
  500. package/dist/lib/scan/strip-markdown.d.ts +7 -0
  501. package/dist/lib/scan/strip-markdown.d.ts.map +1 -0
  502. package/dist/lib/scan/strip-markdown.js +38 -0
  503. package/dist/lib/scan/strip-markdown.js.map +1 -0
  504. package/dist/lib/scan/types.d.ts +23 -0
  505. package/dist/lib/scan/types.d.ts.map +1 -0
  506. package/dist/lib/scan/types.js +3 -0
  507. package/dist/lib/scan/types.js.map +1 -0
  508. package/dist/lib/scheduler-wait.d.ts +2 -0
  509. package/dist/lib/scheduler-wait.d.ts.map +1 -0
  510. package/dist/lib/scheduler-wait.js +59 -0
  511. package/dist/lib/scheduler-wait.js.map +1 -0
  512. package/dist/lib/scheduler.d.ts +254 -0
  513. package/dist/lib/scheduler.d.ts.map +1 -0
  514. package/dist/lib/scheduler.js +1147 -0
  515. package/dist/lib/scheduler.js.map +1 -0
  516. package/dist/lib/state.d.ts +2 -0
  517. package/dist/lib/state.d.ts.map +1 -0
  518. package/dist/lib/state.js +744 -0
  519. package/dist/lib/state.js.map +1 -0
  520. package/dist/lib/think.d.ts +18 -0
  521. package/dist/lib/think.d.ts.map +1 -0
  522. package/dist/lib/think.js +317 -0
  523. package/dist/lib/think.js.map +1 -0
  524. package/dist/lib/tracker.d.ts +2 -0
  525. package/dist/lib/tracker.d.ts.map +1 -0
  526. package/dist/lib/tracker.js +1121 -0
  527. package/dist/lib/tracker.js.map +1 -0
  528. package/dist/lib/types.d.ts +1514 -0
  529. package/dist/lib/types.d.ts.map +1 -0
  530. package/dist/lib/types.js +4 -0
  531. package/dist/lib/types.js.map +1 -0
  532. package/dist/lib/utils.d.ts +2 -0
  533. package/dist/lib/utils.d.ts.map +1 -0
  534. package/dist/lib/utils.js +1363 -0
  535. package/dist/lib/utils.js.map +1 -0
  536. package/dist/lib/verify.d.ts +2 -0
  537. package/dist/lib/verify.d.ts.map +1 -0
  538. package/dist/lib/verify.js +1153 -0
  539. package/dist/lib/verify.js.map +1 -0
  540. package/dist/lib/wireup/autofix.d.ts +2 -0
  541. package/dist/lib/wireup/autofix.d.ts.map +1 -0
  542. package/dist/lib/wireup/autofix.js +188 -0
  543. package/dist/lib/wireup/autofix.js.map +1 -0
  544. package/dist/lib/wireup/cli.d.ts +2 -0
  545. package/dist/lib/wireup/cli.d.ts.map +1 -0
  546. package/dist/lib/wireup/cli.js +194 -0
  547. package/dist/lib/wireup/cli.js.map +1 -0
  548. package/dist/lib/wireup/detection.d.ts +47 -0
  549. package/dist/lib/wireup/detection.d.ts.map +1 -0
  550. package/dist/lib/wireup/detection.js +410 -0
  551. package/dist/lib/wireup/detection.js.map +1 -0
  552. package/dist/lib/wireup/discovery.d.ts +2 -0
  553. package/dist/lib/wireup/discovery.d.ts.map +1 -0
  554. package/dist/lib/wireup/discovery.js +934 -0
  555. package/dist/lib/wireup/discovery.js.map +1 -0
  556. package/dist/lib/wireup/execution.d.ts +2 -0
  557. package/dist/lib/wireup/execution.d.ts.map +1 -0
  558. package/dist/lib/wireup/execution.js +573 -0
  559. package/dist/lib/wireup/execution.js.map +1 -0
  560. package/dist/lib/wireup/index.d.ts +2 -0
  561. package/dist/lib/wireup/index.d.ts.map +1 -0
  562. package/dist/lib/wireup/index.js +85 -0
  563. package/dist/lib/wireup/index.js.map +1 -0
  564. package/dist/lib/wireup/orchestrator.d.ts +2 -0
  565. package/dist/lib/wireup/orchestrator.d.ts.map +1 -0
  566. package/dist/lib/wireup/orchestrator.js +366 -0
  567. package/dist/lib/wireup/orchestrator.js.map +1 -0
  568. package/dist/lib/wireup/report.d.ts +47 -0
  569. package/dist/lib/wireup/report.d.ts.map +1 -0
  570. package/dist/lib/wireup/report.js +201 -0
  571. package/dist/lib/wireup/report.js.map +1 -0
  572. package/dist/lib/wireup/scenarios.d.ts +2 -0
  573. package/dist/lib/wireup/scenarios.d.ts.map +1 -0
  574. package/dist/lib/wireup/scenarios.js +516 -0
  575. package/dist/lib/wireup/scenarios.js.map +1 -0
  576. package/dist/lib/wireup/state.d.ts +2 -0
  577. package/dist/lib/wireup/state.d.ts.map +1 -0
  578. package/dist/lib/wireup/state.js +102 -0
  579. package/dist/lib/wireup/state.js.map +1 -0
  580. package/dist/lib/wireup/types.d.ts +376 -0
  581. package/dist/lib/wireup/types.d.ts.map +1 -0
  582. package/dist/lib/wireup/types.js +3 -0
  583. package/dist/lib/wireup/types.js.map +1 -0
  584. package/dist/lib/worktree.d.ts +2 -0
  585. package/dist/lib/worktree.d.ts.map +1 -0
  586. package/dist/lib/worktree.js +999 -0
  587. package/dist/lib/worktree.js.map +1 -0
  588. package/lib/autopilot-milestone.ts +136 -0
  589. package/lib/autopilot-pipeline.ts +1179 -0
  590. package/lib/autopilot-waves.ts +361 -0
  591. package/lib/autopilot.ts +1874 -0
  592. package/lib/autoplan.ts +280 -0
  593. package/lib/autoresearch.js +4 -0
  594. package/lib/autoresearch.ts +886 -0
  595. package/lib/backend.ts +1252 -0
  596. package/lib/benchmark.ts +341 -0
  597. package/lib/citations.ts +760 -0
  598. package/lib/cleanup.ts +1588 -0
  599. package/lib/cli/adapters.ts +41 -0
  600. package/lib/cli/agent.ts +83 -0
  601. package/lib/cli/index.ts +273 -0
  602. package/lib/cli/output.ts +33 -0
  603. package/lib/cli/scan-dispatch.ts +130 -0
  604. package/lib/cli/tools.ts +198 -0
  605. package/lib/commands/_dashboard-parsers.ts +275 -0
  606. package/lib/commands/analysis.ts +1851 -0
  607. package/lib/commands/assumptions.ts +232 -0
  608. package/lib/commands/blame.ts +174 -0
  609. package/lib/commands/budget.ts +148 -0
  610. package/lib/commands/check-plans.ts +233 -0
  611. package/lib/commands/config.ts +287 -0
  612. package/lib/commands/dashboard.ts +680 -0
  613. package/lib/commands/estimate.ts +204 -0
  614. package/lib/commands/eval-diff.ts +252 -0
  615. package/lib/commands/freshness.ts +213 -0
  616. package/lib/commands/health.ts +607 -0
  617. package/lib/commands/index.ts +266 -0
  618. package/lib/commands/install.ts +307 -0
  619. package/lib/commands/knowhow-aggregator.ts +345 -0
  620. package/lib/commands/knowledge-search.ts +153 -0
  621. package/lib/commands/long-term-roadmap.ts +390 -0
  622. package/lib/commands/patterns.ts +465 -0
  623. package/lib/commands/phase-info.ts +698 -0
  624. package/lib/commands/plan-lint.ts +546 -0
  625. package/lib/commands/plan-phase.ts +375 -0
  626. package/lib/commands/progress.ts +319 -0
  627. package/lib/commands/quality.ts +138 -0
  628. package/lib/commands/rollback.ts +195 -0
  629. package/lib/commands/scan.ts +72 -0
  630. package/lib/commands/search.ts +300 -0
  631. package/lib/commands/select-candidate.ts +687 -0
  632. package/lib/commands/singularity.ts +222 -0
  633. package/lib/commands/slug-timestamp.ts +74 -0
  634. package/lib/commands/tail.ts +129 -0
  635. package/lib/commands/todo.ts +273 -0
  636. package/lib/commands/watch.ts +80 -0
  637. package/lib/complexity.ts +117 -0
  638. package/lib/context/agents.ts +505 -0
  639. package/lib/context/base.ts +123 -0
  640. package/lib/context/execute.ts +977 -0
  641. package/lib/context/index.ts +110 -0
  642. package/lib/context/progress.ts +278 -0
  643. package/lib/context/project.ts +531 -0
  644. package/lib/context/research.ts +646 -0
  645. package/lib/dead-ends.ts +506 -0
  646. package/lib/deps.ts +773 -0
  647. package/lib/discussion.ts +1275 -0
  648. package/lib/drift.ts +519 -0
  649. package/lib/evolve/_dimensions-features.ts +525 -0
  650. package/lib/evolve/_dimensions.ts +511 -0
  651. package/lib/evolve/_product-ideation.ts +405 -0
  652. package/lib/evolve/_prompts.ts +178 -0
  653. package/lib/evolve/cli.ts +330 -0
  654. package/lib/evolve/discovery.ts +571 -0
  655. package/lib/evolve/index.ts +105 -0
  656. package/lib/evolve/orchestrator.ts +1139 -0
  657. package/lib/evolve/scoring.ts +167 -0
  658. package/lib/evolve/state.ts +330 -0
  659. package/lib/evolve/types.ts +290 -0
  660. package/lib/frontmatter.ts +615 -0
  661. package/lib/gates.ts +695 -0
  662. package/lib/genome.ts +402 -0
  663. package/lib/got.js +4 -0
  664. package/lib/got.ts +361 -0
  665. package/lib/invariants.ts +378 -0
  666. package/lib/knowledge.ts +768 -0
  667. package/lib/long-term-roadmap.ts +806 -0
  668. package/lib/markdown-split.ts +273 -0
  669. package/lib/mcp-server.ts +3292 -0
  670. package/lib/metrics.ts +49 -0
  671. package/lib/overstory.ts +270 -0
  672. package/lib/parallel.ts +570 -0
  673. package/lib/paths.ts +293 -0
  674. package/lib/phase-complete-llm.ts +376 -0
  675. package/lib/phase-complete.ts +366 -0
  676. package/lib/phase-io.ts +101 -0
  677. package/lib/phase.ts +1981 -0
  678. package/lib/plan-tournament.ts +426 -0
  679. package/lib/refinement.ts +349 -0
  680. package/lib/requirements.ts +469 -0
  681. package/lib/research-bundle.ts +300 -0
  682. package/lib/roadmap.ts +775 -0
  683. package/lib/scaffold.ts +480 -0
  684. package/lib/scan/_utils.ts +37 -0
  685. package/lib/scan/base64.ts +90 -0
  686. package/lib/scan/ignorefile.ts +109 -0
  687. package/lib/scan/injection.ts +67 -0
  688. package/lib/scan/patterns.ts +139 -0
  689. package/lib/scan/strip-markdown.ts +39 -0
  690. package/lib/scan/types.ts +28 -0
  691. package/lib/scheduler-wait.ts +58 -0
  692. package/lib/scheduler.ts +1370 -0
  693. package/lib/state.ts +1000 -0
  694. package/lib/think.ts +365 -0
  695. package/lib/tracker.ts +1591 -0
  696. package/lib/types.ts +1663 -0
  697. package/lib/utils.ts +1479 -0
  698. package/lib/verify.ts +1434 -0
  699. package/lib/wireup/autofix.ts +241 -0
  700. package/lib/wireup/cli.ts +278 -0
  701. package/lib/wireup/detection.ts +542 -0
  702. package/lib/wireup/discovery.ts +1063 -0
  703. package/lib/wireup/execution.ts +686 -0
  704. package/lib/wireup/index.ts +117 -0
  705. package/lib/wireup/orchestrator.ts +519 -0
  706. package/lib/wireup/report.ts +286 -0
  707. package/lib/wireup/scenarios.ts +616 -0
  708. package/lib/wireup/state.ts +139 -0
  709. package/lib/wireup/types.ts +436 -0
  710. package/lib/worktree.ts +1309 -0
  711. package/package.json +67 -0
@@ -0,0 +1,128 @@
1
+ export interface DeadEndEntry {
2
+ slug: string;
3
+ hypothesis: string;
4
+ forbidden_terms: string[];
5
+ }
6
+ export interface ExtendedAxes {
7
+ must_haves_coverage: number;
8
+ verification_commands: number;
9
+ estimated_tokens: number;
10
+ }
11
+ export interface AdvisoryWarning {
12
+ dead_end_slug: string;
13
+ jaccard: number;
14
+ }
15
+ export interface HardFailReason {
16
+ kind: 'slug_citation' | 'forbidden_term';
17
+ dead_end_slug: string;
18
+ matched: string;
19
+ }
20
+ export interface ClusterInfo {
21
+ /** Cluster index (assigned among DEAD-ENDS survivors only). */
22
+ cluster_id: number;
23
+ /** True if this candidate is its cluster's representative (highest score). */
24
+ is_representative: boolean;
25
+ /**
26
+ * relPath of the representative this candidate was merged into. null when
27
+ * this candidate IS the representative. Hard-failed candidates are not
28
+ * clustered and carry no ClusterInfo.
29
+ */
30
+ merged_into: string | null;
31
+ }
32
+ export interface ExtendedCandidateResult {
33
+ path: string;
34
+ relPath: string;
35
+ base_score: number;
36
+ total_score: number;
37
+ base_breakdown: import('../plan-tournament').ScoreBreakdown;
38
+ extended: ExtendedAxes;
39
+ hard_fail: HardFailReason | null;
40
+ advisory_warnings: AdvisoryWarning[];
41
+ /** v0.4 Phase 4: set for DEAD-ENDS survivors after proximity clustering. */
42
+ cluster?: ClusterInfo;
43
+ }
44
+ export interface SelectionResult {
45
+ phase: string;
46
+ phaseDir: string;
47
+ candidates: ExtendedCandidateResult[];
48
+ winner: ExtendedCandidateResult | null;
49
+ promoted_to: string | null;
50
+ audit_trail_path: string;
51
+ }
52
+ export interface SelectCandidateOptions {
53
+ /** Skip the rename PLAN-N.md → PLAN.md and the audit-trail write. */
54
+ dryRun?: boolean;
55
+ /** Override the milestone (default: read from STATE.md). */
56
+ milestone?: string;
57
+ /**
58
+ * Allow the verification_commands axis to execute commands. Default
59
+ * false (codex review P1) — the axis would otherwise run
60
+ * planner-authored commands during selection, before a plan is chosen.
61
+ */
62
+ runVerificationCommands?: boolean;
63
+ /**
64
+ * Overwrite an existing resolved PLAN.md when promoting the winner.
65
+ * Default false (codex review P2) — refuse to clobber a PLAN.md that
66
+ * a human or a prior selection already resolved.
67
+ */
68
+ force?: boolean;
69
+ }
70
+ /**
71
+ * Parse DEAD-ENDS.md into structured entries. Format: per-entry
72
+ * `## <slug>` header followed by a fenced YAML block. We only need
73
+ * slug, hypothesis, and forbidden_terms for selector input.
74
+ */
75
+ export declare function parseDeadEnds(content: string): DeadEndEntry[];
76
+ /**
77
+ * Scan a candidate's text content for DEAD-ENDS violations. Returns the
78
+ * first hard-fail reason found (slug citation OR forbidden_term exact
79
+ * match) and any advisory Jaccard warnings.
80
+ */
81
+ export declare function checkDeadEnds(candidateText: string, deadEnds: DeadEndEntry[]): {
82
+ hardFail: HardFailReason | null;
83
+ advisory: AdvisoryWarning[];
84
+ };
85
+ /**
86
+ * Score the candidate's coverage of REQUIREMENTS.md must_haves artifacts.
87
+ * Each found artifact = +1, each missing = -10. Negative scores remain
88
+ * finite — they're NOT a hard-fail (DEAD-ENDS is the only hard-fail path).
89
+ */
90
+ export declare function scoreMustHavesCoverage(candidateText: string, candidateFm: Record<string, unknown>, requirementsText: string | null): number;
91
+ /**
92
+ * Run each command from the candidate's `verification_commands:` YAML
93
+ * frontmatter and return pass-rate as a score in [0, 10].
94
+ *
95
+ * SECURITY (codex review P1): verification commands are planner-authored
96
+ * input that would otherwise execute during candidate *selection* —
97
+ * before a plan is even chosen, so a candidate that will be REJECTED
98
+ * could still run code. Two guards:
99
+ * 1. The axis is OFF unless `enabled` is true (selectCandidate reads
100
+ * `plan_selection.run_verification_commands` from config, default
101
+ * false). When off, returns 0 and runs nothing.
102
+ * 2. When on, only allowlisted executables run, and argv[0] must be a
103
+ * bare name (no `/` or `\\`) so `/bin/rm` / `./rm` cannot bypass.
104
+ *
105
+ * Each command is split on whitespace; argv[0] is the binary, the rest
106
+ * positional args. No shell — no pipes, redirects, or glob expansion.
107
+ * Per-command 10s timeout with SIGKILL (codex review P2: SIGTERM lets a
108
+ * child ignore the signal and hang selection).
109
+ */
110
+ export declare function scoreVerificationCommands(candidateFm: Record<string, unknown>, cwd: string, enabled: boolean): number;
111
+ /**
112
+ * Cheap token estimate: whitespace-separated words × 1.3. Used only
113
+ * as a tiebreaker when total scores tie exactly.
114
+ */
115
+ export declare function estimateTokens(text: string): number;
116
+ export declare function scoreExtendedCandidate(candidatePath: string, cwd: string, phase: string, context: {
117
+ deadEnds: DeadEndEntry[];
118
+ requirementsText: string | null;
119
+ /** Whether the verification_commands axis may execute commands. */
120
+ runVerificationCommands: boolean;
121
+ }): ExtendedCandidateResult;
122
+ export declare function selectCandidate(cwd: string, phaseNum: string, opts?: SelectCandidateOptions): SelectionResult;
123
+ export declare function cmdSelectCandidate(cwd: string, phaseNum: string, opts: {
124
+ dryRun?: boolean;
125
+ force?: boolean;
126
+ runVerificationCommands?: boolean;
127
+ }, raw: boolean): void;
128
+ //# sourceMappingURL=select-candidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-candidate.d.ts","sourceRoot":"","sources":["../../../lib/commands/select-candidate.ts"],"names":[],"mappings":"AAwFA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,eAAe,GAAG,gBAAgB,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,oBAAoB,EAAE,cAAc,CAAC;IAC5D,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACvC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAqB7D;AAuBD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,YAAY,EAAE,GACvB;IAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,CA8BlE;AAiDD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAC9B,MAAM,CAgBR;AA6BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,GACf,MAAM,CA8BR;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAID,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACP,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mEAAmE;IACnE,uBAAuB,EAAE,OAAO,CAAC;CAClC,GACA,uBAAuB,CAkDzB;AAID,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,sBAA2B,GAChC,eAAe,CA4IjB;AAqBD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAE,EAC9E,GAAG,EAAE,OAAO,GACX,IAAI,CAgBN"}
@@ -0,0 +1,518 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDeadEnds = parseDeadEnds;
4
+ exports.checkDeadEnds = checkDeadEnds;
5
+ exports.scoreMustHavesCoverage = scoreMustHavesCoverage;
6
+ exports.scoreVerificationCommands = scoreVerificationCommands;
7
+ exports.estimateTokens = estimateTokens;
8
+ exports.scoreExtendedCandidate = scoreExtendedCandidate;
9
+ exports.selectCandidate = selectCandidate;
10
+ exports.cmdSelectCandidate = cmdSelectCandidate;
11
+ /**
12
+ * GRD Commands/SelectCandidate — v0.4 Phase 3 deterministic selector.
13
+ *
14
+ * Picks one PLAN-N.md candidate from a phase directory and promotes it
15
+ * to canonical PLAN.md. Extends the v0.3.x lib/plan-tournament.ts
16
+ * scorer with four real-cost / real-signal axes per
17
+ * .planning/milestones/v0.4/phases/03-deterministic-selector/PLAN.md:
18
+ *
19
+ * 1. must_haves coverage — REQUIREMENTS.md artifacts referenced by
20
+ * the candidate's files_modified + task body
21
+ * 2. DEAD-ENDS hard-fail — slug citation OR forbidden_terms exact
22
+ * case-insensitive match; Jaccard advisory only
23
+ * 3. verification_commands axis — runs deterministic checks declared
24
+ * in the candidate's frontmatter (defaults to 0 when absent)
25
+ * 4. cost tiebreaker — fewer estimated tokens wins on score parity
26
+ *
27
+ * Pipeline:
28
+ * 1. Find PLAN-N.md files in phase dir.
29
+ * 2. Score each with the extended axes.
30
+ * 3. Filter out -Infinity (DEAD-ENDS violations).
31
+ * 4. Sort by total score; cost tiebreaker on parity.
32
+ * 5. Rename winner to PLAN.md.
33
+ * 6. Write PLAN-SELECTION.json audit trail (all candidates, all
34
+ * axis scores, hard-fail reasons, Jaccard advisory warnings).
35
+ *
36
+ * No LLM call anywhere. GENOME heuristic "no LLM-judged scoring on the
37
+ * core execution path" honored.
38
+ *
39
+ * Security: verification_commands run via argv-array spawnSync (no
40
+ * shell). Commands are split on whitespace; pipes / redirects / glob
41
+ * expansion are NOT supported (planner declares one binary + args
42
+ * per command).
43
+ */
44
+ const fs = require('fs');
45
+ const path = require('path');
46
+ const { spawnSync, } = require('child_process');
47
+ const { findPhaseDir, getMilestoneInfo, safeReadFile, safeReadMarkdown, output, error, } = require('../utils');
48
+ const { extractFrontmatter, } = require('../frontmatter');
49
+ const { scorePlanCandidate, DEFAULT_WEIGHTS, extractPlanVocabulary, clusterByJaccard, PROXIMITY_THRESHOLD, } = require('../plan-tournament');
50
+ const { atomicWriteFileSync, } = require('../autopilot-waves');
51
+ // ─── DEAD-ENDS parsing ────────────────────────────────────────────────────
52
+ /**
53
+ * Parse DEAD-ENDS.md into structured entries. Format: per-entry
54
+ * `## <slug>` header followed by a fenced YAML block. We only need
55
+ * slug, hypothesis, and forbidden_terms for selector input.
56
+ */
57
+ function parseDeadEnds(content) {
58
+ const entries = [];
59
+ const sectionRe = /^## ([a-z0-9][a-z0-9-]*)\s*$/gm;
60
+ const matches = [];
61
+ let m;
62
+ while ((m = sectionRe.exec(content)) !== null) {
63
+ matches.push({ slug: m[1], start: m.index });
64
+ }
65
+ for (let i = 0; i < matches.length; i++) {
66
+ const start = matches[i].start;
67
+ const end = i + 1 < matches.length ? matches[i + 1].start : content.length;
68
+ const section = content.slice(start, end);
69
+ const yamlMatch = section.match(/```yaml\s*\n([\s\S]*?)\n```/);
70
+ if (!yamlMatch)
71
+ continue;
72
+ const yaml = yamlMatch[1];
73
+ const slug = matches[i].slug;
74
+ const hypothesis = extractScalar(yaml, 'hypothesis') ?? '';
75
+ const forbidden_terms = extractStringList(yaml, 'forbidden_terms');
76
+ entries.push({ slug, hypothesis, forbidden_terms });
77
+ }
78
+ return entries;
79
+ }
80
+ function extractScalar(yaml, key) {
81
+ const re = new RegExp(`^${key}:\\s*"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"\\s*$`, 'm');
82
+ const m = yaml.match(re);
83
+ if (!m)
84
+ return null;
85
+ return m[1].replace(/\\"/g, '"').replace(/\\\\/g, '\\');
86
+ }
87
+ function extractStringList(yaml, key) {
88
+ const re = new RegExp(`^${key}:\\s*\\n((?: {2}- .*\\n?)+)`, 'm');
89
+ const m = yaml.match(re);
90
+ if (!m)
91
+ return [];
92
+ const out = [];
93
+ for (const line of m[1].split('\n')) {
94
+ const item = line.match(/^ {2}- "([^"\\]*(?:\\.[^"\\]*)*)"\s*$/);
95
+ if (item)
96
+ out.push(item[1].replace(/\\"/g, '"').replace(/\\\\/g, '\\'));
97
+ }
98
+ return out;
99
+ }
100
+ // ─── DEAD-ENDS hard-fail check ────────────────────────────────────────────
101
+ /**
102
+ * Scan a candidate's text content for DEAD-ENDS violations. Returns the
103
+ * first hard-fail reason found (slug citation OR forbidden_term exact
104
+ * match) and any advisory Jaccard warnings.
105
+ */
106
+ function checkDeadEnds(candidateText, deadEnds) {
107
+ const lower = candidateText.toLowerCase();
108
+ const advisory = [];
109
+ let hardFail = null;
110
+ for (const entry of deadEnds) {
111
+ if (!hardFail) {
112
+ // Codex review P2: match the slug case-insensitively and on word
113
+ // boundaries so `Elo-Rated-Plan-Tournament` still confesses while an
114
+ // unrelated longer token merely *containing* the slug does not
115
+ // false-positive.
116
+ if (slugCited(lower, entry.slug)) {
117
+ hardFail = { kind: 'slug_citation', dead_end_slug: entry.slug, matched: entry.slug };
118
+ }
119
+ else {
120
+ for (const term of entry.forbidden_terms) {
121
+ if (lower.includes(term.toLowerCase())) {
122
+ hardFail = { kind: 'forbidden_term', dead_end_slug: entry.slug, matched: term };
123
+ break;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ // Advisory Jaccard always computed for the audit trail (regardless of
129
+ // hard-fail). Threshold 0.6 is a v0.4 guess; Phase 5 may tune from data.
130
+ const j = jaccard(tokens(candidateText), tokens(entry.hypothesis));
131
+ if (j >= 0.6) {
132
+ advisory.push({ dead_end_slug: entry.slug, jaccard: j });
133
+ }
134
+ }
135
+ return { hardFail, advisory };
136
+ }
137
+ const STOP = new Set([
138
+ 'the', 'and', 'for', 'with', 'from', 'into', 'over', 'this', 'that',
139
+ 'are', 'was', 'were', 'has', 'have', 'had', 'will', 'would', 'should',
140
+ 'phase', 'plan', 'summary', 'roadmap', 'task', 'goal',
141
+ ]);
142
+ /**
143
+ * True when `slug` appears in `lowerText` (already lower-cased) bounded by
144
+ * non-slug-characters on both sides. Slug chars are [a-z0-9-]; a boundary
145
+ * is any character outside that class (or string edge). This avoids the
146
+ * substring false-positive where a slug is a fragment of a longer token.
147
+ */
148
+ function slugCited(lowerText, slug) {
149
+ const slugLower = slug.toLowerCase();
150
+ let from = 0;
151
+ for (;;) {
152
+ const idx = lowerText.indexOf(slugLower, from);
153
+ if (idx === -1)
154
+ return false;
155
+ const before = idx === 0 ? '' : lowerText[idx - 1];
156
+ const after = idx + slugLower.length >= lowerText.length ? '' : lowerText[idx + slugLower.length];
157
+ const isSlugChar = (c) => c !== '' && /[a-z0-9-]/.test(c);
158
+ if (!isSlugChar(before) && !isSlugChar(after))
159
+ return true;
160
+ from = idx + 1;
161
+ }
162
+ }
163
+ function tokens(text) {
164
+ const set = new Set();
165
+ const matches = text.toLowerCase().match(/[a-z0-9][a-z0-9_-]{2,}/g);
166
+ if (!matches)
167
+ return set;
168
+ for (const t of matches) {
169
+ if (STOP.has(t))
170
+ continue;
171
+ set.add(t);
172
+ }
173
+ return set;
174
+ }
175
+ function jaccard(a, b) {
176
+ if (a.size === 0 && b.size === 0)
177
+ return 0;
178
+ let intersection = 0;
179
+ for (const x of a)
180
+ if (b.has(x))
181
+ intersection++;
182
+ const union = a.size + b.size - intersection;
183
+ return union === 0 ? 0 : intersection / union;
184
+ }
185
+ // ─── must_haves coverage axis ─────────────────────────────────────────────
186
+ /**
187
+ * Score the candidate's coverage of REQUIREMENTS.md must_haves artifacts.
188
+ * Each found artifact = +1, each missing = -10. Negative scores remain
189
+ * finite — they're NOT a hard-fail (DEAD-ENDS is the only hard-fail path).
190
+ */
191
+ function scoreMustHavesCoverage(candidateText, candidateFm, requirementsText) {
192
+ if (!requirementsText)
193
+ return 0;
194
+ const required = extractRequiredArtifacts(requirementsText);
195
+ if (required.length === 0)
196
+ return 0;
197
+ const filesModified = Array.isArray(candidateFm['files_modified'])
198
+ ? candidateFm['files_modified'].map(String)
199
+ : [];
200
+ const haystack = candidateText + '\n' + filesModified.join('\n');
201
+ let score = 0;
202
+ for (const art of required) {
203
+ if (haystack.includes(art))
204
+ score += 1;
205
+ else
206
+ score -= 10;
207
+ }
208
+ return score;
209
+ }
210
+ function extractRequiredArtifacts(requirementsText) {
211
+ // Best-effort pull of `must_haves.artifacts:` YAML list.
212
+ const re = /must_haves:\s*\n(?:\s+\w+:\s*\n(?:\s+- .*\n)*)*\s+artifacts:\s*\n((?:\s+- .*\n)+)/;
213
+ const m = requirementsText.match(re);
214
+ const out = [];
215
+ if (m) {
216
+ for (const line of m[1].split('\n')) {
217
+ const item = line.match(/^\s+- ["']?([^"'\n]+?)["']?\s*$/);
218
+ if (item)
219
+ out.push(item[1].trim());
220
+ }
221
+ }
222
+ return out;
223
+ }
224
+ // ─── verification_commands axis ───────────────────────────────────────────
225
+ /**
226
+ * Allowlist of permitted verification-command executables. Codex review
227
+ * P1: a blocklist of dangerous binaries is bypassable via absolute paths
228
+ * (`/bin/rm`), relative paths (`./rm`), and unlisted destructive tools.
229
+ * v0.4 uses an ALLOWLIST instead — only these deterministic check tools
230
+ * may run, and only when the bare name matches (no path separators).
231
+ */
232
+ const VERIFICATION_ALLOWLIST = new Set([
233
+ 'npx', 'npm', 'pnpm', 'yarn', 'node', 'tsx', 'tsc', 'eslint', 'jest', 'prettier',
234
+ ]);
235
+ /**
236
+ * Run each command from the candidate's `verification_commands:` YAML
237
+ * frontmatter and return pass-rate as a score in [0, 10].
238
+ *
239
+ * SECURITY (codex review P1): verification commands are planner-authored
240
+ * input that would otherwise execute during candidate *selection* —
241
+ * before a plan is even chosen, so a candidate that will be REJECTED
242
+ * could still run code. Two guards:
243
+ * 1. The axis is OFF unless `enabled` is true (selectCandidate reads
244
+ * `plan_selection.run_verification_commands` from config, default
245
+ * false). When off, returns 0 and runs nothing.
246
+ * 2. When on, only allowlisted executables run, and argv[0] must be a
247
+ * bare name (no `/` or `\\`) so `/bin/rm` / `./rm` cannot bypass.
248
+ *
249
+ * Each command is split on whitespace; argv[0] is the binary, the rest
250
+ * positional args. No shell — no pipes, redirects, or glob expansion.
251
+ * Per-command 10s timeout with SIGKILL (codex review P2: SIGTERM lets a
252
+ * child ignore the signal and hang selection).
253
+ */
254
+ function scoreVerificationCommands(candidateFm, cwd, enabled) {
255
+ if (!enabled)
256
+ return 0;
257
+ const cmds = candidateFm['verification_commands'];
258
+ if (!Array.isArray(cmds) || cmds.length === 0)
259
+ return 0;
260
+ let passed = 0;
261
+ let total = 0;
262
+ for (const raw of cmds) {
263
+ if (typeof raw !== 'string' || !raw.trim())
264
+ continue;
265
+ total++;
266
+ const argv = raw.trim().split(/\s+/);
267
+ const exe = argv[0];
268
+ if (!exe)
269
+ continue;
270
+ // Reject path separators: an absolute / relative path bypasses the
271
+ // allowlist (e.g. `/bin/rm`, `./rm`, `..\\rm`).
272
+ if (exe.includes('/') || exe.includes('\\'))
273
+ continue;
274
+ if (!VERIFICATION_ALLOWLIST.has(exe))
275
+ continue;
276
+ try {
277
+ const result = spawnSync(exe, argv.slice(1), {
278
+ cwd,
279
+ timeout: 10000,
280
+ killSignal: 'SIGKILL',
281
+ stdio: 'pipe',
282
+ });
283
+ if (result.status === 0)
284
+ passed++;
285
+ }
286
+ catch {
287
+ // Treat exceptions as failure.
288
+ }
289
+ }
290
+ if (total === 0)
291
+ return 0;
292
+ return Math.round((passed / total) * 10);
293
+ }
294
+ // ─── Cost tiebreaker ──────────────────────────────────────────────────────
295
+ /**
296
+ * Cheap token estimate: whitespace-separated words × 1.3. Used only
297
+ * as a tiebreaker when total scores tie exactly.
298
+ */
299
+ function estimateTokens(text) {
300
+ const words = text.split(/\s+/).filter((s) => s.length > 0).length;
301
+ return Math.round(words * 1.3);
302
+ }
303
+ // ─── Per-candidate scoring ─────────────────────────────────────────────────
304
+ function scoreExtendedCandidate(candidatePath, cwd, phase, context) {
305
+ const relPath = path.relative(cwd, candidatePath);
306
+ const content = safeReadFile(candidatePath);
307
+ if (!content) {
308
+ return {
309
+ path: candidatePath,
310
+ relPath,
311
+ base_score: 0,
312
+ total_score: -Infinity,
313
+ base_breakdown: {
314
+ completeness: 0,
315
+ goal_alignment: 0,
316
+ hypothesis_quality: 0,
317
+ conciseness: 0,
318
+ },
319
+ extended: { must_haves_coverage: 0, verification_commands: 0, estimated_tokens: 0 },
320
+ hard_fail: { kind: 'slug_citation', dead_end_slug: '(file-unreadable)', matched: '' },
321
+ advisory_warnings: [],
322
+ };
323
+ }
324
+ const base = scorePlanCandidate(candidatePath, cwd, phase, DEFAULT_WEIGHTS);
325
+ const fm = extractFrontmatter(content);
326
+ const { hardFail, advisory } = checkDeadEnds(content, context.deadEnds);
327
+ const mustHavesScore = scoreMustHavesCoverage(content, fm, context.requirementsText);
328
+ const verificationScore = scoreVerificationCommands(fm, cwd, context.runVerificationCommands);
329
+ const tokenEst = estimateTokens(content);
330
+ // Composition: base [0,1] + must_haves (potentially negative) + verification [0,1].
331
+ // Hard-fail short-circuits to -Infinity so the audit trail still records all axes.
332
+ const totalScore = hardFail
333
+ ? -Infinity
334
+ : base.score + mustHavesScore + verificationScore / 10;
335
+ return {
336
+ path: candidatePath,
337
+ relPath,
338
+ base_score: base.score,
339
+ total_score: totalScore,
340
+ base_breakdown: base.breakdown,
341
+ extended: {
342
+ must_haves_coverage: mustHavesScore,
343
+ verification_commands: verificationScore,
344
+ estimated_tokens: tokenEst,
345
+ },
346
+ hard_fail: hardFail,
347
+ advisory_warnings: advisory,
348
+ };
349
+ }
350
+ // ─── Pipeline orchestrator ─────────────────────────────────────────────────
351
+ function selectCandidate(cwd, phaseNum, opts = {}) {
352
+ const milestone = opts.milestone ?? getMilestoneInfo(cwd).version;
353
+ const phasesDir = path.join(cwd, '.planning', 'milestones', milestone, 'phases');
354
+ const phaseDirName = findPhaseDir(phasesDir, phaseNum);
355
+ if (!phaseDirName) {
356
+ error(`phase ${phaseNum} not found under ${phasesDir}`);
357
+ }
358
+ const phaseDir = path.join(phasesDir, phaseDirName);
359
+ const candidates = listCandidateFiles(phaseDir);
360
+ if (candidates.length === 0) {
361
+ error(`no PLAN-N.md candidates found in ${phaseDir}`);
362
+ }
363
+ const deadEndsText = safeReadMarkdown(path.join(cwd, '.planning', 'DEAD-ENDS.md'));
364
+ const deadEnds = deadEndsText ? parseDeadEnds(deadEndsText) : [];
365
+ const requirementsText = safeReadMarkdown(path.join(phaseDir, 'REQUIREMENTS.md'));
366
+ const runVerificationCommands = opts.runVerificationCommands ?? false;
367
+ const scored = candidates.map((p) => scoreExtendedCandidate(p, cwd, phaseNum, {
368
+ deadEnds,
369
+ requirementsText,
370
+ runVerificationCommands,
371
+ }));
372
+ // v0.4 Phase 4 pipeline ordering (codex r1 P1 #4):
373
+ // 1. DEAD-ENDS hard-fail already happened during scoring (-Infinity).
374
+ // 2. Cluster the SURVIVORS by vocabulary Jaccard so near-clones don't
375
+ // each consume a full scoring slot. Hard-failed candidates are never
376
+ // clustered — a violator cannot eliminate an innocent clustermate.
377
+ // 3. Each cluster's representative = its highest-scoring member.
378
+ // 4. Winner = highest-scoring representative across clusters.
379
+ const survivorIdx = scored
380
+ .map((s, i) => (isFinite(s.total_score) ? i : -1))
381
+ .filter((i) => i >= 0);
382
+ // Compare two scored candidates: higher total_score wins; cheaper (fewer
383
+ // estimated tokens) breaks ties. Returns the index (into `scored`) of the
384
+ // better one.
385
+ const better = (a, b) => {
386
+ if (scored[a].total_score !== scored[b].total_score) {
387
+ return scored[a].total_score > scored[b].total_score ? a : b;
388
+ }
389
+ return scored[a].extended.estimated_tokens <= scored[b].extended.estimated_tokens ? a : b;
390
+ };
391
+ const representativeIdx = [];
392
+ if (survivorIdx.length > 0) {
393
+ const survivorVocabs = survivorIdx.map((i) => {
394
+ const content = safeReadFile(scored[i].path) ?? '';
395
+ return extractPlanVocabulary(content, extractFrontmatter(content));
396
+ });
397
+ const clusters = clusterByJaccard(survivorVocabs, PROXIMITY_THRESHOLD);
398
+ clusters.forEach((memberPositions, clusterId) => {
399
+ // memberPositions index into survivorIdx; map to scored indices.
400
+ const memberScoredIdx = memberPositions.map((p) => survivorIdx[p]);
401
+ let repScored = memberScoredIdx[0];
402
+ for (const m of memberScoredIdx)
403
+ repScored = better(repScored, m);
404
+ representativeIdx.push(repScored);
405
+ for (const m of memberScoredIdx) {
406
+ scored[m].cluster = {
407
+ cluster_id: clusterId,
408
+ is_representative: m === repScored,
409
+ merged_into: m === repScored ? null : scored[repScored].relPath,
410
+ };
411
+ }
412
+ });
413
+ }
414
+ // Winner = best representative. (Representatives are the only candidates
415
+ // eligible to be promoted — merged-away members and hard-fails are out.)
416
+ let winner = null;
417
+ if (representativeIdx.length > 0) {
418
+ let best = representativeIdx[0];
419
+ for (const r of representativeIdx)
420
+ best = better(best, r);
421
+ winner = scored[best];
422
+ }
423
+ // Present `scored` deterministically for the audit: total_score desc,
424
+ // cheaper first on parity. -Infinity (hard-fails) sink to the bottom.
425
+ scored.sort((a, b) => {
426
+ if (a.total_score !== b.total_score) {
427
+ if (!isFinite(a.total_score) && isFinite(b.total_score))
428
+ return 1;
429
+ if (isFinite(a.total_score) && !isFinite(b.total_score))
430
+ return -1;
431
+ return b.total_score - a.total_score;
432
+ }
433
+ return a.extended.estimated_tokens - b.extended.estimated_tokens;
434
+ });
435
+ let promotedTo = null;
436
+ if (winner && !opts.dryRun) {
437
+ const planPath = path.join(phaseDir, 'PLAN.md');
438
+ // Codex review P2: refuse to clobber an already-resolved PLAN.md unless
439
+ // --force. Autopilot never hits this (hasMultipleCandidates requires no
440
+ // resolved PLAN.md), but the public CLI could otherwise destroy a plan.
441
+ if (fs.existsSync(planPath) && !opts.force) {
442
+ error(`${path.relative(cwd, planPath)} already exists. Refusing to overwrite a resolved plan. ` +
443
+ `Re-run with --force to replace it, or remove it first.`);
444
+ }
445
+ promotedTo = planPath;
446
+ const winnerContent = fs.readFileSync(winner.path, 'utf-8');
447
+ atomicWriteFileSync(promotedTo, winnerContent);
448
+ }
449
+ const auditPath = path.join(phaseDir, 'PLAN-SELECTION.json');
450
+ const audit = {
451
+ phase: phaseNum,
452
+ phase_dir: phaseDir,
453
+ milestone,
454
+ timestamp: new Date().toISOString(),
455
+ candidates: scored,
456
+ winner: winner ? winner.relPath : null,
457
+ promoted_to: promotedTo ? path.relative(cwd, promotedTo) : null,
458
+ dead_ends_loaded: deadEnds.length,
459
+ requirements_loaded: requirementsText !== null,
460
+ proximity_threshold: PROXIMITY_THRESHOLD,
461
+ hard_failed: scored.filter((s) => s.hard_fail !== null).map((s) => s.relPath),
462
+ clusters_formed: representativeIdx.length,
463
+ };
464
+ if (!opts.dryRun) {
465
+ atomicWriteFileSync(auditPath, JSON.stringify(audit, null, 2));
466
+ }
467
+ return {
468
+ phase: phaseNum,
469
+ phaseDir,
470
+ candidates: scored,
471
+ winner,
472
+ promoted_to: promotedTo,
473
+ audit_trail_path: auditPath,
474
+ };
475
+ }
476
+ function listCandidateFiles(phaseDir) {
477
+ let entries;
478
+ try {
479
+ entries = fs.readdirSync(phaseDir);
480
+ }
481
+ catch {
482
+ return [];
483
+ }
484
+ const candidateRe = /^PLAN-(\d+)\.md$/;
485
+ const matches = [];
486
+ for (const name of entries) {
487
+ const m = name.match(candidateRe);
488
+ if (m)
489
+ matches.push({ idx: parseInt(m[1], 10), name });
490
+ }
491
+ matches.sort((a, b) => a.idx - b.idx);
492
+ return matches.map((m) => path.join(phaseDir, m.name));
493
+ }
494
+ // ─── CLI entry ─────────────────────────────────────────────────────────────
495
+ function cmdSelectCandidate(cwd, phaseNum, opts, raw) {
496
+ const result = selectCandidate(cwd, phaseNum, {
497
+ dryRun: opts.dryRun,
498
+ force: opts.force,
499
+ runVerificationCommands: opts.runVerificationCommands,
500
+ });
501
+ output(result, raw, result.winner
502
+ ? `winner: ${result.winner.relPath} (score ${result.winner.total_score.toFixed(3)})` +
503
+ (result.promoted_to
504
+ ? ` → promoted to ${path.relative(cwd, result.promoted_to)}`
505
+ : ' (dry-run, no promotion)')
506
+ : 'no viable winner (all candidates hard-failed)');
507
+ }
508
+ module.exports = {
509
+ parseDeadEnds,
510
+ checkDeadEnds,
511
+ scoreMustHavesCoverage,
512
+ scoreVerificationCommands,
513
+ estimateTokens,
514
+ scoreExtendedCandidate,
515
+ selectCandidate,
516
+ cmdSelectCandidate,
517
+ };
518
+ //# sourceMappingURL=select-candidate.js.map