@urateam/core 0.1.55 → 0.1.57

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 (332) hide show
  1. package/dist/__tests__/audit-immutability.test.js +8 -0
  2. package/dist/__tests__/audit-immutability.test.js.map +1 -1
  3. package/dist/__tests__/auth-check.test.js +130 -16
  4. package/dist/__tests__/auth-check.test.js.map +1 -1
  5. package/dist/__tests__/auth-monitor.test.js +210 -87
  6. package/dist/__tests__/auth-monitor.test.js.map +1 -1
  7. package/dist/__tests__/bec-238-repro.test.d.ts +2 -0
  8. package/dist/__tests__/bec-238-repro.test.d.ts.map +1 -0
  9. package/dist/__tests__/bec-238-repro.test.js +116 -0
  10. package/dist/__tests__/bec-238-repro.test.js.map +1 -0
  11. package/dist/__tests__/bec146-repro.test.d.ts +2 -0
  12. package/dist/__tests__/bec146-repro.test.d.ts.map +1 -0
  13. package/dist/__tests__/bec146-repro.test.js +153 -0
  14. package/dist/__tests__/bec146-repro.test.js.map +1 -0
  15. package/dist/__tests__/circuit-breaker-config.test.d.ts +2 -0
  16. package/dist/__tests__/circuit-breaker-config.test.d.ts.map +1 -0
  17. package/dist/__tests__/circuit-breaker-config.test.js +32 -0
  18. package/dist/__tests__/circuit-breaker-config.test.js.map +1 -0
  19. package/dist/__tests__/circuit-breaker-events.test.d.ts +2 -0
  20. package/dist/__tests__/circuit-breaker-events.test.d.ts.map +1 -0
  21. package/dist/__tests__/circuit-breaker-events.test.js +53 -0
  22. package/dist/__tests__/circuit-breaker-events.test.js.map +1 -0
  23. package/dist/__tests__/circuit-breaker-integration.test.d.ts +2 -0
  24. package/dist/__tests__/circuit-breaker-integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/circuit-breaker-integration.test.js +192 -0
  26. package/dist/__tests__/circuit-breaker-integration.test.js.map +1 -0
  27. package/dist/__tests__/circuit-breaker-probe.test.d.ts +2 -0
  28. package/dist/__tests__/circuit-breaker-probe.test.d.ts.map +1 -0
  29. package/dist/__tests__/circuit-breaker-probe.test.js +124 -0
  30. package/dist/__tests__/circuit-breaker-probe.test.js.map +1 -0
  31. package/dist/__tests__/circuit-breaker-recover.test.d.ts +2 -0
  32. package/dist/__tests__/circuit-breaker-recover.test.d.ts.map +1 -0
  33. package/dist/__tests__/circuit-breaker-recover.test.js +52 -0
  34. package/dist/__tests__/circuit-breaker-recover.test.js.map +1 -0
  35. package/dist/__tests__/circuit-breaker-sweep.test.d.ts +2 -0
  36. package/dist/__tests__/circuit-breaker-sweep.test.d.ts.map +1 -0
  37. package/dist/__tests__/circuit-breaker-sweep.test.js +118 -0
  38. package/dist/__tests__/circuit-breaker-sweep.test.js.map +1 -0
  39. package/dist/__tests__/db-migrations.test.js +7 -3
  40. package/dist/__tests__/db-migrations.test.js.map +1 -1
  41. package/dist/__tests__/decision-artifact-schema.test.d.ts +2 -0
  42. package/dist/__tests__/decision-artifact-schema.test.d.ts.map +1 -0
  43. package/dist/__tests__/decision-artifact-schema.test.js +45 -0
  44. package/dist/__tests__/decision-artifact-schema.test.js.map +1 -0
  45. package/dist/__tests__/decisions-parser.test.d.ts +2 -0
  46. package/dist/__tests__/decisions-parser.test.d.ts.map +1 -0
  47. package/dist/__tests__/decisions-parser.test.js +59 -0
  48. package/dist/__tests__/decisions-parser.test.js.map +1 -0
  49. package/dist/__tests__/decisions-store.test.d.ts +2 -0
  50. package/dist/__tests__/decisions-store.test.d.ts.map +1 -0
  51. package/dist/__tests__/decisions-store.test.js +68 -0
  52. package/dist/__tests__/decisions-store.test.js.map +1 -0
  53. package/dist/__tests__/decisions-table-migration.test.d.ts +2 -0
  54. package/dist/__tests__/decisions-table-migration.test.d.ts.map +1 -0
  55. package/dist/__tests__/decisions-table-migration.test.js +56 -0
  56. package/dist/__tests__/decisions-table-migration.test.js.map +1 -0
  57. package/dist/__tests__/execute-stage-session-opts.test.js +2 -1
  58. package/dist/__tests__/execute-stage-session-opts.test.js.map +1 -1
  59. package/dist/__tests__/executor-issue-id.test.js +2 -1
  60. package/dist/__tests__/executor-issue-id.test.js.map +1 -1
  61. package/dist/__tests__/extract-handoff-decisions.test.d.ts +2 -0
  62. package/dist/__tests__/extract-handoff-decisions.test.d.ts.map +1 -0
  63. package/dist/__tests__/extract-handoff-decisions.test.js +26 -0
  64. package/dist/__tests__/extract-handoff-decisions.test.js.map +1 -0
  65. package/dist/__tests__/force-push-agent-branches.test.js +38 -15
  66. package/dist/__tests__/force-push-agent-branches.test.js.map +1 -1
  67. package/dist/__tests__/github-webhook.test.js +117 -0
  68. package/dist/__tests__/github-webhook.test.js.map +1 -1
  69. package/dist/__tests__/implement-template-decisions.test.d.ts +2 -0
  70. package/dist/__tests__/implement-template-decisions.test.d.ts.map +1 -0
  71. package/dist/__tests__/implement-template-decisions.test.js +41 -0
  72. package/dist/__tests__/implement-template-decisions.test.js.map +1 -0
  73. package/dist/__tests__/migrator.test.js +137 -39
  74. package/dist/__tests__/migrator.test.js.map +1 -1
  75. package/dist/__tests__/pipeline-runner.test.js +118 -0
  76. package/dist/__tests__/pipeline-runner.test.js.map +1 -1
  77. package/dist/__tests__/pm-audit-retention-step.test.js +3 -0
  78. package/dist/__tests__/pm-audit-retention-step.test.js.map +1 -1
  79. package/dist/__tests__/pm-budget-alerts.test.d.ts +14 -0
  80. package/dist/__tests__/pm-budget-alerts.test.d.ts.map +1 -1
  81. package/dist/__tests__/pm-budget-alerts.test.js +90 -18
  82. package/dist/__tests__/pm-budget-alerts.test.js.map +1 -1
  83. package/dist/__tests__/pm-budget-refused-event.test.js +2 -0
  84. package/dist/__tests__/pm-budget-refused-event.test.js.map +1 -1
  85. package/dist/__tests__/pm-budget-utc-boundary.test.d.ts +2 -0
  86. package/dist/__tests__/pm-budget-utc-boundary.test.d.ts.map +1 -0
  87. package/dist/__tests__/pm-budget-utc-boundary.test.js +128 -0
  88. package/dist/__tests__/pm-budget-utc-boundary.test.js.map +1 -0
  89. package/dist/__tests__/pm-conflict.test.js +145 -5
  90. package/dist/__tests__/pm-conflict.test.js.map +1 -1
  91. package/dist/__tests__/pm-cost-rollup-step.test.js +2 -0
  92. package/dist/__tests__/pm-cost-rollup-step.test.js.map +1 -1
  93. package/dist/__tests__/pm-promote.test.js +111 -0
  94. package/dist/__tests__/pm-promote.test.js.map +1 -1
  95. package/dist/__tests__/pm-scheduler.test.js +1 -0
  96. package/dist/__tests__/pm-scheduler.test.js.map +1 -1
  97. package/dist/__tests__/pm-sso-prune-step.test.js +2 -0
  98. package/dist/__tests__/pm-sso-prune-step.test.js.map +1 -1
  99. package/dist/__tests__/preflight-claude-auth.test.js +3 -2
  100. package/dist/__tests__/preflight-claude-auth.test.js.map +1 -1
  101. package/dist/__tests__/ralph-review-fix-regression.test.js +1 -0
  102. package/dist/__tests__/ralph-review-fix-regression.test.js.map +1 -1
  103. package/dist/__tests__/ralph.test.js +1 -0
  104. package/dist/__tests__/ralph.test.js.map +1 -1
  105. package/dist/__tests__/release-manager-qarun-query.test.d.ts +2 -0
  106. package/dist/__tests__/release-manager-qarun-query.test.d.ts.map +1 -0
  107. package/dist/__tests__/release-manager-qarun-query.test.js +233 -0
  108. package/dist/__tests__/release-manager-qarun-query.test.js.map +1 -0
  109. package/dist/__tests__/release-manager-scheduler.test.js +62 -0
  110. package/dist/__tests__/release-manager-scheduler.test.js.map +1 -1
  111. package/dist/__tests__/release-manager-slack-handler.test.js +66 -0
  112. package/dist/__tests__/release-manager-slack-handler.test.js.map +1 -1
  113. package/dist/__tests__/reproduce-bec113-pagination-warning.test.js +1 -0
  114. package/dist/__tests__/reproduce-bec113-pagination-warning.test.js.map +1 -1
  115. package/dist/__tests__/reproduce-bec62.test.js +1 -0
  116. package/dist/__tests__/reproduce-bec62.test.js.map +1 -1
  117. package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js +2 -0
  118. package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js.map +1 -1
  119. package/dist/__tests__/resolve-claude-auth.test.js +10 -8
  120. package/dist/__tests__/resolve-claude-auth.test.js.map +1 -1
  121. package/dist/__tests__/session-lazy-creation.test.js +2 -1
  122. package/dist/__tests__/session-lazy-creation.test.js.map +1 -1
  123. package/dist/__tests__/session-resolver.test.d.ts +13 -0
  124. package/dist/__tests__/session-resolver.test.d.ts.map +1 -0
  125. package/dist/__tests__/session-resolver.test.js +152 -0
  126. package/dist/__tests__/session-resolver.test.js.map +1 -0
  127. package/dist/__tests__/session-resume-fallback.test.js +2 -1
  128. package/dist/__tests__/session-resume-fallback.test.js.map +1 -1
  129. package/dist/__tests__/stage-models.test.js +3 -2
  130. package/dist/__tests__/stage-models.test.js.map +1 -1
  131. package/dist/__tests__/start-todo.test.js +29 -0
  132. package/dist/__tests__/start-todo.test.js.map +1 -1
  133. package/dist/__tests__/surgical-review-fix-prompt.test.d.ts +2 -0
  134. package/dist/__tests__/surgical-review-fix-prompt.test.d.ts.map +1 -0
  135. package/dist/__tests__/surgical-review-fix-prompt.test.js +71 -0
  136. package/dist/__tests__/surgical-review-fix-prompt.test.js.map +1 -0
  137. package/dist/__tests__/surgical-review-fix-runner.test.d.ts +2 -0
  138. package/dist/__tests__/surgical-review-fix-runner.test.d.ts.map +1 -0
  139. package/dist/__tests__/surgical-review-fix-runner.test.js +171 -0
  140. package/dist/__tests__/surgical-review-fix-runner.test.js.map +1 -0
  141. package/dist/__tests__/triage-preserve-acs.test.d.ts +2 -0
  142. package/dist/__tests__/triage-preserve-acs.test.d.ts.map +1 -0
  143. package/dist/__tests__/triage-preserve-acs.test.js +240 -0
  144. package/dist/__tests__/triage-preserve-acs.test.js.map +1 -0
  145. package/dist/__tests__/validate-run-mode.test.js +1 -0
  146. package/dist/__tests__/validate-run-mode.test.js.map +1 -1
  147. package/dist/__tests__/validate.test.js +1 -0
  148. package/dist/__tests__/validate.test.js.map +1 -1
  149. package/dist/audit/auth-error-messages.d.ts +6 -0
  150. package/dist/audit/auth-error-messages.d.ts.map +1 -0
  151. package/dist/audit/auth-error-messages.js +18 -0
  152. package/dist/audit/auth-error-messages.js.map +1 -0
  153. package/dist/audit/events.d.ts +51 -4
  154. package/dist/audit/events.d.ts.map +1 -1
  155. package/dist/audit/events.js +78 -5
  156. package/dist/audit/events.js.map +1 -1
  157. package/dist/audit/index.d.ts +1 -0
  158. package/dist/audit/index.d.ts.map +1 -1
  159. package/dist/audit/index.js +1 -0
  160. package/dist/audit/index.js.map +1 -1
  161. package/dist/db/client.d.ts.map +1 -1
  162. package/dist/db/client.js +20 -0
  163. package/dist/db/client.js.map +1 -1
  164. package/dist/db/decisions-store.d.ts +25 -0
  165. package/dist/db/decisions-store.d.ts.map +1 -0
  166. package/dist/db/decisions-store.js +56 -0
  167. package/dist/db/decisions-store.js.map +1 -0
  168. package/dist/db/index.d.ts +2 -2
  169. package/dist/db/index.d.ts.map +1 -1
  170. package/dist/db/index.js +2 -2
  171. package/dist/db/index.js.map +1 -1
  172. package/dist/db/migrations/postgres/008_sso.sql +9 -20
  173. package/dist/db/migrations/postgres/009_review_model_runs.sql +9 -18
  174. package/dist/db/migrations/postgres/009_sso.sql +20 -0
  175. package/dist/db/migrations/postgres/010_release_manager.sql +9 -38
  176. package/dist/db/migrations/postgres/010_review_model_runs.sql +18 -0
  177. package/dist/db/migrations/postgres/011_qa_run_columns.sql +9 -8
  178. package/dist/db/migrations/postgres/011_release_manager.sql +38 -0
  179. package/dist/db/migrations/postgres/012_qa_gap_issues.sql +9 -18
  180. package/dist/db/migrations/postgres/012_qa_run_columns.sql +8 -0
  181. package/dist/db/migrations/postgres/013_qa_gap_issues.sql +18 -0
  182. package/dist/db/migrations/postgres/013_stage_runs_cache_tokens.sql +11 -6
  183. package/dist/db/migrations/postgres/014_missing_indexes.sql +9 -28
  184. package/dist/db/migrations/postgres/014_stage_runs_cache_tokens.sql +6 -0
  185. package/dist/db/migrations/postgres/015_missing_indexes.sql +28 -0
  186. package/dist/db/migrations/postgres/015_triage_results.sql +9 -11
  187. package/dist/db/migrations/postgres/016_triage_results.sql +11 -0
  188. package/dist/db/migrations/sqlite/007_sso.sql +9 -20
  189. package/dist/db/migrations/sqlite/008_review_model_runs.sql +9 -18
  190. package/dist/db/migrations/sqlite/008_sso.sql +20 -0
  191. package/dist/db/migrations/sqlite/009_release_manager.sql +9 -43
  192. package/dist/db/migrations/sqlite/009_review_model_runs.sql +18 -0
  193. package/dist/db/migrations/sqlite/010_qa_run_columns.sql +9 -9
  194. package/dist/db/migrations/sqlite/010_release_manager.sql +43 -0
  195. package/dist/db/migrations/sqlite/011_qa_gap_issues.sql +9 -22
  196. package/dist/db/migrations/sqlite/011_qa_run_columns.sql +9 -0
  197. package/dist/db/migrations/sqlite/012_qa_gap_issues.sql +22 -0
  198. package/dist/db/migrations/sqlite/012_stage_runs_cache_tokens.sql +11 -6
  199. package/dist/db/migrations/sqlite/013_missing_indexes.sql +10 -28
  200. package/dist/db/migrations/sqlite/013_stage_runs_cache_tokens.sql +6 -0
  201. package/dist/db/migrations/sqlite/013_triage_results.sql +10 -11
  202. package/dist/db/migrations/sqlite/014_missing_indexes.sql +28 -0
  203. package/dist/db/migrations/sqlite/015_triage_results.sql +11 -0
  204. package/dist/db/migrator.d.ts +45 -2
  205. package/dist/db/migrator.d.ts.map +1 -1
  206. package/dist/db/migrator.js +113 -29
  207. package/dist/db/migrator.js.map +1 -1
  208. package/dist/db/schema.d.ts +213 -0
  209. package/dist/db/schema.d.ts.map +1 -1
  210. package/dist/db/schema.js +28 -0
  211. package/dist/db/schema.js.map +1 -1
  212. package/dist/executor/auth-check.d.ts +30 -7
  213. package/dist/executor/auth-check.d.ts.map +1 -1
  214. package/dist/executor/auth-check.js +66 -16
  215. package/dist/executor/auth-check.js.map +1 -1
  216. package/dist/executor/auth-monitor.d.ts.map +1 -1
  217. package/dist/executor/auth-monitor.js +48 -39
  218. package/dist/executor/auth-monitor.js.map +1 -1
  219. package/dist/executor/deep-review.d.ts.map +1 -1
  220. package/dist/executor/deep-review.js +14 -79
  221. package/dist/executor/deep-review.js.map +1 -1
  222. package/dist/executor/executor.d.ts +21 -0
  223. package/dist/executor/executor.d.ts.map +1 -1
  224. package/dist/executor/executor.js +42 -91
  225. package/dist/executor/executor.js.map +1 -1
  226. package/dist/executor/extract-handoff.d.ts +9 -0
  227. package/dist/executor/extract-handoff.d.ts.map +1 -1
  228. package/dist/executor/extract-handoff.js +48 -0
  229. package/dist/executor/extract-handoff.js.map +1 -1
  230. package/dist/executor/handoff.d.ts +10 -1
  231. package/dist/executor/handoff.d.ts.map +1 -1
  232. package/dist/executor/handoff.js +7 -1
  233. package/dist/executor/handoff.js.map +1 -1
  234. package/dist/executor/index.d.ts +1 -0
  235. package/dist/executor/index.d.ts.map +1 -1
  236. package/dist/executor/index.js +1 -0
  237. package/dist/executor/index.js.map +1 -1
  238. package/dist/executor/prompt/templates.d.ts +12 -1
  239. package/dist/executor/prompt/templates.d.ts.map +1 -1
  240. package/dist/executor/prompt/templates.js +64 -0
  241. package/dist/executor/prompt/templates.js.map +1 -1
  242. package/dist/executor/session-resolver.d.ts +51 -0
  243. package/dist/executor/session-resolver.d.ts.map +1 -0
  244. package/dist/executor/session-resolver.js +83 -0
  245. package/dist/executor/session-resolver.js.map +1 -0
  246. package/dist/index.d.ts +3 -2
  247. package/dist/index.d.ts.map +1 -1
  248. package/dist/index.js +3 -2
  249. package/dist/index.js.map +1 -1
  250. package/dist/notifier/composite.js +1 -1
  251. package/dist/notifier/composite.js.map +1 -1
  252. package/dist/notifier/linear.d.ts +1 -1
  253. package/dist/notifier/linear.d.ts.map +1 -1
  254. package/dist/notifier/linear.js +49 -9
  255. package/dist/notifier/linear.js.map +1 -1
  256. package/dist/pipeline/run-surgical-review-fix.d.ts +29 -0
  257. package/dist/pipeline/run-surgical-review-fix.d.ts.map +1 -0
  258. package/dist/pipeline/run-surgical-review-fix.js +48 -0
  259. package/dist/pipeline/run-surgical-review-fix.js.map +1 -0
  260. package/dist/pipeline/runner.d.ts.map +1 -1
  261. package/dist/pipeline/runner.js +132 -36
  262. package/dist/pipeline/runner.js.map +1 -1
  263. package/dist/pm/actions/circuit-breaker-config.d.ts +13 -0
  264. package/dist/pm/actions/circuit-breaker-config.d.ts.map +1 -0
  265. package/dist/pm/actions/circuit-breaker-config.js +23 -0
  266. package/dist/pm/actions/circuit-breaker-config.js.map +1 -0
  267. package/dist/pm/actions/db-queries.d.ts +18 -0
  268. package/dist/pm/actions/db-queries.d.ts.map +1 -1
  269. package/dist/pm/actions/db-queries.js +75 -2
  270. package/dist/pm/actions/db-queries.js.map +1 -1
  271. package/dist/pm/actions/promote.d.ts +7 -0
  272. package/dist/pm/actions/promote.d.ts.map +1 -1
  273. package/dist/pm/actions/promote.js +17 -1
  274. package/dist/pm/actions/promote.js.map +1 -1
  275. package/dist/pm/actions/recover-circuit-breaker.d.ts +21 -0
  276. package/dist/pm/actions/recover-circuit-breaker.d.ts.map +1 -0
  277. package/dist/pm/actions/recover-circuit-breaker.js +47 -0
  278. package/dist/pm/actions/recover-circuit-breaker.js.map +1 -0
  279. package/dist/pm/actions/select-probe-candidates.d.ts +21 -0
  280. package/dist/pm/actions/select-probe-candidates.d.ts.map +1 -0
  281. package/dist/pm/actions/select-probe-candidates.js +81 -0
  282. package/dist/pm/actions/select-probe-candidates.js.map +1 -0
  283. package/dist/pm/actions/start-todo.d.ts +7 -0
  284. package/dist/pm/actions/start-todo.d.ts.map +1 -1
  285. package/dist/pm/actions/start-todo.js +2 -1
  286. package/dist/pm/actions/start-todo.js.map +1 -1
  287. package/dist/pm/actions/sweep-recovered-circuit-breakers.d.ts +28 -0
  288. package/dist/pm/actions/sweep-recovered-circuit-breakers.d.ts.map +1 -0
  289. package/dist/pm/actions/sweep-recovered-circuit-breakers.js +47 -0
  290. package/dist/pm/actions/sweep-recovered-circuit-breakers.js.map +1 -0
  291. package/dist/pm/actions/triage-prompt.d.ts +14 -0
  292. package/dist/pm/actions/triage-prompt.d.ts.map +1 -1
  293. package/dist/pm/actions/triage-prompt.js +52 -9
  294. package/dist/pm/actions/triage-prompt.js.map +1 -1
  295. package/dist/pm/actions/triage.d.ts.map +1 -1
  296. package/dist/pm/actions/triage.js +37 -24
  297. package/dist/pm/actions/triage.js.map +1 -1
  298. package/dist/pm/conflict.d.ts +2 -0
  299. package/dist/pm/conflict.d.ts.map +1 -1
  300. package/dist/pm/conflict.js +59 -9
  301. package/dist/pm/conflict.js.map +1 -1
  302. package/dist/pm/scheduler.d.ts +5 -0
  303. package/dist/pm/scheduler.d.ts.map +1 -1
  304. package/dist/pm/scheduler.js +91 -44
  305. package/dist/pm/scheduler.js.map +1 -1
  306. package/dist/pm/slack.d.ts +11 -0
  307. package/dist/pm/slack.d.ts.map +1 -1
  308. package/dist/pm/slack.js +48 -5
  309. package/dist/pm/slack.js.map +1 -1
  310. package/dist/release-manager/release-helpers.d.ts +19 -2
  311. package/dist/release-manager/release-helpers.d.ts.map +1 -1
  312. package/dist/release-manager/release-helpers.js +22 -3
  313. package/dist/release-manager/release-helpers.js.map +1 -1
  314. package/dist/release-manager/release-tick.d.ts.map +1 -1
  315. package/dist/release-manager/release-tick.js +20 -8
  316. package/dist/release-manager/release-tick.js.map +1 -1
  317. package/dist/release-manager/slack-handler.d.ts +6 -0
  318. package/dist/release-manager/slack-handler.d.ts.map +1 -1
  319. package/dist/release-manager/slack-handler.js +76 -1
  320. package/dist/release-manager/slack-handler.js.map +1 -1
  321. package/dist/release-manager/state.d.ts.map +1 -1
  322. package/dist/release-manager/state.js +25 -18
  323. package/dist/release-manager/state.js.map +1 -1
  324. package/dist/types.d.ts +238 -13
  325. package/dist/types.d.ts.map +1 -1
  326. package/dist/types.js +67 -0
  327. package/dist/types.js.map +1 -1
  328. package/dist/webhook/github-handler.d.ts +2 -2
  329. package/dist/webhook/github-handler.d.ts.map +1 -1
  330. package/dist/webhook/github-handler.js +18 -6
  331. package/dist/webhook/github-handler.js.map +1 -1
  332. package/package.json +1 -1
@@ -1,21 +1,28 @@
1
1
  /**
2
- * Tests for AuthMonitor (BEC-207) periodic Claude session health-check.
2
+ * Tests for AuthMonitor (BEC-207 / BEC-237 / BEC-244).
3
3
  *
4
4
  * Covers:
5
- * - Returns early when CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY is set.
6
- * - Runs `claude auth status` only when neither env var is set.
7
- * - On expiry: sends Slack alert and writes claude.auth_expired audit event.
5
+ * - Returns early ONLY when ANTHROPIC_API_KEY is set and CLAUDE_CODE_OAUTH_TOKEN is NOT set.
6
+ * - When CLAUDE_CODE_OAUTH_TOKEN is set, runs the real-API probe regardless of ANTHROPIC_API_KEY.
7
+ * - Runs the real-API probe when neither env var is set (mounted-session path).
8
+ * - On auth expiry (probe returns auth error): sends Slack alert + writes claude.auth_expired event.
9
+ * - On network error: probe returns { valid: true } (fail-open) — no alert, no audit event.
8
10
  * - 6-hour throttle: skips check if interval has not elapsed.
9
11
  * - createAuthMonitor stateful wrapper manages lastCheckTime across calls.
10
12
  */
11
13
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
12
14
  // ---------------------------------------------------------------------------
13
- // Mocks — must be declared before any imports that use the mocked modules.
15
+ // Mocks — declared before any imports that use the mocked modules.
14
16
  // vi.mock() is hoisted by vitest, so these run before module initialisation.
15
17
  // ---------------------------------------------------------------------------
16
- // Mock child_process.execFile used by runAuthMonitorCheck
17
- vi.mock("node:child_process", () => ({
18
- execFile: vi.fn(),
18
+ // Mock probeClaudeAuth (and other exports) from auth-check.js.
19
+ // auth-monitor.ts imports probeClaudeAuth from there; mocking at module level
20
+ // lets each test control the probe outcome cleanly.
21
+ vi.mock("../executor/auth-check.js", () => ({
22
+ resetAuthCheckCache: vi.fn(),
23
+ resolveClaudeAuth: vi.fn(() => ({ method: "mounted-session" })),
24
+ isClaudeAuthValid: vi.fn().mockResolvedValue(true),
25
+ probeClaudeAuth: vi.fn(),
19
26
  }));
20
27
  // Mock postSlackMessage
21
28
  vi.mock("../pm/slack-helpers.js", () => ({
@@ -25,38 +32,32 @@ vi.mock("../pm/slack-helpers.js", () => ({
25
32
  vi.mock("../audit/writer.js", () => ({
26
33
  logAuditEventUnchecked: vi.fn().mockResolvedValue(undefined),
27
34
  }));
28
- // Mock resetAuthCheckCache (auth-monitor calls this to bypass the 5-min cache)
29
- vi.mock("../executor/auth-check.js", () => ({
30
- resetAuthCheckCache: vi.fn(),
31
- resolveClaudeAuth: vi.fn(() => ({ method: "session" })),
32
- isClaudeAuthValid: vi.fn().mockResolvedValue(true),
33
- }));
34
35
  // ---------------------------------------------------------------------------
35
36
  // Static imports (mocks are in place due to hoisting)
36
37
  // ---------------------------------------------------------------------------
37
- import { execFile } from "node:child_process";
38
38
  import { postSlackMessage } from "../pm/slack-helpers.js";
39
39
  import { logAuditEventUnchecked } from "../audit/writer.js";
40
+ import { probeClaudeAuth } from "../executor/auth-check.js";
40
41
  import { runAuthMonitorCheck, createAuthMonitor } from "../executor/auth-monitor.js";
41
- const mockExecFile = vi.mocked(execFile);
42
+ const mockProbeClaudeAuth = vi.mocked(probeClaudeAuth);
42
43
  const mockPostSlackMessage = vi.mocked(postSlackMessage);
43
44
  const mockLogAuditEvent = vi.mocked(logAuditEventUnchecked);
44
45
  // ---------------------------------------------------------------------------
45
46
  // Helpers
46
47
  // ---------------------------------------------------------------------------
47
- function simulateCliSuccess() {
48
- mockExecFile.mockImplementation((_cmd, _args, _opts, cb) => {
49
- cb(null);
50
- return {};
51
- });
48
+ function simulateProbeSuccess() {
49
+ mockProbeClaudeAuth.mockResolvedValue({ valid: true });
52
50
  }
53
- function simulateCliFailure() {
54
- mockExecFile.mockImplementation((_cmd, _args, _opts, cb) => {
55
- cb(new Error("session expired"));
56
- return {};
57
- });
51
+ /** Auth failure — probe detects a 401 from the API. */
52
+ function simulateProbeAuthFailure() {
53
+ mockProbeClaudeAuth.mockResolvedValue({ valid: false, reason: "auth" });
54
+ }
55
+ /** Network / transient error — probe fails open (no alert should fire). */
56
+ function simulateProbeNetworkError() {
57
+ // Fail-open: probeClaudeAuth returns { valid: true } on network errors
58
+ mockProbeClaudeAuth.mockResolvedValue({ valid: true });
58
59
  }
59
- const SMALL_INTERVAL = 100; // 100 ms — always elapsed unless we use a very recent timestamp
60
+ const SMALL_INTERVAL = 100; // 100 ms — always elapsed unless we pass a very recent timestamp
60
61
  // ---------------------------------------------------------------------------
61
62
  // Tests: runAuthMonitorCheck
62
63
  // ---------------------------------------------------------------------------
@@ -64,76 +65,155 @@ describe("runAuthMonitorCheck", () => {
64
65
  let savedOauthToken;
65
66
  let savedApiKey;
66
67
  beforeEach(() => {
67
- mockExecFile.mockReset();
68
+ mockProbeClaudeAuth.mockReset();
68
69
  mockPostSlackMessage.mockReset().mockResolvedValue({ ok: true });
69
70
  mockLogAuditEvent.mockReset().mockResolvedValue(undefined);
70
- // Save and clear env vars so each test starts with a clean slate
71
71
  savedOauthToken = process.env.CLAUDE_CODE_OAUTH_TOKEN;
72
72
  savedApiKey = process.env.ANTHROPIC_API_KEY;
73
73
  delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
74
74
  delete process.env.ANTHROPIC_API_KEY;
75
75
  });
76
76
  afterEach(() => {
77
- if (savedOauthToken === undefined) {
77
+ if (savedOauthToken === undefined)
78
78
  delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
79
- }
80
- else {
79
+ else
81
80
  process.env.CLAUDE_CODE_OAUTH_TOKEN = savedOauthToken;
82
- }
83
- if (savedApiKey === undefined) {
81
+ if (savedApiKey === undefined)
84
82
  delete process.env.ANTHROPIC_API_KEY;
85
- }
86
- else {
83
+ else
87
84
  process.env.ANTHROPIC_API_KEY = savedApiKey;
88
- }
89
85
  });
90
86
  // --- Throttle ---
91
87
  it("skips check when interval has not elapsed (lastCheckTime is recent)", async () => {
92
- const recentTime = Date.now(); // just ran
93
- await runAuthMonitorCheck(recentTime, {}, 60_000); // 60-second interval
94
- // Should not run execFile because interval hasn't elapsed
95
- expect(mockExecFile).not.toHaveBeenCalled();
88
+ const recentTime = Date.now();
89
+ await runAuthMonitorCheck(recentTime, {}, 60_000);
90
+ expect(mockProbeClaudeAuth).not.toHaveBeenCalled();
96
91
  });
97
92
  it("runs check when interval has elapsed (lastCheckTime = 0 = never)", async () => {
98
- simulateCliSuccess();
93
+ simulateProbeSuccess();
99
94
  await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
100
- expect(mockExecFile).toHaveBeenCalledTimes(1);
95
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
101
96
  });
102
- // --- Env-var short-circuit (AC #8) ---
103
- it("returns early without subprocess when CLAUDE_CODE_OAUTH_TOKEN is set", async () => {
104
- process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
97
+ // --- Env-var skip logic (BEC-237) ---
98
+ it("skips probe when ANTHROPIC_API_KEY is set and CLAUDE_CODE_OAUTH_TOKEN is NOT set", async () => {
99
+ process.env.ANTHROPIC_API_KEY = "sk-ant-api03-test";
105
100
  await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
106
- expect(mockExecFile).not.toHaveBeenCalled();
101
+ expect(mockProbeClaudeAuth).not.toHaveBeenCalled();
107
102
  expect(mockPostSlackMessage).not.toHaveBeenCalled();
108
103
  expect(mockLogAuditEvent).not.toHaveBeenCalled();
109
104
  });
110
- it("returns early without subprocess when ANTHROPIC_API_KEY is set", async () => {
105
+ it("runs the auth probe when CLAUDE_CODE_OAUTH_TOKEN is set (OAuth tokens can expire)", async () => {
106
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
107
+ simulateProbeSuccess();
108
+ await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
109
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
110
+ });
111
+ it("runs the auth probe when both CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY are set", async () => {
112
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
111
113
  process.env.ANTHROPIC_API_KEY = "sk-ant-api03-test";
114
+ simulateProbeSuccess();
112
115
  await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
113
- expect(mockExecFile).not.toHaveBeenCalled();
116
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
117
+ });
118
+ it("runs the auth probe when neither env var is set (mounted-session path)", async () => {
119
+ simulateProbeSuccess();
120
+ await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
121
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
122
+ });
123
+ it("passes 15-second timeout to probeClaudeAuth", async () => {
124
+ simulateProbeSuccess();
125
+ await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
126
+ expect(mockProbeClaudeAuth).toHaveBeenCalledWith(15_000);
127
+ });
128
+ // --- Probe success → no alert ---
129
+ it("does not alert when CLAUDE_CODE_OAUTH_TOKEN probe succeeds", async () => {
130
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
131
+ simulateProbeSuccess();
132
+ await runAuthMonitorCheck(0, {
133
+ slackBotToken: "xoxb-test",
134
+ slackErrorChannel: "CTEST",
135
+ }, SMALL_INTERVAL);
114
136
  expect(mockPostSlackMessage).not.toHaveBeenCalled();
115
137
  expect(mockLogAuditEvent).not.toHaveBeenCalled();
116
138
  });
117
- it("returns early without subprocess when both env vars are set", async () => {
139
+ // --- Probe auth failure (BEC-244 core scenario) ---
140
+ it("sends Slack alert with oauth-token instructions when CLAUDE_CODE_OAUTH_TOKEN probe detects auth failure", async () => {
141
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
142
+ simulateProbeAuthFailure();
143
+ await runAuthMonitorCheck(0, {
144
+ slackBotToken: "xoxb-bot-token",
145
+ slackErrorChannel: "CERROR",
146
+ }, SMALL_INTERVAL);
147
+ expect(mockPostSlackMessage).toHaveBeenCalledTimes(1);
148
+ const [calledToken, calledPayload] = mockPostSlackMessage.mock.calls[0];
149
+ expect(calledToken).toBe("xoxb-bot-token");
150
+ expect(calledPayload.channel).toBe("CERROR");
151
+ expect(calledPayload.text).toContain("setup-token");
152
+ expect(calledPayload.text).not.toContain("claude login");
153
+ });
154
+ it("logs claude.auth_expired with authMethod=oauth-token when CLAUDE_CODE_OAUTH_TOKEN probe detects auth failure", async () => {
155
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
156
+ simulateProbeAuthFailure();
157
+ const fakeDb = {};
158
+ await runAuthMonitorCheck(0, { db: fakeDb }, SMALL_INTERVAL);
159
+ expect(mockLogAuditEvent).toHaveBeenCalledTimes(1);
160
+ const [calledDb, calledEvent] = mockLogAuditEvent.mock.calls[0];
161
+ expect(calledDb).toBe(fakeDb);
162
+ expect(calledEvent.eventType).toBe("claude.auth_expired");
163
+ expect(calledEvent.actor).toBe("system");
164
+ expect(calledEvent.payload).toMatchObject({
165
+ detectedAt: expect.any(String),
166
+ authMethod: "oauth-token",
167
+ });
168
+ });
169
+ it("sends oauth-token Slack alert when both env vars set and probe detects auth failure", async () => {
118
170
  process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
119
171
  process.env.ANTHROPIC_API_KEY = "sk-ant-api03-test";
120
- await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
121
- expect(mockExecFile).not.toHaveBeenCalled();
172
+ simulateProbeAuthFailure();
173
+ const fakeDb = {};
174
+ await runAuthMonitorCheck(0, {
175
+ slackBotToken: "xoxb-test",
176
+ slackErrorChannel: "CTEST",
177
+ db: fakeDb,
178
+ }, SMALL_INTERVAL);
179
+ expect(mockPostSlackMessage).toHaveBeenCalledTimes(1);
180
+ expect(mockPostSlackMessage.mock.calls[0][1].text).toContain("setup-token");
181
+ const [, calledEvent] = mockLogAuditEvent.mock.calls[0];
182
+ expect(calledEvent.payload.authMethod).toBe("oauth-token");
183
+ });
184
+ // --- Probe network error → fail-open (BEC-244 AC) ---
185
+ it("does NOT fire an alert when probe encounters a network error (fail-open)", async () => {
186
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
187
+ // probeClaudeAuth returns { valid: true } for network/transient errors
188
+ simulateProbeNetworkError();
189
+ await runAuthMonitorCheck(0, {
190
+ slackBotToken: "xoxb-test",
191
+ slackErrorChannel: "CTEST",
192
+ db: {},
193
+ }, SMALL_INTERVAL);
194
+ expect(mockPostSlackMessage).not.toHaveBeenCalled();
195
+ expect(mockLogAuditEvent).not.toHaveBeenCalled();
196
+ });
197
+ it("does NOT fire an audit event when probe encounters a network error (fail-open)", async () => {
198
+ simulateProbeNetworkError();
199
+ const fakeDb = {};
200
+ await runAuthMonitorCheck(0, { db: fakeDb }, SMALL_INTERVAL);
201
+ expect(mockLogAuditEvent).not.toHaveBeenCalled();
122
202
  });
123
203
  // --- Session valid ---
124
- it("runs subprocess and skips alerts when session is valid", async () => {
125
- simulateCliSuccess();
204
+ it("runs probe and skips alerts when mounted session is valid", async () => {
205
+ simulateProbeSuccess();
126
206
  await runAuthMonitorCheck(0, {
127
207
  slackBotToken: "xoxb-test",
128
208
  slackErrorChannel: "CTEST",
129
209
  }, SMALL_INTERVAL);
130
- expect(mockExecFile).toHaveBeenCalledTimes(1);
210
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
131
211
  expect(mockPostSlackMessage).not.toHaveBeenCalled();
132
212
  expect(mockLogAuditEvent).not.toHaveBeenCalled();
133
213
  });
134
- // --- Session expired (AC #7, #15) ---
135
- it("sends Slack alert to configured channel when session is expired", async () => {
136
- simulateCliFailure();
214
+ // --- Mounted session expired ---
215
+ it("sends Slack alert to configured channel when mounted session probe detects auth failure", async () => {
216
+ simulateProbeAuthFailure();
137
217
  await runAuthMonitorCheck(0, {
138
218
  slackBotToken: "xoxb-bot-token",
139
219
  slackErrorChannel: "CERROR",
@@ -141,8 +221,17 @@ describe("runAuthMonitorCheck", () => {
141
221
  expect(mockPostSlackMessage).toHaveBeenCalledTimes(1);
142
222
  expect(mockPostSlackMessage).toHaveBeenCalledWith("xoxb-bot-token", expect.objectContaining({ channel: "CERROR" }));
143
223
  });
144
- it("logs claude.auth_expired audit event when session is expired and db provided (AC #7)", async () => {
145
- simulateCliFailure();
224
+ it("Slack alert for mounted-session auth failure mentions claude login, not setup-token", async () => {
225
+ simulateProbeAuthFailure();
226
+ await runAuthMonitorCheck(0, {
227
+ slackBotToken: "xoxb-test",
228
+ slackErrorChannel: "CTEST",
229
+ }, SMALL_INTERVAL);
230
+ const text = mockPostSlackMessage.mock.calls[0][1].text;
231
+ expect(text).toContain("claude login");
232
+ });
233
+ it("logs claude.auth_expired audit event with authMethod=mounted-session when session probe detects auth failure", async () => {
234
+ simulateProbeAuthFailure();
146
235
  const fakeDb = {};
147
236
  await runAuthMonitorCheck(0, { db: fakeDb }, SMALL_INTERVAL);
148
237
  expect(mockLogAuditEvent).toHaveBeenCalledTimes(1);
@@ -152,10 +241,11 @@ describe("runAuthMonitorCheck", () => {
152
241
  expect(calledEvent.actor).toBe("system");
153
242
  expect(calledEvent.payload).toMatchObject({
154
243
  detectedAt: expect.any(String),
244
+ authMethod: "mounted-session",
155
245
  });
156
246
  });
157
247
  it("does not throw when Slack post fails", async () => {
158
- simulateCliFailure();
248
+ simulateProbeAuthFailure();
159
249
  mockPostSlackMessage.mockRejectedValue(new Error("network error"));
160
250
  await expect(runAuthMonitorCheck(0, {
161
251
  slackBotToken: "xoxb-test",
@@ -163,18 +253,18 @@ describe("runAuthMonitorCheck", () => {
163
253
  }, SMALL_INTERVAL)).resolves.not.toThrow();
164
254
  });
165
255
  it("skips Slack when no slackBotToken configured", async () => {
166
- simulateCliFailure();
256
+ simulateProbeAuthFailure();
167
257
  await runAuthMonitorCheck(0, { slackErrorChannel: "CTEST" }, SMALL_INTERVAL);
168
258
  expect(mockPostSlackMessage).not.toHaveBeenCalled();
169
259
  });
170
260
  it("skips Slack when no slackErrorChannel configured", async () => {
171
- simulateCliFailure();
261
+ simulateProbeAuthFailure();
172
262
  await runAuthMonitorCheck(0, { slackBotToken: "xoxb-test" }, SMALL_INTERVAL);
173
263
  expect(mockPostSlackMessage).not.toHaveBeenCalled();
174
264
  });
175
- // --- Return value (lastCheckTime update) ---
265
+ // --- Return value ---
176
266
  it("returns updated timestamp after running", async () => {
177
- simulateCliSuccess();
267
+ simulateProbeSuccess();
178
268
  const before = Date.now();
179
269
  const returned = await runAuthMonitorCheck(0, {}, SMALL_INTERVAL);
180
270
  const after = Date.now();
@@ -188,13 +278,13 @@ describe("runAuthMonitorCheck", () => {
188
278
  });
189
279
  });
190
280
  // ---------------------------------------------------------------------------
191
- // Tests: createAuthMonitor stateful wrapper (AC #6)
281
+ // Tests: createAuthMonitor stateful wrapper
192
282
  // ---------------------------------------------------------------------------
193
283
  describe("createAuthMonitor", () => {
194
284
  let savedOauthToken;
195
285
  let savedApiKey;
196
286
  beforeEach(() => {
197
- mockExecFile.mockReset();
287
+ mockProbeClaudeAuth.mockReset();
198
288
  mockPostSlackMessage.mockReset().mockResolvedValue({ ok: true });
199
289
  mockLogAuditEvent.mockReset().mockResolvedValue(undefined);
200
290
  savedOauthToken = process.env.CLAUDE_CODE_OAUTH_TOKEN;
@@ -203,40 +293,72 @@ describe("createAuthMonitor", () => {
203
293
  delete process.env.ANTHROPIC_API_KEY;
204
294
  });
205
295
  afterEach(() => {
206
- if (savedOauthToken === undefined) {
296
+ if (savedOauthToken === undefined)
207
297
  delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
208
- }
209
- else {
298
+ else
210
299
  process.env.CLAUDE_CODE_OAUTH_TOKEN = savedOauthToken;
211
- }
212
- if (savedApiKey === undefined) {
300
+ if (savedApiKey === undefined)
213
301
  delete process.env.ANTHROPIC_API_KEY;
214
- }
215
- else {
302
+ else
216
303
  process.env.ANTHROPIC_API_KEY = savedApiKey;
217
- }
218
304
  });
219
- it("tick() runs the check and handles errors gracefully", async () => {
220
- simulateCliSuccess();
305
+ it("tick() runs the probe and handles errors gracefully", async () => {
306
+ simulateProbeSuccess();
221
307
  const monitor = createAuthMonitor({}, SMALL_INTERVAL);
222
308
  await expect(monitor.tick()).resolves.not.toThrow();
223
- expect(mockExecFile).toHaveBeenCalledTimes(1);
309
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
224
310
  });
225
311
  it("tick() is throttled — second call immediately after first is a no-op", async () => {
226
- simulateCliSuccess();
227
- const monitor = createAuthMonitor({}, 60_000); // 60s interval
228
- await monitor.tick(); // first tick — runs
229
- await monitor.tick(); // second tick immediately — throttled
230
- expect(mockExecFile).toHaveBeenCalledTimes(1); // only one subprocess
312
+ simulateProbeSuccess();
313
+ const monitor = createAuthMonitor({}, 60_000);
314
+ await monitor.tick();
315
+ await monitor.tick();
316
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
231
317
  });
232
- it("tick() skips session check when CLAUDE_CODE_OAUTH_TOKEN is set (AC #8)", async () => {
318
+ it("tick() skips probe when only ANTHROPIC_API_KEY is set (static key, never expires)", async () => {
319
+ process.env.ANTHROPIC_API_KEY = "sk-ant-api03-test";
320
+ const monitor = createAuthMonitor({}, SMALL_INTERVAL);
321
+ await monitor.tick();
322
+ expect(mockProbeClaudeAuth).not.toHaveBeenCalled();
323
+ });
324
+ it("tick() runs probe when CLAUDE_CODE_OAUTH_TOKEN is set (OAuth tokens can expire)", async () => {
233
325
  process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
326
+ simulateProbeSuccess();
234
327
  const monitor = createAuthMonitor({}, SMALL_INTERVAL);
235
328
  await monitor.tick();
236
- expect(mockExecFile).not.toHaveBeenCalled();
329
+ expect(mockProbeClaudeAuth).toHaveBeenCalledTimes(1);
330
+ });
331
+ it("tick() does NOT alert when probe returns network error (fail-open)", async () => {
332
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
333
+ simulateProbeNetworkError();
334
+ const fakeDb = {};
335
+ const monitor = createAuthMonitor({
336
+ slackBotToken: "xoxb-test",
337
+ slackErrorChannel: "CALERTS",
338
+ db: fakeDb,
339
+ }, SMALL_INTERVAL);
340
+ await monitor.tick();
341
+ expect(mockPostSlackMessage).not.toHaveBeenCalled();
342
+ expect(mockLogAuditEvent).not.toHaveBeenCalled();
343
+ });
344
+ it("tick() sends alert on auth-failed OAuth token and logs audit event with authMethod=oauth-token", async () => {
345
+ process.env.CLAUDE_CODE_OAUTH_TOKEN = "sk-ant-oat-test";
346
+ simulateProbeAuthFailure();
347
+ const fakeDb = {};
348
+ const monitor = createAuthMonitor({
349
+ slackBotToken: "xoxb-test",
350
+ slackErrorChannel: "CALERTS",
351
+ db: fakeDb,
352
+ }, SMALL_INTERVAL);
353
+ await monitor.tick();
354
+ expect(mockPostSlackMessage).toHaveBeenCalledWith("xoxb-test", expect.objectContaining({ channel: "CALERTS" }));
355
+ expect(mockLogAuditEvent).toHaveBeenCalledTimes(1);
356
+ const [, calledEvent] = mockLogAuditEvent.mock.calls[0];
357
+ expect(calledEvent.eventType).toBe("claude.auth_expired");
358
+ expect(calledEvent.payload.authMethod).toBe("oauth-token");
237
359
  });
238
- it("tick() sends alert on expired session and logs audit event (AC #6, #7)", async () => {
239
- simulateCliFailure();
360
+ it("tick() sends alert on auth-failed mounted session and logs audit event with authMethod=mounted-session", async () => {
361
+ simulateProbeAuthFailure();
240
362
  const fakeDb = {};
241
363
  const monitor = createAuthMonitor({
242
364
  slackBotToken: "xoxb-test",
@@ -248,6 +370,7 @@ describe("createAuthMonitor", () => {
248
370
  expect(mockLogAuditEvent).toHaveBeenCalledTimes(1);
249
371
  const [, calledEvent] = mockLogAuditEvent.mock.calls[0];
250
372
  expect(calledEvent.eventType).toBe("claude.auth_expired");
373
+ expect(calledEvent.payload.authMethod).toBe("mounted-session");
251
374
  });
252
375
  });
253
376
  //# sourceMappingURL=auth-monitor.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-monitor.test.js","sourceRoot":"","sources":["../../src/__tests__/auth-monitor.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-monitor.test.js","sourceRoot":"","sources":["../../src/__tests__/auth-monitor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bec-238-repro.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bec-238-repro.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bec-238-repro.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * BEC-238: Slack bot token missing reactions:read scope.
3
+ *
4
+ * Verifies the fix:
5
+ * 1. probeReactionsScope() logs error exactly once on missing_scope.
6
+ * 2. probeReactionsScope() stays silent when scope is present (any other error).
7
+ * 3. checkApprovalReactions() deduplicates missing_scope warns to one per
8
+ * notifier instance — no 7×/tick flood.
9
+ * 4. checkApprovalReactions() still logs every occurrence of non-missing_scope
10
+ * errors (other error types are not deduped).
11
+ */
12
+ import { describe, it, expect, vi, beforeEach } from "vitest";
13
+ import { PmSlackNotifier } from "../pm/slack.js";
14
+ vi.mock("../logger.js", () => {
15
+ const warnSpy = vi.fn();
16
+ const errorSpy = vi.fn();
17
+ return {
18
+ createLogger: () => ({
19
+ warn: warnSpy,
20
+ error: errorSpy,
21
+ info: vi.fn(),
22
+ debug: vi.fn(),
23
+ }),
24
+ __warnSpy: warnSpy,
25
+ __errorSpy: errorSpy,
26
+ };
27
+ });
28
+ import * as loggerModule from "../logger.js";
29
+ const warnSpy = loggerModule.__warnSpy;
30
+ const errorSpy = loggerModule.__errorSpy;
31
+ const mockFetch = vi.fn();
32
+ beforeEach(() => {
33
+ vi.stubGlobal("fetch", mockFetch);
34
+ mockFetch.mockReset();
35
+ warnSpy.mockReset();
36
+ errorSpy.mockReset();
37
+ });
38
+ function fetchReturning(body) {
39
+ return { ok: true, json: () => Promise.resolve(body) };
40
+ }
41
+ // ── probeReactionsScope ───────────────────────────────────────────────────────
42
+ describe("PmSlackNotifier.probeReactionsScope (BEC-238 AC2)", () => {
43
+ it("logs error exactly once when reactions:read scope is missing", async () => {
44
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: false, error: "missing_scope" }));
45
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
46
+ await notifier.probeReactionsScope();
47
+ expect(errorSpy).toHaveBeenCalledTimes(1);
48
+ const [ctx, msg] = errorSpy.mock.calls[0];
49
+ expect(ctx?.error).toBe("missing_scope");
50
+ expect(msg).toMatch(/reactions:read/);
51
+ expect(msg).toMatch(/Fix:/);
52
+ expect(warnSpy).not.toHaveBeenCalled();
53
+ });
54
+ it("stays silent when scope is present (message_not_found means token can call reactions.get)", async () => {
55
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: false, error: "message_not_found" }));
56
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
57
+ await notifier.probeReactionsScope();
58
+ expect(errorSpy).not.toHaveBeenCalled();
59
+ expect(warnSpy).not.toHaveBeenCalled();
60
+ });
61
+ it("stays silent when reactions.get succeeds (scope definitely present)", async () => {
62
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: true, message: { reactions: [] } }));
63
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
64
+ await notifier.probeReactionsScope();
65
+ expect(errorSpy).not.toHaveBeenCalled();
66
+ expect(warnSpy).not.toHaveBeenCalled();
67
+ });
68
+ it("logs warn (not error) on fetch exception — probe is best-effort", async () => {
69
+ mockFetch.mockRejectedValueOnce(new Error("network timeout"));
70
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
71
+ await notifier.probeReactionsScope();
72
+ expect(errorSpy).not.toHaveBeenCalled();
73
+ expect(warnSpy).toHaveBeenCalledTimes(1);
74
+ expect(warnSpy.mock.calls[0][1]).toMatch(/scope probe failed/);
75
+ });
76
+ });
77
+ // ── checkApprovalReactions dedup (AC3) ───────────────────────────────────────
78
+ describe("PmSlackNotifier.checkApprovalReactions missing_scope dedup (BEC-238 AC3)", () => {
79
+ it("logs warn only once across 7 consecutive missing_scope calls", async () => {
80
+ const PENDING_COUNT = 7;
81
+ for (let i = 0; i < PENDING_COUNT; i++) {
82
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: false, error: "missing_scope" }));
83
+ }
84
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
85
+ for (let i = 0; i < PENDING_COUNT; i++) {
86
+ const result = await notifier.checkApprovalReactions(`ts-${i}`);
87
+ expect(result).toBe("pending");
88
+ }
89
+ // First call logs; subsequent 6 are silently deduped.
90
+ expect(warnSpy).toHaveBeenCalledTimes(1);
91
+ const [ctx, msg] = warnSpy.mock.calls[0];
92
+ expect(ctx?.error).toBe("missing_scope");
93
+ expect(msg).toMatch(/reactions\.get.*ok:false/i);
94
+ });
95
+ it("does NOT dedup non-missing_scope errors — each occurrence is logged", async () => {
96
+ const ERROR_COUNT = 3;
97
+ for (let i = 0; i < ERROR_COUNT; i++) {
98
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: false, error: "channel_not_found" }));
99
+ }
100
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
101
+ for (let i = 0; i < ERROR_COUNT; i++) {
102
+ await notifier.checkApprovalReactions(`ts-${i}`);
103
+ }
104
+ expect(warnSpy).toHaveBeenCalledTimes(ERROR_COUNT);
105
+ });
106
+ it("returns approved / rejected normally when scope is present", async () => {
107
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: true, message: { reactions: [{ name: "white_check_mark", count: 1 }] } }));
108
+ mockFetch.mockResolvedValueOnce(fetchReturning({ ok: true, message: { reactions: [{ name: "x", count: 1 }] } }));
109
+ const notifier = new PmSlackNotifier({ botToken: "xoxb-test", channelId: "C0000" });
110
+ expect(await notifier.checkApprovalReactions("ts-approved")).toBe("approved");
111
+ expect(await notifier.checkApprovalReactions("ts-rejected")).toBe("rejected");
112
+ expect(warnSpy).not.toHaveBeenCalled();
113
+ expect(errorSpy).not.toHaveBeenCalled();
114
+ });
115
+ });
116
+ //# sourceMappingURL=bec-238-repro.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bec-238-repro.test.js","sourceRoot":"","sources":["../../src/__tests__/bec-238-repro.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;IAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IACzB,OAAO;QACL,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YACnB,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;YACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;SACf,CAAC;QACF,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,QAAQ;KACrB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,KAAK,YAAY,MAAM,cAAc,CAAC;AAC7C,MAAM,OAAO,GAAI,YAAoB,CAAC,SAAqC,CAAC;AAC5E,MAAM,QAAQ,GAAI,YAAoB,CAAC,UAAsC,CAAC;AAE9E,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAE1B,UAAU,CAAC,GAAG,EAAE;IACd,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAClC,SAAS,CAAC,SAAS,EAAE,CAAC;IACtB,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,iFAAiF;AAEjF,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;QACvF,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;QACzG,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC;QAC3F,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,SAAS,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,QAAQ,CAAC,0EAA0E,EAAE,GAAG,EAAE;IACxF,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,aAAa,GAAG,CAAC,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;QAED,sDAAsD;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,WAAW,GAAG,CAAC,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,SAAS,CAAC,qBAAqB,CAC7B,cAAc,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC/F,CAAC;QACF,SAAS,CAAC,qBAAqB,CAC7B,cAAc,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAChF,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAEpF,MAAM,CAAC,MAAM,QAAQ,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,QAAQ,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9E,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}