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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/LICENSE +21 -0
  3. package/README.md +168 -2
  4. package/dist/cjs/ApprovalAuthority.d.ts +73 -0
  5. package/dist/cjs/ApprovalAuthority.d.ts.map +1 -0
  6. package/dist/cjs/ApprovalAuthority.js +62 -0
  7. package/dist/cjs/ApprovalAuthority.js.map +7 -0
  8. package/dist/cjs/Cancellation.d.ts +107 -0
  9. package/dist/cjs/Cancellation.d.ts.map +1 -0
  10. package/dist/cjs/Cancellation.js +72 -0
  11. package/dist/cjs/Cancellation.js.map +7 -0
  12. package/dist/cjs/Channels.d.ts +170 -0
  13. package/dist/cjs/Channels.d.ts.map +1 -0
  14. package/dist/cjs/Channels.js +278 -0
  15. package/dist/cjs/Channels.js.map +7 -0
  16. package/dist/cjs/Control.d.ts +202 -0
  17. package/dist/cjs/Control.d.ts.map +1 -0
  18. package/dist/cjs/Control.js +47 -0
  19. package/dist/cjs/Control.js.map +7 -0
  20. package/dist/cjs/ControlClient.d.ts +52 -0
  21. package/dist/cjs/ControlClient.d.ts.map +1 -0
  22. package/dist/cjs/ControlClient.js +191 -0
  23. package/dist/cjs/ControlClient.js.map +7 -0
  24. package/dist/cjs/ControlError.d.ts +318 -0
  25. package/dist/cjs/ControlError.d.ts.map +1 -0
  26. package/dist/cjs/ControlError.js +249 -0
  27. package/dist/cjs/ControlError.js.map +7 -0
  28. package/dist/cjs/ControlExecutor.d.ts +372 -0
  29. package/dist/cjs/ControlExecutor.d.ts.map +1 -0
  30. package/dist/cjs/ControlExecutor.js +123 -0
  31. package/dist/cjs/ControlExecutor.js.map +7 -0
  32. package/dist/cjs/ControlFacts.d.ts +454 -0
  33. package/dist/cjs/ControlFacts.d.ts.map +1 -0
  34. package/dist/cjs/ControlFacts.js +261 -0
  35. package/dist/cjs/ControlFacts.js.map +7 -0
  36. package/dist/cjs/ControlLive.d.ts +23 -0
  37. package/dist/cjs/ControlLive.d.ts.map +1 -0
  38. package/dist/cjs/ControlLive.js +1280 -0
  39. package/dist/cjs/ControlLive.js.map +7 -0
  40. package/dist/cjs/ControlRpcs.d.ts +1204 -0
  41. package/dist/cjs/ControlRpcs.d.ts.map +1 -0
  42. package/dist/cjs/ControlRpcs.js +247 -0
  43. package/dist/cjs/ControlRpcs.js.map +7 -0
  44. package/dist/cjs/ControlRuntime.d.ts +635 -0
  45. package/dist/cjs/ControlRuntime.d.ts.map +1 -0
  46. package/dist/cjs/ControlRuntime.js +740 -0
  47. package/dist/cjs/ControlRuntime.js.map +7 -0
  48. package/dist/cjs/ControlSchema.d.ts +2642 -0
  49. package/dist/cjs/ControlSchema.d.ts.map +1 -0
  50. package/dist/cjs/ControlSchema.js +634 -0
  51. package/dist/cjs/ControlSchema.js.map +7 -0
  52. package/dist/cjs/ControlServer.d.ts +51 -0
  53. package/dist/cjs/ControlServer.d.ts.map +1 -0
  54. package/dist/cjs/ControlServer.js +121 -0
  55. package/dist/cjs/ControlServer.js.map +7 -0
  56. package/dist/cjs/Credential.d.ts +136 -0
  57. package/dist/cjs/Credential.d.ts.map +1 -0
  58. package/dist/cjs/Credential.js +168 -0
  59. package/dist/cjs/Credential.js.map +7 -0
  60. package/dist/cjs/CredentialCipher.d.ts +90 -0
  61. package/dist/cjs/CredentialCipher.d.ts.map +1 -0
  62. package/dist/cjs/CredentialCipher.js +45 -0
  63. package/dist/cjs/CredentialCipher.js.map +7 -0
  64. package/dist/cjs/CredentialStore.d.ts +97 -0
  65. package/dist/cjs/CredentialStore.d.ts.map +1 -0
  66. package/dist/cjs/CredentialStore.js +81 -0
  67. package/dist/cjs/CredentialStore.js.map +7 -0
  68. package/dist/cjs/DispatchReader.d.ts +112 -0
  69. package/dist/cjs/DispatchReader.d.ts.map +1 -0
  70. package/dist/cjs/DispatchReader.js +45 -0
  71. package/dist/cjs/DispatchReader.js.map +7 -0
  72. package/dist/cjs/Health.d.ts +333 -0
  73. package/dist/cjs/Health.d.ts.map +1 -0
  74. package/dist/cjs/Health.js +311 -0
  75. package/dist/cjs/Health.js.map +7 -0
  76. package/dist/cjs/JevSessionChecker.d.ts +57 -0
  77. package/dist/cjs/JevSessionChecker.d.ts.map +1 -0
  78. package/dist/cjs/JevSessionChecker.js +113 -0
  79. package/dist/cjs/JevSessionChecker.js.map +7 -0
  80. package/dist/cjs/Lineage.d.ts +131 -0
  81. package/dist/cjs/Lineage.d.ts.map +1 -0
  82. package/dist/cjs/Lineage.js +81 -0
  83. package/dist/cjs/Lineage.js.map +7 -0
  84. package/dist/cjs/Migrations.d.ts +34 -0
  85. package/dist/cjs/Migrations.d.ts.map +1 -0
  86. package/dist/cjs/Migrations.js +60 -0
  87. package/dist/cjs/Migrations.js.map +7 -0
  88. package/dist/cjs/Monitor.d.ts +282 -0
  89. package/dist/cjs/Monitor.d.ts.map +1 -0
  90. package/dist/cjs/Monitor.js +283 -0
  91. package/dist/cjs/Monitor.js.map +7 -0
  92. package/dist/cjs/ScopedToken.d.ts +193 -0
  93. package/dist/cjs/ScopedToken.d.ts.map +1 -0
  94. package/dist/cjs/ScopedToken.js +135 -0
  95. package/dist/cjs/ScopedToken.js.map +7 -0
  96. package/dist/cjs/SqlControlRuntime.d.ts +161 -0
  97. package/dist/cjs/SqlControlRuntime.d.ts.map +1 -0
  98. package/dist/cjs/SqlControlRuntime.js +1521 -0
  99. package/dist/cjs/SqlControlRuntime.js.map +7 -0
  100. package/dist/cjs/SqlCredentialStore.d.ts +43 -0
  101. package/dist/cjs/SqlCredentialStore.d.ts.map +1 -0
  102. package/dist/cjs/SqlCredentialStore.js +113 -0
  103. package/dist/cjs/SqlCredentialStore.js.map +7 -0
  104. package/dist/cjs/Steering.d.ts +69 -0
  105. package/dist/cjs/Steering.d.ts.map +1 -0
  106. package/dist/cjs/Steering.js +49 -0
  107. package/dist/cjs/Steering.js.map +7 -0
  108. package/dist/cjs/SystemFlows.d.ts +223 -0
  109. package/dist/cjs/SystemFlows.d.ts.map +1 -0
  110. package/dist/cjs/SystemFlows.js +195 -0
  111. package/dist/cjs/SystemFlows.js.map +7 -0
  112. package/dist/cjs/WebCryptoCipher.d.ts +49 -0
  113. package/dist/cjs/WebCryptoCipher.d.ts.map +1 -0
  114. package/dist/cjs/WebCryptoCipher.js +129 -0
  115. package/dist/cjs/WebCryptoCipher.js.map +7 -0
  116. package/dist/cjs/WebhookChannel.d.ts +113 -0
  117. package/dist/cjs/WebhookChannel.d.ts.map +1 -0
  118. package/dist/cjs/WebhookChannel.js +98 -0
  119. package/dist/cjs/WebhookChannel.js.map +7 -0
  120. package/dist/cjs/index.d.ts +160 -0
  121. package/dist/cjs/index.d.ts.map +1 -0
  122. package/dist/cjs/index.js +91 -0
  123. package/dist/cjs/index.js.map +7 -0
  124. package/dist/cjs/internal/MutationBoundary.d.ts +27 -0
  125. package/dist/cjs/internal/MutationBoundary.d.ts.map +1 -0
  126. package/dist/cjs/internal/MutationBoundary.js +50 -0
  127. package/dist/cjs/internal/MutationBoundary.js.map +7 -0
  128. package/dist/cjs/internal/activeFibers.d.ts +12 -0
  129. package/dist/cjs/internal/activeFibers.d.ts.map +1 -0
  130. package/dist/cjs/internal/activeFibers.js +30 -0
  131. package/dist/cjs/internal/activeFibers.js.map +7 -0
  132. package/dist/cjs/internal/issues.d.ts +28 -0
  133. package/dist/cjs/internal/issues.d.ts.map +1 -0
  134. package/dist/cjs/internal/issues.js +34 -0
  135. package/dist/cjs/internal/issues.js.map +7 -0
  136. package/dist/cjs/internal/planning.d.ts +347 -0
  137. package/dist/cjs/internal/planning.d.ts.map +1 -0
  138. package/dist/cjs/internal/planning.js +137 -0
  139. package/dist/cjs/internal/planning.js.map +7 -0
  140. package/dist/cjs/internal/sqlSchemaErrors.d.ts +18 -0
  141. package/dist/cjs/internal/sqlSchemaErrors.d.ts.map +1 -0
  142. package/dist/cjs/internal/sqlSchemaErrors.js +40 -0
  143. package/dist/cjs/internal/sqlSchemaErrors.js.map +7 -0
  144. package/dist/cjs/migrations/0001_control_tables.d.ts +18 -0
  145. package/dist/cjs/migrations/0001_control_tables.d.ts.map +1 -0
  146. package/dist/cjs/migrations/0001_control_tables.js +115 -0
  147. package/dist/cjs/migrations/0001_control_tables.js.map +7 -0
  148. package/dist/cjs/migrations/0002_run_keys.d.ts +15 -0
  149. package/dist/cjs/migrations/0002_run_keys.d.ts.map +1 -0
  150. package/dist/cjs/migrations/0002_run_keys.js +44 -0
  151. package/dist/cjs/migrations/0002_run_keys.js.map +7 -0
  152. package/dist/cjs/migrations/0003_signal_commands.d.ts +13 -0
  153. package/dist/cjs/migrations/0003_signal_commands.d.ts.map +1 -0
  154. package/dist/cjs/migrations/0003_signal_commands.js +50 -0
  155. package/dist/cjs/migrations/0003_signal_commands.js.map +7 -0
  156. package/dist/cjs/migrations/0004_approval_decisions.d.ts +13 -0
  157. package/dist/cjs/migrations/0004_approval_decisions.d.ts.map +1 -0
  158. package/dist/cjs/migrations/0004_approval_decisions.js +45 -0
  159. package/dist/cjs/migrations/0004_approval_decisions.js.map +7 -0
  160. package/dist/cjs/migrations/0005_signal_principals.d.ts +18 -0
  161. package/dist/cjs/migrations/0005_signal_principals.d.ts.map +1 -0
  162. package/dist/cjs/migrations/0005_signal_principals.js +45 -0
  163. package/dist/cjs/migrations/0005_signal_principals.js.map +7 -0
  164. package/dist/cjs/migrations/0006_run_principals.d.ts +18 -0
  165. package/dist/cjs/migrations/0006_run_principals.d.ts.map +1 -0
  166. package/dist/cjs/migrations/0006_run_principals.js +49 -0
  167. package/dist/cjs/migrations/0006_run_principals.js.map +7 -0
  168. package/dist/cjs/migrations/0007_resume_consent.d.ts +18 -0
  169. package/dist/cjs/migrations/0007_resume_consent.d.ts.map +1 -0
  170. package/dist/cjs/migrations/0007_resume_consent.js +46 -0
  171. package/dist/cjs/migrations/0007_resume_consent.js.map +7 -0
  172. package/dist/cjs/package.json +1 -0
  173. package/dist/cjs/test/TestControl.d.ts +19 -0
  174. package/dist/cjs/test/TestControl.d.ts.map +1 -0
  175. package/dist/cjs/test/TestControl.js +62 -0
  176. package/dist/cjs/test/TestControl.js.map +7 -0
  177. package/dist/esm/ApprovalAuthority.d.ts +73 -0
  178. package/dist/esm/ApprovalAuthority.d.ts.map +1 -0
  179. package/dist/esm/ApprovalAuthority.js +72 -0
  180. package/dist/esm/ApprovalAuthority.js.map +1 -0
  181. package/dist/esm/Cancellation.d.ts +107 -0
  182. package/dist/esm/Cancellation.d.ts.map +1 -0
  183. package/dist/esm/Cancellation.js +116 -0
  184. package/dist/esm/Cancellation.js.map +1 -0
  185. package/dist/esm/Channels.d.ts +170 -0
  186. package/dist/esm/Channels.d.ts.map +1 -0
  187. package/dist/esm/Channels.js +312 -0
  188. package/dist/esm/Channels.js.map +1 -0
  189. package/dist/esm/Control.d.ts +202 -0
  190. package/dist/esm/Control.d.ts.map +1 -0
  191. package/dist/esm/Control.js +42 -0
  192. package/dist/esm/Control.js.map +1 -0
  193. package/dist/esm/ControlClient.d.ts +52 -0
  194. package/dist/esm/ControlClient.d.ts.map +1 -0
  195. package/dist/esm/ControlClient.js +217 -0
  196. package/dist/esm/ControlClient.js.map +1 -0
  197. package/dist/esm/ControlError.d.ts +318 -0
  198. package/dist/esm/ControlError.d.ts.map +1 -0
  199. package/dist/esm/ControlError.js +359 -0
  200. package/dist/esm/ControlError.js.map +1 -0
  201. package/dist/esm/ControlExecutor.d.ts +372 -0
  202. package/dist/esm/ControlExecutor.d.ts.map +1 -0
  203. package/dist/esm/ControlExecutor.js +212 -0
  204. package/dist/esm/ControlExecutor.js.map +1 -0
  205. package/dist/esm/ControlFacts.d.ts +454 -0
  206. package/dist/esm/ControlFacts.d.ts.map +1 -0
  207. package/dist/esm/ControlFacts.js +324 -0
  208. package/dist/esm/ControlFacts.js.map +1 -0
  209. package/dist/esm/ControlLive.d.ts +23 -0
  210. package/dist/esm/ControlLive.d.ts.map +1 -0
  211. package/dist/esm/ControlLive.js +1585 -0
  212. package/dist/esm/ControlLive.js.map +1 -0
  213. package/dist/esm/ControlRpcs.d.ts +1204 -0
  214. package/dist/esm/ControlRpcs.d.ts.map +1 -0
  215. package/dist/esm/ControlRpcs.js +299 -0
  216. package/dist/esm/ControlRpcs.js.map +1 -0
  217. package/dist/esm/ControlRuntime.d.ts +635 -0
  218. package/dist/esm/ControlRuntime.d.ts.map +1 -0
  219. package/dist/esm/ControlRuntime.js +807 -0
  220. package/dist/esm/ControlRuntime.js.map +1 -0
  221. package/dist/esm/ControlSchema.d.ts +2642 -0
  222. package/dist/esm/ControlSchema.d.ts.map +1 -0
  223. package/dist/esm/ControlSchema.js +1030 -0
  224. package/dist/esm/ControlSchema.js.map +1 -0
  225. package/dist/esm/ControlServer.d.ts +51 -0
  226. package/dist/esm/ControlServer.d.ts.map +1 -0
  227. package/dist/esm/ControlServer.js +145 -0
  228. package/dist/esm/ControlServer.js.map +1 -0
  229. package/dist/esm/Credential.d.ts +136 -0
  230. package/dist/esm/Credential.d.ts.map +1 -0
  231. package/dist/esm/Credential.js +190 -0
  232. package/dist/esm/Credential.js.map +1 -0
  233. package/dist/esm/CredentialCipher.d.ts +90 -0
  234. package/dist/esm/CredentialCipher.d.ts.map +1 -0
  235. package/dist/esm/CredentialCipher.js +56 -0
  236. package/dist/esm/CredentialCipher.js.map +1 -0
  237. package/dist/esm/CredentialStore.d.ts +97 -0
  238. package/dist/esm/CredentialStore.d.ts.map +1 -0
  239. package/dist/esm/CredentialStore.js +101 -0
  240. package/dist/esm/CredentialStore.js.map +1 -0
  241. package/dist/esm/DispatchReader.d.ts +112 -0
  242. package/dist/esm/DispatchReader.d.ts.map +1 -0
  243. package/dist/esm/DispatchReader.js +76 -0
  244. package/dist/esm/DispatchReader.js.map +1 -0
  245. package/dist/esm/Health.d.ts +333 -0
  246. package/dist/esm/Health.d.ts.map +1 -0
  247. package/dist/esm/Health.js +400 -0
  248. package/dist/esm/Health.js.map +1 -0
  249. package/dist/esm/JevSessionChecker.d.ts +57 -0
  250. package/dist/esm/JevSessionChecker.d.ts.map +1 -0
  251. package/dist/esm/JevSessionChecker.js +108 -0
  252. package/dist/esm/JevSessionChecker.js.map +1 -0
  253. package/dist/esm/Lineage.d.ts +131 -0
  254. package/dist/esm/Lineage.d.ts.map +1 -0
  255. package/dist/esm/Lineage.js +174 -0
  256. package/dist/esm/Lineage.js.map +1 -0
  257. package/dist/esm/Migrations.d.ts +34 -0
  258. package/dist/esm/Migrations.d.ts.map +1 -0
  259. package/dist/esm/Migrations.js +53 -0
  260. package/dist/esm/Migrations.js.map +1 -0
  261. package/dist/esm/Monitor.d.ts +282 -0
  262. package/dist/esm/Monitor.d.ts.map +1 -0
  263. package/dist/esm/Monitor.js +415 -0
  264. package/dist/esm/Monitor.js.map +1 -0
  265. package/dist/esm/ScopedToken.d.ts +193 -0
  266. package/dist/esm/ScopedToken.d.ts.map +1 -0
  267. package/dist/esm/ScopedToken.js +224 -0
  268. package/dist/esm/ScopedToken.js.map +1 -0
  269. package/dist/esm/SqlControlRuntime.d.ts +161 -0
  270. package/dist/esm/SqlControlRuntime.d.ts.map +1 -0
  271. package/dist/esm/SqlControlRuntime.js +1756 -0
  272. package/dist/esm/SqlControlRuntime.js.map +1 -0
  273. package/dist/esm/SqlCredentialStore.d.ts +43 -0
  274. package/dist/esm/SqlCredentialStore.d.ts.map +1 -0
  275. package/dist/esm/SqlCredentialStore.js +97 -0
  276. package/dist/esm/SqlCredentialStore.js.map +1 -0
  277. package/dist/esm/Steering.d.ts +69 -0
  278. package/dist/esm/Steering.d.ts.map +1 -0
  279. package/dist/esm/Steering.js +89 -0
  280. package/dist/esm/Steering.js.map +1 -0
  281. package/dist/esm/SystemFlows.d.ts +223 -0
  282. package/dist/esm/SystemFlows.d.ts.map +1 -0
  283. package/dist/esm/SystemFlows.js +198 -0
  284. package/dist/esm/SystemFlows.js.map +1 -0
  285. package/dist/esm/WebCryptoCipher.d.ts +49 -0
  286. package/dist/esm/WebCryptoCipher.d.ts.map +1 -0
  287. package/dist/esm/WebCryptoCipher.js +123 -0
  288. package/dist/esm/WebCryptoCipher.js.map +1 -0
  289. package/dist/esm/WebhookChannel.d.ts +113 -0
  290. package/dist/esm/WebhookChannel.d.ts.map +1 -0
  291. package/dist/esm/WebhookChannel.js +109 -0
  292. package/dist/esm/WebhookChannel.js.map +1 -0
  293. package/dist/esm/index.d.ts +160 -0
  294. package/dist/esm/index.d.ts.map +1 -0
  295. package/dist/esm/index.js +160 -0
  296. package/dist/esm/index.js.map +1 -0
  297. package/dist/esm/internal/MutationBoundary.d.ts +27 -0
  298. package/dist/esm/internal/MutationBoundary.d.ts.map +1 -0
  299. package/dist/esm/internal/MutationBoundary.js +40 -0
  300. package/dist/esm/internal/MutationBoundary.js.map +1 -0
  301. package/dist/esm/internal/activeFibers.d.ts +12 -0
  302. package/dist/esm/internal/activeFibers.d.ts.map +1 -0
  303. package/dist/esm/internal/activeFibers.js +17 -0
  304. package/dist/esm/internal/activeFibers.js.map +1 -0
  305. package/dist/esm/internal/issues.d.ts +28 -0
  306. package/dist/esm/internal/issues.d.ts.map +1 -0
  307. package/dist/esm/internal/issues.js +35 -0
  308. package/dist/esm/internal/issues.js.map +1 -0
  309. package/dist/esm/internal/planning.d.ts +347 -0
  310. package/dist/esm/internal/planning.d.ts.map +1 -0
  311. package/dist/esm/internal/planning.js +199 -0
  312. package/dist/esm/internal/planning.js.map +1 -0
  313. package/dist/esm/internal/sqlSchemaErrors.d.ts +18 -0
  314. package/dist/esm/internal/sqlSchemaErrors.d.ts.map +1 -0
  315. package/dist/esm/internal/sqlSchemaErrors.js +38 -0
  316. package/dist/esm/internal/sqlSchemaErrors.js.map +1 -0
  317. package/dist/esm/migrations/0001_control_tables.d.ts +18 -0
  318. package/dist/esm/migrations/0001_control_tables.d.ts.map +1 -0
  319. package/dist/esm/migrations/0001_control_tables.js +96 -0
  320. package/dist/esm/migrations/0001_control_tables.js.map +1 -0
  321. package/dist/esm/migrations/0002_run_keys.d.ts +15 -0
  322. package/dist/esm/migrations/0002_run_keys.d.ts.map +1 -0
  323. package/dist/esm/migrations/0002_run_keys.js +22 -0
  324. package/dist/esm/migrations/0002_run_keys.js.map +1 -0
  325. package/dist/esm/migrations/0003_signal_commands.d.ts +13 -0
  326. package/dist/esm/migrations/0003_signal_commands.d.ts.map +1 -0
  327. package/dist/esm/migrations/0003_signal_commands.js +26 -0
  328. package/dist/esm/migrations/0003_signal_commands.js.map +1 -0
  329. package/dist/esm/migrations/0004_approval_decisions.d.ts +13 -0
  330. package/dist/esm/migrations/0004_approval_decisions.d.ts.map +1 -0
  331. package/dist/esm/migrations/0004_approval_decisions.js +25 -0
  332. package/dist/esm/migrations/0004_approval_decisions.js.map +1 -0
  333. package/dist/esm/migrations/0005_signal_principals.d.ts +18 -0
  334. package/dist/esm/migrations/0005_signal_principals.d.ts.map +1 -0
  335. package/dist/esm/migrations/0005_signal_principals.js +27 -0
  336. package/dist/esm/migrations/0005_signal_principals.js.map +1 -0
  337. package/dist/esm/migrations/0006_run_principals.d.ts +18 -0
  338. package/dist/esm/migrations/0006_run_principals.d.ts.map +1 -0
  339. package/dist/esm/migrations/0006_run_principals.js +30 -0
  340. package/dist/esm/migrations/0006_run_principals.js.map +1 -0
  341. package/dist/esm/migrations/0007_resume_consent.d.ts +18 -0
  342. package/dist/esm/migrations/0007_resume_consent.d.ts.map +1 -0
  343. package/dist/esm/migrations/0007_resume_consent.js +27 -0
  344. package/dist/esm/migrations/0007_resume_consent.js.map +1 -0
  345. package/dist/esm/test/TestControl.d.ts +19 -0
  346. package/dist/esm/test/TestControl.d.ts.map +1 -0
  347. package/dist/esm/test/TestControl.js +30 -0
  348. package/dist/esm/test/TestControl.js.map +1 -0
  349. package/docs/README.md +189 -0
  350. package/docs/api.md +982 -0
  351. package/docs/concepts/authority.md +109 -0
  352. package/docs/concepts/cancellation.md +129 -0
  353. package/docs/concepts/lineage.md +132 -0
  354. package/docs/concepts/ownership.md +139 -0
  355. package/docs/concepts/projections.md +203 -0
  356. package/docs/concepts/receipts.md +128 -0
  357. package/docs/guides/approvals.md +284 -0
  358. package/docs/guides/cancel-and-resume.md +162 -0
  359. package/docs/guides/durable-storage.md +147 -0
  360. package/docs/guides/implement-an-executor.md +173 -0
  361. package/docs/guides/ingest-a-webhook.md +177 -0
  362. package/docs/guides/list-runs.md +160 -0
  363. package/docs/guides/monitor-runs.md +176 -0
  364. package/docs/guides/observe-health.md +147 -0
  365. package/docs/guides/postgres-tests.md +5 -0
  366. package/docs/guides/serve-over-rpc.md +220 -0
  367. package/docs/guides/signal-a-run.md +53 -0
  368. package/docs/guides/steer-a-run.md +138 -0
  369. package/docs/guides/store-credentials.md +164 -0
  370. package/docs/guides/testing.md +139 -0
  371. package/docs/guides/watch-a-run.md +154 -0
  372. package/docs/installation.md +106 -0
  373. package/docs/quickstart.md +163 -0
  374. package/docs/troubleshooting.md +208 -0
  375. package/package.json +405 -3
  376. package/src/ApprovalAuthority.ts +114 -0
  377. package/src/Cancellation.ts +172 -0
  378. package/src/Channels.ts +493 -0
  379. package/src/Control.ts +337 -0
  380. package/src/ControlClient.ts +319 -0
  381. package/src/ControlError.ts +378 -0
  382. package/src/ControlExecutor.ts +490 -0
  383. package/src/ControlFacts.ts +383 -0
  384. package/src/ControlLive.ts +2113 -0
  385. package/src/ControlRpcs.ts +443 -0
  386. package/src/ControlRuntime.ts +1597 -0
  387. package/src/ControlSchema.ts +1380 -0
  388. package/src/ControlServer.ts +182 -0
  389. package/src/Credential.ts +310 -0
  390. package/src/CredentialCipher.ts +110 -0
  391. package/src/CredentialStore.ts +152 -0
  392. package/src/DispatchReader.ts +122 -0
  393. package/src/Health.ts +591 -0
  394. package/src/JevSessionChecker.ts +127 -0
  395. package/src/Lineage.ts +203 -0
  396. package/src/Migrations.ts +56 -0
  397. package/src/Monitor.ts +600 -0
  398. package/src/ScopedToken.ts +306 -0
  399. package/src/SqlControlRuntime.ts +2476 -0
  400. package/src/SqlCredentialStore.ts +148 -0
  401. package/src/Steering.ts +96 -0
  402. package/src/SystemFlows.ts +225 -0
  403. package/src/WebCryptoCipher.ts +169 -0
  404. package/src/WebhookChannel.ts +166 -0
  405. package/src/index.ts +188 -0
  406. package/src/internal/MutationBoundary.ts +46 -0
  407. package/src/internal/activeFibers.ts +22 -0
  408. package/src/internal/issues.ts +40 -0
  409. package/src/internal/planning.ts +262 -0
  410. package/src/internal/sqlSchemaErrors.ts +37 -0
  411. package/src/migrations/0001_control_tables.ts +99 -0
  412. package/src/migrations/0002_run_keys.ts +23 -0
  413. package/src/migrations/0003_signal_commands.ts +27 -0
  414. package/src/migrations/0004_approval_decisions.ts +25 -0
  415. package/src/migrations/0005_signal_principals.ts +27 -0
  416. package/src/migrations/0006_run_principals.ts +31 -0
  417. package/src/migrations/0007_resume_consent.ts +28 -0
  418. package/src/test/TestControl.ts +47 -0
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Plan construction shared by every `ControlRuntime` implementation.
3
+ *
4
+ * The plan digest is what an approval is bound to, so the memory runtime and
5
+ * the durable runtime must compute it the same way or an approval taken on one
6
+ * would not validate on the other. Keeping the construction here is what makes
7
+ * that a compile-time fact rather than a convention.
8
+ *
9
+ * @since 0.1.0
10
+ */
11
+ import type * as PersistedPlan from "@smthrs/plan/Plan";
12
+ import { Effect } from "effect";
13
+ import type { PlanInput } from "../Control.ts";
14
+ import { CodeDrift } from "../ControlError.ts";
15
+ import type { Envelope, FlowId, IdempotencyKey, PlanGraph, PlanNode, Principal, Receipt, RunId, RunSummary } from "../ControlSchema.ts";
16
+ /**
17
+ * The drift between the code a run recorded and the code that would resume
18
+ * it, or `undefined` when there is none. A run that recorded no digest (a flow
19
+ * without one, or a row older than the field) is not checked for flow drift,
20
+ * and one that recorded no engine version is not checked for engine drift.
21
+ *
22
+ * @since 1.0.0
23
+ * @private
24
+ */
25
+ export declare const codeDriftOf: (run: RunSummary, flow: {
26
+ readonly executionDigest?: string | undefined;
27
+ } | undefined, engineVersion: string | undefined) => CodeDrift | undefined;
28
+ /**
29
+ * The code identity a resume the operator allowed to drift records on the run,
30
+ * so later checks compare against the code it now runs.
31
+ *
32
+ * @since 1.0.0
33
+ * @private
34
+ */
35
+ export declare const adoptedCode: (run: RunSummary, flow: {
36
+ readonly executionDigest?: string | undefined;
37
+ } | undefined, engineVersion: string | undefined) => Pick<RunSummary, "executionDigest" | "engineVersion">;
38
+ /**
39
+ * The envelope a flow with no declared capabilities carries.
40
+ *
41
+ * @since 0.1.0
42
+ * @private
43
+ */
44
+ export declare const emptyEnvelope: Envelope;
45
+ /**
46
+ * Canonical bytes for a value.
47
+ * Throws on a non-serializable value; every caller either wraps it in
48
+ * `Effect.try` or has already validated the value.
49
+ *
50
+ * @since 0.1.0
51
+ * @private
52
+ */
53
+ export declare const canonical: (value: unknown) => string;
54
+ /**
55
+ * The durable key a caller's idempotency key is stored under.
56
+ *
57
+ * Namespaced by the effective actor: the submitted principal, or the runtime's
58
+ * configured fallback when the caller named none. The principal's clock is
59
+ * omitted, so an equal retry lands on the same key.
60
+ *
61
+ * @since 0.1.0
62
+ * @private
63
+ */
64
+ export declare const mutationKey: (operation: string, key: IdempotencyKey, principal: Pick<Principal, "id" | "kind">) => string;
65
+ /**
66
+ * The content digest of a value's canonical bytes.
67
+ *
68
+ * @since 0.1.0
69
+ * @private
70
+ */
71
+ export declare const digest: (value: unknown) => Effect.Effect<string & import("effect/Brand").Brand<"@smthrs/crypto/Sha256/Digest">, never, import("effect/Crypto").Crypto>;
72
+ /**
73
+ * Envelope equality by canonical bytes, not by reference or key order.
74
+ *
75
+ * @since 0.1.0
76
+ * @private
77
+ */
78
+ export declare const sameEnvelope: (left: Envelope, right: Envelope) => boolean;
79
+ /**
80
+ * A flow's envelope with a planner's budget fields laid over its declared ones.
81
+ *
82
+ * @since 1.0.0-rc.1
83
+ * @private
84
+ */
85
+ export declare const budgeted: (envelope: Envelope, budget: Envelope["budget"] | undefined) => Envelope;
86
+ /**
87
+ * What one plan request asks for, for idempotency: a key replayed with another
88
+ * budget is another plan.
89
+ *
90
+ * @since 1.0.0-rc.1
91
+ * @private
92
+ */
93
+ export declare const planFingerprint: (input: PlanInput) => string;
94
+ /**
95
+ * An accepted receipt, carrying a run id when one exists.
96
+ *
97
+ * @since 0.1.0
98
+ * @private
99
+ */
100
+ export declare const accepted: (receiptId: string, runId?: RunId) => Receipt;
101
+ /**
102
+ * The receipt a replayed mutation returns, derived from the recorded one.
103
+ *
104
+ * @since 0.1.0
105
+ * @private
106
+ */
107
+ export declare const alreadyApplied: (key: IdempotencyKey, receipt: Receipt) => Receipt;
108
+ /**
109
+ * The plan inputs a card is derived from.
110
+ *
111
+ * @since 0.1.0
112
+ * @private
113
+ */
114
+ export interface PlanSource {
115
+ readonly planId: string;
116
+ readonly flowId: FlowId;
117
+ readonly decodedInput: unknown;
118
+ readonly envelope: Envelope;
119
+ readonly deployClass: boolean;
120
+ readonly executionDigest?: string | undefined;
121
+ /** The persisted plan value and cache verdicts produced by the host. */
122
+ readonly handoff?: {
123
+ readonly plan: PersistedPlan.Plan;
124
+ readonly statuses?: Readonly<Record<string, PlanNode["status"]>> | undefined;
125
+ readonly graph?: PlanGraph | undefined;
126
+ } | undefined;
127
+ readonly idempotencyKey?: IdempotencyKey | undefined;
128
+ }
129
+ /**
130
+ * Builds the immutable plan card and the approval target bound to its digest.
131
+ *
132
+ * @since 0.1.0
133
+ * @private
134
+ */
135
+ export declare const planCard: (source: PlanSource) => Effect.Effect<{
136
+ approval: {
137
+ target: {
138
+ readonly _tag: "Plan";
139
+ readonly planId: string;
140
+ readonly digest: string;
141
+ readonly envelope: {
142
+ readonly capabilities: readonly string[];
143
+ readonly flows: readonly string[];
144
+ readonly budget: {
145
+ readonly deadline?: number | undefined;
146
+ readonly tokens?: number | undefined;
147
+ readonly milliseconds?: number | undefined;
148
+ readonly usd?: number | undefined;
149
+ readonly onExceeded?: "fail" | "park" | "warn" | "skip-remaining" | undefined;
150
+ };
151
+ readonly hostImports?: readonly string[] | undefined;
152
+ readonly host?: string | undefined;
153
+ };
154
+ };
155
+ scope: "run";
156
+ idempotencyKey: string;
157
+ };
158
+ graph?: {
159
+ readonly edges: readonly {
160
+ readonly from: string;
161
+ readonly to: string;
162
+ readonly reason: "value" | "continuation" | "failure" | "conflict" | "lane-merge";
163
+ }[];
164
+ readonly nodes?: readonly {
165
+ readonly id: string;
166
+ readonly declaredAt?: {
167
+ readonly path: string;
168
+ readonly line: number;
169
+ };
170
+ }[] | undefined;
171
+ readonly sourceRevision?: string | undefined;
172
+ };
173
+ nodes: readonly {
174
+ readonly status: "run" | "cached";
175
+ readonly id: string;
176
+ readonly kind: "step" | "agent" | "merge";
177
+ readonly key: string & import("effect/Brand").Brand<"@smthrs/keys/Key">;
178
+ readonly material: {
179
+ readonly capabilities: readonly string[];
180
+ readonly version: "flows/key-material/v2";
181
+ readonly inputs: readonly ({
182
+ readonly _tag: "Literal";
183
+ readonly value: unknown;
184
+ } | {
185
+ readonly _tag: "Ref";
186
+ readonly from: string;
187
+ readonly path: readonly string[];
188
+ } | {
189
+ readonly _tag: "Pending";
190
+ readonly from: string;
191
+ })[];
192
+ readonly layers: readonly string[];
193
+ readonly kind: "sealed" | "compensable" | "irreversible";
194
+ readonly body: unknown;
195
+ readonly nondeterministic?: true | undefined;
196
+ readonly effects?: unknown;
197
+ readonly placement?: unknown;
198
+ };
199
+ readonly effects: {
200
+ readonly reads: readonly (string | {
201
+ readonly _tag: "Glob";
202
+ readonly include: readonly [string, ...string[]];
203
+ readonly exclude?: readonly string[] | undefined;
204
+ } | {
205
+ readonly _tag: "Filegroup";
206
+ readonly name: string;
207
+ readonly entries: readonly (string | {
208
+ readonly _tag: "Glob";
209
+ readonly include: readonly [string, ...string[]];
210
+ readonly exclude?: readonly string[] | undefined;
211
+ })[];
212
+ })[];
213
+ readonly writes: readonly (string | {
214
+ readonly _tag: "Glob";
215
+ readonly include: readonly [string, ...string[]];
216
+ readonly exclude?: readonly string[] | undefined;
217
+ } | {
218
+ readonly _tag: "TreeArtifact";
219
+ readonly path: string;
220
+ } | {
221
+ readonly _tag: "Filegroup";
222
+ readonly name: string;
223
+ readonly entries: readonly (string | {
224
+ readonly _tag: "Glob";
225
+ readonly include: readonly [string, ...string[]];
226
+ readonly exclude?: readonly string[] | undefined;
227
+ } | {
228
+ readonly _tag: "TreeArtifact";
229
+ readonly path: string;
230
+ })[];
231
+ })[];
232
+ readonly boundaryMode: "expected" | "hard";
233
+ readonly removes?: readonly string[] | undefined;
234
+ };
235
+ readonly dependsOn: readonly string[];
236
+ readonly conflicts: readonly {
237
+ readonly with: string;
238
+ readonly paths: readonly string[];
239
+ readonly strategy: "serialize" | "lane" | "fail";
240
+ readonly runtime: "delay-rebase" | "stop-merge";
241
+ }[];
242
+ readonly strategy: "serialize" | "lane" | "fail";
243
+ readonly runtime: "delay-rebase" | "stop-merge";
244
+ readonly priority: number;
245
+ readonly generation: number;
246
+ }[];
247
+ plan?: {
248
+ readonly planId: string;
249
+ readonly flow: string;
250
+ readonly generation: number;
251
+ readonly baseDigest: string & import("effect/Brand").Brand<"@smthrs/keys/Key">;
252
+ readonly digest: string & import("effect/Brand").Brand<"@smthrs/keys/Key">;
253
+ readonly nodes: readonly {
254
+ readonly id: string;
255
+ readonly kind: "step" | "agent" | "merge";
256
+ readonly key: string & import("effect/Brand").Brand<"@smthrs/keys/Key">;
257
+ readonly material: {
258
+ readonly capabilities: readonly string[];
259
+ readonly version: "flows/key-material/v2";
260
+ readonly inputs: readonly ({
261
+ readonly _tag: "Literal";
262
+ readonly value: unknown;
263
+ } | {
264
+ readonly _tag: "Ref";
265
+ readonly from: string;
266
+ readonly path: readonly string[];
267
+ } | {
268
+ readonly _tag: "Pending";
269
+ readonly from: string;
270
+ })[];
271
+ readonly layers: readonly string[];
272
+ readonly kind: "sealed" | "compensable" | "irreversible";
273
+ readonly body: unknown;
274
+ readonly nondeterministic?: true | undefined;
275
+ readonly effects?: unknown;
276
+ readonly placement?: unknown;
277
+ };
278
+ readonly effects: {
279
+ readonly reads: readonly (string | {
280
+ readonly _tag: "Glob";
281
+ readonly include: readonly [string, ...string[]];
282
+ readonly exclude?: readonly string[] | undefined;
283
+ } | {
284
+ readonly _tag: "Filegroup";
285
+ readonly name: string;
286
+ readonly entries: readonly (string | {
287
+ readonly _tag: "Glob";
288
+ readonly include: readonly [string, ...string[]];
289
+ readonly exclude?: readonly string[] | undefined;
290
+ })[];
291
+ })[];
292
+ readonly writes: readonly (string | {
293
+ readonly _tag: "Glob";
294
+ readonly include: readonly [string, ...string[]];
295
+ readonly exclude?: readonly string[] | undefined;
296
+ } | {
297
+ readonly _tag: "TreeArtifact";
298
+ readonly path: string;
299
+ } | {
300
+ readonly _tag: "Filegroup";
301
+ readonly name: string;
302
+ readonly entries: readonly (string | {
303
+ readonly _tag: "Glob";
304
+ readonly include: readonly [string, ...string[]];
305
+ readonly exclude?: readonly string[] | undefined;
306
+ } | {
307
+ readonly _tag: "TreeArtifact";
308
+ readonly path: string;
309
+ })[];
310
+ })[];
311
+ readonly boundaryMode: "expected" | "hard";
312
+ readonly removes?: readonly string[] | undefined;
313
+ };
314
+ readonly dependsOn: readonly string[];
315
+ readonly conflicts: readonly {
316
+ readonly with: string;
317
+ readonly paths: readonly string[];
318
+ readonly strategy: "serialize" | "lane" | "fail";
319
+ readonly runtime: "delay-rebase" | "stop-merge";
320
+ }[];
321
+ readonly strategy: "serialize" | "lane" | "fail";
322
+ readonly runtime: "delay-rebase" | "stop-merge";
323
+ readonly priority: number;
324
+ readonly generation: number;
325
+ }[];
326
+ };
327
+ executionDigest?: string;
328
+ planId: string;
329
+ flowId: string;
330
+ digest: string & import("effect/Brand").Brand<"@smthrs/crypto/Sha256/Digest">;
331
+ inputSummary: string;
332
+ envelope: {
333
+ readonly capabilities: readonly string[];
334
+ readonly flows: readonly string[];
335
+ readonly budget: {
336
+ readonly deadline?: number | undefined;
337
+ readonly tokens?: number | undefined;
338
+ readonly milliseconds?: number | undefined;
339
+ readonly usd?: number | undefined;
340
+ readonly onExceeded?: "fail" | "park" | "warn" | "skip-remaining" | undefined;
341
+ };
342
+ readonly hostImports?: readonly string[] | undefined;
343
+ readonly host?: string | undefined;
344
+ };
345
+ deployClass: boolean;
346
+ }, never, import("effect/Crypto").Crypto>;
347
+ //# sourceMappingURL=planning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../../src/internal/planning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Plan construction shared by every `ControlRuntime` implementation.
3
+ *
4
+ * The plan digest is what an approval is bound to, so the memory runtime and
5
+ * the durable runtime must compute it the same way or an approval taken on one
6
+ * would not validate on the other. Keeping the construction here is what makes
7
+ * that a compile-time fact rather than a convention.
8
+ *
9
+ * @since 0.1.0
10
+ */
11
+ import { canonicalize } from "@smthrs/canonical";
12
+ import { Sha256 } from "@smthrs/crypto";
13
+ import * as Sha256Digest from "@smthrs/crypto/Sha256";
14
+ import { Effect, Schema } from "effect";
15
+ import { CodeDrift } from "../ControlError.js";
16
+ /**
17
+ * The drift between the code a run recorded and the code that would resume
18
+ * it, or `undefined` when there is none. A run that recorded no digest (a flow
19
+ * without one, or a row older than the field) is not checked for flow drift,
20
+ * and one that recorded no engine version is not checked for engine drift.
21
+ *
22
+ * @since 1.0.0
23
+ * @private
24
+ */
25
+ export const codeDriftOf = (run, flow, engineVersion) => {
26
+ const flowDrift = run.executionDigest !== undefined && flow?.executionDigest !== run.executionDigest;
27
+ const engineDrift = run.engineVersion !== undefined && engineVersion !== undefined &&
28
+ engineVersion !== run.engineVersion;
29
+ if (!flowDrift && !engineDrift)
30
+ return undefined;
31
+ return new CodeDrift({
32
+ runId: run.runId,
33
+ flowId: run.flowId,
34
+ ...(flowDrift ? { recorded: run.executionDigest } : {}),
35
+ ...(flowDrift && flow?.executionDigest !== undefined ? { current: flow.executionDigest } : {}),
36
+ ...(engineDrift ? { recordedEngine: run.engineVersion, currentEngine: engineVersion } : {})
37
+ });
38
+ };
39
+ /**
40
+ * The code identity a resume the operator allowed to drift records on the run,
41
+ * so later checks compare against the code it now runs.
42
+ *
43
+ * @since 1.0.0
44
+ * @private
45
+ */
46
+ export const adoptedCode = (run, flow, engineVersion) => ({
47
+ executionDigest: flow?.executionDigest,
48
+ engineVersion: engineVersion ?? run.engineVersion
49
+ });
50
+ /**
51
+ * The envelope a flow with no declared capabilities carries.
52
+ *
53
+ * @since 0.1.0
54
+ * @private
55
+ */
56
+ export const emptyEnvelope = {
57
+ capabilities: [],
58
+ flows: [],
59
+ budget: {}
60
+ };
61
+ /**
62
+ * Canonical bytes for a value.
63
+ * Throws on a non-serializable value; every caller either wraps it in
64
+ * `Effect.try` or has already validated the value.
65
+ *
66
+ * @since 0.1.0
67
+ * @private
68
+ */
69
+ export const canonical = (value) => canonicalize(value);
70
+ /**
71
+ * The durable key a caller's idempotency key is stored under.
72
+ *
73
+ * Namespaced by the effective actor: the submitted principal, or the runtime's
74
+ * configured fallback when the caller named none. The principal's clock is
75
+ * omitted, so an equal retry lands on the same key.
76
+ *
77
+ * @since 0.1.0
78
+ * @private
79
+ */
80
+ export const mutationKey = (operation, key, principal) => `${operation}:actor:${Sha256Digest.digestSync(canonical({ id: principal.id, kind: principal.kind }))}:${key}`;
81
+ /**
82
+ * The content digest of a value's canonical bytes.
83
+ *
84
+ * @since 0.1.0
85
+ * @private
86
+ */
87
+ export const digest = (value) => Schema.decodeUnknownEffect(Sha256)(canonical(value)).pipe(Effect.orDie);
88
+ /**
89
+ * Envelope equality by canonical bytes, not by reference or key order.
90
+ *
91
+ * @since 0.1.0
92
+ * @private
93
+ */
94
+ export const sameEnvelope = (left, right) => canonical(left) === canonical(right);
95
+ /**
96
+ * A flow's envelope with a planner's budget fields laid over its declared ones.
97
+ *
98
+ * @since 1.0.0-rc.1
99
+ * @private
100
+ */
101
+ export const budgeted = (envelope, budget) => budget === undefined ? envelope : { ...envelope, budget: { ...envelope.budget, ...budget } };
102
+ /**
103
+ * What one plan request asks for, for idempotency: a key replayed with another
104
+ * budget is another plan.
105
+ *
106
+ * @since 1.0.0-rc.1
107
+ * @private
108
+ */
109
+ export const planFingerprint = (input) => canonical({
110
+ flowId: input.flowId,
111
+ input: input.input,
112
+ ...(input.budget === undefined ? {} : { budget: input.budget })
113
+ });
114
+ /**
115
+ * An accepted receipt, carrying a run id when one exists.
116
+ *
117
+ * @since 0.1.0
118
+ * @private
119
+ */
120
+ export const accepted = (receiptId, runId) => {
121
+ /* v8 ignore next 3 -- both runtimes call this from `launch`, which has the run it just started; the parameter stays optional for the receipt's shape rather than for a caller */
122
+ return runId === undefined
123
+ ? { _tag: "Accepted", receiptId }
124
+ : { _tag: "Accepted", receiptId, runId };
125
+ };
126
+ /**
127
+ * The receipt a replayed mutation returns, derived from the recorded one.
128
+ *
129
+ * @since 0.1.0
130
+ * @private
131
+ */
132
+ export const alreadyApplied = (key, receipt) => {
133
+ const receiptId = receipt._tag === "Accepted" || receipt._tag === "AlreadyApplied" ? receipt.receiptId : key;
134
+ const runId = receipt._tag === "Accepted" || receipt._tag === "AlreadyApplied" || receipt._tag === "Terminal"
135
+ ? receipt.runId
136
+ : undefined;
137
+ const input = receipt._tag === "Accepted" || receipt._tag === "AlreadyApplied"
138
+ ? {
139
+ ...(receipt.inputConsumed === undefined ? {} : { inputConsumed: receipt.inputConsumed }),
140
+ ...(receipt.inputBody === undefined ? {} : { inputBody: receipt.inputBody })
141
+ }
142
+ : {};
143
+ return runId === undefined
144
+ ? { _tag: "AlreadyApplied", receiptId, ...input }
145
+ : { _tag: "AlreadyApplied", receiptId, runId, ...input };
146
+ };
147
+ /**
148
+ * Builds the immutable plan card and the approval target bound to its digest.
149
+ *
150
+ * @since 0.1.0
151
+ * @private
152
+ */
153
+ export const planCard = (source) => Effect.gen(function* () {
154
+ const plan = source.handoff?.plan;
155
+ const nodes = plan === undefined
156
+ ? []
157
+ : plan.nodes.map((node) => ({
158
+ ...node,
159
+ status: source.handoff?.statuses?.[node.id] ?? "run"
160
+ }));
161
+ const planDigest = yield* digest({
162
+ flowId: source.flowId,
163
+ input: source.decodedInput,
164
+ envelope: source.envelope,
165
+ deployClass: source.deployClass,
166
+ ...(source.executionDigest === undefined ? {} : { executionDigest: source.executionDigest }),
167
+ // The persisted plan digest covers keys, edges, effects, conflicts,
168
+ // priorities, and generations. Hashing only node keys loses executable
169
+ // graph changes whose content keys legitimately stay stable.
170
+ persistedPlan: plan?.digest ?? null
171
+ });
172
+ const target = {
173
+ _tag: "Plan",
174
+ planId: source.planId,
175
+ digest: planDigest,
176
+ envelope: source.envelope
177
+ };
178
+ return {
179
+ planId: source.planId,
180
+ flowId: source.flowId,
181
+ digest: planDigest,
182
+ inputSummary: canonical(source.decodedInput),
183
+ envelope: source.envelope,
184
+ deployClass: source.deployClass,
185
+ ...(source.executionDigest === undefined ? {} : { executionDigest: source.executionDigest }),
186
+ ...(plan === undefined ? {} : { plan }),
187
+ nodes,
188
+ // Outside `digest` above on purpose: the edges are how a reader draws
189
+ // the plan, not what the plan will do, so gaining them must not
190
+ // invalidate an approval taken before the host reported them.
191
+ ...(source.handoff?.graph === undefined ? {} : { graph: source.handoff.graph }),
192
+ approval: {
193
+ target,
194
+ scope: "run",
195
+ idempotencyKey: source.idempotencyKey ?? `approve:${source.planId}`
196
+ }
197
+ };
198
+ });
199
+ //# sourceMappingURL=planning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planning.js","sourceRoot":"","sources":["../../../src/internal/planning.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Plan construction shared by every `ControlRuntime` implementation.\n *\n * The plan digest is what an approval is bound to, so the memory runtime and\n * the durable runtime must compute it the same way or an approval taken on one\n * would not validate on the other. Keeping the construction here is what makes\n * that a compile-time fact rather than a convention.\n *\n * @since 0.1.0\n */\n\nimport { canonicalize } from \"@smthrs/canonical\"\nimport { Sha256 } from \"@smthrs/crypto\"\nimport * as Sha256Digest from \"@smthrs/crypto/Sha256\"\nimport type * as PersistedPlan from \"@smthrs/plan/Plan\"\nimport { Effect, Schema } from \"effect\"\nimport type { ApprovalTarget, PlanInput } from \"../Control.ts\"\nimport { CodeDrift } from \"../ControlError.ts\"\nimport type {\n Envelope,\n FlowId,\n IdempotencyKey,\n PlanCard,\n PlanGraph,\n PlanNode,\n Principal,\n Receipt,\n RunId,\n RunSummary\n} from \"../ControlSchema.ts\"\n\n/**\n * The drift between the code a run recorded and the code that would resume\n * it, or `undefined` when there is none. A run that recorded no digest (a flow\n * without one, or a row older than the field) is not checked for flow drift,\n * and one that recorded no engine version is not checked for engine drift.\n *\n * @since 1.0.0\n * @private\n */\nexport const codeDriftOf = (\n run: RunSummary,\n flow: { readonly executionDigest?: string | undefined } | undefined,\n engineVersion: string | undefined\n): CodeDrift | undefined => {\n const flowDrift = run.executionDigest !== undefined && flow?.executionDigest !== run.executionDigest\n const engineDrift = run.engineVersion !== undefined && engineVersion !== undefined &&\n engineVersion !== run.engineVersion\n if (!flowDrift && !engineDrift) return undefined\n return new CodeDrift({\n runId: run.runId,\n flowId: run.flowId,\n ...(flowDrift ? { recorded: run.executionDigest } : {}),\n ...(flowDrift && flow?.executionDigest !== undefined ? { current: flow.executionDigest } : {}),\n ...(engineDrift ? { recordedEngine: run.engineVersion, currentEngine: engineVersion } : {})\n })\n}\n\n/**\n * The code identity a resume the operator allowed to drift records on the run,\n * so later checks compare against the code it now runs.\n *\n * @since 1.0.0\n * @private\n */\nexport const adoptedCode = (\n run: RunSummary,\n flow: { readonly executionDigest?: string | undefined } | undefined,\n engineVersion: string | undefined\n): Pick<RunSummary, \"executionDigest\" | \"engineVersion\"> => ({\n executionDigest: flow?.executionDigest,\n engineVersion: engineVersion ?? run.engineVersion\n})\n\n/**\n * The envelope a flow with no declared capabilities carries.\n *\n * @since 0.1.0\n * @private\n */\nexport const emptyEnvelope: Envelope = {\n capabilities: [],\n flows: [],\n budget: {}\n}\n\n/**\n * Canonical bytes for a value.\n * Throws on a non-serializable value; every caller either wraps it in\n * `Effect.try` or has already validated the value.\n *\n * @since 0.1.0\n * @private\n */\nexport const canonical = (value: unknown): string => canonicalize(value)\n\n/**\n * The durable key a caller's idempotency key is stored under.\n *\n * Namespaced by the effective actor: the submitted principal, or the runtime's\n * configured fallback when the caller named none. The principal's clock is\n * omitted, so an equal retry lands on the same key.\n *\n * @since 0.1.0\n * @private\n */\nexport const mutationKey = (\n operation: string,\n key: IdempotencyKey,\n principal: Pick<Principal, \"id\" | \"kind\">\n): string =>\n `${operation}:actor:${Sha256Digest.digestSync(canonical({ id: principal.id, kind: principal.kind }))}:${key}`\n\n/**\n * The content digest of a value's canonical bytes.\n *\n * @since 0.1.0\n * @private\n */\nexport const digest = (value: unknown) => Schema.decodeUnknownEffect(Sha256)(canonical(value)).pipe(Effect.orDie)\n\n/**\n * Envelope equality by canonical bytes, not by reference or key order.\n *\n * @since 0.1.0\n * @private\n */\nexport const sameEnvelope = (left: Envelope, right: Envelope): boolean => canonical(left) === canonical(right)\n\n/**\n * A flow's envelope with a planner's budget fields laid over its declared ones.\n *\n * @since 1.0.0-rc.1\n * @private\n */\nexport const budgeted = (envelope: Envelope, budget: Envelope[\"budget\"] | undefined): Envelope =>\n budget === undefined ? envelope : { ...envelope, budget: { ...envelope.budget, ...budget } }\n\n/**\n * What one plan request asks for, for idempotency: a key replayed with another\n * budget is another plan.\n *\n * @since 1.0.0-rc.1\n * @private\n */\nexport const planFingerprint = (input: PlanInput): string =>\n canonical({\n flowId: input.flowId,\n input: input.input,\n ...(input.budget === undefined ? {} : { budget: input.budget })\n })\n\n/**\n * An accepted receipt, carrying a run id when one exists.\n *\n * @since 0.1.0\n * @private\n */\nexport const accepted = (receiptId: string, runId?: RunId): Receipt => {\n /* v8 ignore next 3 -- both runtimes call this from `launch`, which has the run it just started; the parameter stays optional for the receipt's shape rather than for a caller */\n return runId === undefined\n ? { _tag: \"Accepted\", receiptId }\n : { _tag: \"Accepted\", receiptId, runId }\n}\n\n/**\n * The receipt a replayed mutation returns, derived from the recorded one.\n *\n * @since 0.1.0\n * @private\n */\nexport const alreadyApplied = (key: IdempotencyKey, receipt: Receipt): Receipt => {\n const receiptId = receipt._tag === \"Accepted\" || receipt._tag === \"AlreadyApplied\" ? receipt.receiptId : key\n const runId = receipt._tag === \"Accepted\" || receipt._tag === \"AlreadyApplied\" || receipt._tag === \"Terminal\"\n ? receipt.runId\n : undefined\n const input = receipt._tag === \"Accepted\" || receipt._tag === \"AlreadyApplied\"\n ? {\n ...(receipt.inputConsumed === undefined ? {} : { inputConsumed: receipt.inputConsumed }),\n ...(receipt.inputBody === undefined ? {} : { inputBody: receipt.inputBody })\n }\n : {}\n return runId === undefined\n ? { _tag: \"AlreadyApplied\", receiptId, ...input }\n : { _tag: \"AlreadyApplied\", receiptId, runId, ...input }\n}\n\n/**\n * The plan inputs a card is derived from.\n *\n * @since 0.1.0\n * @private\n */\nexport interface PlanSource {\n readonly planId: string\n readonly flowId: FlowId\n readonly decodedInput: unknown\n readonly envelope: Envelope\n readonly deployClass: boolean\n readonly executionDigest?: string | undefined\n /** The persisted plan value and cache verdicts produced by the host. */\n readonly handoff?: {\n readonly plan: PersistedPlan.Plan\n readonly statuses?: Readonly<Record<string, PlanNode[\"status\"]>> | undefined\n readonly graph?: PlanGraph | undefined\n } | undefined\n readonly idempotencyKey?: IdempotencyKey | undefined\n}\n\n/**\n * Builds the immutable plan card and the approval target bound to its digest.\n *\n * @since 0.1.0\n * @private\n */\nexport const planCard = (source: PlanSource) =>\n Effect.gen(function*() {\n const plan = source.handoff?.plan\n const nodes: ReadonlyArray<PlanNode> = plan === undefined\n ? []\n : plan.nodes.map((node) => ({\n ...node,\n status: source.handoff?.statuses?.[node.id] ?? \"run\"\n }))\n const planDigest = yield* digest({\n flowId: source.flowId,\n input: source.decodedInput,\n envelope: source.envelope,\n deployClass: source.deployClass,\n ...(source.executionDigest === undefined ? {} : { executionDigest: source.executionDigest }),\n // The persisted plan digest covers keys, edges, effects, conflicts,\n // priorities, and generations. Hashing only node keys loses executable\n // graph changes whose content keys legitimately stay stable.\n persistedPlan: plan?.digest ?? null\n })\n const target: ApprovalTarget = {\n _tag: \"Plan\",\n planId: source.planId,\n digest: planDigest,\n envelope: source.envelope\n }\n return {\n planId: source.planId,\n flowId: source.flowId,\n digest: planDigest,\n inputSummary: canonical(source.decodedInput),\n envelope: source.envelope,\n deployClass: source.deployClass,\n ...(source.executionDigest === undefined ? {} : { executionDigest: source.executionDigest }),\n ...(plan === undefined ? {} : { plan }),\n nodes,\n // Outside `digest` above on purpose: the edges are how a reader draws\n // the plan, not what the plan will do, so gaining them must not\n // invalidate an approval taken before the host reported them.\n ...(source.handoff?.graph === undefined ? {} : { graph: source.handoff.graph }),\n approval: {\n target,\n scope: \"run\" as const,\n idempotencyKey: source.idempotencyKey ?? `approve:${source.planId}`\n }\n } satisfies PlanCard\n })\n"]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Exact optional-schema failure classification across SQL driver wrappers.
3
+ * @since 1.0.0
4
+ */
5
+ /**
6
+ * Driver messages stay separate so wrapper context cannot identify a different failure.
7
+ * The depth bound terminates cyclic driver causes.
8
+ * @since 1.0.0
9
+ * @private
10
+ */
11
+ export declare const causeMessages: (value: unknown, depth?: number) => ReadonlyArray<string>;
12
+ /**
13
+ * Only the relation named by a driver's missing-table diagnostic may be absent.
14
+ * @since 1.0.0
15
+ * @private
16
+ */
17
+ export declare const missingTable: (table: string) => (cause: unknown) => boolean;
18
+ //# sourceMappingURL=sqlSchemaErrors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlSchemaErrors.d.ts","sourceRoot":"","sources":["../../../src/internal/sqlSchemaErrors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,EAAE,cAAS,KAAG,aAAa,CAAC,MAAM,CAS7E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,MAAM,OAAO,OAAO,KAAG,OAS7D,CAAA"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Exact optional-schema failure classification across SQL driver wrappers.
3
+ * @since 1.0.0
4
+ */
5
+ /**
6
+ * Driver messages stay separate so wrapper context cannot identify a different failure.
7
+ * The depth bound terminates cyclic driver causes.
8
+ * @since 1.0.0
9
+ * @private
10
+ */
11
+ export const causeMessages = (value, depth = 4) => {
12
+ if (typeof value === "string")
13
+ return [value];
14
+ if (depth === 0 || typeof value !== "object" || value === null)
15
+ return [];
16
+ const fields = value;
17
+ return [
18
+ ...(typeof fields.message === "string" ? [fields.message] : []),
19
+ ...causeMessages(fields.reason, depth - 1),
20
+ ...causeMessages(fields.cause, depth - 1)
21
+ ];
22
+ };
23
+ /**
24
+ * Only the relation named by a driver's missing-table diagnostic may be absent.
25
+ * @since 1.0.0
26
+ * @private
27
+ */
28
+ export const missingTable = (table) => (cause) => causeMessages(cause).some((message) => {
29
+ const relation = /^no such table: (\S+)$/.exec(message)?.[1]
30
+ ?? /^relation "([^"]+)" does not exist$/.exec(message)?.[1];
31
+ // These queries name unqualified relations. A qualified name can refer
32
+ // to a different schema's dependency, so do not discard its qualifier.
33
+ if (relation !== undefined)
34
+ return relation === table;
35
+ // MySQL always names the database in its table diagnostic.
36
+ return /^Table '[^.']+\.([^']+)' doesn't exist$/.exec(message)?.[1] === table;
37
+ });
38
+ //# sourceMappingURL=sqlSchemaErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlSchemaErrors.js","sourceRoot":"","sources":["../../../src/internal/sqlSchemaErrors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC,EAAyB,EAAE;IAChF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7C,IAAI,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IACzE,MAAM,MAAM,GAAG,KAA4F,CAAA;IAC3G,OAAO;QACL,GAAG,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC;QAC1C,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC;KAC1C,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAc,EAAW,EAAE,CACzE,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;IACpC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;WACvD,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7D,uEAAuE;IACvE,uEAAuE;IACvE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,KAAK,KAAK,CAAA;IACrD,2DAA2D;IAC3D,OAAO,yCAAyC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAA;AAC/E,CAAC,CAAC,CAAA","sourcesContent":["/**\n * Exact optional-schema failure classification across SQL driver wrappers.\n * @since 1.0.0\n */\n\n/**\n * Driver messages stay separate so wrapper context cannot identify a different failure.\n * The depth bound terminates cyclic driver causes.\n * @since 1.0.0\n * @private\n */\nexport const causeMessages = (value: unknown, depth = 4): ReadonlyArray<string> => {\n if (typeof value === \"string\") return [value]\n if (depth === 0 || typeof value !== \"object\" || value === null) return []\n const fields = value as { readonly message?: unknown; readonly cause?: unknown; readonly reason?: unknown }\n return [\n ...(typeof fields.message === \"string\" ? [fields.message] : []),\n ...causeMessages(fields.reason, depth - 1),\n ...causeMessages(fields.cause, depth - 1)\n ]\n}\n\n/**\n * Only the relation named by a driver's missing-table diagnostic may be absent.\n * @since 1.0.0\n * @private\n */\nexport const missingTable = (table: string) => (cause: unknown): boolean =>\n causeMessages(cause).some((message) => {\n const relation = /^no such table: (\\S+)$/.exec(message)?.[1]\n ?? /^relation \"([^\"]+)\" does not exist$/.exec(message)?.[1]\n // These queries name unqualified relations. A qualified name can refer\n // to a different schema's dependency, so do not discard its qualifier.\n if (relation !== undefined) return relation === table\n // MySQL always names the database in its table diagnostic.\n return /^Table '[^.']+\\.([^']+)' doesn't exist$/.exec(message)?.[1] === table\n })\n"]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Initial durable control-plane schema.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import * as Effect from "effect/Effect";
7
+ import * as SqlClient from "effect/unstable/sql/SqlClient";
8
+ /**
9
+ * Creates every table owned by `@smthrs/control`.
10
+ *
11
+ * `IF NOT EXISTS` lets the recorded migration and each standalone adapter's
12
+ * bootstrap share this exact schema without competing over table creation.
13
+ *
14
+ * @category migrations
15
+ * @since 0.1.0
16
+ */
17
+ export declare const initial: Effect.Effect<void, unknown, SqlClient.SqlClient>;
18
+ //# sourceMappingURL=0001_control_tables.d.ts.map