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

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 +1293 -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 +744 -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 +1522 -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 +1589 -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 +808 -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 +7 -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 +2127 -0
  385. package/src/ControlRpcs.ts +443 -0
  386. package/src/ControlRuntime.ts +1601 -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 +2478 -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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/SqlControlRuntime.ts"],
4
+ "sourcesContent": ["/**\n * Durable `ControlRuntime` over `@smthrs/journal`'s fenced `RunStore` and a\n * SQL database.\n *\n * `layerMemory` models the production seams but keeps everything in a `Map`, so\n * nothing it decides survives the process. This adapter supplies the durable\n * boundary the header of `ControlRuntime` describes.\n *\n * ## Where ownership lives\n *\n * The run lifecycle is not re-implemented here. `RunStore` already owns it, and\n * it is the piece that is hard to get right: every ownership move is a single\n * SQL compare-and-swap, so a stale writer loses the `UPDATE` rather than\n * racing a read-then-write. This module maps the control plane's vocabulary\n * onto it:\n *\n * | control status | `RunStore` status | ownership |\n * | --- | --- | --- |\n * | `accepted`, `running` | `running` | held by this process |\n * | `accepted` after an executor declines | `suspended` | released |\n * | `parked`, `waiting-approval` | `suspended` | released |\n * | `cancelled` / `completed` / `failed` | same | released, terminal |\n *\n * The authoritative `RunSummary` is written into the row's `state_json` by the\n * same fenced `UPDATE` that moves the status, so a projection can never be read\n * out of step with the lifecycle. `RunStore` has no list operation, so\n * `control_runs` is kept as a plain id index and each summary is read back\n * through the store rather than duplicated.\n *\n * ## Fences\n *\n * A fence is a serialized `OwnerId`. `hostId` and `pid` identify the process;\n * the `nonce` is regenerated on **every** claim, so a fence taken before a\n * park is not the fence held after the resume that follows it, and the stale\n * one is refused by the CAS. This is the `rangeID`-style monotonic fence from\n * `reference/temporal`'s history service, narrowed to a per-run token.\n *\n * ## Browser safety\n *\n * Nothing here imports `node:*`. Identity comes from `globalThis.crypto`, and\n * persistence is the driver-neutral SQL contract, so this module runs anywhere\n * `@smthrs/database` has a driver. Fibers are the exception and are\n * deliberately process-local: a fiber is a live continuation, not a row, and\n * cancellation is interruption of the fiber that this process owns.\n *\n * @since 0.1.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport { DurableWriter } from \"@smthrs/database/DurableWriter\"\nimport * as DurableWrites from \"@smthrs/database/DurableWriter\"\nimport { Ownership, RunStore } from \"@smthrs/run-store\"\nimport { Clock, Crypto, Effect, Fiber, Layer, Option, Schema } from \"effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\nimport type * as SqlError from \"effect/unstable/sql/SqlError\"\nimport * as ApprovalAuthority from \"./ApprovalAuthority.ts\"\nimport * as Attribution from \"./Cancellation.ts\"\nimport type { PlanInput } from \"./Control.ts\"\nimport {\n AlreadyResolved,\n ClaimLost,\n type CodeDrift,\n EnvelopeMismatch,\n FlowNotFound,\n InvalidInput,\n PersistenceError,\n PlanDenied,\n PlanDigestMismatch,\n PlanNotFound,\n RunNotFound,\n Unauthorized\n} from \"./ControlError.ts\"\nimport * as ControlExecutor from \"./ControlExecutor.ts\"\nimport type {\n ApprovalToken,\n BulkGrant,\n IdPage,\n IdPageRequest,\n LaunchResult,\n MemoryFlow,\n PlanPage,\n PlanQuery,\n RunCursor,\n RunQuery,\n Service,\n StoredPlan\n} from \"./ControlRuntime.ts\"\nimport { ApprovalDecision, ControlRuntime, idPageLimit, make } from \"./ControlRuntime.ts\"\nimport {\n ApprovalTarget,\n type Cancellation,\n Envelope,\n GrantScope,\n type IdempotencyKey,\n type PendingWait,\n PlanCard,\n PlanDecision,\n Principal,\n Receipt,\n type RunId,\n type RunStatus,\n RunSummary,\n SignalPayload\n} from \"./ControlSchema.ts\"\nimport * as ActiveFibers from \"./internal/activeFibers.ts\"\nimport { canonicalIssue, cappedIssue, schemaIssuePath } from \"./internal/issues.ts\"\nimport {\n accepted,\n adoptedCode,\n alreadyApplied,\n budgeted,\n canonical,\n codeDriftOf,\n emptyEnvelope,\n planCard,\n planFingerprint,\n sameEnvelope\n} from \"./internal/planning.ts\"\nimport { causeMessages, missingTable } from \"./internal/sqlSchemaErrors.ts\"\nimport * as Lineage from \"./Lineage.ts\"\nimport * as Migrations from \"./Migrations.ts\"\nimport { plannable } from \"./SystemFlows.ts\"\n\n/**\n * A flow the durable runtime can plan.\n *\n * The same shape the memory runtime takes, so a composition can hand the same\n * catalog to either.\n *\n * @category models\n * @since 0.1.0\n */\nexport type DurableFlow = MemoryFlow\n\n/**\n * Durable runtime configuration.\n *\n * `owner` is the process identity every claim is stamped with. When omitted,\n * one valid synthetic identity is minted for this runtime only, so separately\n * constructed runtimes cannot cross each other's fences. Hosts that can\n * report their real process identity should still supply it so liveness probes\n * can reason about the operating-system process.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface Options {\n readonly flows?: ReadonlyArray<DurableFlow> | undefined\n /**\n * Reads the current flow catalog for each plan and listing. When supplied,\n * this replaces `flows`, including the default system catalog. A host with\n * a refreshable registry should return one complete snapshot per call.\n * Existing plans retain the definition they were approved against.\n */\n readonly loadFlows?: (() => Effect.Effect<ReadonlyArray<DurableFlow>, PersistenceError>) | undefined\n /**\n * Reads each flow's code as it is on disk now, for the drift check that runs\n * before a run is re-driven and for the code an allowed drift adopts. A host\n * whose `loadFlows` answers from a cached snapshot supplies this, so a flow\n * edited or deleted after the run parked is refused before the claim rather\n * than found by the executor after it. Defaults to `loadFlows`.\n */\n readonly currentFlows?: (() => Effect.Effect<ReadonlyArray<DurableFlow>, PersistenceError>) | undefined\n /** Verifies a durable pinned source closure before consenting to resume it. */\n readonly pinnedFlow?:\n | ((flowId: string, digest: string) => Effect.Effect<boolean | undefined, PersistenceError>)\n | undefined\n /**\n * Makes one flow's code on disk now the code this host executes, for a\n * resume the operator allowed to drift, and answers the identity the host\n * can now run, or `undefined` when it can run none. A host whose executor\n * serves a loaded snapshot supplies this: recording a digest its executor\n * does not hold accepted the resume and then failed the run (#2740).\n * Defaults to the flow's entry in `currentFlows`.\n */\n readonly adoptFlow?:\n | ((flowId: string, runId: string) => Effect.Effect<DurableFlow | undefined, PersistenceError>)\n | undefined\n readonly owner?: Ownership.OwnerId | undefined\n /**\n * Whether the process a running run's owner names is still working. With\n * it, `resume` takes over a running run whose owner is gone (a host killed\n * mid-run) once that owner's lease has expired, instead of answering\n * `ClaimLost`; the run store verifies the expired lease. Without it a\n * running run belongs to its recorded owner for good.\n */\n readonly isAlive?: Ownership.LivenessCheck | undefined\n readonly principal?: Omit<Principal, \"stampedAt\"> | undefined\n readonly approvalAuthority?: ApprovalAuthority.Service | undefined\n /** The engine version stamped on every run this runtime starts. */\n readonly engineVersion?: string | undefined\n}\n\nconst persistence = (operation: string) => (cause: unknown): PersistenceError =>\n new PersistenceError({\n operation,\n message: `Control runtime failed to ${operation}`,\n cause\n })\n\nconst storedFailure = (location: string, path: string, reason: string): PersistenceError =>\n new PersistenceError({\n operation: `decode ${location}`,\n message: `Control runtime could not decode ${location}: ${cappedIssue(path, reason)}`\n })\n\nconst decodeStoredValue = <S extends Schema.Top>(\n location: string,\n schema: S,\n value: unknown\n): Effect.Effect<S[\"Type\"], PersistenceError, S[\"DecodingServices\"]> =>\n Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError((error) =>\n storedFailure(location, schemaIssuePath(error), \"stored value does not match its schema\")\n )\n )\n\nconst decodeStoredJson = <S extends Schema.Top>(\n location: string,\n schema: S,\n json: string\n): Effect.Effect<S[\"Type\"], PersistenceError, S[\"DecodingServices\"]> =>\n Effect.try({\n try: () => JSON.parse(json) as unknown,\n catch: () => storedFailure(location, \"$\", \"stored value is not valid JSON\")\n }).pipe(Effect.flatMap((value) => decodeStoredValue(location, schema, value)))\n\n/** The admitting principal a signal command recorded, spread onto the command. */\n/** `summary` with the launcher its run's launch index recorded, if any. */\nconst withLauncher = (\n summary: RunSummary,\n launcher: { readonly id: string; readonly kind: string } | undefined\n): RunSummary => launcher === undefined ? summary : { ...summary, launchedBy: { id: launcher.id, kind: launcher.kind } }\n\nconst signalPrincipal = (\n json: string | null\n): Effect.Effect<{ readonly principal?: Principal }, PersistenceError> =>\n json === null ? Effect.succeed({}) : Effect.map(\n decodeStoredJson(\"control_signal_commands.principal_json\", Principal, json),\n (principal) => ({ principal })\n )\n\n/** A random identifier that does not depend on any Node API. */\nconst randomId = (): string => globalThis.crypto.randomUUID()\n\nconst terminal = (status: RunStatus): boolean => status === \"cancelled\" || status === \"completed\" || status === \"failed\"\n\n/**\n * The deepest nesting the wait walk climbs.\n *\n * It matches `@smthrs/engine-store` `waitingTreeMaxDepth` and exists for the\n * same reason: authored nesting is a handful of executions deep, and the cap\n * bounds the read of a tree whose edges were corrupted outside the engine.\n */\nconst maxWaitTreeDepth = 64\n\n/**\n * Whether this database lacks the engine's wait-tree schema.\n *\n * Run-store installs the wait and trampoline columns before the engine\n * installs spawn edges and `execution_flow`. A control-only database can\n * lack the latter without making its ordinary run listings unreadable.\n */\nconst missingWaitTreeSchema = (cause: unknown): boolean =>\n missingTable(\"flows_runs\")(cause) || missingTable(\"flows_run_parents\")(cause) ||\n causeMessages(cause).some((message) => message.includes(\"execution_flow\"))\n\n/**\n * The question a park declared, as JSON, or nothing.\n *\n * The column is the wait's own text under a `json_valid` check, so text that\n * does not parse is text nothing wrote: it reads as a park that declared no\n * question rather than failing the listing it appears in.\n */\nconst declaredRequest = (value: string | null): { readonly request?: typeof Schema.Json.Type } => {\n if (value === null) return {}\n try {\n return { request: JSON.parse(value) as typeof Schema.Json.Type }\n } catch {\n return {}\n }\n}\n\n/** The `RunStore` status the control plane's status projects onto. */\nconst storeStatus = (status: RunStatus): RunStore.RunStatus => {\n switch (status) {\n case \"accepted\":\n case \"running\":\n return \"running\"\n case \"parked\":\n case \"waiting-approval\":\n return \"suspended\"\n default:\n return status\n }\n}\n\n/**\n * Whether two identities are the same *process*.\n *\n * The nonce is deliberately excluded: it is the per-claim fence, so a process\n * that re-claims a run has a new nonce but is still the same owner.\n */\nconst sameProcess = (left: Ownership.OwnerId, right: Ownership.OwnerId): boolean =>\n left.hostId === right.hostId && left.pid === right.pid\n\ninterface PlanRow {\n readonly planId: string\n readonly cardJson: string\n readonly decodedInputJson: string\n readonly decision: string\n}\n\ninterface TokenRow {\n readonly tokenId: string\n readonly targetJson: string\n readonly resolved: number\n readonly decisionPrincipalJson: string | null\n readonly decisionJson: string | null\n}\n\ninterface ApprovalIdentity {\n readonly targetTag: ApprovalTarget[\"_tag\"]\n readonly runId: string\n readonly targetId: string\n}\n\nconst approvalIdentity = (target: ApprovalTarget): ApprovalIdentity =>\n target._tag === \"Plan\"\n ? { targetTag: target._tag, runId: \"\", targetId: target.planId }\n : { targetTag: target._tag, runId: target.runId, targetId: target.requestId }\n\nconst sameApprovalIdentity = (left: ApprovalTarget, right: ApprovalTarget): boolean =>\n left._tag === \"Plan\"\n ? right._tag === \"Plan\" && left.planId === right.planId\n : right._tag === \"Node\" && left.runId === right.runId && left.requestId === right.requestId\n\nconst tokenFromRow = (\n row: TokenRow,\n target: ApprovalTarget\n): Effect.Effect<ApprovalToken, PersistenceError> =>\n Effect.gen(function*() {\n const decision = row.decisionJson === null\n ? { _tag: \"Pending\" as const }\n : yield* decodeStoredJson(\"control_tokens.decision_json\", ApprovalDecision, row.decisionJson)\n if (row.decisionJson === null && row.resolved === 1) {\n return yield* new PersistenceError({\n operation: \"recover an approval decision\",\n message:\n \"This legacy approval erased its decision. Preserve the database for review; create a new run and request a new approval. It cannot safely resume through this gate.\"\n })\n }\n const expectedPrincipal = decision._tag === \"Pending\" ? undefined : decision.decisionPrincipal\n const storedPrincipal = row.decisionPrincipalJson === null\n ? undefined\n : yield* decodeStoredJson(\"control_tokens.decision_principal_json\", Principal, row.decisionPrincipalJson)\n if (\n row.resolved !== (decision._tag === \"Pending\" ? 0 : 1) ||\n JSON.stringify(storedPrincipal) !== JSON.stringify(expectedPrincipal)\n ) {\n return yield* storedFailure(\n \"control_tokens.decision_json\",\n \"$\",\n \"approval decision disagrees with its resolution\"\n )\n }\n return {\n tokenId: row.tokenId,\n target,\n ...decision\n }\n })\n\n/** Plans read per statement while a filtered plan page fills. */\nconst planScanBatch = 200\n\nconst CancelRequestPayload = Schema.Struct({\n principal: Schema.optional(Principal),\n reason: Schema.optional(Schema.String)\n})\n\nconst EngineInterruptionPayload = Schema.Struct({\n outcome: Schema.optional(Schema.String),\n interruptedAtMs: Schema.optional(Schema.Number)\n})\n\n// Control only projects an engine-owned row's flow name. Importing the full\n// engine state schema would add an engine-store runtime dependency, so this\n// validates exactly the field this package reads and permits the remaining\n// engine-owned fields to pass through the struct decoder unused.\nconst EngineStateProjection = Schema.Struct({ flowName: Schema.NonEmptyString })\n\n/**\n * Creates every control-plane table.\n *\n * `RunStore`'s own migrations are the journal package's business and are\n * applied by its layer. A read-only client installs nothing.\n *\n * @category migrations\n * @since 0.1.0\n */\nexport const migrate: Effect.Effect<void, PersistenceError, SqlClient.SqlClient> = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n // A read-only observer reads the schema it finds and installs nothing.\n if (Dialect.isReadOnly(sql)) return\n // A standalone runtime cannot record control's high-offset migration first:\n // that high-water mark would make later journal and run-store sets look\n // skipped. The idempotent bootstrap keeps standalone construction safe. The\n // cross-package follow-up is for the host to compose `Migrations.set` beside\n // the journal and run-store sets before it constructs any adapter.\n // Reuse the canonical migration set and the shared transaction/retry policy,\n // without advancing the shared migration ledger during standalone bootstrap.\n yield* DurableWrites.make(sql).write(\n Effect.forEach(Object.values(Migrations.set.migrations), (migration) => migration, { discard: true })\n )\n}).pipe(Effect.mapError(persistence(\"migrate\")))\n\n/**\n * Constructs a durable runtime over the ambient database and run store.\n *\n * Not exported under this name: `make` below is the single public constructor.\n * Exporting both put two names for one function on the package's public\n * surface, and only one of them was documented.\n */\nconst makeRuntime = (\n options: Options = {}\n): Effect.Effect<\n Service,\n PersistenceError,\n Crypto.Crypto | DurableWriter | SqlClient.SqlClient | RunStore.RunStore\n> => {\n // Snapshot before the Effect starts: construction options are caller-owned\n // and may be mutated while migrations or service acquisition are suspended.\n const owner: Ownership.OwnerId = options.owner === undefined\n ? Object.freeze({\n hostId: `control-runtime-${randomId()}`,\n pid: 1,\n nonce: randomId()\n })\n : Object.freeze({ ...options.owner })\n const isAlive = options.isAlive\n const approvalAuthority = options.approvalAuthority ?? ApprovalAuthority.local\n const authorizeApproval = approvalAuthority.authorize.bind(approvalAuthority)\n\n return Effect.gen(function*() {\n const crypto = yield* Crypto.Crypto\n const writer = yield* DurableWriter\n const runStore = yield* RunStore.RunStore\n yield* migrate\n const sql = yield* Effect.service(SqlClient.SqlClient)\n\n const configuredFlows = options.flows ?? plannable.map((entry): DurableFlow => ({\n flowId: entry.flowId,\n description: `Reserved ${entry.verb} system flow`,\n deployClass: entry.deployClass,\n envelope: emptyEnvelope\n }))\n const readFlows = (options.loadFlows === undefined\n ? Effect.succeed(configuredFlows)\n : Effect.suspend(options.loadFlows)).pipe(\n Effect.map((entries) => new Map(entries.map((flow) => [flow.flowId, flow] as const)))\n )\n const readCurrentFlows = options.currentFlows === undefined\n ? readFlows\n : Effect.suspend(options.currentFlows).pipe(\n Effect.map((entries) => new Map(entries.map((flow) => [flow.flowId, flow] as const)))\n )\n const readAdoptedFlow = (flowId: string, runId: string) =>\n options.adoptFlow === undefined\n ? readCurrentFlows.pipe(Effect.map((flows) => flows.get(flowId)))\n : Effect.suspend(() => options.adoptFlow!(flowId, runId))\n\n // Fibers are live continuations, not rows. A restarted process legitimately\n // has none, and interrupting a run it does not own is the other process's\n // job \u2014 so this map is process-local by design, not by omission.\n const fibers = new Map<RunId, Fiber.Fiber<unknown, unknown>>()\n let pendingSignalCursor = 0\n\n const now = Clock.currentTimeMillis\n\n const query = <A>(operation: string) => (effect: Effect.Effect<ReadonlyArray<A>, unknown>) =>\n effect.pipe(Effect.mapError(persistence(operation)))\n\n /**\n * Runs a read that may fail on a missing table or column, and is caught.\n *\n * Inside an enclosing transaction the read takes a savepoint, because a\n * failed statement aborts a PostgreSQL transaction and the catch could not\n * recover it. Outside one it runs bare: on SQLite a top-level transaction\n * is `BEGIN IMMEDIATE`, which takes the write lock for a read and fails a\n * contender with `SQLITE_BUSY` while another plane holds the claim.\n */\n const probe = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | SqlError.SqlError, R> =>\n Effect.flatMap(\n Effect.serviceOption(sql.transactionService),\n (enclosing): Effect.Effect<A, E | SqlError.SqlError, R> =>\n Option.isSome(enclosing) ? sql.withTransaction(effect) : effect\n )\n\n /** Allocates the next value of a durable counter inside one transaction. */\n const nextSequence = (name: string): Effect.Effect<number, PersistenceError> =>\n writer.write(Effect.gen(function*() {\n yield* sql`INSERT INTO control_sequences (name, value) VALUES (${name}, 0) ON CONFLICT (name) DO NOTHING`\n const rows = yield* sql<{ readonly value: number }>`\n UPDATE control_sequences SET value = value + 1\n WHERE name = ${name} AND value < ${Number.MAX_SAFE_INTEGER} RETURNING value\n `\n const value = Number(rows[0]?.value)\n if (!Number.isSafeInteger(value) || value < 1) {\n return yield* Effect.fail(new Error(`Sequence ${name} did not return a positive safe integer`))\n }\n return value\n })).pipe(Effect.mapError(persistence(\"allocate a sequence\")))\n\n const readPlan = (planId: string): Effect.Effect<Option.Option<PlanRow>, PersistenceError> =>\n sql<PlanRow>`\n SELECT plan_id AS \"planId\", card_json AS \"cardJson\",\n decoded_input_json AS \"decodedInputJson\", decision\n FROM control_plans WHERE plan_id = ${planId}\n `.pipe(query(\"read a plan\"), Effect.map((rows) => Option.fromNullishOr(rows[0])))\n\n const storedPlan = (row: PlanRow): Effect.Effect<StoredPlan, PersistenceError> =>\n Effect.all({\n card: decodeStoredJson(\"control_plans.card_json\", PlanCard, row.cardJson),\n decodedInput: decodeStoredJson(\"control_plans.decoded_input_json\", Schema.Json, row.decodedInputJson),\n decision: decodeStoredValue(\"control_plans.decision\", PlanDecision, row.decision)\n })\n\n const requirePlan = (planId: string): Effect.Effect<PlanRow, PlanNotFound | PersistenceError> =>\n Effect.flatMap(\n readPlan(planId),\n Option.match({\n onNone: () => Effect.fail(new PlanNotFound({ planId })),\n onSome: Effect.succeed\n })\n )\n\n /**\n * Reads a run row, translating a missing row into `RunNotFound` and every\n * other store failure into `PersistenceError` \u2014 never a defect.\n */\n const requireRow = (runId: RunId): Effect.Effect<RunStore.RunRow, RunNotFound | PersistenceError> =>\n runStore.get(runId).pipe(\n Effect.mapError((error) =>\n error.code === \"not_found_row\"\n ? new RunNotFound({ runId })\n : persistence(\"read a run\")(error)\n )\n )\n\n /**\n * The control status a store status projects back onto.\n *\n * The forward map is lossy \u2014 `accepted` and `running` both store as\n * `running` \u2014 so a run this plane did not launch is reported under the\n * status the store can actually prove.\n */\n const controlStatus = (status: RunStore.RunStatus): RunStatus => {\n switch (status) {\n case \"pending\":\n return \"accepted\"\n case \"running\":\n return \"running\"\n case \"suspended\":\n return \"parked\"\n default:\n return status\n }\n }\n\n type DecodedRunState =\n | { readonly _tag: \"Control\"; readonly summary: RunSummary }\n | { readonly _tag: \"Engine\"; readonly flowName: string }\n\n /**\n * Decodes one state row once, then validates the projection its keys name.\n * A control summary and an engine state share the column but not a schema.\n */\n const decodeRunState = (stateJson: string): Effect.Effect<DecodedRunState, PersistenceError> =>\n Effect.gen(function*() {\n const parsed = yield* decodeStoredJson(\"flows_runs.state_json\", Schema.Json, stateJson)\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const candidate = parsed as Readonly<Record<string, unknown>>\n if (\"runId\" in candidate || \"flowId\" in candidate || \"status\" in candidate) {\n return {\n _tag: \"Control\",\n summary: yield* decodeStoredValue(\"flows_runs.state_json as RunSummary\", RunSummary, parsed)\n }\n }\n }\n const engine = yield* decodeStoredValue(\n \"flows_runs.state_json as engine state\",\n EngineStateProjection,\n parsed\n )\n return { _tag: \"Engine\", flowName: engine.flowName }\n })\n\n const optional = <A>(value: A | null | undefined): { readonly value?: A } =>\n value === null || value === undefined ? {} : { value }\n\n /**\n * How much of the database one projection needs to read.\n *\n * A page needs only its selected runs and their ancestor chains. Cascade\n * attribution walks ancestors and stops, so a page or a single-run\n * mutation does not project unrelated runs, and no read projects them all.\n */\n type IndexScope = ReadonlyArray<string>\n\n /** `WHERE` material narrowing a column to a scope. */\n const within = (column: string, scope: IndexScope) => sql.in(column, scope as Array<string>)\n\n /**\n * The two facts a run row cannot tell about itself.\n */\n interface AncestryIndex {\n /** Run ids a `fork-created` marker names. */\n readonly forked: ReadonlySet<string>\n /** The run that spawned each child, by child id. */\n readonly spawnedBy: ReadonlyMap<string, string>\n /** What each parked run is waiting for, by run id. */\n readonly waitingFor: ReadonlyMap<string, string>\n /** Open human waits in each run's tree, by the run that contains them. */\n readonly humanWaits: ReadonlyMap<string, ReadonlyArray<PendingWait>>\n /** Who cancelled each cancelled run, by run id. */\n readonly cancellations: ReadonlyMap<string, Cancellation>\n /** The outstanding resume delegation of each run that has one. */\n readonly pendingResumes: ReadonlyMap<string, number>\n }\n\n /**\n * Projects a run row onto a control summary, ancestry included.\n *\n * Ancestry reaches the row from two different places, because the engine\n * records two different relationships. `parent_run_id` is the trampoline\n * chain \u2014 the round before this one \u2014 and it is the only ancestry a run\n * row carries. A run another run SPAWNED records nothing in its own row:\n * the edge lives in `flows_run_parents`, which is the subflow DAG cycle\n * detection walks (`packages/smithers/flows/run-store/src/migrations/0002_lineage.ts`).\n * A projection that read the column alone would report every child of\n * every run as an orphan.\n *\n * The column wins when both exist, which is the case for round 1 of a run\n * that was itself spawned: the round's nearest ancestor is the round\n * before it, not the run that spawned round 0.\n *\n * @param row the run row\n * @param ancestry the fork markers and spawn edges of the whole database\n */\n const baseSummary = (row: RunStore.RunRow, state: DecodedRunState): RunSummary =>\n state._tag === \"Control\"\n ? state.summary\n : {\n runId: row.runId,\n flowId: state.flowName,\n status: controlStatus(row.status),\n createdAt: row.createdAtMs,\n updatedAt: row.finishedAtMs ?? row.startedAtMs ?? row.createdAtMs\n }\n\n const summaryFrom = (\n row: RunStore.RunRow,\n ancestry: AncestryIndex\n ): Effect.Effect<RunSummary, PersistenceError> =>\n Effect.gen(function*() {\n const base = withLauncher(baseSummary(row, yield* decodeRunState(row.stateJson)), yield* launcherOf(row.runId))\n const parentRunId = optional(row.parentRunId).value ?? ancestry.spawnedBy.get(row.runId)\n const lineageId = optional(row.lineageId).value\n const roundOrdinal = optional(row.roundOrdinal).value\n const origin = Lineage.originOf({\n ...(parentRunId === undefined ? {} : { parentRunId }),\n ...(roundOrdinal === undefined ? {} : { roundOrdinal }),\n forked: ancestry.forked.has(row.runId)\n })\n const waitingReason = ancestry.waitingFor.get(row.runId)\n const cancellation = ancestry.cancellations.get(row.runId)\n const pendingResume = ancestry.pendingResumes.get(row.runId)\n const pendingWaits = ancestry.humanWaits.get(row.runId)\n return {\n ...base,\n // A run whose tree holds an open human wait is waiting on a human,\n // however nested the row that holds it and whether or not its own row\n // has flipped to parked yet: a parent awaiting a `.child()` is\n // blocked on that child's question either way. Rolling the status up\n // is what lets every existing `status: \"waiting-approval\"` filter \u2014\n // the gateway inbox, `smithers approvals list`, the diagnosis card \u2014\n // find a `HumanTask` parked on a descendant.\n //\n // Only ATTACHED waits reach here. A `detach` spawn outlives the run\n // that started it (`@smthrs/engine-store` `RunState.onParentExit`),\n // so the walk stops at one rather than telling a reader that a run\n // which can proceed cannot.\n ...(pendingWaits === undefined ? {} : { pendingWaits }),\n ...(pendingWaits === undefined || !pendingWaits.some((wait) =>\n wait.reason === ControlExecutor.humanWaitReason\n ) ||\n terminal(base.status)\n ? {}\n : { status: \"waiting-approval\" as const }),\n ...(pendingResume === undefined ? {} : { pendingResume }),\n ...(parentRunId === undefined ? {} : { parentRunId }),\n ...(lineageId === undefined ? {} : { lineageId }),\n ...(roundOrdinal === undefined ? {} : { roundOrdinal }),\n ...(origin === undefined ? {} : { origin }),\n ...(waitingReason === undefined ? {} : { waitingReason }),\n ...(cancellation === undefined ? {} : { cancellation })\n }\n })\n\n /**\n * The runs a `fork-created` marker names.\n *\n * Time travel writes the marker on the forked child's own journal, which\n * is the only evidence separating a fork from an ordinary child: both\n * record `parent_run_id`. A composition whose journal is not this database\n * has no journal table here at all, and the honest answer there is \"no\n * fork evidence\" \u2014 not a failed projection \u2014 so exactly that one failure\n * is folded into the empty set.\n *\n * Every other failure is reported. A locked database, a corrupt page, or\n * a table that exists but no longer answers this question would otherwise\n * report every fork in the deployment as an ordinary child, silently and\n * for as long as the condition lasted.\n */\n const forkedRunIds = (scope: IndexScope): Effect.Effect<ReadonlySet<string>, PersistenceError> =>\n sql<{ readonly runId: string }>`\n SELECT DISTINCT run_id AS \"runId\" FROM flows_journal_events\n WHERE event_type = ${Lineage.forkCreatedEventType} AND ${within(\"run_id\", scope)}\n `.pipe(\n Effect.map((rows) => new Set(rows.map((row) => row.runId)) as ReadonlySet<string>),\n Effect.catchIf(\n missingTable(\"flows_journal_events\"),\n () => Effect.succeed(new Set<string>() as ReadonlySet<string>)\n ),\n Effect.mapError(persistence(\"read fork markers\"))\n )\n\n /**\n * The run that spawned each child, by child id.\n *\n * `seq` is the engine's store-global insertion order, so the FIRST edge is\n * the creating parent. A diamond's later parents are edges too, and a\n * summary names one ancestor, so the creating one is the one it names.\n *\n * Missing table, missing evidence, exactly as with the fork markers: a\n * control plane over a database with no engine state in it observes runs\n * that spawned nothing.\n */\n const spawnedBy = (scope: IndexScope): Effect.Effect<ReadonlyMap<string, string>, PersistenceError> =>\n sql<{\n readonly childId: string\n readonly parentId: string\n }>`\n SELECT child_id AS \"childId\", parent_id AS \"parentId\"\n FROM flows_run_parents WHERE ${within(\"child_id\", scope)} ORDER BY seq DESC\n `.pipe(\n probe,\n // Descending, so the lowest `seq` is written last and wins the key.\n Effect.map((rows) => new Map(rows.map((row) => [row.childId, row.parentId])) as ReadonlyMap<string, string>),\n Effect.catchIf(\n missingTable(\"flows_run_parents\"),\n () => Effect.succeed(new Map<string, string>() as ReadonlyMap<string, string>)\n ),\n Effect.mapError(persistence(\"read spawn edges\"))\n )\n\n /**\n * What each parked run is waiting for, by run id.\n *\n * The engine writes `waiting_reason` on the run row when it parks a run\n * (`packages/smithers/flows/engine-store/src/DurableEngineState.ts` `park`), and clears\n * it on the wake. The control plane reads it and never writes it: a park\n * belongs to whoever is holding the run, and the projection reports the\n * hold rather than deciding it.\n *\n * The reason separates the parks a steer can end from the parks it\n * cannot, so `Control.steer` needs it on the summary and not only in the\n * engine's own store.\n */\n const waitingFor = (scope: IndexScope): Effect.Effect<ReadonlyMap<string, string>, PersistenceError> =>\n sql<{\n readonly runId: string\n readonly waitingReason: string\n }>`\n SELECT run_id AS \"runId\", waiting_reason AS \"waitingReason\"\n FROM flows_runs WHERE waiting_reason IS NOT NULL AND ${within(\"run_id\", scope)}\n `.pipe(\n Effect.map((rows) => new Map(rows.map((row) => [row.runId, row.waitingReason])) as ReadonlyMap<string, string>),\n Effect.mapError(persistence(\"read waiting reasons\"))\n )\n\n /**\n * Open human waits in each run's tree, by every run that contains one.\n *\n * The walk goes UP, not down. Approval parks are rare and run trees are\n * shallow, so start from the parked rows and climb every spawn and\n * trampoline edge; starting from every run in scope and descending would\n * re-walk the whole forest to find the same few rows. A wait therefore\n * appears under its own execution AND under every ancestor of it, which\n * is exactly what \"does this run tree owe anybody an answer\" asks.\n *\n * The scope filters the ANCESTOR, not the parked row: a listing wants the\n * waits of the runs it is about to return, wherever those waits are held.\n *\n * Collapse paths to each wait/ancestor pair at their shortest depth so\n * shared descendants and cycles cannot duplicate or reorder a wait.\n * A database without the engine's wait-tree schema observes no nested\n * waits rather than failing every listing.\n */\n const humanWaits = (scope: IndexScope): Effect.Effect<\n ReadonlyMap<string, ReadonlyArray<PendingWait>>,\n PersistenceError\n > =>\n sql<{\n readonly ancestorId: string\n readonly runId: string\n readonly flowId: string | null\n readonly waitingReason: string\n readonly waitingToken: string | null\n readonly waitingRequest: string | null\n readonly createdAtMs: number\n readonly depth: number\n }>`\n WITH RECURSIVE human_waits(wait_run_id, ancestor_id, depth) AS (\n SELECT run_id, run_id, 0 FROM flows_runs\n WHERE waiting_reason IN (${ControlExecutor.humanWaitReason}, 'event')\n AND waiting_token IS NOT NULL\n AND status NOT IN ('completed', 'failed', 'cancelled')\n UNION\n SELECT human_waits.wait_run_id, parent.run_id, human_waits.depth + 1\n FROM flows_runs step JOIN human_waits ON step.run_id = human_waits.ancestor_id\n JOIN flows_runs parent ON parent.run_id IN (\n SELECT parent_id FROM flows_run_parents WHERE child_id = step.run_id\n UNION ALL\n SELECT step.parent_run_id WHERE step.parent_run_id IS NOT NULL\n )\n WHERE human_waits.depth < ${maxWaitTreeDepth}\n AND (parent.run_id = step.parent_run_id\n OR COALESCE(${Dialect.jsonText(sql, sql`step.state_json`, \"$.onParentExit\")}, 'cancel') <> 'detach')\n ), reachable(wait_run_id, ancestor_id, depth) AS (\n SELECT wait_run_id, ancestor_id, MIN(depth) FROM human_waits GROUP BY wait_run_id, ancestor_id\n )\n SELECT\n reachable.ancestor_id AS \"ancestorId\",\n reachable.depth AS \"depth\",\n parked.run_id AS \"runId\",\n parked.execution_flow AS \"flowId\",\n parked.waiting_reason AS \"waitingReason\",\n parked.waiting_token AS \"waitingToken\",\n parked.waiting_request AS \"waitingRequest\",\n parked.created_at_ms AS \"createdAtMs\"\n FROM reachable JOIN flows_runs parked ON parked.run_id = reachable.wait_run_id\n WHERE ${within(\"reachable.ancestor_id\", scope)}\n ORDER BY reachable.ancestor_id, reachable.depth, parked.created_at_ms, parked.run_id\n `.pipe(\n probe,\n Effect.map((rows) => {\n const index = new Map<string, Array<PendingWait>>()\n for (const row of rows) {\n const built = ControlExecutor.pendingWaitOf({\n runId: row.runId,\n reason: row.waitingReason,\n token: row.waitingToken,\n createdAt: row.createdAtMs,\n ...(row.flowId === null ? {} : { flowId: row.flowId }),\n ...declaredRequest(row.waitingRequest)\n })\n if (built === undefined) continue\n const waits = index.get(row.ancestorId) ?? []\n waits.push(built)\n index.set(row.ancestorId, waits)\n }\n return index\n }),\n Effect.catchIf(\n missingWaitTreeSchema,\n () => Effect.succeed(new Map<string, ReadonlyArray<PendingWait>>())\n ),\n Effect.mapError(persistence(\"read nested human waits\"))\n )\n\n /**\n * The attributed cancel requests this plane journaled, by run id.\n *\n * The FIRST entry for a run wins. A cancel is idempotent, so a repeat asks\n * for something that already happened; the request that caused the\n * cancellation is the one that gets to name the principal and the reason.\n */\n const cancelRequests = (\n scope: IndexScope\n ): Effect.Effect<ReadonlyMap<string, Attribution.Request>, PersistenceError> =>\n sql<{\n readonly runId: string\n readonly emittedAtMs: number\n readonly payloadJson: string\n }>`\n SELECT run_id AS \"runId\", emitted_at_ms AS \"emittedAtMs\", payload_json AS \"payloadJson\"\n FROM flows_journal_events\n WHERE event_type = ${Attribution.requestedEventType} AND ${within(\"run_id\", scope)}\n ORDER BY run_id, seq\n `.pipe(\n Effect.catchIf(\n missingTable(\"flows_journal_events\"),\n () =>\n Effect.succeed(\n new Array<{ readonly runId: string; readonly emittedAtMs: number; readonly payloadJson: string }>()\n )\n ),\n Effect.mapError(persistence(\"read cancel requests\")),\n Effect.flatMap((rows) =>\n Effect.gen(function*() {\n const requests = new Map<string, Attribution.Request>()\n for (const row of rows) {\n if (requests.has(row.runId)) continue\n const payload = yield* decodeStoredJson(\n \"flows_journal_events.payload_json for control.run.cancel-requested\",\n CancelRequestPayload,\n row.payloadJson\n )\n requests.set(row.runId, {\n requestedAt: Number(row.emittedAtMs),\n ...(payload.principal === undefined ? {} : { principal: payload.principal }),\n ...(payload.reason === undefined ? {} : { reason: payload.reason })\n })\n }\n return requests\n })\n )\n )\n\n /**\n * When the engine journaled each run's interruption.\n *\n * The engine writes this record in the same transaction as the `cancelled`\n * transition (`packages/smithers/flows/engine-store/src/internal/RunDriver.ts`), so it is\n * the moment a cancellation actually took, as opposed to the moment\n * somebody asked. A run cancelled by a peer process that never wrote a\n * request column still has this.\n */\n const engineInterruptions = (scope: IndexScope): Effect.Effect<ReadonlyMap<string, number>, PersistenceError> =>\n sql<{\n readonly runId: string\n readonly payloadJson: string\n }>`\n SELECT run_id AS \"runId\", payload_json AS \"payloadJson\"\n FROM flows_journal_events\n WHERE event_type = ${Attribution.interruptedEventType} AND ${within(\"run_id\", scope)}\n `.pipe(\n Effect.catchIf(\n missingTable(\"flows_journal_events\"),\n () => Effect.succeed(new Array<{ readonly runId: string; readonly payloadJson: string }>())\n ),\n Effect.mapError(persistence(\"read engine interruptions\")),\n Effect.flatMap((rows) =>\n Effect.gen(function*() {\n const cancelled = new Map<string, number>()\n for (const row of rows) {\n const payload = yield* decodeStoredJson(\n \"flows_journal_events.payload_json for flows.engine.interrupted\",\n EngineInterruptionPayload,\n row.payloadJson\n )\n if (payload.outcome !== \"cancelled\") continue\n cancelled.set(row.runId, Number(payload.interruptedAtMs ?? 0))\n }\n return cancelled\n })\n )\n )\n\n /**\n * The ancestry and cancel columns of every run row.\n *\n * Cascade is a fact about a run's ancestors, so the attribution cannot be\n * decided a row at a time: the request that cancelled a child may be three\n * rounds up the chain.\n */\n const cancelEvidence = (scope: IndexScope): Effect.Effect<\n ReadonlyArray<{\n readonly runId: string\n readonly parentRunId: string | null\n readonly cancelRequestedAtMs: number | null\n }>,\n PersistenceError\n > =>\n sql<{\n readonly runId: string\n readonly parentRunId: string | null\n readonly cancelRequestedAtMs: number | null\n }>`\n SELECT run_id AS \"runId\", parent_run_id AS \"parentRunId\",\n cancel_requested_at_ms AS \"cancelRequestedAtMs\"\n FROM flows_runs WHERE ${within(\"run_id\", scope)}\n `.pipe(Effect.mapError(persistence(\"read cancel evidence\")))\n\n /** Every cancelled run's attribution in the scope, folded in one pass. */\n const cancellations = (scope: IndexScope): Effect.Effect<ReadonlyMap<string, Cancellation>, PersistenceError> =>\n Effect.map(\n Effect.all({\n rows: cancelEvidence(scope),\n requests: cancelRequests(scope),\n interrupted: engineInterruptions(scope),\n spawnedBy: spawnedBy(scope)\n }),\n ({ interrupted, requests, rows, spawnedBy }) =>\n Attribution.attribute({\n runs: rows.map((row) => {\n const parentRunId = row.parentRunId ?? spawnedBy.get(row.runId)\n const cancelledAt = interrupted.get(row.runId)\n return {\n runId: row.runId,\n ...(parentRunId === undefined || parentRunId === null ? {} : { parentRunId }),\n ...(row.cancelRequestedAtMs === null ? {} : { cancelRequestedAt: Number(row.cancelRequestedAtMs) }),\n ...(cancelledAt === undefined ? {} : { cancelledAt })\n }\n }),\n requests\n })\n )\n\n /**\n * The outstanding resume delegation of each run in the scope.\n *\n * Read from `control_run_resumes` rather than from the journal because the\n * question is \"what has not been taken up yet\", which a log of what was\n * asked cannot answer without a per-run cursor.\n */\n const pendingResumeIndex = (scope: IndexScope): Effect.Effect<ReadonlyMap<string, number>, PersistenceError> =>\n sql<{ readonly runId: string; readonly requestedSeq: number }>`\n SELECT run_id AS \"runId\", requested_seq AS \"requestedSeq\"\n FROM control_run_resumes WHERE ${within(\"run_id\", scope)}\n `.pipe(\n Effect.map((rows) =>\n new Map(rows.map((row) => [row.runId, Number(row.requestedSeq)] as const)) as ReadonlyMap<string, number>\n ),\n Effect.mapError(persistence(\"read pending resumes\"))\n )\n\n /** Every index a projection needs over one scope, read together. */\n const ancestryIndex = (scope: IndexScope): Effect.Effect<AncestryIndex, PersistenceError> =>\n Effect.map(\n Effect.all({\n forked: forkedRunIds(scope),\n spawnedBy: spawnedBy(scope),\n waitingFor: waitingFor(scope),\n humanWaits: humanWaits(scope),\n cancellations: cancellations(scope),\n pendingResumes: pendingResumeIndex(scope)\n }),\n (index): AncestryIndex => index\n )\n\n /**\n * One run and every ancestor above it, nearest first.\n *\n * The trampoline chain is one recursive read over `parent_run_id`. A\n * SPAWNED run records nothing in its own row, so when a chain runs out the\n * spawn edge is looked up and the walk continues from there \u2014 one extra\n * read per nesting level, and subflow nesting is shallow where a\n * trampoline is long. The visited set makes corrupt ancestry terminate\n * instead of taking the control plane down with it.\n */\n const ancestorChain = (runId: RunId): Effect.Effect<ReadonlyArray<string>, PersistenceError> =>\n Effect.gen(function*() {\n const chain: Array<string> = []\n const visited = new Set<string>()\n let start: string | undefined = runId\n while (start !== undefined && !visited.has(start)) {\n const rows = yield* sql<{ readonly runId: string; readonly parentRunId: string | null }>`\n WITH RECURSIVE ancestry(run_id, parent_run_id) AS (\n SELECT run_id, parent_run_id FROM flows_runs WHERE run_id = ${start}\n UNION\n SELECT runs.run_id, runs.parent_run_id\n FROM flows_runs runs JOIN ancestry ON runs.run_id = ancestry.parent_run_id\n )\n SELECT run_id AS \"runId\", parent_run_id AS \"parentRunId\" FROM ancestry\n `.pipe(Effect.mapError(persistence(\"walk a run's ancestry\")))\n if (rows.length === 0) {\n // No row at all: the caller's own `requireRow` reports that.\n chain.push(start)\n break\n }\n let last: string | undefined\n for (const row of rows) {\n if (visited.has(row.runId)) continue\n visited.add(row.runId)\n chain.push(row.runId)\n if (row.parentRunId === null) last = row.runId\n }\n // The chain ended at a row naming no parent. A run somebody SPAWNED\n // records its parent in the edge table instead, so the walk\n // continues from there.\n const spawn = last === undefined ? undefined : (yield* spawnedBy([last])).get(last)\n start = spawn\n }\n return chain\n })\n\n /**\n * One run row as a control summary, whoever wrote the row.\n *\n * `flows_runs.state_json` is `@smthrs/run-store`'s column and it has two\n * writers: this plane stores a `RunSummary` there, and the engine stores\n * its own `RunState` (`version`, `flowName`, `payload`). Decoding the\n * column as a `RunSummary` outright therefore failed\n * `PersistenceError` for every engine-created run before the caller could\n * reach the answer it was owed: `interrupt` reads the summary before it\n * asks who owns the row, so cancelling a run the ENGINE owns reported a\n * corrupt database instead of the `ClaimLost` that lets `Control.cancel`\n * fall back to the durable request, and `resume` failed the same way\n * before it could delegate to the owning driver.\n *\n * `baseSummary` already projects both shapes for listings. Sharing it here\n * keeps one answer for one row: a control row decodes to the summary it\n * stored, and an engine row is projected from the columns the run store\n * owns. Nothing writes back through this path except a transition this\n * plane's own fence authorized, which is a control row by construction.\n */\n const summaryOf = (row: RunStore.RunRow): Effect.Effect<RunSummary, PersistenceError> =>\n Effect.zipWith(\n decodeRunState(row.stateJson),\n launcherOf(row.runId),\n (state, launcher) => withLauncher(baseSummary(row, state), launcher)\n )\n\n const snapshotOf = (row: RunStore.RunRow): RunStore.RunSnapshot => ({\n status: row.status,\n owner: row.owner,\n heartbeatAtMs: row.heartbeatAtMs\n })\n\n // A type predicate, not a plain boolean: a row this process owns has a\n // non-null owner by construction, and the callers hand `row.owner` straight\n // to the fenced transitions.\n const ownedByUs = (\n row: RunStore.RunRow\n ): row is RunStore.RunRow & { readonly owner: Ownership.OwnerId } =>\n row.status === \"running\" && row.owner !== null && sameProcess(row.owner, owner)\n\n /**\n * Moves a run this process owns to a new control status, writing the\n * projection in the same compare-and-swap. A lost fence is `ClaimLost`.\n */\n const transition = (\n runId: RunId,\n claim: Ownership.OwnerId,\n summary: RunSummary,\n status: RunStatus\n ): Effect.Effect<RunSummary, RunNotFound | ClaimLost | PersistenceError> =>\n Effect.gen(function*() {\n const timestamp = yield* now\n const next: RunSummary = {\n ...summary,\n status,\n updatedAt: timestamp,\n ...(storeStatus(status) === \"running\" ? {} : { ownerId: undefined }),\n // A park releases the owner columns, so the row itself stops saying\n // which process is hosting the execution. The fence it was parked\n // under is kept instead: it is what lets the host recognize its own\n // park, and every other process tell that the execution belongs to\n // one it cannot see (triage B-15). Any other status ends the park,\n // so it ends the record with it.\n parkedBy: storeStatus(status) === \"suspended\" ? JSON.stringify(claim) : undefined\n }\n const outcome = yield* runStore.transitionOwned(\n runId,\n claim,\n storeStatus(status),\n JSON.stringify(next)\n ).pipe(Effect.mapError(persistence(\"transition a run\")))\n if (outcome._tag === \"NotFound\") return yield* Effect.fail(new RunNotFound({ runId }))\n if (outcome._tag !== \"Transitioned\") return yield* Effect.fail(new ClaimLost({ runId }))\n return next\n })\n\n /**\n * Evidence that a running row's owner is gone, from the configured\n * liveness check, or `undefined` when there is no check or the owner is\n * alive. A pid is evidence only on its own host; elsewhere the claim\n * rests on the expired lease the run store verifies.\n */\n const deadOwner = (\n row: RunStore.RunRow\n ): Effect.Effect<Ownership.LivenessEvidence | undefined> =>\n Effect.gen(function*() {\n if (isAlive === undefined || row.owner === null) return undefined\n const nowMs = yield* now\n const alive = yield* isAlive(row.owner, { claimant: owner, heartbeatAtMs: row.heartbeatAtMs, nowMs })\n if (alive) return undefined\n return {\n expectedOwner: row.owner,\n checkedAtMs: nowMs,\n kind: Ownership.sameHostIncarnation(row.owner, owner)\n ? \"same-host-pid-dead\" as const\n : \"lease-expired\" as const\n }\n })\n\n /**\n * Takes ownership of a suspended or pending run under a fresh nonce, or\n * of a running one whose owner `evidence` says is gone.\n */\n const claim = (\n runId: RunId,\n row: RunStore.RunRow,\n evidence?: Ownership.LivenessEvidence | undefined,\n adopted?: Pick<RunSummary, \"executionDigest\" | \"engineVersion\"> | undefined\n ): Effect.Effect<RunSummary, RunNotFound | ClaimLost | PersistenceError> =>\n Effect.gen(function*() {\n const timestamp = evidence?.checkedAtMs ?? (yield* now)\n const claimant: Ownership.OwnerId = { ...owner, nonce: randomId() }\n const outcome = yield* runStore.claimAndOwn(runId, snapshotOf(row), claimant, timestamp, evidence).pipe(\n Effect.mapError(persistence(\"claim a run\"))\n )\n if (outcome._tag === \"NotFound\") return yield* Effect.fail(new RunNotFound({ runId }))\n if (outcome._tag !== \"Activated\") return yield* Effect.fail(new ClaimLost({ runId }))\n const summary = yield* summaryOf(row)\n return yield* transition(runId, claimant, {\n ...summary,\n ...adopted,\n ownerId: JSON.stringify(claimant)\n }, \"accepted\")\n })\n\n /**\n * The run's summary with the code identity it started on.\n *\n * A row with no control summary of its own (a trampoline round, or a fork\n * or child the engine wrote) records no identity, and checking it against\n * nothing let it resume on any code. It inherits the identity of its\n * nearest ancestor of the same flow that recorded one.\n */\n const recordedCode = (row: RunStore.RunRow): Effect.Effect<RunSummary, PersistenceError> =>\n Effect.gen(function*() {\n const summary = yield* summaryOf(row)\n const seen = new Set<string>([row.runId])\n let parentId = optional(row.parentRunId).value ?? summary.parentRunId\n while (\n summary.executionDigest === undefined && summary.engineVersion === undefined &&\n parentId !== undefined && !seen.has(parentId)\n ) {\n seen.add(parentId)\n const parentRow = yield* requireRow(parentId).pipe(\n Effect.catchTag(\"/control/RunNotFound\", () => Effect.succeed(undefined))\n )\n if (parentRow === undefined) break\n const parent = yield* summaryOf(parentRow)\n if (parent.flowId !== summary.flowId) break\n if (parent.executionDigest !== undefined || parent.engineVersion !== undefined) {\n return { ...summary, executionDigest: parent.executionDigest, engineVersion: parent.engineVersion }\n }\n parentId = optional(parentRow.parentRunId).value ?? parent.parentRunId\n }\n return summary\n })\n\n /**\n * The code identity an allowed drift records, read before the claim: a\n * flow this host cannot run leaves the run where it was rather than\n * accepted and then failed (#2740).\n */\n const adoptable = (\n row: RunStore.RunRow\n ): Effect.Effect<Pick<RunSummary, \"executionDigest\" | \"engineVersion\">, CodeDrift | PersistenceError> =>\n Effect.gen(function*() {\n const summary = yield* summaryOf(row)\n const flow = yield* readAdoptedFlow(summary.flowId, summary.runId)\n const gone = flow === undefined\n ? codeDriftOf(yield* recordedCode(row), undefined, options.engineVersion)\n : undefined\n if (gone !== undefined) return yield* gone\n return adoptedCode(summary, flow, options.engineVersion)\n })\n\n /** `resume`, recording the identity `adopt` answers on the claimed run when given. */\n const resumeRun = <E = never>(\n runId: RunId,\n scope: \"launched\" | \"any\" | undefined,\n adopt?:\n | ((row: RunStore.RunRow) => Effect.Effect<Pick<RunSummary, \"executionDigest\" | \"engineVersion\">, E>)\n | undefined\n ): Effect.Effect<RunSummary, RunNotFound | ClaimLost | PersistenceError | E> =>\n Effect.gen(function*() {\n const row = yield* requireRow(runId)\n const summary = yield* summaryOf(row)\n if (terminal(summary.status)) return summary\n // Start-or-join: owning the run already means resume is a no-op.\n if (ownedByUs(row)) return summary\n // Parking clears ownership, but the detached host can still be alive.\n // Public resume may take its park only after a same-host dead-pid\n // probe; otherwise the caller would steal and interrupt its execution.\n // The refusal names that host, so `Control.resume` hands the resume\n // to it instead (#3342). Trusted host claims remain able to reclaim\n // their engine's execution.\n if (scope === \"launched\" && row.status === \"suspended\" && summary.parkedBy !== undefined) {\n const parkedOwner = yield* decodeStoredJson(\"parked host\", Ownership.OwnerId, summary.parkedBy)\n if (!sameProcess(parkedOwner, owner)) {\n const alive = isAlive === undefined || !Ownership.sameHostIncarnation(parkedOwner, owner)\n ? true\n : yield* isAlive(parkedOwner, { claimant: owner, heartbeatAtMs: row.heartbeatAtMs, nowMs: yield* now })\n if (alive) {\n return yield* new ClaimLost({\n runId,\n reason: \"The host that parked this run is still alive or its liveness is unknown\",\n parkedBy: { hostId: parkedOwner.hostId, pid: parkedOwner.pid }\n })\n }\n }\n }\n // Every public Control resume and steer wake uses launched scope.\n // Engine-created runs keep their continuation and driver. Unrestricted\n // claims are a trusted low-level capability for hosts that can drive\n // the execution; node approval delegates through requestResume instead.\n if (scope === \"launched\") {\n const indexed = yield* sql`SELECT run_id FROM control_runs WHERE run_id = ${runId}`.pipe(\n Effect.mapError(persistence(\"read the launch index\"))\n )\n if (indexed.length === 0) return yield* new ClaimLost({ runId })\n }\n // A run owned by a live peer is theirs to drive. A run whose owner is\n // gone is taken over, with the evidence the run store checks.\n if (row.status === \"running\") {\n const evidence = yield* deadOwner(row)\n return evidence === undefined\n ? yield* new ClaimLost({ runId })\n : yield* claim(runId, row, evidence, adopt === undefined ? undefined : yield* adopt(row))\n }\n return yield* claim(runId, row, undefined, adopt === undefined ? undefined : yield* adopt(row))\n })\n\n // Match summaryFrom's durable fields in SQL. Only the selected ids are\n // decoded or expanded into ancestry; one extra key determines continuation.\n const runPageKeys = (\n request: RunQuery,\n includeSpawn: boolean = true,\n includeWaitRollup: boolean = true\n ): Effect.Effect<\n ReadonlyArray<RunCursor>,\n PersistenceError\n > => {\n const filters = request.filters\n const source = sql`CASE WHEN indexed.created_seq IS NULL THEN 1 ELSE 0 END`\n const sequence = sql`COALESCE(indexed.created_seq, 0)`\n const controlState = sql`(${Dialect.jsonText(sql, sql`runs.state_json`, \"$.runId\")} IS NOT NULL\n OR ${Dialect.jsonText(sql, sql`runs.state_json`, \"$.flowId\")} IS NOT NULL\n OR ${Dialect.jsonText(sql, sql`runs.state_json`, \"$.status\")} IS NOT NULL)`\n const flowId = sql`CASE WHEN ${controlState} THEN ${Dialect.jsonText(sql, sql`runs.state_json`, \"$.flowId\")}\n ELSE ${Dialect.jsonText(sql, sql`runs.state_json`, \"$.flowName\")} END`\n const ownStatus = sql`CASE WHEN ${controlState} THEN ${Dialect.jsonText(sql, sql`runs.state_json`, \"$.status\")}\n ELSE CASE runs.status WHEN 'pending' THEN 'accepted' WHEN 'suspended' THEN 'parked' ELSE runs.status END END`\n // The listing filter has to agree with the summary the listing returns.\n // `summaryFrom` rolls a run tree's open human waits up onto the root's\n // status, so the SQL that decides which runs a `status:\n // \"waiting-approval\"` page contains must roll them up too \u2014 otherwise\n // the inbox filter skips exactly the rows the inbox is for, which is how\n // run-3 stayed invisible while parked on `coding-clarification`.\n const status = includeWaitRollup\n ? sql`CASE\n WHEN runs.status NOT IN ('completed', 'failed', 'cancelled')\n AND runs.run_id IN (SELECT ancestorId FROM human_wait_ancestry)\n THEN 'waiting-approval' ELSE ${ownStatus} END`\n : ownStatus\n const storedParent = sql`CASE WHEN ${controlState} THEN ${\n Dialect.jsonText(sql, sql`runs.state_json`, \"$.parentRunId\")\n } END`\n const storedLineage = sql`CASE WHEN ${controlState} THEN ${\n Dialect.jsonText(sql, sql`runs.state_json`, \"$.lineageId\")\n } END`\n const parent = includeSpawn\n ? sql`COALESCE(runs.parent_run_id,\n (SELECT parent_id FROM flows_run_parents WHERE child_id = runs.run_id ORDER BY seq LIMIT 1),\n ${storedParent})`\n : sql`COALESCE(runs.parent_run_id, ${storedParent})`\n const lineage = sql`COALESCE(runs.lineage_id, ${storedLineage})`\n const after = request.cursor\n const conditions = [sql`1 = 1`]\n if (filters?.flowId !== undefined) conditions.push(sql`${flowId} = ${filters.flowId}`)\n if (filters?.status !== undefined) conditions.push(sql`${status} = ${filters.status}`)\n if (filters?.terminal !== undefined) {\n const isTerminal = sql`${status} IN ('completed', 'failed', 'cancelled')`\n conditions.push(filters.terminal ? isTerminal : sql`NOT (${isTerminal})`)\n }\n if (filters?.parentRunId !== undefined) conditions.push(sql`${parent} = ${filters.parentRunId}`)\n if (filters?.lineageId !== undefined) conditions.push(sql`${lineage} = ${filters.lineageId}`)\n if (filters?.since !== undefined) conditions.push(sql`runs.created_at_ms >= ${filters.since}`)\n if (filters?.until !== undefined) conditions.push(sql`runs.created_at_ms < ${filters.until}`)\n if (filters?.launchedBy !== undefined) {\n conditions.push(sql`indexed.principal_id = ${filters.launchedBy.id}`)\n if (filters.launchedBy.kind !== undefined) {\n conditions.push(sql`indexed.principal_kind = ${filters.launchedBy.kind}`)\n }\n }\n if (filters?.runIds !== undefined) {\n // One JSON parameter, so a trigger's whole ledger never meets the bind-variable limit.\n const ids = JSON.stringify([...new Set(filters.runIds)])\n conditions.push(\n sql.onDialectOrElse({\n pg: () => sql`runs.run_id IN (SELECT jsonb_array_elements_text(${ids}::jsonb))`,\n orElse: () => sql`runs.run_id IN (SELECT value FROM json_each(${ids}))`\n })\n )\n }\n if (after !== undefined) {\n conditions.push(\n request.order === \"newest\"\n ? sql`(runs.created_at_ms, ${source}, ${sequence}, runs.run_id) <\n (${after.createdAt}, ${after.source}, ${after.sequence}, ${after.runId})`\n : request.order === \"oldest\"\n ? sql`(runs.created_at_ms, ${source}, ${sequence}, runs.run_id) >\n (${after.createdAt}, ${after.source}, ${after.sequence}, ${after.runId})`\n : sql`(${source}, ${sequence}, runs.created_at_ms, runs.run_id) >\n (${after.source}, ${after.sequence}, ${after.createdAt}, ${after.runId})`\n )\n }\n // Computed once for the whole page rather than per row: the set of runs\n // with an open human wait at or below them, climbed from the few parked\n // rows instead of descended from every run.\n const waitAncestry = includeWaitRollup\n ? sql`WITH RECURSIVE human_wait_ancestry(ancestorId, depth) AS (\n SELECT run_id, 0 FROM flows_runs\n WHERE waiting_reason = ${ControlExecutor.humanWaitReason}\n AND status NOT IN ('completed', 'failed', 'cancelled')\n UNION\n SELECT parent.run_id, human_wait_ancestry.depth + 1\n FROM flows_runs step JOIN human_wait_ancestry ON step.run_id = human_wait_ancestry.ancestorId\n JOIN flows_runs parent ON parent.run_id IN (\n SELECT parent_id FROM flows_run_parents WHERE child_id = step.run_id\n UNION ALL\n SELECT step.parent_run_id WHERE step.parent_run_id IS NOT NULL\n )\n WHERE human_wait_ancestry.depth < ${maxWaitTreeDepth}\n AND (parent.run_id = step.parent_run_id\n OR COALESCE(${Dialect.jsonText(sql, sql`step.state_json`, \"$.onParentExit\")}, 'cancel') <> 'detach')\n )`\n : sql.literal(\"\")\n return sql<RunCursor>`\n ${waitAncestry}\n SELECT runs.run_id AS \"runId\", ${source} AS source, ${sequence} AS sequence,\n runs.created_at_ms AS \"createdAt\"\n FROM flows_runs AS runs LEFT JOIN control_runs AS indexed ON indexed.run_id = runs.run_id\n WHERE ${sql.and(conditions)}\n ORDER BY ${\n request.order === \"newest\"\n ? sql`runs.created_at_ms DESC, ${source} DESC, ${sequence} DESC, runs.run_id DESC`\n : request.order === \"oldest\"\n ? sql`runs.created_at_ms, ${source}, ${sequence}, runs.run_id`\n : sql`${source}, ${sequence}, runs.created_at_ms, runs.run_id`\n }\n LIMIT ${request.limit + 1}\n `.pipe(\n probe,\n Effect.catchIf(\n (error) => includeSpawn && filters?.parentRunId !== undefined && missingTable(\"flows_run_parents\")(error),\n () => runPageKeys(request, false, includeWaitRollup)\n ),\n // Without the engine's wait-tree schema, retain the ordinary page.\n Effect.catchIf(\n (error) => includeWaitRollup && missingWaitTreeSchema(error),\n () => runPageKeys(request, includeSpawn, false)\n ),\n Effect.mapError(persistence(\"query runs\"))\n )\n }\n\n /**\n * One inventory page of `table` by `rowid`: the insertion-ordered row key\n * both dialects index (SQLite's b-tree key, PostgreSQL's identity column),\n * so a page is one seek and `limit + 1` rows however large the table is.\n * The first page pins `through` to the newest row, so a walk ends while\n * inserts continue.\n */\n const pageByRowId = (\n request: IdPageRequest,\n table: \"flows_runs\" | \"control_plans\",\n column: \"run_id\" | \"plan_id\",\n operation: string\n ): Effect.Effect<IdPage, InvalidInput | PersistenceError> =>\n Effect.gen(function*() {\n yield* idPageLimit(request.limit)\n const through = request.through ?? Number(\n (yield* sql<{ readonly newest: number | string | null }>`\n SELECT MAX(rowid) AS newest FROM ${sql.literal(table)}\n `.pipe(query(operation)))[0]?.newest ?? 0\n )\n const rows = yield* sql<{ readonly id: string; readonly position: number | string }>`\n SELECT ${sql.literal(column)} AS id, rowid AS position FROM ${sql.literal(table)}\n WHERE rowid > ${request.after ?? 0} AND rowid <= ${through}\n ORDER BY rowid LIMIT ${request.limit + 1}\n `.pipe(query(operation))\n const selected = rows.slice(0, request.limit)\n return rows.length > request.limit\n ? { ids: selected.map((row) => row.id), next: Number(selected.at(-1)!.position), through }\n : { ids: selected.map((row) => row.id), through }\n })\n\n const pagePlanIds = (request: IdPageRequest) => pageByRowId(request, \"control_plans\", \"plan_id\", \"page plans\")\n\n /**\n * One page of stored plans by `rowid`. The decision narrows in SQL; the flow\n * is read from the stored card, so a page reads batches until it fills or\n * the table ends.\n */\n const queryPlans = (request: PlanQuery): Effect.Effect<PlanPage, InvalidInput | PersistenceError> =>\n Effect.gen(function*() {\n yield* idPageLimit(request.limit)\n const plans: Array<StoredPlan> = []\n let after = request.after ?? 0\n while (true) {\n const conditions = [\n sql`rowid > ${after}`,\n ...(request.decision === undefined ? [] : [sql`decision = ${request.decision}`])\n ]\n const rows = yield* sql<PlanRow & { readonly position: number | string }>`\n SELECT plan_id AS \"planId\", card_json AS \"cardJson\",\n decoded_input_json AS \"decodedInputJson\", decision, rowid AS position\n FROM control_plans WHERE ${sql.and(conditions)}\n ORDER BY rowid LIMIT ${planScanBatch}\n `.pipe(query(\"page plans\"))\n for (const [index, row] of rows.entries()) {\n after = Number(row.position)\n const plan = yield* storedPlan(row)\n if (request.flowId !== undefined && plan.card.flowId !== request.flowId) continue\n plans.push(plan)\n if (plans.length === request.limit) {\n return index < rows.length - 1 || rows.length === planScanBatch ? { plans, next: after } : { plans }\n }\n }\n if (rows.length < planScanBatch) return { plans }\n }\n })\n\n /**\n * The recorded launcher of a run this plane launched. The launch index is\n * written once, so it outlives the control summary the engine replaces in\n * `flows_runs.state_json` when it takes the run over.\n */\n const launcherOf = (\n runId: RunId\n ): Effect.Effect<{ readonly id: string; readonly kind: string } | undefined, PersistenceError> =>\n Effect.map(\n sql<{ readonly id: string | null; readonly kind: string | null }>`\n SELECT principal_id AS id, principal_kind AS kind FROM control_runs WHERE run_id = ${runId}\n `.pipe(query(\"read a run launcher\")),\n (rows) => {\n const row = rows[0]\n return row === undefined || row.id === null || row.kind === null ? undefined : { id: row.id, kind: row.kind }\n }\n )\n\n const messages = <S extends Schema.Top>(\n runId: RunId,\n kind: \"signal\",\n schema: S\n ): Effect.Effect<ReadonlyArray<S[\"Type\"]>, PersistenceError, S[\"DecodingServices\"]> =>\n sql<{ readonly payloadJson: string }>`\n SELECT payload_json AS \"payloadJson\" FROM control_run_messages\n WHERE run_id = ${runId} AND kind = ${kind} ORDER BY seq\n `.pipe(\n query(\"read run messages\"),\n Effect.flatMap((rows) =>\n Effect.forEach(\n rows,\n (row) => decodeStoredJson(`control_run_messages.payload_json as ${kind}`, schema, row.payloadJson)\n )\n )\n )\n\n const appendMessage = (\n runId: RunId,\n kind: \"signal\",\n payload: unknown\n ): Effect.Effect<void, RunNotFound | PersistenceError> =>\n Effect.gen(function*() {\n yield* requireRow(runId)\n yield* sql`\n INSERT INTO control_run_messages (run_id, kind, payload_json)\n VALUES (${runId}, ${kind}, ${JSON.stringify(payload)})\n `.pipe(Effect.mapError(persistence(\"append a run message\")))\n })\n\n const service = make({\n authorizeApproval,\n plan: Effect.fn(\"SqlControlRuntime.plan\")(function*(input: PlanInput) {\n const flow = (yield* readFlows).get(input.flowId)\n if (flow === undefined) {\n return yield* new FlowNotFound({ flowId: input.flowId })\n }\n const requestFingerprint = yield* Effect.try({\n try: () => planFingerprint(input),\n catch: (cause) => new InvalidInput({ issue: canonicalIssue(cause) })\n })\n if (input.idempotencyKey !== undefined) {\n const prior = yield* sql<{ readonly fingerprint: string; readonly planId: string }>`\n SELECT fingerprint, plan_id AS \"planId\" FROM control_plan_keys\n WHERE idempotency_key = ${input.idempotencyKey}\n `.pipe(query(\"read a plan key\"))\n const found = prior[0]\n if (found !== undefined) {\n if (found.fingerprint !== requestFingerprint) {\n return yield* new InvalidInput({\n issue: `idempotency key ${input.idempotencyKey} was used for another plan`\n })\n }\n const stored = yield* readPlan(found.planId)\n if (Option.isSome(stored)) {\n const decoded = yield* storedPlan(stored.value)\n return { card: decoded.card, created: false }\n }\n }\n }\n const decoded = yield* (flow.decode?.(input.input) ?? Effect.try({\n try: () => {\n canonical(input.input)\n return input.input\n },\n catch: (cause) => new InvalidInput({ issue: canonicalIssue(cause) })\n }))\n const planId = `plan-${yield* nextSequence(\"plan\")}`\n const handoff = flow.plan === undefined ? undefined : yield* flow.plan(decoded, planId)\n const card = yield* planCard({\n planId,\n flowId: input.flowId,\n decodedInput: decoded,\n envelope: budgeted(flow.envelope, input.budget),\n deployClass: flow.deployClass,\n executionDigest: flow.executionDigest,\n handoff,\n idempotencyKey: input.idempotencyKey\n }).pipe(Effect.provideService(Crypto.Crypto, crypto))\n const identity = approvalIdentity(card.approval.target)\n // The key row is claimed FIRST, and the claim is a conditional insert\n // followed by a read of whoever holds it. `idempotency_key` is the\n // primary key, so a bare insert made two runtimes planning under one\n // key a race the loser lost with a constraint violation surfaced as\n // `PersistenceError`, instead of the winner's card the key promises.\n // Under Control.plan this write joins the journal transaction, so the\n // card, key, token and creation entry commit or roll back together.\n const outcome = yield* writer.write(Effect.gen(function*() {\n if (input.idempotencyKey !== undefined) {\n yield* sql`\n INSERT INTO control_plan_keys (idempotency_key, fingerprint, plan_id)\n VALUES (${input.idempotencyKey}, ${requestFingerprint}, ${planId})\n ON CONFLICT (idempotency_key) DO NOTHING\n `\n const settled = yield* sql<{ readonly fingerprint: string; readonly planId: string }>`\n SELECT fingerprint, plan_id AS \"planId\" FROM control_plan_keys\n WHERE idempotency_key = ${input.idempotencyKey}\n `\n const holder = settled[0]\n if (holder !== undefined && holder.planId !== planId) {\n return { _tag: \"raced\", holder } as const\n }\n }\n // An explicit null input is stored as JSON text in the non-null column.\n const decodedJson = JSON.stringify(decoded ?? null)\n yield* sql`\n INSERT INTO control_plans (plan_id, card_json, decoded_input_json, decision)\n VALUES (${planId}, ${JSON.stringify(card)}, ${decodedJson}, 'pending')\n `\n yield* sql`\n INSERT INTO control_tokens (\n target_tag, run_id, target_id, token_id, target_json, resolved, decision_principal_json\n )\n VALUES (\n ${identity.targetTag}, ${identity.runId}, ${identity.targetId}, ${planId},\n ${JSON.stringify(card.approval.target)}, 0, NULL\n )\n `\n return { _tag: \"stored\" } as const\n })).pipe(Effect.mapError(persistence(\"store a plan\")))\n if (outcome._tag === \"raced\") {\n if (outcome.holder.fingerprint !== requestFingerprint) {\n return yield* new InvalidInput({\n issue: `idempotency key ${String(input.idempotencyKey)} was used for another plan`\n })\n }\n const stored = yield* readPlan(outcome.holder.planId)\n if (Option.isNone(stored)) {\n return yield* new PersistenceError({\n operation: \"read a plan\",\n message: `plan key ${String(input.idempotencyKey)} names plan ${outcome.holder.planId}, which is absent`\n })\n }\n const decodedHolder = yield* storedPlan(stored.value)\n return { card: decodedHolder.card, created: false }\n }\n return { card, created: true }\n }),\n getPlan: Effect.fn(\"SqlControlRuntime.getPlan\")((planId: string) =>\n Effect.flatMap(requirePlan(planId), storedPlan)\n ),\n pagePlanIds,\n queryPlans,\n lookupApproval: Effect.fn(\"SqlControlRuntime.lookupApproval\")(function*(target: ApprovalTarget) {\n const tokenId = target._tag === \"Plan\" ? target.planId : target.requestId\n const identity = approvalIdentity(target)\n const rows = yield* sql<TokenRow>`\n SELECT token_id AS \"tokenId\", target_json AS \"targetJson\", resolved,\n decision_principal_json AS \"decisionPrincipalJson\", decision_json AS \"decisionJson\"\n FROM control_tokens\n WHERE target_tag = ${identity.targetTag}\n AND run_id = ${identity.runId}\n AND target_id = ${identity.targetId}\n `.pipe(query(\"read an approval token\"))\n const row = rows[0]\n if (row === undefined) {\n return yield* (target._tag === \"Node\"\n ? new RunNotFound({ runId: target.runId })\n : new PlanNotFound({ planId: target.planId }))\n }\n const stored = yield* decodeStoredJson(\"control_tokens.target_json\", ApprovalTarget, row.targetJson)\n // The composite columns select the requested identity. The decoded copy\n // must agree too, or a rewritten JSON blob could smuggle a foreign\n // target back into the token after lookup.\n if (!sameApprovalIdentity(stored, target)) {\n return yield* new PersistenceError({\n operation: \"validate an approval token\",\n message: \"The stored approval target does not match its identity\"\n })\n }\n if (stored.digest !== target.digest) {\n return yield* new PlanDigestMismatch({\n planId: tokenId,\n expected: stored.digest,\n actual: target.digest\n })\n }\n if (!sameEnvelope(stored.envelope, target.envelope)) {\n return yield* new EnvelopeMismatch({\n planId: tokenId,\n expected: canonical(stored.envelope),\n actual: canonical(target.envelope)\n })\n }\n const token = yield* tokenFromRow(row, stored)\n if (token._tag !== \"Pending\") return yield* new AlreadyResolved({ requestId: tokenId })\n return token\n }),\n registerApproval: Effect.fn(\"SqlControlRuntime.registerApproval\")(function*(\n target: Extract<ApprovalTarget, { readonly _tag: \"Node\" }>\n ) {\n yield* requireRow(target.runId)\n const identity = approvalIdentity(target)\n yield* sql`\n INSERT INTO control_tokens (\n target_tag, run_id, target_id, token_id, target_json, resolved, decision_principal_json\n )\n VALUES (\n ${identity.targetTag}, ${identity.runId}, ${identity.targetId}, ${target.requestId},\n ${JSON.stringify(target)}, 0, NULL\n )\n ON CONFLICT (target_tag, run_id, target_id) DO NOTHING\n `.pipe(Effect.mapError(persistence(\"register an approval token\")))\n const rows = yield* sql<TokenRow>`\n SELECT token_id AS \"tokenId\", target_json AS \"targetJson\", resolved,\n decision_principal_json AS \"decisionPrincipalJson\", decision_json AS \"decisionJson\"\n FROM control_tokens\n WHERE target_tag = ${identity.targetTag}\n AND run_id = ${identity.runId}\n AND target_id = ${identity.targetId}\n `.pipe(query(\"read an approval token\"))\n const row = rows[0]\n if (row === undefined) {\n return yield* Effect.fail(\n new PersistenceError({\n operation: \"register an approval token\",\n message: \"A registered approval token could not be read back\"\n })\n )\n }\n const stored = yield* decodeStoredJson(\"control_tokens.target_json\", ApprovalTarget, row.targetJson)\n if (!sameApprovalIdentity(stored, target)) {\n return yield* new PersistenceError({\n operation: \"validate an approval token\",\n message: \"The stored approval target does not match its identity\"\n })\n }\n if (stored.digest !== target.digest) {\n return yield* new PlanDigestMismatch({\n planId: target.requestId,\n expected: stored.digest,\n actual: target.digest\n })\n }\n if (!sameEnvelope(stored.envelope, target.envelope)) {\n return yield* new EnvelopeMismatch({\n planId: target.requestId,\n expected: canonical(stored.envelope),\n actual: canonical(target.envelope)\n })\n }\n return yield* tokenFromRow(row, stored)\n }),\n installBulkGrant: Effect.fn(\"SqlControlRuntime.installBulkGrant\")(function*(\n token: ApprovalToken,\n envelope: Envelope,\n scope\n ) {\n const timestamp = yield* now\n const identity = approvalIdentity(token.target)\n // The envelope is installed whole. Splitting it into capabilities here\n // would let a partial grant exist, which is exactly what the bulk-grant\n // rule forbids.\n yield* sql`\n INSERT INTO control_grants (\n target_tag, run_id, target_id, token_id, envelope_json, scope, installed_at_ms\n )\n VALUES (\n ${identity.targetTag}, ${identity.runId}, ${identity.targetId}, ${token.tokenId},\n ${JSON.stringify(envelope)}, ${scope}, ${timestamp}\n )\n ON CONFLICT (target_tag, run_id, target_id) DO NOTHING\n `.pipe(Effect.mapError(persistence(\"install a grant\")))\n }),\n resolveApproval: Effect.fn(\"SqlControlRuntime.resolveApproval\")(function*(\n token: ApprovalToken,\n decision: \"approved\" | \"denied\",\n principal: Principal,\n scope: GrantScope = \"once\"\n ) {\n // Caller-owned objects can change while the clock or writer yields.\n // Bind both representations of the principal, and the plan update,\n // to the same captured request rather than reading the caller again.\n const requested = yield* Effect.try({\n try: () => structuredClone({ target: token.target, principal, tokenId: token.tokenId }),\n catch: () =>\n new PersistenceError({\n operation: \"record an approval decision\",\n message: \"The approval request cannot be captured\"\n })\n })\n const identity = approvalIdentity(requested.target)\n const requestedPrincipal = requested.principal\n const tokenId = requested.tokenId\n const decidedAt = yield* now\n const answer = yield* decodeStoredValue(\n \"approval decision\",\n ApprovalDecision,\n decision === \"approved\"\n ? { _tag: \"Approved\", decisionPrincipal: requestedPrincipal, decidedAt, scope }\n : { _tag: \"Denied\", decisionPrincipal: requestedPrincipal, decidedAt }\n )\n // Exactly once: the guard is in the UPDATE, so two concurrent decisions\n // cannot both observe an unresolved token.\n const resolved = yield* writer.write(Effect.gen(function*() {\n yield* authorizeApproval({ principal: requestedPrincipal, target: requested.target, decision, scope })\n const rows = yield* sql<{ readonly tokenId: string }>`\n UPDATE control_tokens\n SET resolved = 1, decision_principal_json = ${JSON.stringify(requestedPrincipal)},\n decision_json = ${JSON.stringify(answer)}\n WHERE target_tag = ${identity.targetTag}\n AND run_id = ${identity.runId}\n AND target_id = ${identity.targetId}\n AND resolved = 0\n RETURNING token_id AS \"tokenId\"\n `\n if (rows.length === 0) return false\n if (identity.targetTag === \"Plan\") {\n yield* sql`UPDATE control_plans SET decision = ${decision} WHERE plan_id = ${identity.targetId}`\n }\n return true\n })).pipe(Effect.mapError((error) =>\n error instanceof Unauthorized || error instanceof PersistenceError\n ? error\n : persistence(\"resolve an approval\")(error)\n ))\n if (!resolved) return yield* new AlreadyResolved({ requestId: tokenId })\n }),\n launch: Effect.fn(\"SqlControlRuntime.launch\")(function*(\n planId: string,\n requestedDigest: string,\n envelope: Envelope,\n principal?: Principal | undefined,\n reservedRunId?: RunId | undefined\n ) {\n const row = yield* requirePlan(planId)\n const plan = yield* storedPlan(row)\n if (plan.card.digest !== requestedDigest) {\n return yield* new PlanDigestMismatch({\n planId,\n expected: plan.card.digest,\n actual: requestedDigest\n })\n }\n if (!sameEnvelope(plan.card.envelope, envelope)) {\n return yield* new EnvelopeMismatch({\n planId,\n expected: canonical(plan.card.envelope),\n actual: canonical(envelope)\n })\n }\n if (plan.decision === \"pending\") {\n const parked: LaunchResult = {\n _tag: \"Parked\",\n receipt: {\n _tag: \"Parked\",\n receiptId: `launch:${planId}`,\n planId,\n status: \"waiting-approval\"\n }\n }\n return parked\n }\n if (plan.decision !== \"approved\") return yield* new PlanDenied({ planId })\n\n const sequence = yield* nextSequence(\"run\")\n const runId = reservedRunId ?? `run-${sequence}`\n const timestamp = yield* now\n const claimant: Ownership.OwnerId = { ...owner, nonce: randomId() }\n const summary: RunSummary = {\n runId,\n flowId: plan.card.flowId,\n status: \"accepted\",\n planId,\n planDigest: plan.card.digest,\n ...(plan.card.executionDigest === undefined ? {} : { executionDigest: plan.card.executionDigest }),\n ...(options.engineVersion === undefined ? {} : { engineVersion: options.engineVersion }),\n ownerId: JSON.stringify(claimant),\n ...(plan.card.envelope.budget.deadline === undefined\n ? {}\n : { deadlineAt: timestamp + plan.card.envelope.budget.deadline }),\n createdAt: timestamp,\n updatedAt: timestamp\n }\n yield* runStore.create(runId, JSON.stringify(summary)).pipe(\n Effect.mapError(persistence(\"create a run\"))\n )\n yield* sql`INSERT INTO control_runs (run_id, created_seq, principal_id, principal_kind)\n VALUES (${runId}, ${sequence}, ${principal?.id ?? null}, ${principal?.kind ?? null})`.pipe(\n Effect.mapError(persistence(\"index a run\"))\n )\n const outcome = yield* runStore.claimAndOwn(\n runId,\n { status: \"pending\", owner: null, heartbeatAtMs: null },\n claimant,\n timestamp\n ).pipe(Effect.mapError(persistence(\"claim a new run\")))\n if (outcome._tag !== \"Activated\") return yield* new ClaimLost({ runId })\n const started: LaunchResult = {\n _tag: \"Started\",\n receipt: accepted(`launch:${planId}:${runId}`, runId),\n run: withLauncher(summary, principal)\n }\n return started\n }),\n getRun: Effect.fn(\"SqlControlRuntime.getRun\")((runId: RunId) =>\n Effect.gen(function*() {\n const row = yield* requireRow(runId)\n return yield* summaryFrom(row, yield* ancestryIndex(yield* ancestorChain(runId)))\n })\n ),\n /**\n * Every durable run in `flows_runs` insertion order: `control_runs`\n * indexes only the runs this plane launched, while a child, a fork, and a\n * later trampoline round are created by the engine straight into\n * `flows_runs`. One indexed seek per page, with no row decoded, so a\n * caller that walks every run holds one page of ids at a time.\n */\n pageRunIds: (request) => pageByRowId(request, \"flows_runs\", \"run_id\", \"page runs\"),\n queryRuns: Effect.fn(\"SqlControlRuntime.queryRuns\")(function*(request) {\n if (!Number.isSafeInteger(request.limit) || request.limit < 1 || request.limit > 500) {\n return yield* new InvalidInput({ issue: \"limit: must be an integer between 1 and 500\" })\n }\n const keys = yield* runPageKeys(request)\n const selected = keys.slice(0, request.limit)\n if (selected.length === 0) return { items: [] }\n const chains = yield* Effect.forEach(selected, (key) => ancestorChain(key.runId))\n const ancestry = yield* ancestryIndex([...new Set(chains.flat())])\n const summaries = yield* Effect.forEach(selected, (key) =>\n requireRow(key.runId).pipe(\n Effect.flatMap((row) => Effect.map(summaryFrom(row, ancestry), Option.some)),\n Effect.catchTag(\"/control/RunNotFound\", () => Effect.succeed(Option.none<RunSummary>()))\n ))\n return {\n items: summaries.filter(Option.isSome).map((summary) => summary.value),\n ...(keys.length > request.limit ? { nextCursor: selected[selected.length - 1]! } : {})\n }\n }),\n listFlows: Effect.fn(\"SqlControlRuntime.listFlows\")(() =>\n Effect.map(readFlows, (flows) =>\n Array.from(flows.values(), (flow) => ({\n flowId: flow.flowId,\n description: flow.description\n })))\n )(),\n deliverSignal: Effect.fn(\"SqlControlRuntime.deliverSignal\")((runId: RunId, signal: SignalPayload) =>\n // Durable delivery, and deliberately no resumption: a signal records a\n // fact, it does not decide who runs next.\n appendMessage(runId, \"signal\", signal)\n ),\n admitSignal: Effect.fn(\"SqlControlRuntime.admitSignal\")(function*(commandId, runId, signal, principal) {\n yield* requireRow(runId)\n const payloadJson = JSON.stringify(signal)\n const principalJson = principal === undefined ? null : JSON.stringify(principal)\n yield* writer.write(sql`INSERT INTO control_signal_commands (command_id, run_id, payload_json, principal_json)\n VALUES (${commandId}, ${runId}, ${payloadJson}, ${principalJson}) ON CONFLICT(command_id) DO NOTHING`).pipe(\n Effect.mapError(persistence(\"admit signal command\"))\n )\n }),\n signalCommand: Effect.fn(\"SqlControlRuntime.signalCommand\")(function*(commandId) {\n const rows = yield* sql<\n {\n commandId: string\n runId: string\n payloadJson: string\n token: string | null\n state: \"pending\" | \"delivered\" | \"rejected\" | \"terminal\"\n principalJson: string | null\n }\n >`\n SELECT command_id AS \"commandId\", run_id AS \"runId\", payload_json AS \"payloadJson\", wait_token AS token, state,\n principal_json AS \"principalJson\"\n FROM control_signal_commands WHERE command_id = ${commandId}`.pipe(query(\"read signal command\"))\n const row = rows[0]\n if (row === undefined) return undefined\n return {\n commandId: row.commandId,\n runId: row.runId,\n token: row.token,\n state: row.state,\n signal: yield* decodeStoredJson(\"control_signal_commands.payload_json\", SignalPayload, row.payloadJson),\n ...yield* signalPrincipal(row.principalJson)\n }\n }),\n pendingSignals: Effect.gen(function*() {\n const read = (after: number) =>\n sql<\n {\n seq: number\n commandId: string\n runId: string\n payloadJson: string\n token: string | null\n state: \"pending\"\n principalJson: string | null\n }\n >`\n SELECT seq, command_id AS \"commandId\", run_id AS \"runId\", payload_json AS \"payloadJson\", wait_token AS token, state,\n principal_json AS \"principalJson\"\n FROM control_signal_commands WHERE state = 'pending' AND seq > ${after} ORDER BY seq LIMIT 100`.pipe(\n query(\"read pending signals\")\n )\n let rows = yield* read(pendingSignalCursor)\n if (rows.length === 0 && pendingSignalCursor !== 0) rows = yield* read(0)\n pendingSignalCursor = rows.at(-1)?.seq ?? 0\n const decoded = yield* Effect.forEach(\n rows,\n (row) =>\n Effect.all([\n decodeStoredJson(\"control_signal_commands.payload_json\", SignalPayload, row.payloadJson),\n signalPrincipal(row.principalJson)\n ]).pipe(\n Effect.map(([signal, principal]) =>\n Option.some({\n commandId: row.commandId,\n runId: row.runId,\n token: row.token,\n state: row.state,\n signal,\n ...principal\n })\n ),\n Effect.catch((error) =>\n writer.write(\n sql`UPDATE control_signal_commands SET state = 'rejected' WHERE command_id = ${row.commandId} AND state = 'pending'`\n ).pipe(\n Effect.mapError(persistence(\"quarantine malformed signal\")),\n Effect.andThen(\n Effect.logWarning(\"Malformed admitted signal rejected\", { commandId: row.commandId, error })\n ),\n Effect.as(Option.none())\n )\n )\n )\n )\n return decoded.filter(Option.isSome).map((item) => item.value)\n }),\n bindSignal: Effect.fn(\"SqlControlRuntime.bindSignal\")((commandId, token) =>\n writer.write(Effect.gen(function*() {\n yield* sql`UPDATE control_signal_commands SET wait_token = ${token} WHERE command_id = ${commandId} AND wait_token IS NULL AND state = 'pending' AND NOT EXISTS (SELECT 1 FROM control_signal_commands WHERE wait_token = ${token})`\n const rows = yield* sql<\n { token: string | null }\n >`SELECT wait_token AS token FROM control_signal_commands WHERE command_id = ${commandId}`\n if (rows[0] === undefined) {\n return yield* new PersistenceError({\n operation: \"bind signal\",\n message: `No pending signal command ${commandId}`\n })\n }\n return rows[0].token\n })).pipe(Effect.mapError(persistence(\"bind signal\")))\n ),\n settleSignal: Effect.fn(\"SqlControlRuntime.settleSignal\")((commandId, state) =>\n writer.write(\n sql`UPDATE control_signal_commands SET state = ${state} WHERE command_id = ${commandId} AND state = 'pending'`\n ).pipe(Effect.asVoid, Effect.mapError(persistence(\"settle signal\")))\n ),\n deliveredSignals: Effect.fn(\"SqlControlRuntime.deliveredSignals\")(function*(runId: RunId) {\n yield* requireRow(runId)\n const legacy = yield* messages(runId, \"signal\", SignalPayload)\n const rows = yield* sql<\n { payloadJson: string }\n >`SELECT payload_json AS \"payloadJson\" FROM control_signal_commands WHERE run_id = ${runId} AND state != 'rejected' ORDER BY seq`\n .pipe(query(\"read admitted signals\"))\n return [\n ...legacy,\n ...yield* Effect.forEach(\n rows,\n (row) => decodeStoredJson(\"control_signal_commands.payload_json\", SignalPayload, row.payloadJson)\n )\n ]\n }),\n requestResume: Effect.fn(\"SqlControlRuntime.requestResume\")(function*(\n runId: RunId,\n options?: { readonly consent?: number | undefined } | undefined\n ) {\n const summary = yield* summaryOf(yield* requireRow(runId))\n // A settled run has no host left to take the delegation up: recording\n // one anyway leaves an orphaned row that `pendingResumes` filters out\n // of every poll but nothing ever clears.\n if (terminal(summary.status)) {\n return yield* new InvalidInput({\n issue: `run ${runId} is ${summary.status} and cannot take a resume`\n })\n }\n const sequence = yield* nextSequence(\"resume\")\n const timestamp = yield* now\n const consent = options?.consent ?? null\n // A delegation that arrives before the host took up an operator's\n // resume keeps that consent; only a newer explicit resume replaces it.\n yield* writer.write(sql`\n INSERT INTO control_run_resumes (run_id, requested_seq, requested_at_ms, consent_seq)\n VALUES (${runId}, ${sequence}, ${timestamp}, ${consent})\n ON CONFLICT (run_id) DO UPDATE SET\n requested_seq = excluded.requested_seq,\n requested_at_ms = excluded.requested_at_ms,\n consent_seq = COALESCE(excluded.consent_seq, control_run_resumes.consent_seq)\n `).pipe(Effect.mapError(persistence(\"record a resume delegation\")))\n return sequence\n }),\n // Terminal runs are filtered in SQL: a delegation nobody will ever take\n // up must not keep appearing in every host's poll.\n pendingResumes: sql<\n {\n readonly runId: string\n readonly requestedSeq: number\n readonly requestedAtMs: number\n readonly consentSeq: number | null\n }\n >`\n SELECT resumes.run_id AS \"runId\",\n resumes.requested_seq AS \"requestedSeq\",\n resumes.requested_at_ms AS \"requestedAtMs\",\n resumes.consent_seq AS \"consentSeq\"\n FROM control_run_resumes AS resumes\n JOIN flows_runs AS runs ON runs.run_id = resumes.run_id\n WHERE runs.status NOT IN ('completed', 'failed', 'cancelled')\n ORDER BY resumes.requested_seq\n `.pipe(\n query(\"read pending resumes\"),\n Effect.map((rows) =>\n rows.map((row) => ({\n runId: row.runId,\n sequence: Number(row.requestedSeq),\n requestedAtMs: Number(row.requestedAtMs),\n ...(row.consentSeq === null ? {} : { consent: Number(row.consentSeq) })\n }))\n )\n ),\n clearResume: Effect.fn(\"SqlControlRuntime.clearResume\")((runId: RunId, sequence: number) =>\n writer.write(sql`\n DELETE FROM control_run_resumes WHERE run_id = ${runId} AND requested_seq = ${sequence}\n `).pipe(Effect.mapError(persistence(\"clear a resume delegation\")), Effect.asVoid)\n ),\n registerFiber: Effect.fn(\"SqlControlRuntime.registerFiber\")(function*(\n runId: RunId,\n fiber: Fiber.Fiber<unknown, unknown>\n ) {\n yield* requireRow(runId)\n ActiveFibers.register(fibers, runId, fiber)\n }),\n interrupt: Effect.fn(\"SqlControlRuntime.interrupt\")(function*(runId: RunId, settle = (effect) => effect) {\n const row = yield* requireRow(runId)\n const summary = yield* summaryOf(row)\n // Terminality is asked FIRST, as `resume` asks it. A settled run has\n // released its owner, so `ownedByUs` is false for every process\n // including the one that ran it, and asking ownership first answered\n // `ClaimLost` \u2014 \"somebody else has it\" \u2014 for a run that had simply\n // finished. Its caller has a `Terminal` receipt for exactly this.\n if (terminal(summary.status)) return summary\n if (!ownedByUs(row)) return yield* new ClaimLost({ runId })\n const fiber = fibers.get(runId)\n // Cancellation is fiber interruption, not a flag anyone polls.\n if (fiber !== undefined) yield* Fiber.interrupt(fiber)\n if (fibers.get(runId) === fiber) fibers.delete(runId)\n // Only reconciliation holds the writer. Re-read after finalizers and\n // retain the original fence so cleanup cannot transfer this cancel to\n // a replacement owner or overwrite a terminal outcome.\n return yield* settle(\n writer.write(Effect.gen(function*() {\n const current = yield* summaryOf(yield* requireRow(runId))\n if (terminal(current.status)) return current\n return yield* transition(runId, row.owner, current, \"cancelled\")\n })).pipe(\n Effect.catchTag(\n \"@smthrs/database/DatabaseError\",\n (error) => Effect.fail(persistence(\"settle an interrupted run\")(error))\n )\n )\n )\n }),\n codeDrift: Effect.fn(\"SqlControlRuntime.codeDrift\")(function*(runId: RunId) {\n const summary = yield* recordedCode(yield* requireRow(runId))\n const current = (yield* readCurrentFlows).get(summary.flowId)\n const pinned = summary.executionDigest === undefined || options.pinnedFlow === undefined\n ? undefined :\n yield* options.pinnedFlow(summary.flowId, summary.executionDigest)\n return codeDriftOf(\n summary,\n pinned === true ?\n { executionDigest: summary.executionDigest }\n : pinned === false\n ? undefined\n : current,\n options.engineVersion\n )\n }),\n recordedCode: Effect.fn(\"SqlControlRuntime.recordedCode\")(function*(runId: RunId) {\n const { executionDigest, engineVersion } = yield* recordedCode(yield* requireRow(runId))\n return { executionDigest, engineVersion }\n }),\n resume: Effect.fn(\"SqlControlRuntime.resume\")((\n runId: RunId,\n resumeOptions?: { readonly scope?: \"launched\" | \"any\" | undefined } | undefined\n ) => resumeRun(runId, resumeOptions?.scope)),\n resumeAdopting: Effect.fn(\"SqlControlRuntime.resumeAdopting\")((\n runId: RunId,\n resumeOptions?: { readonly scope?: \"launched\" | \"any\" | undefined } | undefined\n ) => resumeRun(runId, resumeOptions?.scope, adoptable)),\n claimFence: Effect.fn(\"SqlControlRuntime.claimFence\")(function*(runId: RunId) {\n const row = yield* requireRow(runId)\n if (!ownedByUs(row)) return yield* new ClaimLost({ runId })\n return JSON.stringify(row.owner)\n }),\n releasePending: Effect.fn(\"SqlControlRuntime.releasePending\")(function*(runId: RunId, fence: string) {\n const row = yield* requireRow(runId)\n const presented = yield* decodeStoredJson(\"control fence\", Ownership.OwnerId, fence).pipe(\n Effect.mapError(() => new ClaimLost({ runId }))\n )\n const timestamp = yield* now\n const next: RunSummary = {\n ...yield* summaryOf(row),\n status: \"accepted\",\n ownerId: undefined,\n parkedBy: undefined,\n updatedAt: timestamp\n }\n const outcome = yield* runStore.transitionOwned(\n runId,\n presented,\n \"suspended\",\n JSON.stringify(next)\n ).pipe(Effect.mapError(persistence(\"release a pending run\")))\n if (outcome._tag === \"NotFound\") return yield* new RunNotFound({ runId })\n if (outcome._tag !== \"Transitioned\") return yield* new ClaimLost({ runId })\n return next\n }),\n writeStatus: Effect.fn(\"SqlControlRuntime.writeStatus\")(function*(\n runId: RunId,\n fence: string,\n status: RunStatus\n ) {\n const row = yield* requireRow(runId)\n const presented = yield* decodeStoredJson(\"control fence\", Ownership.OwnerId, fence).pipe(\n Effect.mapError(() => new ClaimLost({ runId }))\n )\n return yield* transition(runId, presented, yield* summaryOf(row), status)\n }),\n /**\n * The submitted identity wins, and only the clock is the runtime's.\n *\n * `Control.RunMutationInput` states the order: the runtime \"supplies its\n * own principal when the caller names none\". The submitted one is the\n * identity the server authenticated at its boundary, so a composition\n * default that overrode it would rename every remote operator to\n * whatever this process was built with.\n */\n stampPrincipal: Effect.fn(\"SqlControlRuntime.stampPrincipal\")(function*(submitted?: Principal | undefined) {\n const timestamp = yield* now\n return {\n id: submitted?.id ?? options.principal?.id ?? \"local\",\n kind: submitted?.kind ?? options.principal?.kind ?? \"operator\",\n stampedAt: timestamp\n }\n }),\n lookupMutation: Effect.fn(\"SqlControlRuntime.lookupMutation\")(function*(\n key: IdempotencyKey,\n fingerprint: string\n ) {\n const rows = yield* sql<{ readonly fingerprint: string; readonly receiptJson: string }>`\n SELECT fingerprint, receipt_json AS \"receiptJson\" FROM control_mutations WHERE mutation_key = ${key}\n `.pipe(query(\"read a mutation\"))\n const row = rows[0]\n if (row === undefined) return undefined\n if (row.fingerprint !== fingerprint) {\n return { _tag: \"Conflict\" as const, message: `idempotency key ${key} was used for another mutation` }\n }\n const receipt = yield* decodeStoredJson(\"control_mutations.receipt_json\", Receipt, row.receiptJson)\n return alreadyApplied(key, receipt)\n }),\n recordMutation: Effect.fn(\"SqlControlRuntime.recordMutation\")((\n key: IdempotencyKey,\n fingerprint: string,\n receipt: Receipt\n ) =>\n writer.write(Effect.gen(function*() {\n yield* sql`\n INSERT INTO control_mutations (mutation_key, fingerprint, receipt_json)\n VALUES (${key}, ${fingerprint}, ${JSON.stringify(receipt)})\n ON CONFLICT (mutation_key) DO NOTHING\n `\n const rows = yield* sql<{ readonly fingerprint: string; readonly receiptJson: string }>`\n SELECT fingerprint, receipt_json AS \"receiptJson\"\n FROM control_mutations WHERE mutation_key = ${key}\n `\n const stored = rows[0]\n if (\n stored === undefined || stored.fingerprint !== fingerprint || stored.receiptJson !== JSON.stringify(receipt)\n ) {\n return yield* Effect.fail(\n new PersistenceError({\n operation: \"record a mutation\",\n message: `Idempotency key ${key} was already settled by another mutation`\n })\n )\n }\n })).pipe(\n Effect.asVoid,\n Effect.mapError((cause) =>\n cause instanceof PersistenceError ? cause : persistence(\"record a mutation\")(cause)\n )\n )\n ),\n claimRunKey: Effect.fn(\"SqlControlRuntime.claimRunKey\")((\n key: IdempotencyKey,\n fingerprint: string\n ) => {\n const claimant = randomId()\n return writer.write(Effect.gen(function*() {\n yield* sql`\n INSERT INTO control_run_keys (idempotency_key, fingerprint, claimant)\n VALUES (${key}, ${fingerprint}, ${claimant})\n ON CONFLICT (idempotency_key) DO NOTHING\n `\n const holders = yield* sql<{\n readonly fingerprint: string\n readonly claimant: string\n }>`\n SELECT fingerprint, claimant FROM control_run_keys\n WHERE idempotency_key = ${key}\n `\n const holder = holders[0]\n if (holder === undefined) {\n return yield* new PersistenceError({\n operation: \"claim a run key\",\n message: `Run key ${key} disappeared while it was being claimed`\n })\n }\n if (holder.fingerprint !== fingerprint) {\n return yield* new InvalidInput({\n issue: `idempotency key ${key} was used for another run`\n })\n }\n if (holder.claimant === claimant) return { _tag: \"Claimed\" as const }\n\n // Serialized writers make the winner's key and receipt visible in\n // one commit. Seeing its key without its receipt is therefore\n // corruption (or a claim written by an older, non-atomic build), not\n // permission to launch a second run.\n const rows = yield* sql<{ readonly fingerprint: string; readonly receiptJson: string }>`\n SELECT fingerprint, receipt_json AS \"receiptJson\"\n FROM control_mutations WHERE mutation_key = ${key}\n `\n const record = rows[0]\n if (record === undefined || record.fingerprint !== fingerprint) {\n return yield* new PersistenceError({\n operation: \"claim a run key\",\n message: `Run key ${key} has no matching settled receipt`\n })\n }\n const receipt = yield* decodeStoredJson(\"control_mutations.receipt_json\", Receipt, record.receiptJson)\n return { _tag: \"Raced\" as const, receipt }\n })).pipe(\n Effect.mapError((cause) =>\n cause instanceof InvalidInput || cause instanceof PersistenceError\n ? cause\n : persistence(\"claim a run key\")(cause)\n )\n )\n }),\n releaseRunKey: Effect.fn(\"SqlControlRuntime.releaseRunKey\")((key: IdempotencyKey) =>\n writer.write(sql`\n DELETE FROM control_run_keys WHERE idempotency_key = ${key}\n `).pipe(\n Effect.asVoid,\n Effect.mapError(persistence(\"release a run key\"))\n )\n ),\n grants: Effect.fn(\"SqlControlRuntime.grants\")(() =>\n sql<{\n readonly tokenId: string\n readonly envelopeJson: string\n readonly scope: string\n readonly installedAtMs: number\n }>`\n SELECT token_id AS \"tokenId\", envelope_json AS \"envelopeJson\",\n scope, installed_at_ms AS \"installedAtMs\"\n FROM control_grants ORDER BY installed_at_ms, target_tag, run_id, target_id\n `.pipe(\n query(\"list grants\"),\n Effect.flatMap((rows) =>\n Effect.forEach(rows, (row): Effect.Effect<BulkGrant, PersistenceError> =>\n Effect.all({\n envelope: decodeStoredJson(\"control_grants.envelope_json\", Envelope, row.envelopeJson),\n scope: decodeStoredValue(\"control_grants.scope\", GrantScope, row.scope)\n }).pipe(\n Effect.map(({ envelope, scope }) => ({\n tokenId: row.tokenId,\n envelope,\n scope,\n installedAt: Number(row.installedAtMs)\n }))\n ))\n )\n )\n )()\n })\n return service\n })\n}\n\n/**\n * Provides a durable runtime over the ambient database and run store.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer = (\n options: Options = {}\n): Layer.Layer<\n ControlRuntime,\n PersistenceError,\n Crypto.Crypto | DurableWriter | SqlClient.SqlClient | RunStore.RunStore\n> => Layer.effect(ControlRuntime)(makeRuntime(options))\n\n/**\n * Provides a durable runtime and the run store it needs over the ambient\n * database.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layerWithStore = (\n options: Options = {}\n): Layer.Layer<\n ControlRuntime,\n PersistenceError,\n Crypto.Crypto | DurableWriter | SqlClient.SqlClient\n> => layer(options).pipe(Layer.provideMerge(RunStore.layer))\n\n/**\n * Constructs a durable runtime over the ambient database and run store.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport { makeRuntime as make }\n"],
5
+ "mappings": "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",
6
+ "names": ["spawnedBy", "claim", "decoded", "options"]
7
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Durable credential persistence over `@smthrs/database`.
3
+ *
4
+ * This is the host adapter behind {@link CredentialStore} on any runtime with
5
+ * a SQL database — the Node composition uses `@smthrs/database/node`, and
6
+ * tests use its in-memory SQLite driver. The module itself imports no `node:*`
7
+ * API: it speaks the driver-neutral SQL contract, so it stays bundleable and a
8
+ * browser host that ships a SQL driver can use it unchanged.
9
+ *
10
+ * Only ciphertext is stored. The row carries no key material, and the
11
+ * compare-and-set on `version` is what makes two concurrent rotations
12
+ * serializable: the loser is refused with `CredentialConflict` instead of
13
+ * clobbering the winner.
14
+ *
15
+ * @since 0.1.0
16
+ */
17
+ import { DurableWriter } from "@smthrs/database/DurableWriter";
18
+ import { Effect, Layer } from "effect";
19
+ import * as SqlClient from "effect/unstable/sql/SqlClient";
20
+ import { Unavailable } from "./ControlError.ts";
21
+ import * as CredentialStore from "./CredentialStore.ts";
22
+ /**
23
+ * Creates the credential table if it does not exist.
24
+ *
25
+ * @category migrations
26
+ * @since 0.1.0
27
+ */
28
+ export declare const migrate: Effect.Effect<void, Unavailable, SqlClient.SqlClient>;
29
+ /**
30
+ * Constructs a durable credential store over the ambient database.
31
+ *
32
+ * @category constructors
33
+ * @since 0.1.0
34
+ */
35
+ export declare const make: Effect.Effect<CredentialStore.Service, Unavailable, DurableWriter | SqlClient.SqlClient>;
36
+ /**
37
+ * Provides durable credential persistence over the ambient database.
38
+ *
39
+ * @category layers
40
+ * @since 0.1.0
41
+ */
42
+ export declare const layer: Layer.Layer<CredentialStore.CredentialStore, Unavailable, DurableWriter | SqlClient.SqlClient>;
43
+ //# sourceMappingURL=SqlCredentialStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlCredentialStore.d.ts","sourceRoot":"","sources":["../../src/SqlCredentialStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAA;AAC9C,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAC1D,OAAO,EAAsB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AA2BvD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,SAAS,CAEzE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAC9B,eAAe,CAAC,OAAO,EACvB,WAAW,EACX,aAAa,GAAG,SAAS,CAAC,SAAS,CAoEnC,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAC7B,eAAe,CAAC,eAAe,EAC/B,WAAW,EACX,aAAa,GAAG,SAAS,CAAC,SAAS,CACkB,CAAA"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var SqlCredentialStore_exports = {};
30
+ __export(SqlCredentialStore_exports, {
31
+ layer: () => layer,
32
+ make: () => make,
33
+ migrate: () => migrate
34
+ });
35
+ module.exports = __toCommonJS(SqlCredentialStore_exports);
36
+ var import_DurableWriter = require("@smthrs/database/DurableWriter");
37
+ var import_effect = require("effect");
38
+ var SqlClient = __toESM(require("effect/unstable/sql/SqlClient"), 1);
39
+ var import_ControlError = require("./ControlError.js");
40
+ var CredentialStore = __toESM(require("./CredentialStore.js"), 1);
41
+ var import_control_tables = require("./migrations/0001_control_tables.js");
42
+ const toRecord = (row) => ({
43
+ id: row.id,
44
+ name: row.name,
45
+ ciphertext: row.ciphertext,
46
+ nonce: row.nonce,
47
+ version: Number(row.version),
48
+ updatedAtMs: Number(row.updated_at_ms)
49
+ });
50
+ const unavailable = (operation) => () => new import_ControlError.Unavailable({
51
+ feature: `credential storage (${operation})`,
52
+ ticket: "control-credential-storage"
53
+ });
54
+ const migrate = import_control_tables.initial.pipe(
55
+ import_effect.Effect.mapError(unavailable("migrate"))
56
+ );
57
+ const make = import_effect.Effect.gen(function* () {
58
+ const sql = yield* import_effect.Effect.service(SqlClient.SqlClient);
59
+ const writer = yield* import_DurableWriter.DurableWriter;
60
+ yield* migrate;
61
+ const list = () => sql`SELECT * FROM control_credentials ORDER BY name`.pipe(
62
+ import_effect.Effect.map((rows) => rows.map(toRecord)),
63
+ import_effect.Effect.mapError(unavailable("list"))
64
+ );
65
+ const read = (id) => sql`SELECT * FROM control_credentials WHERE id = ${id}`.pipe(
66
+ import_effect.Effect.map((rows) => import_effect.Option.map(import_effect.Option.fromNullishOr(rows[0]), toRecord)),
67
+ import_effect.Effect.mapError(unavailable("read"))
68
+ );
69
+ const write = (record) => writer.write(import_effect.Effect.gen(function* () {
70
+ const rows = yield* sql`
71
+ SELECT version FROM control_credentials WHERE id = ${record.id}
72
+ `;
73
+ const stored = rows[0];
74
+ const actual = stored === void 0 ? 0 : Number(stored.version);
75
+ if (actual !== record.version - 1) {
76
+ return yield* import_effect.Effect.fail(
77
+ new import_ControlError.CredentialConflict({
78
+ id: record.id,
79
+ expectedVersion: record.version - 1,
80
+ actualVersion: actual
81
+ })
82
+ );
83
+ }
84
+ yield* sql`
85
+ INSERT INTO control_credentials (id, name, ciphertext, nonce, version, updated_at_ms)
86
+ VALUES (
87
+ ${record.id},
88
+ ${record.name},
89
+ ${record.ciphertext},
90
+ ${record.nonce},
91
+ ${record.version},
92
+ ${record.updatedAtMs}
93
+ )
94
+ ON CONFLICT (id) DO UPDATE SET
95
+ name = excluded.name,
96
+ ciphertext = excluded.ciphertext,
97
+ nonce = excluded.nonce,
98
+ version = excluded.version,
99
+ updated_at_ms = excluded.updated_at_ms
100
+ `;
101
+ })).pipe(
102
+ import_effect.Effect.mapError(
103
+ (cause) => cause instanceof import_ControlError.CredentialConflict ? cause : unavailable("write")()
104
+ )
105
+ );
106
+ const remove = (id) => sql`DELETE FROM control_credentials WHERE id = ${id}`.pipe(
107
+ import_effect.Effect.asVoid,
108
+ import_effect.Effect.mapError(unavailable("remove"))
109
+ );
110
+ return CredentialStore.make({ list, read, write, remove });
111
+ });
112
+ const layer = import_effect.Layer.effect(CredentialStore.CredentialStore)(make);
113
+ //# sourceMappingURL=SqlCredentialStore.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/SqlCredentialStore.ts"],
4
+ "sourcesContent": ["/**\n * Durable credential persistence over `@smthrs/database`.\n *\n * This is the host adapter behind {@link CredentialStore} on any runtime with\n * a SQL database \u2014 the Node composition uses `@smthrs/database/node`, and\n * tests use its in-memory SQLite driver. The module itself imports no `node:*`\n * API: it speaks the driver-neutral SQL contract, so it stays bundleable and a\n * browser host that ships a SQL driver can use it unchanged.\n *\n * Only ciphertext is stored. The row carries no key material, and the\n * compare-and-set on `version` is what makes two concurrent rotations\n * serializable: the loser is refused with `CredentialConflict` instead of\n * clobbering the winner.\n *\n * @since 0.1.0\n */\n\nimport { DurableWriter } from \"@smthrs/database/DurableWriter\"\nimport { Effect, Layer, Option } from \"effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\nimport { CredentialConflict, Unavailable } from \"./ControlError.ts\"\nimport * as CredentialStore from \"./CredentialStore.ts\"\nimport { initial } from \"./migrations/0001_control_tables.ts\"\n\ninterface Row {\n readonly id: string\n readonly name: string\n readonly ciphertext: string\n readonly nonce: string\n readonly version: number\n readonly updated_at_ms: number\n}\n\nconst toRecord = (row: Row): CredentialStore.SealedRecord => ({\n id: row.id,\n name: row.name,\n ciphertext: row.ciphertext,\n nonce: row.nonce,\n version: Number(row.version),\n updatedAtMs: Number(row.updated_at_ms)\n})\n\nconst unavailable = (operation: string) => (): Unavailable =>\n new Unavailable({\n feature: `credential storage (${operation})`,\n ticket: \"control-credential-storage\"\n })\n\n/**\n * Creates the credential table if it does not exist.\n *\n * @category migrations\n * @since 0.1.0\n */\nexport const migrate: Effect.Effect<void, Unavailable, SqlClient.SqlClient> = initial.pipe(\n Effect.mapError(unavailable(\"migrate\"))\n)\n\n/**\n * Constructs a durable credential store over the ambient database.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make: Effect.Effect<\n CredentialStore.Service,\n Unavailable,\n DurableWriter | SqlClient.SqlClient\n> = Effect.gen(function*() {\n const sql = yield* Effect.service(SqlClient.SqlClient)\n const writer = yield* DurableWriter\n yield* migrate\n\n const list = (): Effect.Effect<ReadonlyArray<CredentialStore.SealedRecord>, Unavailable> =>\n sql<Row>`SELECT * FROM control_credentials ORDER BY name`.pipe(\n Effect.map((rows) => rows.map(toRecord)),\n Effect.mapError(unavailable(\"list\"))\n )\n\n const read = (id: string): Effect.Effect<Option.Option<CredentialStore.SealedRecord>, Unavailable> =>\n sql<Row>`SELECT * FROM control_credentials WHERE id = ${id}`.pipe(\n Effect.map((rows) => Option.map(Option.fromNullishOr(rows[0]), toRecord)),\n Effect.mapError(unavailable(\"read\"))\n )\n\n // One write transaction, so the version this writer read and the row it\n // guards cannot interleave with a concurrent rotation.\n const write = (\n record: CredentialStore.SealedRecord\n ): Effect.Effect<void, Unavailable | CredentialConflict> =>\n writer.write(Effect.gen(function*() {\n const rows = yield* sql<{ readonly version: number }>`\n SELECT version FROM control_credentials WHERE id = ${record.id}\n `\n const stored = rows[0]\n const actual = stored === undefined ? 0 : Number(stored.version)\n if (actual !== record.version - 1) {\n return yield* Effect.fail(\n new CredentialConflict({\n id: record.id,\n expectedVersion: record.version - 1,\n actualVersion: actual\n })\n )\n }\n yield* sql`\n INSERT INTO control_credentials (id, name, ciphertext, nonce, version, updated_at_ms)\n VALUES (\n ${record.id},\n ${record.name},\n ${record.ciphertext},\n ${record.nonce},\n ${record.version},\n ${record.updatedAtMs}\n )\n ON CONFLICT (id) DO UPDATE SET\n name = excluded.name,\n ciphertext = excluded.ciphertext,\n nonce = excluded.nonce,\n version = excluded.version,\n updated_at_ms = excluded.updated_at_ms\n `\n })).pipe(\n Effect.mapError((cause): Unavailable | CredentialConflict =>\n cause instanceof CredentialConflict ? cause : unavailable(\"write\")()\n )\n )\n\n const remove = (id: string): Effect.Effect<void, Unavailable> =>\n sql`DELETE FROM control_credentials WHERE id = ${id}`.pipe(\n Effect.asVoid,\n Effect.mapError(unavailable(\"remove\"))\n )\n\n return CredentialStore.make({ list, read, write, remove })\n})\n\n/**\n * Provides durable credential persistence over the ambient database.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer: Layer.Layer<\n CredentialStore.CredentialStore,\n Unavailable,\n DurableWriter | SqlClient.SqlClient\n> = Layer.effect(CredentialStore.CredentialStore)(make)\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,2BAA8B;AAC9B,oBAAsC;AACtC,gBAA2B;AAC3B,0BAAgD;AAChD,sBAAiC;AACjC,4BAAwB;AAWxB,MAAM,WAAW,CAAC,SAA4C;AAAA,EAC5D,IAAI,IAAI;AAAA,EACR,MAAM,IAAI;AAAA,EACV,YAAY,IAAI;AAAA,EAChB,OAAO,IAAI;AAAA,EACX,SAAS,OAAO,IAAI,OAAO;AAAA,EAC3B,aAAa,OAAO,IAAI,aAAa;AACvC;AAEA,MAAM,cAAc,CAAC,cAAsB,MACzC,IAAI,gCAAY;AAAA,EACd,SAAS,uBAAuB,SAAS;AAAA,EACzC,QAAQ;AACV,CAAC;AAQI,MAAM,UAAiE,8BAAQ;AAAA,EACpF,qBAAO,SAAS,YAAY,SAAS,CAAC;AACxC;AAQO,MAAM,OAIT,qBAAO,IAAI,aAAY;AACzB,QAAM,MAAM,OAAO,qBAAO,QAAQ,UAAU,SAAS;AACrD,QAAM,SAAS,OAAO;AACtB,SAAO;AAEP,QAAM,OAAO,MACX,qDAA0D;AAAA,IACxD,qBAAO,IAAI,CAAC,SAAS,KAAK,IAAI,QAAQ,CAAC;AAAA,IACvC,qBAAO,SAAS,YAAY,MAAM,CAAC;AAAA,EACrC;AAEF,QAAM,OAAO,CAAC,OACZ,mDAAwD,EAAE,GAAG;AAAA,IAC3D,qBAAO,IAAI,CAAC,SAAS,qBAAO,IAAI,qBAAO,cAAc,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC;AAAA,IACxE,qBAAO,SAAS,YAAY,MAAM,CAAC;AAAA,EACrC;AAIF,QAAM,QAAQ,CACZ,WAEA,OAAO,MAAM,qBAAO,IAAI,aAAY;AAClC,UAAM,OAAO,OAAO;AAAA,6DACmC,OAAO,EAAE;AAAA;AAEhE,UAAM,SAAS,KAAK,CAAC;AACrB,UAAM,SAAS,WAAW,SAAY,IAAI,OAAO,OAAO,OAAO;AAC/D,QAAI,WAAW,OAAO,UAAU,GAAG;AACjC,aAAO,OAAO,qBAAO;AAAA,QACnB,IAAI,uCAAmB;AAAA,UACrB,IAAI,OAAO;AAAA,UACX,iBAAiB,OAAO,UAAU;AAAA,UAClC,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA;AAAA;AAAA,YAGD,OAAO,EAAE;AAAA,YACT,OAAO,IAAI;AAAA,YACX,OAAO,UAAU;AAAA,YACjB,OAAO,KAAK;AAAA,YACZ,OAAO,OAAO;AAAA,YACd,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1B,CAAC,CAAC,EAAE;AAAA,IACF,qBAAO;AAAA,MAAS,CAAC,UACf,iBAAiB,yCAAqB,QAAQ,YAAY,OAAO,EAAE;AAAA,IACrE;AAAA,EACF;AAEF,QAAM,SAAS,CAAC,OACd,iDAAiD,EAAE,GAAG;AAAA,IACpD,qBAAO;AAAA,IACP,qBAAO,SAAS,YAAY,QAAQ,CAAC;AAAA,EACvC;AAEF,SAAO,gBAAgB,KAAK,EAAE,MAAM,MAAM,OAAO,OAAO,CAAC;AAC3D,CAAC;AAQM,MAAM,QAIT,oBAAM,OAAO,gBAAgB,eAAe,EAAE,IAAI;",
6
+ "names": []
7
+ }