@shipfox/api-runners 2.0.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 (465) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-type$colon$emit.log +1 -0
  3. package/.turbo/turbo-type.log +1 -0
  4. package/CHANGELOG.md +187 -0
  5. package/LICENSE +21 -0
  6. package/dist/config.d.ts +30 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +208 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/core/demand.d.ts +33 -0
  11. package/dist/core/demand.d.ts.map +1 -0
  12. package/dist/core/demand.js +169 -0
  13. package/dist/core/demand.js.map +1 -0
  14. package/dist/core/entities/ephemeral-registration-token.d.ts +14 -0
  15. package/dist/core/entities/ephemeral-registration-token.d.ts.map +1 -0
  16. package/dist/core/entities/ephemeral-registration-token.js +3 -0
  17. package/dist/core/entities/ephemeral-registration-token.js.map +1 -0
  18. package/dist/core/entities/manual-registration-token.d.ts +12 -0
  19. package/dist/core/entities/manual-registration-token.d.ts.map +1 -0
  20. package/dist/core/entities/manual-registration-token.js +3 -0
  21. package/dist/core/entities/manual-registration-token.js.map +1 -0
  22. package/dist/core/entities/provisioned-runner.d.ts +24 -0
  23. package/dist/core/entities/provisioned-runner.d.ts.map +1 -0
  24. package/dist/core/entities/provisioned-runner.js +3 -0
  25. package/dist/core/entities/provisioned-runner.js.map +1 -0
  26. package/dist/core/entities/provisioner-token.d.ts +18 -0
  27. package/dist/core/entities/provisioner-token.d.ts.map +1 -0
  28. package/dist/core/entities/provisioner-token.js +3 -0
  29. package/dist/core/entities/provisioner-token.js.map +1 -0
  30. package/dist/core/entities/reservation.d.ts +10 -0
  31. package/dist/core/entities/reservation.d.ts.map +1 -0
  32. package/dist/core/entities/reservation.js +3 -0
  33. package/dist/core/entities/reservation.js.map +1 -0
  34. package/dist/core/entities/runner-session.d.ts +18 -0
  35. package/dist/core/entities/runner-session.d.ts.map +1 -0
  36. package/dist/core/entities/runner-session.js +3 -0
  37. package/dist/core/entities/runner-session.js.map +1 -0
  38. package/dist/core/ephemeral-registration-tokens.d.ts +31 -0
  39. package/dist/core/ephemeral-registration-tokens.d.ts.map +1 -0
  40. package/dist/core/ephemeral-registration-tokens.js +61 -0
  41. package/dist/core/ephemeral-registration-tokens.js.map +1 -0
  42. package/dist/core/errors.d.ts +62 -0
  43. package/dist/core/errors.d.ts.map +1 -0
  44. package/dist/core/errors.js +92 -0
  45. package/dist/core/errors.js.map +1 -0
  46. package/dist/core/index.d.ts +14 -0
  47. package/dist/core/index.d.ts.map +1 -0
  48. package/dist/core/index.js +10 -0
  49. package/dist/core/index.js.map +1 -0
  50. package/dist/core/job-executions.d.ts +14 -0
  51. package/dist/core/job-executions.d.ts.map +1 -0
  52. package/dist/core/job-executions.js +37 -0
  53. package/dist/core/job-executions.js.map +1 -0
  54. package/dist/core/maintenance-policy.d.ts +2 -0
  55. package/dist/core/maintenance-policy.d.ts.map +1 -0
  56. package/dist/core/maintenance-policy.js +3 -0
  57. package/dist/core/maintenance-policy.js.map +1 -0
  58. package/dist/core/maintenance.d.ts +33 -0
  59. package/dist/core/maintenance.d.ts.map +1 -0
  60. package/dist/core/maintenance.js +55 -0
  61. package/dist/core/maintenance.js.map +1 -0
  62. package/dist/core/manual-registration-tokens.d.ts +17 -0
  63. package/dist/core/manual-registration-tokens.d.ts.map +1 -0
  64. package/dist/core/manual-registration-tokens.js +28 -0
  65. package/dist/core/manual-registration-tokens.js.map +1 -0
  66. package/dist/core/provisioned-runners.d.ts +67 -0
  67. package/dist/core/provisioned-runners.d.ts.map +1 -0
  68. package/dist/core/provisioned-runners.js +162 -0
  69. package/dist/core/provisioned-runners.js.map +1 -0
  70. package/dist/core/provisioner-tokens.d.ts +20 -0
  71. package/dist/core/provisioner-tokens.d.ts.map +1 -0
  72. package/dist/core/provisioner-tokens.js +36 -0
  73. package/dist/core/provisioner-tokens.js.map +1 -0
  74. package/dist/core/rate-limit.d.ts +35 -0
  75. package/dist/core/rate-limit.d.ts.map +1 -0
  76. package/dist/core/rate-limit.js +74 -0
  77. package/dist/core/rate-limit.js.map +1 -0
  78. package/dist/core/runner-sessions.d.ts +26 -0
  79. package/dist/core/runner-sessions.d.ts.map +1 -0
  80. package/dist/core/runner-sessions.js +41 -0
  81. package/dist/core/runner-sessions.js.map +1 -0
  82. package/dist/core/runner-tool-capabilities.d.ts +24 -0
  83. package/dist/core/runner-tool-capabilities.d.ts.map +1 -0
  84. package/dist/core/runner-tool-capabilities.js +43 -0
  85. package/dist/core/runner-tool-capabilities.js.map +1 -0
  86. package/dist/db/db.d.ts +4478 -0
  87. package/dist/db/db.d.ts.map +1 -0
  88. package/dist/db/db.js +36 -0
  89. package/dist/db/db.js.map +1 -0
  90. package/dist/db/ephemeral-registration-tokens.d.ts +47 -0
  91. package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -0
  92. package/dist/db/ephemeral-registration-tokens.js +170 -0
  93. package/dist/db/ephemeral-registration-tokens.js.map +1 -0
  94. package/dist/db/index.d.ts +19 -0
  95. package/dist/db/index.d.ts.map +1 -0
  96. package/dist/db/index.js +15 -0
  97. package/dist/db/index.js.map +1 -0
  98. package/dist/db/job-executions.d.ts +128 -0
  99. package/dist/db/job-executions.d.ts.map +1 -0
  100. package/dist/db/job-executions.js +354 -0
  101. package/dist/db/job-executions.js.map +1 -0
  102. package/dist/db/manual-registration-tokens.d.ts +16 -0
  103. package/dist/db/manual-registration-tokens.d.ts.map +1 -0
  104. package/dist/db/manual-registration-tokens.js +37 -0
  105. package/dist/db/manual-registration-tokens.js.map +1 -0
  106. package/dist/db/provisioned-runners.d.ts +79 -0
  107. package/dist/db/provisioned-runners.d.ts.map +1 -0
  108. package/dist/db/provisioned-runners.js +466 -0
  109. package/dist/db/provisioned-runners.js.map +1 -0
  110. package/dist/db/provisioner-tokens.d.ts +26 -0
  111. package/dist/db/provisioner-tokens.d.ts.map +1 -0
  112. package/dist/db/provisioner-tokens.js +54 -0
  113. package/dist/db/provisioner-tokens.js.map +1 -0
  114. package/dist/db/rate-limits.d.ts +18 -0
  115. package/dist/db/rate-limits.d.ts.map +1 -0
  116. package/dist/db/rate-limits.js +44 -0
  117. package/dist/db/rate-limits.js.map +1 -0
  118. package/dist/db/reservations.d.ts +48 -0
  119. package/dist/db/reservations.d.ts.map +1 -0
  120. package/dist/db/reservations.js +162 -0
  121. package/dist/db/reservations.js.map +1 -0
  122. package/dist/db/runner-sessions.d.ts +18 -0
  123. package/dist/db/runner-sessions.d.ts.map +1 -0
  124. package/dist/db/runner-sessions.js +38 -0
  125. package/dist/db/runner-sessions.js.map +1 -0
  126. package/dist/db/schema/common.d.ts +2 -0
  127. package/dist/db/schema/common.d.ts.map +1 -0
  128. package/dist/db/schema/common.js +4 -0
  129. package/dist/db/schema/common.js.map +1 -0
  130. package/dist/db/schema/ephemeral-registration-tokens.d.ts +199 -0
  131. package/dist/db/schema/ephemeral-registration-tokens.d.ts.map +1 -0
  132. package/dist/db/schema/ephemeral-registration-tokens.js +45 -0
  133. package/dist/db/schema/ephemeral-registration-tokens.js.map +1 -0
  134. package/dist/db/schema/manual-registration-tokens.d.ts +165 -0
  135. package/dist/db/schema/manual-registration-tokens.d.ts.map +1 -0
  136. package/dist/db/schema/manual-registration-tokens.js +40 -0
  137. package/dist/db/schema/manual-registration-tokens.js.map +1 -0
  138. package/dist/db/schema/outbox.d.ts +195 -0
  139. package/dist/db/schema/outbox.d.ts.map +1 -0
  140. package/dist/db/schema/outbox.js +5 -0
  141. package/dist/db/schema/outbox.js.map +1 -0
  142. package/dist/db/schema/pending-job-executions.d.ts +189 -0
  143. package/dist/db/schema/pending-job-executions.d.ts.map +1 -0
  144. package/dist/db/schema/pending-job-executions.js +21 -0
  145. package/dist/db/schema/pending-job-executions.js.map +1 -0
  146. package/dist/db/schema/provisioned-runners.d.ts +379 -0
  147. package/dist/db/schema/provisioned-runners.d.ts.map +1 -0
  148. package/dist/db/schema/provisioned-runners.js +83 -0
  149. package/dist/db/schema/provisioned-runners.js.map +1 -0
  150. package/dist/db/schema/provisioner-tokens.d.ts +216 -0
  151. package/dist/db/schema/provisioner-tokens.d.ts.map +1 -0
  152. package/dist/db/schema/provisioner-tokens.js +48 -0
  153. package/dist/db/schema/provisioner-tokens.js.map +1 -0
  154. package/dist/db/schema/rate-limits.d.ts +145 -0
  155. package/dist/db/schema/rate-limits.d.ts.map +1 -0
  156. package/dist/db/schema/rate-limits.js +25 -0
  157. package/dist/db/schema/rate-limits.js.map +1 -0
  158. package/dist/db/schema/reservations.d.ts +157 -0
  159. package/dist/db/schema/reservations.d.ts.map +1 -0
  160. package/dist/db/schema/reservations.js +34 -0
  161. package/dist/db/schema/reservations.js.map +1 -0
  162. package/dist/db/schema/runner-sessions.d.ts +298 -0
  163. package/dist/db/schema/runner-sessions.d.ts.map +1 -0
  164. package/dist/db/schema/runner-sessions.js +61 -0
  165. package/dist/db/schema/runner-sessions.js.map +1 -0
  166. package/dist/db/schema/running-job-executions.d.ts +334 -0
  167. package/dist/db/schema/running-job-executions.d.ts.map +1 -0
  168. package/dist/db/schema/running-job-executions.js +41 -0
  169. package/dist/db/schema/running-job-executions.js.map +1 -0
  170. package/dist/index.d.ts +6 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +56 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/metrics/index.d.ts +3 -0
  175. package/dist/metrics/index.d.ts.map +1 -0
  176. package/dist/metrics/index.js +4 -0
  177. package/dist/metrics/index.js.map +1 -0
  178. package/dist/metrics/instance.d.ts +34 -0
  179. package/dist/metrics/instance.d.ts.map +1 -0
  180. package/dist/metrics/instance.js +60 -0
  181. package/dist/metrics/instance.js.map +1 -0
  182. package/dist/metrics/service.d.ts +2 -0
  183. package/dist/metrics/service.d.ts.map +1 -0
  184. package/dist/metrics/service.js +21 -0
  185. package/dist/metrics/service.js.map +1 -0
  186. package/dist/presentation/auth/index.d.ts +3 -0
  187. package/dist/presentation/auth/index.d.ts.map +1 -0
  188. package/dist/presentation/auth/index.js +4 -0
  189. package/dist/presentation/auth/index.js.map +1 -0
  190. package/dist/presentation/auth/provisioner-token-auth.d.ts +3 -0
  191. package/dist/presentation/auth/provisioner-token-auth.d.ts.map +1 -0
  192. package/dist/presentation/auth/provisioner-token-auth.js +81 -0
  193. package/dist/presentation/auth/provisioner-token-auth.js.map +1 -0
  194. package/dist/presentation/auth/runner-registration-token-auth.d.ts +17 -0
  195. package/dist/presentation/auth/runner-registration-token-auth.d.ts.map +1 -0
  196. package/dist/presentation/auth/runner-registration-token-auth.js +77 -0
  197. package/dist/presentation/auth/runner-registration-token-auth.js.map +1 -0
  198. package/dist/presentation/dto/active-provisioner.d.ts +8 -0
  199. package/dist/presentation/dto/active-provisioner.d.ts.map +1 -0
  200. package/dist/presentation/dto/active-provisioner.js +10 -0
  201. package/dist/presentation/dto/active-provisioner.js.map +1 -0
  202. package/dist/presentation/dto/index.d.ts +7 -0
  203. package/dist/presentation/dto/index.d.ts.map +1 -0
  204. package/dist/presentation/dto/index.js +8 -0
  205. package/dist/presentation/dto/index.js.map +1 -0
  206. package/dist/presentation/dto/manual-registration-token.d.ts +12 -0
  207. package/dist/presentation/dto/manual-registration-token.d.ts.map +1 -0
  208. package/dist/presentation/dto/manual-registration-token.js +14 -0
  209. package/dist/presentation/dto/manual-registration-token.js.map +1 -0
  210. package/dist/presentation/dto/mint-registration-tokens.d.ts +5 -0
  211. package/dist/presentation/dto/mint-registration-tokens.d.ts.map +1 -0
  212. package/dist/presentation/dto/mint-registration-tokens.js +19 -0
  213. package/dist/presentation/dto/mint-registration-tokens.js.map +1 -0
  214. package/dist/presentation/dto/poll-demand.d.ts +4 -0
  215. package/dist/presentation/dto/poll-demand.d.ts.map +1 -0
  216. package/dist/presentation/dto/poll-demand.js +19 -0
  217. package/dist/presentation/dto/poll-demand.js.map +1 -0
  218. package/dist/presentation/dto/provisioned-runners.d.ts +38 -0
  219. package/dist/presentation/dto/provisioned-runners.d.ts.map +1 -0
  220. package/dist/presentation/dto/provisioned-runners.js +44 -0
  221. package/dist/presentation/dto/provisioned-runners.js.map +1 -0
  222. package/dist/presentation/dto/provisioner-token.d.ts +15 -0
  223. package/dist/presentation/dto/provisioner-token.d.ts.map +1 -0
  224. package/dist/presentation/dto/provisioner-token.js +17 -0
  225. package/dist/presentation/dto/provisioner-token.js.map +1 -0
  226. package/dist/presentation/index.d.ts +4 -0
  227. package/dist/presentation/index.d.ts.map +1 -0
  228. package/dist/presentation/index.js +5 -0
  229. package/dist/presentation/index.js.map +1 -0
  230. package/dist/presentation/routes/create-manual-registration-token.d.ts +2 -0
  231. package/dist/presentation/routes/create-manual-registration-token.d.ts.map +1 -0
  232. package/dist/presentation/routes/create-manual-registration-token.js +44 -0
  233. package/dist/presentation/routes/create-manual-registration-token.js.map +1 -0
  234. package/dist/presentation/routes/create-provisioner-token.d.ts +2 -0
  235. package/dist/presentation/routes/create-provisioner-token.d.ts.map +1 -0
  236. package/dist/presentation/routes/create-provisioner-token.js +42 -0
  237. package/dist/presentation/routes/create-provisioner-token.js.map +1 -0
  238. package/dist/presentation/routes/get-provisioner-me.d.ts +2 -0
  239. package/dist/presentation/routes/get-provisioner-me.d.ts.map +1 -0
  240. package/dist/presentation/routes/get-provisioner-me.js +22 -0
  241. package/dist/presentation/routes/get-provisioner-me.js.map +1 -0
  242. package/dist/presentation/routes/heartbeat.d.ts +2 -0
  243. package/dist/presentation/routes/heartbeat.d.ts.map +1 -0
  244. package/dist/presentation/routes/heartbeat.js +64 -0
  245. package/dist/presentation/routes/heartbeat.js.map +1 -0
  246. package/dist/presentation/routes/index.d.ts +4 -0
  247. package/dist/presentation/routes/index.d.ts.map +1 -0
  248. package/dist/presentation/routes/index.js +97 -0
  249. package/dist/presentation/routes/index.js.map +1 -0
  250. package/dist/presentation/routes/list-active-provisioners.d.ts +2 -0
  251. package/dist/presentation/routes/list-active-provisioners.d.ts.map +1 -0
  252. package/dist/presentation/routes/list-active-provisioners.js +32 -0
  253. package/dist/presentation/routes/list-active-provisioners.js.map +1 -0
  254. package/dist/presentation/routes/list-active-runners.d.ts +2 -0
  255. package/dist/presentation/routes/list-active-runners.d.ts.map +1 -0
  256. package/dist/presentation/routes/list-active-runners.js +32 -0
  257. package/dist/presentation/routes/list-active-runners.js.map +1 -0
  258. package/dist/presentation/routes/list-manual-registration-tokens.d.ts +2 -0
  259. package/dist/presentation/routes/list-manual-registration-tokens.d.ts.map +1 -0
  260. package/dist/presentation/routes/list-manual-registration-tokens.js +32 -0
  261. package/dist/presentation/routes/list-manual-registration-tokens.js.map +1 -0
  262. package/dist/presentation/routes/list-provisioner-tokens.d.ts +2 -0
  263. package/dist/presentation/routes/list-provisioner-tokens.d.ts.map +1 -0
  264. package/dist/presentation/routes/list-provisioner-tokens.js +32 -0
  265. package/dist/presentation/routes/list-provisioner-tokens.js.map +1 -0
  266. package/dist/presentation/routes/mint-registration-tokens.d.ts +2 -0
  267. package/dist/presentation/routes/mint-registration-tokens.d.ts.map +1 -0
  268. package/dist/presentation/routes/mint-registration-tokens.js +74 -0
  269. package/dist/presentation/routes/mint-registration-tokens.js.map +1 -0
  270. package/dist/presentation/routes/poll-demand.d.ts +2 -0
  271. package/dist/presentation/routes/poll-demand.d.ts.map +1 -0
  272. package/dist/presentation/routes/poll-demand.js +53 -0
  273. package/dist/presentation/routes/poll-demand.js.map +1 -0
  274. package/dist/presentation/routes/rate-limit.d.ts +4 -0
  275. package/dist/presentation/routes/rate-limit.d.ts.map +1 -0
  276. package/dist/presentation/routes/rate-limit.js +94 -0
  277. package/dist/presentation/routes/rate-limit.js.map +1 -0
  278. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts +2 -0
  279. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts.map +1 -0
  280. package/dist/presentation/routes/reconcile-provisioned-runners.js +27 -0
  281. package/dist/presentation/routes/reconcile-provisioned-runners.js.map +1 -0
  282. package/dist/presentation/routes/register.d.ts +2 -0
  283. package/dist/presentation/routes/register.d.ts.map +1 -0
  284. package/dist/presentation/routes/register.js +63 -0
  285. package/dist/presentation/routes/register.js.map +1 -0
  286. package/dist/presentation/routes/report-provisioned-runners.d.ts +2 -0
  287. package/dist/presentation/routes/report-provisioned-runners.d.ts.map +1 -0
  288. package/dist/presentation/routes/report-provisioned-runners.js +37 -0
  289. package/dist/presentation/routes/report-provisioned-runners.js.map +1 -0
  290. package/dist/presentation/routes/request-job.d.ts +2 -0
  291. package/dist/presentation/routes/request-job.d.ts.map +1 -0
  292. package/dist/presentation/routes/request-job.js +45 -0
  293. package/dist/presentation/routes/request-job.js.map +1 -0
  294. package/dist/presentation/routes/revoke-manual-registration-token.d.ts +2 -0
  295. package/dist/presentation/routes/revoke-manual-registration-token.d.ts.map +1 -0
  296. package/dist/presentation/routes/revoke-manual-registration-token.js +42 -0
  297. package/dist/presentation/routes/revoke-manual-registration-token.js.map +1 -0
  298. package/dist/presentation/routes/revoke-provisioner-token.d.ts +2 -0
  299. package/dist/presentation/routes/revoke-provisioner-token.d.ts.map +1 -0
  300. package/dist/presentation/routes/revoke-provisioner-token.js +44 -0
  301. package/dist/presentation/routes/revoke-provisioner-token.js.map +1 -0
  302. package/dist/presentation/routes/workspace-membership.d.ts +6 -0
  303. package/dist/presentation/routes/workspace-membership.d.ts.map +1 -0
  304. package/dist/presentation/routes/workspace-membership.js +6 -0
  305. package/dist/presentation/routes/workspace-membership.js.map +1 -0
  306. package/dist/presentation/subscribers/on-workflows-job-execution-timed-out.d.ts +3 -0
  307. package/dist/presentation/subscribers/on-workflows-job-execution-timed-out.d.ts.map +1 -0
  308. package/dist/presentation/subscribers/on-workflows-job-execution-timed-out.js +14 -0
  309. package/dist/presentation/subscribers/on-workflows-job-execution-timed-out.js.map +1 -0
  310. package/dist/temporal/activities/index.d.ts +9 -0
  311. package/dist/temporal/activities/index.d.ts.map +1 -0
  312. package/dist/temporal/activities/index.js +12 -0
  313. package/dist/temporal/activities/index.js.map +1 -0
  314. package/dist/temporal/activities/maintenance-activities.d.ts +31 -0
  315. package/dist/temporal/activities/maintenance-activities.d.ts.map +1 -0
  316. package/dist/temporal/activities/maintenance-activities.js +18 -0
  317. package/dist/temporal/activities/maintenance-activities.js.map +1 -0
  318. package/dist/temporal/constants.d.ts +2 -0
  319. package/dist/temporal/constants.d.ts.map +1 -0
  320. package/dist/temporal/constants.js +3 -0
  321. package/dist/temporal/constants.js.map +1 -0
  322. package/dist/temporal/workflows/index.d.ts +2 -0
  323. package/dist/temporal/workflows/index.d.ts.map +1 -0
  324. package/dist/temporal/workflows/index.js +3 -0
  325. package/dist/temporal/workflows/index.js.map +1 -0
  326. package/dist/temporal/workflows/stuck-job-detector.d.ts +2 -0
  327. package/dist/temporal/workflows/stuck-job-detector.d.ts.map +1 -0
  328. package/dist/temporal/workflows/stuck-job-detector.js +61 -0
  329. package/dist/temporal/workflows/stuck-job-detector.js.map +1 -0
  330. package/dist/tsconfig.test.tsbuildinfo +1 -0
  331. package/drizzle/0000_initial.sql +185 -0
  332. package/drizzle/meta/0000_snapshot.json +1582 -0
  333. package/drizzle/meta/_journal.json +13 -0
  334. package/drizzle.config.ts +7 -0
  335. package/package.json +82 -0
  336. package/src/config.test.ts +374 -0
  337. package/src/config.ts +330 -0
  338. package/src/core/demand.test.ts +301 -0
  339. package/src/core/demand.ts +239 -0
  340. package/src/core/entities/ephemeral-registration-token.ts +13 -0
  341. package/src/core/entities/manual-registration-token.ts +11 -0
  342. package/src/core/entities/provisioned-runner.ts +30 -0
  343. package/src/core/entities/provisioner-token.ts +16 -0
  344. package/src/core/entities/reservation.ts +9 -0
  345. package/src/core/entities/runner-session.ts +18 -0
  346. package/src/core/ephemeral-registration-tokens.test.ts +108 -0
  347. package/src/core/ephemeral-registration-tokens.ts +112 -0
  348. package/src/core/errors.ts +128 -0
  349. package/src/core/index.ts +56 -0
  350. package/src/core/job-executions.ts +47 -0
  351. package/src/core/maintenance-policy.ts +1 -0
  352. package/src/core/maintenance.test.ts +251 -0
  353. package/src/core/maintenance.ts +74 -0
  354. package/src/core/manual-registration-tokens.test.ts +44 -0
  355. package/src/core/manual-registration-tokens.ts +51 -0
  356. package/src/core/provisioned-runners.test.ts +101 -0
  357. package/src/core/provisioned-runners.ts +301 -0
  358. package/src/core/provisioner-tokens.test.ts +61 -0
  359. package/src/core/provisioner-tokens.ts +61 -0
  360. package/src/core/rate-limit.test.ts +158 -0
  361. package/src/core/rate-limit.ts +121 -0
  362. package/src/core/runner-sessions.test.ts +209 -0
  363. package/src/core/runner-sessions.ts +66 -0
  364. package/src/core/runner-tool-capabilities.test.ts +141 -0
  365. package/src/core/runner-tool-capabilities.ts +75 -0
  366. package/src/db/db.ts +38 -0
  367. package/src/db/ephemeral-registration-tokens.test.ts +332 -0
  368. package/src/db/ephemeral-registration-tokens.ts +348 -0
  369. package/src/db/index.ts +90 -0
  370. package/src/db/job-executions.test.ts +1500 -0
  371. package/src/db/job-executions.ts +647 -0
  372. package/src/db/manual-registration-tokens.test.ts +99 -0
  373. package/src/db/manual-registration-tokens.ts +87 -0
  374. package/src/db/provisioned-runners.test.ts +1812 -0
  375. package/src/db/provisioned-runners.ts +886 -0
  376. package/src/db/provisioner-tokens.test.ts +133 -0
  377. package/src/db/provisioner-tokens.ts +142 -0
  378. package/src/db/rate-limits.test.ts +74 -0
  379. package/src/db/rate-limits.ts +69 -0
  380. package/src/db/reservations.test.ts +399 -0
  381. package/src/db/reservations.ts +296 -0
  382. package/src/db/runner-sessions.test.ts +153 -0
  383. package/src/db/runner-sessions.ts +97 -0
  384. package/src/db/schema/common.ts +3 -0
  385. package/src/db/schema/ephemeral-registration-tokens.ts +58 -0
  386. package/src/db/schema/manual-registration-tokens.ts +40 -0
  387. package/src/db/schema/outbox.ts +4 -0
  388. package/src/db/schema/pending-job-executions.ts +25 -0
  389. package/src/db/schema/provisioned-runners.ts +89 -0
  390. package/src/db/schema/provisioner-tokens.ts +50 -0
  391. package/src/db/schema/rate-limits.ts +27 -0
  392. package/src/db/schema/reservations.ts +38 -0
  393. package/src/db/schema/runner-sessions.ts +77 -0
  394. package/src/db/schema/running-job-executions.ts +50 -0
  395. package/src/index.ts +63 -0
  396. package/src/metrics/index.ts +13 -0
  397. package/src/metrics/instance.ts +115 -0
  398. package/src/metrics/service.ts +22 -0
  399. package/src/presentation/auth/index.ts +6 -0
  400. package/src/presentation/auth/provisioner-token-auth.ts +76 -0
  401. package/src/presentation/auth/runner-registration-token-auth.ts +105 -0
  402. package/src/presentation/dto/active-provisioner.ts +15 -0
  403. package/src/presentation/dto/index.ts +13 -0
  404. package/src/presentation/dto/manual-registration-token.ts +23 -0
  405. package/src/presentation/dto/mint-registration-tokens.ts +35 -0
  406. package/src/presentation/dto/poll-demand.ts +20 -0
  407. package/src/presentation/dto/provisioned-runners.ts +88 -0
  408. package/src/presentation/dto/provisioner-token.ts +29 -0
  409. package/src/presentation/index.ts +6 -0
  410. package/src/presentation/routes/create-manual-registration-token.ts +43 -0
  411. package/src/presentation/routes/create-provisioner-token.ts +41 -0
  412. package/src/presentation/routes/get-provisioner-me.ts +22 -0
  413. package/src/presentation/routes/heartbeat.test.ts +325 -0
  414. package/src/presentation/routes/heartbeat.ts +80 -0
  415. package/src/presentation/routes/index.ts +86 -0
  416. package/src/presentation/routes/list-active-provisioners.ts +25 -0
  417. package/src/presentation/routes/list-active-runners.test.ts +366 -0
  418. package/src/presentation/routes/list-active-runners.ts +25 -0
  419. package/src/presentation/routes/list-manual-registration-tokens.ts +25 -0
  420. package/src/presentation/routes/list-provisioner-tokens.ts +25 -0
  421. package/src/presentation/routes/manual-registration-tokens.test.ts +213 -0
  422. package/src/presentation/routes/mint-registration-tokens.test.ts +453 -0
  423. package/src/presentation/routes/mint-registration-tokens.ts +82 -0
  424. package/src/presentation/routes/poll-demand-release.test.ts +80 -0
  425. package/src/presentation/routes/poll-demand.test.ts +323 -0
  426. package/src/presentation/routes/poll-demand.ts +56 -0
  427. package/src/presentation/routes/provisioner-me.test.ts +172 -0
  428. package/src/presentation/routes/provisioner-tokens.test.ts +219 -0
  429. package/src/presentation/routes/rate-limit.ts +115 -0
  430. package/src/presentation/routes/reconcile-provisioned-runners.test.ts +380 -0
  431. package/src/presentation/routes/reconcile-provisioned-runners.ts +30 -0
  432. package/src/presentation/routes/register.test.ts +453 -0
  433. package/src/presentation/routes/register.ts +75 -0
  434. package/src/presentation/routes/report-provisioned-runners.test.ts +249 -0
  435. package/src/presentation/routes/report-provisioned-runners.ts +40 -0
  436. package/src/presentation/routes/request-job.test.ts +222 -0
  437. package/src/presentation/routes/request-job.ts +47 -0
  438. package/src/presentation/routes/revoke-manual-registration-token.ts +35 -0
  439. package/src/presentation/routes/revoke-provisioner-token.ts +37 -0
  440. package/src/presentation/routes/workspace-membership.ts +9 -0
  441. package/src/presentation/subscribers/on-workflows-job-execution-timed-out.test.ts +147 -0
  442. package/src/presentation/subscribers/on-workflows-job-execution-timed-out.ts +17 -0
  443. package/src/temporal/activities/index.ts +17 -0
  444. package/src/temporal/activities/maintenance-activities.test.ts +104 -0
  445. package/src/temporal/activities/maintenance-activities.ts +41 -0
  446. package/src/temporal/constants.ts +1 -0
  447. package/src/temporal/workflows/index.ts +1 -0
  448. package/src/temporal/workflows/stuck-job-detector.test.ts +93 -0
  449. package/src/temporal/workflows/stuck-job-detector.ts +67 -0
  450. package/test/env.ts +11 -0
  451. package/test/factories/ephemeral-registration-token.ts +41 -0
  452. package/test/factories/manual-registration-token.ts +37 -0
  453. package/test/factories/pending-job.ts +44 -0
  454. package/test/factories/provisioned-runner.ts +78 -0
  455. package/test/factories/provisioner-token.ts +41 -0
  456. package/test/factories/reservation.ts +33 -0
  457. package/test/factories/runner-session.ts +32 -0
  458. package/test/globalSetup.ts +23 -0
  459. package/test/index.ts +16 -0
  460. package/test/setup.ts +17 -0
  461. package/tsconfig.build.json +9 -0
  462. package/tsconfig.build.tsbuildinfo +1 -0
  463. package/tsconfig.json +3 -0
  464. package/tsconfig.test.json +8 -0
  465. package/vitest.config.ts +14 -0
@@ -0,0 +1,2 @@
1
+ $ shipfox-swc
2
+ Successfully compiled: 81 files with swc (114.17ms)
@@ -0,0 +1 @@
1
+ $ shipfox-tsc-emit
@@ -0,0 +1 @@
1
+ $ shipfox-tsc-check
package/CHANGELOG.md ADDED
@@ -0,0 +1,187 @@
1
+ # @shipfox/api-runners
2
+
3
+ ## 2.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1b0d344: Publishes the complete API runtime closure with packed-consumer-safe internal imports and records its exact package set in application releases.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [0cd6dd4]
12
+ - Updated dependencies [a68458a]
13
+ - Updated dependencies [6eba800]
14
+ - Updated dependencies [c31a7e0]
15
+ - Updated dependencies [1b0d344]
16
+ - Updated dependencies [521e006]
17
+ - @shipfox/node-module@0.2.0
18
+ - @shipfox/node-temporal@0.2.0
19
+ - @shipfox/api-auth@2.0.0
20
+ - @shipfox/api-auth-context@2.0.0
21
+ - @shipfox/api-runners-dto@2.0.0
22
+ - @shipfox/api-workflows-dto@2.0.0
23
+ - @shipfox/node-rate-limit@0.2.0
24
+ - @shipfox/node-tokens@0.2.0
25
+ - @shipfox/runner-labels@0.1.0
26
+ - @shipfox/config@1.2.1
27
+ - @shipfox/node-drizzle@0.2.1
28
+ - @shipfox/node-fastify@0.2.1
29
+ - @shipfox/node-opentelemetry@0.5.0
30
+ - @shipfox/node-outbox@0.2.1
31
+ - @shipfox/node-postgres@0.4.1
32
+
33
+ ## 0.1.2
34
+
35
+ ### Patch Changes
36
+
37
+ - Updated dependencies [705dd43]
38
+ - @shipfox/node-outbox@0.2.0
39
+ - @shipfox/api-auth@0.1.2
40
+ - @shipfox/node-module@0.1.2
41
+
42
+ ## 0.1.1
43
+
44
+ ### Patch Changes
45
+
46
+ - Updated dependencies [ec75cd5]
47
+ - Updated dependencies [6a1fb54]
48
+ - @shipfox/node-drizzle@0.2.0
49
+ - @shipfox/node-postgres@0.4.0
50
+ - @shipfox/api-auth@0.1.1
51
+ - @shipfox/node-module@0.1.1
52
+ - @shipfox/node-outbox@0.1.1
53
+
54
+ ## 0.1.0
55
+
56
+ ### Minor Changes
57
+
58
+ - 8100b48: Adds the provisioned-runner reconcile endpoint and shared request/response schemas for provisioner state recovery.
59
+ - 7a9943d: Adds the backend contract for per-step execution: job claims mint a lease token for the step API, step reports carry attempts and exit codes, and workflow completion can be signalled through the workflows outbox. The runner-side step loop is intentionally owned by the follow-up runner protocol work.
60
+ - 2bc5595: Adds workflow-run cancellation across the API, orchestration queue cleanup, event contract, and run-page cancel action.
61
+ - c47be09: Reshape Scheduling around runner job leases. Jobs are now enqueued with `workflowRunId`, `workflowRunAttemptId`, `jobId`, and `jobExecutionId`; the claim route mints a job lease token and returns the same workflow/job identity tuple. The stuck-job detector emits `runners.job.lease_expired` with that tuple when a lease expires.
62
+ - f9f059e: Cut the runner protocol over to per-step pull/report and remove the job-atomic path.
63
+
64
+ The job workflow now terminates on two signals: `job-finished` (raised by
65
+ `recordStepResult` on step exhaustion) and `job-lease-expired` (raised by the new
66
+ `runners.job.lease_expired` subscriber). A precedence ladder keeps a genuinely
67
+ finished job from being failed by a late lease expiry, and the lease-expiry branch
68
+ re-derives the outcome from the authoritative step projection in a single
69
+ transaction (server state is the final gate). On finish the workflow releases the
70
+ lease via `releaseJob` (deleting both the running and any orphaned pending row);
71
+ release is best-effort so a Scheduling outage never blocks the run DAG.
72
+
73
+ Removed the atomic path end to end: the runner `POST /runners/jobs/:jobId/complete`
74
+ route, the `RUNNER_JOB_COMPLETED` event, `finalizeRunningJob`/`completeJob`, the
75
+ `applyStepResults*` apply path and its workflow subscriber, and the dead
76
+ `jobPayload*`/`complete-job` DTO schemas. The runner now parses the step-less claim
77
+ response, and `claimPendingJob` drops an orphan pending row instead of poison-looping.
78
+
79
+ Internal breaking change (deleted exported DTOs/events and a runner route, plus a
80
+ Temporal signal rename) consumed only within this monorepo; backend and agent ship
81
+ together.
82
+
83
+ - 1c1fb3e: Adds shared fixed-window rate limiting for provisioner token minting and ephemeral runner registration.
84
+ - fb64f13: Adds a job lease capability token (HS256, `verifyJobLeaseToken` plus the claims schema) so runner step calls can be authenticated in-process without a hop back to Scheduling.
85
+ - 03d9eae: Adds runner-advertised tool capabilities to registration, heartbeat, persistence, and runner protocol reporting.
86
+ - 6181819: Adds runner registration sessions with bounded label contracts, session-token auth, and lease-token heartbeat ownership.
87
+
88
+ ### Patch Changes
89
+
90
+ - 2325d76: Adds provisioned-runner terminate intent signals for cancelled bound jobs across runner polling and reconcile responses.
91
+ - 89026d5: Fixes provisioned-runner reconcile results when fresh lifecycle reports commit during stale-absent termination.
92
+ - c0a883c: Moves the job lease capability token codec and its claims schema from the runners packages into api-auth/api-auth-dto, renaming its config to `AUTH_JOB_LEASE_TOKEN_*`, so all signed-token codecs live with authentication. Adds a shared leased-job auth context for request-scoped lease claims, and a shared `createLeaseTokenAuthMethod` (the `leased-job` auth method) registered on the auth module so any feature module can protect routes with a lease token by name.
93
+ - ae7a63c: Adds daily dispatched outbox row retention with bounded cleanup batches and retention indexes on module outbox tables.
94
+ - 5729548: Stuck-job expiry now reaps a bounded batch in one transaction instead of N+1: a single `DELETE … RETURNING` (oldest-first, `FOR UPDATE SKIP LOCKED`, capped at 100 per tick) feeds a multi-row outbox insert via the new `writeOutboxEvents` helper. Behavior is unchanged (same rows reaped, one `runners.job.lease_expired` event per reaped job, same orphan-pending sweep).
95
+ - e250c4c: Propagates `projectId` end-to-end into the job lease token. Workflows sources the `{workspaceId, projectId, workflowRunId, workflowRunAttemptId, jobId, jobExecutionId}` identity tuple and threads it through the runner pending/running job tables and lease claims. This is lease-shape groundwork for per-project log-ingest authorization; the stream-stamping consumer lands separately.
96
+ - 2617db9: Folds the runner database migrations into a single baseline and drops six redundant indexes; the resulting schema is unchanged.
97
+ - 247cbd6: Adds label-aware runner job claiming with shared runner-label validation and required-label orchestration.
98
+ - 1d98b19: Rewrites the pending-job claim query with the Drizzle query builder instead of raw SQL, keeping the same FOR UPDATE SKIP LOCKED locking behavior.
99
+ - 5823bac: Removes the per-request workspace existence and status check from provisioner token auth, severing the last `@shipfox/api-workspaces` dependency in `@shipfox/api-runners`; workspace-status enforcement on the provisioner path moves to the upcoming workspace removal/disable work.
100
+ - 75520ff: Add the foundation for metrics observability. `@shipfox/node-module` gains an optional `metrics` hook on `ShipfoxModule` plus `registerModuleMetrics`, a declarative slot for modules to register service-level metrics (observable gauges) once at app startup, kept separate from `initializeModules` so unit tests never bind the metrics port. `@shipfox/api-runners` is instrumented as the worked example across both planes: instance counters for job enqueue, claim, and lease expiry recorded inline, and `runners_pending_jobs` / `runners_running_jobs` observable gauges over a new `getJobQueueDepth` query wired through the module hook.
101
+ - 62720ea: Consolidates runner label canonicalization on `@shipfox/runner-labels` across runner scheduling and protocol code.
102
+ - b855d6f: Adds reconciliation observability metrics for provisioned-runner divergence and terminate-intent reconciliation.
103
+ - 362b3eb: Scope runner log append authorization to the dispatched step attempt carried by the job lease token.
104
+ - 3bea87f: Adds a typed `subscriberFactory` that binds each outbox event name to its payload type at construction, so subscriber handlers receive a typed `(payload, event)` and the per-handler `event.payload as X` casts are gone; a private brand makes the factory the only way to build a module subscriber.
105
+ - 82d22e4: Make the workspace-membership gate stateless. `requireWorkspaceAccess` now lives in `@shipfox/api-auth-context` and authorizes a request purely from the verified session-token claims, replacing the `requireMembership` gate in `@shipfox/api-workspaces` that read the workspace row from the database on every workspace-scoped request. Membership and role already travel in the token, so the check needs no database access.
106
+
107
+ This removes the per-request database read and severs the runtime dependency on `@shipfox/api-workspaces` from feature modules that only needed the membership gate (integration providers, secrets, projects, agent, runners). Workspace existence and `active`-status enforcement, which no code path currently exercises, moves off the hot path; enforce it at token issuance when workspace suspension is introduced.
108
+
109
+ - 2933c33: Adds drain-boundary Zod validation for current outbox publisher event payloads.
110
+ - 8b9c3e0: Runs the API runners and integration core test suites without per-file Vitest module isolation, removing runner auth-helper mocks and cleaning up module-reset handling for shared test modules.
111
+ - 0dd23a7: Warns on agent tool capability mismatches during dispatch without blocking label-matched runners.
112
+ - 8ecc121: Track queue/run/finish timing for workflow runs and jobs. Adds nullable `started_at`/`finished_at` to workflow runs and `queued_at`/`started_at`/`finished_at` to jobs, exposed on the run and job DTOs. The runners module emits two new authoritative-timestamp events (`runners.job.queued`, `runners.job.started`) in the same transaction as the enqueue/claim; workflows projects them onto the job row with a first-write-wins `coalesce`, so the at-least-once outbox can redeliver out of order safely. Run `started_at`/`finished_at` and job `finished_at` are stamped in-module at the status transitions. All columns are nullable and eventually consistent, so consumers must treat a missing endpoint as "not yet known" and clamp any duration math.
113
+ - Updated dependencies [eb40964]
114
+ - Updated dependencies [5c18360]
115
+ - Updated dependencies [34ba284]
116
+ - Updated dependencies [8100b48]
117
+ - Updated dependencies [5707d6d]
118
+ - Updated dependencies [7a9943d]
119
+ - Updated dependencies [b9c3f32]
120
+ - Updated dependencies [2325d76]
121
+ - Updated dependencies [d02c5fd]
122
+ - Updated dependencies [c17dd6e]
123
+ - Updated dependencies [a81b68c]
124
+ - Updated dependencies [c0a883c]
125
+ - Updated dependencies [72ce351]
126
+ - Updated dependencies [e47f8da]
127
+ - Updated dependencies [736249b]
128
+ - Updated dependencies [2bc5595]
129
+ - Updated dependencies [7b175f5]
130
+ - Updated dependencies [c47be09]
131
+ - Updated dependencies [f9f059e]
132
+ - Updated dependencies [940696a]
133
+ - Updated dependencies [f98c2be]
134
+ - Updated dependencies [e9396c9]
135
+ - Updated dependencies [ae7a63c]
136
+ - Updated dependencies [5729548]
137
+ - Updated dependencies [f92122b]
138
+ - Updated dependencies [e250c4c]
139
+ - Updated dependencies [b525dcd]
140
+ - Updated dependencies [b0a0e1a]
141
+ - Updated dependencies [857fd73]
142
+ - Updated dependencies [1c1fb3e]
143
+ - Updated dependencies [3afb7e3]
144
+ - Updated dependencies [1daf39a]
145
+ - Updated dependencies [247cbd6]
146
+ - Updated dependencies [c652a68]
147
+ - Updated dependencies [fb64f13]
148
+ - Updated dependencies [75520ff]
149
+ - Updated dependencies [62720ea]
150
+ - Updated dependencies [795f440]
151
+ - Updated dependencies [3dcd751]
152
+ - Updated dependencies [c0a883c]
153
+ - Updated dependencies [362b3eb]
154
+ - Updated dependencies [d6d4862]
155
+ - Updated dependencies [c0a883c]
156
+ - Updated dependencies [6077301]
157
+ - Updated dependencies [3bea87f]
158
+ - Updated dependencies [82d22e4]
159
+ - Updated dependencies [d69b164]
160
+ - Updated dependencies [2fb3e87]
161
+ - Updated dependencies [ef1e917]
162
+ - Updated dependencies [61de795]
163
+ - Updated dependencies [88b9793]
164
+ - Updated dependencies [27770eb]
165
+ - Updated dependencies [2933c33]
166
+ - Updated dependencies [03d9eae]
167
+ - Updated dependencies [a5c7562]
168
+ - Updated dependencies [6181819]
169
+ - Updated dependencies [e699508]
170
+ - Updated dependencies [9c149d1]
171
+ - Updated dependencies [fb64f13]
172
+ - Updated dependencies [8ecc121]
173
+ - @shipfox/api-workflows-dto@0.1.0
174
+ - @shipfox/node-fastify@0.2.0
175
+ - @shipfox/api-runners-dto@0.1.0
176
+ - @shipfox/node-drizzle@0.1.0
177
+ - @shipfox/api-auth@0.1.0
178
+ - @shipfox/node-tokens@0.1.0
179
+ - @shipfox/api-auth-context@0.1.0
180
+ - @shipfox/node-opentelemetry@0.4.2
181
+ - @shipfox/node-postgres@0.3.2
182
+ - @shipfox/node-temporal@0.1.1
183
+ - @shipfox/node-module@0.1.0
184
+ - @shipfox/node-outbox@0.1.0
185
+ - @shipfox/node-rate-limit@0.1.0
186
+ - @shipfox/runner-labels@0.0.1
187
+ - @shipfox/config@1.2.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shipfox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ export declare const config: Readonly<{
2
+ EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: number;
3
+ REGISTRATION_TOKEN_BATCH_MAX: number;
4
+ PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS: number;
5
+ PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS: number;
6
+ EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS: number;
7
+ EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS: number;
8
+ RUNNERS_RATE_LIMIT_TIMEOUT_MS: number;
9
+ RATE_LIMIT_IDENTIFIER_SECRET: string | undefined;
10
+ RESERVATION_TTL_SECONDS: number;
11
+ RESERVATION_LONG_POLL_MAX_WAIT_SECONDS: number;
12
+ RESERVATION_POLL_INTERVAL_MS: number;
13
+ RESERVATION_POLL_MAX_INTERVAL_MS: number;
14
+ RUNNER_ACTIVE_WINDOW_SECONDS: number;
15
+ RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS: number;
16
+ RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS: number;
17
+ RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS: number;
18
+ RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS: number;
19
+ RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT: number;
20
+ RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS: number;
21
+ RUNNER_SESSION_MANUAL_RETENTION_DAYS: number;
22
+ RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS: number;
23
+ RUNNER_SESSION_GC_BATCH_SIZE: number;
24
+ RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS: number;
25
+ RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE: number;
26
+ PROVISIONER_ACTIVE_WINDOW_SECONDS: number;
27
+ PROVISIONER_LAST_SEEN_THROTTLE_SECONDS: number;
28
+ PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED: boolean;
29
+ } & import("@shipfox/config").CleanedEnvAccessors>;
30
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDA6GjB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,208 @@
1
+ import { REGISTRATION_TOKEN_BATCH_HARD_MAX } from '@shipfox/api-runners-dto';
2
+ import { bool, createConfig, num, str } from '@shipfox/config';
3
+ import { STUCK_JOB_THRESHOLD_SECONDS } from '#core/maintenance-policy.js';
4
+ const EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS = 3600;
5
+ export const config = createConfig({
6
+ EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: num({
7
+ desc: `Lifetime of a provisioner-minted runner registration token, in seconds. The token can be exchanged once by a runner before this time passes. Set this between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,
8
+ default: 300
9
+ }),
10
+ REGISTRATION_TOKEN_BATCH_MAX: num({
11
+ desc: `Maximum number of runner registration tokens a provisioner can mint in one batch request. Set this between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,
12
+ default: 500
13
+ }),
14
+ PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS: num({
15
+ desc: 'Maximum number of batch runner registration token mint requests one provisioner can make per rate-limit window.',
16
+ default: 120
17
+ }),
18
+ PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS: num({
19
+ desc: 'Rate-limit window for provisioner batch runner registration token mint requests, in seconds.',
20
+ default: 60
21
+ }),
22
+ EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS: num({
23
+ desc: 'Maximum number of runner registration attempts one ephemeral registration token can make per rate-limit window.',
24
+ default: 5
25
+ }),
26
+ EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS: num({
27
+ desc: 'Rate-limit window for runner registration attempts with one ephemeral registration token, in seconds.',
28
+ default: 60
29
+ }),
30
+ RUNNERS_RATE_LIMIT_TIMEOUT_MS: num({
31
+ desc: 'Maximum time, in milliseconds, a runners rate-limit storage check may wait before the request fails closed.',
32
+ default: 250
33
+ }),
34
+ RATE_LIMIT_IDENTIFIER_SECRET: str({
35
+ desc: 'Optional secret used to HMAC identifiers before storing rate-limit counters. Leave it unset to derive a stable key from AUTH_JWT_SECRET.',
36
+ default: undefined
37
+ }),
38
+ RESERVATION_TTL_SECONDS: num({
39
+ desc: 'Lifetime of a count-based runner reservation, in seconds. Expired reservations stop counting against queued demand.',
40
+ default: 60
41
+ }),
42
+ RESERVATION_LONG_POLL_MAX_WAIT_SECONDS: num({
43
+ desc: 'Maximum time the provisioner demand poll endpoint waits for reservable demand before returning, in seconds.',
44
+ default: 30
45
+ }),
46
+ RESERVATION_POLL_INTERVAL_MS: num({
47
+ desc: 'Initial interval between demand re-checks while a provisioner request is waiting, in milliseconds.',
48
+ default: 1000
49
+ }),
50
+ RESERVATION_POLL_MAX_INTERVAL_MS: num({
51
+ desc: 'Maximum backoff interval between demand re-checks while a provisioner request is waiting, in milliseconds.',
52
+ default: 5000
53
+ }),
54
+ RUNNER_ACTIVE_WINDOW_SECONDS: num({
55
+ desc: 'Time window, in seconds, used to list active runners from recent heartbeats and provisioned runner reports.',
56
+ default: 60
57
+ }),
58
+ RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS: num({
59
+ desc: 'Time window, in seconds, after which a runner tool capability report is treated as stale. Set this higher than the runner heartbeat interval so active runners keep their advertised tools fresh.',
60
+ default: 60
61
+ }),
62
+ RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS: num({
63
+ desc: 'Grace window, in seconds, before maintenance expires a claimed job that has not sent its first heartbeat. Set this lower than the normal stuck-job threshold so startup crashes release work quickly.',
64
+ default: 60
65
+ }),
66
+ RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS: num({
67
+ desc: 'Grace window, in seconds, before reconcile marks an absent provisioned runner as terminated. Set this higher than the provisioner report interval so a transient empty or partial observed set does not kill a live runner.',
68
+ default: 120
69
+ }),
70
+ RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS: num({
71
+ desc: 'Time, in seconds, after which a provisioned runner with no recent report, no live provisioner, no live runner session, and no running job is marked failed by backend maintenance.',
72
+ default: 300
73
+ }),
74
+ RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT: num({
75
+ desc: 'Maximum number of stale provisioned runners the maintenance worker marks failed in one run. Higher values clear backlogs faster but hold database locks longer.',
76
+ default: 100
77
+ }),
78
+ RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS: num({
79
+ desc: 'Minimum time, in seconds, between runner session liveness writes from job request polls. Set this lower than RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS so active idle runners stay fresh.',
80
+ default: 10
81
+ }),
82
+ RUNNER_SESSION_MANUAL_RETENTION_DAYS: num({
83
+ desc: 'How long manual runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',
84
+ default: 30
85
+ }),
86
+ RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS: num({
87
+ desc: 'How long ephemeral runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',
88
+ default: 7
89
+ }),
90
+ RUNNER_SESSION_GC_BATCH_SIZE: num({
91
+ desc: 'Maximum number of expired runner sessions maintenance deletes in one pass.',
92
+ default: 1000
93
+ }),
94
+ RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS: num({
95
+ desc: 'How long consumed or expired ephemeral registration tokens are retained for audit and debugging before maintenance deletes them, in days. Active tokens that are neither consumed nor expired are never deleted. This window is independent of the runner-session retention windows.',
96
+ default: 7
97
+ }),
98
+ RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE: num({
99
+ desc: 'Maximum number of consumed or expired ephemeral registration tokens maintenance deletes in one pass.',
100
+ default: 1000
101
+ }),
102
+ PROVISIONER_ACTIVE_WINDOW_SECONDS: num({
103
+ desc: 'Time window, in seconds, used to list active provisioners from recent authenticated requests.',
104
+ default: 120
105
+ }),
106
+ PROVISIONER_LAST_SEEN_THROTTLE_SECONDS: num({
107
+ desc: 'Minimum time, in seconds, between last-seen writes for one provisioner token.',
108
+ default: 10
109
+ }),
110
+ PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED: bool({
111
+ desc: 'Whether runners_provisioned_runner_count_divergence includes template_key as a metric label. Use true or false. Defaults to false because template keys can create high-cardinality metric series. Set true only when template keys are bounded and stable.',
112
+ default: false
113
+ })
114
+ });
115
+ if (!Number.isInteger(config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS) || config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS < 1 || config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS > EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS) {
116
+ throw new Error(`EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS (${config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS}) must be a whole number of seconds between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`);
117
+ }
118
+ if (!Number.isInteger(config.REGISTRATION_TOKEN_BATCH_MAX) || config.REGISTRATION_TOKEN_BATCH_MAX < 1 || config.REGISTRATION_TOKEN_BATCH_MAX > REGISTRATION_TOKEN_BATCH_HARD_MAX) {
119
+ throw new Error(`REGISTRATION_TOKEN_BATCH_MAX (${config.REGISTRATION_TOKEN_BATCH_MAX}) must be a whole number between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`);
120
+ }
121
+ for (const [name, value] of [
122
+ [
123
+ 'PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS',
124
+ config.PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS
125
+ ],
126
+ [
127
+ 'PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS',
128
+ config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS
129
+ ],
130
+ [
131
+ 'EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS',
132
+ config.EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS
133
+ ],
134
+ [
135
+ 'EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS',
136
+ config.EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS
137
+ ],
138
+ [
139
+ 'RUNNERS_RATE_LIMIT_TIMEOUT_MS',
140
+ config.RUNNERS_RATE_LIMIT_TIMEOUT_MS
141
+ ]
142
+ ]){
143
+ if (!Number.isInteger(value) || value < 1) {
144
+ throw new Error(`${name} (${value}) must be a whole number >= 1.`);
145
+ }
146
+ }
147
+ if (!Number.isInteger(config.RESERVATION_TTL_SECONDS) || config.RESERVATION_TTL_SECONDS < 1) {
148
+ throw new Error(`RESERVATION_TTL_SECONDS (${config.RESERVATION_TTL_SECONDS}) must be a whole number of seconds >= 1.`);
149
+ }
150
+ if (!Number.isInteger(config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS) || config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS < 0) {
151
+ throw new Error(`RESERVATION_LONG_POLL_MAX_WAIT_SECONDS (${config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS}) must be a whole number of seconds >= 0.`);
152
+ }
153
+ if (!Number.isInteger(config.RESERVATION_POLL_INTERVAL_MS) || config.RESERVATION_POLL_INTERVAL_MS < 1) {
154
+ throw new Error(`RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}) must be a whole number of milliseconds >= 1.`);
155
+ }
156
+ if (!Number.isInteger(config.RESERVATION_POLL_MAX_INTERVAL_MS) || config.RESERVATION_POLL_MAX_INTERVAL_MS < config.RESERVATION_POLL_INTERVAL_MS) {
157
+ throw new Error(`RESERVATION_POLL_MAX_INTERVAL_MS (${config.RESERVATION_POLL_MAX_INTERVAL_MS}) must be a whole number of milliseconds >= RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}).`);
158
+ }
159
+ if (!Number.isInteger(config.RUNNER_ACTIVE_WINDOW_SECONDS) || config.RUNNER_ACTIVE_WINDOW_SECONDS < 1) {
160
+ throw new Error(`RUNNER_ACTIVE_WINDOW_SECONDS (${config.RUNNER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`);
161
+ }
162
+ if (!Number.isInteger(config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS) || config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS < 1) {
163
+ throw new Error(`RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS (${config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS}) must be a whole number of seconds >= 1.`);
164
+ }
165
+ if (!Number.isInteger(config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS) || config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS < 1 || config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS >= STUCK_JOB_THRESHOLD_SECONDS) {
166
+ throw new Error(`RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS (${config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS}) must be a whole number of seconds >= 1 and < ${STUCK_JOB_THRESHOLD_SECONDS}.`);
167
+ }
168
+ if (!Number.isInteger(config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS) || config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS < 1) {
169
+ throw new Error(`RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS (${config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS}) must be a whole number of seconds >= 1.`);
170
+ }
171
+ if (!Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS) || config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS < 1) {
172
+ throw new Error(`RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be a whole number of seconds >= 1.`);
173
+ }
174
+ if (!Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT) || config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT < 1) {
175
+ throw new Error(`RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT (${config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT}) must be a whole number >= 1.`);
176
+ }
177
+ if (!Number.isInteger(config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS) || config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS < 1) {
178
+ throw new Error(`RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`);
179
+ }
180
+ if (!Number.isInteger(config.RUNNER_SESSION_MANUAL_RETENTION_DAYS) || config.RUNNER_SESSION_MANUAL_RETENTION_DAYS < 1) {
181
+ throw new Error(`RUNNER_SESSION_MANUAL_RETENTION_DAYS (${config.RUNNER_SESSION_MANUAL_RETENTION_DAYS}) must be a whole number of days >= 1.`);
182
+ }
183
+ if (!Number.isInteger(config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS) || config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS < 1) {
184
+ throw new Error(`RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS (${config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS}) must be a whole number of days >= 1.`);
185
+ }
186
+ if (!Number.isInteger(config.RUNNER_SESSION_GC_BATCH_SIZE) || config.RUNNER_SESSION_GC_BATCH_SIZE < 1) {
187
+ throw new Error(`RUNNER_SESSION_GC_BATCH_SIZE (${config.RUNNER_SESSION_GC_BATCH_SIZE}) must be a whole number >= 1.`);
188
+ }
189
+ if (!Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS) || config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS < 1) {
190
+ throw new Error(`RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS (${config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS}) must be a whole number of days >= 1.`);
191
+ }
192
+ if (!Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE) || config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE < 1) {
193
+ throw new Error(`RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE (${config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE}) must be a whole number >= 1.`);
194
+ }
195
+ if (!Number.isInteger(config.PROVISIONER_ACTIVE_WINDOW_SECONDS) || config.PROVISIONER_ACTIVE_WINDOW_SECONDS < 1) {
196
+ throw new Error(`PROVISIONER_ACTIVE_WINDOW_SECONDS (${config.PROVISIONER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`);
197
+ }
198
+ if (!Number.isInteger(config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS) || config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS < 1) {
199
+ throw new Error(`PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`);
200
+ }
201
+ if (config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <= config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS) {
202
+ throw new Error(`RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}).`);
203
+ }
204
+ if (config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <= config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS) {
205
+ throw new Error(`RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}).`);
206
+ }
207
+
208
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {REGISTRATION_TOKEN_BATCH_HARD_MAX} from '@shipfox/api-runners-dto';\nimport {bool, createConfig, num, str} from '@shipfox/config';\nimport {STUCK_JOB_THRESHOLD_SECONDS} from '#core/maintenance-policy.js';\n\nconst EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS = 3600;\n\nexport const config = createConfig({\n EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: num({\n desc: `Lifetime of a provisioner-minted runner registration token, in seconds. The token can be exchanged once by a runner before this time passes. Set this between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n default: 300,\n }),\n REGISTRATION_TOKEN_BATCH_MAX: num({\n desc: `Maximum number of runner registration tokens a provisioner can mint in one batch request. Set this between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n default: 500,\n }),\n PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of batch runner registration token mint requests one provisioner can make per rate-limit window.',\n default: 120,\n }),\n PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for provisioner batch runner registration token mint requests, in seconds.',\n default: 60,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of runner registration attempts one ephemeral registration token can make per rate-limit window.',\n default: 5,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for runner registration attempts with one ephemeral registration token, in seconds.',\n default: 60,\n }),\n RUNNERS_RATE_LIMIT_TIMEOUT_MS: num({\n desc: 'Maximum time, in milliseconds, a runners rate-limit storage check may wait before the request fails closed.',\n default: 250,\n }),\n RATE_LIMIT_IDENTIFIER_SECRET: str({\n desc: 'Optional secret used to HMAC identifiers before storing rate-limit counters. Leave it unset to derive a stable key from AUTH_JWT_SECRET.',\n default: undefined,\n }),\n RESERVATION_TTL_SECONDS: num({\n desc: 'Lifetime of a count-based runner reservation, in seconds. Expired reservations stop counting against queued demand.',\n default: 60,\n }),\n RESERVATION_LONG_POLL_MAX_WAIT_SECONDS: num({\n desc: 'Maximum time the provisioner demand poll endpoint waits for reservable demand before returning, in seconds.',\n default: 30,\n }),\n RESERVATION_POLL_INTERVAL_MS: num({\n desc: 'Initial interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 1000,\n }),\n RESERVATION_POLL_MAX_INTERVAL_MS: num({\n desc: 'Maximum backoff interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 5000,\n }),\n RUNNER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active runners from recent heartbeats and provisioned runner reports.',\n default: 60,\n }),\n RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS: num({\n desc: 'Time window, in seconds, after which a runner tool capability report is treated as stale. Set this higher than the runner heartbeat interval so active runners keep their advertised tools fresh.',\n default: 60,\n }),\n RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before maintenance expires a claimed job that has not sent its first heartbeat. Set this lower than the normal stuck-job threshold so startup crashes release work quickly.',\n default: 60,\n }),\n RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before reconcile marks an absent provisioned runner as terminated. Set this higher than the provisioner report interval so a transient empty or partial observed set does not kill a live runner.',\n default: 120,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS: num({\n desc: 'Time, in seconds, after which a provisioned runner with no recent report, no live provisioner, no live runner session, and no running job is marked failed by backend maintenance.',\n default: 300,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT: num({\n desc: 'Maximum number of stale provisioned runners the maintenance worker marks failed in one run. Higher values clear backlogs faster but hold database locks longer.',\n default: 100,\n }),\n RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between runner session liveness writes from job request polls. Set this lower than RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS so active idle runners stay fresh.',\n default: 10,\n }),\n RUNNER_SESSION_MANUAL_RETENTION_DAYS: num({\n desc: 'How long manual runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 30,\n }),\n RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS: num({\n desc: 'How long ephemeral runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 7,\n }),\n RUNNER_SESSION_GC_BATCH_SIZE: num({\n desc: 'Maximum number of expired runner sessions maintenance deletes in one pass.',\n default: 1000,\n }),\n RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS: num({\n desc: 'How long consumed or expired ephemeral registration tokens are retained for audit and debugging before maintenance deletes them, in days. Active tokens that are neither consumed nor expired are never deleted. This window is independent of the runner-session retention windows.',\n default: 7,\n }),\n RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE: num({\n desc: 'Maximum number of consumed or expired ephemeral registration tokens maintenance deletes in one pass.',\n default: 1000,\n }),\n PROVISIONER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active provisioners from recent authenticated requests.',\n default: 120,\n }),\n PROVISIONER_LAST_SEEN_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between last-seen writes for one provisioner token.',\n default: 10,\n }),\n PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED: bool({\n desc: 'Whether runners_provisioned_runner_count_divergence includes template_key as a metric label. Use true or false. Defaults to false because template keys can create high-cardinality metric series. Set true only when template keys are bounded and stable.',\n default: false,\n }),\n});\n\nif (\n !Number.isInteger(config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS) ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS < 1 ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS >\n EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS\n) {\n throw new Error(\n `EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS (${config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS}) must be a whole number of seconds between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n );\n}\n\nif (\n !Number.isInteger(config.REGISTRATION_TOKEN_BATCH_MAX) ||\n config.REGISTRATION_TOKEN_BATCH_MAX < 1 ||\n config.REGISTRATION_TOKEN_BATCH_MAX > REGISTRATION_TOKEN_BATCH_HARD_MAX\n) {\n throw new Error(\n `REGISTRATION_TOKEN_BATCH_MAX (${config.REGISTRATION_TOKEN_BATCH_MAX}) must be a whole number between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n );\n}\n\nfor (const [name, value] of [\n ['PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS', config.PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS],\n ['PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS', config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS],\n ['EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS', config.EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS],\n [\n 'EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS',\n config.EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS,\n ],\n ['RUNNERS_RATE_LIMIT_TIMEOUT_MS', config.RUNNERS_RATE_LIMIT_TIMEOUT_MS],\n] as const) {\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`${name} (${value}) must be a whole number >= 1.`);\n }\n}\n\nif (!Number.isInteger(config.RESERVATION_TTL_SECONDS) || config.RESERVATION_TTL_SECONDS < 1) {\n throw new Error(\n `RESERVATION_TTL_SECONDS (${config.RESERVATION_TTL_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS) ||\n config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS < 0\n) {\n throw new Error(\n `RESERVATION_LONG_POLL_MAX_WAIT_SECONDS (${config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS}) must be a whole number of seconds >= 0.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_INTERVAL_MS) ||\n config.RESERVATION_POLL_INTERVAL_MS < 1\n) {\n throw new Error(\n `RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}) must be a whole number of milliseconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_MAX_INTERVAL_MS) ||\n config.RESERVATION_POLL_MAX_INTERVAL_MS < config.RESERVATION_POLL_INTERVAL_MS\n) {\n throw new Error(\n `RESERVATION_POLL_MAX_INTERVAL_MS (${config.RESERVATION_POLL_MAX_INTERVAL_MS}) must be a whole number of milliseconds >= RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}).`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_ACTIVE_WINDOW_SECONDS) ||\n config.RUNNER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_ACTIVE_WINDOW_SECONDS (${config.RUNNER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS) ||\n config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS (${config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS) ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS < 1 ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS >= STUCK_JOB_THRESHOLD_SECONDS\n) {\n throw new Error(\n `RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS (${config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS}) must be a whole number of seconds >= 1 and < ${STUCK_JOB_THRESHOLD_SECONDS}.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS) ||\n config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS (${config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT (${config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS) ||\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_MANUAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_MANUAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_MANUAL_RETENTION_DAYS (${config.RUNNER_SESSION_MANUAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS (${config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_GC_BATCH_SIZE) ||\n config.RUNNER_SESSION_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_SESSION_GC_BATCH_SIZE (${config.RUNNER_SESSION_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS) ||\n config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS (${config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE) ||\n config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE (${config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_ACTIVE_WINDOW_SECONDS) ||\n config.PROVISIONER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_ACTIVE_WINDOW_SECONDS (${config.PROVISIONER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS) ||\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}).`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}).`,\n );\n}\n"],"names":["REGISTRATION_TOKEN_BATCH_HARD_MAX","bool","createConfig","num","str","STUCK_JOB_THRESHOLD_SECONDS","EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS","config","EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS","desc","default","REGISTRATION_TOKEN_BATCH_MAX","PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS","PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS","EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS","EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS","RUNNERS_RATE_LIMIT_TIMEOUT_MS","RATE_LIMIT_IDENTIFIER_SECRET","undefined","RESERVATION_TTL_SECONDS","RESERVATION_LONG_POLL_MAX_WAIT_SECONDS","RESERVATION_POLL_INTERVAL_MS","RESERVATION_POLL_MAX_INTERVAL_MS","RUNNER_ACTIVE_WINDOW_SECONDS","RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS","RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS","RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT","RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS","RUNNER_SESSION_MANUAL_RETENTION_DAYS","RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS","RUNNER_SESSION_GC_BATCH_SIZE","RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS","RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE","PROVISIONER_ACTIVE_WINDOW_SECONDS","PROVISIONER_LAST_SEEN_THROTTLE_SECONDS","PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED","Number","isInteger","Error","name","value"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type ActiveProvisionedRunnerTemplateCount } from '#db/provisioned-runners.js';
2
+ import { type DemandStat, type ReservationGrant, type ReservationTemplate } from '#db/reservations.js';
3
+ export interface PollDemandParams {
4
+ workspaceId: string;
5
+ provisionerId: string;
6
+ maxReservations: number;
7
+ waitSeconds?: number | undefined;
8
+ ttlSeconds: number;
9
+ terminateIntentLimit: number;
10
+ templates: ReservationTemplate[];
11
+ signal: AbortSignal;
12
+ }
13
+ export interface PollDemandResult {
14
+ stats: DemandStat[];
15
+ reservations: ReservationGrant[];
16
+ terminateProvisionedRunnerIds: string[];
17
+ }
18
+ export interface ProvisionedRunnerCountDivergence {
19
+ templateKey: string;
20
+ state: 'starting' | 'running';
21
+ direction: 'backend-higher' | 'advertised-higher';
22
+ delta: number;
23
+ }
24
+ export declare function pollDemand(params: PollDemandParams): Promise<PollDemandResult>;
25
+ export declare function releaseReservationGrants(reservations: ReservationGrant[]): Promise<void>;
26
+ export declare function shouldReturn(result: PollDemandResult, maxReservations: number, totalCapacity: number, deadlinePassed: boolean): boolean;
27
+ export declare function nextBackoffInterval(ms: number): number;
28
+ export declare function withJitter(ms: number): number;
29
+ export declare function calculateProvisionedRunnerCountDivergences(params: {
30
+ advertisedTemplates: ReservationTemplate[];
31
+ backendCounts: ActiveProvisionedRunnerTemplateCount[];
32
+ }): ProvisionedRunnerCountDivergence[];
33
+ //# sourceMappingURL=demand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demand.d.ts","sourceRoot":"","sources":["../../src/core/demand.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,oCAAoC,EAI1C,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,6BAA6B,EAAE,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,SAAS,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAsB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+EpF;AAED,wBAAsB,wBAAwB,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9F;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,OAAO,GACtB,OAAO,CAQT;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAgB,0CAA0C,CAAC,MAAM,EAAE;IACjE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;IAC3C,aAAa,EAAE,oCAAoC,EAAE,CAAC;CACvD,GAAG,gCAAgC,EAAE,CA4BrC"}