@nathapp/nax 0.28.0 → 0.30.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 (385) hide show
  1. package/CHANGELOG.md +23 -2
  2. package/bin/nax.ts +2 -3
  3. package/dist/nax.js +72753 -0
  4. package/package.json +11 -3
  5. package/src/cli/analyze.ts +2 -7
  6. package/src/cli/config.ts +3 -1
  7. package/src/config/defaults.ts +1 -0
  8. package/src/config/schemas.ts +1 -0
  9. package/src/config/types.ts +1 -0
  10. package/src/context/builder.ts +10 -1
  11. package/src/execution/lifecycle/headless-formatter.ts +2 -4
  12. package/src/prompts/builder.ts +12 -69
  13. package/src/prompts/sections/isolation.ts +38 -8
  14. package/src/prompts/sections/role-task.ts +79 -17
  15. package/src/review/runner.ts +6 -1
  16. package/src/version.ts +2 -1
  17. package/.claude/rules/01-project-conventions.md +0 -34
  18. package/.claude/rules/02-test-architecture.md +0 -39
  19. package/.claude/rules/03-test-writing.md +0 -58
  20. package/.claude/rules/04-forbidden-patterns.md +0 -29
  21. package/.claude/settings.json +0 -15
  22. package/.githooks/pre-commit +0 -16
  23. package/.gitlab-ci.yml +0 -103
  24. package/.mcp.json +0 -8
  25. package/BRIEF.md +0 -140
  26. package/CLAUDE.md +0 -143
  27. package/US-007-IMPLEMENTATION.md +0 -139
  28. package/biome.json +0 -14
  29. package/bun.lock +0 -163
  30. package/bunfig.toml +0 -12
  31. package/docker-compose.test.yml +0 -15
  32. package/docs/20260216-fix-plan-context-review.md +0 -56
  33. package/docs/20260216-relentless-vs-ngent-comparison.md +0 -208
  34. package/docs/20260216-v02-plan.md +0 -136
  35. package/docs/20260216-v02-review.md +0 -685
  36. package/docs/20260217-dogfood-findings.md +0 -56
  37. package/docs/20260217-p2-plus-plan.md +0 -117
  38. package/docs/20260217-partial-fixes-plan.md +0 -62
  39. package/docs/20260217-plan-analyze-spec.md +0 -117
  40. package/docs/20260217-post-impl-review.md +0 -1137
  41. package/docs/20260217-quick-wins-plan.md +0 -66
  42. package/docs/20260217-split-runner-plan.md +0 -75
  43. package/docs/20260217-v03-impl-plan.md +0 -80
  44. package/docs/20260217-v03-post-impl-review.md +0 -589
  45. package/docs/20260217-v04-impl-plan.md +0 -86
  46. package/docs/20260217-v05-post-impl-review.md +0 -850
  47. package/docs/20260217-v06-post-impl-review.md +0 -817
  48. package/docs/20260218-adr003-port-plan.md +0 -151
  49. package/docs/20260218-review-adr003-verification.md +0 -175
  50. package/docs/20260219-fix-plan-bug16-19.md +0 -79
  51. package/docs/20260219-fix-plan-bug20-22.md +0 -114
  52. package/docs/20260219-plan-llm-routing.md +0 -116
  53. package/docs/20260219-review-bug20-22-fixes.md +0 -135
  54. package/docs/20260219-routing-baseline-keyword.md +0 -63
  55. package/docs/20260220-plan-structured-logging-p1.md +0 -80
  56. package/docs/20260220-plan-structured-logging-p2.md +0 -37
  57. package/docs/20260220-review-llm-routing.md +0 -180
  58. package/docs/20260220-review-post-fix-llm-routing.md +0 -70
  59. package/docs/20260221-fix-plan-relevantfiles-split.md +0 -101
  60. package/docs/20260221-fix-plan-routing-mode.md +0 -125
  61. package/docs/20260221-review-v0.9-implementation.md +0 -379
  62. package/docs/20260222-fix-plan-v091-routing-isolation.md +0 -197
  63. package/docs/20260223-fix-plan-prompt-audit.md +0 -62
  64. package/docs/20260224-nax-roadmap-phases.md +0 -189
  65. package/docs/20260225-phase2-llm-service-layer.md +0 -401
  66. package/docs/20260225-review-v0.10.1.md +0 -187
  67. package/docs/20260303-v010-implementation-plan.md +0 -165
  68. package/docs/20260304-review-nax.md +0 -492
  69. package/docs/CLAUDE.md.bak +0 -191
  70. package/docs/ROADMAP.md +0 -390
  71. package/docs/SPEC-rectification.md +0 -0
  72. package/docs/SPEC.md +0 -324
  73. package/docs/US-001-plugin-loading-verification.md +0 -152
  74. package/docs/adr/ADR-005-implementation-plan.md +0 -655
  75. package/docs/adr/ADR-005-pipeline-re-architecture.md +0 -464
  76. package/docs/architecture-analysis.md +0 -1076
  77. package/docs/bugs/BUG-21-escalation-null-attempts.md +0 -48
  78. package/docs/bugs-from-dogfood-run-c.md +0 -243
  79. package/docs/code-review-20260228.md +0 -612
  80. package/docs/code-review-v0.15.0.md +0 -629
  81. package/docs/hook-lifecycle-test-plan.md +0 -149
  82. package/docs/releases/v0.11.0-and-earlier.md +0 -20
  83. package/docs/releases/v0.12.0.md +0 -15
  84. package/docs/releases/v0.13.0.md +0 -14
  85. package/docs/releases/v0.14.0.md +0 -20
  86. package/docs/releases/v0.14.1.md +0 -36
  87. package/docs/releases/v0.14.2.md +0 -51
  88. package/docs/releases/v0.14.3.md +0 -174
  89. package/docs/releases/v0.14.4.md +0 -94
  90. package/docs/releases/v0.15.0.md +0 -502
  91. package/docs/releases/v0.15.1.md +0 -170
  92. package/docs/releases/v0.15.3.md +0 -193
  93. package/docs/specs/bug-039-orphan-processes.md +0 -131
  94. package/docs/specs/bug-040-review-rectification.md +0 -82
  95. package/docs/specs/bug-041-cross-story-test-isolation.md +0 -88
  96. package/docs/specs/bug-042-verifier-failure-capture.md +0 -117
  97. package/docs/specs/bun-pty-migration.md +0 -171
  98. package/docs/specs/central-run-registry.md +0 -116
  99. package/docs/specs/feat-010-smart-runner-git-history.md +0 -96
  100. package/docs/specs/feat-011-file-context-strategy.md +0 -73
  101. package/docs/specs/feat-012-tdd-writer-tier.md +0 -79
  102. package/docs/specs/feat-013-test-after-review.md +0 -89
  103. package/docs/specs/feat-014-heartbeat-observability.md +0 -127
  104. package/docs/specs/status-file-consolidation.md +0 -93
  105. package/docs/specs/status-file-v0.10.1.md +0 -812
  106. package/docs/specs/trigger-completion.md +0 -145
  107. package/docs/specs/verification-architecture-v2.md +0 -343
  108. package/docs/tdd/strategies.md +0 -97
  109. package/docs/v0.10-global-config.md +0 -206
  110. package/docs/v0.10-plugin-system.md +0 -415
  111. package/docs/v0.10-prompt-optimizer.md +0 -234
  112. package/docs/v0.3-spec.md +0 -244
  113. package/docs/v0.4-spec.md +0 -140
  114. package/docs/v0.5-spec.md +0 -237
  115. package/docs/v0.6-spec.md +0 -371
  116. package/docs/v0.7-spec.md +0 -177
  117. package/docs/v0.8-llm-routing.md +0 -206
  118. package/docs/v0.8-structured-logging.md +0 -132
  119. package/docs/v0.9.3-prompt-audit.md +0 -112
  120. package/examples/plugins/console-reporter/index.test.ts +0 -207
  121. package/examples/plugins/console-reporter/index.ts +0 -110
  122. package/memory/topic/feat-010-baseref.md +0 -28
  123. package/memory/topic/feat-013-test-after-deprecation.md +0 -22
  124. package/nax/config.json +0 -154
  125. package/nax/features/bug-039-medium/prd.json +0 -45
  126. package/nax/features/bugfix-v0171/prd.json +0 -52
  127. package/nax/features/central-run-registry/prd.json +0 -105
  128. package/nax/features/config-management/prd.json +0 -108
  129. package/nax/features/config-management/progress.txt +0 -5
  130. package/nax/features/diagnose/acceptance.test.ts +0 -414
  131. package/nax/features/diagnose/prd.json +0 -41
  132. package/nax/features/nax-compliance/prd.json +0 -52
  133. package/nax/features/nax-compliance/progress.txt +0 -1
  134. package/nax/features/orchestration-fixes/prd.json +0 -89
  135. package/nax/features/orchestration-fixes/progress.txt +0 -1
  136. package/nax/features/plugin-integration/US-007-VERIFICATION.md +0 -259
  137. package/nax/features/plugin-integration/prd.json +0 -208
  138. package/nax/features/plugin-integration/progress.txt +0 -5
  139. package/nax/features/post-rearch-bugfix/prd.json +0 -137
  140. package/nax/features/precheck/prd.json +0 -205
  141. package/nax/features/precheck/progress.txt +0 -15
  142. package/nax/features/prompt-builder/prd.json +0 -152
  143. package/nax/features/prompt-builder/progress.txt +0 -3
  144. package/nax/features/review-quality/prd.json +0 -55
  145. package/nax/features/routing-persistence/prd.json +0 -104
  146. package/nax/features/routing-persistence/progress.txt +0 -1
  147. package/nax/features/smart-test-runner/plan.md +0 -7
  148. package/nax/features/smart-test-runner/prd.json +0 -203
  149. package/nax/features/smart-test-runner/progress.txt +0 -13
  150. package/nax/features/smart-test-runner/spec.md +0 -7
  151. package/nax/features/smart-test-runner/tasks.md +0 -8
  152. package/nax/features/status-file-consolidation/prd.json +0 -106
  153. package/nax/features/structured-logging/prd.json +0 -199
  154. package/nax/features/trigger-completion/prd.json +0 -150
  155. package/nax/features/trigger-completion/progress.txt +0 -7
  156. package/nax/features/unlock/prd.json +0 -36
  157. package/nax/features/v0.18.3-execution-reliability/prd.json +0 -80
  158. package/nax/features/v0.18.3-execution-reliability/progress.txt +0 -3
  159. package/nax/features/v0.19.0-hardening/plan.md +0 -7
  160. package/nax/features/v0.19.0-hardening/prd.json +0 -84
  161. package/nax/features/v0.19.0-hardening/progress.txt +0 -7
  162. package/nax/features/v0.19.0-hardening/spec.md +0 -18
  163. package/nax/features/v0.19.0-hardening/tasks.md +0 -8
  164. package/nax/features/verify-v2/prd.json +0 -79
  165. package/nax/features/verify-v2/progress.txt +0 -3
  166. package/nax/status.json +0 -36
  167. package/src/prompts/templates/implementer.ts +0 -6
  168. package/src/prompts/templates/single-session.ts +0 -6
  169. package/src/prompts/templates/test-writer.ts +0 -6
  170. package/src/prompts/templates/verifier.ts +0 -6
  171. package/test/COVERAGE-GAPS.md +0 -333
  172. package/test/e2e/cm-003-default-view.test.ts +0 -195
  173. package/test/e2e/plan-analyze-run.test.ts +0 -902
  174. package/test/helpers/helpers.test.ts +0 -295
  175. package/test/helpers/timeout.ts +0 -42
  176. package/test/integration/US-002-TEST-SUMMARY.md +0 -107
  177. package/test/integration/US-003-TEST-SUMMARY.md +0 -149
  178. package/test/integration/US-004-TEST-SUMMARY.md +0 -106
  179. package/test/integration/US-005-TEST-SUMMARY.md +0 -138
  180. package/test/integration/US-007-TEST-SUMMARY.md +0 -100
  181. package/test/integration/cli/agent-validation.test.ts +0 -439
  182. package/test/integration/cli/cli-config-default-edge-cases.test.ts +0 -223
  183. package/test/integration/cli/cli-config-default-view.test.ts +0 -230
  184. package/test/integration/cli/cli-config-diff.test.ts +0 -461
  185. package/test/integration/cli/cli-config-prompts-explain.test.ts +0 -74
  186. package/test/integration/cli/cli-config.test.ts +0 -737
  187. package/test/integration/cli/cli-diagnose.test.ts +0 -595
  188. package/test/integration/cli/cli-logs.test.ts +0 -346
  189. package/test/integration/cli/cli-plugins.test.ts +0 -679
  190. package/test/integration/cli/cli-precheck.test.ts +0 -372
  191. package/test/integration/cli/cli-run-headless.test.ts +0 -174
  192. package/test/integration/cli/cli.test.ts +0 -76
  193. package/test/integration/cli/precheck-integration.test.ts +0 -476
  194. package/test/integration/cli/precheck-orchestrator.test.ts +0 -247
  195. package/test/integration/cli/precheck.test.ts +0 -806
  196. package/test/integration/config/config-loader.test.ts +0 -266
  197. package/test/integration/config/config.test.ts +0 -444
  198. package/test/integration/config/merger.test.ts +0 -466
  199. package/test/integration/config/paths.test.ts +0 -52
  200. package/test/integration/config/security-loader.test.ts +0 -83
  201. package/test/integration/context/context-integration.test.ts +0 -703
  202. package/test/integration/context/context-path-security.test.ts +0 -173
  203. package/test/integration/context/context-provider-injection.test.ts +0 -507
  204. package/test/integration/context/context-verification-integration.test.ts +0 -296
  205. package/test/integration/context/s5-greenfield-fallback.test.ts +0 -298
  206. package/test/integration/execution/execution-isolation.test.ts +0 -143
  207. package/test/integration/execution/execution.test.ts +0 -634
  208. package/test/integration/execution/feature-status-write.test.ts +0 -302
  209. package/test/integration/execution/parallel.test.ts +0 -251
  210. package/test/integration/execution/prd-pause.test.ts +0 -205
  211. package/test/integration/execution/prd-resolvers.test.ts +0 -186
  212. package/test/integration/execution/progress.test.ts +0 -34
  213. package/test/integration/execution/runner-batching.test.ts +0 -682
  214. package/test/integration/execution/runner-config-plugins.test.ts +0 -462
  215. package/test/integration/execution/runner-escalation.test.ts +0 -561
  216. package/test/integration/execution/runner-fixes.test.ts +0 -400
  217. package/test/integration/execution/runner-plugin-integration.test.ts +0 -544
  218. package/test/integration/execution/runner-queue-and-attempts.test.ts +0 -476
  219. package/test/integration/execution/status-file-integration.test.ts +0 -289
  220. package/test/integration/execution/status-file.test.ts +0 -380
  221. package/test/integration/execution/status-writer.test.ts +0 -447
  222. package/test/integration/execution/story-id-in-events.test.ts +0 -274
  223. package/test/integration/interaction/interaction-chain-pipeline.test.ts +0 -476
  224. package/test/integration/pipeline/hooks.test.ts +0 -363
  225. package/test/integration/pipeline/pipeline-acceptance.test.ts +0 -303
  226. package/test/integration/pipeline/pipeline-events.test.ts +0 -476
  227. package/test/integration/pipeline/pipeline.test.ts +0 -660
  228. package/test/integration/pipeline/reporter-lifecycle.test.ts +0 -862
  229. package/test/integration/pipeline/verify-stage.test.ts +0 -286
  230. package/test/integration/plan/analyze-integration.test.ts +0 -262
  231. package/test/integration/plan/analyze-scanner.test.ts +0 -132
  232. package/test/integration/plan/logger.test.ts +0 -461
  233. package/test/integration/plan/plan.test.ts +0 -157
  234. package/test/integration/plugins/config-integration.test.ts +0 -173
  235. package/test/integration/plugins/config-resolution.test.ts +0 -523
  236. package/test/integration/plugins/loader.test.ts +0 -644
  237. package/test/integration/plugins/plugins-registry.test.ts +0 -747
  238. package/test/integration/plugins/validator.test.ts +0 -564
  239. package/test/integration/prompts/pb-004-migration.test.ts +0 -523
  240. package/test/integration/review/review-config-commands.test.ts +0 -320
  241. package/test/integration/review/review-config-schema.test.ts +0 -117
  242. package/test/integration/review/review-plugin-integration.test.ts +0 -729
  243. package/test/integration/review/review.test.ts +0 -150
  244. package/test/integration/routing/plugin-routing-advanced.test.ts +0 -461
  245. package/test/integration/routing/plugin-routing-core.test.ts +0 -527
  246. package/test/integration/routing/routing-stage-bug-021.test.ts +0 -275
  247. package/test/integration/routing/routing-stage-greenfield.test.ts +0 -287
  248. package/test/integration/tdd/tdd-cleanup.test.ts +0 -246
  249. package/test/integration/tdd/tdd-orchestrator-core.test.ts +0 -565
  250. package/test/integration/tdd/tdd-orchestrator-failureCategory.test.ts +0 -355
  251. package/test/integration/tdd/tdd-orchestrator-fallback.test.ts +0 -311
  252. package/test/integration/tdd/tdd-orchestrator-lite.test.ts +0 -289
  253. package/test/integration/tdd/tdd-orchestrator-prompts.test.ts +0 -260
  254. package/test/integration/tdd/tdd-orchestrator-verdict.test.ts +0 -536
  255. package/test/integration/tmp/headless-test/test.jsonl +0 -30
  256. package/test/integration/verification/test-scanner.test.ts +0 -403
  257. package/test/integration/verification/verification-asset-check.test.ts +0 -143
  258. package/test/integration/worktree/manager.test.ts +0 -218
  259. package/test/integration/worktree/worktree-merge.test.ts +0 -341
  260. package/test/manual/logging-formatter-demo.ts +0 -158
  261. package/test/ui/tui-agent-panel.test.tsx +0 -99
  262. package/test/ui/tui-pty-integration.test.tsx +0 -146
  263. package/test/unit/acceptance.test.ts +0 -187
  264. package/test/unit/agent-stderr-capture.test.ts +0 -147
  265. package/test/unit/agents/claude.test.ts +0 -107
  266. package/test/unit/analyze-classifier.test.ts +0 -216
  267. package/test/unit/analyze.test.ts +0 -224
  268. package/test/unit/auto-detect.test.ts +0 -250
  269. package/test/unit/cli-status-project-level.test.ts +0 -283
  270. package/test/unit/cli-status.test.ts +0 -418
  271. package/test/unit/commands/common.test.ts +0 -321
  272. package/test/unit/commands/logs.test.ts +0 -458
  273. package/test/unit/commands/runs.test.ts +0 -303
  274. package/test/unit/commands/unlock.test.ts +0 -320
  275. package/test/unit/config/defaults.test.ts +0 -70
  276. package/test/unit/config/quality-commands-schema.test.ts +0 -72
  277. package/test/unit/config/regression-gate-schema.test.ts +0 -160
  278. package/test/unit/config/smart-runner-flag.test.ts +0 -250
  279. package/test/unit/constitution-generators.test.ts +0 -161
  280. package/test/unit/constitution.test.ts +0 -210
  281. package/test/unit/context/context-autodetect.test.ts +0 -297
  282. package/test/unit/context/context-build.test.ts +0 -575
  283. package/test/unit/context/context-coverage.test.ts +0 -236
  284. package/test/unit/context/context-error.test.ts +0 -93
  285. package/test/unit/context/context-estimate-tokens.test.ts +0 -201
  286. package/test/unit/context/context-format.test.ts +0 -302
  287. package/test/unit/context/context-isolation.test.ts +0 -267
  288. package/test/unit/context/context-sort.test.ts +0 -93
  289. package/test/unit/context/context-story.test.ts +0 -108
  290. package/test/unit/context/prior-failures.test.ts +0 -463
  291. package/test/unit/context.test.ts +0 -1726
  292. package/test/unit/cost.test.ts +0 -231
  293. package/test/unit/crash-recovery.test.ts +0 -309
  294. package/test/unit/escalation.test.ts +0 -127
  295. package/test/unit/execution/lifecycle/run-completion.test.ts +0 -240
  296. package/test/unit/execution/lifecycle/run-regression.test.ts +0 -420
  297. package/test/unit/execution/pid-registry.test.ts +0 -241
  298. package/test/unit/execution/sequential-executor.test.ts +0 -235
  299. package/test/unit/execution/sfc-004-dead-code-cleanup.test.ts +0 -89
  300. package/test/unit/execution/structured-failure.test.ts +0 -415
  301. package/test/unit/execution-logging-stderr.test.ts +0 -157
  302. package/test/unit/execution-stage.test.ts +0 -123
  303. package/test/unit/fix-generator.test.ts +0 -276
  304. package/test/unit/formatters.test.ts +0 -468
  305. package/test/unit/greenfield.test.ts +0 -180
  306. package/test/unit/hooks/shell-security.test.ts +0 -40
  307. package/test/unit/interaction/auto-plugin.test.ts +0 -162
  308. package/test/unit/interaction/human-review-trigger.test.ts +0 -165
  309. package/test/unit/interaction-network-failures.test.ts +0 -390
  310. package/test/unit/interaction-plugins.test.ts +0 -472
  311. package/test/unit/logging/formatter.test.ts +0 -456
  312. package/test/unit/merge.test.ts +0 -269
  313. package/test/unit/metrics/aggregator.test.ts +0 -164
  314. package/test/unit/metrics/tracker.test.ts +0 -186
  315. package/test/unit/metrics.test.ts +0 -276
  316. package/test/unit/optimizer/noop.optimizer.test.ts +0 -125
  317. package/test/unit/optimizer/rule-based.optimizer.test.ts +0 -358
  318. package/test/unit/pipeline/event-bus.test.ts +0 -105
  319. package/test/unit/pipeline/routing-partial-override.test.ts +0 -121
  320. package/test/unit/pipeline/runner-retry.test.ts +0 -89
  321. package/test/unit/pipeline/stages/autofix.test.ts +0 -97
  322. package/test/unit/pipeline/stages/completion-review-gate.test.ts +0 -218
  323. package/test/unit/pipeline/stages/execution-ambiguity.test.ts +0 -311
  324. package/test/unit/pipeline/stages/execution-merge-conflict.test.ts +0 -218
  325. package/test/unit/pipeline/stages/rectify.test.ts +0 -101
  326. package/test/unit/pipeline/stages/regression-stage.test.ts +0 -69
  327. package/test/unit/pipeline/stages/review.test.ts +0 -201
  328. package/test/unit/pipeline/stages/routing-idempotence.test.ts +0 -139
  329. package/test/unit/pipeline/stages/routing-initial-complexity.test.ts +0 -321
  330. package/test/unit/pipeline/stages/routing-persistence.test.ts +0 -380
  331. package/test/unit/pipeline/stages/verify.test.ts +0 -267
  332. package/test/unit/pipeline/subscribers/events-writer.test.ts +0 -227
  333. package/test/unit/pipeline/subscribers/hooks.test.ts +0 -84
  334. package/test/unit/pipeline/subscribers/interaction.test.ts +0 -313
  335. package/test/unit/pipeline/subscribers/registry.test.ts +0 -149
  336. package/test/unit/pipeline/subscribers/reporters.test.ts +0 -90
  337. package/test/unit/pipeline/verify-smart-runner.test.ts +0 -345
  338. package/test/unit/prd-auto-default.test.ts +0 -291
  339. package/test/unit/prd-failure-category.test.ts +0 -177
  340. package/test/unit/prd-get-next-story.test.ts +0 -215
  341. package/test/unit/precheck/checks-warnings.test.ts +0 -114
  342. package/test/unit/precheck-checks.test.ts +0 -841
  343. package/test/unit/precheck-story-size-gate.test.ts +0 -288
  344. package/test/unit/precheck-types.test.ts +0 -143
  345. package/test/unit/prompts/builder.test.ts +0 -258
  346. package/test/unit/prompts/loader.test.ts +0 -355
  347. package/test/unit/prompts/sections/conventions.test.ts +0 -30
  348. package/test/unit/prompts/sections/isolation.test.ts +0 -35
  349. package/test/unit/prompts/sections/role-task.test.ts +0 -40
  350. package/test/unit/prompts/sections/sections.test.ts +0 -238
  351. package/test/unit/prompts/sections/story.test.ts +0 -45
  352. package/test/unit/prompts/sections/verdict.test.ts +0 -58
  353. package/test/unit/prompts.test.ts +0 -476
  354. package/test/unit/queue.test.ts +0 -237
  355. package/test/unit/rectification.test.ts +0 -285
  356. package/test/unit/registry.test.ts +0 -288
  357. package/test/unit/review/runner.test.ts +0 -117
  358. package/test/unit/routing/content-hash.test.ts +0 -99
  359. package/test/unit/routing/routing-stability.test.ts +0 -208
  360. package/test/unit/routing/strategies/llm.test.ts +0 -306
  361. package/test/unit/routing-advanced.test.ts +0 -313
  362. package/test/unit/routing-core.test.ts +0 -341
  363. package/test/unit/routing-strategies.test.ts +0 -440
  364. package/test/unit/storyid-events.test.ts +0 -213
  365. package/test/unit/tdd-verdict.test.ts +0 -492
  366. package/test/unit/test-output-parser.test.ts +0 -377
  367. package/test/unit/ui/tui-controls.test.ts +0 -335
  368. package/test/unit/ui/tui-cost-and-pty.test.ts +0 -190
  369. package/test/unit/ui/tui-layout.test.ts +0 -379
  370. package/test/unit/ui/tui-stories.test.ts +0 -333
  371. package/test/unit/unit-isolation.test.ts +0 -135
  372. package/test/unit/utils/git.test.ts +0 -50
  373. package/test/unit/utils/path-security.test.ts +0 -47
  374. package/test/unit/utils-helpers.test.ts +0 -318
  375. package/test/unit/verdict.test.ts +0 -325
  376. package/test/unit/verification/orchestrator-types.test.ts +0 -54
  377. package/test/unit/verification/orchestrator.test.ts +0 -66
  378. package/test/unit/verification/smart-runner-config.test.ts +0 -163
  379. package/test/unit/verification/smart-runner-discovery.test.ts +0 -354
  380. package/test/unit/verification/smart-runner.test.ts +0 -262
  381. package/test/unit/verification/strategies/acceptance.test.ts +0 -33
  382. package/test/unit/verification/strategies/regression.test.ts +0 -87
  383. package/test/unit/verification/strategies/scoped.test.ts +0 -100
  384. package/test/unit/worktree-manager.test.ts +0 -159
  385. package/tsconfig.json +0 -27
@@ -1,295 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
- import { mkdirSync, rmSync } from "node:fs";
3
- import path from "node:path";
4
- import { spawn } from "bun";
5
- import { acquireLock, formatProgress, releaseLock } from "../../src/execution/helpers";
6
- import type { StoryCounts } from "../../src/execution/helpers";
7
-
8
- describe("formatProgress", () => {
9
- test("formats progress with all stories pending", () => {
10
- const counts: StoryCounts = {
11
- total: 12,
12
- passed: 0,
13
- failed: 0,
14
- pending: 12,
15
- };
16
-
17
- const progress = formatProgress(counts, 0, 5.0, 0, 12);
18
-
19
- expect(progress).toContain("0/12 stories");
20
- expect(progress).toContain("0 passed");
21
- expect(progress).toContain("0 failed");
22
- expect(progress).toContain("$0.00/$5.00");
23
- expect(progress).toContain("calculating...");
24
- });
25
-
26
- test("formats progress with some stories completed", () => {
27
- const counts: StoryCounts = {
28
- total: 12,
29
- passed: 5,
30
- failed: 1,
31
- pending: 6,
32
- };
33
-
34
- // 10 minutes elapsed (600000 ms), 6 stories completed
35
- // avg = 600000 / 6 = 100000 ms per story
36
- // remaining = 6 stories * 100000 = 600000 ms = 10 minutes
37
- const progress = formatProgress(counts, 0.45, 5.0, 600000, 12);
38
-
39
- expect(progress).toContain("6/12 stories");
40
- expect(progress).toContain("5 passed");
41
- expect(progress).toContain("1 failed");
42
- expect(progress).toContain("$0.45/$5.00");
43
- expect(progress).toContain("~10 min remaining");
44
- });
45
-
46
- test("formats progress when all stories are complete", () => {
47
- const counts: StoryCounts = {
48
- total: 12,
49
- passed: 10,
50
- failed: 2,
51
- pending: 0,
52
- };
53
-
54
- const progress = formatProgress(counts, 1.23, 5.0, 1200000, 12);
55
-
56
- expect(progress).toContain("12/12 stories");
57
- expect(progress).toContain("10 passed");
58
- expect(progress).toContain("2 failed");
59
- expect(progress).toContain("$1.23/$5.00");
60
- expect(progress).toContain("complete");
61
- });
62
-
63
- test("calculates ETA correctly for fast stories", () => {
64
- const counts: StoryCounts = {
65
- total: 20,
66
- passed: 10,
67
- failed: 0,
68
- pending: 10,
69
- };
70
-
71
- // 2 minutes elapsed (120000 ms) for 10 stories
72
- // avg = 120000 / 10 = 12000 ms per story
73
- // remaining = 10 stories * 12000 = 120000 ms = 2 minutes
74
- const progress = formatProgress(counts, 0.5, 10.0, 120000, 20);
75
-
76
- expect(progress).toContain("~2 min remaining");
77
- });
78
-
79
- test("rounds ETA to nearest minute", () => {
80
- const counts: StoryCounts = {
81
- total: 10,
82
- passed: 3,
83
- failed: 0,
84
- pending: 7,
85
- };
86
-
87
- // 8.5 minutes elapsed (510000 ms) for 3 stories
88
- // avg = 510000 / 3 = 170000 ms per story
89
- // remaining = 7 stories * 170000 = 1190000 ms ≈ 19.8 minutes → rounds to 20
90
- const progress = formatProgress(counts, 0.3, 5.0, 510000, 10);
91
-
92
- expect(progress).toContain("~20 min remaining");
93
- });
94
-
95
- test("includes cost information with proper formatting", () => {
96
- const counts: StoryCounts = {
97
- total: 5,
98
- passed: 2,
99
- failed: 0,
100
- pending: 3,
101
- };
102
-
103
- const progress = formatProgress(counts, 1.2345, 10.0, 300000, 5);
104
-
105
- // Should round cost to 2 decimal places
106
- expect(progress).toContain("$1.23/$10.00");
107
- });
108
-
109
- test("handles zero elapsed time gracefully", () => {
110
- const counts: StoryCounts = {
111
- total: 10,
112
- passed: 0,
113
- failed: 0,
114
- pending: 10,
115
- };
116
-
117
- const progress = formatProgress(counts, 0, 5.0, 0, 10);
118
-
119
- expect(progress).toContain("calculating...");
120
- expect(progress).not.toContain("NaN");
121
- expect(progress).not.toContain("Infinity");
122
- });
123
-
124
- test("includes all required progress indicators", () => {
125
- const counts: StoryCounts = {
126
- total: 10,
127
- passed: 3,
128
- failed: 1,
129
- pending: 6,
130
- };
131
-
132
- const progress = formatProgress(counts, 0.5, 5.0, 300000, 10);
133
-
134
- expect(progress).toContain("Progress:");
135
- expect(progress).toContain("passed");
136
- expect(progress).toContain("failed");
137
- expect(progress).toContain("$");
138
- expect(progress).toContain("min remaining");
139
- });
140
- });
141
-
142
- describe("acquireLock and releaseLock", () => {
143
- const testDir = path.join(import.meta.dir, ".test-locks");
144
- const lockPath = path.join(testDir, "nax.lock");
145
-
146
- beforeEach(() => {
147
- // Create clean test directory
148
- rmSync(testDir, { recursive: true, force: true });
149
- mkdirSync(testDir, { recursive: true });
150
- });
151
-
152
- afterEach(() => {
153
- // Clean up test directory
154
- rmSync(testDir, { recursive: true, force: true });
155
- });
156
-
157
- test("acquires lock when no lock file exists", async () => {
158
- const acquired = await acquireLock(testDir);
159
- expect(acquired).toBe(true);
160
-
161
- // Verify lock file was created
162
- const lockFile = Bun.file(lockPath);
163
- expect(await lockFile.exists()).toBe(true);
164
-
165
- // Verify lock file contains current PID
166
- const lockContent = await lockFile.text();
167
- const lockData = JSON.parse(lockContent);
168
- expect(lockData.pid).toBe(process.pid);
169
- expect(typeof lockData.timestamp).toBe("number");
170
-
171
- await releaseLock(testDir);
172
- });
173
-
174
- test("fails to acquire lock when another process holds it", async () => {
175
- // First process acquires lock
176
- const acquired1 = await acquireLock(testDir);
177
- expect(acquired1).toBe(true);
178
-
179
- // Second process tries to acquire lock
180
- const acquired2 = await acquireLock(testDir);
181
- expect(acquired2).toBe(false);
182
-
183
- await releaseLock(testDir);
184
- });
185
-
186
- test("releases lock successfully", async () => {
187
- await acquireLock(testDir);
188
- await releaseLock(testDir);
189
-
190
- // Verify lock file was deleted
191
- const lockFile = Bun.file(lockPath);
192
- expect(await lockFile.exists()).toBe(false);
193
- });
194
-
195
- test("can re-acquire lock after release", async () => {
196
- const acquired1 = await acquireLock(testDir);
197
- expect(acquired1).toBe(true);
198
-
199
- await releaseLock(testDir);
200
-
201
- const acquired2 = await acquireLock(testDir);
202
- expect(acquired2).toBe(true);
203
-
204
- await releaseLock(testDir);
205
- });
206
-
207
- test("removes stale lock when process is dead", async () => {
208
- // Create a lock file with a fake PID that doesn't exist
209
- const stalePid = 999999; // Very unlikely to be a real process
210
- const staleLock = {
211
- pid: stalePid,
212
- timestamp: Date.now() - 60000, // 1 minute ago
213
- };
214
- await Bun.write(lockPath, JSON.stringify(staleLock));
215
-
216
- // Try to acquire lock - should detect stale lock and remove it
217
- const acquired = await acquireLock(testDir);
218
- expect(acquired).toBe(true);
219
-
220
- // Verify new lock file has current PID
221
- const lockFile = Bun.file(lockPath);
222
- const lockContent = await lockFile.text();
223
- const lockData = JSON.parse(lockContent);
224
- expect(lockData.pid).toBe(process.pid);
225
-
226
- await releaseLock(testDir);
227
- });
228
-
229
- test("detects stale lock from OOM-killed process", async () => {
230
- // Spawn a short-lived child process
231
- const proc = spawn({
232
- cmd: ["sleep", "0.1"],
233
- stdout: "pipe",
234
- stderr: "pipe",
235
- });
236
-
237
- // Get the child PID
238
- const childPid = proc.pid;
239
-
240
- // Wait for it to exit
241
- await proc.exited;
242
-
243
- // Create a lock file with the dead child's PID
244
- const staleLock = {
245
- pid: childPid,
246
- timestamp: Date.now() - 60000, // 1 minute ago
247
- };
248
- await Bun.write(lockPath, JSON.stringify(staleLock));
249
-
250
- // Now try to acquire lock - should detect child process is dead
251
- const acquired = await acquireLock(testDir);
252
- expect(acquired).toBe(true);
253
-
254
- // Verify new lock has current PID
255
- const lockFile = Bun.file(lockPath);
256
- const lockContent = await lockFile.text();
257
- const lockData = JSON.parse(lockContent);
258
- expect(lockData.pid).toBe(process.pid);
259
-
260
- await releaseLock(testDir);
261
- });
262
-
263
- test("does not remove lock when process is still alive", async () => {
264
- // Create lock with current process PID
265
- const validLock = {
266
- pid: process.pid,
267
- timestamp: Date.now() - 60000, // 1 minute ago
268
- };
269
- await Bun.write(lockPath, JSON.stringify(validLock));
270
-
271
- // Try to acquire lock - should NOT remove it since process is alive
272
- const acquired = await acquireLock(testDir);
273
- expect(acquired).toBe(false);
274
-
275
- // Verify lock still exists with same PID
276
- const lockFile = Bun.file(lockPath);
277
- const lockContent = await lockFile.text();
278
- const lockData = JSON.parse(lockContent);
279
- expect(lockData.pid).toBe(process.pid);
280
- });
281
-
282
- test("handles corrupted lock file gracefully", async () => {
283
- // Create invalid JSON lock file
284
- await Bun.write(lockPath, "not valid json");
285
-
286
- // Should treat corrupt lock as stale and acquire successfully
287
- const acquired = await acquireLock(testDir);
288
- expect(acquired).toBe(true);
289
- });
290
-
291
- test("handles release when lock file doesn't exist", async () => {
292
- // Should not throw when releasing non-existent lock
293
- await expect(releaseLock(testDir)).resolves.toBeUndefined();
294
- });
295
- });
@@ -1,42 +0,0 @@
1
- /**
2
- * Test Timeout Helpers
3
- *
4
- * Utilities to prevent tests from hanging indefinitely.
5
- */
6
-
7
- /**
8
- * Wraps a promise with a hard timeout.
9
- * If the promise doesn't resolve within the timeout, rejects with a timeout error.
10
- *
11
- * @param promise The promise to wrap
12
- * @param timeoutMs Timeout in milliseconds
13
- * @param operation Description of the operation (for error messages)
14
- * @returns The promise result if it completes in time
15
- * @throws TimeoutError if the timeout is exceeded
16
- */
17
- export async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, operation = "Operation"): Promise<T> {
18
- return Promise.race([
19
- promise,
20
- new Promise<T>((_, reject) =>
21
- setTimeout(() => reject(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs),
22
- ),
23
- ]);
24
- }
25
-
26
- /**
27
- * Wraps a function call with a hard timeout.
28
- * Useful for wrapping synchronous or async functions that might hang.
29
- *
30
- * @param fn The function to execute
31
- * @param timeoutMs Timeout in milliseconds
32
- * @param operation Description of the operation (for error messages)
33
- * @returns The function result if it completes in time
34
- * @throws TimeoutError if the timeout is exceeded
35
- */
36
- export async function executeWithTimeout<T>(
37
- fn: () => Promise<T> | T,
38
- timeoutMs: number,
39
- operation = "Operation",
40
- ): Promise<T> {
41
- return withTimeout(Promise.resolve(fn()), timeoutMs, operation);
42
- }
@@ -1,107 +0,0 @@
1
- # US-002 Test Summary: Context Provider Injection
2
-
3
- ## Overview
4
- Created comprehensive test suite for US-002 that verifies context providers inject external data into agent prompts with proper token budget management.
5
-
6
- ## Test File
7
- - **Location**: `test/integration/context-provider-injection.test.ts`
8
- - **Total Tests**: 20
9
- - **Passing**: 14 (features already implemented)
10
- - **Failing**: 6 (features not yet implemented)
11
-
12
- ## Test Coverage by Acceptance Criteria
13
-
14
- ### ✅ AC1: All registered context providers are called before agent execution
15
- **Status**: All tests passing (feature implemented)
16
- - ✓ Calls all registered context providers
17
- - ✓ Providers receive the current story
18
- - ✓ Works with no providers registered
19
-
20
- ### ✅ AC2: Provider content appended under markdown section with label
21
- **Status**: All tests passing (feature implemented)
22
- - ✓ Appends provider content under labeled markdown section
23
- - ✓ Multiple providers create separate labeled sections
24
- - ✓ Provider content appended to existing context markdown
25
-
26
- ### ❌ AC3: Total injected tokens respect token budget
27
- **Status**: 4 tests failing (feature NOT implemented correctly)
28
-
29
- **Issue**: Current implementation uses hardcoded `PLUGIN_CONTEXT_MAX_TOKENS = 20_000` instead of reading from `config.execution.contextProviderTokenBudget`
30
-
31
- Failing tests:
32
- - ✗ Respects default token budget of 2000 tokens when not configured
33
- - ✗ Respects custom token budget from config
34
- - ✗ Providers added in order until budget exhausted
35
- - ✗ Single provider exceeding budget is skipped
36
-
37
- ### ✅ AC4: Provider errors caught, logged, and skipped
38
- **Status**: All tests passing (feature implemented)
39
- - ✓ Continues when a provider throws error
40
- - ✓ Handles all providers failing gracefully
41
- - ✓ Error in one provider doesn't affect others
42
-
43
- ### ❌ AC5: Token budget configurable via execution.contextProviderTokenBudget
44
- **Status**: 2 tests failing (feature NOT implemented)
45
-
46
- **Issue**:
47
- 1. `ExecutionConfig` type doesn't include `contextProviderTokenBudget` field
48
- 2. `DEFAULT_CONFIG` doesn't set default value of 2000 tokens
49
- 3. Context stage uses hardcoded value instead of reading from config
50
-
51
- Failing tests:
52
- - ✗ Default config includes contextProviderTokenBudget with default of 2000
53
- - ✗ Different projects can have different token budgets
54
-
55
- ## Implementation Gaps
56
-
57
- ### 1. Config Schema Missing Field
58
- **File**: `src/config/schema.ts`
59
- - Add `contextProviderTokenBudget: number` to `ExecutionConfig` interface
60
- - Add validation in `ExecutionConfigSchema` (Zod)
61
- - Set default value of 2000 in `DEFAULT_CONFIG.execution`
62
-
63
- ### 2. Context Stage Uses Hardcoded Value
64
- **File**: `src/pipeline/stages/context.ts`
65
- - Line 32: `const PLUGIN_CONTEXT_MAX_TOKENS = 20_000;` (hardcoded)
66
- - Should read from: `ctx.config.execution.contextProviderTokenBudget`
67
- - Lines 62, 72: Replace `PLUGIN_CONTEXT_MAX_TOKENS` with config value
68
-
69
- ## Test Execution
70
-
71
- ```bash
72
- # Run US-002 tests only
73
- bun test ./test/integration/context-provider-injection.test.ts
74
-
75
- # Current results:
76
- # 14 pass, 6 fail, 46 expect() calls
77
- ```
78
-
79
- ## Next Steps for Implementer
80
-
81
- 1. **Update ExecutionConfig interface** (src/config/schema.ts):
82
- - Add `contextProviderTokenBudget: number` field
83
- - Add Zod validation: `z.number().int().min(100).max(100000).default(2000)`
84
- - Add to DEFAULT_CONFIG: `contextProviderTokenBudget: 2000`
85
-
86
- 2. **Update context stage** (src/pipeline/stages/context.ts):
87
- - Remove hardcoded `PLUGIN_CONTEXT_MAX_TOKENS` constant
88
- - Read budget from `ctx.config.execution.contextProviderTokenBudget`
89
- - Use configured value in budget checks (lines 62, 72)
90
-
91
- 3. **Verify all tests pass**:
92
- ```bash
93
- bun test ./test/integration/context-provider-injection.test.ts
94
- ```
95
-
96
- ## Coverage Notes
97
-
98
- The test suite covers:
99
- - ✓ Provider registration and invocation
100
- - ✓ Markdown formatting with labels
101
- - ✓ Error handling and soft failures
102
- - ✓ Token budget enforcement (with config)
103
- - ✓ Multi-provider orchestration
104
- - ✓ Integration with existing PRD context
105
- - ✓ Built context element tracking
106
-
107
- All edge cases are covered per acceptance criteria.
@@ -1,149 +0,0 @@
1
- # US-003 Test Summary: Review Plugins Run After Built-in Verification
2
-
3
- **Story ID:** US-003
4
- **Date:** 2026-02-27
5
- **Status:** ✅ PASSED
6
- **Test File:** `test/integration/review-plugin-integration.test.ts`
7
-
8
- ## Overview
9
-
10
- This test suite verifies that plugin reviewers are correctly integrated into the review pipeline stage, running after built-in checks and triggering appropriate retry/escalation on failure.
11
-
12
- ## Test Results
13
-
14
- **Total Tests:** 19
15
- **Passed:** 19
16
- **Failed:** 0
17
- **Success Rate:** 100%
18
-
19
- ## Acceptance Criteria Coverage
20
-
21
- ### ✅ AC1: Plugin reviewers run after built-in checks pass
22
-
23
- | Test | Status |
24
- |------|--------|
25
- | Plugin reviewers execute when built-in checks pass | ✅ PASS |
26
- | Plugin reviewers do not run if built-in checks fail | ✅ PASS |
27
- | No plugin reviewers registered - continues normally | ✅ PASS |
28
-
29
- **Verification:** Plugin reviewers only execute after built-in checks succeed, preventing unnecessary work when code quality gates fail.
30
-
31
- ### ✅ AC2: Each reviewer receives workdir and changed files
32
-
33
- | Test | Status |
34
- |------|--------|
35
- | Reviewer receives correct workdir | ✅ PASS |
36
- | Reviewer receives list of changed files | ✅ PASS |
37
- | Reviewer receives empty array when no files changed | ✅ PASS |
38
-
39
- **Verification:** Reviewers receive accurate context about the working directory and which files were modified, enabling targeted analysis.
40
-
41
- ### ✅ AC3: Reviewer failure triggers retry/escalation
42
-
43
- | Test | Status |
44
- |------|--------|
45
- | Failing reviewer returns fail action | ✅ PASS |
46
- | Reviewer failure includes plugin name in reason | ✅ PASS |
47
-
48
- **Verification:** When a plugin reviewer fails, the pipeline returns a `fail` action with the plugin name in the failure reason, triggering the same retry/escalation logic as built-in check failures.
49
-
50
- ### ✅ AC4: Reviewer output included in story result
51
-
52
- | Test | Status |
53
- |------|--------|
54
- | Passing reviewer output is captured | ✅ PASS |
55
- | Failing reviewer output is captured | ✅ PASS |
56
-
57
- **Verification:** All reviewer outputs (success and failure) are stored in `ctx.reviewResult.pluginReviewers`, providing debugging information and audit trail.
58
-
59
- ### ✅ AC5: Exceptions count as failures
60
-
61
- | Test | Status |
62
- |------|--------|
63
- | Reviewer throwing exception counts as failure | ✅ PASS |
64
- | Exception message captured in output | ✅ PASS |
65
- | Non-Error exception converted to string | ✅ PASS |
66
-
67
- **Verification:** When a reviewer throws an exception, it's treated as a failure with the error message captured for debugging. The pipeline correctly handles both Error objects and primitive throws.
68
-
69
- ### ✅ AC6: Multiple reviewers run sequentially with short-circuiting
70
-
71
- | Test | Status |
72
- |------|--------|
73
- | Multiple reviewers run in order when all pass | ✅ PASS |
74
- | First failure short-circuits remaining reviewers | ✅ PASS |
75
- | Exception short-circuits remaining reviewers | ✅ PASS |
76
-
77
- **Verification:** Reviewers execute sequentially in registration order. When one fails (or throws), subsequent reviewers are skipped, providing fail-fast behavior.
78
-
79
- ### ✅ Edge Cases
80
-
81
- | Test | Status |
82
- |------|--------|
83
- | No plugins context - continues normally | ✅ PASS |
84
- | Reviewer returns empty output | ✅ PASS |
85
- | Reviewer without exitCode works | ✅ PASS |
86
-
87
- **Verification:** The implementation handles edge cases gracefully: missing plugin context, empty output strings, and optional exitCode field.
88
-
89
- ## Implementation Verification
90
-
91
- ### Key Files Modified
92
-
93
- 1. **`src/pipeline/stages/review.ts`**
94
- - Lines 77-155: Plugin reviewer execution logic
95
- - Lines 35-53: `getChangedFiles()` helper function
96
- - Correctly integrates plugin reviewers after built-in checks
97
-
98
- 2. **`src/review/types.ts`**
99
- - Lines 26-38: `PluginReviewerResult` interface
100
- - Line 51: Extended `ReviewResult` with `pluginReviewers` field
101
-
102
- 3. **`test/integration/review-plugin-integration.test.ts`**
103
- - 722 lines of comprehensive test coverage
104
- - Mock plugins and reviewers for isolated testing
105
- - Git repository setup for realistic changed file detection
106
-
107
- ### Type Safety
108
-
109
- - ✅ All TypeScript types correctly defined
110
- - ✅ No type errors (`bun run typecheck` passes)
111
- - ✅ Proper type guards and assertions
112
-
113
- ### Error Handling
114
-
115
- - ✅ Exceptions caught and converted to failures
116
- - ✅ Error messages preserved for debugging
117
- - ✅ Non-Error throws handled correctly
118
- - ✅ Missing optional fields handled safely
119
-
120
- ### Integration Points
121
-
122
- - ✅ Integrates with `PluginRegistry.getReviewers()`
123
- - ✅ Uses existing pipeline context structure
124
- - ✅ Follows established patterns from built-in checks
125
- - ✅ Compatible with retry/escalation logic
126
-
127
- ## Performance Considerations
128
-
129
- - Reviewers run sequentially (not parallel) to prevent resource contention
130
- - Fail-fast behavior minimizes wasted computation
131
- - Changed files retrieved once and reused for all reviewers
132
- - No unnecessary git operations or file system scans
133
-
134
- ## Conclusion
135
-
136
- **US-003 is fully implemented and verified.** All acceptance criteria are met with comprehensive test coverage. The implementation follows the codebase patterns, handles edge cases gracefully, and integrates seamlessly with the existing plugin system architecture.
137
-
138
- ## Test Execution
139
-
140
- ```bash
141
- $ bun test test/integration/review-plugin-integration.test.ts
142
-
143
- 19 pass
144
- 0 fail
145
- 51 expect() calls
146
- Ran 19 tests across 1 file. [1.71s]
147
- ```
148
-
149
- **Final Status:** ✅ READY FOR PRODUCTION
@@ -1,106 +0,0 @@
1
- # US-004: Reporter plugins receive lifecycle events — Test Summary
2
-
3
- **Status:** ✅ PASSED
4
- **Date:** 2026-02-27
5
- **Commit:** 26181a1
6
-
7
- ## Overview
8
-
9
- This story implements reporter lifecycle events that fire at appropriate points in the runner loop. All reporter calls are fire-and-forget (errors logged, never block pipeline).
10
-
11
- ## Implementation Summary
12
-
13
- ### Changes Made
14
-
15
- 1. **Moved PRD initialization** (runner.ts:205)
16
- - Moved `prd` declaration before try block to make it accessible in finally block
17
- - Ensures `prd` is available for onRunEnd event even on failure/abort
18
-
19
- 2. **Consolidated onRunEnd calls** (runner.ts:1417-1439)
20
- - Moved onRunEnd reporter events to finally block
21
- - Removed duplicate calls from success paths (parallel and sequential)
22
- - Guarantees onRunEnd fires even when run fails or is aborted
23
-
24
- 3. **Added dry-run onStoryComplete events** (runner.ts:666-684)
25
- - Added missing onStoryComplete events for dry-run mode
26
- - Ensures reporters receive events consistently across all execution modes
27
-
28
- ### Key Design Decisions
29
-
30
- - **Finally block placement**: onRunEnd must fire even on exceptions, so it's placed in the finally block before teardown and lock release
31
- - **Error isolation**: Each reporter call is wrapped in try/catch to prevent one reporter's failure from affecting others
32
- - **Event ordering**: onRunEnd fires before plugin teardown to ensure reporters can still access plugin state
33
-
34
- ## Test Results
35
-
36
- All 9 tests in `test/integration/reporter-lifecycle.test.ts` pass:
37
-
38
- ### AC1: onRunStart fires once at run start ✅
39
- - Verified event contains: runId, feature, totalStories, startTime
40
- - Verified event fires exactly once per run
41
-
42
- ### AC2: onStoryComplete fires after each story ✅
43
- - Verified event contains: runId, storyId, status, durationMs, cost, tier, testStrategy
44
- - Verified event fires for each story execution (including dry-run)
45
- - Verified correct status values (completed, failed, skipped, paused)
46
-
47
- ### AC3: onRunEnd fires once at run end ✅
48
- - Verified event contains: runId, totalDurationMs, totalCost, storySummary
49
- - Verified storySummary contains: completed, failed, skipped, paused counts
50
- - Verified correct counts match PRD state
51
-
52
- ### AC4: Reporter errors never block execution ✅
53
- - Verified failing reporter doesn't abort run
54
- - Verified run completes successfully despite reporter errors
55
- - Verified errors are logged (not thrown)
56
-
57
- ### AC5: Multiple reporters all receive events ✅
58
- - Verified two reporters both receive onRunStart, onStoryComplete, onRunEnd
59
- - Verified second reporter receives events even if first reporter fails
60
- - Verified no short-circuiting on error (all reporters always execute)
61
-
62
- ### AC6: Events fire even when run fails or is aborted ✅
63
- - Verified onRunStart and onRunEnd fire when stories are pre-failed
64
- - Verified onRunEnd fires in finally block (even on exception)
65
- - Verified storySummary reflects actual failure state
66
-
67
- ## Additional Test Coverage
68
-
69
- - **onStoryComplete for different outcomes**: Verified events for completed, failed, skipped, paused stories
70
- - **Multiple stories**: Verified consistent runId across all events in same run
71
- - **Dry-run mode**: Verified reporters receive events in dry-run mode
72
-
73
- ## Verification Command
74
-
75
- ```bash
76
- bun test test/integration/reporter-lifecycle.test.ts
77
- ```
78
-
79
- **Result:** 9 pass, 0 fail, 48 expect() calls
80
-
81
- ## Integration with Existing Code
82
-
83
- - **US-001 (Plugin loading)**: Uses pluginRegistry.getReporters() to retrieve all loaded reporters
84
- - **US-002 (Context provider injection)**: No conflicts, reporters operate independently
85
- - **US-003 (Review plugins)**: No conflicts, different lifecycle hooks
86
-
87
- ## Notes
88
-
89
- - Reporter events are fire-and-forget by design
90
- - All reporter methods are optional (IReporter interface)
91
- - Reporter errors are logged at WARN level (not ERROR) since they're non-critical
92
- - onRunEnd always fires in finally block, even if try block throws
93
- - PRD must be accessible in finally block, so it's initialized before try
94
-
95
- ## Acceptance Criteria Status
96
-
97
- | AC | Description | Status |
98
- |----|-------------|--------|
99
- | 1 | onRunStart fires once at run start with runId, feature, totalStories, startTime | ✅ |
100
- | 2 | onStoryComplete fires after each story with storyId, status, durationMs, cost, tier, testStrategy | ✅ |
101
- | 3 | onRunEnd fires once at run end with runId, totalDurationMs, totalCost, storySummary counts | ✅ |
102
- | 4 | Reporter errors are caught and logged but never block execution | ✅ |
103
- | 5 | Multiple reporters all receive events (not short-circuited on error) | ✅ |
104
- | 6 | Events fire even when the run fails or is aborted (onRunEnd still fires) | ✅ |
105
-
106
- **Overall Status:** ✅ ALL ACCEPTANCE CRITERIA MET