@rulemetric/cli 0.1.1 → 0.2.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 (251) hide show
  1. package/README.md +66 -0
  2. package/dist/base-command.d.ts.map +1 -1
  3. package/dist/base-command.js +15 -0
  4. package/dist/base-command.js.map +1 -1
  5. package/dist/commands/auth/login.d.ts.map +1 -1
  6. package/dist/commands/auth/login.js +7 -0
  7. package/dist/commands/auth/login.js.map +1 -1
  8. package/dist/commands/crons/list.d.ts +7 -0
  9. package/dist/commands/crons/list.d.ts.map +1 -0
  10. package/dist/commands/crons/list.js +24 -0
  11. package/dist/commands/crons/list.js.map +1 -0
  12. package/dist/commands/crons/run.d.ts +13 -0
  13. package/dist/commands/crons/run.d.ts.map +1 -0
  14. package/dist/commands/crons/run.js +48 -0
  15. package/dist/commands/crons/run.js.map +1 -0
  16. package/dist/commands/evals/listen.d.ts +28 -2
  17. package/dist/commands/evals/listen.d.ts.map +1 -1
  18. package/dist/commands/evals/listen.js +159 -25
  19. package/dist/commands/evals/listen.js.map +1 -1
  20. package/dist/commands/evals/listen.test.d.ts +2 -0
  21. package/dist/commands/evals/listen.test.d.ts.map +1 -0
  22. package/dist/commands/evals/listen.test.js +48 -0
  23. package/dist/commands/evals/listen.test.js.map +1 -0
  24. package/dist/commands/gateway/ensure.js +1 -1
  25. package/dist/commands/gateway/ensure.js.map +1 -1
  26. package/dist/commands/hooks/install.d.ts.map +1 -1
  27. package/dist/commands/hooks/install.js +40 -3
  28. package/dist/commands/hooks/install.js.map +1 -1
  29. package/dist/commands/hooks/run.js +1 -1
  30. package/dist/commands/hooks/run.js.map +1 -1
  31. package/dist/commands/hooks/uninstall.d.ts.map +1 -1
  32. package/dist/commands/hooks/uninstall.js +9 -1
  33. package/dist/commands/hooks/uninstall.js.map +1 -1
  34. package/dist/commands/org/current.d.ts +7 -0
  35. package/dist/commands/org/current.d.ts.map +1 -0
  36. package/dist/commands/org/current.js +70 -0
  37. package/dist/commands/org/current.js.map +1 -0
  38. package/dist/commands/org/list.d.ts +7 -0
  39. package/dist/commands/org/list.d.ts.map +1 -0
  40. package/dist/commands/org/list.js +37 -0
  41. package/dist/commands/org/list.js.map +1 -0
  42. package/dist/commands/org/switch.d.ts +13 -0
  43. package/dist/commands/org/switch.d.ts.map +1 -0
  44. package/dist/commands/org/switch.js +52 -0
  45. package/dist/commands/org/switch.js.map +1 -0
  46. package/dist/commands/proxy/restart.d.ts +11 -0
  47. package/dist/commands/proxy/restart.d.ts.map +1 -0
  48. package/dist/commands/proxy/restart.js +36 -0
  49. package/dist/commands/proxy/restart.js.map +1 -0
  50. package/dist/commands/proxy/start.d.ts.map +1 -1
  51. package/dist/commands/proxy/start.js +4 -0
  52. package/dist/commands/proxy/start.js.map +1 -1
  53. package/dist/commands/service/install.d.ts +16 -0
  54. package/dist/commands/service/install.d.ts.map +1 -1
  55. package/dist/commands/service/install.js +145 -6
  56. package/dist/commands/service/install.js.map +1 -1
  57. package/dist/commands/service/uninstall.d.ts.map +1 -1
  58. package/dist/commands/service/uninstall.js +28 -0
  59. package/dist/commands/service/uninstall.js.map +1 -1
  60. package/dist/commands/sessions/start.d.ts.map +1 -1
  61. package/dist/commands/sessions/start.js +5 -0
  62. package/dist/commands/sessions/start.js.map +1 -1
  63. package/dist/commands/signals/report.d.ts +10 -0
  64. package/dist/commands/signals/report.d.ts.map +1 -0
  65. package/dist/commands/signals/report.js +35 -0
  66. package/dist/commands/signals/report.js.map +1 -0
  67. package/dist/commands/signals/report.test.d.ts +2 -0
  68. package/dist/commands/signals/report.test.d.ts.map +1 -0
  69. package/dist/commands/signals/report.test.js +65 -0
  70. package/dist/commands/signals/report.test.js.map +1 -0
  71. package/dist/commands/skills/export-approved.d.ts +10 -0
  72. package/dist/commands/skills/export-approved.d.ts.map +1 -0
  73. package/dist/commands/skills/export-approved.js +31 -0
  74. package/dist/commands/skills/export-approved.js.map +1 -0
  75. package/dist/commands/skills/publish.d.ts +17 -0
  76. package/dist/commands/skills/publish.d.ts.map +1 -0
  77. package/dist/commands/skills/publish.js +80 -0
  78. package/dist/commands/skills/publish.js.map +1 -0
  79. package/dist/commands/skills/update.d.ts +3 -0
  80. package/dist/commands/skills/update.d.ts.map +1 -1
  81. package/dist/commands/skills/update.js +17 -6
  82. package/dist/commands/skills/update.js.map +1 -1
  83. package/dist/commands/suggestions/accept.d.ts +16 -0
  84. package/dist/commands/suggestions/accept.d.ts.map +1 -0
  85. package/dist/commands/suggestions/accept.js +61 -0
  86. package/dist/commands/suggestions/accept.js.map +1 -0
  87. package/dist/commands/suggestions/accept.test.d.ts +2 -0
  88. package/dist/commands/suggestions/accept.test.d.ts.map +1 -0
  89. package/dist/commands/suggestions/accept.test.js +52 -0
  90. package/dist/commands/suggestions/accept.test.js.map +1 -0
  91. package/dist/commands/suggestions/dismiss.d.ts +10 -0
  92. package/dist/commands/suggestions/dismiss.d.ts.map +1 -0
  93. package/dist/commands/suggestions/dismiss.js +26 -0
  94. package/dist/commands/suggestions/dismiss.js.map +1 -0
  95. package/dist/commands/suggestions/list.d.ts +10 -0
  96. package/dist/commands/suggestions/list.d.ts.map +1 -0
  97. package/dist/commands/suggestions/list.js +40 -0
  98. package/dist/commands/suggestions/list.js.map +1 -0
  99. package/dist/commands/suggestions/refresh.d.ts +7 -0
  100. package/dist/commands/suggestions/refresh.d.ts.map +1 -0
  101. package/dist/commands/suggestions/refresh.js +11 -0
  102. package/dist/commands/suggestions/refresh.js.map +1 -0
  103. package/dist/dashboard/Dashboard.d.ts.map +1 -1
  104. package/dist/dashboard/Dashboard.js +7 -1
  105. package/dist/dashboard/Dashboard.js.map +1 -1
  106. package/dist/lib/active-org-refresh.d.ts +22 -0
  107. package/dist/lib/active-org-refresh.d.ts.map +1 -0
  108. package/dist/lib/active-org-refresh.js +108 -0
  109. package/dist/lib/active-org-refresh.js.map +1 -0
  110. package/dist/lib/active-org-refresh.test.d.ts +2 -0
  111. package/dist/lib/active-org-refresh.test.d.ts.map +1 -0
  112. package/dist/lib/active-org-refresh.test.js +190 -0
  113. package/dist/lib/active-org-refresh.test.js.map +1 -0
  114. package/dist/lib/active-org.d.ts +43 -0
  115. package/dist/lib/active-org.d.ts.map +1 -0
  116. package/dist/lib/active-org.js +96 -0
  117. package/dist/lib/active-org.js.map +1 -0
  118. package/dist/lib/active-org.test.d.ts +2 -0
  119. package/dist/lib/active-org.test.d.ts.map +1 -0
  120. package/dist/lib/active-org.test.js +147 -0
  121. package/dist/lib/active-org.test.js.map +1 -0
  122. package/dist/lib/cron-registry.d.ts +47 -0
  123. package/dist/lib/cron-registry.d.ts.map +1 -0
  124. package/dist/lib/cron-registry.js +102 -0
  125. package/dist/lib/cron-registry.js.map +1 -0
  126. package/dist/lib/cron-registry.test.d.ts +2 -0
  127. package/dist/lib/cron-registry.test.d.ts.map +1 -0
  128. package/dist/lib/cron-registry.test.js +136 -0
  129. package/dist/lib/cron-registry.test.js.map +1 -0
  130. package/dist/lib/cron-runner.d.ts +16 -0
  131. package/dist/lib/cron-runner.d.ts.map +1 -0
  132. package/dist/lib/cron-runner.js +68 -0
  133. package/dist/lib/cron-runner.js.map +1 -0
  134. package/dist/lib/detect-languages.d.ts +7 -0
  135. package/dist/lib/detect-languages.d.ts.map +1 -0
  136. package/dist/lib/detect-languages.js +113 -0
  137. package/dist/lib/detect-languages.js.map +1 -0
  138. package/dist/lib/detect-languages.test.d.ts +2 -0
  139. package/dist/lib/detect-languages.test.d.ts.map +1 -0
  140. package/dist/lib/detect-languages.test.js +29 -0
  141. package/dist/lib/detect-languages.test.js.map +1 -0
  142. package/dist/lib/eval-executor.d.ts.map +1 -1
  143. package/dist/lib/eval-executor.js +5 -2
  144. package/dist/lib/eval-executor.js.map +1 -1
  145. package/dist/lib/gateway-entry.js +4 -1
  146. package/dist/lib/gateway-entry.js.map +1 -1
  147. package/dist/lib/gateway-lifecycle.d.ts +1 -1
  148. package/dist/lib/gateway-lifecycle.d.ts.map +1 -1
  149. package/dist/lib/gateway-lifecycle.js +13 -2
  150. package/dist/lib/gateway-lifecycle.js.map +1 -1
  151. package/dist/lib/gateway.d.ts +4 -5
  152. package/dist/lib/gateway.d.ts.map +1 -1
  153. package/dist/lib/gateway.js +68 -2
  154. package/dist/lib/gateway.js.map +1 -1
  155. package/dist/lib/graphile-worker-runner.d.ts +124 -0
  156. package/dist/lib/graphile-worker-runner.d.ts.map +1 -0
  157. package/dist/lib/graphile-worker-runner.js +526 -0
  158. package/dist/lib/graphile-worker-runner.js.map +1 -0
  159. package/dist/lib/graphile-worker-runner.test.d.ts +2 -0
  160. package/dist/lib/graphile-worker-runner.test.d.ts.map +1 -0
  161. package/dist/lib/graphile-worker-runner.test.js +153 -0
  162. package/dist/lib/graphile-worker-runner.test.js.map +1 -0
  163. package/dist/lib/handlers/cron-close-stale-sessions.d.ts +3 -0
  164. package/dist/lib/handlers/cron-close-stale-sessions.d.ts.map +1 -0
  165. package/dist/lib/handlers/cron-close-stale-sessions.js +8 -0
  166. package/dist/lib/handlers/cron-close-stale-sessions.js.map +1 -0
  167. package/dist/lib/handlers/cron-data-integrity-audit.d.ts +3 -0
  168. package/dist/lib/handlers/cron-data-integrity-audit.d.ts.map +1 -0
  169. package/dist/lib/handlers/cron-data-integrity-audit.js +16 -0
  170. package/dist/lib/handlers/cron-data-integrity-audit.js.map +1 -0
  171. package/dist/lib/handlers/cron-refresh-skills.d.ts +3 -0
  172. package/dist/lib/handlers/cron-refresh-skills.d.ts.map +1 -0
  173. package/dist/lib/handlers/cron-refresh-skills.js +91 -0
  174. package/dist/lib/handlers/cron-refresh-skills.js.map +1 -0
  175. package/dist/lib/handlers/cron-refresh-skills.test.d.ts +2 -0
  176. package/dist/lib/handlers/cron-refresh-skills.test.d.ts.map +1 -0
  177. package/dist/lib/handlers/cron-refresh-skills.test.js +114 -0
  178. package/dist/lib/handlers/cron-refresh-skills.test.js.map +1 -0
  179. package/dist/lib/handlers/cron-regenerate-insights.d.ts +3 -0
  180. package/dist/lib/handlers/cron-regenerate-insights.d.ts.map +1 -0
  181. package/dist/lib/handlers/cron-regenerate-insights.js +6 -0
  182. package/dist/lib/handlers/cron-regenerate-insights.js.map +1 -0
  183. package/dist/lib/handlers/cron-suggest-instructions.d.ts +3 -0
  184. package/dist/lib/handlers/cron-suggest-instructions.d.ts.map +1 -0
  185. package/dist/lib/handlers/cron-suggest-instructions.js +159 -0
  186. package/dist/lib/handlers/cron-suggest-instructions.js.map +1 -0
  187. package/dist/lib/handlers/cron-suggest-instructions.test.d.ts +2 -0
  188. package/dist/lib/handlers/cron-suggest-instructions.test.d.ts.map +1 -0
  189. package/dist/lib/handlers/cron-suggest-instructions.test.js +80 -0
  190. package/dist/lib/handlers/cron-suggest-instructions.test.js.map +1 -0
  191. package/dist/lib/handlers/process-conversation.d.ts +35 -0
  192. package/dist/lib/handlers/process-conversation.d.ts.map +1 -0
  193. package/dist/lib/handlers/process-conversation.js +35 -0
  194. package/dist/lib/handlers/process-conversation.js.map +1 -0
  195. package/dist/lib/handlers/process-eval.d.ts +32 -0
  196. package/dist/lib/handlers/process-eval.d.ts.map +1 -0
  197. package/dist/lib/handlers/process-eval.js +207 -0
  198. package/dist/lib/handlers/process-eval.js.map +1 -0
  199. package/dist/lib/handlers/process-insights.d.ts +39 -0
  200. package/dist/lib/handlers/process-insights.d.ts.map +1 -0
  201. package/dist/lib/handlers/process-insights.js +300 -0
  202. package/dist/lib/handlers/process-insights.js.map +1 -0
  203. package/dist/lib/handlers/process-launch.d.ts +29 -0
  204. package/dist/lib/handlers/process-launch.d.ts.map +1 -0
  205. package/dist/lib/handlers/process-launch.js +41 -0
  206. package/dist/lib/handlers/process-launch.js.map +1 -0
  207. package/dist/lib/hooks-config.d.ts +28 -4
  208. package/dist/lib/hooks-config.d.ts.map +1 -1
  209. package/dist/lib/hooks-config.js +138 -10
  210. package/dist/lib/hooks-config.js.map +1 -1
  211. package/dist/lib/llm-client.d.ts.map +1 -1
  212. package/dist/lib/llm-client.js +149 -16
  213. package/dist/lib/llm-client.js.map +1 -1
  214. package/dist/lib/mirror-writer-db.d.ts +12 -0
  215. package/dist/lib/mirror-writer-db.d.ts.map +1 -0
  216. package/dist/lib/mirror-writer-db.js +51 -0
  217. package/dist/lib/mirror-writer-db.js.map +1 -0
  218. package/dist/lib/mirror-writer.d.ts +35 -0
  219. package/dist/lib/mirror-writer.d.ts.map +1 -0
  220. package/dist/lib/mirror-writer.js +27 -0
  221. package/dist/lib/mirror-writer.js.map +1 -0
  222. package/dist/lib/mirror-writer.test.d.ts +2 -0
  223. package/dist/lib/mirror-writer.test.d.ts.map +1 -0
  224. package/dist/lib/mirror-writer.test.js +47 -0
  225. package/dist/lib/mirror-writer.test.js.map +1 -0
  226. package/dist/lib/permanent-job-error.d.ts +17 -0
  227. package/dist/lib/permanent-job-error.d.ts.map +1 -0
  228. package/dist/lib/permanent-job-error.js +23 -0
  229. package/dist/lib/permanent-job-error.js.map +1 -0
  230. package/dist/lib/permanent-job-error.test.d.ts +2 -0
  231. package/dist/lib/permanent-job-error.test.d.ts.map +1 -0
  232. package/dist/lib/permanent-job-error.test.js +29 -0
  233. package/dist/lib/permanent-job-error.test.js.map +1 -0
  234. package/dist/lib/version-check.d.ts +11 -0
  235. package/dist/lib/version-check.d.ts.map +1 -0
  236. package/dist/lib/version-check.js +106 -0
  237. package/dist/lib/version-check.js.map +1 -0
  238. package/oclif.manifest.json +611 -81
  239. package/package.json +19 -5
  240. package/dist/commands/insights/sync.d.ts +0 -17
  241. package/dist/commands/insights/sync.d.ts.map +0 -1
  242. package/dist/commands/insights/sync.js +0 -477
  243. package/dist/commands/insights/sync.js.map +0 -1
  244. package/dist/lib/eval-worker.d.ts +0 -12
  245. package/dist/lib/eval-worker.d.ts.map +0 -1
  246. package/dist/lib/eval-worker.js +0 -395
  247. package/dist/lib/eval-worker.js.map +0 -1
  248. package/dist/lib/insights-worker.d.ts +0 -10
  249. package/dist/lib/insights-worker.d.ts.map +0 -1
  250. package/dist/lib/insights-worker.js +0 -329
  251. package/dist/lib/insights-worker.js.map +0 -1
@@ -0,0 +1,526 @@
1
+ // apps/cli/src/lib/graphile-worker-runner.ts
2
+ //
3
+ // Central worker orchestration: registers the four task handlers, wires
4
+ // `runner.events` so each lifecycle event (job:start/success/error/failed)
5
+ // translates into a mirror-row update via `applyMirrorUpdate`, and runs an
6
+ // in-process heartbeat that carries `currentJobId` + `lastError` so the
7
+ // dashboard can detect hung workers.
8
+ //
9
+ // The heartbeat is started BEFORE `await run(...)` resolves — this is the
10
+ // cold-start fix from the design doc: a worker that boots but takes a few
11
+ // seconds to claim its first job should still show up as alive in the
12
+ // dashboard during that window.
13
+ //
14
+ // Cron tasks are intentionally absent here — they're added in Tasks 17/18.
15
+ import { execFile } from 'node:child_process';
16
+ import * as fs from 'node:fs';
17
+ import { promisify } from 'node:util';
18
+ const execFileAsync = promisify(execFile);
19
+ import os from 'node:os';
20
+ import { run } from 'graphile-worker';
21
+ import postgres from 'postgres';
22
+ import { captureException as sentryCaptureException } from '@rulemetric/telemetry';
23
+ import { apiPost } from './api-client.js';
24
+ import { CRON_REGISTRY, wrapCronWithEnvelope } from './cron-registry.js';
25
+ import { processConversation } from './handlers/process-conversation.js';
26
+ import { processEval } from './handlers/process-eval.js';
27
+ import { processInsights } from './handlers/process-insights.js';
28
+ import { processLaunch } from './handlers/process-launch.js';
29
+ import { jobToMirrorUpdate } from './mirror-writer.js';
30
+ import { applyMirrorUpdate, isMirrorTask } from './mirror-writer-db.js';
31
+ import { isPermanentJobError } from './permanent-job-error.js';
32
+ // Watchdog thresholds. Heartbeat runs every 30s, so 5 consecutive failures =
33
+ // ~2.5 min of API unreachable. The pg-listen threshold is 3 min without a
34
+ // successful LISTEN connection, which is well past graphile-worker's own
35
+ // reconnect backoff (caps around 30s) — so by the time we trip, recovery has
36
+ // genuinely failed rather than just being slow.
37
+ const HEARTBEAT_FAILURE_LIMIT = 5;
38
+ const LISTEN_DEAD_THRESHOLD_MS = 180_000;
39
+ const WATCHDOG_INTERVAL_MS = 30_000;
40
+ /**
41
+ * Pure decision function: given watchdog state and "now", return a fatal
42
+ * reason string if the worker should exit, or null if it's healthy. Extracted
43
+ * so the threshold logic can be unit-tested without booting graphile-worker
44
+ * or stubbing process.exit.
45
+ */
46
+ export function watchdogVerdict(_state, _now) {
47
+ // No process-exit paths. Both signals previously routed here (heartbeat
48
+ // failure and pg LISTEN dead) fire reliably during Supavisor pool pressure
49
+ // even when the worker itself is healthy — exiting turned transient outages
50
+ // into launchd respawn loops whose replacements stacked sockets onto an
51
+ // already-saturated pooler (EMAXCONN cascade; see scripts/repro-pool-cascade.sh
52
+ // injections C and D). Visibility now comes from three places that don't
53
+ // require suicide: (a) heartbeat `lastError` surfaces both conditions to the
54
+ // dashboard, (b) the server-side mirror reconciler flips stuck mirror rows
55
+ // to `failed` after 60s, (c) `unhandledRejection` swallows known transient
56
+ // pg errors instead of letting Node terminate. Kept as a function so test
57
+ // coverage of "does NOT exit under X" stays explicit.
58
+ return null;
59
+ }
60
+ /**
61
+ * Derive a short status string from watchdog state for `lastError` reporting.
62
+ * Returns null when nothing notable; otherwise a human-readable signal the
63
+ * dashboard can surface (e.g. "pg listen has been failing for 240s"). This is
64
+ * the logged-signal replacement for the old exit paths.
65
+ */
66
+ export function watchdogStatus(state, now) {
67
+ if (state.lastListenErrorAt !== null) {
68
+ const lastGood = state.lastListenSuccessAt ?? 0;
69
+ if (state.lastListenErrorAt > lastGood && now - state.lastListenErrorAt > LISTEN_DEAD_THRESHOLD_MS) {
70
+ return `pg listen has been failing for ${Math.round((now - state.lastListenErrorAt) / 1000)}s`;
71
+ }
72
+ }
73
+ if (state.consecutiveHeartbeatFailures >= HEARTBEAT_FAILURE_LIMIT) {
74
+ return `heartbeat has failed ${state.consecutiveHeartbeatFailures} consecutive times`;
75
+ }
76
+ return null;
77
+ }
78
+ /**
79
+ * Coerce graphile-worker's `error: unknown` payload into a string for
80
+ * `lastError` reporting. Walks `.cause` so a wrapped pg/graphile error still
81
+ * surfaces its underlying message — important for the unhandledRejection
82
+ * swallow regex, which would otherwise miss errors thrown as
83
+ * `new Error("...", { cause: original })`.
84
+ */
85
+ function errorMessage(err, depth = 0) {
86
+ if (depth > 4)
87
+ return '';
88
+ if (err instanceof Error) {
89
+ const cause = err.cause;
90
+ return cause !== undefined ? `${err.message} | cause: ${errorMessage(cause, depth + 1)}` : err.message;
91
+ }
92
+ if (typeof err === 'string')
93
+ return err;
94
+ try {
95
+ return JSON.stringify(err);
96
+ }
97
+ catch {
98
+ return String(err);
99
+ }
100
+ }
101
+ /**
102
+ * Parse `lsof -i TCP -P -n` output into a count of established sockets to the
103
+ * Supabase pooler, grouped by remote host.
104
+ *
105
+ * Matches BOTH pooler ports: 6543 (transaction mode) and 5432 (session mode).
106
+ * The worker connects through the session pooler — see deriveSessionPoolerUrl
107
+ * in commands/evals/listen.ts — while the API uses the transaction pooler; a
108
+ * counter that matched only :6543 would silently report 0 sockets for every
109
+ * worker. The `->` anchor is load-bearing: it matches the REMOTE port, not a
110
+ * local source port that happens to share those digits.
111
+ */
112
+ export function parsePoolerSockets(lsofStdout) {
113
+ const byNode = {};
114
+ let total = 0;
115
+ for (const line of lsofStdout.split('\n')) {
116
+ const m = line.match(/->([\d.]+|\[[^\]]+\]):(?:6543|5432)\b/);
117
+ if (m) {
118
+ const host = m[1].replace(/^\[|\]$/g, '');
119
+ byNode[host] = (byNode[host] ?? 0) + 1;
120
+ total += 1;
121
+ }
122
+ }
123
+ return { total, byNode };
124
+ }
125
+ /**
126
+ * Release stale Graphile job locks owned by this worker's user.
127
+ *
128
+ * The graphile_worker._private_jobs table tracks in-flight jobs via
129
+ * `locked_at`/`locked_by`. When a worker crashes mid-job (SIGKILL, OOM, the
130
+ * 10s graceful-shutdown timeout in evals/listen.ts forcing exit before
131
+ * graphile can release locks) those fields stay populated — and graphile's
132
+ * built-in lock-timeout sweeper only reclaims them after a 4-hour TTL by
133
+ * default. Until that fires, the job is invisible to every worker: it's not
134
+ * `available`, but no one is actually running it.
135
+ *
136
+ * At worker BOOT we know that no jobs belonging to OUR user are legitimately
137
+ * in flight (the previous instance is dead — that's why we're starting). Any
138
+ * lock on a task identifier ending `__<userId>` is therefore stale and safe
139
+ * to clear. We scope by suffix so multiple users on a shared pooler don't
140
+ * accidentally release each other's live locks.
141
+ *
142
+ * Best-effort: a thrown executor error is logged but swallowed. If reclaim
143
+ * fails, graphile's 4h timeout still kicks in eventually, and crippling
144
+ * worker startup over a transient DB hiccup is worse than waiting it out.
145
+ *
146
+ * Returns the count of rows released (0 on error or no-op).
147
+ */
148
+ export async function reclaimStaleLocks(exec, userId, log) {
149
+ try {
150
+ const rows = await exec(`UPDATE graphile_worker._private_jobs j
151
+ SET locked_at = NULL, locked_by = NULL
152
+ FROM graphile_worker._private_tasks t
153
+ WHERE j.task_id = t.id
154
+ AND t.identifier LIKE $1
155
+ AND j.locked_at IS NOT NULL
156
+ RETURNING j.id, t.identifier`, [`%__${userId}`]);
157
+ if (rows.length > 0) {
158
+ const summary = rows.map((r) => `${r.identifier}#${r.id}`).join(', ');
159
+ log(`[startup] reclaimed ${rows.length} stale lock(s): ${summary}`);
160
+ }
161
+ return rows.length;
162
+ }
163
+ catch (err) {
164
+ log(`[startup] stale-lock reclaim failed (non-fatal, graphile's 4h timeout will eventually free these): ${err instanceof Error ? err.message : String(err)}`);
165
+ return 0;
166
+ }
167
+ }
168
+ /**
169
+ * Wrap a typed handler so it conforms to graphile-worker's `Task` shape AND
170
+ * intercepts `PermanentJobError` to skip retry waste.
171
+ *
172
+ * How the skip works: graphile-worker decides retry-vs-permanent-fail by
173
+ * comparing `job.attempts >= job.max_attempts` on the in-memory `Job` object
174
+ * AFTER the handler throws (see graphile-worker dist/worker.js). We mutate
175
+ * `helpers.job.max_attempts` to equal the current attempt count just before
176
+ * re-throwing — that flips the inequality so Graphile emits `job:failed`
177
+ * instead of scheduling another retry. The mutation is purely in JS memory;
178
+ * Graphile uses the in-memory `Job` object for its decision and never re-reads
179
+ * `max_attempts` from the DB on this code path, so a SQL update isn't needed.
180
+ *
181
+ * Exported for use in integration tests that want the same retry-skip behavior
182
+ * the runner applies in production.
183
+ */
184
+ export function makeTask(handler) {
185
+ return (async (payload, helpers) => {
186
+ try {
187
+ await handler(payload, helpers);
188
+ }
189
+ catch (err) {
190
+ if (isPermanentJobError(err)) {
191
+ // Mutate the in-memory job so Graphile's post-throw retry-vs-fail
192
+ // check (`job.attempts >= job.max_attempts`) sees us at the cap.
193
+ const job = helpers.job;
194
+ job.max_attempts = job.attempts;
195
+ }
196
+ throw err;
197
+ }
198
+ });
199
+ }
200
+ /**
201
+ * Boot a graphile-worker runner with the four task handlers wired up.
202
+ *
203
+ * Returns a cleanup function that:
204
+ * 1. clears the heartbeat interval
205
+ * 2. fires a final `status: 'shutting_down'` heartbeat so the dashboard
206
+ * can show a clean shutdown rather than a missed-heartbeat timeout
207
+ * 3. awaits `runner.stop()` for graceful drain (in-flight jobs finish)
208
+ */
209
+ export async function startWorker(options) {
210
+ const { connectionString, log, userId } = options;
211
+ // onFatal kept on the options interface for back-compat with callers/tests,
212
+ // but the runner no longer invokes it. All "fatal" signals are reported via
213
+ // heartbeat lastError and the server-side reconciler instead — see
214
+ // watchdogStatus and the comment on watchdogVerdict.
215
+ void options.onFatal;
216
+ const now = options.now ?? Date.now;
217
+ // Stable worker identity: hostname only, NOT including process.pid. Each
218
+ // PID change (restart, --force install, dev iteration) used to create a
219
+ // fresh row in worker_connections, leaving "ghost" entries forever in the
220
+ // dashboard. The heartbeat endpoint UPSERTs by (userId, workerType,
221
+ // clientName) — so collapsing clientName to hostname means one row per
222
+ // host per workerType, regardless of restart count.
223
+ const workerId = os.hostname();
224
+ // Survive graphile-worker's unhandled rejections. The cron scheduler
225
+ // (graphile-worker/dist/cron.js scheduleCronJobs) and the internal worker's
226
+ // completeJob path can throw `(EMAXCONN)` or `Connection terminated
227
+ // unexpectedly` when the Supavisor pool is briefly saturated. Neither path
228
+ // catches its own throw, so Node's default unhandledRejection behavior
229
+ // terminates the process — turning a 30-second transient into an indefinite
230
+ // launchd-restart loop. Reproduction: scripts/repro-pool-cascade.sh D
231
+ // (150 psql sleeps + API down) produces "Failed to release job ...;
232
+ // committing seppuku\nConnection terminated unexpectedly" without these
233
+ // listeners. With them, graphile-worker logs the error and reschedules.
234
+ const pgErrorPattern = /EMAXCONN|Connection terminated|EAUTHTIMEOUT|ECONNRESET|getaddrinfo/i;
235
+ const onUnhandled = (reason) => {
236
+ const msg = errorMessage(reason);
237
+ if (pgErrorPattern.test(msg)) {
238
+ log(`[recovered] transient pool error swallowed: ${msg.slice(0, 200)}`);
239
+ return;
240
+ }
241
+ // Re-throw non-pool errors via the default behavior so real bugs aren't
242
+ // hidden. Setting exitCode lets the runtime decide.
243
+ log(`unhandledRejection (not pool-related): ${msg}`);
244
+ process.exitCode = 1;
245
+ };
246
+ process.on('unhandledRejection', onUnhandled);
247
+ process.on('uncaughtException', onUnhandled);
248
+ const inFlight = new Map();
249
+ // `lastError` surfaces the most recent error from any job for dashboard
250
+ // display — distinct from the per-job `lastError` stored on the Map
251
+ // entry, which is keyed for cleanup but not currently surfaced.
252
+ let lastError = null;
253
+ const mostRecentEntry = () => {
254
+ let last;
255
+ for (const value of inFlight.values())
256
+ last = value;
257
+ return last;
258
+ };
259
+ const watchdog = {
260
+ consecutiveHeartbeatFailures: 0,
261
+ lastListenSuccessAt: null,
262
+ lastListenErrorAt: null,
263
+ };
264
+ // What this worker can claim. Reported on every heartbeat in
265
+ // `metadata.capabilities` so the API can warn when the set drifts from
266
+ // EXPECTED_WORKER_CAPABILITIES['cli-worker'] (apps/api/src/routes/worker-status.ts).
267
+ // Use bare task kinds, not the user-suffixed task names — the server's
268
+ // expected set is `['eval','insights','launch','conversation']`.
269
+ const CAPABILITIES = ['eval', 'insights', 'launch', 'conversation'];
270
+ // De-dupe advisory log lines: server returns the same advisory on every
271
+ // 30s heartbeat, so log only when the message changes (and re-log on
272
+ // recovery from advisory → no advisory).
273
+ let lastLoggedAdvisoryMessage = null;
274
+ const lsofBin = ['/usr/sbin/lsof', '/usr/bin/lsof', '/bin/lsof'].find((p) => fs.existsSync(p)) ?? 'lsof';
275
+ // Fully async: previously this was execFileSync, which can block the event
276
+ // loop for up to the 3s timeout under fork()/process-table contention —
277
+ // exactly the conditions present during Supavisor pool saturation. Blocking
278
+ // the heartbeat tick on lsof would delay the very heartbeat that's supposed
279
+ // to surface the pool-saturation state. Fire-and-forget: never awaited by
280
+ // sendHeartbeat, errors swallowed, no impact on job processing or watchdog.
281
+ const sendPoolerSelfReport = async () => {
282
+ try {
283
+ const { stdout } = await execFileAsync(lsofBin, ['-a', '-p', String(process.pid), '-i', 'TCP', '-P', '-n'], { encoding: 'utf8', timeout: 3000 });
284
+ const { total, byNode } = parsePoolerSockets(stdout);
285
+ await apiPost('/api/diag/pg-health/self-report', {
286
+ process: process.env.PG_APPLICATION_NAME ?? 'rulemetric-worker',
287
+ pid: process.pid,
288
+ pool_max: Number(process.env.PG_POOL_MAX) || 3,
289
+ pooler_sockets: total,
290
+ pooler_sockets_by_node: byNode,
291
+ }).catch(() => null);
292
+ }
293
+ catch {
294
+ // Swallow: lsof binary missing, timeout, permission denied, etc. all
295
+ // mean "no telemetry this tick" — never block job processing.
296
+ }
297
+ };
298
+ const sendHeartbeat = (status = 'alive') => {
299
+ void sendPoolerSelfReport();
300
+ const entry = mostRecentEntry();
301
+ // Merge watchdog status into lastError so the dashboard surfaces wedge
302
+ // conditions (stuck LISTEN, persistent heartbeat failures) without us
303
+ // having to exit the process. lastError already captures the most recent
304
+ // job-level failure; watchdog status takes precedence when present
305
+ // because it indicates a process-level issue the user should see.
306
+ const wdStatus = watchdogStatus(watchdog, now());
307
+ const reportedError = wdStatus ?? lastError;
308
+ return apiPost('/api/workers/heartbeat', {
309
+ workerType: 'cli-worker',
310
+ clientName: workerId,
311
+ workerVersion: '0.1.0',
312
+ currentJobId: entry?.mirrorId ?? null,
313
+ inFlightCount: inFlight.size,
314
+ lastError: reportedError,
315
+ status,
316
+ metadata: { capabilities: CAPABILITIES },
317
+ }).then((result) => {
318
+ watchdog.consecutiveHeartbeatFailures = 0;
319
+ const advisory = result?.advisory;
320
+ if (advisory) {
321
+ if (advisory.message !== lastLoggedAdvisoryMessage) {
322
+ log(`heartbeat advisory [${advisory.code}]: ${advisory.message}`);
323
+ lastLoggedAdvisoryMessage = advisory.message;
324
+ }
325
+ }
326
+ else if (lastLoggedAdvisoryMessage !== null) {
327
+ log('heartbeat advisory cleared');
328
+ lastLoggedAdvisoryMessage = null;
329
+ }
330
+ return result;
331
+ }, (err) => {
332
+ watchdog.consecutiveHeartbeatFailures += 1;
333
+ log(`heartbeat failed: ${errorMessage(err)}`);
334
+ });
335
+ };
336
+ // Cold-start fix: start the heartbeat BEFORE awaiting run(). If `run()`
337
+ // takes a few seconds to settle (initial schema check, LISTEN setup),
338
+ // the worker still appears alive in the dashboard during that window.
339
+ void sendHeartbeat();
340
+ const heartbeatTimer = setInterval(() => {
341
+ void sendHeartbeat();
342
+ }, 30_000);
343
+ // Tag this pool's connections so they show up distinctly in pg_stat_activity
344
+ // (separate from the postgres-js pool inside getDb()).
345
+ const taggedConnectionString = (() => {
346
+ try {
347
+ const u = new URL(connectionString);
348
+ if (!u.searchParams.has('application_name')) {
349
+ u.searchParams.set('application_name', 'rulemetric-worker-graphile');
350
+ }
351
+ return u.toString();
352
+ }
353
+ catch {
354
+ return connectionString;
355
+ }
356
+ })();
357
+ const runnerOptions = {
358
+ connectionString: taggedConnectionString,
359
+ // After SIGTERM/SIGINT, graphile-worker waits for in-flight jobs to drain
360
+ // before resolving runner.stop(). With handlers that spawn `claude`
361
+ // subprocesses (insights, cron_suggest_instructions), the drain can take
362
+ // minutes. Cap it at 5s so graphile triggers its forcefulShutdown path
363
+ // and runner.stop() resolves promptly. The outer SIGTERM handler in
364
+ // evals/listen.ts wraps this in a 10s process-level timeout too, so even
365
+ // if graphile's force-abort hangs, the worker dies cleanly.
366
+ gracefulShutdownAbortTimeout: 5_000,
367
+ // PgBouncer transaction-mode (Supabase pooler) doesn't share prepared statements across pooled connections — disable to avoid "prepared statement already exists" crashes.
368
+ noPreparedStatements: true,
369
+ // Cap concurrent jobs across all task types. This replaces the global
370
+ // `processing` flag in the legacy worker — Graphile handles fairness
371
+ // and per-task ordering automatically.
372
+ concurrency: 4,
373
+ // Per-user task names — both work tasks (process_*) AND cron tasks. The
374
+ // Graphile queue is global; the suffix is what makes each laptop only
375
+ // claim its own user's jobs. Cron tasks need the suffix too because
376
+ // cron handlers POST to API endpoints that scope by `c.get('userId')` —
377
+ // an unsuffixed cron would be claimed by whichever worker polls first
378
+ // and would only regenerate THAT user's data, leaving every other user
379
+ // without cron-driven updates. With the suffix, each laptop independently
380
+ // schedules and claims its own user's crons. Cost: a user whose laptop is
381
+ // offline at 4am misses that day's skills refresh until they boot back up.
382
+ taskList: {
383
+ [`process_eval__${userId}`]: makeTask(processEval),
384
+ [`process_insights__${userId}`]: makeTask(processInsights),
385
+ [`process_launch__${userId}`]: makeTask(processLaunch),
386
+ [`process_conversation__${userId}`]: makeTask(processConversation),
387
+ // Wrap each cron in `wrapCronWithEnvelope` so we get a uniform
388
+ // `[cron <name>] start/ok/failed` log envelope on every fire. The
389
+ // per-handler progress lines stay as-is — the envelope just bookends.
390
+ // Added 2026-05-21 after the eight-fix arc made it obvious that
391
+ // half the crons logged ad-hoc start lines and none logged duration.
392
+ ...Object.fromEntries(CRON_REGISTRY.map((c) => [`${c.name}__${userId}`, wrapCronWithEnvelope(c.name, c.handler)])),
393
+ },
394
+ // `?jobKey=cron-<task>__<userId>` dedupes cron-scheduled jobs in graphile's
395
+ // queue. Without it, every worker restart / missed scheduling could leave
396
+ // duplicates: we observed 3 simultaneous `cron_refresh_skills` rows with
397
+ // the same run_at, each locked by a different internal-worker slot — they
398
+ // saturated concurrency=4 and starved user-facing launches. With jobKey
399
+ // (and the default jobKeyMode='replace'), a subsequent scheduled fire
400
+ // replaces any existing queued job of the same key instead of accumulating.
401
+ // Diagnosed 2026-05-20.
402
+ crontab: CRON_REGISTRY.map((c) => `${c.schedule} ${c.name}__${userId} ?jobKey=cron-${c.name}__${userId}`).join('\n') + '\n',
403
+ };
404
+ // Reclaim stale locks BEFORE booting the runner. When the previous worker
405
+ // instance dies hard (SIGKILL, OOM, the 10s shutdown-grace timeout in
406
+ // evals/listen.ts forcing exit before graphile released locks) the jobs
407
+ // it was holding stay marked `is_available = false AND locked_at IS NOT NULL`
408
+ // — graphile's built-in lock-timeout reclaim only kicks in after a 4h TTL.
409
+ // We know no jobs of OUR user are legitimately in flight at boot (this
410
+ // process IS the user's worker; the previous one is dead). Scoping by
411
+ // `__<userId>` suffix keeps multi-tenant pools safe.
412
+ // See reclaimStaleLocks() for the SQL + rationale.
413
+ {
414
+ const sql = postgres(taggedConnectionString, { max: 1, prepare: false, idle_timeout: 5 });
415
+ try {
416
+ await reclaimStaleLocks(async (text, params) => (await sql.unsafe(text, params)), userId, log);
417
+ }
418
+ finally {
419
+ await sql.end({ timeout: 5 }).catch(() => { });
420
+ }
421
+ }
422
+ const runner = await run(runnerOptions);
423
+ // Each event listener is fire-and-forget on the mirror write. We don't
424
+ // want a transient API blip to break the worker — `applyMirrorUpdate`
425
+ // already retries once internally, and Graphile's own job state is the
426
+ // source of truth regardless.
427
+ //
428
+ // The in-flight Map is keyed by the Graphile job id (numeric, unique
429
+ // per job) so that concurrent jobs don't trample each other's entries.
430
+ // We re-set on `start` so the most-recent insertion order reflects what
431
+ // started last, and delete on success/failed (terminal states).
432
+ // Cron tasks flow through the same runner.events stream as mirror-backed
433
+ // tasks, but they have no mirror row and no entry in ENDPOINTS — short-
434
+ // circuit so they don't fire bogus `/api/.../undefined/state` requests.
435
+ const onStart = ({ job }) => {
436
+ const payload = job.payload;
437
+ const mirrorId = payload.mirrorId ?? String(job.id);
438
+ inFlight.delete(Number(job.id));
439
+ inFlight.set(Number(job.id), { mirrorId });
440
+ if (!isMirrorTask(job.task_identifier))
441
+ return;
442
+ void applyMirrorUpdate(job.task_identifier, jobToMirrorUpdate('job:start', job), log);
443
+ };
444
+ const onSuccess = ({ job }) => {
445
+ inFlight.delete(Number(job.id));
446
+ if (inFlight.size === 0)
447
+ lastError = null;
448
+ if (!isMirrorTask(job.task_identifier))
449
+ return;
450
+ void applyMirrorUpdate(job.task_identifier, jobToMirrorUpdate('job:success', job), log);
451
+ };
452
+ const onError = ({ job, error }) => {
453
+ // Don't remove from inFlight here — the job may still be in-flight
454
+ // if Graphile decides to retry. We only delete on success/failed.
455
+ const message = errorMessage(error);
456
+ lastError = message;
457
+ const entry = inFlight.get(Number(job.id));
458
+ if (entry)
459
+ entry.lastError = message;
460
+ if (!isMirrorTask(job.task_identifier))
461
+ return;
462
+ void applyMirrorUpdate(job.task_identifier, jobToMirrorUpdate('job:error', job), log);
463
+ };
464
+ const onFailed = ({ job, error }) => {
465
+ inFlight.delete(Number(job.id));
466
+ lastError = errorMessage(error);
467
+ // Forward to Sentry with tags that make dashboard filtering useful.
468
+ // `job:failed` fires only after attempts >= max_attempts, so every event
469
+ // here represents a real terminal failure — exactly the signal we want
470
+ // to alert on. The mirrorId is the row in eval_jobs / insights_jobs /
471
+ // launch_jobs that's about to be flipped to `failed`. Crons have no
472
+ // mirror row; for them `mirrorId` is the graphile job id (best we have).
473
+ const payload = (job.payload ?? {});
474
+ sentryCaptureException(error, {
475
+ tags: {
476
+ taskName: job.task_identifier,
477
+ source: 'graphile-worker',
478
+ },
479
+ extra: {
480
+ graphileJobId: String(job.id),
481
+ mirrorId: payload.mirrorId ?? null,
482
+ attempts: job.attempts,
483
+ maxAttempts: job.max_attempts,
484
+ },
485
+ });
486
+ if (!isMirrorTask(job.task_identifier))
487
+ return;
488
+ void applyMirrorUpdate(job.task_identifier, jobToMirrorUpdate('job:failed', job), log);
489
+ };
490
+ runner.events.on('job:start', onStart);
491
+ runner.events.on('job:success', onSuccess);
492
+ runner.events.on('job:error', onError);
493
+ runner.events.on('job:failed', onFailed);
494
+ // Watchdog signals — observed during the 2026-05-06 wedge, where the
495
+ // PG pool listener died ("Connection terminated unexpectedly" repeating)
496
+ // and the worker stayed alive but stopped polling for ~9 hours.
497
+ runner.events.on('pool:listen:success', () => {
498
+ watchdog.lastListenSuccessAt = now();
499
+ });
500
+ runner.events.on('pool:listen:error', ({ error }) => {
501
+ watchdog.lastListenErrorAt = now();
502
+ log(`pool:listen:error: ${errorMessage(error)}`);
503
+ });
504
+ // Watchdog tick: previously this called onFatal(reason) → process.exit(1).
505
+ // That path was the cascade root cause — see watchdogVerdict comment. The
506
+ // tick now only logs persistent wedge conditions so they show up in
507
+ // stderr alongside the heartbeat-reported status. Kept as a tick (rather
508
+ // than dropped) because logging on a separate cadence from the 30s
509
+ // heartbeat helps operators see whether a condition is sticky or transient
510
+ // when correlating timestamps.
511
+ const watchdogTimer = setInterval(() => {
512
+ const status = watchdogStatus(watchdog, now());
513
+ if (status)
514
+ log(`[watchdog] ${status}`);
515
+ }, WATCHDOG_INTERVAL_MS);
516
+ log(`Worker ${workerId} listening for user ${userId} jobs (eval, insights, launch, conversation)`);
517
+ return async () => {
518
+ clearInterval(heartbeatTimer);
519
+ clearInterval(watchdogTimer);
520
+ process.off('unhandledRejection', onUnhandled);
521
+ process.off('uncaughtException', onUnhandled);
522
+ await sendHeartbeat('shutting_down');
523
+ await runner.stop();
524
+ };
525
+ }
526
+ //# sourceMappingURL=graphile-worker-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphile-worker-runner.js","sourceRoot":"","sources":["../../src/lib/graphile-worker-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=graphile-worker-runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphile-worker-runner.test.d.ts","sourceRoot":"","sources":["../../src/lib/graphile-worker-runner.test.ts"],"names":[],"mappings":""}