@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 @@
1
+ {"version":3,"file":"Channels.js","sourceRoot":"","sources":["../../src/Channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAe,SAAS,EAAE,MAAM,QAAQ,CAAA;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAqB,YAAY,EAAqB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAuFvD,MAAM,YAAY,GAAG,CAAI,OAAmB,EAAqB,EAAE,CAAC,CAAC;IACnE,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,MAAM,EAAE,OAAO,CAAC,MAAM;IACtB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;IAC9C,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC;IACpC,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7F,OAAO,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;CAC3D,CAAC,CAAA;AAqCF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAwC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAEjG,MAAM,WAAW,GAAG,CAAC,OAAe,EAAe,EAAE,CACnD,IAAI,WAAW,CAAC;IACd,OAAO;IACP,MAAM,EAAE,0BAA0B;CACnC,CAAC,CAAA;AAEJ,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,GAAe,EAAU,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,CAAA;AAE7G,2EAA2E;AAC3E,MAAM,SAAS,GAAG,CAAC,OAAe,EAAE,GAAmB,EAAkB,EAAE,CACzE,WAAW,OAAO,CAAC,MAAM,IAAI,OAAO,IAAI,GAAG,EAAE,CAAA;AAE/C,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,GAAmB,EAAkB,EAAE,CAC3E,kBAAkB,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAA;AAE7C,MAAM,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,SAAS,CAAW,CAAA;AACjF,MAAM,gBAAgB,GAAG,MAAM,CAAC,wBAAwB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;AAC5F,MAAM,oBAAoB,GAAG,MAAM,CAAC,wBAAwB,CAAC,mBAAmB,EAAE,YAAY,CAAC,EAAE,GAAG,CAAA;AACpG,MAAM,oBAAoB,GAAG,MAAM,CAAC,wBAAwB,CAAC,mBAAmB,EAAE,YAAY,CAAC,EAAE,GAAG,CAAA;AAEpG,MAAM,oBAAqB,SAAQ,SAAS;IACjC,KAAK,CAAQ;IACtB,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,CAAC,CAAA;QACZ,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAS,EAAE;IACxC,MAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAA;AACvC,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,IAAY,EAAgC,EAAE;IACjF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,QAAQ,CAAC,GAAG,IAAI,0BAA0B,CAAC,CAAA;IACpD,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;IAC9C,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,QAAQ,CAAC,GAAG,IAAI,+BAA+B,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,KAAqC,CAAA;AAC9C,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,KAAmC,EAAE,GAAgB,EAAE,IAAY,EAAW,EAAE;IAC/F,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAC9D,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC;QAAE,OAAO,QAAQ,CAAC,GAAG,IAAI,gCAAgC,CAAC,CAAA;IAClH,OAAO,UAAU,CAAC,KAAK,CAAA;AACzB,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAc,EAAE;IAC9C,wLAAwL;IACxL,IACE,gBAAgB,KAAK,SAAS,IAAI,oBAAoB,KAAK,SAAS;QACpE,oBAAoB,KAAK,SAAS;QAClC,OAAO,QAAQ,CAAC,iDAAiD,CAAC,CAAA;IACpE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,EAAE,EAAE,CAAoB,CAAA;QAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAW,CAAA;QAC3E,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAW,CAAA;QAC3E,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAA;QAC3C,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACpB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;AACH,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,KAAc,EAAgD,EAAE;IACvF,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAuC,CAAA;IAC1E,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC,4CAA4C,CAAC,CAAA;QAC1F,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC/D,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACnF,OAAO,QAAQ,CAAC,eAAe,GAAG,uCAAuC,CAAC,CAAA;QAC5E,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC3E,OAAO,QAAQ,CAAC,eAAe,GAAG,iCAAiC,CAAC,CAAA;QACtE,CAAC;QACD,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;QACpC,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YACxC,OAAO,QAAQ,CAAC,eAAe,UAAU,mCAAmC,CAAC,CAAA;QAC/E,CAAC;QACD,QAAQ,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,KAA2B,CAAA;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AAChC,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CACtB,KAAoB,EACiE,EAAE,CACvF,MAAM,CAAC,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,EAAE;QACR,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAA;QAC9D,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,CAAA;QACpF,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,EAAE,gBAAgB,EAAE,oBAAoB,CAAC,CAAA;QACjF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC,oCAAoC,CAAC,CAAA;QAC9G,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,QAAQ,CAAC,uCAAuC,CAAC,CAAA;QAC1D,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,OAAO;YACP,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC;gBACjB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;gBACtD,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;gBACtE,cAAc;aACf,CAAC;SACH,CAAC,CAAA;IACJ,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,YAAY,CAAC;QACf,KAAK,EAAE,KAAK,YAAY,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,+CAA+C;KAC7G,CAAC;CACL,CAAC,CAAA;AAEJ,MAAM,4BAA4B,GAAG,CAAC,OAA0B,EAAyB,EAAE,CACzF,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAElG,oFAAoF;AACpF,MAAM,WAAW,GAAG,CAClB,IAAgB,EAChB,OAAqD,EACrD,KAA4B,EACpB,EAAE;IACV,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;KACnD,CAAC,CAAA;IACF,OAAO,sBAAsB,MAAM,CAAC,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAA;AACtF,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,GAAmB,EAAW,EAAE;IACzE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,UAAU,CAAC;QAChB,KAAK,gBAAgB,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;QACvC;YACE,OAAO,OAAO,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAeD;;;;GAIG;AACH,MAAM,QAAQ,GAAG,CAAC,OAA4B,EAAE,EAAE,CAChD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAA6B,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAA;IAC9C,4EAA4E;IAC5E,6EAA6E;IAC7E,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAA;IAC5C,MAAM,yBAAyB,GAAG,IAAI,CAAA;IACtC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;IAE9B,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CACzC,QAAQ,CAAC,EAAC,IAAY;QACpB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE;YAC7D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACpC,OAAO,OAAO,KAAK,SAAS;gBAC1B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,IAAI,qBAAqB,CAAC,CAAC;gBACjE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC7B,CAAC,CAAC,CAAA;IACJ,CAAC,CACF,CAAA;IAED,OAAO,QAAQ,CAAC,EAAE,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAI,OAAmB,EAAE,EAAE,CAClE,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAA;YAChC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7C,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CACH;QACD,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAC/C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CACpD,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC/C,MAAM,kBAAkB,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAA;YAChE,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;YAChG,8DAA8D;YAC9D,uEAAuE;YACvE,mEAAmE;YACnE,kEAAkE;YAClE,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC7E,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAA;YAC/C,MAAM,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;YACxE,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;YAEnE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACxD,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YACpD,IAAI,OAAgB,CAAA;YACpB,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,+DAA+D;gBAC/D,gEAAgE;gBAChE,kEAAkE;gBAClE,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,cAAc,EAAE,GAAG;oBACnB,SAAS,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE;iBAChG,CAAC,CAAA;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;oBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,cAAc,EAAE,GAAG;iBACpB,CAAC,CAAA;gBACF,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;oBAC3B,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,cAAc,EAAE,GAAG;iBACpB,CAAC,CAAA;YACJ,CAAC;YACD,gEAAgE;YAChE,iEAAiE;YACjE,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7D,KAAK,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,CAAC,CAAA;YACrE,CAAC;YACD,OAAO,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAC,CAAC,CACP;QACD,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,EAAC,OAAO;YACtD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;YAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;YACrD,wEAAwE;YACxE,wDAAwD;YACxD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACjC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;gBACtD,IACE,UAAU,CAAC,SAAS,KAAK,MAAM;oBAC/B,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC,SAAS,CAAC,EACvG,CAAC;oBACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC,CAAA;gBACrF,CAAC;gBACD,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAA;oBACjC,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;wBAC5E,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;wBAC3B,IAAI,kBAAkB,CAAC,IAAI,GAAG,yBAAyB,EAAE,CAAC;4BACxD,0DAA0D;4BAC1D,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAA;4BACxD,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;4BACjC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;wBAC3B,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBAChC,CAAC;gBACH,CAAC;gBACD,OAAO,UAAU,CAAA;YACnB,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC;KACH,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IACrC,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AACjC,CAAC,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAC7B,IAAI,GAAG,EAGH,CACL,CAAA;IACD,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC;QACrB,cAAc,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CACjC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC7B,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAA;YACzC,OAAO,KAAK,CAAC,WAAW,KAAK,SAAS;gBACpC,CAAC,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC;gBACpC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,mBAAmB,GAAG,gCAAgC,EAAE,CAAA;QAC3F,CAAC,CAAC,CAAC;QACL,cAAc,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,CAC1C,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;YAClD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC;KACL,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAA0C,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA","sourcesContent":["/**\n * Channel contracts and the in-memory channel coordinator.\n *\n * A channel verifies opaque transport data before it decodes or maps it. The\n * resulting request is then dispatched through the Control service; channels\n * do not acquire an execution path of their own.\n *\n * @since 0.1.0\n */\n\nimport * as Sha256 from \"@smthrs/crypto/Sha256\"\nimport { Clock, Context, Effect, Layer, Ref, type Schema, Semaphore } from \"effect\"\nimport { Control } from \"./Control.ts\"\nimport { type ControlError, InvalidInput, type Unauthorized, Unavailable } from \"./ControlError.ts\"\nimport { ControlRuntime } from \"./ControlRuntime.ts\"\nimport type { FlowId, IdempotencyKey, Receipt, RunId, RunSummary, SignalPayload } from \"./ControlSchema.ts\"\nimport { alreadyApplied } from \"./internal/planning.ts\"\n\n/**\n * Opaque request data passed to a channel before decoding.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface RawInbound {\n readonly body: Uint8Array\n readonly headers: Readonly<Record<string, string | undefined>>\n readonly idempotencyKey: IdempotencyKey\n}\n\n/**\n * The channel mapping after a verified payload has been decoded.\n *\n * @category models\n * @since 0.1.0\n */\nexport type InboundResult =\n | { readonly _tag: \"Start\"; readonly flowId: FlowId; readonly input: unknown }\n | { readonly _tag: \"Signal\"; readonly runId: RunId; readonly signal: SignalPayload }\n\n/**\n * A process-local per-channel delivery record. `messageId` identifies an existing\n * platform message, so a reconnect can update it instead of posting again.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface Delivery {\n readonly cursor: string\n readonly messageId?: string | undefined\n}\n\n/**\n * A side-effect-free outbound projection. Network delivery belongs to the\n * transport adapter, which consumes this value after it is journaled.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface DeliveryProjection {\n readonly cursor: string\n readonly messageId?: string | undefined\n readonly operation: \"post\" | \"edit\" | \"noop\"\n readonly message: unknown\n}\n\n/**\n * A bidirectional platform adapter.\n *\n * `verify` must only inspect opaque bytes and headers. It always precedes\n * `decode`, preventing untrusted public requests from reaching planning.\n *\n * @category services\n * @since 0.1.0\n */\nexport interface Channel<A = unknown> {\n readonly name: string\n readonly schema: Schema.Schema<A>\n /**\n * Non-secret HTTP header names whose values change the decoded command.\n * Names are matched case-insensitively and folded into durable idempotency;\n * signature, authorization, and credential headers must not be declared.\n */\n readonly fingerprintHeaders?: ReadonlyArray<string> | undefined\n readonly verify: (raw: RawInbound) => Effect.Effect<void, Unauthorized>\n /** Deterministic, side-effect-free decoding; retries may evaluate it again. */\n readonly decode: (raw: RawInbound) => Effect.Effect<A, InvalidInput>\n /** Deterministic, side-effect-free mapping; retries may evaluate it again. */\n readonly map: (payload: A) => Effect.Effect<InboundResult, InvalidInput>\n readonly project: (run: RunSummary, delivery: Delivery | undefined) => DeliveryProjection\n}\n\n/**\n * A registered channel with its payload type hidden. Decoding and mapping stay\n * paired, so lookup never exposes a mapper accepting arbitrary unknown data.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface RegisteredChannel extends Omit<Channel, \"decode\" | \"map\"> {\n readonly decodeAndMap: (raw: RawInbound) => Effect.Effect<InboundResult, InvalidInput>\n}\n\nconst eraseChannel = <A>(channel: Channel<A>): RegisteredChannel => ({\n name: channel.name,\n schema: channel.schema,\n fingerprintHeaders: channel.fingerprintHeaders,\n verify: (raw) => channel.verify(raw),\n decodeAndMap: (raw) => Effect.flatMap(channel.decode(raw), (payload) => channel.map(payload)),\n project: (run, delivery) => channel.project(run, delivery)\n})\n\n/**\n * Arguments for ingesting one authenticated channel request.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface IngestRequest {\n readonly channel: string\n readonly raw: RawInbound\n}\n\n/**\n * Arguments for projecting one run onto a channel.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface ProjectRequest {\n readonly channel: string\n readonly run: RunSummary\n}\n\n/**\n * The channel coordinator.\n *\n * @category services\n * @since 0.1.0\n */\nexport interface Channels {\n readonly register: <A>(channel: Channel<A>) => Effect.Effect<void>\n readonly lookup: (name: string) => Effect.Effect<RegisteredChannel, Unavailable>\n readonly ingest: (request: IngestRequest) => Effect.Effect<Receipt, ControlError>\n readonly project: (request: ProjectRequest) => Effect.Effect<DeliveryProjection, Unavailable>\n}\n\n/**\n * Service tag for channel registration, ingestion, and pure projection.\n *\n * @category services\n * @since 0.1.0\n */\nexport const Channels: Context.Service<Channels, Channels> = Context.Service(\"/control/Channels\")\n\nconst unavailable = (feature: string): Unavailable =>\n new Unavailable({\n feature,\n ticket: \"control-channel-registry\"\n })\n\nconst deliveryKey = (channel: string, run: RunSummary): string => `${channel.length}:${channel}:${run.runId}`\n\n/** Collision-free control-plane key for one channel-owned external key. */\nconst scopedKey = (channel: string, key: IdempotencyKey): IdempotencyKey =>\n `channel:${channel.length}:${channel}:${key}`\n\nconst mutationKey = (channel: string, key: IdempotencyKey): IdempotencyKey =>\n `channel.ingest:${scopedKey(channel, key)}`\n\nconst typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype) as object\nconst typedArrayBuffer = Object.getOwnPropertyDescriptor(typedArrayPrototype, \"buffer\")?.get\nconst typedArrayByteOffset = Object.getOwnPropertyDescriptor(typedArrayPrototype, \"byteOffset\")?.get\nconst typedArrayByteLength = Object.getOwnPropertyDescriptor(typedArrayPrototype, \"byteLength\")?.get\n\nclass InboundBoundaryError extends TypeError {\n readonly issue: string\n constructor(issue: string) {\n super(issue)\n this.issue = issue\n }\n}\n\nconst boundary = (issue: string): never => {\n throw new InboundBoundaryError(issue)\n}\n\nconst plainRecord = (input: unknown, path: string): Record<PropertyKey, unknown> => {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) {\n return boundary(`${path}: must be a plain record`)\n }\n const prototype = Object.getPrototypeOf(input)\n if (prototype !== Object.prototype && prototype !== null) {\n return boundary(`${path}: must have a plain prototype`)\n }\n return input as Record<PropertyKey, unknown>\n}\n\nconst ownData = (input: Record<PropertyKey, unknown>, key: PropertyKey, path: string): unknown => {\n const descriptor = Object.getOwnPropertyDescriptor(input, key)\n if (descriptor === undefined || !(\"value\" in descriptor)) return boundary(`${path}: must be an own data property`)\n return descriptor.value\n}\n\nconst copyBody = (input: unknown): Uint8Array => {\n /* v8 ignore next 4 -- every host that has `Uint8Array` has its prototype accessors; the refusal exists so a host without them fails closed rather than reading a caller-owned buffer */\n if (\n typedArrayBuffer === undefined || typedArrayByteOffset === undefined ||\n typedArrayByteLength === undefined\n ) return boundary(\"raw.body: this host cannot inspect typed arrays\")\n try {\n const buffer = Reflect.apply(typedArrayBuffer, input, []) as ArrayBufferLike\n const byteOffset = Reflect.apply(typedArrayByteOffset, input, []) as number\n const byteLength = Reflect.apply(typedArrayByteLength, input, []) as number\n const source = new Uint8Array(buffer, byteOffset, byteLength)\n const snapshot = new Uint8Array(byteLength)\n snapshot.set(source)\n return snapshot\n } catch {\n return boundary(\"raw.body: must be a Uint8Array\")\n }\n}\n\nconst snapshotHeaders = (input: unknown): Readonly<Record<string, string | undefined>> => {\n const record = plainRecord(input, \"raw.headers\")\n const snapshot = Object.create(null) as Record<string, string | undefined>\n for (const key of Reflect.ownKeys(record)) {\n if (typeof key !== \"string\") return boundary(\"raw.headers: symbol keys are not supported\")\n const descriptor = Object.getOwnPropertyDescriptor(record, key)\n if (descriptor === undefined || !(\"value\" in descriptor) || !descriptor.enumerable) {\n return boundary(`raw.headers.${key}: must be an enumerable data property`)\n }\n if (descriptor.value !== undefined && typeof descriptor.value !== \"string\") {\n return boundary(`raw.headers.${key}: must be a string or undefined`)\n }\n const normalized = key.toLowerCase()\n if (Object.hasOwn(snapshot, normalized)) {\n return boundary(`raw.headers.${normalized}: duplicate case-insensitive name`)\n }\n snapshot[normalized] = descriptor.value as string | undefined\n }\n return Object.freeze(snapshot)\n}\n\nconst snapshotRequest = (\n input: IngestRequest\n): Effect.Effect<{ readonly channel: string; readonly raw: RawInbound }, InvalidInput> =>\n Effect.try({\n try: () => {\n const request = plainRecord(input, \"request\")\n const channel = ownData(request, \"channel\", \"request.channel\")\n const candidate = plainRecord(ownData(request, \"raw\", \"request.raw\"), \"request.raw\")\n const idempotencyKey = ownData(candidate, \"idempotencyKey\", \"raw.idempotencyKey\")\n if (typeof channel !== \"string\" || channel.length === 0) return boundary(\"request.channel: must be non-empty\")\n if (typeof idempotencyKey !== \"string\" || idempotencyKey.length === 0) {\n return boundary(\"raw.idempotencyKey: must be non-empty\")\n }\n return Object.freeze({\n channel,\n raw: Object.freeze({\n body: copyBody(ownData(candidate, \"body\", \"raw.body\")),\n headers: snapshotHeaders(ownData(candidate, \"headers\", \"raw.headers\")),\n idempotencyKey\n })\n })\n },\n catch: (cause) =>\n new InvalidInput({\n issue: cause instanceof InboundBoundaryError ? cause.issue : \"channel request could not be inspected safely\"\n })\n })\n\nconst normalizedFingerprintHeaders = (channel: RegisteredChannel): ReadonlyArray<string> =>\n Array.from(new Set((channel.fingerprintHeaders ?? []).map((name) => name.toLowerCase()))).sort()\n\n/** Digests the body plus only the adapter-declared, non-secret semantic headers. */\nconst fingerprint = (\n body: Uint8Array,\n headers: Readonly<Record<string, string | undefined>>,\n names: ReadonlyArray<string>\n): string => {\n const document = JSON.stringify([\n Sha256.digestSync(body),\n names.map((name) => [name, headers[name] ?? null])\n ])\n return `channel-ingress:v2:${Sha256.digestSync(new TextEncoder().encode(document))}`\n}\n\nconst externalReceipt = (receipt: Receipt, key: IdempotencyKey): Receipt => {\n switch (receipt._tag) {\n case \"Accepted\":\n case \"AlreadyApplied\":\n case \"Parked\":\n return { ...receipt, receiptId: key }\n default:\n return receipt\n }\n}\n\n/** The slice of the control runtime's mutation store that inbound idempotency uses. */\ninterface InboundReceiptStore {\n readonly lookupMutation: (\n key: IdempotencyKey,\n fingerprint: string\n ) => Effect.Effect<Receipt | undefined, ControlError>\n readonly recordMutation: (\n key: IdempotencyKey,\n fingerprint: string,\n receipt: Receipt\n ) => Effect.Effect<void, ControlError>\n}\n\n/**\n * Builds an in-memory channel registry and delivery map over Control's durable\n * mutation store. Inbound idempotency therefore survives coordinator restarts;\n * only registration and outbound projection cursors are process-local.\n */\nconst makeWith = (runtime: InboundReceiptStore) =>\n Effect.gen(function*() {\n const channels = yield* Ref.make(new Map<string, RegisteredChannel>())\n const deliveries = new Map<string, Delivery>()\n // Live identities are never evicted. Terminal identities have a FIFO window\n // for reconnects; retaining one per historical run would grow without bound.\n const terminalDeliveries = new Set<string>()\n const maximumTerminalDeliveries = 1024\n const ingestion = yield* Semaphore.make(1)\n const control = yield* Control\n\n const lookup = Effect.fn(\"Channels.lookup\")(\n function*(name: string): Effect.fn.Return<RegisteredChannel, Unavailable> {\n return yield* Effect.flatMap(Ref.get(channels), (registered) => {\n const channel = registered.get(name)\n return channel === undefined\n ? Effect.fail(unavailable(`channel \"${name}\" is not registered`))\n : Effect.succeed(channel)\n })\n }\n )\n\n return Channels.of({\n register: Effect.fn(\"Channels.register\")(<A>(channel: Channel<A>) =>\n Ref.update(channels, (registered) => {\n const next = new Map(registered)\n next.set(channel.name, eraseChannel(channel))\n return next\n })\n ),\n lookup,\n ingest: Effect.fn(\"Channels.ingest\")((request) =>\n Effect.flatMap(snapshotRequest(request), (snapshot) =>\n ingestion.withPermits(1)(Effect.gen(function*() {\n const channel = yield* lookup(snapshot.channel)\n const fingerprintHeaders = normalizedFingerprintHeaders(channel)\n const bodyFingerprint = fingerprint(snapshot.raw.body, snapshot.raw.headers, fingerprintHeaders)\n // This ordering is intentional: signature verification is the\n // amplification guard and must happen before decode or Control access.\n // The verifier receives its own body copy, so even a verifier that\n // edits bytes cannot change what the decoder sees after approval.\n yield* channel.verify({ ...snapshot.raw, body: copyBody(snapshot.raw.body) })\n const externalKey = snapshot.raw.idempotencyKey\n const durableKey = mutationKey(snapshot.channel, externalKey)\n const prior = yield* runtime.lookupMutation(durableKey, bodyFingerprint)\n if (prior !== undefined) return externalReceipt(prior, externalKey)\n\n const mapped = yield* channel.decodeAndMap(snapshot.raw)\n const key = scopedKey(snapshot.channel, externalKey)\n let receipt: Receipt\n if (mapped._tag === \"Signal\") {\n // The channel is the caller, not the local operator: a webhook\n // body names the run and wait, so a signal it maps to answers a\n // human wait only if the host delegates approval to this channel.\n receipt = yield* control.signal({\n runId: mapped.runId,\n signal: mapped.signal,\n idempotencyKey: key,\n principal: { id: snapshot.channel, kind: \"channel\", stampedAt: yield* Clock.currentTimeMillis }\n })\n } else {\n const plan = yield* control.plan({\n flowId: mapped.flowId,\n input: mapped.input,\n idempotencyKey: key\n })\n receipt = yield* control.run({\n _tag: \"Plan\",\n planId: plan.planId,\n digest: plan.digest,\n envelope: plan.envelope,\n idempotencyKey: key\n })\n }\n // A parked start has not launched. Leave ingress unsettled so a\n // redelivery can retry the same Control key after plan approval.\n if (receipt._tag !== \"Conflict\" && receipt._tag !== \"Parked\") {\n yield* runtime.recordMutation(durableKey, bodyFingerprint, receipt)\n }\n return externalReceipt(receipt, externalKey)\n })))\n ),\n project: Effect.fn(\"Channels.project\")(function*(request) {\n const channel = yield* lookup(request.channel)\n const key = deliveryKey(request.channel, request.run)\n // Keep the read, projection and update synchronous so concurrent fibers\n // cannot project from the same stale delivery identity.\n return yield* Effect.sync(() => {\n const prior = deliveries.get(key)\n const projection = channel.project(request.run, prior)\n if (\n projection.operation !== \"noop\" &&\n (prior === undefined || prior.cursor !== projection.cursor || prior.messageId !== projection.messageId)\n ) {\n deliveries.set(key, { cursor: projection.cursor, messageId: projection.messageId })\n }\n if (deliveries.has(key)) {\n const status = request.run.status\n if (status === \"completed\" || status === \"failed\" || status === \"cancelled\") {\n terminalDeliveries.add(key)\n if (terminalDeliveries.size > maximumTerminalDeliveries) {\n // The set is nonempty because it just exceeded the limit.\n const oldest = terminalDeliveries.values().next().value!\n terminalDeliveries.delete(oldest)\n deliveries.delete(oldest)\n }\n } else {\n terminalDeliveries.delete(key)\n }\n }\n return projection\n })\n })\n })\n })\n\n/**\n * Builds the coordinator over Control's durable mutation store.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const make = Effect.gen(function*() {\n const runtime = yield* ControlRuntime\n return yield* makeWith(runtime)\n})\n\n/**\n * Builds a process-local coordinator for adapter unit tests.\n *\n * Production hosts use {@link layer}; this constructor deliberately makes no\n * restart guarantee.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const makeMemory = Effect.gen(function*() {\n const records = yield* Ref.make(\n new Map<IdempotencyKey, {\n readonly fingerprint: string\n readonly receipt: Receipt\n }>()\n )\n return yield* makeWith({\n lookupMutation: (key, candidate) =>\n Ref.get(records).pipe(Effect.map((stored) => {\n const prior = stored.get(key)\n if (prior === undefined) return undefined\n return prior.fingerprint === candidate\n ? alreadyApplied(key, prior.receipt)\n : { _tag: \"Conflict\", message: `idempotency key ${key} was used for another mutation` }\n })),\n recordMutation: (key, candidate, receipt) =>\n Ref.update(records, (stored) => {\n const next = new Map(stored)\n next.set(key, { fingerprint: candidate, receipt })\n return next\n })\n })\n})\n\n/**\n * Channel layer with durable inbound receipts supplied by `ControlRuntime`.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer = Layer.effect(Channels, make)\n\n/**\n * Process-local channel layer for adapter unit tests only.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerMemory: Layer.Layer<Channels, never, Control> = Layer.effect(Channels, makeMemory)\n"]}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Transport-independent control-plane vtable.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import type { NotificationError } from "@smthrs/notifications/NotificationQueue";
7
+ import { Context, Effect, Layer, Stream } from "effect";
8
+ import type { AlreadyResolved, ClaimLost, CodeDrift, ControlError, EnvelopeMismatch, FlowNotFound, InvalidInput, LaunchFailed, NoMatchingWait, PersistenceError, PlanDenied, PlanDigestMismatch, PlanNotFound, RunNotFound, TransportError, Unauthorized, Unavailable } from "./ControlError.ts";
9
+ import type { ApprovalPayload, ControlEvent, Envelope, FlowId, IdempotencyKey, ListRequest, ListResponse, PlanCard, Principal, Receipt, RunId, RunInputSchema, SignalInputSchema, SteerInputSchema, WatchFilter } from "./ControlSchema.ts";
10
+ /**
11
+ * Raw input submitted to planning. Decoding is owned by `ControlRuntime`.
12
+ *
13
+ * This local contract accepts `unknown` so the selected flow can decode its
14
+ * own input. `ControlSchema.PlanInputSchema` is the narrower JSON wire
15
+ * contract used by RPC clients.
16
+ *
17
+ * @category models
18
+ * @since 0.1.0
19
+ */
20
+ export interface PlanInput {
21
+ readonly flowId: FlowId;
22
+ readonly input: unknown;
23
+ readonly idempotencyKey?: IdempotencyKey | undefined;
24
+ /** Budget fields that replace the flow's declared ones on this plan's envelope. */
25
+ readonly budget?: Envelope["budget"] | undefined;
26
+ }
27
+ /**
28
+ * Starts an approved plan or joins/resumes an existing run.
29
+ *
30
+ * @category models
31
+ * @since 0.1.0
32
+ */
33
+ export type RunInput = typeof RunInputSchema.Type & {
34
+ /** Trusted runtime caller reserves the execution identity; absent from public RPC. */
35
+ readonly reservedRunId?: RunId | undefined;
36
+ /** Authenticated actor used only to scope durable idempotency. */
37
+ readonly principal?: Principal | undefined;
38
+ };
39
+ /**
40
+ * @category models
41
+ * @since 0.1.0
42
+ */
43
+ export type { ApprovalTarget } from "./ControlSchema.ts";
44
+ /**
45
+ * A listing request, restricted to one reader's runs when `reader` is set.
46
+ *
47
+ * The server sets `reader` to the authenticated principal unless its
48
+ * `RunVisibility` lets that principal see every run; `ControlSchema.ListRequest`
49
+ * excludes it from the wire, so a remote client cannot widen or borrow a view.
50
+ * A restricted reader sees only the runs its principal launched, and the fires
51
+ * that started them; an in-process caller that names no reader sees every run.
52
+ *
53
+ * @category models
54
+ * @since 1.0.0
55
+ */
56
+ export type ListInput = ListRequest & {
57
+ readonly reader?: Principal | undefined;
58
+ };
59
+ /**
60
+ * A watch filter, restricted to one reader's runs when `reader` is set.
61
+ *
62
+ * A restricted reader receives the events of the runs its principal launched
63
+ * and nothing from a plan or from a run it did not launch. See {@link ListInput}.
64
+ *
65
+ * @category models
66
+ * @since 1.0.0
67
+ */
68
+ export type WatchInput = WatchFilter & {
69
+ readonly reader?: Principal | undefined;
70
+ };
71
+ /**
72
+ * Full approval decision submitted to the authenticated server boundary.
73
+ *
74
+ * The local service may receive a runtime-stamped principal.
75
+ * `ControlSchema.ApprovalInputSchema` excludes it from the wire so a remote
76
+ * client cannot claim another identity.
77
+ *
78
+ * @category models
79
+ * @since 0.1.0
80
+ */
81
+ export interface ApprovalInput extends ApprovalPayload {
82
+ readonly principal?: Principal | undefined;
83
+ }
84
+ /**
85
+ * Steering mutation arguments.
86
+ *
87
+ * @category models
88
+ * @since 0.1.0
89
+ */
90
+ export type SteerInput = typeof SteerInputSchema.Type & {
91
+ /**
92
+ * Set by the server to the authenticated principal unless its
93
+ * `RunVisibility` lets that principal see every run. A run the reader may
94
+ * not see fails `RunNotFound`, exactly as a missing run does. Not on the
95
+ * wire; an in-process caller that names no reader mutates any run.
96
+ */
97
+ readonly reader?: Principal | undefined;
98
+ };
99
+ /**
100
+ * Signal mutation arguments.
101
+ *
102
+ * @category models
103
+ * @since 0.1.0
104
+ */
105
+ export type SignalInput = typeof SignalInputSchema.Type & {
106
+ /** Authenticated actor used only to scope durable idempotency. */
107
+ readonly principal?: Principal | undefined;
108
+ /**
109
+ * Set by the server to the authenticated principal unless its
110
+ * `RunVisibility` lets that principal see every run. A run the reader may
111
+ * not see fails `RunNotFound`, exactly as a missing run does. Not on the
112
+ * wire; an in-process caller that names no reader mutates any run.
113
+ */
114
+ readonly reader?: Principal | undefined;
115
+ };
116
+ /**
117
+ * Run lifecycle mutation arguments.
118
+ *
119
+ * The local contract includes the runtime-stamped principal.
120
+ * `ControlSchema.ReasonedMutationInputSchema` carries only the caller's reason
121
+ * over RPC.
122
+ *
123
+ * @category models
124
+ * @since 0.1.0
125
+ */
126
+ export interface RunMutationInput {
127
+ readonly runId: RunId;
128
+ readonly idempotencyKey: IdempotencyKey;
129
+ /**
130
+ * Why the run is being cancelled or resumed.
131
+ *
132
+ * Free text, recorded on the journal entry the mutation writes and projected
133
+ * back onto `RunSummary.cancellation`. An operator reading a cancelled run a
134
+ * week later asks "why", and a control plane that never carried the answer
135
+ * cannot produce one afterwards.
136
+ */
137
+ readonly reason?: string | undefined;
138
+ /**
139
+ * Who is asking. Stamped by the runtime, which supplies its own principal
140
+ * when the caller names none.
141
+ */
142
+ readonly principal?: Principal | undefined;
143
+ /**
144
+ * Resume only: run the flow's current code even when its execution digest
145
+ * differs from the one the run started with. Without it such a resume fails
146
+ * `CodeDrift` and leaves the run where it was.
147
+ */
148
+ readonly allowCodeDrift?: boolean | undefined;
149
+ /**
150
+ * Set by the server to the authenticated principal unless its
151
+ * `RunVisibility` lets that principal see every run. A run the reader may
152
+ * not see fails `RunNotFound`, exactly as a missing run does. Not on the
153
+ * wire; an in-process caller that names no reader mutates any run.
154
+ */
155
+ readonly reader?: Principal | undefined;
156
+ }
157
+ /**
158
+ * Transport-independent control operations.
159
+ *
160
+ * Every operation admits transport and authentication failures so the same
161
+ * service key can be provided by either a local implementation or an RPC client.
162
+ *
163
+ * @category models
164
+ * @since 0.1.0
165
+ */
166
+ export interface Service {
167
+ readonly plan: (input: PlanInput) => Effect.Effect<PlanCard, FlowNotFound | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized>;
168
+ readonly run: (input: RunInput) => Effect.Effect<Receipt, RunNotFound | PlanNotFound | PlanDenied | PlanDigestMismatch | EnvelopeMismatch | ClaimLost | CodeDrift | InvalidInput | LaunchFailed | PersistenceError | Unavailable | TransportError | Unauthorized>;
169
+ readonly approve: (input: ApprovalInput) => Effect.Effect<Receipt, PlanDigestMismatch | EnvelopeMismatch | AlreadyResolved | PlanNotFound | RunNotFound | CodeDrift | InvalidInput | Unauthorized | PersistenceError | Unavailable | TransportError>;
170
+ readonly deny: (input: ApprovalInput) => Effect.Effect<Receipt, PlanDigestMismatch | EnvelopeMismatch | AlreadyResolved | PlanNotFound | RunNotFound | CodeDrift | InvalidInput | Unauthorized | PersistenceError | Unavailable | TransportError>;
171
+ readonly steer: (input: SteerInput) => Effect.Effect<Receipt, RunNotFound | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized | NotificationError>;
172
+ readonly signal: (input: SignalInput) => Effect.Effect<Receipt, RunNotFound | NoMatchingWait | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized>;
173
+ readonly cancel: (input: RunMutationInput) => Effect.Effect<Receipt, RunNotFound | ClaimLost | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized>;
174
+ readonly resume: (input: RunMutationInput) => Effect.Effect<Receipt, RunNotFound | ClaimLost | CodeDrift | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized>;
175
+ readonly list: (input: ListInput) => Effect.Effect<ListResponse, ControlError>;
176
+ /** Checkpoint `event.cursor` after processing each event and resume with `afterCursor`. */
177
+ readonly watch: (filter: WatchInput) => Stream.Stream<ControlEvent, ControlError>;
178
+ }
179
+ declare const Control_base: Context.ServiceClass<Control, "/control/Control", Service>;
180
+ /**
181
+ * Service key for the authoritative control-plane vtable.
182
+ *
183
+ * @category services
184
+ * @since 0.1.0
185
+ */
186
+ export declare class Control extends Control_base {
187
+ }
188
+ /**
189
+ * Constructs a control service from an implementation record.
190
+ *
191
+ * @category constructors
192
+ * @since 0.1.0
193
+ */
194
+ export declare const make: (implementation: Service) => Service;
195
+ /**
196
+ * Provides an unavailable control implementation for optional integrations.
197
+ *
198
+ * @category layers
199
+ * @since 0.1.0
200
+ */
201
+ export declare const layerNoop: Layer.Layer<Control>;
202
+ //# sourceMappingURL=Control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Control.d.ts","sourceRoot":"","sources":["../../src/Control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Transport-independent control-plane vtable.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import { Context, Effect, Layer, Stream } from "effect";
7
+ import { Unavailable as UnavailableError } from "./ControlError.js";
8
+ /**
9
+ * Service key for the authoritative control-plane vtable.
10
+ *
11
+ * @category services
12
+ * @since 0.1.0
13
+ */
14
+ export class Control extends Context.Service()("/control/Control") {
15
+ }
16
+ /**
17
+ * Constructs a control service from an implementation record.
18
+ *
19
+ * @category constructors
20
+ * @since 0.1.0
21
+ */
22
+ export const make = (implementation) => Control.of(implementation);
23
+ const unavailable = (feature) => new UnavailableError({ feature, ticket: "control-runtime-engine-integration" });
24
+ /**
25
+ * Provides an unavailable control implementation for optional integrations.
26
+ *
27
+ * @category layers
28
+ * @since 0.1.0
29
+ */
30
+ export const layerNoop = Layer.succeed(Control, make({
31
+ plan: Effect.fn("Control.plan")(() => Effect.fail(unavailable("plan"))),
32
+ run: Effect.fn("Control.run")(() => Effect.fail(unavailable("run"))),
33
+ approve: Effect.fn("Control.approve")(() => Effect.fail(unavailable("approve"))),
34
+ deny: Effect.fn("Control.deny")(() => Effect.fail(unavailable("deny"))),
35
+ steer: Effect.fn("Control.steer")(() => Effect.fail(unavailable("steer"))),
36
+ signal: Effect.fn("Control.signal")(() => Effect.fail(unavailable("signal"))),
37
+ cancel: Effect.fn("Control.cancel")(() => Effect.fail(unavailable("cancel"))),
38
+ resume: Effect.fn("Control.resume")(() => Effect.fail(unavailable("resume"))),
39
+ list: Effect.fn("Control.list")(() => Effect.fail(unavailable("list"))),
40
+ watch: () => Stream.fail(unavailable("watch"))
41
+ }));
42
+ //# sourceMappingURL=Control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Control.js","sourceRoot":"","sources":["../../src/Control.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAoBvD,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AA8QnE;;;;;GAKG;AACH,MAAM,OAAO,OAAQ,SAAQ,OAAO,CAAC,OAAO,EAAoB,CAAC,kBAAkB,CAAC;CAAG;AAEvF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,cAAuB,EAAW,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAAA;AAEpF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAe,EAAE,CACnD,IAAI,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC,CAAA;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAyB,KAAK,CAAC,OAAO,CAC1D,OAAO,EACP,IAAI,CAAC;IACH,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1E,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7E,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7E,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7E,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;CAC/C,CAAC,CACH,CAAA","sourcesContent":["/**\n * Transport-independent control-plane vtable.\n *\n * @since 0.1.0\n */\n\nimport type { NotificationError } from \"@smthrs/notifications/NotificationQueue\"\nimport { Context, Effect, Layer, Stream } from \"effect\"\nimport type {\n AlreadyResolved,\n ClaimLost,\n CodeDrift,\n ControlError,\n EnvelopeMismatch,\n FlowNotFound,\n InvalidInput,\n LaunchFailed,\n NoMatchingWait,\n PersistenceError,\n PlanDenied,\n PlanDigestMismatch,\n PlanNotFound,\n RunNotFound,\n TransportError,\n Unauthorized,\n Unavailable\n} from \"./ControlError.ts\"\nimport { Unavailable as UnavailableError } from \"./ControlError.ts\"\nimport type {\n ApprovalPayload,\n ControlEvent,\n Envelope,\n FlowId,\n IdempotencyKey,\n ListRequest,\n ListResponse,\n PlanCard,\n Principal,\n Receipt,\n RunId,\n RunInputSchema,\n SignalInputSchema,\n SteerInputSchema,\n WatchFilter\n} from \"./ControlSchema.ts\"\n\n/**\n * Raw input submitted to planning. Decoding is owned by `ControlRuntime`.\n *\n * This local contract accepts `unknown` so the selected flow can decode its\n * own input. `ControlSchema.PlanInputSchema` is the narrower JSON wire\n * contract used by RPC clients.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface PlanInput {\n readonly flowId: FlowId\n readonly input: unknown\n readonly idempotencyKey?: IdempotencyKey | undefined\n /** Budget fields that replace the flow's declared ones on this plan's envelope. */\n readonly budget?: Envelope[\"budget\"] | undefined\n}\n\n/**\n * Starts an approved plan or joins/resumes an existing run.\n *\n * @category models\n * @since 0.1.0\n */\nexport type RunInput = typeof RunInputSchema.Type & {\n /** Trusted runtime caller reserves the execution identity; absent from public RPC. */\n readonly reservedRunId?: RunId | undefined\n /** Authenticated actor used only to scope durable idempotency. */\n readonly principal?: Principal | undefined\n}\n\n/**\n * @category models\n * @since 0.1.0\n */\nexport type { ApprovalTarget } from \"./ControlSchema.ts\"\n\n/**\n * A listing request, restricted to one reader's runs when `reader` is set.\n *\n * The server sets `reader` to the authenticated principal unless its\n * `RunVisibility` lets that principal see every run; `ControlSchema.ListRequest`\n * excludes it from the wire, so a remote client cannot widen or borrow a view.\n * A restricted reader sees only the runs its principal launched, and the fires\n * that started them; an in-process caller that names no reader sees every run.\n *\n * @category models\n * @since 1.0.0\n */\nexport type ListInput = ListRequest & {\n readonly reader?: Principal | undefined\n}\n\n/**\n * A watch filter, restricted to one reader's runs when `reader` is set.\n *\n * A restricted reader receives the events of the runs its principal launched\n * and nothing from a plan or from a run it did not launch. See {@link ListInput}.\n *\n * @category models\n * @since 1.0.0\n */\nexport type WatchInput = WatchFilter & {\n readonly reader?: Principal | undefined\n}\n\n/**\n * Full approval decision submitted to the authenticated server boundary.\n *\n * The local service may receive a runtime-stamped principal.\n * `ControlSchema.ApprovalInputSchema` excludes it from the wire so a remote\n * client cannot claim another identity.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface ApprovalInput extends ApprovalPayload {\n readonly principal?: Principal | undefined\n}\n\n/**\n * Steering mutation arguments.\n *\n * @category models\n * @since 0.1.0\n */\nexport type SteerInput = typeof SteerInputSchema.Type & {\n /**\n * Set by the server to the authenticated principal unless its\n * `RunVisibility` lets that principal see every run. A run the reader may\n * not see fails `RunNotFound`, exactly as a missing run does. Not on the\n * wire; an in-process caller that names no reader mutates any run.\n */\n readonly reader?: Principal | undefined\n}\n\n/**\n * Signal mutation arguments.\n *\n * @category models\n * @since 0.1.0\n */\nexport type SignalInput = typeof SignalInputSchema.Type & {\n /** Authenticated actor used only to scope durable idempotency. */\n readonly principal?: Principal | undefined\n /**\n * Set by the server to the authenticated principal unless its\n * `RunVisibility` lets that principal see every run. A run the reader may\n * not see fails `RunNotFound`, exactly as a missing run does. Not on the\n * wire; an in-process caller that names no reader mutates any run.\n */\n readonly reader?: Principal | undefined\n}\n\n/**\n * Run lifecycle mutation arguments.\n *\n * The local contract includes the runtime-stamped principal.\n * `ControlSchema.ReasonedMutationInputSchema` carries only the caller's reason\n * over RPC.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface RunMutationInput {\n readonly runId: RunId\n readonly idempotencyKey: IdempotencyKey\n /**\n * Why the run is being cancelled or resumed.\n *\n * Free text, recorded on the journal entry the mutation writes and projected\n * back onto `RunSummary.cancellation`. An operator reading a cancelled run a\n * week later asks \"why\", and a control plane that never carried the answer\n * cannot produce one afterwards.\n */\n readonly reason?: string | undefined\n /**\n * Who is asking. Stamped by the runtime, which supplies its own principal\n * when the caller names none.\n */\n readonly principal?: Principal | undefined\n /**\n * Resume only: run the flow's current code even when its execution digest\n * differs from the one the run started with. Without it such a resume fails\n * `CodeDrift` and leaves the run where it was.\n */\n readonly allowCodeDrift?: boolean | undefined\n /**\n * Set by the server to the authenticated principal unless its\n * `RunVisibility` lets that principal see every run. A run the reader may\n * not see fails `RunNotFound`, exactly as a missing run does. Not on the\n * wire; an in-process caller that names no reader mutates any run.\n */\n readonly reader?: Principal | undefined\n}\n\n/**\n * Transport-independent control operations.\n *\n * Every operation admits transport and authentication failures so the same\n * service key can be provided by either a local implementation or an RPC client.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface Service {\n readonly plan: (\n input: PlanInput\n ) => Effect.Effect<\n PlanCard,\n FlowNotFound | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized\n >\n readonly run: (\n input: RunInput\n ) => Effect.Effect<\n Receipt,\n | RunNotFound\n | PlanNotFound\n | PlanDenied\n | PlanDigestMismatch\n | EnvelopeMismatch\n | ClaimLost\n | CodeDrift\n | InvalidInput\n | LaunchFailed\n | PersistenceError\n | Unavailable\n | TransportError\n | Unauthorized\n >\n readonly approve: (\n input: ApprovalInput\n ) => Effect.Effect<\n Receipt,\n | PlanDigestMismatch\n | EnvelopeMismatch\n | AlreadyResolved\n | PlanNotFound\n | RunNotFound\n | CodeDrift\n | InvalidInput\n | Unauthorized\n | PersistenceError\n | Unavailable\n | TransportError\n >\n readonly deny: (\n input: ApprovalInput\n ) => Effect.Effect<\n Receipt,\n | PlanDigestMismatch\n | EnvelopeMismatch\n | AlreadyResolved\n | PlanNotFound\n | RunNotFound\n | CodeDrift\n | InvalidInput\n | Unauthorized\n | PersistenceError\n | Unavailable\n | TransportError\n >\n readonly steer: (\n input: SteerInput\n ) => Effect.Effect<\n Receipt,\n RunNotFound | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized | NotificationError\n >\n readonly signal: (\n input: SignalInput\n ) => Effect.Effect<\n Receipt,\n RunNotFound | NoMatchingWait | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized\n >\n readonly cancel: (\n input: RunMutationInput\n ) => Effect.Effect<\n Receipt,\n RunNotFound | ClaimLost | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized\n >\n readonly resume: (\n input: RunMutationInput\n ) => Effect.Effect<\n Receipt,\n RunNotFound | ClaimLost | CodeDrift | InvalidInput | PersistenceError | Unavailable | TransportError | Unauthorized\n >\n readonly list: (input: ListInput) => Effect.Effect<ListResponse, ControlError>\n /** Checkpoint `event.cursor` after processing each event and resume with `afterCursor`. */\n readonly watch: (filter: WatchInput) => Stream.Stream<ControlEvent, ControlError>\n}\n\n/**\n * Service key for the authoritative control-plane vtable.\n *\n * @category services\n * @since 0.1.0\n */\nexport class Control extends Context.Service<Control, Service>()(\"/control/Control\") {}\n\n/**\n * Constructs a control service from an implementation record.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = (implementation: Service): Service => Control.of(implementation)\n\nconst unavailable = (feature: string): Unavailable =>\n new UnavailableError({ feature, ticket: \"control-runtime-engine-integration\" })\n\n/**\n * Provides an unavailable control implementation for optional integrations.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layerNoop: Layer.Layer<Control> = Layer.succeed(\n Control,\n make({\n plan: Effect.fn(\"Control.plan\")(() => Effect.fail(unavailable(\"plan\"))),\n run: Effect.fn(\"Control.run\")(() => Effect.fail(unavailable(\"run\"))),\n approve: Effect.fn(\"Control.approve\")(() => Effect.fail(unavailable(\"approve\"))),\n deny: Effect.fn(\"Control.deny\")(() => Effect.fail(unavailable(\"deny\"))),\n steer: Effect.fn(\"Control.steer\")(() => Effect.fail(unavailable(\"steer\"))),\n signal: Effect.fn(\"Control.signal\")(() => Effect.fail(unavailable(\"signal\"))),\n cancel: Effect.fn(\"Control.cancel\")(() => Effect.fail(unavailable(\"cancel\"))),\n resume: Effect.fn(\"Control.resume\")(() => Effect.fail(unavailable(\"resume\"))),\n list: Effect.fn(\"Control.list\")(() => Effect.fail(unavailable(\"list\"))),\n watch: () => Stream.fail(unavailable(\"watch\"))\n })\n)\n"]}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * RPC client layer projected back into the control service interface.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import { Layer } from "effect";
7
+ import { HttpClient } from "effect/unstable/http";
8
+ import { Control } from "./Control.ts";
9
+ import { TransportError, Unauthorized } from "./ControlError.ts";
10
+ /**
11
+ * Whether a value is one of the control plane's declared failures, as opposed
12
+ * to a defect that escaped some other layer.
13
+ *
14
+ * Derived from `ControlError.ControlErrorSchema` rather than restated, so a new
15
+ * error class cannot be a member of the union and a stranger to the client.
16
+ *
17
+ * @category refinements
18
+ * @since 0.1.0
19
+ */
20
+ export declare const isControlError: <I>(input: I) => input is I & (import("@smthrs/notifications/NotificationQueue").NotificationError | import("./ControlError.ts").RunNotFound | import("./ControlError.ts").PlanNotFound | import("./ControlError.ts").PlanDenied | import("./ControlError.ts").FlowNotFound | import("./ControlError.ts").PlanDigestMismatch | import("./ControlError.ts").EnvelopeMismatch | import("./ControlError.ts").ClaimLost | import("./ControlError.ts").CodeDrift | import("./ControlError.ts").AlreadyResolved | import("./ControlError.ts").InvalidInput | Unauthorized | import("./ControlError.ts").Unavailable | TransportError | import("./ControlError.ts").PersistenceError | import("./ControlError.ts").LaunchFailed | import("./ControlError.ts").NoMatchingWait | import("./ControlError.ts").CredentialConflict);
21
+ /**
22
+ * Client transport configuration. Unary procedures use HTTP at this URL;
23
+ * `watch` uses the abstract WebSocket supplied by the platform layer.
24
+ *
25
+ * `credential` reaches the HTTP protocol only. It is attached as a bearer
26
+ * token on each HTTP RPC request; the `watch` stream rides a WebSocket whose
27
+ * upgrade request a browser cannot add headers to, so the socket carries no
28
+ * credential at all in a browser deployment. A deployment that authenticates
29
+ * control traffic must therefore front the socket (terminate auth at a proxy
30
+ * that injects the credential on the upgrade) or serve `watch` over the HTTP
31
+ * protocol instead.
32
+ *
33
+ * @category models
34
+ * @since 0.1.0
35
+ */
36
+ export interface ClientConfig {
37
+ readonly url: string;
38
+ /**
39
+ * Bearer token attached to every HTTP RPC request when present.
40
+ *
41
+ * Not sent on the `watch` WebSocket: see {@link ClientConfig}.
42
+ */
43
+ readonly credential?: string | undefined;
44
+ }
45
+ /**
46
+ * Provides `Control` through an RPC client while preserving the local vtable.
47
+ *
48
+ * @category layers
49
+ * @since 0.1.0
50
+ */
51
+ export declare const layer: (config: ClientConfig) => Layer.Layer<Control, never, import("effect/unstable/rpc/RpcSerialization").RpcSerialization | HttpClient.HttpClient | import("effect/unstable/socket/Socket").Socket>;
52
+ //# sourceMappingURL=ControlClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ControlClient.d.ts","sourceRoot":"","sources":["../../src/ControlClient.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiB,KAAK,EAA0B,MAAM,QAAQ,CAAA;AACrE,OAAO,EAAE,UAAU,EAAqB,MAAM,sBAAsB,CAAA;AAEpE,OAAO,EAAE,OAAO,EAAQ,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAyC,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAcvG;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,yxBAAgC,CAAA;AAiM3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,QAAQ,YAAY,0KA4DzC,CAAA"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * RPC client layer projected back into the control service interface.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import { Cause, Effect, Layer, Result, Schema, Stream } from "effect";
7
+ import { HttpClient, HttpClientRequest } from "effect/unstable/http";
8
+ import { RpcClient, RpcClientError } from "effect/unstable/rpc";
9
+ import { Control, make } from "./Control.js";
10
+ import { ControlErrorSchema, TransportError, Unauthorized } from "./ControlError.js";
11
+ import { ControlRpcs } from "./ControlRpcs.js";
12
+ import { ApprovalInputSchema, CancelInputSchema, ListRequest, PlanInputSchema, ResumeInputSchema, RunInputSchema, SignalInputSchema, SteerInputSchema, WatchFilter } from "./ControlSchema.js";
13
+ /**
14
+ * Whether a value is one of the control plane's declared failures, as opposed
15
+ * to a defect that escaped some other layer.
16
+ *
17
+ * Derived from `ControlError.ControlErrorSchema` rather than restated, so a new
18
+ * error class cannot be a member of the union and a stranger to the client.
19
+ *
20
+ * @category refinements
21
+ * @since 0.1.0
22
+ */
23
+ export const isControlError = Schema.is(ControlErrorSchema);
24
+ const requestEncoding = {
25
+ message: "The control request could not be encoded.",
26
+ retryable: false
27
+ };
28
+ const responseDecoding = {
29
+ message: "The control response could not be decoded.",
30
+ retryable: false
31
+ };
32
+ const connectionFailure = {
33
+ message: "The control server could not be reached.",
34
+ retryable: true
35
+ };
36
+ const clientHttpFailure = {
37
+ message: "The control server rejected the HTTP request.",
38
+ retryable: false
39
+ };
40
+ const serverHttpFailure = {
41
+ message: "The control server failed while handling the HTTP request.",
42
+ retryable: true
43
+ };
44
+ const invalidClientUrl = {
45
+ message: "The control server URL is invalid.",
46
+ retryable: false
47
+ };
48
+ const unknownClientFailure = {
49
+ message: "The control RPC client failed.",
50
+ retryable: false
51
+ };
52
+ const transportError = (cause, classification) => new TransportError({
53
+ ...classification,
54
+ cause
55
+ });
56
+ // A `StatusCodeError` reported by the RPC client always carries the concrete
57
+ // error, and that error always carries its response. The three refusals below
58
+ // are what keeps a hand-built wrapper without one from being read as a 5xx and
59
+ // retried forever; none of them is reachable from the client's own transports.
60
+ const statusFrom = (cause) => {
61
+ /* v8 ignore next -- a StatusCodeError cause always carries its response */
62
+ if (typeof cause !== "object" || cause === null || !("response" in cause))
63
+ return undefined;
64
+ const response = cause.response;
65
+ /* v8 ignore next -- as above: the response is an object carrying a status */
66
+ if (typeof response !== "object" || response === null || !("status" in response))
67
+ return undefined;
68
+ /* v8 ignore next -- as above: the status is a number */
69
+ return typeof response.status === "number" ? response.status : undefined;
70
+ };
71
+ /**
72
+ * What each HTTP failure means for a retry.
73
+ *
74
+ * `StatusCodeError` is absent on purpose: it is the one kind whose answer
75
+ * depends on the response, not on the kind.
76
+ */
77
+ const httpClassification = {
78
+ TransportError: connectionFailure,
79
+ EncodeError: requestEncoding,
80
+ InvalidUrlError: invalidClientUrl,
81
+ DecodeError: responseDecoding,
82
+ EmptyBodyError: responseDecoding
83
+ };
84
+ /**
85
+ * What each non-HTTP transport failure means for a retry.
86
+ *
87
+ * A table rather than a switch, because the mapping is data: the compiler
88
+ * still requires every reason the RPC client can report to have an answer, and
89
+ * a reader can check the whole policy at a glance.
90
+ */
91
+ const reasonClassification = {
92
+ RpcClientDefect: responseDecoding,
93
+ SocketReadError: connectionFailure,
94
+ SocketWriteError: connectionFailure,
95
+ SocketOpenError: connectionFailure,
96
+ // The socket cannot perform a requested protocol upgrade; retries of the
97
+ // same unsupported operation cannot change that host capability.
98
+ SocketUpgradeError: unknownClientFailure,
99
+ SocketCloseError: connectionFailure,
100
+ // A worker transport is not composable with this client, which speaks HTTP
101
+ // and WebSocket. The entries exist so the table stays exhaustive.
102
+ WorkerSpawnError: unknownClientFailure,
103
+ WorkerSendError: unknownClientFailure,
104
+ WorkerReceiveError: unknownClientFailure,
105
+ WorkerUnknownError: unknownClientFailure
106
+ };
107
+ const classifyRpcClientError = (error) => {
108
+ const reason = error.reason;
109
+ if (reason._tag !== "HttpError")
110
+ return reasonClassification[reason._tag];
111
+ if (reason.kind !== "StatusCodeError")
112
+ return httpClassification[reason.kind];
113
+ // Effect's serializable HttpError keeps the concrete StatusCodeError in
114
+ // `cause`. The wrapper has no separate status field, so a hand-built wrapper
115
+ // without that cause cannot safely be classified as retryable and falls back
116
+ // to the client class.
117
+ const status = statusFrom(reason.cause);
118
+ return status !== undefined && status >= 500 && status <= 599
119
+ ? serverHttpFailure
120
+ : clientHttpFailure;
121
+ };
122
+ const isRpcClientError = Schema.is(RpcClientError.RpcClientError);
123
+ const classify = (error) => {
124
+ if (Schema.isSchemaError(error))
125
+ return responseDecoding;
126
+ if (isRpcClientError(error))
127
+ return classifyRpcClientError(error);
128
+ return unknownClientFailure;
129
+ };
130
+ // Preserve the operation-specific control failures from the RPC schema while
131
+ // replacing transport and decoding failures with the public TransportError.
132
+ const normalizedFailure = (cause) => {
133
+ const failure = Cause.findError(cause);
134
+ if (Result.isSuccess(failure)) {
135
+ return Effect.fail(isControlError(failure.success)
136
+ ? failure.success
137
+ : transportError(failure.success, classify(failure.success)));
138
+ }
139
+ const defect = Cause.findDefect(cause);
140
+ // A cause with neither a failure nor a defect is an interruption, and an
141
+ // operator's own cancellation is not the server failing. It is re-raised
142
+ // exactly as it arrived rather than described as a transport failure.
143
+ /* v8 ignore next 2 -- the fiber propagates an interrupt-only cause without reaching this operator */
144
+ return Result.isSuccess(defect)
145
+ ? Effect.fail(transportError(defect.success, classify(defect.success)))
146
+ : Effect.failCause(cause);
147
+ };
148
+ const normalize = (effect) => Effect.catchCause(effect, normalizedFailure);
149
+ const encoder = (schema) =>
150
+ // Every request schema in this module is service-free. `Schema.Top` erases
151
+ // that fact to `unknown`, so restore it at this one construction boundary.
152
+ Schema.encodeUnknownEffect(Schema.toCodecJson(schema));
153
+ const planEncoder = encoder(PlanInputSchema);
154
+ const runEncoder = encoder(RunInputSchema);
155
+ const approvalEncoder = encoder(ApprovalInputSchema);
156
+ const steerEncoder = encoder(SteerInputSchema);
157
+ const signalEncoder = encoder(SignalInputSchema);
158
+ const cancelEncoder = encoder(CancelInputSchema);
159
+ const resumeEncoder = encoder(ResumeInputSchema);
160
+ const listEncoder = encoder(ListRequest);
161
+ const watchEncoder = encoder(WatchFilter);
162
+ const normalizeRequest = (encode, input, request) => encode(input).pipe(Effect.mapError((cause) => transportError(cause, requestEncoding)), Effect.andThen(Effect.suspend(() => normalize(request()))));
163
+ const normalizeStream = (stream) => Stream.catchCause(stream, (cause) => Stream.fromEffect(normalizedFailure(cause)));
164
+ const normalizeStreamRequest = (encode, input, request) => Stream.unwrap(encode(input).pipe(Effect.mapError((cause) => transportError(cause, requestEncoding)), Effect.map(() => normalizeStream(request()))));
165
+ /**
166
+ * Provides `Control` through an RPC client while preserving the local vtable.
167
+ *
168
+ * @category layers
169
+ * @since 0.1.0
170
+ */
171
+ export const layer = (config) => {
172
+ const http = RpcClient.layerProtocolHttp({
173
+ url: config.url,
174
+ transformClient: (client) => {
175
+ // The RPC protocol already admits HttpClientError, but transformClient's
176
+ // generic signature cannot express that filtering adds the same error
177
+ // its input client already carries.
178
+ const checked = HttpClient.filterStatusOk(client);
179
+ return config.credential === undefined
180
+ ? checked
181
+ : HttpClient.mapRequest(checked, HttpClientRequest.bearerToken(config.credential));
182
+ }
183
+ });
184
+ const websocket = RpcClient.layerProtocolSocket();
185
+ return Layer.effect(Control, Effect.gen(function* () {
186
+ // Built into the layer's own scope: `Effect.provide(layer)` would close
187
+ // each protocol as soon as the client was constructed.
188
+ const httpServices = yield* Layer.build(http);
189
+ const websocketServices = yield* Layer.build(websocket);
190
+ const unary = yield* RpcClient.make(ControlRpcs).pipe(Effect.provide(httpServices));
191
+ const streaming = yield* RpcClient.make(ControlRpcs).pipe(Effect.provide(websocketServices));
192
+ return make({
193
+ plan: Effect.fn("Control.plan")((input) => normalizeRequest(planEncoder, input, () => unary.Plan(input))),
194
+ run: Effect.fn("Control.run")((input) => normalizeRequest(runEncoder, input, () => unary.Run(input))),
195
+ // RPC authenticates with this client's credential and does not carry
196
+ // local attribution. Refuse here before an agent becomes that operator.
197
+ approve: Effect.fn("Control.approve")((input) => normalizeRequest(approvalEncoder, input, () => input.principal?.kind === "agent"
198
+ ? Effect.fail(new Unauthorized({ message: "Approval decisions are operator-only" }))
199
+ : unary.Approve(input))),
200
+ deny: Effect.fn("Control.deny")((input) => normalizeRequest(approvalEncoder, input, () => input.principal?.kind === "agent"
201
+ ? Effect.fail(new Unauthorized({ message: "Approval decisions are operator-only" }))
202
+ : unary.Deny(input))),
203
+ steer: Effect.fn("Control.steer")((input) => normalizeRequest(steerEncoder, input, () => unary.Steer(input))),
204
+ signal: Effect.fn("Control.signal")((input) => normalizeRequest(signalEncoder, input, () => unary.Signal(input))),
205
+ cancel: Effect.fn("Control.cancel")((input) => normalizeRequest(cancelEncoder, input, () => unary.Cancel(input))),
206
+ resume: Effect.fn("Control.resume")((input) => normalizeRequest(resumeEncoder, input, () => unary.Resume(input))),
207
+ list: Effect.fn("Control.list")((input) => normalizeRequest(listEncoder, input, () => unary.List(input))),
208
+ // `watch` is the only procedure on the socket protocol, and the
209
+ // socket is why `credential` cannot protect it: a browser's WebSocket
210
+ // upgrade takes no headers, so the bearer token that authenticates
211
+ // every unary call above never reaches this stream. Credentialed
212
+ // deployments front the socket or use the HTTP protocol for watch.
213
+ watch: (input) => normalizeStreamRequest(watchEncoder, input, () => streaming.Watch(input))
214
+ });
215
+ }));
216
+ };
217
+ //# sourceMappingURL=ControlClient.js.map