@smthrs/control 0.0.0-stage → 1.0.0-rc.3

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 (418) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/LICENSE +21 -0
  3. package/README.md +168 -2
  4. package/dist/cjs/ApprovalAuthority.d.ts +73 -0
  5. package/dist/cjs/ApprovalAuthority.d.ts.map +1 -0
  6. package/dist/cjs/ApprovalAuthority.js +62 -0
  7. package/dist/cjs/ApprovalAuthority.js.map +7 -0
  8. package/dist/cjs/Cancellation.d.ts +107 -0
  9. package/dist/cjs/Cancellation.d.ts.map +1 -0
  10. package/dist/cjs/Cancellation.js +72 -0
  11. package/dist/cjs/Cancellation.js.map +7 -0
  12. package/dist/cjs/Channels.d.ts +170 -0
  13. package/dist/cjs/Channels.d.ts.map +1 -0
  14. package/dist/cjs/Channels.js +278 -0
  15. package/dist/cjs/Channels.js.map +7 -0
  16. package/dist/cjs/Control.d.ts +202 -0
  17. package/dist/cjs/Control.d.ts.map +1 -0
  18. package/dist/cjs/Control.js +47 -0
  19. package/dist/cjs/Control.js.map +7 -0
  20. package/dist/cjs/ControlClient.d.ts +52 -0
  21. package/dist/cjs/ControlClient.d.ts.map +1 -0
  22. package/dist/cjs/ControlClient.js +191 -0
  23. package/dist/cjs/ControlClient.js.map +7 -0
  24. package/dist/cjs/ControlError.d.ts +318 -0
  25. package/dist/cjs/ControlError.d.ts.map +1 -0
  26. package/dist/cjs/ControlError.js +249 -0
  27. package/dist/cjs/ControlError.js.map +7 -0
  28. package/dist/cjs/ControlExecutor.d.ts +372 -0
  29. package/dist/cjs/ControlExecutor.d.ts.map +1 -0
  30. package/dist/cjs/ControlExecutor.js +123 -0
  31. package/dist/cjs/ControlExecutor.js.map +7 -0
  32. package/dist/cjs/ControlFacts.d.ts +454 -0
  33. package/dist/cjs/ControlFacts.d.ts.map +1 -0
  34. package/dist/cjs/ControlFacts.js +261 -0
  35. package/dist/cjs/ControlFacts.js.map +7 -0
  36. package/dist/cjs/ControlLive.d.ts +23 -0
  37. package/dist/cjs/ControlLive.d.ts.map +1 -0
  38. package/dist/cjs/ControlLive.js +1280 -0
  39. package/dist/cjs/ControlLive.js.map +7 -0
  40. package/dist/cjs/ControlRpcs.d.ts +1204 -0
  41. package/dist/cjs/ControlRpcs.d.ts.map +1 -0
  42. package/dist/cjs/ControlRpcs.js +247 -0
  43. package/dist/cjs/ControlRpcs.js.map +7 -0
  44. package/dist/cjs/ControlRuntime.d.ts +635 -0
  45. package/dist/cjs/ControlRuntime.d.ts.map +1 -0
  46. package/dist/cjs/ControlRuntime.js +740 -0
  47. package/dist/cjs/ControlRuntime.js.map +7 -0
  48. package/dist/cjs/ControlSchema.d.ts +2642 -0
  49. package/dist/cjs/ControlSchema.d.ts.map +1 -0
  50. package/dist/cjs/ControlSchema.js +634 -0
  51. package/dist/cjs/ControlSchema.js.map +7 -0
  52. package/dist/cjs/ControlServer.d.ts +51 -0
  53. package/dist/cjs/ControlServer.d.ts.map +1 -0
  54. package/dist/cjs/ControlServer.js +121 -0
  55. package/dist/cjs/ControlServer.js.map +7 -0
  56. package/dist/cjs/Credential.d.ts +136 -0
  57. package/dist/cjs/Credential.d.ts.map +1 -0
  58. package/dist/cjs/Credential.js +168 -0
  59. package/dist/cjs/Credential.js.map +7 -0
  60. package/dist/cjs/CredentialCipher.d.ts +90 -0
  61. package/dist/cjs/CredentialCipher.d.ts.map +1 -0
  62. package/dist/cjs/CredentialCipher.js +45 -0
  63. package/dist/cjs/CredentialCipher.js.map +7 -0
  64. package/dist/cjs/CredentialStore.d.ts +97 -0
  65. package/dist/cjs/CredentialStore.d.ts.map +1 -0
  66. package/dist/cjs/CredentialStore.js +81 -0
  67. package/dist/cjs/CredentialStore.js.map +7 -0
  68. package/dist/cjs/DispatchReader.d.ts +112 -0
  69. package/dist/cjs/DispatchReader.d.ts.map +1 -0
  70. package/dist/cjs/DispatchReader.js +45 -0
  71. package/dist/cjs/DispatchReader.js.map +7 -0
  72. package/dist/cjs/Health.d.ts +333 -0
  73. package/dist/cjs/Health.d.ts.map +1 -0
  74. package/dist/cjs/Health.js +311 -0
  75. package/dist/cjs/Health.js.map +7 -0
  76. package/dist/cjs/JevSessionChecker.d.ts +57 -0
  77. package/dist/cjs/JevSessionChecker.d.ts.map +1 -0
  78. package/dist/cjs/JevSessionChecker.js +113 -0
  79. package/dist/cjs/JevSessionChecker.js.map +7 -0
  80. package/dist/cjs/Lineage.d.ts +131 -0
  81. package/dist/cjs/Lineage.d.ts.map +1 -0
  82. package/dist/cjs/Lineage.js +81 -0
  83. package/dist/cjs/Lineage.js.map +7 -0
  84. package/dist/cjs/Migrations.d.ts +34 -0
  85. package/dist/cjs/Migrations.d.ts.map +1 -0
  86. package/dist/cjs/Migrations.js +60 -0
  87. package/dist/cjs/Migrations.js.map +7 -0
  88. package/dist/cjs/Monitor.d.ts +282 -0
  89. package/dist/cjs/Monitor.d.ts.map +1 -0
  90. package/dist/cjs/Monitor.js +283 -0
  91. package/dist/cjs/Monitor.js.map +7 -0
  92. package/dist/cjs/ScopedToken.d.ts +193 -0
  93. package/dist/cjs/ScopedToken.d.ts.map +1 -0
  94. package/dist/cjs/ScopedToken.js +135 -0
  95. package/dist/cjs/ScopedToken.js.map +7 -0
  96. package/dist/cjs/SqlControlRuntime.d.ts +161 -0
  97. package/dist/cjs/SqlControlRuntime.d.ts.map +1 -0
  98. package/dist/cjs/SqlControlRuntime.js +1521 -0
  99. package/dist/cjs/SqlControlRuntime.js.map +7 -0
  100. package/dist/cjs/SqlCredentialStore.d.ts +43 -0
  101. package/dist/cjs/SqlCredentialStore.d.ts.map +1 -0
  102. package/dist/cjs/SqlCredentialStore.js +113 -0
  103. package/dist/cjs/SqlCredentialStore.js.map +7 -0
  104. package/dist/cjs/Steering.d.ts +69 -0
  105. package/dist/cjs/Steering.d.ts.map +1 -0
  106. package/dist/cjs/Steering.js +49 -0
  107. package/dist/cjs/Steering.js.map +7 -0
  108. package/dist/cjs/SystemFlows.d.ts +223 -0
  109. package/dist/cjs/SystemFlows.d.ts.map +1 -0
  110. package/dist/cjs/SystemFlows.js +195 -0
  111. package/dist/cjs/SystemFlows.js.map +7 -0
  112. package/dist/cjs/WebCryptoCipher.d.ts +49 -0
  113. package/dist/cjs/WebCryptoCipher.d.ts.map +1 -0
  114. package/dist/cjs/WebCryptoCipher.js +129 -0
  115. package/dist/cjs/WebCryptoCipher.js.map +7 -0
  116. package/dist/cjs/WebhookChannel.d.ts +113 -0
  117. package/dist/cjs/WebhookChannel.d.ts.map +1 -0
  118. package/dist/cjs/WebhookChannel.js +98 -0
  119. package/dist/cjs/WebhookChannel.js.map +7 -0
  120. package/dist/cjs/index.d.ts +160 -0
  121. package/dist/cjs/index.d.ts.map +1 -0
  122. package/dist/cjs/index.js +91 -0
  123. package/dist/cjs/index.js.map +7 -0
  124. package/dist/cjs/internal/MutationBoundary.d.ts +27 -0
  125. package/dist/cjs/internal/MutationBoundary.d.ts.map +1 -0
  126. package/dist/cjs/internal/MutationBoundary.js +50 -0
  127. package/dist/cjs/internal/MutationBoundary.js.map +7 -0
  128. package/dist/cjs/internal/activeFibers.d.ts +12 -0
  129. package/dist/cjs/internal/activeFibers.d.ts.map +1 -0
  130. package/dist/cjs/internal/activeFibers.js +30 -0
  131. package/dist/cjs/internal/activeFibers.js.map +7 -0
  132. package/dist/cjs/internal/issues.d.ts +28 -0
  133. package/dist/cjs/internal/issues.d.ts.map +1 -0
  134. package/dist/cjs/internal/issues.js +34 -0
  135. package/dist/cjs/internal/issues.js.map +7 -0
  136. package/dist/cjs/internal/planning.d.ts +347 -0
  137. package/dist/cjs/internal/planning.d.ts.map +1 -0
  138. package/dist/cjs/internal/planning.js +137 -0
  139. package/dist/cjs/internal/planning.js.map +7 -0
  140. package/dist/cjs/internal/sqlSchemaErrors.d.ts +18 -0
  141. package/dist/cjs/internal/sqlSchemaErrors.d.ts.map +1 -0
  142. package/dist/cjs/internal/sqlSchemaErrors.js +40 -0
  143. package/dist/cjs/internal/sqlSchemaErrors.js.map +7 -0
  144. package/dist/cjs/migrations/0001_control_tables.d.ts +18 -0
  145. package/dist/cjs/migrations/0001_control_tables.d.ts.map +1 -0
  146. package/dist/cjs/migrations/0001_control_tables.js +115 -0
  147. package/dist/cjs/migrations/0001_control_tables.js.map +7 -0
  148. package/dist/cjs/migrations/0002_run_keys.d.ts +15 -0
  149. package/dist/cjs/migrations/0002_run_keys.d.ts.map +1 -0
  150. package/dist/cjs/migrations/0002_run_keys.js +44 -0
  151. package/dist/cjs/migrations/0002_run_keys.js.map +7 -0
  152. package/dist/cjs/migrations/0003_signal_commands.d.ts +13 -0
  153. package/dist/cjs/migrations/0003_signal_commands.d.ts.map +1 -0
  154. package/dist/cjs/migrations/0003_signal_commands.js +50 -0
  155. package/dist/cjs/migrations/0003_signal_commands.js.map +7 -0
  156. package/dist/cjs/migrations/0004_approval_decisions.d.ts +13 -0
  157. package/dist/cjs/migrations/0004_approval_decisions.d.ts.map +1 -0
  158. package/dist/cjs/migrations/0004_approval_decisions.js +45 -0
  159. package/dist/cjs/migrations/0004_approval_decisions.js.map +7 -0
  160. package/dist/cjs/migrations/0005_signal_principals.d.ts +18 -0
  161. package/dist/cjs/migrations/0005_signal_principals.d.ts.map +1 -0
  162. package/dist/cjs/migrations/0005_signal_principals.js +45 -0
  163. package/dist/cjs/migrations/0005_signal_principals.js.map +7 -0
  164. package/dist/cjs/migrations/0006_run_principals.d.ts +18 -0
  165. package/dist/cjs/migrations/0006_run_principals.d.ts.map +1 -0
  166. package/dist/cjs/migrations/0006_run_principals.js +49 -0
  167. package/dist/cjs/migrations/0006_run_principals.js.map +7 -0
  168. package/dist/cjs/migrations/0007_resume_consent.d.ts +18 -0
  169. package/dist/cjs/migrations/0007_resume_consent.d.ts.map +1 -0
  170. package/dist/cjs/migrations/0007_resume_consent.js +46 -0
  171. package/dist/cjs/migrations/0007_resume_consent.js.map +7 -0
  172. package/dist/cjs/package.json +1 -0
  173. package/dist/cjs/test/TestControl.d.ts +19 -0
  174. package/dist/cjs/test/TestControl.d.ts.map +1 -0
  175. package/dist/cjs/test/TestControl.js +62 -0
  176. package/dist/cjs/test/TestControl.js.map +7 -0
  177. package/dist/esm/ApprovalAuthority.d.ts +73 -0
  178. package/dist/esm/ApprovalAuthority.d.ts.map +1 -0
  179. package/dist/esm/ApprovalAuthority.js +72 -0
  180. package/dist/esm/ApprovalAuthority.js.map +1 -0
  181. package/dist/esm/Cancellation.d.ts +107 -0
  182. package/dist/esm/Cancellation.d.ts.map +1 -0
  183. package/dist/esm/Cancellation.js +116 -0
  184. package/dist/esm/Cancellation.js.map +1 -0
  185. package/dist/esm/Channels.d.ts +170 -0
  186. package/dist/esm/Channels.d.ts.map +1 -0
  187. package/dist/esm/Channels.js +312 -0
  188. package/dist/esm/Channels.js.map +1 -0
  189. package/dist/esm/Control.d.ts +202 -0
  190. package/dist/esm/Control.d.ts.map +1 -0
  191. package/dist/esm/Control.js +42 -0
  192. package/dist/esm/Control.js.map +1 -0
  193. package/dist/esm/ControlClient.d.ts +52 -0
  194. package/dist/esm/ControlClient.d.ts.map +1 -0
  195. package/dist/esm/ControlClient.js +217 -0
  196. package/dist/esm/ControlClient.js.map +1 -0
  197. package/dist/esm/ControlError.d.ts +318 -0
  198. package/dist/esm/ControlError.d.ts.map +1 -0
  199. package/dist/esm/ControlError.js +359 -0
  200. package/dist/esm/ControlError.js.map +1 -0
  201. package/dist/esm/ControlExecutor.d.ts +372 -0
  202. package/dist/esm/ControlExecutor.d.ts.map +1 -0
  203. package/dist/esm/ControlExecutor.js +212 -0
  204. package/dist/esm/ControlExecutor.js.map +1 -0
  205. package/dist/esm/ControlFacts.d.ts +454 -0
  206. package/dist/esm/ControlFacts.d.ts.map +1 -0
  207. package/dist/esm/ControlFacts.js +324 -0
  208. package/dist/esm/ControlFacts.js.map +1 -0
  209. package/dist/esm/ControlLive.d.ts +23 -0
  210. package/dist/esm/ControlLive.d.ts.map +1 -0
  211. package/dist/esm/ControlLive.js +1585 -0
  212. package/dist/esm/ControlLive.js.map +1 -0
  213. package/dist/esm/ControlRpcs.d.ts +1204 -0
  214. package/dist/esm/ControlRpcs.d.ts.map +1 -0
  215. package/dist/esm/ControlRpcs.js +299 -0
  216. package/dist/esm/ControlRpcs.js.map +1 -0
  217. package/dist/esm/ControlRuntime.d.ts +635 -0
  218. package/dist/esm/ControlRuntime.d.ts.map +1 -0
  219. package/dist/esm/ControlRuntime.js +807 -0
  220. package/dist/esm/ControlRuntime.js.map +1 -0
  221. package/dist/esm/ControlSchema.d.ts +2642 -0
  222. package/dist/esm/ControlSchema.d.ts.map +1 -0
  223. package/dist/esm/ControlSchema.js +1030 -0
  224. package/dist/esm/ControlSchema.js.map +1 -0
  225. package/dist/esm/ControlServer.d.ts +51 -0
  226. package/dist/esm/ControlServer.d.ts.map +1 -0
  227. package/dist/esm/ControlServer.js +145 -0
  228. package/dist/esm/ControlServer.js.map +1 -0
  229. package/dist/esm/Credential.d.ts +136 -0
  230. package/dist/esm/Credential.d.ts.map +1 -0
  231. package/dist/esm/Credential.js +190 -0
  232. package/dist/esm/Credential.js.map +1 -0
  233. package/dist/esm/CredentialCipher.d.ts +90 -0
  234. package/dist/esm/CredentialCipher.d.ts.map +1 -0
  235. package/dist/esm/CredentialCipher.js +56 -0
  236. package/dist/esm/CredentialCipher.js.map +1 -0
  237. package/dist/esm/CredentialStore.d.ts +97 -0
  238. package/dist/esm/CredentialStore.d.ts.map +1 -0
  239. package/dist/esm/CredentialStore.js +101 -0
  240. package/dist/esm/CredentialStore.js.map +1 -0
  241. package/dist/esm/DispatchReader.d.ts +112 -0
  242. package/dist/esm/DispatchReader.d.ts.map +1 -0
  243. package/dist/esm/DispatchReader.js +76 -0
  244. package/dist/esm/DispatchReader.js.map +1 -0
  245. package/dist/esm/Health.d.ts +333 -0
  246. package/dist/esm/Health.d.ts.map +1 -0
  247. package/dist/esm/Health.js +400 -0
  248. package/dist/esm/Health.js.map +1 -0
  249. package/dist/esm/JevSessionChecker.d.ts +57 -0
  250. package/dist/esm/JevSessionChecker.d.ts.map +1 -0
  251. package/dist/esm/JevSessionChecker.js +108 -0
  252. package/dist/esm/JevSessionChecker.js.map +1 -0
  253. package/dist/esm/Lineage.d.ts +131 -0
  254. package/dist/esm/Lineage.d.ts.map +1 -0
  255. package/dist/esm/Lineage.js +174 -0
  256. package/dist/esm/Lineage.js.map +1 -0
  257. package/dist/esm/Migrations.d.ts +34 -0
  258. package/dist/esm/Migrations.d.ts.map +1 -0
  259. package/dist/esm/Migrations.js +53 -0
  260. package/dist/esm/Migrations.js.map +1 -0
  261. package/dist/esm/Monitor.d.ts +282 -0
  262. package/dist/esm/Monitor.d.ts.map +1 -0
  263. package/dist/esm/Monitor.js +415 -0
  264. package/dist/esm/Monitor.js.map +1 -0
  265. package/dist/esm/ScopedToken.d.ts +193 -0
  266. package/dist/esm/ScopedToken.d.ts.map +1 -0
  267. package/dist/esm/ScopedToken.js +224 -0
  268. package/dist/esm/ScopedToken.js.map +1 -0
  269. package/dist/esm/SqlControlRuntime.d.ts +161 -0
  270. package/dist/esm/SqlControlRuntime.d.ts.map +1 -0
  271. package/dist/esm/SqlControlRuntime.js +1756 -0
  272. package/dist/esm/SqlControlRuntime.js.map +1 -0
  273. package/dist/esm/SqlCredentialStore.d.ts +43 -0
  274. package/dist/esm/SqlCredentialStore.d.ts.map +1 -0
  275. package/dist/esm/SqlCredentialStore.js +97 -0
  276. package/dist/esm/SqlCredentialStore.js.map +1 -0
  277. package/dist/esm/Steering.d.ts +69 -0
  278. package/dist/esm/Steering.d.ts.map +1 -0
  279. package/dist/esm/Steering.js +89 -0
  280. package/dist/esm/Steering.js.map +1 -0
  281. package/dist/esm/SystemFlows.d.ts +223 -0
  282. package/dist/esm/SystemFlows.d.ts.map +1 -0
  283. package/dist/esm/SystemFlows.js +198 -0
  284. package/dist/esm/SystemFlows.js.map +1 -0
  285. package/dist/esm/WebCryptoCipher.d.ts +49 -0
  286. package/dist/esm/WebCryptoCipher.d.ts.map +1 -0
  287. package/dist/esm/WebCryptoCipher.js +123 -0
  288. package/dist/esm/WebCryptoCipher.js.map +1 -0
  289. package/dist/esm/WebhookChannel.d.ts +113 -0
  290. package/dist/esm/WebhookChannel.d.ts.map +1 -0
  291. package/dist/esm/WebhookChannel.js +109 -0
  292. package/dist/esm/WebhookChannel.js.map +1 -0
  293. package/dist/esm/index.d.ts +160 -0
  294. package/dist/esm/index.d.ts.map +1 -0
  295. package/dist/esm/index.js +160 -0
  296. package/dist/esm/index.js.map +1 -0
  297. package/dist/esm/internal/MutationBoundary.d.ts +27 -0
  298. package/dist/esm/internal/MutationBoundary.d.ts.map +1 -0
  299. package/dist/esm/internal/MutationBoundary.js +40 -0
  300. package/dist/esm/internal/MutationBoundary.js.map +1 -0
  301. package/dist/esm/internal/activeFibers.d.ts +12 -0
  302. package/dist/esm/internal/activeFibers.d.ts.map +1 -0
  303. package/dist/esm/internal/activeFibers.js +17 -0
  304. package/dist/esm/internal/activeFibers.js.map +1 -0
  305. package/dist/esm/internal/issues.d.ts +28 -0
  306. package/dist/esm/internal/issues.d.ts.map +1 -0
  307. package/dist/esm/internal/issues.js +35 -0
  308. package/dist/esm/internal/issues.js.map +1 -0
  309. package/dist/esm/internal/planning.d.ts +347 -0
  310. package/dist/esm/internal/planning.d.ts.map +1 -0
  311. package/dist/esm/internal/planning.js +199 -0
  312. package/dist/esm/internal/planning.js.map +1 -0
  313. package/dist/esm/internal/sqlSchemaErrors.d.ts +18 -0
  314. package/dist/esm/internal/sqlSchemaErrors.d.ts.map +1 -0
  315. package/dist/esm/internal/sqlSchemaErrors.js +38 -0
  316. package/dist/esm/internal/sqlSchemaErrors.js.map +1 -0
  317. package/dist/esm/migrations/0001_control_tables.d.ts +18 -0
  318. package/dist/esm/migrations/0001_control_tables.d.ts.map +1 -0
  319. package/dist/esm/migrations/0001_control_tables.js +96 -0
  320. package/dist/esm/migrations/0001_control_tables.js.map +1 -0
  321. package/dist/esm/migrations/0002_run_keys.d.ts +15 -0
  322. package/dist/esm/migrations/0002_run_keys.d.ts.map +1 -0
  323. package/dist/esm/migrations/0002_run_keys.js +22 -0
  324. package/dist/esm/migrations/0002_run_keys.js.map +1 -0
  325. package/dist/esm/migrations/0003_signal_commands.d.ts +13 -0
  326. package/dist/esm/migrations/0003_signal_commands.d.ts.map +1 -0
  327. package/dist/esm/migrations/0003_signal_commands.js +26 -0
  328. package/dist/esm/migrations/0003_signal_commands.js.map +1 -0
  329. package/dist/esm/migrations/0004_approval_decisions.d.ts +13 -0
  330. package/dist/esm/migrations/0004_approval_decisions.d.ts.map +1 -0
  331. package/dist/esm/migrations/0004_approval_decisions.js +25 -0
  332. package/dist/esm/migrations/0004_approval_decisions.js.map +1 -0
  333. package/dist/esm/migrations/0005_signal_principals.d.ts +18 -0
  334. package/dist/esm/migrations/0005_signal_principals.d.ts.map +1 -0
  335. package/dist/esm/migrations/0005_signal_principals.js +27 -0
  336. package/dist/esm/migrations/0005_signal_principals.js.map +1 -0
  337. package/dist/esm/migrations/0006_run_principals.d.ts +18 -0
  338. package/dist/esm/migrations/0006_run_principals.d.ts.map +1 -0
  339. package/dist/esm/migrations/0006_run_principals.js +30 -0
  340. package/dist/esm/migrations/0006_run_principals.js.map +1 -0
  341. package/dist/esm/migrations/0007_resume_consent.d.ts +18 -0
  342. package/dist/esm/migrations/0007_resume_consent.d.ts.map +1 -0
  343. package/dist/esm/migrations/0007_resume_consent.js +27 -0
  344. package/dist/esm/migrations/0007_resume_consent.js.map +1 -0
  345. package/dist/esm/test/TestControl.d.ts +19 -0
  346. package/dist/esm/test/TestControl.d.ts.map +1 -0
  347. package/dist/esm/test/TestControl.js +30 -0
  348. package/dist/esm/test/TestControl.js.map +1 -0
  349. package/docs/README.md +189 -0
  350. package/docs/api.md +982 -0
  351. package/docs/concepts/authority.md +109 -0
  352. package/docs/concepts/cancellation.md +129 -0
  353. package/docs/concepts/lineage.md +132 -0
  354. package/docs/concepts/ownership.md +139 -0
  355. package/docs/concepts/projections.md +203 -0
  356. package/docs/concepts/receipts.md +128 -0
  357. package/docs/guides/approvals.md +284 -0
  358. package/docs/guides/cancel-and-resume.md +162 -0
  359. package/docs/guides/durable-storage.md +147 -0
  360. package/docs/guides/implement-an-executor.md +173 -0
  361. package/docs/guides/ingest-a-webhook.md +177 -0
  362. package/docs/guides/list-runs.md +160 -0
  363. package/docs/guides/monitor-runs.md +176 -0
  364. package/docs/guides/observe-health.md +147 -0
  365. package/docs/guides/postgres-tests.md +5 -0
  366. package/docs/guides/serve-over-rpc.md +220 -0
  367. package/docs/guides/signal-a-run.md +53 -0
  368. package/docs/guides/steer-a-run.md +138 -0
  369. package/docs/guides/store-credentials.md +164 -0
  370. package/docs/guides/testing.md +139 -0
  371. package/docs/guides/watch-a-run.md +154 -0
  372. package/docs/installation.md +106 -0
  373. package/docs/quickstart.md +163 -0
  374. package/docs/troubleshooting.md +208 -0
  375. package/package.json +405 -3
  376. package/src/ApprovalAuthority.ts +114 -0
  377. package/src/Cancellation.ts +172 -0
  378. package/src/Channels.ts +493 -0
  379. package/src/Control.ts +337 -0
  380. package/src/ControlClient.ts +319 -0
  381. package/src/ControlError.ts +378 -0
  382. package/src/ControlExecutor.ts +490 -0
  383. package/src/ControlFacts.ts +383 -0
  384. package/src/ControlLive.ts +2113 -0
  385. package/src/ControlRpcs.ts +443 -0
  386. package/src/ControlRuntime.ts +1597 -0
  387. package/src/ControlSchema.ts +1380 -0
  388. package/src/ControlServer.ts +182 -0
  389. package/src/Credential.ts +310 -0
  390. package/src/CredentialCipher.ts +110 -0
  391. package/src/CredentialStore.ts +152 -0
  392. package/src/DispatchReader.ts +122 -0
  393. package/src/Health.ts +591 -0
  394. package/src/JevSessionChecker.ts +127 -0
  395. package/src/Lineage.ts +203 -0
  396. package/src/Migrations.ts +56 -0
  397. package/src/Monitor.ts +600 -0
  398. package/src/ScopedToken.ts +306 -0
  399. package/src/SqlControlRuntime.ts +2476 -0
  400. package/src/SqlCredentialStore.ts +148 -0
  401. package/src/Steering.ts +96 -0
  402. package/src/SystemFlows.ts +225 -0
  403. package/src/WebCryptoCipher.ts +169 -0
  404. package/src/WebhookChannel.ts +166 -0
  405. package/src/index.ts +188 -0
  406. package/src/internal/MutationBoundary.ts +46 -0
  407. package/src/internal/activeFibers.ts +22 -0
  408. package/src/internal/issues.ts +40 -0
  409. package/src/internal/planning.ts +262 -0
  410. package/src/internal/sqlSchemaErrors.ts +37 -0
  411. package/src/migrations/0001_control_tables.ts +99 -0
  412. package/src/migrations/0002_run_keys.ts +23 -0
  413. package/src/migrations/0003_signal_commands.ts +27 -0
  414. package/src/migrations/0004_approval_decisions.ts +25 -0
  415. package/src/migrations/0005_signal_principals.ts +27 -0
  416. package/src/migrations/0006_run_principals.ts +31 -0
  417. package/src/migrations/0007_resume_consent.ts +28 -0
  418. package/src/test/TestControl.ts +47 -0
@@ -0,0 +1,400 @@
1
+ /** Observational health contracts shared by durable runs and native sessions.
2
+ * @since 1.0.0
3
+ */
4
+ import * as Sha256 from "@smthrs/crypto/Sha256";
5
+ import * as Fault from "@smthrs/flow/Fault";
6
+ import { Cause, Effect, Metric, Schema } from "effect";
7
+ import { makeJevSessionChecker } from "./JevSessionChecker.js";
8
+ /** Authoritative subject lifecycle.
9
+ * @category schemas
10
+ * @since 1.0.0
11
+ */
12
+ export const SubjectState = Schema.Literals([
13
+ "accepted",
14
+ "running",
15
+ "parked",
16
+ "waiting-approval",
17
+ "completed",
18
+ "failed",
19
+ "cancelled",
20
+ "spawning",
21
+ "exited"
22
+ ]);
23
+ /** Health vocabulary shared with Monitor.
24
+ * @category schemas
25
+ * @since 1.0.0
26
+ */
27
+ export const HealthState = Schema.Literals([
28
+ "healthy",
29
+ "stalled",
30
+ "wedged-node",
31
+ "runaway-loop",
32
+ "awaiting-human",
33
+ "failing",
34
+ "unknown"
35
+ ]);
36
+ /** Only explicit semantic checks establish activity.
37
+ * @category schemas
38
+ * @since 1.0.0
39
+ */
40
+ export const Activity = Schema.Literals(["working", "idle", "needs-input", "unknown"]);
41
+ /** Attention never confers permission to act. `needs-resume` is a run parked over
42
+ * executions its owner released: nothing restarts them until `smthrs runs resume`.
43
+ * @category schemas
44
+ * @since 1.0.0
45
+ */
46
+ export const Attention = Schema.Literals(["none", "awaiting-approval", "needs-input", "needs-resume", "unhealthy"]);
47
+ /** Whether a successful reading still describes this subject.
48
+ * @category schemas
49
+ * @since 1.0.0
50
+ */
51
+ export const Freshness = Schema.Literals(["fresh", "stale", "unobserved"]);
52
+ /** Public reasons; arbitrary exception text and terminal bytes never cross this boundary.
53
+ * @category schemas
54
+ * @since 1.0.0
55
+ */
56
+ export const ReasonCode = Schema.Literals([
57
+ "ok",
58
+ "no-progress",
59
+ "awaiting-reply",
60
+ "prompt-detected",
61
+ "quota-wait",
62
+ "timer-wait",
63
+ "event-wait",
64
+ "released",
65
+ "unreachable",
66
+ "probe-timeout",
67
+ "probe-error",
68
+ "owner-changed"
69
+ ]);
70
+ /** Validated checker output, containing no authority or ordering fields.
71
+ * @category schemas
72
+ * @since 1.0.0
73
+ */
74
+ export const ProbeReport = Schema.Struct({ activity: Activity, reason: Schema.optional(ReasonCode) });
75
+ const Counter = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)));
76
+ /** A host-stamped observation; its journal sequence is supplied by the durable writer.
77
+ * @category schemas
78
+ * @since 1.0.0
79
+ */
80
+ export const HealthObservation = Schema.Struct({
81
+ subjectId: Schema.String,
82
+ state: SubjectState,
83
+ checkerId: Schema.String,
84
+ monitorId: Schema.String,
85
+ incarnation: Schema.String,
86
+ evidenceSeq: Counter,
87
+ observedAt: Counter,
88
+ expiresAt: Counter,
89
+ durationMs: Counter,
90
+ baseHealth: Schema.optional(HealthState),
91
+ outcome: Schema.Literals(["ok", "timeout", "error", "interrupted", "discarded"]),
92
+ report: Schema.optional(ProbeReport),
93
+ reason: Schema.optional(ReasonCode)
94
+ });
95
+ /** The additive wire contract rendered by every status surface.
96
+ * @category schemas
97
+ * @since 1.0.0
98
+ */
99
+ export const StatusRollup = Schema.Struct({
100
+ subjectId: Schema.String,
101
+ state: SubjectState,
102
+ activity: Activity,
103
+ health: HealthState,
104
+ attention: Attention,
105
+ freshness: Freshness,
106
+ reason: Schema.optional(ReasonCode),
107
+ provenance: Schema.optional(Schema.Struct({
108
+ checkerId: Schema.String,
109
+ monitorId: Schema.String,
110
+ observedAt: Counter,
111
+ expiresAt: Counter,
112
+ evidenceSeq: Counter,
113
+ incarnation: Schema.String,
114
+ version: Counter
115
+ })),
116
+ updatedAt: Counter
117
+ });
118
+ /** Durable event type for observational health.
119
+ * @category constants
120
+ * @since 1.0.0
121
+ */
122
+ export const statusObservedEventType = "control.status.observed";
123
+ /** Opaque identity of the authoritative run ownership and lifecycle point being observed.
124
+ * Equality is meaningful; lexical or numeric ordering is not.
125
+ * @category getters
126
+ * @since 1.0.0
127
+ */
128
+ export const runIncarnation = (run) => Sha256.digestSync(JSON.stringify([
129
+ run.runId,
130
+ run.createdAt,
131
+ run.updatedAt,
132
+ run.ownerId ?? null,
133
+ run.parkedBy ?? null,
134
+ run.status,
135
+ run.waitingReason ?? null
136
+ ]));
137
+ /** Invalid trusted configuration fails startup instead of silently running another policy.
138
+ * @category errors
139
+ * @since 1.0.0
140
+ */
141
+ export class HealthConfigurationError extends Schema.TaggedError()("HealthConfigurationError", {
142
+ reason: Schema.Literals(["invalid-policy", "invalid-checker", "invalid-config"])
143
+ }) {
144
+ }
145
+ Fault.register("HealthConfigurationError", "bug");
146
+ /** Safe cadence used by unconfigured hosts.
147
+ * @category constants
148
+ * @since 1.0.0
149
+ */
150
+ export const defaultPolicy = {
151
+ intervalMs: 5_000,
152
+ timeoutMs: 2_000,
153
+ ttlMs: 20_000,
154
+ stallAfterMs: 120_000,
155
+ backoff: { initialMs: 5_000, maxMs: 60_000, factor: 2 }
156
+ };
157
+ /** A known engine wait is a lifecycle fact, not missing progress.
158
+ * @category getters
159
+ * @since 1.0.0
160
+ */
161
+ export const waitReason = (state, waitingReason) => state !== "parked" ? undefined : waitingReason === "quota" ?
162
+ "quota-wait"
163
+ : waitingReason === "timer"
164
+ ? "timer-wait"
165
+ : waitingReason === "event"
166
+ ? "event-wait"
167
+ : undefined;
168
+ /** Flow default observes lifecycle without inventing semantic activity.
169
+ * @category constants
170
+ * @since 1.0.0
171
+ */
172
+ export const lifecycleRunChecker = {
173
+ id: "lifecycle.run",
174
+ probe: (context) => Effect.succeed({ activity: "unknown", reason: waitReason(context.state, context.summary?.waitingReason) ?? "ok" })
175
+ };
176
+ /** Session default never interprets silence or output movement as task activity.
177
+ * @category constants
178
+ * @since 1.0.0
179
+ */
180
+ export const lifecycleSessionChecker = {
181
+ id: "lifecycle.session",
182
+ probe: () => Effect.succeed({ activity: "unknown", reason: "ok" })
183
+ };
184
+ const hostCheckers = (evaluator) => [
185
+ makeJevSessionChecker({ evaluator })
186
+ ];
187
+ /** Checkers every host may bind by id, beyond the lifecycle default it always has.
188
+ *
189
+ * Registration is not a binding. A host opts in by naming one of these as a
190
+ * `HealthBinding.checkerId`; a host that names none keeps the lifecycle
191
+ * default, and no entry here is ever consulted for an unbound subject.
192
+ *
193
+ * @category constants
194
+ * @since 1.0.0
195
+ */
196
+ export const registeredCheckers = hostCheckers(undefined);
197
+ const bounded = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
198
+ const invalid = (reason) => {
199
+ throw new HealthConfigurationError({ reason });
200
+ };
201
+ /** Admit a host registry and all configured bindings. Unknown checker ids use the lifecycle default.
202
+ * @category constructors
203
+ * @since 1.0.0
204
+ */
205
+ export const makeRegistry = (config = {}, kind = "run", evaluator) => {
206
+ const fallback = kind === "run" ? lifecycleRunChecker : lifecycleSessionChecker;
207
+ const checkers = new Map([
208
+ [fallback.id, fallback],
209
+ ...hostCheckers(evaluator).map((checker) => [checker.id, checker])
210
+ ]);
211
+ for (const checker of config.checkers ?? []) {
212
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}$/.test(checker.id) || checkers.has(checker.id))
213
+ invalid("invalid-checker");
214
+ checkers.set(checker.id, checker);
215
+ }
216
+ const resolve = (binding) => {
217
+ const checker = binding === undefined ? fallback : checkers.get(binding.checkerId) ?? fallback;
218
+ const merged = { ...defaultPolicy, ...checker.defaults, ...binding?.policy };
219
+ if (merged.backoff == null || typeof merged.backoff !== "object")
220
+ invalid("invalid-policy");
221
+ const policy = { ...merged, backoff: { ...merged.backoff } };
222
+ if (!bounded(policy.intervalMs, 10, 3_600_000) || !bounded(policy.timeoutMs, 1, 60_000) ||
223
+ !bounded(policy.ttlMs, policy.timeoutMs, 86_400_000) ||
224
+ !bounded(policy.stallAfterMs, policy.intervalMs, 86_400_000) ||
225
+ !bounded(policy.backoff.initialMs, 10, 3_600_000) ||
226
+ !bounded(policy.backoff.maxMs, policy.backoff.initialMs, 3_600_000) ||
227
+ !Number.isFinite(policy.backoff.factor) || policy.backoff.factor < 1 || policy.backoff.factor > 10)
228
+ invalid("invalid-policy");
229
+ let decoded = undefined;
230
+ if (checker !== fallback || binding?.checkerId === fallback.id) {
231
+ if (checker.configSchema !== undefined) {
232
+ try {
233
+ decoded = Schema.decodeUnknownSync(checker.configSchema)(binding?.config);
234
+ }
235
+ catch {
236
+ invalid("invalid-config");
237
+ }
238
+ }
239
+ else if (binding?.config !== undefined)
240
+ invalid("invalid-config");
241
+ }
242
+ return { checker, config: decoded, policy, exposeOutput: binding?.exposeOutput === true };
243
+ };
244
+ const defaults = resolve();
245
+ const bindings = new Map(Object.entries(config.bindings ?? {}).map(([key, value]) => [key, resolve(value)]));
246
+ const maxSubjects = config.limits?.maxSubjects ?? 128;
247
+ const maxConcurrentProbes = config.limits?.maxConcurrentProbes ?? 8;
248
+ if (!bounded(maxSubjects, 1, 500) || !bounded(maxConcurrentProbes, 1, 64))
249
+ invalid("invalid-policy");
250
+ return { resolve: (key) => bindings.get(key) ?? defaults, limits: { maxSubjects, maxConcurrentProbes } };
251
+ };
252
+ /** Failure delay, bounded even when a subject has failed for a long time.
253
+ * @category getters
254
+ * @since 1.0.0
255
+ */
256
+ export const nextDelay = (policy, consecutiveFailures) => consecutiveFailures <= 0 ? policy.intervalMs : Math.max(policy.intervalMs, Math.min(policy.backoff.maxMs, policy.backoff.initialMs * policy.backoff.factor ** Math.min(consecutiveFailures - 1, 32)));
257
+ const outcomes = Metric.counter("smithers.health.probes");
258
+ const durations = Metric.histogram("smithers.health.probe_duration_ms", {
259
+ boundaries: [1, 10, 100, 1_000, 5_000, 60_000]
260
+ });
261
+ const decodeReport = Schema.decodeUnknownSync(ProbeReport);
262
+ /** Evaluate one trusted checker with bounded timeout and safe failure values. Scope interruption propagates.
263
+ * The host must still compare current ownership/lifecycle before durably publishing the returned observation.
264
+ * @category constructors
265
+ * @since 1.0.0
266
+ */
267
+ export const evaluate = (check, context, stamp) => Effect.gen(function* () {
268
+ const subjectId = context.subjectId;
269
+ const state = context.state;
270
+ const captured = { ...stamp };
271
+ const started = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
272
+ const result = yield* Effect.suspend(() => check.checker.probe(context, check.config)).pipe(Effect.flatMap((candidate) => Effect.try({ try: () => decodeReport(candidate), catch: () => "invalid-report" })), Effect.map((report) => ({ outcome: "ok", report })), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause)
273
+ ? Effect.interrupt
274
+ : Effect.succeed({ outcome: "error", reason: "probe-error" })), Effect.timeoutOrElse({
275
+ duration: check.policy.timeoutMs,
276
+ orElse: () => Effect.succeed({ outcome: "timeout", reason: "probe-timeout" })
277
+ }), Effect.tap((outcome) => Effect.annotateCurrentSpan({
278
+ outcome: outcome.outcome,
279
+ activity: "report" in outcome ? outcome.report.activity : "unknown"
280
+ })), Effect.withSpan("smithers.health.probe", {
281
+ attributes: {
282
+ subjectKind: context.session === undefined ? "run" : "session",
283
+ subjectId,
284
+ checkerId: check.checker.id,
285
+ monitorId: captured.monitorId
286
+ }
287
+ }));
288
+ const observedAt = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
289
+ const durationMs = Math.max(0, observedAt - started);
290
+ yield* Metric.update(outcomes.pipe(Metric.withAttributes({ outcome: result.outcome })), 1);
291
+ yield* Metric.update(durations, durationMs);
292
+ return {
293
+ subjectId,
294
+ state,
295
+ checkerId: check.checker.id,
296
+ ...captured,
297
+ observedAt,
298
+ expiresAt: observedAt + check.policy.ttlMs,
299
+ durationMs,
300
+ ...result
301
+ };
302
+ });
303
+ /** Select evidence for the current opaque owner incarnation, breaking equal evidence ties by durable sequence.
304
+ * @category projections
305
+ * @since 1.0.0
306
+ */
307
+ export const latestObservation = (candidates, subjectId, incarnation) => {
308
+ let selected;
309
+ for (const candidate of candidates) {
310
+ const observation = candidate.observation;
311
+ if (observation.subjectId !== subjectId || observation.incarnation !== incarnation ||
312
+ observation.outcome === "discarded")
313
+ continue;
314
+ if (selected === undefined || observation.evidenceSeq > selected.observation.evidenceSeq ||
315
+ observation.evidenceSeq === selected.observation.evidenceSeq && candidate.sequence > selected.sequence)
316
+ selected = candidate;
317
+ }
318
+ return selected;
319
+ };
320
+ /** Pure precedence: lifecycle and approvals win, and stale probes never establish activity.
321
+ * @category projections
322
+ * @since 1.0.0
323
+ */
324
+ export const rollup = (input) => {
325
+ const latest = input.latest;
326
+ const reading = latest?.observation;
327
+ const freshness = reading === undefined ?
328
+ "unobserved" :
329
+ reading.subjectId !== input.subjectId || reading.incarnation !== input.incarnation ||
330
+ reading.state !== input.state ||
331
+ reading.outcome !== "ok" || reading.report === undefined || input.now < reading.observedAt ||
332
+ input.now >= reading.expiresAt ||
333
+ (input.evidenceSeq !== undefined && reading.evidenceSeq < input.evidenceSeq) ?
334
+ "stale" :
335
+ "fresh";
336
+ const terminal = input.state === "completed" || input.state === "failed" || input.state === "cancelled" ||
337
+ input.state === "exited";
338
+ const approval = input.state === "waiting-approval" || input.state === "parked" && input.waitingReason === "approval";
339
+ // Released executions stay parked until an operator resumes the run (#3328).
340
+ const released = input.state === "parked" && input.waitingReason === "released";
341
+ const waiting = waitReason(input.state, input.waitingReason);
342
+ let activity = freshness === "fresh" && !terminal && !approval && !released
343
+ ? reading.report.activity
344
+ : "unknown";
345
+ let health = input.state === "failed" ? "failing" : input.state === "exited" ?
346
+ input.exitCode === 0 ? "healthy" : input.exitCode == null ? "unknown" : "failing" :
347
+ terminal ?
348
+ "healthy" :
349
+ approval || released ?
350
+ "awaiting-human" :
351
+ waiting !== undefined ?
352
+ "healthy" :
353
+ input.state === "parked" && input.waitingReason === undefined ?
354
+ "awaiting-human" :
355
+ freshness !== "fresh"
356
+ ? "unknown"
357
+ : input.baseHealth ?? "unknown";
358
+ const reason = approval
359
+ ? "awaiting-reply"
360
+ : released
361
+ ? "released"
362
+ : waiting ?? (freshness === "fresh" ? reading?.report?.reason : reading?.reason);
363
+ if (!terminal && !approval && !released && waiting === undefined && freshness === "fresh") {
364
+ if (reason === "unreachable" && health !== "awaiting-human")
365
+ health = "failing";
366
+ else if (reason === "no-progress" && health === "healthy")
367
+ health = "stalled";
368
+ }
369
+ if (waiting !== undefined)
370
+ activity = "unknown";
371
+ const attention = approval ? "awaiting-approval" : released ?
372
+ "needs-resume" :
373
+ activity === "needs-input" ?
374
+ "needs-input" :
375
+ ["stalled", "wedged-node", "runaway-loop", "failing"].includes(health)
376
+ ? "unhealthy"
377
+ : "none";
378
+ return {
379
+ subjectId: input.subjectId,
380
+ state: input.state,
381
+ activity,
382
+ health,
383
+ attention,
384
+ freshness,
385
+ ...(reason === undefined ? {} : { reason }),
386
+ ...(reading === undefined ? {} : {
387
+ provenance: {
388
+ checkerId: reading.checkerId,
389
+ monitorId: reading.monitorId,
390
+ observedAt: reading.observedAt,
391
+ expiresAt: reading.expiresAt,
392
+ evidenceSeq: reading.evidenceSeq,
393
+ incarnation: reading.incarnation,
394
+ version: latest.sequence
395
+ }
396
+ }),
397
+ updatedAt: Math.max(input.updatedAt, reading?.observedAt ?? 0)
398
+ };
399
+ };
400
+ //# sourceMappingURL=Health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Health.js","sourceRoot":"","sources":["../../src/Health.ts"],"names":[],"mappings":"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","sourcesContent":["/** Observational health contracts shared by durable runs and native sessions.\n * @since 1.0.0\n */\n\nimport * as Sha256 from \"@smthrs/crypto/Sha256\"\nimport * as Fault from \"@smthrs/flow/Fault\"\nimport type * as Evaluator from \"@smthrs/model/Evaluator\"\nimport { Cause, Effect, Metric, Schema } from \"effect\"\nimport type { ControlEvent, RunSummary } from \"./ControlSchema.ts\"\nimport { makeJevSessionChecker } from \"./JevSessionChecker.ts\"\n\n/** Authoritative subject lifecycle.\n * @category schemas\n * @since 1.0.0\n */\nexport const SubjectState = Schema.Literals([\n \"accepted\",\n \"running\",\n \"parked\",\n \"waiting-approval\",\n \"completed\",\n \"failed\",\n \"cancelled\",\n \"spawning\",\n \"exited\"\n])\n/** Authoritative subject lifecycle.\n * @category models\n * @since 1.0.0\n */\nexport type SubjectState = typeof SubjectState.Type\n/** Health vocabulary shared with Monitor.\n * @category schemas\n * @since 1.0.0\n */\nexport const HealthState = Schema.Literals([\n \"healthy\",\n \"stalled\",\n \"wedged-node\",\n \"runaway-loop\",\n \"awaiting-human\",\n \"failing\",\n \"unknown\"\n])\n/** Derived subject health.\n * @category models\n * @since 1.0.0\n */\nexport type HealthState = typeof HealthState.Type\n/** Only explicit semantic checks establish activity.\n * @category schemas\n * @since 1.0.0\n */\nexport const Activity = Schema.Literals([\"working\", \"idle\", \"needs-input\", \"unknown\"])\n/** Semantic activity.\n * @category models\n * @since 1.0.0\n */\nexport type Activity = typeof Activity.Type\n/** Attention never confers permission to act. `needs-resume` is a run parked over\n * executions its owner released: nothing restarts them until `smthrs runs resume`.\n * @category schemas\n * @since 1.0.0\n */\nexport const Attention = Schema.Literals([\"none\", \"awaiting-approval\", \"needs-input\", \"needs-resume\", \"unhealthy\"])\n/** Human attention.\n * @category models\n * @since 1.0.0\n */\nexport type Attention = typeof Attention.Type\n/** Whether a successful reading still describes this subject.\n * @category schemas\n * @since 1.0.0\n */\nexport const Freshness = Schema.Literals([\"fresh\", \"stale\", \"unobserved\"])\n/** Reading freshness.\n * @category models\n * @since 1.0.0\n */\nexport type Freshness = typeof Freshness.Type\n/** Public reasons; arbitrary exception text and terminal bytes never cross this boundary.\n * @category schemas\n * @since 1.0.0\n */\nexport const ReasonCode = Schema.Literals([\n \"ok\",\n \"no-progress\",\n \"awaiting-reply\",\n \"prompt-detected\",\n \"quota-wait\",\n \"timer-wait\",\n \"event-wait\",\n \"released\",\n \"unreachable\",\n \"probe-timeout\",\n \"probe-error\",\n \"owner-changed\"\n])\n/** Public reason code.\n * @category models\n * @since 1.0.0\n */\nexport type ReasonCode = typeof ReasonCode.Type\n/** Validated checker output, containing no authority or ordering fields.\n * @category schemas\n * @since 1.0.0\n */\nexport const ProbeReport = Schema.Struct({ activity: Activity, reason: Schema.optional(ReasonCode) })\n/** Validated checker output.\n * @category models\n * @since 1.0.0\n */\nexport type ProbeReport = typeof ProbeReport.Type\nconst Counter = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\n\n/** A host-stamped observation; its journal sequence is supplied by the durable writer.\n * @category schemas\n * @since 1.0.0\n */\nexport const HealthObservation = Schema.Struct({\n subjectId: Schema.String,\n state: SubjectState,\n checkerId: Schema.String,\n monitorId: Schema.String,\n incarnation: Schema.String,\n evidenceSeq: Counter,\n observedAt: Counter,\n expiresAt: Counter,\n durationMs: Counter,\n baseHealth: Schema.optional(HealthState),\n outcome: Schema.Literals([\"ok\", \"timeout\", \"error\", \"interrupted\", \"discarded\"]),\n report: Schema.optional(ProbeReport),\n reason: Schema.optional(ReasonCode)\n})\n/** A host-stamped observation.\n * @category models\n * @since 1.0.0\n */\nexport type HealthObservation = typeof HealthObservation.Type\n/** One observation with its authoritative publication order.\n * @category models\n * @since 1.0.0\n */\nexport interface RecordedObservation {\n readonly observation: HealthObservation\n readonly sequence: number\n}\n/** The additive wire contract rendered by every status surface.\n * @category schemas\n * @since 1.0.0\n */\nexport const StatusRollup = Schema.Struct({\n subjectId: Schema.String,\n state: SubjectState,\n activity: Activity,\n health: HealthState,\n attention: Attention,\n freshness: Freshness,\n reason: Schema.optional(ReasonCode),\n provenance: Schema.optional(Schema.Struct({\n checkerId: Schema.String,\n monitorId: Schema.String,\n observedAt: Counter,\n expiresAt: Counter,\n evidenceSeq: Counter,\n incarnation: Schema.String,\n version: Counter\n })),\n updatedAt: Counter\n})\n/** The additive wire contract.\n * @category models\n * @since 1.0.0\n */\nexport type StatusRollup = typeof StatusRollup.Type\n/** Durable event type for observational health.\n * @category constants\n * @since 1.0.0\n */\nexport const statusObservedEventType = \"control.status.observed\"\n/** Opaque identity of the authoritative run ownership and lifecycle point being observed.\n * Equality is meaningful; lexical or numeric ordering is not.\n * @category getters\n * @since 1.0.0\n */\nexport const runIncarnation = (run: RunSummary): string =>\n Sha256.digestSync(JSON.stringify([\n run.runId,\n run.createdAt,\n run.updatedAt,\n run.ownerId ?? null,\n run.parkedBy ?? null,\n run.status,\n run.waitingReason ?? null\n ]))\n\n/** Read-only evidence, deliberately excluding mutation ports and terminal text by default.\n * Checkers are trusted host TypeScript, not a sandbox: captured ambient authority remains their author's responsibility.\n * @category models\n * @since 1.0.0\n */\nexport interface ProbeContext {\n readonly subjectId: string\n readonly state: SubjectState\n readonly events: ReadonlyArray<ControlEvent>\n readonly summary?: RunSummary | undefined\n readonly session?: {\n readonly alive: boolean\n readonly exitCode: number | null\n readonly outputCursor: number\n readonly outputTail?: string | undefined\n } | undefined\n readonly sinceCursor: number\n}\n/** Bounded polling, expiry and failure backoff.\n * @category models\n * @since 1.0.0\n */\nexport interface CheckPolicy {\n readonly intervalMs: number\n readonly timeoutMs: number\n readonly ttlMs: number\n /** Grace for silent work before the flow host considers missing progress unhealthy. */\n readonly stallAfterMs: number\n readonly backoff: { readonly initialMs: number; readonly maxMs: number; readonly factor: number }\n}\n/** Trusted host checker; supply service requirements around its Effect before registration.\n * @category models\n * @since 1.0.0\n */\nexport interface HealthChecker<C = unknown> {\n readonly id: string\n readonly configSchema?: Schema.Codec<C, unknown> | undefined\n readonly defaults?: Partial<CheckPolicy> | undefined\n readonly probe: (context: ProbeContext, config: C) => Effect.Effect<ProbeReport, unknown>\n}\n/** Data may select a registered checker but never executable code.\n * @category models\n * @since 1.0.0\n */\nexport interface HealthBinding {\n readonly checkerId: string\n readonly config?: unknown\n readonly policy?: Partial<CheckPolicy> | undefined\n readonly exposeOutput?: boolean | undefined\n}\n/** Trusted host health configuration.\n * @category models\n * @since 1.0.0\n */\nexport interface HealthConfig {\n // A heterogeneous registry erases C only after each binding is decoded by its own schema.\n readonly checkers?: ReadonlyArray<HealthChecker<any>> | undefined\n readonly bindings?: Readonly<Record<string, HealthBinding>> | undefined\n readonly limits?: { readonly maxSubjects?: number; readonly maxConcurrentProbes?: number } | undefined\n}\n/** Fully admitted checker binding.\n * @category models\n * @since 1.0.0\n */\nexport interface ResolvedCheck {\n readonly checker: HealthChecker<any>\n readonly config: unknown\n readonly policy: CheckPolicy\n readonly exposeOutput: boolean\n}\n/** Host registry, built once before admitting subjects.\n * @category models\n * @since 1.0.0\n */\nexport interface Registry {\n readonly resolve: (key: string) => ResolvedCheck\n readonly limits: { readonly maxSubjects: number; readonly maxConcurrentProbes: number }\n}\n/** Invalid trusted configuration fails startup instead of silently running another policy.\n * @category errors\n * @since 1.0.0\n */\nexport class HealthConfigurationError\n extends Schema.TaggedError<HealthConfigurationError>()(\"HealthConfigurationError\", {\n reason: Schema.Literals([\"invalid-policy\", \"invalid-checker\", \"invalid-config\"])\n })\n{}\nFault.register(\"HealthConfigurationError\", \"bug\")\n/** Safe cadence used by unconfigured hosts.\n * @category constants\n * @since 1.0.0\n */\nexport const defaultPolicy: CheckPolicy = {\n intervalMs: 5_000,\n timeoutMs: 2_000,\n ttlMs: 20_000,\n stallAfterMs: 120_000,\n backoff: { initialMs: 5_000, maxMs: 60_000, factor: 2 }\n}\n/** A known engine wait is a lifecycle fact, not missing progress.\n * @category getters\n * @since 1.0.0\n */\nexport const waitReason = (state: SubjectState, waitingReason?: string): ReasonCode | undefined =>\n state !== \"parked\" ? undefined : waitingReason === \"quota\" ?\n \"quota-wait\"\n : waitingReason === \"timer\"\n ? \"timer-wait\"\n : waitingReason === \"event\"\n ? \"event-wait\"\n : undefined\n/** Flow default observes lifecycle without inventing semantic activity.\n * @category constants\n * @since 1.0.0\n */\nexport const lifecycleRunChecker: HealthChecker = {\n id: \"lifecycle.run\",\n probe: (context) =>\n Effect.succeed({ activity: \"unknown\", reason: waitReason(context.state, context.summary?.waitingReason) ?? \"ok\" })\n}\n/** Session default never interprets silence or output movement as task activity.\n * @category constants\n * @since 1.0.0\n */\nexport const lifecycleSessionChecker: HealthChecker = {\n id: \"lifecycle.session\",\n probe: () => Effect.succeed({ activity: \"unknown\", reason: \"ok\" })\n}\nconst hostCheckers = (evaluator: Evaluator.Evaluator | undefined): ReadonlyArray<HealthChecker<any>> => [\n makeJevSessionChecker({ evaluator })\n]\n/** Checkers every host may bind by id, beyond the lifecycle default it always has.\n *\n * Registration is not a binding. A host opts in by naming one of these as a\n * `HealthBinding.checkerId`; a host that names none keeps the lifecycle\n * default, and no entry here is ever consulted for an unbound subject.\n *\n * @category constants\n * @since 1.0.0\n */\nexport const registeredCheckers: ReadonlyArray<HealthChecker<any>> = hostCheckers(undefined)\nconst bounded = (value: number, min: number, max: number) => Number.isSafeInteger(value) && value >= min && value <= max\nconst invalid = (reason: HealthConfigurationError[\"reason\"]): never => {\n throw new HealthConfigurationError({ reason })\n}\n/** Admit a host registry and all configured bindings. Unknown checker ids use the lifecycle default.\n * @category constructors\n * @since 1.0.0\n */\nexport const makeRegistry = (\n config: HealthConfig = {},\n kind: \"run\" | \"session\" = \"run\",\n evaluator?: Evaluator.Evaluator\n): Registry => {\n const fallback = kind === \"run\" ? lifecycleRunChecker : lifecycleSessionChecker\n const checkers = new Map<string, ResolvedCheck[\"checker\"]>([\n [fallback.id, fallback],\n ...hostCheckers(evaluator).map((checker) => [checker.id, checker] as const)\n ])\n for (const checker of config.checkers ?? []) {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}$/.test(checker.id) || checkers.has(checker.id)) invalid(\"invalid-checker\")\n checkers.set(checker.id, checker)\n }\n const resolve = (binding?: HealthBinding): ResolvedCheck => {\n const checker = binding === undefined ? fallback : checkers.get(binding.checkerId) ?? fallback\n const merged = { ...defaultPolicy, ...checker.defaults, ...binding?.policy }\n if (merged.backoff == null || typeof merged.backoff !== \"object\") invalid(\"invalid-policy\")\n const policy = { ...merged, backoff: { ...merged.backoff } }\n if (\n !bounded(policy.intervalMs, 10, 3_600_000) || !bounded(policy.timeoutMs, 1, 60_000) ||\n !bounded(policy.ttlMs, policy.timeoutMs, 86_400_000) ||\n !bounded(policy.stallAfterMs, policy.intervalMs, 86_400_000) ||\n !bounded(policy.backoff.initialMs, 10, 3_600_000) ||\n !bounded(policy.backoff.maxMs, policy.backoff.initialMs, 3_600_000) ||\n !Number.isFinite(policy.backoff.factor) || policy.backoff.factor < 1 || policy.backoff.factor > 10\n ) invalid(\"invalid-policy\")\n let decoded: unknown = undefined\n if (checker !== fallback || binding?.checkerId === fallback.id) {\n if (checker.configSchema !== undefined) {\n try {\n decoded = Schema.decodeUnknownSync(checker.configSchema)(binding?.config)\n } catch {\n invalid(\"invalid-config\")\n }\n } else if (binding?.config !== undefined) invalid(\"invalid-config\")\n }\n return { checker, config: decoded, policy, exposeOutput: binding?.exposeOutput === true }\n }\n const defaults = resolve()\n const bindings = new Map(Object.entries(config.bindings ?? {}).map(([key, value]) => [key, resolve(value)]))\n const maxSubjects = config.limits?.maxSubjects ?? 128\n const maxConcurrentProbes = config.limits?.maxConcurrentProbes ?? 8\n if (!bounded(maxSubjects, 1, 500) || !bounded(maxConcurrentProbes, 1, 64)) invalid(\"invalid-policy\")\n return { resolve: (key) => bindings.get(key) ?? defaults, limits: { maxSubjects, maxConcurrentProbes } }\n}\n/** Failure delay, bounded even when a subject has failed for a long time.\n * @category getters\n * @since 1.0.0\n */\nexport const nextDelay = (policy: CheckPolicy, consecutiveFailures: number): number =>\n consecutiveFailures <= 0 ? policy.intervalMs : Math.max(\n policy.intervalMs,\n Math.min(\n policy.backoff.maxMs,\n policy.backoff.initialMs * policy.backoff.factor ** Math.min(consecutiveFailures - 1, 32)\n )\n )\n/** Host-only ordering stamp captured before a probe.\n * @category models\n * @since 1.0.0\n */\nexport interface ObservationStamp {\n readonly monitorId: string\n readonly incarnation: string\n readonly evidenceSeq: number\n}\nconst outcomes = Metric.counter(\"smithers.health.probes\")\nconst durations = Metric.histogram(\"smithers.health.probe_duration_ms\", {\n boundaries: [1, 10, 100, 1_000, 5_000, 60_000]\n})\nconst decodeReport = Schema.decodeUnknownSync(ProbeReport)\n/** Evaluate one trusted checker with bounded timeout and safe failure values. Scope interruption propagates.\n * The host must still compare current ownership/lifecycle before durably publishing the returned observation.\n * @category constructors\n * @since 1.0.0\n */\nexport const evaluate = (\n check: ResolvedCheck,\n context: ProbeContext,\n stamp: ObservationStamp\n): Effect.Effect<HealthObservation> =>\n Effect.gen(function*() {\n const subjectId = context.subjectId\n const state = context.state\n const captured = { ...stamp }\n const started = yield* Effect.clockWith((clock) => clock.currentTimeMillis)\n const result = yield* Effect.suspend(() => check.checker.probe(context, check.config)).pipe(\n Effect.flatMap((candidate) => Effect.try({ try: () => decodeReport(candidate), catch: () => \"invalid-report\" })),\n Effect.map((report) => ({ outcome: \"ok\" as const, report })),\n Effect.catchCause((cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.interrupt\n : Effect.succeed({ outcome: \"error\" as const, reason: \"probe-error\" as const })\n ),\n Effect.timeoutOrElse({\n duration: check.policy.timeoutMs,\n orElse: () => Effect.succeed({ outcome: \"timeout\" as const, reason: \"probe-timeout\" as const })\n }),\n Effect.tap((outcome) =>\n Effect.annotateCurrentSpan({\n outcome: outcome.outcome,\n activity: \"report\" in outcome ? outcome.report.activity : \"unknown\"\n })\n ),\n Effect.withSpan(\"smithers.health.probe\", {\n attributes: {\n subjectKind: context.session === undefined ? \"run\" : \"session\",\n subjectId,\n checkerId: check.checker.id,\n monitorId: captured.monitorId\n }\n })\n )\n const observedAt = yield* Effect.clockWith((clock) => clock.currentTimeMillis)\n const durationMs = Math.max(0, observedAt - started)\n yield* Metric.update(outcomes.pipe(Metric.withAttributes({ outcome: result.outcome })), 1)\n yield* Metric.update(durations, durationMs)\n return {\n subjectId,\n state,\n checkerId: check.checker.id,\n ...captured,\n observedAt,\n expiresAt: observedAt + check.policy.ttlMs,\n durationMs,\n ...result\n }\n })\n\n/** Select evidence for the current opaque owner incarnation, breaking equal evidence ties by durable sequence.\n * @category projections\n * @since 1.0.0\n */\nexport const latestObservation = (\n candidates: ReadonlyArray<RecordedObservation>,\n subjectId: string,\n incarnation: string\n): RecordedObservation | undefined => {\n let selected: RecordedObservation | undefined\n for (const candidate of candidates) {\n const observation = candidate.observation\n if (\n observation.subjectId !== subjectId || observation.incarnation !== incarnation ||\n observation.outcome === \"discarded\"\n ) continue\n if (\n selected === undefined || observation.evidenceSeq > selected.observation.evidenceSeq ||\n observation.evidenceSeq === selected.observation.evidenceSeq && candidate.sequence > selected.sequence\n ) selected = candidate\n }\n return selected\n}\n/** Authoritative facts supplied independently of checker output.\n * @category models\n * @since 1.0.0\n */\nexport interface RollupInput {\n readonly subjectId: string\n readonly state: SubjectState\n readonly incarnation: string\n readonly waitingReason?: string | undefined\n readonly exitCode?: number | null | undefined\n readonly baseHealth?: HealthState | undefined\n readonly latest?: RecordedObservation | undefined\n readonly evidenceSeq?: number | undefined\n readonly now: number\n readonly updatedAt: number\n}\n/** Pure precedence: lifecycle and approvals win, and stale probes never establish activity.\n * @category projections\n * @since 1.0.0\n */\nexport const rollup = (input: RollupInput): StatusRollup => {\n const latest = input.latest\n const reading = latest?.observation\n const freshness = reading === undefined ?\n \"unobserved\" :\n reading.subjectId !== input.subjectId || reading.incarnation !== input.incarnation ||\n reading.state !== input.state ||\n reading.outcome !== \"ok\" || reading.report === undefined || input.now < reading.observedAt ||\n input.now >= reading.expiresAt ||\n (input.evidenceSeq !== undefined && reading.evidenceSeq < input.evidenceSeq) ?\n \"stale\" :\n \"fresh\"\n const terminal = input.state === \"completed\" || input.state === \"failed\" || input.state === \"cancelled\" ||\n input.state === \"exited\"\n const approval = input.state === \"waiting-approval\" || input.state === \"parked\" && input.waitingReason === \"approval\"\n // Released executions stay parked until an operator resumes the run (#3328).\n const released = input.state === \"parked\" && input.waitingReason === \"released\"\n const waiting = waitReason(input.state, input.waitingReason)\n let activity: typeof Activity.Type = freshness === \"fresh\" && !terminal && !approval && !released\n ? reading!.report!.activity\n : \"unknown\"\n let health: HealthState = input.state === \"failed\" ? \"failing\" : input.state === \"exited\" ?\n input.exitCode === 0 ? \"healthy\" : input.exitCode == null ? \"unknown\" : \"failing\" :\n terminal ?\n \"healthy\" :\n approval || released ?\n \"awaiting-human\" :\n waiting !== undefined ?\n \"healthy\" :\n input.state === \"parked\" && input.waitingReason === undefined ?\n \"awaiting-human\" :\n freshness !== \"fresh\"\n ? \"unknown\"\n : input.baseHealth ?? \"unknown\"\n const reason = approval\n ? \"awaiting-reply\"\n : released\n ? \"released\"\n : waiting ?? (freshness === \"fresh\" ? reading?.report?.reason : reading?.reason)\n if (!terminal && !approval && !released && waiting === undefined && freshness === \"fresh\") {\n if (reason === \"unreachable\" && health !== \"awaiting-human\") health = \"failing\"\n else if (reason === \"no-progress\" && health === \"healthy\") health = \"stalled\"\n }\n if (waiting !== undefined) activity = \"unknown\"\n const attention: typeof Attention.Type = approval ? \"awaiting-approval\" : released ?\n \"needs-resume\" :\n activity === \"needs-input\" ?\n \"needs-input\" :\n [\"stalled\", \"wedged-node\", \"runaway-loop\", \"failing\"].includes(health)\n ? \"unhealthy\"\n : \"none\"\n return {\n subjectId: input.subjectId,\n state: input.state,\n activity,\n health,\n attention,\n freshness,\n ...(reason === undefined ? {} : { reason }),\n ...(reading === undefined ? {} : {\n provenance: {\n checkerId: reading.checkerId,\n monitorId: reading.monitorId,\n observedAt: reading.observedAt,\n expiresAt: reading.expiresAt,\n evidenceSeq: reading.evidenceSeq,\n incarnation: reading.incarnation,\n version: latest!.sequence\n }\n }),\n updatedAt: Math.max(input.updatedAt, reading?.observedAt ?? 0)\n }\n}\n"]}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Session activity judged by the host's existing evaluator.
3
+ * @since 1.0.0
4
+ */
5
+ import type * as Evaluator from "@smthrs/model/Evaluator";
6
+ import { Schema } from "effect";
7
+ import type { HealthChecker } from "./Health.ts";
8
+ declare const JevProbeError_base: Schema.Class<JevProbeError, Schema.TaggedStruct<"JevProbeError", {
9
+ readonly reason: Schema.Literals<readonly ["unconfigured", "http", "timeout", "unreachable", "malformed"]>;
10
+ readonly status: Schema.optional<Schema.Number>;
11
+ }>, import("effect/Cause").YieldableError>;
12
+ /** The configured judge could not produce a usable observation.
13
+ * @category errors
14
+ * @since 1.0.0
15
+ */
16
+ export declare class JevProbeError extends JevProbeError_base {
17
+ }
18
+ /** Maximum terminal evidence retained for one judgment.
19
+ * @category constants
20
+ * @since 1.0.0
21
+ */
22
+ export declare const jevStateTailCharacters: number;
23
+ /** Subscription judgments have a bounded deadline.
24
+ * @category constants
25
+ * @since 1.0.0
26
+ */
27
+ export declare const jevRequestTimeoutMs = 45000;
28
+ /** Probe budget, longer than the request deadline.
29
+ * @category constants
30
+ * @since 1.0.0
31
+ */
32
+ export declare const jevProbeTimeoutMs = 50000;
33
+ /** Minimum confidence for an activity report.
34
+ * @category constants
35
+ * @since 1.0.0
36
+ */
37
+ export declare const jevConfidenceFloor = 0.7;
38
+ /** The host evaluator and its bounded request deadline.
39
+ * @category models
40
+ * @since 1.0.0
41
+ */
42
+ export interface JevSessionCheckerOptions {
43
+ readonly evaluator?: Evaluator.Evaluator | undefined;
44
+ readonly timeoutMs?: number | undefined;
45
+ }
46
+ /** Uses the same judge as flow completion, with no independent auth path.
47
+ * @category constructors
48
+ * @since 1.0.0
49
+ */
50
+ export declare const makeJevSessionChecker: (options?: JevSessionCheckerOptions) => HealthChecker;
51
+ /** Registered but unconfigured until a host supplies its evaluator.
52
+ * @category constants
53
+ * @since 1.0.0
54
+ */
55
+ export declare const jevSessionChecker: HealthChecker;
56
+ export {};
57
+ //# sourceMappingURL=JevSessionChecker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JevSessionChecker.d.ts","sourceRoot":"","sources":["../../src/JevSessionChecker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,KAAK,SAAS,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,aAAa,CAAA;;;;;AAE7D;;;GAGG;AACH,qBAAa,aAAc,SAAQ,kBAGjC;CAAG;AAYL;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAW,CAAA;AAC9C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAS,CAAA;AACzC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAS,CAAA;AACvC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAA;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAoBD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAS,wBAA6B,KAAG,aAyC7E,CAAA;AACF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAuC,CAAA"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Session activity judged by the host's existing evaluator.
3
+ * @since 1.0.0
4
+ */
5
+ import * as Fault from "@smthrs/flow/Fault";
6
+ import { Effect, Schema } from "effect";
7
+ /** The configured judge could not produce a usable observation.
8
+ * @category errors
9
+ * @since 1.0.0
10
+ */
11
+ export class JevProbeError extends Schema.TaggedError()("JevProbeError", {
12
+ reason: Schema.Literals(["unconfigured", "http", "timeout", "unreachable", "malformed"]),
13
+ status: Schema.optional(Schema.Number)
14
+ }) {
15
+ }
16
+ Fault.register("JevProbeError", {
17
+ unconfigured: "policy",
18
+ http: "dependency",
19
+ timeout: "dependency",
20
+ unreachable: "dependency",
21
+ malformed: "dependency"
22
+ }, "reason");
23
+ /** Maximum terminal evidence retained for one judgment.
24
+ * @category constants
25
+ * @since 1.0.0
26
+ */
27
+ export const jevStateTailCharacters = 4 * 1024;
28
+ /** Subscription judgments have a bounded deadline.
29
+ * @category constants
30
+ * @since 1.0.0
31
+ */
32
+ export const jevRequestTimeoutMs = 45_000;
33
+ /** Probe budget, longer than the request deadline.
34
+ * @category constants
35
+ * @since 1.0.0
36
+ */
37
+ export const jevProbeTimeoutMs = 50_000;
38
+ /** Minimum confidence for an activity report.
39
+ * @category constants
40
+ * @since 1.0.0
41
+ */
42
+ export const jevConfidenceFloor = 0.7;
43
+ const lifecycleReport = { activity: "unknown", reason: "ok" };
44
+ const activityCriteria = {
45
+ "working": "the agent is executing tools, editing files, or producing work",
46
+ "idle": "the agent finished and is producing nothing",
47
+ "needs-input": "the agent asked the person a question, requested approval or a credential, and is waiting"
48
+ };
49
+ const questions = {
50
+ activity: {
51
+ type: "choice",
52
+ instructions: "Read the tail of this agent session's output. What is the agent doing right now?",
53
+ criteria: activityCriteria
54
+ },
55
+ question: {
56
+ type: "boolean",
57
+ instructions: "Does the output end with the agent waiting for a person to answer?"
58
+ }
59
+ };
60
+ /** Uses the same judge as flow completion, with no independent auth path.
61
+ * @category constructors
62
+ * @since 1.0.0
63
+ */
64
+ export const makeJevSessionChecker = (options = {}) => ({
65
+ id: "jev.session",
66
+ defaults: { timeoutMs: jevProbeTimeoutMs, ttlMs: 60_000 },
67
+ probe: (context) => Effect.gen(function* () {
68
+ const session = context.session;
69
+ const tail = session?.outputTail;
70
+ if (session === undefined || !session.alive || tail === undefined || tail === "")
71
+ return lifecycleReport;
72
+ if (options.evaluator === undefined)
73
+ return yield* Effect.fail(new JevProbeError({ reason: "unconfigured" }));
74
+ const result = yield* options.evaluator.evaluate({
75
+ state: { alive: session.alive, exitCode: session.exitCode, outputTail: tail.slice(-jevStateTailCharacters) },
76
+ questions
77
+ }).pipe(Effect.mapError((error) => new JevProbeError({
78
+ reason: error.code === "timeout"
79
+ ? "timeout"
80
+ : error.code === "refused"
81
+ ? "http"
82
+ : error.code === "unreachable"
83
+ ? "unreachable"
84
+ : "malformed",
85
+ ...(error.status === undefined ? {} : { status: error.status })
86
+ })), Effect.timeoutOrElse({
87
+ duration: options.timeoutMs ?? jevRequestTimeoutMs,
88
+ orElse: () => Effect.fail(new JevProbeError({ reason: "timeout" }))
89
+ }));
90
+ const answer = result.answers.activity;
91
+ if (answer?.type !== "choice" || !Object.hasOwn(activityCriteria, answer.choice)) {
92
+ return yield* Effect.fail(new JevProbeError({ reason: "malformed" }));
93
+ }
94
+ const confidence = result.confidence?.activity ?? answer.probabilities?.[answer.choice] ?? 0;
95
+ if (!Number.isFinite(confidence) || confidence < jevConfidenceFloor || confidence > 1)
96
+ return lifecycleReport;
97
+ const choice = answer.choice;
98
+ return choice === "needs-input"
99
+ ? { activity: choice, reason: "prompt-detected" }
100
+ : { activity: choice, reason: "ok" };
101
+ })
102
+ });
103
+ /** Registered but unconfigured until a host supplies its evaluator.
104
+ * @category constants
105
+ * @since 1.0.0
106
+ */
107
+ export const jevSessionChecker = makeJevSessionChecker();
108
+ //# sourceMappingURL=JevSessionChecker.js.map