popeye-cli 2.1.0 → 2.7.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 (356) hide show
  1. package/dist/adapters/gemini.d.ts +14 -0
  2. package/dist/adapters/gemini.d.ts.map +1 -1
  3. package/dist/adapters/gemini.js +41 -6
  4. package/dist/adapters/gemini.js.map +1 -1
  5. package/dist/adapters/grok.d.ts +14 -0
  6. package/dist/adapters/grok.d.ts.map +1 -1
  7. package/dist/adapters/grok.js +42 -6
  8. package/dist/adapters/grok.js.map +1 -1
  9. package/dist/adapters/openai.d.ts +10 -0
  10. package/dist/adapters/openai.d.ts.map +1 -1
  11. package/dist/adapters/openai.js +44 -5
  12. package/dist/adapters/openai.js.map +1 -1
  13. package/dist/cli/commands/create.js +1 -1
  14. package/dist/cli/commands/create.js.map +1 -1
  15. package/dist/cli/interactive.d.ts.map +1 -1
  16. package/dist/cli/interactive.js +328 -21
  17. package/dist/cli/interactive.js.map +1 -1
  18. package/dist/generators/all.d.ts.map +1 -1
  19. package/dist/generators/all.js +25 -2
  20. package/dist/generators/all.js.map +1 -1
  21. package/dist/generators/doc-parser.d.ts +21 -6
  22. package/dist/generators/doc-parser.d.ts.map +1 -1
  23. package/dist/generators/doc-parser.js +55 -4
  24. package/dist/generators/doc-parser.js.map +1 -1
  25. package/dist/generators/templates/fullstack.js +1 -1
  26. package/dist/generators/templates/website-components.js +1 -1
  27. package/dist/generators/templates/website-components.js.map +1 -1
  28. package/dist/generators/templates/website-config.d.ts +4 -1
  29. package/dist/generators/templates/website-config.d.ts.map +1 -1
  30. package/dist/generators/templates/website-config.js +17 -11
  31. package/dist/generators/templates/website-config.js.map +1 -1
  32. package/dist/generators/templates/website-conversion.js +1 -1
  33. package/dist/generators/templates/website-conversion.js.map +1 -1
  34. package/dist/generators/templates/website-landing.js +1 -1
  35. package/dist/generators/templates/website-landing.js.map +1 -1
  36. package/dist/generators/templates/website-layout.d.ts +36 -4
  37. package/dist/generators/templates/website-layout.d.ts.map +1 -1
  38. package/dist/generators/templates/website-layout.js +466 -23
  39. package/dist/generators/templates/website-layout.js.map +1 -1
  40. package/dist/generators/templates/website-pricing.js +1 -1
  41. package/dist/generators/templates/website-pricing.js.map +1 -1
  42. package/dist/generators/templates/website-sections.js +1 -1
  43. package/dist/generators/templates/website-sections.js.map +1 -1
  44. package/dist/generators/templates/website-seo.d.ts.map +1 -1
  45. package/dist/generators/templates/website-seo.js +4 -1
  46. package/dist/generators/templates/website-seo.js.map +1 -1
  47. package/dist/generators/templates/website.d.ts +1 -1
  48. package/dist/generators/templates/website.d.ts.map +1 -1
  49. package/dist/generators/templates/website.js +1 -1
  50. package/dist/generators/templates/website.js.map +1 -1
  51. package/dist/generators/website-content-ai.d.ts +52 -0
  52. package/dist/generators/website-content-ai.d.ts.map +1 -0
  53. package/dist/generators/website-content-ai.js +141 -0
  54. package/dist/generators/website-content-ai.js.map +1 -0
  55. package/dist/generators/website-content-scanner.d.ts +1 -1
  56. package/dist/generators/website-content-scanner.d.ts.map +1 -1
  57. package/dist/generators/website-content-scanner.js +98 -1
  58. package/dist/generators/website-content-scanner.js.map +1 -1
  59. package/dist/generators/website-context.d.ts +34 -1
  60. package/dist/generators/website-context.d.ts.map +1 -1
  61. package/dist/generators/website-context.js +131 -9
  62. package/dist/generators/website-context.js.map +1 -1
  63. package/dist/generators/website-debug.d.ts +12 -0
  64. package/dist/generators/website-debug.d.ts.map +1 -1
  65. package/dist/generators/website-debug.js +16 -0
  66. package/dist/generators/website-debug.js.map +1 -1
  67. package/dist/generators/website.d.ts.map +1 -1
  68. package/dist/generators/website.js +26 -4
  69. package/dist/generators/website.js.map +1 -1
  70. package/dist/pipeline/artifact-manager.d.ts.map +1 -1
  71. package/dist/pipeline/artifact-manager.js +3 -0
  72. package/dist/pipeline/artifact-manager.js.map +1 -1
  73. package/dist/pipeline/auto-recovery.d.ts +56 -0
  74. package/dist/pipeline/auto-recovery.d.ts.map +1 -0
  75. package/dist/pipeline/auto-recovery.js +185 -0
  76. package/dist/pipeline/auto-recovery.js.map +1 -0
  77. package/dist/pipeline/change-request.d.ts +39 -0
  78. package/dist/pipeline/change-request.d.ts.map +1 -1
  79. package/dist/pipeline/change-request.js +40 -1
  80. package/dist/pipeline/change-request.js.map +1 -1
  81. package/dist/pipeline/check-runner.d.ts +30 -1
  82. package/dist/pipeline/check-runner.d.ts.map +1 -1
  83. package/dist/pipeline/check-runner.js +122 -1
  84. package/dist/pipeline/check-runner.js.map +1 -1
  85. package/dist/pipeline/command-resolver.d.ts.map +1 -1
  86. package/dist/pipeline/command-resolver.js +33 -2
  87. package/dist/pipeline/command-resolver.js.map +1 -1
  88. package/dist/pipeline/consensus/arbitrator-query.d.ts +22 -0
  89. package/dist/pipeline/consensus/arbitrator-query.d.ts.map +1 -0
  90. package/dist/pipeline/consensus/arbitrator-query.js +70 -0
  91. package/dist/pipeline/consensus/arbitrator-query.js.map +1 -0
  92. package/dist/pipeline/consensus/consensus-runner.d.ts +131 -7
  93. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -1
  94. package/dist/pipeline/consensus/consensus-runner.js +809 -35
  95. package/dist/pipeline/consensus/consensus-runner.js.map +1 -1
  96. package/dist/pipeline/cr-lifecycle.d.ts +42 -0
  97. package/dist/pipeline/cr-lifecycle.d.ts.map +1 -0
  98. package/dist/pipeline/cr-lifecycle.js +89 -0
  99. package/dist/pipeline/cr-lifecycle.js.map +1 -0
  100. package/dist/pipeline/gate-engine.d.ts +1 -0
  101. package/dist/pipeline/gate-engine.d.ts.map +1 -1
  102. package/dist/pipeline/gate-engine.js +27 -8
  103. package/dist/pipeline/gate-engine.js.map +1 -1
  104. package/dist/pipeline/migration.d.ts.map +1 -1
  105. package/dist/pipeline/migration.js +3 -26
  106. package/dist/pipeline/migration.js.map +1 -1
  107. package/dist/pipeline/orchestrator.d.ts +1 -1
  108. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  109. package/dist/pipeline/orchestrator.js +311 -16
  110. package/dist/pipeline/orchestrator.js.map +1 -1
  111. package/dist/pipeline/packets/consensus-packet-builder.d.ts +15 -4
  112. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -1
  113. package/dist/pipeline/packets/consensus-packet-builder.js +29 -17
  114. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -1
  115. package/dist/pipeline/phases/architecture.d.ts.map +1 -1
  116. package/dist/pipeline/phases/architecture.js +5 -3
  117. package/dist/pipeline/phases/architecture.js.map +1 -1
  118. package/dist/pipeline/phases/audit.d.ts.map +1 -1
  119. package/dist/pipeline/phases/audit.js +5 -3
  120. package/dist/pipeline/phases/audit.js.map +1 -1
  121. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -1
  122. package/dist/pipeline/phases/consensus-architecture.js +10 -1
  123. package/dist/pipeline/phases/consensus-architecture.js.map +1 -1
  124. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -1
  125. package/dist/pipeline/phases/consensus-master-plan.js +10 -3
  126. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -1
  127. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -1
  128. package/dist/pipeline/phases/consensus-role-plans.js +10 -1
  129. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -1
  130. package/dist/pipeline/phases/done.d.ts.map +1 -1
  131. package/dist/pipeline/phases/done.js +9 -4
  132. package/dist/pipeline/phases/done.js.map +1 -1
  133. package/dist/pipeline/phases/intake.d.ts +1 -0
  134. package/dist/pipeline/phases/intake.d.ts.map +1 -1
  135. package/dist/pipeline/phases/intake.js +56 -13
  136. package/dist/pipeline/phases/intake.js.map +1 -1
  137. package/dist/pipeline/phases/phase-context.d.ts +2 -0
  138. package/dist/pipeline/phases/phase-context.d.ts.map +1 -1
  139. package/dist/pipeline/phases/phase-context.js +3 -1
  140. package/dist/pipeline/phases/phase-context.js.map +1 -1
  141. package/dist/pipeline/phases/production-gate.d.ts.map +1 -1
  142. package/dist/pipeline/phases/production-gate.js +28 -3
  143. package/dist/pipeline/phases/production-gate.js.map +1 -1
  144. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -1
  145. package/dist/pipeline/phases/qa-validation.js +38 -5
  146. package/dist/pipeline/phases/qa-validation.js.map +1 -1
  147. package/dist/pipeline/phases/recovery-loop.d.ts +2 -0
  148. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -1
  149. package/dist/pipeline/phases/recovery-loop.js +200 -6
  150. package/dist/pipeline/phases/recovery-loop.js.map +1 -1
  151. package/dist/pipeline/phases/review.d.ts.map +1 -1
  152. package/dist/pipeline/phases/review.js +58 -28
  153. package/dist/pipeline/phases/review.js.map +1 -1
  154. package/dist/pipeline/phases/role-planning.d.ts.map +1 -1
  155. package/dist/pipeline/phases/role-planning.js +20 -5
  156. package/dist/pipeline/phases/role-planning.js.map +1 -1
  157. package/dist/pipeline/phases/stuck.d.ts.map +1 -1
  158. package/dist/pipeline/phases/stuck.js +10 -0
  159. package/dist/pipeline/phases/stuck.js.map +1 -1
  160. package/dist/pipeline/repo-snapshot.d.ts.map +1 -1
  161. package/dist/pipeline/repo-snapshot.js +3 -0
  162. package/dist/pipeline/repo-snapshot.js.map +1 -1
  163. package/dist/pipeline/role-execution-adapter.d.ts +2 -1
  164. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -1
  165. package/dist/pipeline/role-execution-adapter.js +22 -7
  166. package/dist/pipeline/role-execution-adapter.js.map +1 -1
  167. package/dist/pipeline/skill-loader.d.ts +19 -0
  168. package/dist/pipeline/skill-loader.d.ts.map +1 -1
  169. package/dist/pipeline/skill-loader.js +22 -0
  170. package/dist/pipeline/skill-loader.js.map +1 -1
  171. package/dist/pipeline/skills/constitution-generator.d.ts +51 -0
  172. package/dist/pipeline/skills/constitution-generator.d.ts.map +1 -0
  173. package/dist/pipeline/skills/constitution-generator.js +210 -0
  174. package/dist/pipeline/skills/constitution-generator.js.map +1 -0
  175. package/dist/pipeline/skills/coverage-gate.d.ts +44 -0
  176. package/dist/pipeline/skills/coverage-gate.d.ts.map +1 -0
  177. package/dist/pipeline/skills/coverage-gate.js +143 -0
  178. package/dist/pipeline/skills/coverage-gate.js.map +1 -0
  179. package/dist/pipeline/skills/generator.d.ts +65 -0
  180. package/dist/pipeline/skills/generator.d.ts.map +1 -0
  181. package/dist/pipeline/skills/generator.js +221 -0
  182. package/dist/pipeline/skills/generator.js.map +1 -0
  183. package/dist/pipeline/skills/role-map.d.ts +38 -0
  184. package/dist/pipeline/skills/role-map.d.ts.map +1 -0
  185. package/dist/pipeline/skills/role-map.js +234 -0
  186. package/dist/pipeline/skills/role-map.js.map +1 -0
  187. package/dist/pipeline/skills/types.d.ts +47 -0
  188. package/dist/pipeline/skills/types.d.ts.map +1 -0
  189. package/dist/pipeline/skills/types.js +5 -0
  190. package/dist/pipeline/skills/types.js.map +1 -0
  191. package/dist/pipeline/skills/usage-registry.d.ts +48 -0
  192. package/dist/pipeline/skills/usage-registry.d.ts.map +1 -0
  193. package/dist/pipeline/skills/usage-registry.js +55 -0
  194. package/dist/pipeline/skills/usage-registry.js.map +1 -0
  195. package/dist/pipeline/strategy-context.d.ts +20 -0
  196. package/dist/pipeline/strategy-context.d.ts.map +1 -0
  197. package/dist/pipeline/strategy-context.js +55 -0
  198. package/dist/pipeline/strategy-context.js.map +1 -0
  199. package/dist/pipeline/type-defs/artifacts.d.ts +30 -5
  200. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -1
  201. package/dist/pipeline/type-defs/artifacts.js +5 -0
  202. package/dist/pipeline/type-defs/artifacts.js.map +1 -1
  203. package/dist/pipeline/type-defs/audit.d.ts +28 -13
  204. package/dist/pipeline/type-defs/audit.d.ts.map +1 -1
  205. package/dist/pipeline/type-defs/checks.d.ts +19 -8
  206. package/dist/pipeline/type-defs/checks.d.ts.map +1 -1
  207. package/dist/pipeline/type-defs/checks.js +4 -0
  208. package/dist/pipeline/type-defs/checks.js.map +1 -1
  209. package/dist/pipeline/type-defs/packets.d.ts +119 -18
  210. package/dist/pipeline/type-defs/packets.d.ts.map +1 -1
  211. package/dist/pipeline/type-defs/packets.js +17 -1
  212. package/dist/pipeline/type-defs/packets.js.map +1 -1
  213. package/dist/pipeline/type-defs/state.d.ts +165 -16
  214. package/dist/pipeline/type-defs/state.d.ts.map +1 -1
  215. package/dist/pipeline/type-defs/state.js +26 -1
  216. package/dist/pipeline/type-defs/state.js.map +1 -1
  217. package/dist/shared/text-utils.d.ts +23 -0
  218. package/dist/shared/text-utils.d.ts.map +1 -0
  219. package/dist/shared/text-utils.js +66 -0
  220. package/dist/shared/text-utils.js.map +1 -0
  221. package/dist/shared/website-strategy-format.d.ts +18 -0
  222. package/dist/shared/website-strategy-format.d.ts.map +1 -0
  223. package/dist/shared/website-strategy-format.js +47 -0
  224. package/dist/shared/website-strategy-format.js.map +1 -0
  225. package/dist/state/index.d.ts +2 -0
  226. package/dist/state/index.d.ts.map +1 -1
  227. package/dist/state/index.js +57 -8
  228. package/dist/state/index.js.map +1 -1
  229. package/dist/types/consensus.d.ts +1 -0
  230. package/dist/types/consensus.d.ts.map +1 -1
  231. package/dist/types/consensus.js.map +1 -1
  232. package/dist/types/website-strategy.d.ts +1 -1
  233. package/dist/types/workflow.d.ts +447 -0
  234. package/dist/types/workflow.d.ts.map +1 -1
  235. package/dist/types/workflow.js +3 -0
  236. package/dist/types/workflow.js.map +1 -1
  237. package/dist/upgrade/handlers.d.ts.map +1 -1
  238. package/dist/upgrade/handlers.js +6 -3
  239. package/dist/upgrade/handlers.js.map +1 -1
  240. package/dist/workflow/consensus.d.ts.map +1 -1
  241. package/dist/workflow/consensus.js +1 -0
  242. package/dist/workflow/consensus.js.map +1 -1
  243. package/dist/workflow/website-strategy.d.ts.map +1 -1
  244. package/dist/workflow/website-strategy.js +2 -29
  245. package/dist/workflow/website-strategy.js.map +1 -1
  246. package/dist/workflow/website-updater.d.ts.map +1 -1
  247. package/dist/workflow/website-updater.js +3 -2
  248. package/dist/workflow/website-updater.js.map +1 -1
  249. package/package.json +1 -1
  250. package/src/adapters/gemini.ts +51 -6
  251. package/src/adapters/grok.ts +51 -6
  252. package/src/adapters/openai.ts +53 -5
  253. package/src/cli/commands/create.ts +1 -1
  254. package/src/cli/interactive.ts +337 -20
  255. package/src/generators/all.ts +25 -2
  256. package/src/generators/doc-parser.ts +75 -15
  257. package/src/generators/templates/fullstack.ts +1 -1
  258. package/src/generators/templates/website-components.ts +1 -1
  259. package/src/generators/templates/website-config.ts +23 -11
  260. package/src/generators/templates/website-conversion.ts +1 -1
  261. package/src/generators/templates/website-landing.ts +1 -1
  262. package/src/generators/templates/website-layout.ts +491 -23
  263. package/src/generators/templates/website-pricing.ts +1 -1
  264. package/src/generators/templates/website-sections.ts +1 -1
  265. package/src/generators/templates/website-seo.ts +4 -1
  266. package/src/generators/templates/website.ts +3 -0
  267. package/src/generators/website-content-ai.ts +186 -0
  268. package/src/generators/website-content-scanner.ts +113 -1
  269. package/src/generators/website-context.ts +151 -12
  270. package/src/generators/website-debug.ts +26 -0
  271. package/src/generators/website.ts +28 -3
  272. package/src/pipeline/artifact-manager.ts +3 -0
  273. package/src/pipeline/auto-recovery.ts +283 -0
  274. package/src/pipeline/change-request.ts +63 -1
  275. package/src/pipeline/check-runner.ts +141 -2
  276. package/src/pipeline/command-resolver.ts +34 -2
  277. package/src/pipeline/consensus/arbitrator-query.ts +101 -0
  278. package/src/pipeline/consensus/consensus-runner.ts +1099 -42
  279. package/src/pipeline/cr-lifecycle.ts +103 -0
  280. package/src/pipeline/gate-engine.ts +36 -8
  281. package/src/pipeline/migration.ts +5 -30
  282. package/src/pipeline/orchestrator.ts +367 -16
  283. package/src/pipeline/packets/consensus-packet-builder.ts +44 -18
  284. package/src/pipeline/phases/architecture.ts +6 -3
  285. package/src/pipeline/phases/audit.ts +6 -3
  286. package/src/pipeline/phases/consensus-architecture.ts +10 -1
  287. package/src/pipeline/phases/consensus-master-plan.ts +10 -3
  288. package/src/pipeline/phases/consensus-role-plans.ts +10 -1
  289. package/src/pipeline/phases/done.ts +15 -4
  290. package/src/pipeline/phases/intake.ts +67 -14
  291. package/src/pipeline/phases/phase-context.ts +6 -1
  292. package/src/pipeline/phases/production-gate.ts +41 -3
  293. package/src/pipeline/phases/qa-validation.ts +51 -5
  294. package/src/pipeline/phases/recovery-loop.ts +229 -7
  295. package/src/pipeline/phases/review.ts +73 -30
  296. package/src/pipeline/phases/role-planning.ts +23 -5
  297. package/src/pipeline/phases/stuck.ts +10 -0
  298. package/src/pipeline/repo-snapshot.ts +3 -0
  299. package/src/pipeline/role-execution-adapter.ts +30 -4
  300. package/src/pipeline/skill-loader.ts +33 -0
  301. package/src/pipeline/skills/constitution-generator.ts +236 -0
  302. package/src/pipeline/skills/coverage-gate.ts +199 -0
  303. package/src/pipeline/skills/generator.ts +287 -0
  304. package/src/pipeline/skills/role-map.ts +248 -0
  305. package/src/pipeline/skills/types.ts +53 -0
  306. package/src/pipeline/skills/usage-registry.ts +87 -0
  307. package/src/pipeline/strategy-context.ts +60 -0
  308. package/src/pipeline/type-defs/artifacts.ts +5 -0
  309. package/src/pipeline/type-defs/checks.ts +4 -0
  310. package/src/pipeline/type-defs/packets.ts +18 -1
  311. package/src/pipeline/type-defs/state.ts +26 -1
  312. package/src/shared/text-utils.ts +70 -0
  313. package/src/shared/website-strategy-format.ts +56 -0
  314. package/src/state/index.ts +60 -8
  315. package/src/types/consensus.ts +1 -0
  316. package/src/types/workflow.ts +6 -0
  317. package/src/upgrade/handlers.ts +9 -3
  318. package/src/workflow/consensus.ts +1 -0
  319. package/src/workflow/website-strategy.ts +2 -36
  320. package/src/workflow/website-updater.ts +4 -2
  321. package/tests/adapters/gemini.test.ts +165 -0
  322. package/tests/adapters/grok.test.ts +137 -0
  323. package/tests/adapters/openai.test.ts +128 -0
  324. package/tests/generators/doc-parser.test.ts +88 -9
  325. package/tests/generators/quality-gate.test.ts +19 -3
  326. package/tests/generators/website-components.test.ts +34 -0
  327. package/tests/generators/website-content-ai.test.ts +308 -0
  328. package/tests/generators/website-content-scanner.test.ts +86 -0
  329. package/tests/generators/website-context.test.ts +3 -2
  330. package/tests/integration/smokestack-scaffold.test.ts +385 -0
  331. package/tests/pipeline/auto-recovery.test.ts +337 -0
  332. package/tests/pipeline/change-request.test.ts +70 -0
  333. package/tests/pipeline/command-resolver.test.ts +42 -0
  334. package/tests/pipeline/consensus/arbitrator-query.test.ts +107 -0
  335. package/tests/pipeline/consensus-runner.test.ts +1333 -10
  336. package/tests/pipeline/consensus-scoring.test.ts +602 -18
  337. package/tests/pipeline/gate-engine.test.ts +34 -0
  338. package/tests/pipeline/install-check.test.ts +261 -0
  339. package/tests/pipeline/migration.test.ts +4 -3
  340. package/tests/pipeline/orchestrator.test.ts +1506 -15
  341. package/tests/pipeline/packets/builders.test.ts +29 -6
  342. package/tests/pipeline/phases/role-planning.strategy.test.ts +204 -0
  343. package/tests/pipeline/pipeline-persistence.test.ts +230 -0
  344. package/tests/pipeline/recovery-loop-guidance.test.ts +280 -0
  345. package/tests/pipeline/role-execution-adapter.test.ts +88 -0
  346. package/tests/pipeline/skills/constitution-generator.test.ts +201 -0
  347. package/tests/pipeline/skills/coverage-gate.test.ts +370 -0
  348. package/tests/pipeline/skills/generator.test.ts +213 -0
  349. package/tests/pipeline/skills/role-map.test.ts +198 -0
  350. package/tests/pipeline/skills/usage-registry.test.ts +114 -0
  351. package/tests/pipeline/strategy-context.test.ts +148 -0
  352. package/tests/shared/text-utils.test.ts +155 -0
  353. package/tests/state/progress-analysis.test.ts +375 -0
  354. package/tests/upgrade/handlers.test.ts +33 -2
  355. package/tests/workflow/consensus.test.ts +6 -0
  356. package/tsconfig.json +1 -1
@@ -3,9 +3,11 @@
3
3
  * Uses commandResolver + checkRunner. Runs placeholder scan (P2-2).
4
4
  * v1.1: Adds start check and env check.
5
5
  */
6
+ import { join } from 'node:path';
7
+ import { existsSync } from 'node:fs';
6
8
  import { successResult, failureResult, triggerJournalist } from './phase-context.js';
7
9
  import { resolveCommands } from '../command-resolver.js';
8
- import { runAllChecks, runPlaceholderScan, runStartCheck, runEnvCheck, storeCheckResults } from '../check-runner.js';
10
+ import { runAllChecks, runPlaceholderScan, runStartCheck, runEnvCheck, runCheck, storeCheckResults, shouldSkipInstall, writeInstallMarker, } from '../check-runner.js';
9
11
  import { generateRepoSnapshot } from '../repo-snapshot.js';
10
12
  export async function runProductionGate(context) {
11
13
  const { pipeline, artifactManager, projectDir } = context;
@@ -15,6 +17,24 @@ export async function runProductionGate(context) {
15
17
  const snapshot = await generateRepoSnapshot(projectDir);
16
18
  const commands = resolveCommands(snapshot);
17
19
  pipeline.resolvedCommands = commands;
20
+ // 1.5. Install dependencies if needed (skips if unchanged since QA_VALIDATION)
21
+ if (commands.install) {
22
+ const installCwd = commands.install_cwd
23
+ ? join(projectDir, commands.install_cwd)
24
+ : projectDir;
25
+ const skipInstall = shouldSkipInstall(projectDir, snapshot);
26
+ if (!skipInstall) {
27
+ const installResult = await runCheck('install', commands.install, installCwd);
28
+ if (installResult.status === 'fail') {
29
+ const stored = storeCheckResults([installResult], artifactManager, 'PRODUCTION_GATE');
30
+ artifacts.push(...stored);
31
+ pipeline.artifacts.push(...artifacts);
32
+ pipeline.gateChecks['PRODUCTION_GATE'] = [installResult];
33
+ return failureResult('PRODUCTION_GATE', 'Dependency installation failed', installResult.stderr_summary ?? '');
34
+ }
35
+ writeInstallMarker(projectDir, snapshot);
36
+ }
37
+ }
18
38
  // 2. Run all checks
19
39
  const checkResults = await runAllChecks(commands, projectDir);
20
40
  // 3. Run placeholder scan (P2-2)
@@ -39,7 +59,12 @@ export async function runProductionGate(context) {
39
59
  const failedChecks = checkResults.filter((r) => r.status === 'fail' && r.check_type !== 'placeholder_scan');
40
60
  const hasPlaceholders = placeholderResult.status === 'fail';
41
61
  const auditPassed = pipeline.artifacts.some((a) => a.type === 'audit_report');
42
- const passed = failedChecks.length === 0 && auditPassed;
62
+ // Detect website projects placeholder_scan blocks for these
63
+ const isWebsiteProject = existsSync(join(projectDir, 'next.config.mjs')) ||
64
+ existsSync(join(projectDir, 'next.config.js')) ||
65
+ existsSync(join(projectDir, 'src', 'app', 'layout.tsx'));
66
+ const placeholderBlocking = hasPlaceholders && isWebsiteProject;
67
+ const passed = failedChecks.length === 0 && auditPassed && !placeholderBlocking;
43
68
  // 9. Create production readiness report
44
69
  const report = [
45
70
  '# Production Readiness Report',
@@ -61,7 +86,7 @@ export async function runProductionGate(context) {
61
86
  `- Env: ${findCheckStatus(checkResults, 'env_check')}`,
62
87
  `- Start: ${findCheckStatus(checkResults, 'start')}`,
63
88
  `- Audit: ${auditPassed ? 'PASS' : 'MISSING'}`,
64
- `- Placeholders: ${hasPlaceholders ? 'WARNING' : 'CLEAN'}`,
89
+ `- Placeholders: ${hasPlaceholders ? (placeholderBlocking ? 'FAIL (blocking for website)' : 'WARNING') : 'CLEAN'}`,
65
90
  ].join('\n');
66
91
  const reportEntry = artifactManager.createAndStoreText('production_readiness', report, 'PRODUCTION_GATE');
67
92
  artifacts.push(reportEntry);
@@ -1 +1 @@
1
- {"version":3,"file":"production-gate.js","sourceRoot":"","sources":["../../../src/pipeline/phases/production-gate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"production-gate.js","sourceRoot":"","sources":["../../../src/pipeline/phases/production-gate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAqB;IAC3D,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,SAAS,GAAG,EAAE,CAAC;IAErB,IAAI,CAAC;QACH,oCAAoC;QACpC,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC3C,QAAQ,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QAErC,+EAA+E;QAC/E,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW;gBACrC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC;gBACxC,CAAC,CAAC,UAAU,CAAC;YACf,MAAM,WAAW,GAAG,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;gBAC9E,IAAI,aAAa,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBACpC,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,aAAa,CAAC,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;oBACtF,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;oBAC1B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;oBACtC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBACzD,OAAO,aAAa,CAAC,iBAAiB,EAAE,gCAAgC,EAAE,aAAa,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;gBAChH,CAAC;gBACD,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAE9D,iCAAiC;QACjC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACzD,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAErC,0BAA0B;QAC1B,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACpD,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE7B,oDAAoD;QACpD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE;gBAClE,IAAI,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,IAAI;aAC1C,CAAC,CAAC;YACH,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACjC,CAAC;QAED,sCAAsC;QACtC,MAAM,cAAc,GAAG,iBAAiB,CAAC,YAAY,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;QAC3F,SAAS,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;QAElC,mCAAmC;QACnC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,YAAY,CAAC;QAEtD,yBAAyB;QACzB,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,KAAK,kBAAkB,CAClE,CAAC;QACF,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,KAAK,MAAM,CAAC;QAC5D,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;QAE9E,8DAA8D;QAC9D,MAAM,gBAAgB,GACpB,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;YAC9C,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3D,MAAM,mBAAmB,GAAG,eAAe,IAAI,gBAAgB,CAAC;QAChE,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,mBAAmB,CAAC;QAEhF,wCAAwC;QACxC,MAAM,MAAM,GAAG;YACb,+BAA+B;YAC/B,EAAE;YACF,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;YAC5C,gBAAgB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE;YAC1C,EAAE;YACF,kBAAkB;YAClB,EAAE;YACF,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxB,OAAO,CAAC,CAAC,UAAU,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CACxF;YACD,EAAE;YACF,eAAe,CAAC,CAAC,CAAC,4CAA4C,GAAG,CAAC,iBAAiB,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YAC9G,EAAE;YACF,gBAAgB;YAChB,YAAY,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE;YACpD,YAAY,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE;YACnD,WAAW,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE;YAClD,gBAAgB,eAAe,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE;YAC5D,UAAU,eAAe,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE;YACtD,YAAY,eAAe,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE;YACpD,YAAY,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE;YAC9C,mBAAmB,eAAe,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;SACnH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,WAAW,GAAG,eAAe,CAAC,kBAAkB,CACpD,sBAAsB,EACtB,MAAM,EACN,iBAAiB,CAClB,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE5B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAEtC,yBAAyB;QACzB,MAAM,iBAAiB,CAAC,iBAAiB,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAE/D,OAAO,aAAa,CAClB,iBAAiB,EACjB,SAAS,EACT,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,yBAAyB,YAAY,CAAC,MAAM,gBAAgB,CAC/F,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,OAAO,aAAa,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,OAAiD,EACjD,IAAY;IAEZ,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACtB,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"qa-validation.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/qa-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMpE,wBAAsB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmDjF"}
1
+ {"version":3,"file":"qa-validation.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/qa-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAYpE,wBAAsB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAyFjF"}
@@ -2,19 +2,44 @@
2
2
  * QA_VALIDATION phase — execute QA plan and validate critical paths.
3
3
  * Runs tests via checkRunner. Creates qa_validation artifact.
4
4
  */
5
+ import { join } from 'node:path';
5
6
  import { successResult, failureResult } from './phase-context.js';
6
7
  import { resolveCommands } from '../command-resolver.js';
7
- import { runCheck, storeCheckResults } from '../check-runner.js';
8
+ import { runCheck, storeCheckResults, shouldSkipInstall, writeInstallMarker, invalidateInstallMarker, } from '../check-runner.js';
8
9
  import { generateRepoSnapshot } from '../repo-snapshot.js';
9
10
  export async function runQaValidation(context) {
10
- const { pipeline, artifactManager, projectDir } = context;
11
+ const { pipeline, artifactManager, skillLoader, skillUsageRegistry, projectDir } = context;
11
12
  const artifacts = [];
12
13
  try {
13
- // 1. Resolve test command
14
+ // 1. Load QA_TESTER skill and record usage
15
+ const { definition: _qaSkill, meta: qaMeta } = skillLoader.loadSkillWithMeta('QA_TESTER');
16
+ skillUsageRegistry.record('QA_TESTER', 'QA_VALIDATION', 'system_prompt', qaMeta.source, qaMeta.version);
17
+ // 2. Resolve test command
14
18
  const snapshot = await generateRepoSnapshot(projectDir);
15
19
  const commands = resolveCommands(snapshot);
16
20
  pipeline.resolvedCommands = commands;
17
- // 2. Run test command
21
+ // 2.5. Install dependencies if needed
22
+ if (commands.install) {
23
+ const installCwd = commands.install_cwd
24
+ ? join(projectDir, commands.install_cwd)
25
+ : projectDir;
26
+ const skipInstall = shouldSkipInstall(projectDir, snapshot);
27
+ if (!skipInstall) {
28
+ const installResult = await runCheck('install', commands.install, installCwd);
29
+ const stored = storeCheckResults([installResult], artifactManager, 'QA_VALIDATION');
30
+ artifacts.push(...stored);
31
+ if (!pipeline.gateChecks['QA_VALIDATION']) {
32
+ pipeline.gateChecks['QA_VALIDATION'] = [];
33
+ }
34
+ pipeline.gateChecks['QA_VALIDATION'].push(installResult);
35
+ if (installResult.status === 'fail') {
36
+ pipeline.artifacts.push(...artifacts);
37
+ return failureResult('QA_VALIDATION', 'Dependency installation failed', installResult.stderr_summary ?? '');
38
+ }
39
+ writeInstallMarker(projectDir, snapshot);
40
+ }
41
+ }
42
+ // 3. Run test command
18
43
  if (commands.test) {
19
44
  const testResult = await runCheck('test', commands.test, projectDir);
20
45
  const stored = storeCheckResults([testResult], artifactManager, 'QA_VALIDATION');
@@ -24,8 +49,16 @@ export async function runQaValidation(context) {
24
49
  pipeline.gateChecks['QA_VALIDATION'] = [];
25
50
  }
26
51
  pipeline.gateChecks['QA_VALIDATION'].push(testResult);
52
+ // Invalidate install marker on missing-module errors
53
+ if (testResult.status === 'fail' && testResult.stderr_summary) {
54
+ const missingModule = /Cannot find module|ModuleNotFoundError|Failed to resolve import/
55
+ .test(testResult.stderr_summary);
56
+ if (missingModule) {
57
+ invalidateInstallMarker(projectDir);
58
+ }
59
+ }
27
60
  }
28
- // 3. Create QA validation summary artifact
61
+ // 4. Create QA validation summary artifact
29
62
  const qaReport = [
30
63
  '# QA Validation Report',
31
64
  '',
@@ -1 +1 @@
1
- {"version":3,"file":"qa-validation.js","sourceRoot":"","sources":["../../../src/pipeline/phases/qa-validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAqB;IACzD,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,SAAS,GAAG,EAAE,CAAC;IAErB,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC3C,QAAQ,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QAErC,sBAAsB;QACtB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACrE,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,UAAU,CAAC,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;YACjF,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAE1B,gCAAgC;YAChC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC1C,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC;YAC5C,CAAC;YACD,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxD,CAAC;QAED,2CAA2C;QAC3C,MAAM,QAAQ,GAAG;YACf,wBAAwB;YACxB,EAAE;YACF,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;YAC5C,qBAAqB,QAAQ,CAAC,IAAI,IAAI,MAAM,EAAE;YAC9C,oBAAoB,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,MAAM,EAAE;YACjF,EAAE;YACF,YAAY;YACZ,EAAE;YACF,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,KAAK,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,WAAW,KAAK,CACtD,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe;SAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,OAAO,GAAG,eAAe,CAAC,kBAAkB,CAChD,eAAe,EACf,QAAQ,EACR,eAAe,CAChB,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAExB,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QACtC,OAAO,aAAa,CAAC,eAAe,EAAE,SAAS,EAAE,wBAAwB,CAAC,CAAC;IAC7E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,OAAO,aAAa,CAAC,eAAe,EAAE,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"qa-validation.js","sourceRoot":"","sources":["../../../src/pipeline/phases/qa-validation.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * RECOVERY_LOOP phase — self-heal using RCA, not guesswork.
3
3
  * Routes via requires_phase_rewind_to (P1-3). Max 5 iterations.
4
+ * v2.1: Extracts reviewer feedback from consensus failures and
5
+ * builds structured revision directive for sessionGuidance.
4
6
  */
5
7
  import type { PhaseContext, PhaseResult } from './phase-context.js';
6
8
  export declare function runRecoveryLoop(context: PhaseContext): Promise<PhaseResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"recovery-loop.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/recovery-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIpE,wBAAsB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwFjF"}
1
+ {"version":3,"file":"recovery-loop.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/recovery-loop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIpE,wBAAsB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA6KjF"}
@@ -1,19 +1,38 @@
1
1
  /**
2
2
  * RECOVERY_LOOP phase — self-heal using RCA, not guesswork.
3
3
  * Routes via requires_phase_rewind_to (P1-3). Max 5 iterations.
4
+ * v2.1: Extracts reviewer feedback from consensus failures and
5
+ * builds structured revision directive for sessionGuidance.
4
6
  */
7
+ import { existsSync, unlinkSync } from 'node:fs';
8
+ import { join } from 'node:path';
5
9
  import { successResult, failureResult, triggerJournalist } from './phase-context.js';
6
10
  import { buildRCAPacket } from '../packets/rca-packet-builder.js';
7
11
  export async function runRecoveryLoop(context) {
8
- const { pipeline, artifactManager, skillLoader } = context;
12
+ const { pipeline, artifactManager, skillLoader, skillUsageRegistry } = context;
9
13
  const artifacts = [];
10
14
  try {
11
- // 1. Load debugger skill
12
- const debuggerSkill = skillLoader.loadSkill('DEBUGGER');
15
+ // 1. Load debugger skill with metadata
16
+ const { definition: debuggerSkill, meta: debuggerMeta } = skillLoader.loadSkillWithMeta('DEBUGGER');
13
17
  // 2. Gather failure evidence
14
18
  const failedPhase = pipeline.failedPhase;
15
19
  const failedGateResult = failedPhase ? pipeline.gateResults[failedPhase] : undefined;
16
20
  const failedChecks = failedPhase ? pipeline.gateChecks[failedPhase] ?? [] : [];
21
+ // 2a. Detect missing module errors in stderr — invalidate install marker
22
+ const combinedStderr = failedChecks
23
+ .filter((c) => c.status === 'fail')
24
+ .map((c) => c.stderr_summary ?? '')
25
+ .join('\n');
26
+ const missingModule = /Cannot find module|ModuleNotFoundError|Failed to resolve import/
27
+ .test(combinedStderr);
28
+ if (missingModule) {
29
+ try {
30
+ const markerPath = join(context.projectDir, '.popeye', 'install-marker.json');
31
+ if (existsSync(markerPath))
32
+ unlinkSync(markerPath);
33
+ }
34
+ catch { /* non-fatal */ }
35
+ }
17
36
  const failureEvidence = [
18
37
  `Failed phase: ${failedPhase ?? 'unknown'}`,
19
38
  failedGateResult
@@ -23,6 +42,47 @@ export async function runRecoveryLoop(context) {
23
42
  ? `Failed checks: ${failedChecks.filter((c) => c.status === 'fail').map((c) => `${c.check_type}: ${c.stderr_summary?.slice(0, 200) ?? 'no details'}`).join('; ')}`
24
43
  : 'No check failures',
25
44
  ].join('\n');
45
+ // 2b. For consensus failures, build revision directive from reviewer feedback
46
+ if (failedPhase?.startsWith('CONSENSUS_')) {
47
+ const directive = buildRevisionDirective(pipeline, failedPhase);
48
+ if (directive) {
49
+ const existing = pipeline.sessionGuidance ?? '';
50
+ const marker = '--- REVISION DIRECTIVE ---';
51
+ const base = existing.includes(marker)
52
+ ? existing.slice(0, existing.indexOf(marker)).trim()
53
+ : existing;
54
+ pipeline.sessionGuidance = [base, '', marker, directive.slice(0, 3000)].join('\n').trim();
55
+ }
56
+ }
57
+ // 2c. For QA/build failures, build a targeted fix directive from test stderr
58
+ // so the implementation phase knows exactly what to fix on rewind.
59
+ if (failedPhase === 'QA_VALIDATION' || failedPhase === 'PRODUCTION_GATE'
60
+ || failedPhase === 'IMPLEMENTATION') {
61
+ const failedCheckDetails = failedChecks
62
+ .filter((c) => c.status === 'fail')
63
+ .map((c) => [
64
+ `**${c.check_type}** (exit code ${c.exit_code}):`,
65
+ `Command: \`${c.command}\``,
66
+ c.stderr_summary ? c.stderr_summary.slice(0, 500) : 'No stderr captured',
67
+ ].join('\n'))
68
+ .join('\n\n');
69
+ if (failedCheckDetails) {
70
+ const existing = pipeline.sessionGuidance ?? '';
71
+ const marker = '--- QA FIX DIRECTIVE ---';
72
+ const base = existing.includes(marker)
73
+ ? existing.slice(0, existing.indexOf(marker)).trim()
74
+ : existing;
75
+ const directive = [
76
+ `Fix the following failures (recovery iteration ${pipeline.recoveryCount}):`,
77
+ '',
78
+ failedCheckDetails,
79
+ '',
80
+ 'Apply targeted fixes only. Do not rewrite code that already works.',
81
+ ].join('\n');
82
+ pipeline.sessionGuidance = [base, '', marker, directive.slice(0, 3000)]
83
+ .join('\n').trim();
84
+ }
85
+ }
26
86
  // 3. Generate RCA via Claude with Debugger skill
27
87
  const { executePrompt } = await import('../../adapters/claude.js');
28
88
  const guidance = pipeline.sessionGuidance;
@@ -44,6 +104,26 @@ export async function runRecoveryLoop(context) {
44
104
  ].join('\n');
45
105
  const rcaResult = await executePrompt(rcaPrompt);
46
106
  const rcaResponse = rcaResult.response;
107
+ // Record skill usage — debugger skill injected into RCA prompt
108
+ skillUsageRegistry.record('DEBUGGER', 'RECOVERY_LOOP', 'system_prompt', debuggerMeta.source, debuggerMeta.version);
109
+ // 3b. Build recovery micro-plan from RCA + stderr
110
+ const microPlan = buildRecoveryMicroPlan(rcaResponse, failedChecks, pipeline.recoveryCount);
111
+ // 3c. Store micro-plan as artifact for traceability
112
+ const microPlanEntry = artifactManager.createAndStoreText('recovery_fix_plan', microPlan.plan, 'RECOVERY_LOOP');
113
+ artifacts.push(microPlanEntry);
114
+ // 3d. Inject micro-plan into sessionGuidance (replaces any prior fix directive)
115
+ {
116
+ const existing = pipeline.sessionGuidance ?? '';
117
+ const markers = ['--- QA FIX DIRECTIVE ---', '--- RECOVERY FIX PLAN ---'];
118
+ let base = existing;
119
+ for (const m of markers) {
120
+ if (base.includes(m))
121
+ base = base.slice(0, base.indexOf(m)).trim();
122
+ }
123
+ pipeline.sessionGuidance = [
124
+ base, '', '--- RECOVERY FIX PLAN ---', microPlan.plan.slice(0, 3000),
125
+ ].join('\n').trim();
126
+ }
47
127
  // 4. Build RCA packet
48
128
  const rcaPacket = buildRCAPacket({
49
129
  incidentSummary: `Gate failure at ${failedPhase ?? 'unknown'} (recovery iteration ${pipeline.recoveryCount})`,
@@ -73,15 +153,12 @@ export async function runRecoveryLoop(context) {
73
153
  }
74
154
  /** Determine rewind target from RCA response */
75
155
  function determineRewindTarget(_rcaResponse, failedPhase) {
76
- // If the failure was in production gate or audit, rewind to implementation
77
156
  if (failedPhase === 'PRODUCTION_GATE' || failedPhase === 'AUDIT') {
78
157
  return 'IMPLEMENTATION';
79
158
  }
80
- // If in QA, rewind to implementation
81
159
  if (failedPhase === 'QA_VALIDATION') {
82
160
  return 'IMPLEMENTATION';
83
161
  }
84
- // For consensus failures, rewind to the phase being validated
85
162
  if (failedPhase === 'CONSENSUS_MASTER_PLAN')
86
163
  return 'INTAKE';
87
164
  if (failedPhase === 'CONSENSUS_ARCHITECTURE')
@@ -90,4 +167,121 @@ function determineRewindTarget(_rcaResponse, failedPhase) {
90
167
  return 'ROLE_PLANNING';
91
168
  return undefined;
92
169
  }
170
+ /**
171
+ * Extract reviewer feedback from the latest consensus artifact and
172
+ * build a structured revision directive for the planner.
173
+ *
174
+ * Uses Set<string> for dedup. Output is capped at 3000 chars by caller.
175
+ */
176
+ function buildRevisionDirective(pipeline, failedPhase) {
177
+ // Find the latest consensus artifact for this phase
178
+ const consensusArtifacts = pipeline.artifacts.filter((a) => a.type === 'consensus' && a.content);
179
+ if (consensusArtifacts.length === 0)
180
+ return null;
181
+ const latest = consensusArtifacts[consensusArtifacts.length - 1];
182
+ const packet = latest.content;
183
+ if (!packet?.reviewer_votes)
184
+ return null;
185
+ const blockers = new Set();
186
+ const required = new Set();
187
+ const suggestions = new Set();
188
+ for (const vote of packet.reviewer_votes) {
189
+ for (const issue of vote.blocking_issues) {
190
+ const trimmed = issue.trim();
191
+ if (trimmed)
192
+ blockers.add(trimmed);
193
+ }
194
+ for (const change of (vote.required_changes ?? [])) {
195
+ const trimmed = change.trim();
196
+ if (trimmed)
197
+ required.add(trimmed);
198
+ }
199
+ for (const suggestion of vote.suggestions) {
200
+ const trimmed = suggestion.trim();
201
+ if (trimmed)
202
+ suggestions.add(trimmed);
203
+ }
204
+ }
205
+ if (blockers.size === 0 && required.size === 0 && suggestions.size === 0)
206
+ return null;
207
+ const lines = [
208
+ `Revise the plan to address reviewer feedback from ${failedPhase}:`,
209
+ '',
210
+ ];
211
+ if (blockers.size > 0) {
212
+ lines.push('BLOCKING (must fix):');
213
+ for (const b of blockers)
214
+ lines.push(`- ${b}`);
215
+ lines.push('');
216
+ }
217
+ if (required.size > 0) {
218
+ lines.push('REQUIRED CHANGES:');
219
+ for (const r of required)
220
+ lines.push(`- ${r}`);
221
+ lines.push('');
222
+ }
223
+ if (suggestions.size > 0) {
224
+ lines.push('SUGGESTIONS:');
225
+ for (const s of suggestions)
226
+ lines.push(`- ${s}`);
227
+ lines.push('');
228
+ }
229
+ lines.push('Keep existing plan structure. Apply targeted revisions only.');
230
+ return lines.join('\n');
231
+ }
232
+ /**
233
+ * Build a structured micro-fix plan from RCA + test failures.
234
+ * Returns the plan text and a risk assessment for consensus gating.
235
+ *
236
+ * Heuristics:
237
+ * - Low risk (skip consensus): <=3 files, no schema/dep/config changes
238
+ * - Medium risk (consensus): schema, dependency, or build config changes
239
+ * - High risk (consensus): API changes, >5 files
240
+ */
241
+ function buildRecoveryMicroPlan(rcaResponse, failedChecks, recoveryCount) {
242
+ const stderrLines = failedChecks
243
+ .filter((c) => c.status === 'fail')
244
+ .map((c) => c.stderr_summary ?? '')
245
+ .join('\n');
246
+ // Combine RCA + stderr for signal extraction
247
+ const combined = rcaResponse + '\n' + stderrLines;
248
+ const combinedLower = combined.toLowerCase();
249
+ const touchesSchema = /schema|migration|prisma|drizzle|typeorm|knex/.test(combinedLower);
250
+ const touchesDeps = /package\.json|requirements\.txt|dependency|npm install|pip install/
251
+ .test(combinedLower);
252
+ const touchesConfig = /tsconfig\.json|vite\.config|jest\.config|vitest\.config|docker-compose|\.github\/workflows/
253
+ .test(combinedLower);
254
+ const touchesApi = /api route|endpoint|public api|breaking change/.test(combinedLower);
255
+ // Extract file paths from BOTH RCA and stderr
256
+ const mentionedFiles = combined.match(/[\w/.-]+\.(ts|tsx|js|jsx|py|sql|prisma)/gi) ?? [];
257
+ const uniqueFiles = [...new Set(mentionedFiles)];
258
+ let riskLevel = 'low';
259
+ if (touchesApi || uniqueFiles.length > 5)
260
+ riskLevel = 'high';
261
+ else if (touchesSchema || touchesDeps || touchesConfig)
262
+ riskLevel = 'medium';
263
+ // Only require consensus for medium+ risk on second+ attempt
264
+ const needsConsensus = riskLevel !== 'low' && recoveryCount >= 2;
265
+ const plan = [
266
+ `# Recovery Fix Plan (iteration ${recoveryCount})`,
267
+ '',
268
+ `**Risk level:** ${riskLevel}`,
269
+ `**Files likely affected:** ${uniqueFiles.length > 0 ? uniqueFiles.join(', ') : 'unknown'}`,
270
+ `**Consensus required:** ${needsConsensus ? 'yes' : 'no'}`,
271
+ '',
272
+ '## Root Cause Summary',
273
+ rcaResponse.slice(0, 800),
274
+ '',
275
+ '## Test Failures',
276
+ stderrLines.slice(0, 1000) || 'No stderr captured',
277
+ '',
278
+ '## Fix Checklist',
279
+ '- [ ] Address root cause identified above',
280
+ '- [ ] Fix failing test assertions',
281
+ '- [ ] Verify no regressions in passing tests',
282
+ touchesSchema ? '- [ ] Review schema/migration changes for correctness' : '',
283
+ touchesDeps ? '- [ ] Verify dependency changes are necessary and compatible' : '',
284
+ ].filter(Boolean).join('\n');
285
+ return { plan, needsConsensus, riskLevel };
286
+ }
93
287
  //# sourceMappingURL=recovery-loop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recovery-loop.js","sourceRoot":"","sources":["../../../src/pipeline/phases/recovery-loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recovery-loop.js","sourceRoot":"","sources":["../../../src/pipeline/phases/recovery-loop.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/review.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQpE,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsI3E"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/review.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQpE,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiL3E"}
@@ -5,11 +5,11 @@
5
5
  */
6
6
  import { successResult, failureResult } from './phase-context.js';
7
7
  import { generateRepoSnapshot, createSnapshotArtifact, diffSnapshots } from '../repo-snapshot.js';
8
- import { buildChangeRequest, formatChangeRequest, routeChangeRequest } from '../change-request.js';
8
+ import { buildChangeRequest, formatChangeRequest, routeChangeRequest, computeDriftKey, isDuplicateCR } from '../change-request.js';
9
9
  import { existsSync, readFileSync } from 'node:fs';
10
10
  import { join } from 'node:path';
11
11
  export async function runReview(context) {
12
- const { pipeline, artifactManager, projectDir } = context;
12
+ const { pipeline, artifactManager, skillLoader, skillUsageRegistry, projectDir } = context;
13
13
  const artifacts = [];
14
14
  const changeRequests = [];
15
15
  try {
@@ -18,9 +18,16 @@ export async function runReview(context) {
18
18
  const snapshotEntry = createSnapshotArtifact(currentSnapshot, artifactManager, 'REVIEW');
19
19
  artifacts.push(snapshotEntry);
20
20
  pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
21
- // 2. Find role-plan-approval snapshot for drift detection
22
- const rolePlanSnapshots = pipeline.artifacts.filter((a) => a.type === 'repo_snapshot' && a.phase === 'CONSENSUS_ROLE_PLANS');
23
- const baselineSnapshot = rolePlanSnapshots[rolePlanSnapshots.length - 1];
21
+ // 2. Find baseline snapshot for drift detection
22
+ // v2.4.9: Check baselineSnapshotOverride first (set after config CR resolved)
23
+ let baselineSnapshot = pipeline.baselineSnapshotOverride
24
+ ? pipeline.artifacts.find((a) => a.id === pipeline.baselineSnapshotOverride.artifact_id)
25
+ : undefined;
26
+ // Fallback to CONSENSUS_ROLE_PLANS snapshot
27
+ if (!baselineSnapshot) {
28
+ const rolePlanSnapshots = pipeline.artifacts.filter((a) => a.type === 'repo_snapshot' && a.phase === 'CONSENSUS_ROLE_PLANS');
29
+ baselineSnapshot = rolePlanSnapshots[rolePlanSnapshots.length - 1];
30
+ }
24
31
  let driftReport = 'No baseline snapshot found for drift detection.';
25
32
  let hasDrift = false;
26
33
  if (baselineSnapshot) {
@@ -41,31 +48,49 @@ export async function runReview(context) {
41
48
  diff.changed_configs.length > 0 ? `Changed configs: ${diff.changed_configs.join(', ')}` : '',
42
49
  ].filter(Boolean).join('\n');
43
50
  // v1.1: Create change requests for detected drift
51
+ // v2.4.9: Deduplicate — skip if an active CR with the same drift_key exists
44
52
  if (diff.changed_configs.length > 0) {
45
- const cr = buildChangeRequest({
46
- originPhase: 'REVIEW',
47
- requestedBy: 'REVIEWER',
48
- changeType: 'config',
49
- description: `Config files changed during implementation: ${diff.changed_configs.join(', ')}`,
50
- justification: 'Detected by snapshot diff during review phase',
51
- affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
52
- affectedPhases: ['IMPLEMENTATION', 'QA_VALIDATION'],
53
- riskLevel: diff.changed_configs.length > 3 ? 'high' : 'medium',
53
+ const configHashPairs = diff.changed_configs.map((cfgPath) => {
54
+ const before = baselineData.config_files?.find((f) => f.path === cfgPath)?.content_hash ?? 'unknown';
55
+ const after = currentSnapshot.config_files?.find((f) => f.path === cfgPath)?.content_hash ?? 'unknown';
56
+ return `${cfgPath}:${before}->${after}`;
54
57
  });
55
- changeRequests.push(cr);
58
+ const configDriftKey = computeDriftKey('config', baselineSnapshot.id, diff.changed_configs, configHashPairs);
59
+ if (!isDuplicateCR(pipeline.pendingChangeRequests, configDriftKey)) {
60
+ const cr = buildChangeRequest({
61
+ originPhase: 'REVIEW',
62
+ requestedBy: 'REVIEWER',
63
+ changeType: 'config',
64
+ description: `Config files changed during implementation: ${diff.changed_configs.join(', ')}`,
65
+ justification: 'Detected by snapshot diff during review phase',
66
+ affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
67
+ affectedPhases: ['IMPLEMENTATION', 'QA_VALIDATION'],
68
+ riskLevel: diff.changed_configs.length > 3 ? 'high' : 'medium',
69
+ driftKey: configDriftKey,
70
+ });
71
+ changeRequests.push(cr);
72
+ }
56
73
  }
57
- if (Math.abs(diff.lines_delta) > 1000) {
58
- const cr = buildChangeRequest({
59
- originPhase: 'REVIEW',
60
- requestedBy: 'REVIEWER',
61
- changeType: 'scope',
62
- description: `Significant scope drift detected: ${diff.lines_delta > 0 ? '+' : ''}${diff.lines_delta} lines`,
63
- justification: 'Large line delta suggests scope changes beyond approved plans',
64
- affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
65
- affectedPhases: ['CONSENSUS_MASTER_PLAN', 'IMPLEMENTATION'],
66
- riskLevel: 'high',
67
- });
68
- changeRequests.push(cr);
74
+ // v2.5.1: Only check scope drift on revision-over-revision passes.
75
+ // On first pass, baseline = CONSENSUS_ROLE_PLANS (pre-implementation),
76
+ // so large line deltas are expected from implementation — not scope drift.
77
+ const isRevisionComparison = !!pipeline.baselineSnapshotOverride;
78
+ if (isRevisionComparison && Math.abs(diff.lines_delta) > 1000) {
79
+ const scopeDriftKey = computeDriftKey('scope', baselineSnapshot.id, [`lines_delta:${diff.lines_delta}`], []);
80
+ if (!isDuplicateCR(pipeline.pendingChangeRequests, scopeDriftKey)) {
81
+ const cr = buildChangeRequest({
82
+ originPhase: 'REVIEW',
83
+ requestedBy: 'REVIEWER',
84
+ changeType: 'scope',
85
+ description: `Significant scope drift detected: ${diff.lines_delta > 0 ? '+' : ''}${diff.lines_delta} lines`,
86
+ justification: 'Large line delta suggests scope changes beyond approved plans',
87
+ affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
88
+ affectedPhases: ['CONSENSUS_MASTER_PLAN', 'IMPLEMENTATION'],
89
+ riskLevel: 'high',
90
+ driftKey: scopeDriftKey,
91
+ });
92
+ changeRequests.push(cr);
93
+ }
69
94
  }
70
95
  }
71
96
  else {
@@ -90,9 +115,13 @@ export async function runReview(context) {
90
115
  change_type: cr.change_type,
91
116
  target_phase: routeChangeRequest(cr),
92
117
  status: 'proposed',
118
+ drift_key: cr.drift_key,
93
119
  });
94
120
  }
95
- // 4. Create review decision artifact
121
+ // 3b. Load REVIEWER skill and record usage for skill-guided review
122
+ const { definition: reviewerSkill, meta: reviewerMeta } = skillLoader.loadSkillWithMeta('REVIEWER');
123
+ skillUsageRegistry.record('REVIEWER', 'REVIEW', 'review_prompt', reviewerMeta.source, reviewerMeta.version);
124
+ // 4. Create review decision artifact (skill-guided)
96
125
  const reviewDoc = [
97
126
  '# Review Decision',
98
127
  '',
@@ -107,6 +136,7 @@ export async function runReview(context) {
107
136
  changeRequests.length > 0 ? '## Change Requests\n' + changeRequests.map((cr) => `- ${cr.cr_id}: ${cr.description}`).join('\n') : '',
108
137
  '',
109
138
  '## Plan Alignment',
139
+ `Reviewed using ${reviewerSkill.role} skill (v${reviewerSkill.version}).`,
110
140
  'Implementation reviewed against approved role plans.',
111
141
  '',
112
142
  '## Decision',