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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/LICENSE +21 -0
  3. package/README.md +168 -2
  4. package/dist/cjs/ApprovalAuthority.d.ts +73 -0
  5. package/dist/cjs/ApprovalAuthority.d.ts.map +1 -0
  6. package/dist/cjs/ApprovalAuthority.js +62 -0
  7. package/dist/cjs/ApprovalAuthority.js.map +7 -0
  8. package/dist/cjs/Cancellation.d.ts +107 -0
  9. package/dist/cjs/Cancellation.d.ts.map +1 -0
  10. package/dist/cjs/Cancellation.js +72 -0
  11. package/dist/cjs/Cancellation.js.map +7 -0
  12. package/dist/cjs/Channels.d.ts +170 -0
  13. package/dist/cjs/Channels.d.ts.map +1 -0
  14. package/dist/cjs/Channels.js +278 -0
  15. package/dist/cjs/Channels.js.map +7 -0
  16. package/dist/cjs/Control.d.ts +202 -0
  17. package/dist/cjs/Control.d.ts.map +1 -0
  18. package/dist/cjs/Control.js +47 -0
  19. package/dist/cjs/Control.js.map +7 -0
  20. package/dist/cjs/ControlClient.d.ts +52 -0
  21. package/dist/cjs/ControlClient.d.ts.map +1 -0
  22. package/dist/cjs/ControlClient.js +191 -0
  23. package/dist/cjs/ControlClient.js.map +7 -0
  24. package/dist/cjs/ControlError.d.ts +318 -0
  25. package/dist/cjs/ControlError.d.ts.map +1 -0
  26. package/dist/cjs/ControlError.js +249 -0
  27. package/dist/cjs/ControlError.js.map +7 -0
  28. package/dist/cjs/ControlExecutor.d.ts +372 -0
  29. package/dist/cjs/ControlExecutor.d.ts.map +1 -0
  30. package/dist/cjs/ControlExecutor.js +123 -0
  31. package/dist/cjs/ControlExecutor.js.map +7 -0
  32. package/dist/cjs/ControlFacts.d.ts +454 -0
  33. package/dist/cjs/ControlFacts.d.ts.map +1 -0
  34. package/dist/cjs/ControlFacts.js +261 -0
  35. package/dist/cjs/ControlFacts.js.map +7 -0
  36. package/dist/cjs/ControlLive.d.ts +23 -0
  37. package/dist/cjs/ControlLive.d.ts.map +1 -0
  38. package/dist/cjs/ControlLive.js +1293 -0
  39. package/dist/cjs/ControlLive.js.map +7 -0
  40. package/dist/cjs/ControlRpcs.d.ts +1204 -0
  41. package/dist/cjs/ControlRpcs.d.ts.map +1 -0
  42. package/dist/cjs/ControlRpcs.js +247 -0
  43. package/dist/cjs/ControlRpcs.js.map +7 -0
  44. package/dist/cjs/ControlRuntime.d.ts +635 -0
  45. package/dist/cjs/ControlRuntime.d.ts.map +1 -0
  46. package/dist/cjs/ControlRuntime.js +744 -0
  47. package/dist/cjs/ControlRuntime.js.map +7 -0
  48. package/dist/cjs/ControlSchema.d.ts +2642 -0
  49. package/dist/cjs/ControlSchema.d.ts.map +1 -0
  50. package/dist/cjs/ControlSchema.js +634 -0
  51. package/dist/cjs/ControlSchema.js.map +7 -0
  52. package/dist/cjs/ControlServer.d.ts +51 -0
  53. package/dist/cjs/ControlServer.d.ts.map +1 -0
  54. package/dist/cjs/ControlServer.js +121 -0
  55. package/dist/cjs/ControlServer.js.map +7 -0
  56. package/dist/cjs/Credential.d.ts +136 -0
  57. package/dist/cjs/Credential.d.ts.map +1 -0
  58. package/dist/cjs/Credential.js +168 -0
  59. package/dist/cjs/Credential.js.map +7 -0
  60. package/dist/cjs/CredentialCipher.d.ts +90 -0
  61. package/dist/cjs/CredentialCipher.d.ts.map +1 -0
  62. package/dist/cjs/CredentialCipher.js +45 -0
  63. package/dist/cjs/CredentialCipher.js.map +7 -0
  64. package/dist/cjs/CredentialStore.d.ts +97 -0
  65. package/dist/cjs/CredentialStore.d.ts.map +1 -0
  66. package/dist/cjs/CredentialStore.js +81 -0
  67. package/dist/cjs/CredentialStore.js.map +7 -0
  68. package/dist/cjs/DispatchReader.d.ts +112 -0
  69. package/dist/cjs/DispatchReader.d.ts.map +1 -0
  70. package/dist/cjs/DispatchReader.js +45 -0
  71. package/dist/cjs/DispatchReader.js.map +7 -0
  72. package/dist/cjs/Health.d.ts +333 -0
  73. package/dist/cjs/Health.d.ts.map +1 -0
  74. package/dist/cjs/Health.js +311 -0
  75. package/dist/cjs/Health.js.map +7 -0
  76. package/dist/cjs/JevSessionChecker.d.ts +57 -0
  77. package/dist/cjs/JevSessionChecker.d.ts.map +1 -0
  78. package/dist/cjs/JevSessionChecker.js +113 -0
  79. package/dist/cjs/JevSessionChecker.js.map +7 -0
  80. package/dist/cjs/Lineage.d.ts +131 -0
  81. package/dist/cjs/Lineage.d.ts.map +1 -0
  82. package/dist/cjs/Lineage.js +81 -0
  83. package/dist/cjs/Lineage.js.map +7 -0
  84. package/dist/cjs/Migrations.d.ts +34 -0
  85. package/dist/cjs/Migrations.d.ts.map +1 -0
  86. package/dist/cjs/Migrations.js +60 -0
  87. package/dist/cjs/Migrations.js.map +7 -0
  88. package/dist/cjs/Monitor.d.ts +282 -0
  89. package/dist/cjs/Monitor.d.ts.map +1 -0
  90. package/dist/cjs/Monitor.js +283 -0
  91. package/dist/cjs/Monitor.js.map +7 -0
  92. package/dist/cjs/ScopedToken.d.ts +193 -0
  93. package/dist/cjs/ScopedToken.d.ts.map +1 -0
  94. package/dist/cjs/ScopedToken.js +135 -0
  95. package/dist/cjs/ScopedToken.js.map +7 -0
  96. package/dist/cjs/SqlControlRuntime.d.ts +161 -0
  97. package/dist/cjs/SqlControlRuntime.d.ts.map +1 -0
  98. package/dist/cjs/SqlControlRuntime.js +1522 -0
  99. package/dist/cjs/SqlControlRuntime.js.map +7 -0
  100. package/dist/cjs/SqlCredentialStore.d.ts +43 -0
  101. package/dist/cjs/SqlCredentialStore.d.ts.map +1 -0
  102. package/dist/cjs/SqlCredentialStore.js +113 -0
  103. package/dist/cjs/SqlCredentialStore.js.map +7 -0
  104. package/dist/cjs/Steering.d.ts +69 -0
  105. package/dist/cjs/Steering.d.ts.map +1 -0
  106. package/dist/cjs/Steering.js +49 -0
  107. package/dist/cjs/Steering.js.map +7 -0
  108. package/dist/cjs/SystemFlows.d.ts +223 -0
  109. package/dist/cjs/SystemFlows.d.ts.map +1 -0
  110. package/dist/cjs/SystemFlows.js +195 -0
  111. package/dist/cjs/SystemFlows.js.map +7 -0
  112. package/dist/cjs/WebCryptoCipher.d.ts +49 -0
  113. package/dist/cjs/WebCryptoCipher.d.ts.map +1 -0
  114. package/dist/cjs/WebCryptoCipher.js +129 -0
  115. package/dist/cjs/WebCryptoCipher.js.map +7 -0
  116. package/dist/cjs/WebhookChannel.d.ts +113 -0
  117. package/dist/cjs/WebhookChannel.d.ts.map +1 -0
  118. package/dist/cjs/WebhookChannel.js +98 -0
  119. package/dist/cjs/WebhookChannel.js.map +7 -0
  120. package/dist/cjs/index.d.ts +160 -0
  121. package/dist/cjs/index.d.ts.map +1 -0
  122. package/dist/cjs/index.js +91 -0
  123. package/dist/cjs/index.js.map +7 -0
  124. package/dist/cjs/internal/MutationBoundary.d.ts +27 -0
  125. package/dist/cjs/internal/MutationBoundary.d.ts.map +1 -0
  126. package/dist/cjs/internal/MutationBoundary.js +50 -0
  127. package/dist/cjs/internal/MutationBoundary.js.map +7 -0
  128. package/dist/cjs/internal/activeFibers.d.ts +12 -0
  129. package/dist/cjs/internal/activeFibers.d.ts.map +1 -0
  130. package/dist/cjs/internal/activeFibers.js +30 -0
  131. package/dist/cjs/internal/activeFibers.js.map +7 -0
  132. package/dist/cjs/internal/issues.d.ts +28 -0
  133. package/dist/cjs/internal/issues.d.ts.map +1 -0
  134. package/dist/cjs/internal/issues.js +34 -0
  135. package/dist/cjs/internal/issues.js.map +7 -0
  136. package/dist/cjs/internal/planning.d.ts +347 -0
  137. package/dist/cjs/internal/planning.d.ts.map +1 -0
  138. package/dist/cjs/internal/planning.js +137 -0
  139. package/dist/cjs/internal/planning.js.map +7 -0
  140. package/dist/cjs/internal/sqlSchemaErrors.d.ts +18 -0
  141. package/dist/cjs/internal/sqlSchemaErrors.d.ts.map +1 -0
  142. package/dist/cjs/internal/sqlSchemaErrors.js +40 -0
  143. package/dist/cjs/internal/sqlSchemaErrors.js.map +7 -0
  144. package/dist/cjs/migrations/0001_control_tables.d.ts +18 -0
  145. package/dist/cjs/migrations/0001_control_tables.d.ts.map +1 -0
  146. package/dist/cjs/migrations/0001_control_tables.js +115 -0
  147. package/dist/cjs/migrations/0001_control_tables.js.map +7 -0
  148. package/dist/cjs/migrations/0002_run_keys.d.ts +15 -0
  149. package/dist/cjs/migrations/0002_run_keys.d.ts.map +1 -0
  150. package/dist/cjs/migrations/0002_run_keys.js +44 -0
  151. package/dist/cjs/migrations/0002_run_keys.js.map +7 -0
  152. package/dist/cjs/migrations/0003_signal_commands.d.ts +13 -0
  153. package/dist/cjs/migrations/0003_signal_commands.d.ts.map +1 -0
  154. package/dist/cjs/migrations/0003_signal_commands.js +50 -0
  155. package/dist/cjs/migrations/0003_signal_commands.js.map +7 -0
  156. package/dist/cjs/migrations/0004_approval_decisions.d.ts +13 -0
  157. package/dist/cjs/migrations/0004_approval_decisions.d.ts.map +1 -0
  158. package/dist/cjs/migrations/0004_approval_decisions.js +45 -0
  159. package/dist/cjs/migrations/0004_approval_decisions.js.map +7 -0
  160. package/dist/cjs/migrations/0005_signal_principals.d.ts +18 -0
  161. package/dist/cjs/migrations/0005_signal_principals.d.ts.map +1 -0
  162. package/dist/cjs/migrations/0005_signal_principals.js +45 -0
  163. package/dist/cjs/migrations/0005_signal_principals.js.map +7 -0
  164. package/dist/cjs/migrations/0006_run_principals.d.ts +18 -0
  165. package/dist/cjs/migrations/0006_run_principals.d.ts.map +1 -0
  166. package/dist/cjs/migrations/0006_run_principals.js +49 -0
  167. package/dist/cjs/migrations/0006_run_principals.js.map +7 -0
  168. package/dist/cjs/migrations/0007_resume_consent.d.ts +18 -0
  169. package/dist/cjs/migrations/0007_resume_consent.d.ts.map +1 -0
  170. package/dist/cjs/migrations/0007_resume_consent.js +46 -0
  171. package/dist/cjs/migrations/0007_resume_consent.js.map +7 -0
  172. package/dist/cjs/package.json +1 -0
  173. package/dist/cjs/test/TestControl.d.ts +19 -0
  174. package/dist/cjs/test/TestControl.d.ts.map +1 -0
  175. package/dist/cjs/test/TestControl.js +62 -0
  176. package/dist/cjs/test/TestControl.js.map +7 -0
  177. package/dist/esm/ApprovalAuthority.d.ts +73 -0
  178. package/dist/esm/ApprovalAuthority.d.ts.map +1 -0
  179. package/dist/esm/ApprovalAuthority.js +72 -0
  180. package/dist/esm/ApprovalAuthority.js.map +1 -0
  181. package/dist/esm/Cancellation.d.ts +107 -0
  182. package/dist/esm/Cancellation.d.ts.map +1 -0
  183. package/dist/esm/Cancellation.js +116 -0
  184. package/dist/esm/Cancellation.js.map +1 -0
  185. package/dist/esm/Channels.d.ts +170 -0
  186. package/dist/esm/Channels.d.ts.map +1 -0
  187. package/dist/esm/Channels.js +312 -0
  188. package/dist/esm/Channels.js.map +1 -0
  189. package/dist/esm/Control.d.ts +202 -0
  190. package/dist/esm/Control.d.ts.map +1 -0
  191. package/dist/esm/Control.js +42 -0
  192. package/dist/esm/Control.js.map +1 -0
  193. package/dist/esm/ControlClient.d.ts +52 -0
  194. package/dist/esm/ControlClient.d.ts.map +1 -0
  195. package/dist/esm/ControlClient.js +217 -0
  196. package/dist/esm/ControlClient.js.map +1 -0
  197. package/dist/esm/ControlError.d.ts +318 -0
  198. package/dist/esm/ControlError.d.ts.map +1 -0
  199. package/dist/esm/ControlError.js +359 -0
  200. package/dist/esm/ControlError.js.map +1 -0
  201. package/dist/esm/ControlExecutor.d.ts +372 -0
  202. package/dist/esm/ControlExecutor.d.ts.map +1 -0
  203. package/dist/esm/ControlExecutor.js +212 -0
  204. package/dist/esm/ControlExecutor.js.map +1 -0
  205. package/dist/esm/ControlFacts.d.ts +454 -0
  206. package/dist/esm/ControlFacts.d.ts.map +1 -0
  207. package/dist/esm/ControlFacts.js +324 -0
  208. package/dist/esm/ControlFacts.js.map +1 -0
  209. package/dist/esm/ControlLive.d.ts +23 -0
  210. package/dist/esm/ControlLive.d.ts.map +1 -0
  211. package/dist/esm/ControlLive.js +1589 -0
  212. package/dist/esm/ControlLive.js.map +1 -0
  213. package/dist/esm/ControlRpcs.d.ts +1204 -0
  214. package/dist/esm/ControlRpcs.d.ts.map +1 -0
  215. package/dist/esm/ControlRpcs.js +299 -0
  216. package/dist/esm/ControlRpcs.js.map +1 -0
  217. package/dist/esm/ControlRuntime.d.ts +635 -0
  218. package/dist/esm/ControlRuntime.d.ts.map +1 -0
  219. package/dist/esm/ControlRuntime.js +808 -0
  220. package/dist/esm/ControlRuntime.js.map +1 -0
  221. package/dist/esm/ControlSchema.d.ts +2642 -0
  222. package/dist/esm/ControlSchema.d.ts.map +1 -0
  223. package/dist/esm/ControlSchema.js +1030 -0
  224. package/dist/esm/ControlSchema.js.map +1 -0
  225. package/dist/esm/ControlServer.d.ts +51 -0
  226. package/dist/esm/ControlServer.d.ts.map +1 -0
  227. package/dist/esm/ControlServer.js +145 -0
  228. package/dist/esm/ControlServer.js.map +1 -0
  229. package/dist/esm/Credential.d.ts +136 -0
  230. package/dist/esm/Credential.d.ts.map +1 -0
  231. package/dist/esm/Credential.js +190 -0
  232. package/dist/esm/Credential.js.map +1 -0
  233. package/dist/esm/CredentialCipher.d.ts +90 -0
  234. package/dist/esm/CredentialCipher.d.ts.map +1 -0
  235. package/dist/esm/CredentialCipher.js +56 -0
  236. package/dist/esm/CredentialCipher.js.map +1 -0
  237. package/dist/esm/CredentialStore.d.ts +97 -0
  238. package/dist/esm/CredentialStore.d.ts.map +1 -0
  239. package/dist/esm/CredentialStore.js +101 -0
  240. package/dist/esm/CredentialStore.js.map +1 -0
  241. package/dist/esm/DispatchReader.d.ts +112 -0
  242. package/dist/esm/DispatchReader.d.ts.map +1 -0
  243. package/dist/esm/DispatchReader.js +76 -0
  244. package/dist/esm/DispatchReader.js.map +1 -0
  245. package/dist/esm/Health.d.ts +333 -0
  246. package/dist/esm/Health.d.ts.map +1 -0
  247. package/dist/esm/Health.js +400 -0
  248. package/dist/esm/Health.js.map +1 -0
  249. package/dist/esm/JevSessionChecker.d.ts +57 -0
  250. package/dist/esm/JevSessionChecker.d.ts.map +1 -0
  251. package/dist/esm/JevSessionChecker.js +108 -0
  252. package/dist/esm/JevSessionChecker.js.map +1 -0
  253. package/dist/esm/Lineage.d.ts +131 -0
  254. package/dist/esm/Lineage.d.ts.map +1 -0
  255. package/dist/esm/Lineage.js +174 -0
  256. package/dist/esm/Lineage.js.map +1 -0
  257. package/dist/esm/Migrations.d.ts +34 -0
  258. package/dist/esm/Migrations.d.ts.map +1 -0
  259. package/dist/esm/Migrations.js +53 -0
  260. package/dist/esm/Migrations.js.map +1 -0
  261. package/dist/esm/Monitor.d.ts +282 -0
  262. package/dist/esm/Monitor.d.ts.map +1 -0
  263. package/dist/esm/Monitor.js +415 -0
  264. package/dist/esm/Monitor.js.map +1 -0
  265. package/dist/esm/ScopedToken.d.ts +193 -0
  266. package/dist/esm/ScopedToken.d.ts.map +1 -0
  267. package/dist/esm/ScopedToken.js +224 -0
  268. package/dist/esm/ScopedToken.js.map +1 -0
  269. package/dist/esm/SqlControlRuntime.d.ts +161 -0
  270. package/dist/esm/SqlControlRuntime.d.ts.map +1 -0
  271. package/dist/esm/SqlControlRuntime.js +1756 -0
  272. package/dist/esm/SqlControlRuntime.js.map +1 -0
  273. package/dist/esm/SqlCredentialStore.d.ts +43 -0
  274. package/dist/esm/SqlCredentialStore.d.ts.map +1 -0
  275. package/dist/esm/SqlCredentialStore.js +97 -0
  276. package/dist/esm/SqlCredentialStore.js.map +1 -0
  277. package/dist/esm/Steering.d.ts +69 -0
  278. package/dist/esm/Steering.d.ts.map +1 -0
  279. package/dist/esm/Steering.js +89 -0
  280. package/dist/esm/Steering.js.map +1 -0
  281. package/dist/esm/SystemFlows.d.ts +223 -0
  282. package/dist/esm/SystemFlows.d.ts.map +1 -0
  283. package/dist/esm/SystemFlows.js +198 -0
  284. package/dist/esm/SystemFlows.js.map +1 -0
  285. package/dist/esm/WebCryptoCipher.d.ts +49 -0
  286. package/dist/esm/WebCryptoCipher.d.ts.map +1 -0
  287. package/dist/esm/WebCryptoCipher.js +123 -0
  288. package/dist/esm/WebCryptoCipher.js.map +1 -0
  289. package/dist/esm/WebhookChannel.d.ts +113 -0
  290. package/dist/esm/WebhookChannel.d.ts.map +1 -0
  291. package/dist/esm/WebhookChannel.js +109 -0
  292. package/dist/esm/WebhookChannel.js.map +1 -0
  293. package/dist/esm/index.d.ts +160 -0
  294. package/dist/esm/index.d.ts.map +1 -0
  295. package/dist/esm/index.js +160 -0
  296. package/dist/esm/index.js.map +1 -0
  297. package/dist/esm/internal/MutationBoundary.d.ts +27 -0
  298. package/dist/esm/internal/MutationBoundary.d.ts.map +1 -0
  299. package/dist/esm/internal/MutationBoundary.js +40 -0
  300. package/dist/esm/internal/MutationBoundary.js.map +1 -0
  301. package/dist/esm/internal/activeFibers.d.ts +12 -0
  302. package/dist/esm/internal/activeFibers.d.ts.map +1 -0
  303. package/dist/esm/internal/activeFibers.js +17 -0
  304. package/dist/esm/internal/activeFibers.js.map +1 -0
  305. package/dist/esm/internal/issues.d.ts +28 -0
  306. package/dist/esm/internal/issues.d.ts.map +1 -0
  307. package/dist/esm/internal/issues.js +35 -0
  308. package/dist/esm/internal/issues.js.map +1 -0
  309. package/dist/esm/internal/planning.d.ts +347 -0
  310. package/dist/esm/internal/planning.d.ts.map +1 -0
  311. package/dist/esm/internal/planning.js +199 -0
  312. package/dist/esm/internal/planning.js.map +1 -0
  313. package/dist/esm/internal/sqlSchemaErrors.d.ts +18 -0
  314. package/dist/esm/internal/sqlSchemaErrors.d.ts.map +1 -0
  315. package/dist/esm/internal/sqlSchemaErrors.js +38 -0
  316. package/dist/esm/internal/sqlSchemaErrors.js.map +1 -0
  317. package/dist/esm/migrations/0001_control_tables.d.ts +18 -0
  318. package/dist/esm/migrations/0001_control_tables.d.ts.map +1 -0
  319. package/dist/esm/migrations/0001_control_tables.js +96 -0
  320. package/dist/esm/migrations/0001_control_tables.js.map +1 -0
  321. package/dist/esm/migrations/0002_run_keys.d.ts +15 -0
  322. package/dist/esm/migrations/0002_run_keys.d.ts.map +1 -0
  323. package/dist/esm/migrations/0002_run_keys.js +22 -0
  324. package/dist/esm/migrations/0002_run_keys.js.map +1 -0
  325. package/dist/esm/migrations/0003_signal_commands.d.ts +13 -0
  326. package/dist/esm/migrations/0003_signal_commands.d.ts.map +1 -0
  327. package/dist/esm/migrations/0003_signal_commands.js +26 -0
  328. package/dist/esm/migrations/0003_signal_commands.js.map +1 -0
  329. package/dist/esm/migrations/0004_approval_decisions.d.ts +13 -0
  330. package/dist/esm/migrations/0004_approval_decisions.d.ts.map +1 -0
  331. package/dist/esm/migrations/0004_approval_decisions.js +25 -0
  332. package/dist/esm/migrations/0004_approval_decisions.js.map +1 -0
  333. package/dist/esm/migrations/0005_signal_principals.d.ts +18 -0
  334. package/dist/esm/migrations/0005_signal_principals.d.ts.map +1 -0
  335. package/dist/esm/migrations/0005_signal_principals.js +27 -0
  336. package/dist/esm/migrations/0005_signal_principals.js.map +1 -0
  337. package/dist/esm/migrations/0006_run_principals.d.ts +18 -0
  338. package/dist/esm/migrations/0006_run_principals.d.ts.map +1 -0
  339. package/dist/esm/migrations/0006_run_principals.js +30 -0
  340. package/dist/esm/migrations/0006_run_principals.js.map +1 -0
  341. package/dist/esm/migrations/0007_resume_consent.d.ts +18 -0
  342. package/dist/esm/migrations/0007_resume_consent.d.ts.map +1 -0
  343. package/dist/esm/migrations/0007_resume_consent.js +27 -0
  344. package/dist/esm/migrations/0007_resume_consent.js.map +1 -0
  345. package/dist/esm/test/TestControl.d.ts +19 -0
  346. package/dist/esm/test/TestControl.d.ts.map +1 -0
  347. package/dist/esm/test/TestControl.js +30 -0
  348. package/dist/esm/test/TestControl.js.map +1 -0
  349. package/docs/README.md +189 -0
  350. package/docs/api.md +982 -0
  351. package/docs/concepts/authority.md +109 -0
  352. package/docs/concepts/cancellation.md +129 -0
  353. package/docs/concepts/lineage.md +132 -0
  354. package/docs/concepts/ownership.md +139 -0
  355. package/docs/concepts/projections.md +203 -0
  356. package/docs/concepts/receipts.md +128 -0
  357. package/docs/guides/approvals.md +284 -0
  358. package/docs/guides/cancel-and-resume.md +162 -0
  359. package/docs/guides/durable-storage.md +147 -0
  360. package/docs/guides/implement-an-executor.md +173 -0
  361. package/docs/guides/ingest-a-webhook.md +177 -0
  362. package/docs/guides/list-runs.md +160 -0
  363. package/docs/guides/monitor-runs.md +176 -0
  364. package/docs/guides/observe-health.md +147 -0
  365. package/docs/guides/postgres-tests.md +7 -0
  366. package/docs/guides/serve-over-rpc.md +220 -0
  367. package/docs/guides/signal-a-run.md +53 -0
  368. package/docs/guides/steer-a-run.md +138 -0
  369. package/docs/guides/store-credentials.md +164 -0
  370. package/docs/guides/testing.md +139 -0
  371. package/docs/guides/watch-a-run.md +154 -0
  372. package/docs/installation.md +106 -0
  373. package/docs/quickstart.md +163 -0
  374. package/docs/troubleshooting.md +208 -0
  375. package/package.json +405 -3
  376. package/src/ApprovalAuthority.ts +114 -0
  377. package/src/Cancellation.ts +172 -0
  378. package/src/Channels.ts +493 -0
  379. package/src/Control.ts +337 -0
  380. package/src/ControlClient.ts +319 -0
  381. package/src/ControlError.ts +378 -0
  382. package/src/ControlExecutor.ts +490 -0
  383. package/src/ControlFacts.ts +383 -0
  384. package/src/ControlLive.ts +2127 -0
  385. package/src/ControlRpcs.ts +443 -0
  386. package/src/ControlRuntime.ts +1601 -0
  387. package/src/ControlSchema.ts +1380 -0
  388. package/src/ControlServer.ts +182 -0
  389. package/src/Credential.ts +310 -0
  390. package/src/CredentialCipher.ts +110 -0
  391. package/src/CredentialStore.ts +152 -0
  392. package/src/DispatchReader.ts +122 -0
  393. package/src/Health.ts +591 -0
  394. package/src/JevSessionChecker.ts +127 -0
  395. package/src/Lineage.ts +203 -0
  396. package/src/Migrations.ts +56 -0
  397. package/src/Monitor.ts +600 -0
  398. package/src/ScopedToken.ts +306 -0
  399. package/src/SqlControlRuntime.ts +2478 -0
  400. package/src/SqlCredentialStore.ts +148 -0
  401. package/src/Steering.ts +96 -0
  402. package/src/SystemFlows.ts +225 -0
  403. package/src/WebCryptoCipher.ts +169 -0
  404. package/src/WebhookChannel.ts +166 -0
  405. package/src/index.ts +188 -0
  406. package/src/internal/MutationBoundary.ts +46 -0
  407. package/src/internal/activeFibers.ts +22 -0
  408. package/src/internal/issues.ts +40 -0
  409. package/src/internal/planning.ts +262 -0
  410. package/src/internal/sqlSchemaErrors.ts +37 -0
  411. package/src/migrations/0001_control_tables.ts +99 -0
  412. package/src/migrations/0002_run_keys.ts +23 -0
  413. package/src/migrations/0003_signal_commands.ts +27 -0
  414. package/src/migrations/0004_approval_decisions.ts +25 -0
  415. package/src/migrations/0005_signal_principals.ts +27 -0
  416. package/src/migrations/0006_run_principals.ts +31 -0
  417. package/src/migrations/0007_resume_consent.ts +28 -0
  418. package/src/test/TestControl.ts +47 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ControlSchema.js","sourceRoot":"","sources":["../../src/ControlSchema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Serializable control-plane values shared by local and RPC projections.\n *\n * @since 0.1.0\n */\n\nimport { EngineEvent, ExecutionFact } from \"@smthrs/journal\"\nimport { Attribution } from \"@smthrs/notifications/Notification\"\nimport * as SteerPayload from \"@smthrs/notifications/SteerPayload\"\nimport * as PersistedPlan from \"@smthrs/plan/Plan\"\nimport { BudgetOnExceeded, DiscoveryWarning } from \"@smthrs/registry/Descriptor\"\nimport { Schema } from \"effect\"\nimport { Origin } from \"./Lineage.ts\"\n\n/**\n * A durable control-plane run identifier.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunId = Schema.String\n\n/**\n * A durable control-plane run identifier.\n *\n * @since 0.1.0\n * @category models\n */\nexport type RunId = typeof RunId.Type\n\n/**\n * A registry flow identifier.\n *\n * @since 0.1.0\n * @category models\n */\nexport const FlowId = Schema.String\n\n/**\n * A registry flow identifier.\n *\n * @since 0.1.0\n * @category models\n */\nexport type FlowId = typeof FlowId.Type\n\n/**\n * A caller-supplied key that makes a control mutation idempotent.\n *\n * @since 0.1.0\n * @category models\n */\nexport const IdempotencyKey = Schema.String\n\n/**\n * A caller-supplied key that makes a control mutation idempotent.\n *\n * @since 0.1.0\n * @category models\n */\nexport type IdempotencyKey = typeof IdempotencyKey.Type\n\n/**\n * A server-authenticated identity stamped at the control boundary.\n *\n * @since 0.1.0\n * @category models\n */\nexport const Principal = Schema.Struct({\n id: Schema.String,\n kind: Schema.String,\n stampedAt: Schema.Number\n})\n\n/**\n * A server-authenticated identity stamped at the control boundary.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Principal = typeof Principal.Type\n\n/**\n * The capabilities, flows, budget, and placement approved for a plan.\n *\n * `budget` holds the run's approved ceilings: `tokens`, `milliseconds` of\n * active time, and `usd` in dollars, and its `deadline`: milliseconds of\n * wall-clock time counted from the run's first start, shared by every round\n * of the run. An absent ceiling or deadline is none.\n *\n * @since 0.1.0\n * @category models\n */\nexport const Envelope = Schema.Struct({\n capabilities: Schema.Array(Schema.String),\n /** Unrestricted builtin/addon/package imports, outside the guarded capability ceiling. */\n hostImports: Schema.optional(Schema.Array(Schema.String)),\n flows: Schema.Array(Schema.String),\n budget: Schema.Struct({\n tokens: Schema.optional(Schema.Number),\n milliseconds: Schema.optional(Schema.Number),\n usd: Schema.optional(Schema.Number),\n onExceeded: Schema.optional(BudgetOnExceeded),\n deadline: Schema.optional(Schema.Int.check(Schema.isGreaterThan(0)))\n }),\n host: Schema.optional(Schema.String)\n})\n\n/**\n * The capabilities, flows, budget, and placement approved for a plan.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Envelope = typeof Envelope.Type\n\n/**\n * The durability selected for an approval grant.\n *\n * @since 0.1.0\n * @category models\n */\nexport const GrantScope = Schema.Literals([\"once\", \"run\", \"remembered\"])\n\n/**\n * The durability selected for an approval grant.\n *\n * @since 0.1.0\n * @category models\n */\nexport type GrantScope = typeof GrantScope.Type\n\n/**\n * A plan or in-run approval target. The digest and full envelope are submitted\n * with the target so the server can verify exactly what the caller reviewed.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ApprovalTarget = Schema.Union([\n Schema.TaggedStruct(\"Plan\", {\n planId: Schema.String,\n digest: Schema.String,\n envelope: Envelope\n }),\n Schema.TaggedStruct(\"Node\", {\n runId: RunId,\n requestId: Schema.String,\n digest: Schema.String,\n envelope: Envelope\n })\n])\n\n/**\n * A plan or in-run approval target.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ApprovalTarget = typeof ApprovalTarget.Type\n\n/**\n * The complete, reviewable payload emitted by planning and submitted unchanged\n * when an approval decision is made.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ApprovalPayload = Schema.Struct({\n target: ApprovalTarget,\n scope: GrantScope,\n idempotencyKey: IdempotencyKey\n})\n\n/**\n * The complete, reviewable payload emitted by planning.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ApprovalPayload = typeof ApprovalPayload.Type\n\n/**\n * What `smithers plan` reports for one node before anything runs.\n *\n * The two outcomes fall out of step keys for free — a key either hits the\n * step cache or it does not — which is why they are reported here rather than\n * discovered during execution. The third outcome, `release`, belongs to\n * orphan reconciliation and is deliberately not part of a plan card.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanNodeStatus = Schema.Literals([\"cached\", \"run\"])\n\n/**\n * What `smithers plan` reports for one node before anything runs.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanNodeStatus = typeof PlanNodeStatus.Type\n\n/**\n * One keyed node of the plan an approval is being taken on.\n *\n * `key` is an `@smthrs/keys` `Key` produced by `@smthrs/plan`'s step-key\n * compiler, so a node named here and a node recorded in the persisted plan are\n * the same node. Ids are lookup addresses and are never hashed.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanNode = Schema.Struct({\n ...PersistedPlan.PlanNode.fields,\n status: PlanNodeStatus\n})\n\n/**\n * One keyed node of the plan an approval is being taken on.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanNode = typeof PlanNode.Type\n\n/**\n * Why one node of a plan waits for another.\n *\n * These are the reasons the two shipped graph builders already record.\n * `value` consumes an upstream result and `continuation` is the sequencing\n * edge of a builder or a branch arm, from both. `failure` is `@smthrs/flow`'s\n * recovery arm; `conflict` is the ordering edge `@smthrs/core`'s\n * write-conflict pass adds, and `lane-merge` orders laned writers with their\n * merge. A host reports the vocabulary of the builder it graphs with.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanEdgeReason = Schema.Literals([\"value\", \"continuation\", \"failure\", \"conflict\", \"lane-merge\"])\n\n/**\n * Why one node of a plan waits for another.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanEdgeReason = typeof PlanEdgeReason.Type\n\n/**\n * One labelled edge of the graph a plan was built from.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanEdge = Schema.Struct({\n from: Schema.NonEmptyString,\n to: Schema.NonEmptyString,\n reason: PlanEdgeReason\n})\n\n/**\n * One labelled edge of the graph a plan was built from.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanEdge = typeof PlanEdge.Type\n\n/**\n * One node of the built graph, as the reader of a plan drills into it.\n *\n * It carries the address and the declaration site, and nothing else: the\n * keyed node beside it (`PlanNode`) already says what the node is and what it\n * would do, and this is the one fact about it the key material deliberately\n * does not hold. `declaredAt` is the journal's own schema, so a plan card and\n * a run's records state a declaration site the same way and under the same\n * refusal of an absolute path; a host that cannot make a path relative to its\n * own root omits it.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanGraphNode = Schema.Struct({\n id: Schema.NonEmptyString,\n declaredAt: Schema.optionalKey(EngineEvent.DeclaredAt)\n})\n\n/**\n * One node of the built graph, as the reader of a plan drills into it.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanGraphNode = typeof PlanGraphNode.Type\n\n/**\n * The shape of the graph a plan was built from, for a reader that draws it.\n *\n * A `PlanNode` carries `dependsOn`, which is one unlabelled edge set: it\n * cannot tell a value dependency from a `catch` arm or from an ordering edge\n * a write conflict added. The graph builder knows which is which, so a host\n * that graphs a flow reports the reasons here rather than making every reader\n * guess them back.\n *\n * `nodes` is the same statement about provenance: the builder observed where\n * each node was declared and the key material deliberately does not carry it,\n * so it travels here, beside the edges and outside the digest. A host that\n * reports none is a host whose reader cannot open the code, not a host whose\n * plan is wrong.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanGraph = Schema.Struct({\n edges: Schema.Array(PlanEdge),\n nodes: Schema.optional(Schema.Array(PlanGraphNode)),\n /**\n * The revision of the workspace those declaration sites were read out of.\n *\n * A site is a path and a line, and neither says which bytes were there: a\n * host's working tree moves, so the same path after an edit or a branch\n * switch is a different file. This is the immutable name of the tree the\n * host loaded the flow from — a jj working-copy commit id, or a git commit\n * for a tree that still matches one — and a reader asks the content route\n * for the file AT this revision rather than for whatever is on disk now.\n *\n * A host that cannot name one reports nothing, and a reader that has\n * nothing shows no code at all rather than code it cannot bind (D-068).\n *\n * Exactly the forty lowercase hex digits the only producer emits\n * (`SourceRevision.objectId`), because the app puts this value straight\n * into a contents route's `?ref=` and a route that spawns jj or git from it\n * should never see anything else.\n */\n sourceRevision: Schema.optional(\n Schema.NonEmptyString.check(Schema.makeFilter((value) => /^[0-9a-f]{40}$/.test(value)))\n )\n})\n\n/**\n * The shape of the graph a plan was built from, for a reader that draws it.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanGraph = typeof PlanGraph.Type\n\n/**\n * The reviewable, signed payload returned by planning and resubmitted to\n * approval without reconstructing authority client-side.\n *\n * `nodes` is the keyed node graph the plan phase produced. It is part of the\n * card, and part of the digest an approval binds to, because \"approve this\n * flow with this input\" and \"approve this graph of keyed work\" are different\n * promises: a change that re-keys a node changes what will run, and an\n * approval taken against the old graph must not authorize the new one. A host\n * that has not built a graph reports an empty one and loses nothing.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanCard = Schema.Struct({\n planId: Schema.String,\n flowId: FlowId,\n digest: Schema.String,\n inputSummary: Schema.String,\n /** Discovery diagnostics for the selected flow; outside the approval identity. */\n warnings: Schema.optional(Schema.Array(DiscoveryWarning)),\n envelope: Envelope,\n deployClass: Schema.Boolean,\n /** Executable source/metadata identity supplied by a discovery-based host. */\n executionDigest: Schema.optional(Schema.String),\n plan: Schema.optional(PersistedPlan.Plan),\n nodes: Schema.Array(PlanNode),\n /**\n * The labelled edges of the graph this plan was built from, and where its\n * nodes were declared.\n *\n * Deliberately OUTSIDE the digest an approval binds to: the edges and the\n * declaration sites describe the plan a reader draws, and nothing here\n * changes what will run. The\n * persisted plan's own digest already covers keys, edges, effects,\n * conflicts, priorities and generations, so a host that starts reporting\n * this field re-plans to the digest it planned to before and every parked\n * approval still validates.\n */\n graph: Schema.optional(PlanGraph),\n approval: ApprovalPayload\n})\n\n/**\n * The reviewable, signed payload returned by planning and resubmitted to\n * approval without reconstructing authority client-side.\n *\n * @since 0.1.0\n * @category models\n */\nexport type PlanCard = typeof PlanCard.Type\n\n/**\n * Stable statuses projected for a durable run.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunStatus = Schema.Literals([\n \"accepted\",\n \"running\",\n \"parked\",\n \"waiting-approval\",\n \"cancelled\",\n \"completed\",\n \"failed\"\n])\n\n/**\n * Stable statuses projected for a durable run.\n *\n * @since 0.1.0\n * @category models\n */\nexport type RunStatus = typeof RunStatus.Type\n\n/**\n * How a run came to exist, when it did not start on its own.\n *\n * Defined by `@smthrs/control/Lineage` and re-exported here so a serializable\n * projection needs one import.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunOrigin = Origin\n\n/**\n * How a run came to exist, when it did not start on its own.\n *\n * @since 0.1.0\n * @category models\n */\nexport type RunOrigin = typeof RunOrigin.Type\n\n/**\n * Where a cancellation came from.\n *\n * `control` is an operator asking through this plane, and it is the only\n * source that can name a principal. `cascade` is a run swept up in an\n * ancestor's cancellation. `engine` is everything the runtime decided on its\n * own account: a lease expiry, a budget, a supervisor.\n *\n * @since 0.1.0\n * @category models\n */\nexport const CancelSource = Schema.Literals([\"control\", \"engine\", \"cascade\"])\n\n/**\n * Where a cancellation came from.\n *\n * @since 0.1.0\n * @category models\n */\nexport type CancelSource = typeof CancelSource.Type\n\n/**\n * Who cancelled a run, why, and on whose behalf.\n *\n * A durable cancellation is anonymous on its own: the run row records that\n * somebody asked and when, and nothing else. This is the attribution the\n * journal adds back. `principal` and `reason` are present exactly when a\n * request named them, which a cascade inherits from the request that started\n * it and an engine-decided cancellation never has.\n *\n * @since 0.1.0\n * @category models\n */\nexport const Cancellation = Schema.Struct({\n requestedAt: Schema.Number,\n source: CancelSource,\n principal: Schema.optional(Principal),\n reason: Schema.optional(Schema.String),\n /** The cancelled ancestor this run was swept up with, on a cascade. */\n cascadedFrom: Schema.optional(RunId)\n})\n\n/**\n * Who cancelled a run, why, and on whose behalf.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Cancellation = typeof Cancellation.Type\n\n/**\n * One open wait in a run tree that a person or named signal can end.\n *\n * A run that calls another flow parks the CHILD execution, not the run an\n * operator named. `run-3` of `coding/request` sat at `waiting-reason: event`\n * while the question a person owed an answer to — `coding-clarification` —\n * was parked three executions below it on `coding/PreparePlan`. Every reader\n * that asked the named run what it was waiting on was therefore told \"an\n * event\", which is true of that one row and false of the run tree: nothing\n * was going to arrive, because the run was waiting on a human.\n *\n * This is the wait as the ROOT of the tree reports it. `runId` is the\n * execution actually holding it, which is what a decision has to be routed\n * to; `token` is the durable wait address, submitted back unchanged;\n * `request` is what the wait declared about itself, which for a `HumanTask`\n * is `{kind, name, prompt, attempt, maxAttempts}`.\n *\n * @since 1.0.0\n * @category models\n */\nexport const PendingWait = Schema.Struct({\n /** The execution parked on this wait, which may be the root run itself. */\n runId: RunId,\n /** The flow that execution is running. */\n flowId: Schema.optional(FlowId),\n /** The supervisor vocabulary: `approval` for people or `event` for a named signal. */\n reason: Schema.String,\n /** The durable wait address a decision is routed to. */\n token: Schema.String,\n /** Digest used to join replayed display facts to this current operational address. */\n tokenDigest: Schema.optional(Schema.String),\n /** The wait point's own name, when the token addresses a named one. */\n name: Schema.optional(Schema.String),\n /** Which attempt of a re-asked question this is, counting from 1. */\n attempt: Schema.optional(Schema.Number),\n /** What the wait declared about itself, absent when it declared nothing. */\n request: Schema.optional(Schema.Json),\n /** When the execution holding this wait was created. */\n createdAt: Schema.Number\n})\n\n/**\n * One open wait in a run tree that a person or named signal can end.\n *\n * @since 1.0.0\n * @category models\n */\nexport type PendingWait = typeof PendingWait.Type\n\n/**\n * A compact summary for run listings and status projections.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunSummary = Schema.Struct({\n /** Whether lifecycle fields were observed in the engine or no engine row was visible. */\n executionObservation: Schema.optional(Schema.Literals([\"observed\", \"missing\"])),\n /** Exact native semantic observation; never a control-stream fact. */\n executionView: Schema.optional(ExecutionFact.View),\n runId: RunId,\n flowId: FlowId,\n status: RunStatus,\n planId: Schema.optional(Schema.String),\n planDigest: Schema.optional(Schema.String),\n /** The flow's executable identity when the run started; resume refuses a different one. */\n executionDigest: Schema.optional(Schema.String),\n /** The engine version that started the run. */\n engineVersion: Schema.optional(Schema.String),\n /**\n * How the code that would resume this run differs from the code it\n * recorded. Computed by an exact run lookup, never stored; absent when\n * nothing changed or the run is terminal.\n */\n codeDrift: Schema.optional(Schema.Struct({\n recorded: Schema.optional(Schema.String),\n current: Schema.optional(Schema.String),\n recordedEngine: Schema.optional(Schema.String),\n currentEngine: Schema.optional(Schema.String)\n })),\n ownerId: Schema.optional(Schema.String),\n /**\n * The authenticated principal that launched this run through the control\n * plane. A reader that does not see every run sees only the runs its own\n * principal launched. Absent on a run the engine created (a child, a fork,\n * a later trampoline round) and on a run launched before it was recorded;\n * only a reader that sees every run sees those.\n */\n launchedBy: Schema.optional(Schema.Struct({ id: Schema.String, kind: Schema.String })),\n /**\n * The run this one branched from: the spawning run, the forked-from run, or\n * the previous trampoline round. Absent on a run with no ancestor.\n */\n parentRunId: Schema.optional(RunId),\n /**\n * The trampoline lineage this run is a round of, and which round it is.\n * Both absent means a lineage of one, read as round 0 of itself.\n */\n lineageId: Schema.optional(Schema.String),\n roundOrdinal: Schema.optional(Schema.Number),\n origin: Schema.optional(RunOrigin),\n /**\n * What a parked run is holding on: `approval`, `event`, `timer`, `quota`, or\n * a reason a plugin declared. Absent on a run that is not parked, and on a\n * park whose owner released the run without declaring one.\n *\n * The CLI's `ps` and `status` listings also render `executor` here for a run\n * that has sat at `accepted` with no owner process past the launch handoff\n * window. That value is computed at render time and never stored, so a\n * reader going through the control RPC, the gateway projection, or a plugin\n * sees the field absent on the same run.\n */\n waitingReason: Schema.optional(Schema.String),\n /** What has been steered to this run and not yet delivered. */\n steering: Schema.optional(Schema.Struct({ pending: Schema.Number })),\n /**\n * A resume this run has been told to take and no host has taken up yet.\n *\n * A decision on an in-run approval restarts the run server-side, and the\n * process that decides is usually not the process that hosts the execution:\n * an operator's `smithers approve`, a gateway, a second CLI. The intent is\n * therefore recorded durably here, and the host that owns the execution\n * takes it up on its next tick and clears it. The number is the durable\n * sequence of the request, so an operator can tell a delegation that is\n * still outstanding from one that has been taken up. Absent means nothing\n * is waiting to be taken up.\n */\n pendingResume: Schema.optional(Schema.Number),\n /**\n * The executor claim this run was parked under.\n *\n * A parked execution releases its owner columns — that is what makes it\n * resumable at all — so after a park nothing on the row says which process\n * is hosting it. Every process that shares the databases can therefore see\n * the parked execution and resume it, including a short-lived `smithers\n * approve` that would drive the run and then exit. The fence the park was\n * written under is recorded here instead, so the host that parked the run\n * recognizes its own park and every other composition can tell that the\n * execution is not its to take up (triage B-15). Absent on a run that is not\n * parked, and on a park written by something that held no fence.\n */\n parkedBy: Schema.optional(Schema.String),\n /** Who cancelled this run, why, and on whose behalf. Absent until one did. */\n cancellation: Schema.optional(Cancellation),\n /**\n * Open human waits anywhere in this run's tree, nearest execution first.\n *\n * Present only when there is at least one, so a run nobody owes an answer\n * carries no field rather than an empty array. `status` rolls up with it:\n * a run any of whose descendants is parked on `approval` reports\n * `waiting-approval`, which is what the existing inbox filters select on.\n */\n pendingWaits: Schema.optional(Schema.Array(PendingWait)),\n /**\n * When the run's approved deadline passes: its `createdAt` plus the\n * envelope's `budget.deadline`, which is the instant the run is failed with\n * `deadline_exceeded` if it has not settled. Absent on a run approved with\n * no deadline.\n */\n deadlineAt: Schema.optional(Schema.Number),\n createdAt: Schema.Number,\n updatedAt: Schema.Number\n})\n\n/**\n * A compact summary for run listings and status projections.\n *\n * @since 0.1.0\n * @category models\n */\nexport type RunSummary = typeof RunSummary.Type\n\n/**\n * The bookkeeping every steer variant carries.\n *\n * `principal` stays here even though `CancelInput` argues a wire principal is\n * a client naming someone else, and the difference is who the callers are. A\n * cancel is only ever an operator command, so the server can be its sole\n * source of identity. A steer is not: `agent/send` steers a child run and\n * attributes the message to the parent flow, which is an identity no\n * authenticator knows and no operator issued. Dropping the field would erase\n * that attribution, so the field remains and `ControlServer` overwrites it\n * with the authenticated principal on every steer that arrives over RPC. An\n * in-process caller keeps naming its own.\n */\nconst steerEnvelope = {\n messageId: Schema.String,\n /**\n * The run this message is for. `Control.steer` refuses a message whose\n * `runId` disagrees with the one the call names: the notification would be\n * admitted to the call's run while the stored message claimed another, and an\n * operator reading it later would be told it belongs somewhere it was never\n * delivered.\n */\n runId: RunId,\n principal: Principal,\n // Producer labels are data, distinct from principal. Public RPC strips\n // these; a trusted product bridge may relay its already-authorized sender.\n attribution: Schema.optional(Attribution),\n /**\n * When the caller says it wrote the message. It is the caller's own\n * statement, recorded on `control.steer.enqueued` and never used to decide\n * anything. Over RPC the server's own clock is already on\n * `principal.stampedAt`, which is the time a decision may be replayed\n * against.\n */\n createdAt: Schema.Number\n}\n\n/**\n * An operator message inserted into the transcript at the next turn boundary.\n *\n * `kind` is optional here and required on every other variant, which is what\n * keeps a steer written before the vocabulary widened readable: a body and no\n * kind is a message, and always was.\n *\n * @since 0.1.0\n * @category models\n */\nexport const MessageSteer = Schema.Struct({\n ...steerEnvelope,\n kind: Schema.optional(Schema.Literal(\"Message\")),\n body: Schema.String\n})\n\n/**\n * A model-seat change that applies from the next turn on.\n *\n * @since 0.1.0\n * @category models\n */\nexport const SeatSteer = Schema.Struct({ ...steerEnvelope, ...SteerPayload.SeatPayload.fields })\n\n/**\n * A thinking-level change that applies from the next turn on.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ThinkingSteer = Schema.Struct({ ...steerEnvelope, ...SteerPayload.ThinkingPayload.fields })\n\n/**\n * Tools added to the active set for future turns.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ToolsSteer = Schema.Struct({ ...steerEnvelope, ...SteerPayload.ToolsPayload.fields })\n\n/**\n * A durable operator steer delivered at an execution turn boundary.\n *\n * An operator steers a run for four different reasons, and only one of them is\n * something to tell the model. Saying \"your seat changed\" would spend a turn on\n * bookkeeping; changing the seat is what was asked for. So the four are one\n * union rather than four free-text conventions the harness would have to\n * parse.\n *\n * @since 0.1.0\n * @category models\n */\nexport const SteerMessage = Schema.Union([MessageSteer, SeatSteer, ThinkingSteer, ToolsSteer])\n\n/**\n * A durable operator steer delivered at an execution turn boundary.\n *\n * @since 0.1.0\n * @category models\n */\nexport type SteerMessage = typeof SteerMessage.Type\n\n/**\n * The stored steering item one steer carries.\n *\n * The envelope — who asked, when, for which run — is control-plane\n * bookkeeping. What crosses into the notification queue is the item alone, in\n * the vocabulary `@smthrs/notifications` defines and the harness reads back.\n *\n * @param message the steer\n * @since 0.1.0\n * @category conversions\n */\nexport const steerItem = (message: SteerMessage): SteerPayload.SteerPayload => {\n switch (message.kind) {\n case undefined:\n case \"Message\":\n return { kind: \"Message\", body: message.body }\n case \"Seat\":\n return { kind: \"Seat\", seat: message.seat }\n case \"Thinking\":\n return { kind: \"Thinking\", thinking: message.thinking }\n case \"Tools\":\n return { kind: \"Tools\", toolNames: message.toolNames }\n }\n}\n\n/**\n * A durable, named signal delivered to a waiting run.\n *\n * @since 0.1.0\n * @category models\n */\nexport const SignalPayload = Schema.Struct({\n name: Schema.String,\n payload: Schema.Json\n})\n\n/**\n * A durable, named signal delivered to a waiting run.\n *\n * @since 0.1.0\n * @category models\n */\nexport type SignalPayload = typeof SignalPayload.Type\n\n/**\n * The RPC request schema for planning.\n *\n * The wire accepts JSON because an RPC request must be serializable. The local\n * `Control.PlanInput` keeps `input` as `unknown` so a runtime can decode its\n * flow's own input schema before anything crosses a transport.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PlanInputSchema = Schema.Struct({\n flowId: FlowId,\n input: Schema.Json,\n idempotencyKey: Schema.optional(IdempotencyKey),\n budget: Schema.optional(Envelope.fields.budget)\n})\n\n/**\n * The RPC request schema for starting a plan or resuming a run.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunInputSchema = Schema.Union([\n Schema.TaggedStruct(\"Plan\", {\n planId: Schema.String,\n digest: Schema.String,\n envelope: Envelope,\n idempotencyKey: IdempotencyKey\n }),\n Schema.TaggedStruct(\"Resume\", {\n runId: RunId,\n idempotencyKey: IdempotencyKey,\n allowCodeDrift: Schema.optional(Schema.Boolean)\n })\n])\n\n/**\n * The RPC request schema for an approval decision.\n *\n * The authenticated server supplies the principal, so a client cannot name a\n * different identity on the wire.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ApprovalInputSchema = ApprovalPayload\n\n/**\n * The RPC request schema for steering a run.\n *\n * @since 0.1.0\n * @category models\n */\nexport const SteerInputSchema = Schema.Struct({\n version: Schema.optional(Schema.Number),\n runId: RunId,\n message: SteerMessage,\n idempotencyKey: IdempotencyKey\n})\n\n/**\n * The RPC request schema for signaling a run.\n *\n * @since 0.1.0\n * @category models\n */\nexport const SignalInputSchema = Schema.Struct({\n runId: RunId,\n signal: SignalPayload,\n idempotencyKey: IdempotencyKey\n})\n\n/**\n * The shared fields of an RPC run mutation request.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RunMutationInputSchema = Schema.Struct({ runId: RunId, idempotencyKey: IdempotencyKey })\n\n/**\n * The RPC request schema for a lifecycle mutation that records a reason.\n *\n * The reason is on the wire because the server records it with the decision.\n * The principal is absent because the authenticated server stamps it.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ReasonedMutationInputSchema = Schema.Struct({\n ...RunMutationInputSchema.fields,\n reason: Schema.optional(Schema.String)\n})\n\n/**\n * The RPC request schema for cancellation.\n *\n * Cancellation currently has the same wire shape as every reasoned lifecycle\n * mutation. This named alias keeps the operation's public contract explicit.\n *\n * @since 0.1.0\n * @category models\n */\nexport const CancelInputSchema = ReasonedMutationInputSchema\n\n/**\n * The RPC request schema for resume: a reasoned mutation that may accept a\n * changed flow.\n *\n * @since 1.0.0\n * @category models\n */\nexport const ResumeInputSchema = Schema.Struct({\n ...ReasonedMutationInputSchema.fields,\n allowCodeDrift: Schema.optional(Schema.Boolean)\n})\n\n/**\n * A checkpoint in one journal entry's expansion. Without `offset`, the whole\n * entry is consumed. With it, only members through that zero-based index are\n * consumed. Pass the cursor back unchanged with the same run id.\n *\n * @since 0.1.0\n * @category models\n */\nexport const WatchCursor = Schema.Struct({\n sequence: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0), Schema.isLessThan(Number.MAX_SAFE_INTEGER)),\n offset: Schema.optional(\n Schema.Int.check(Schema.isGreaterThanOrEqualTo(0), Schema.isLessThan(Number.MAX_SAFE_INTEGER))\n )\n})\n\n/**\n * A checkpoint in one journal entry's expansion.\n *\n * @since 0.1.0\n * @category models\n */\nexport type WatchCursor = typeof WatchCursor.Type\n\n/**\n * A journal-projection cursor, optional run restriction, and delivery mode.\n * Omitting `follow` preserves the live-stream behavior; `false` requests a\n * finite snapshot of entries durable when the request is handled.\n *\n * @since 0.1.0\n * @category models\n */\nexport const WatchFilter = Schema.Struct({\n runId: Schema.optional(RunId),\n /** Resume after a fully consumed source entry, including all its deltas. Requires `runId`. */\n afterSequence: Schema.optional(Schema.Number),\n /** Resume after one emitted event, even inside an expansion. Requires `runId`. Cannot be combined with `afterSequence`. */\n afterCursor: Schema.optional(WatchCursor),\n follow: Schema.optional(Schema.Boolean)\n})\n\n/**\n * A resumable journal-projection watch cursor and optional run restriction.\n *\n * @since 0.1.0\n * @category models\n */\nexport type WatchFilter = typeof WatchFilter.Type\n\n/**\n * One ordered journal-projection delta streamed by `watch`.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ControlEvent = Schema.Struct({\n /** Present on `ControlLive.watch` events; absent on raw projections and older providers. */\n cursor: Schema.optional(WatchCursor),\n sequence: Schema.Number,\n kind: Schema.String,\n runId: Schema.optional(RunId),\n occurredAt: Schema.Number,\n payload: Schema.Json\n})\n\n/**\n * One ordered journal-projection delta streamed by `watch`.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ControlEvent = typeof ControlEvent.Type\n\n/**\n * How many items a listing returns when the caller names no `limit`.\n *\n * A listing with no bound returned the whole collection and paid one pending\n * steer query per run, so `smithers ps` on a busy project grew without bound.\n * A default is the smallest fix that keeps every caller working: a client that\n * wants more walks `nextCursor`.\n *\n * @since 0.1.0\n * @category models\n */\nexport const defaultPageSize = 100\n\n/**\n * The largest `limit` a listing accepts.\n *\n * The cap is the resource bound: a remote bearer holder cannot ask one request\n * to project an unbounded number of rows.\n *\n * @since 0.1.0\n * @category models\n */\nexport const maxPageSize = 500\n\n/**\n * A page size a listing can actually make progress on.\n *\n * `0`, a negative size, a fraction, `NaN`, and `Infinity` are all refused. A\n * zero-sized page used to answer `{ items: [], nextCursor: \"0\" }`, which is a\n * cursor a client loops on forever.\n *\n * @since 0.1.0\n * @category models\n */\nexport const PageLimit = Schema.Int.check(\n Schema.isGreaterThanOrEqualTo(1),\n Schema.isLessThanOrEqualTo(maxPageSize)\n)\n\n/**\n * How a claimed trigger occurrence ended.\n *\n * The same six words `@smthrs/triggers` records in its fire ledger. They are\n * declared here rather than imported because the triggers package depends on\n * this one (its scheduler launches runs through `Control`), so the vocabulary\n * has to live on the control side of that edge.\n *\n * @since 1.0.0\n * @category models\n */\nexport const FireOutcome = Schema.Literals([\"launched\", \"completed\", \"skipped\", \"buffered\", \"superseded\", \"failed\"])\n\n/**\n * How a claimed trigger occurrence ended.\n *\n * @since 1.0.0\n * @category models\n */\nexport type FireOutcome = typeof FireOutcome.Type\n\n/**\n * One registered trigger as a listing reports it.\n *\n * `nextOccurrencesMs` is the store clock's view of the next fires, computed at\n * read time, so an operator sees when a schedule will next run without\n * evaluating the cron expression client-side. `schedulerLastTickMs` is the\n * last poll the scheduler recorded; absent means no scheduler has ticked on\n * this host, so an enabled trigger is not going to fire. `activeRunId` names\n * the run the trigger is currently holding, and is absent while the trigger\n * holds a reservation rather than a launched run.\n *\n * @since 1.0.0\n * @category models\n */\nexport const TriggerSummary = Schema.Struct({\n triggerId: Schema.String,\n flowId: FlowId,\n input: Schema.Json,\n cron: Schema.String,\n timezone: Schema.optional(Schema.String),\n overlap: Schema.Literals([\"skip\", \"buffer-one\", \"supersede\"]),\n catchUp: Schema.Literals([\"none\", \"one\", \"all\"]),\n maxCatchUp: Schema.optional(Schema.Number),\n enabled: Schema.Boolean,\n revision: Schema.Number,\n lastFiredAtMs: Schema.optional(Schema.Number),\n pendingAtMs: Schema.optional(Schema.Number),\n activeRunId: Schema.optional(RunId),\n nextOccurrencesMs: Schema.Array(Schema.Number),\n schedulerLastTickMs: Schema.optional(Schema.Number)\n})\n\n/**\n * One registered trigger as a listing reports it.\n *\n * @since 1.0.0\n * @category models\n */\nexport type TriggerSummary = typeof TriggerSummary.Type\n\n/**\n * One claimed trigger occurrence and what became of it.\n *\n * `outcome` is `null` while the occurrence is claimed and not yet reported,\n * which is the window between a claim and its `recordResult`. `waiting` names\n * what a launched run is parked on when the ledger can see it.\n *\n * @since 1.0.0\n * @category models\n */\nexport const FireSummary = Schema.Struct({\n triggerId: Schema.String,\n occurrenceAtMs: Schema.Number,\n outcome: Schema.NullOr(FireOutcome),\n runId: Schema.optional(RunId),\n error: Schema.optional(Schema.String),\n waiting: Schema.optional(Schema.Literal(\"approval\"))\n})\n\n/**\n * One claimed trigger occurrence and what became of it.\n *\n * @since 1.0.0\n * @category models\n */\nexport type FireSummary = typeof FireSummary.Type\n\n/**\n * An operator's decision on a stored plan.\n *\n * @since 1.0.0\n * @category models\n */\nexport const PlanDecision = Schema.Literals([\"pending\", \"approved\", \"denied\"])\n\n/**\n * An operator's decision on a stored plan.\n *\n * @since 1.0.0\n * @category models\n */\nexport type PlanDecision = typeof PlanDecision.Type\n\n/**\n * One stored plan as a listing reports it: the card an approval submits\n * (`card.approval`), the decoded input it was planned with, and its decision.\n *\n * @since 1.0.0\n * @category models\n */\nexport const PlanSummary = Schema.Struct({\n card: PlanCard,\n input: Schema.Json,\n decision: PlanDecision\n})\n\n/**\n * One stored plan as a listing reports it.\n *\n * @since 1.0.0\n * @category models\n */\nexport type PlanSummary = typeof PlanSummary.Type\n\n/** Exact native observations, including unavailable evidence rather than a guessed lifecycle.\n * @category schemas\n * @since 1.0.0\n */\nexport const ExecutionBatch = Schema.Struct({\n source: Schema.NullOr(Schema.String),\n revision: Schema.NullOr(Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))),\n snapshots: Schema.Array(Schema.Union([\n Schema.TaggedStruct(\"Observed\", {\n executionId: RunId,\n source: Schema.String,\n revision: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n observation: ExecutionFact.Observation\n }),\n Schema.TaggedStruct(\"Missing\", {\n executionId: RunId,\n source: Schema.String,\n revision: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n deleted: Schema.Boolean\n }),\n Schema.TaggedStruct(\"Unavailable\", {\n executionId: RunId,\n reason: Schema.Literals([\"unsupported\", \"outside-run\", \"ancestry-unavailable\"])\n })\n ]))\n})\n/** Native execution observations with their source watermark.\n * @category models\n * @since 1.0.0\n */\nexport type ExecutionBatch = typeof ExecutionBatch.Type\n\n/**\n * A typed listing request for discovered flows, durable runs, registered\n * triggers, the trigger fire ledger, or stored plans.\n *\n * `plans` lists stored plans oldest first, narrowed by flow and decision, so an\n * operator can find what is waiting for approval: a build target declaring\n * `approval: \"required\"` leaves a pending `system/target` plan. Plans are an\n * operator's to read; a restricted reader lists none.\n *\n * `principalId` selects the runs whose `launchedBy.id` it names. It narrows a\n * listing; it is not an authorization boundary. The server restricts a reader\n * that does not see every run to the runs its own principal launched, whatever\n * filter it sends.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ListRequest = Schema.Union([\n Schema.TaggedStruct(\"executions\", {\n runId: RunId,\n executionIds: Schema.Array(Schema.NonEmptyString).check(Schema.isMaxLength(200))\n }),\n Schema.TaggedStruct(\"flows\", {\n filters: Schema.optional(Schema.Json),\n cursor: Schema.optional(Schema.String),\n limit: Schema.optional(PageLimit)\n }),\n Schema.TaggedStruct(\"runs\", {\n filters: Schema.optional(Schema.Struct({\n runId: Schema.optional(RunId),\n flowId: Schema.optional(FlowId),\n status: Schema.optional(RunStatus),\n terminal: Schema.optional(Schema.Boolean),\n principalId: Schema.optional(Schema.String),\n parentRunId: Schema.optional(RunId),\n lineageId: Schema.optional(Schema.String),\n /** Runs created at or after this epoch millisecond. */\n since: Schema.optional(Schema.Number),\n /** Runs created before this epoch millisecond. */\n until: Schema.optional(Schema.Number),\n /** Runs a fire of this trigger started. */\n triggerId: Schema.optional(Schema.String)\n })),\n /** Creation time, newest or oldest first; omitted preserves the historical listing order. */\n order: Schema.optional(Schema.Literals([\"newest\", \"oldest\"])),\n cursor: Schema.optional(Schema.String),\n limit: Schema.optional(PageLimit)\n }),\n Schema.TaggedStruct(\"triggers\", {\n filters: Schema.optional(Schema.Struct({\n triggerId: Schema.optional(Schema.String),\n flowId: Schema.optional(FlowId),\n enabled: Schema.optional(Schema.Boolean)\n })),\n cursor: Schema.optional(Schema.String),\n limit: Schema.optional(PageLimit)\n }),\n Schema.TaggedStruct(\"fires\", {\n filters: Schema.optional(Schema.Struct({\n triggerId: Schema.optional(Schema.String),\n runId: Schema.optional(RunId),\n outcome: Schema.optional(FireOutcome)\n })),\n cursor: Schema.optional(Schema.String),\n limit: Schema.optional(PageLimit)\n }),\n Schema.TaggedStruct(\"plans\", {\n filters: Schema.optional(Schema.Struct({\n flowId: Schema.optional(FlowId),\n decision: Schema.optional(PlanDecision)\n })),\n cursor: Schema.optional(Schema.String),\n limit: Schema.optional(PageLimit)\n })\n])\n\n/**\n * A typed listing request for discovered flows, durable runs, registered\n * triggers, the trigger fire ledger, or stored plans.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ListRequest = typeof ListRequest.Type\n\n/**\n * A typed page returned for a flow, run, trigger, fire, or plan listing.\n *\n * @since 0.1.0\n * @category models\n */\nexport const ListResponse = Schema.Union([\n Schema.TaggedStruct(\"executions\", {\n source: ExecutionBatch.fields.source,\n revision: ExecutionBatch.fields.revision,\n items: ExecutionBatch.fields.snapshots,\n nextCursor: Schema.optional(Schema.Never)\n }),\n Schema.TaggedStruct(\"flows\", {\n items: Schema.Array(\n Schema.Struct({ flowId: FlowId, description: Schema.String, inputSchema: Schema.optional(Schema.Json) })\n ),\n warnings: Schema.optional(Schema.Array(DiscoveryWarning)),\n nextCursor: Schema.optional(Schema.String)\n }),\n Schema.TaggedStruct(\"runs\", {\n items: Schema.Array(RunSummary),\n nextCursor: Schema.optional(Schema.String)\n }),\n Schema.TaggedStruct(\"triggers\", {\n items: Schema.Array(TriggerSummary),\n nextCursor: Schema.optional(Schema.String)\n }),\n Schema.TaggedStruct(\"fires\", {\n items: Schema.Array(FireSummary),\n nextCursor: Schema.optional(Schema.String)\n }),\n Schema.TaggedStruct(\"plans\", {\n items: Schema.Array(PlanSummary),\n nextCursor: Schema.optional(Schema.String)\n })\n])\n\n/**\n * A typed page returned for a flow, run, trigger, fire, or plan listing.\n *\n * @since 0.1.0\n * @category models\n */\nexport type ListResponse = typeof ListResponse.Type\n\n/**\n * A live process that hosts a run: its machine and process id.\n *\n * @since 1.0.0\n * @category models\n */\nexport const RunHost = Schema.Struct({ hostId: Schema.String, pid: Schema.Number })\n\n/**\n * A live process that hosts a run: its machine and process id.\n *\n * @since 1.0.0\n * @category models\n */\nexport type RunHost = typeof RunHost.Type\n\n/**\n * The idempotent outcome returned by every control mutation.\n *\n * An `Accepted` resume with `handedTo` was not claimed by the caller: the live\n * process that parked the run takes it up and drives it.\n *\n * @since 0.1.0\n * @category models\n */\nexport const Receipt = Schema.Union([\n Schema.TaggedStruct(\"Accepted\", {\n inputConsumed: Schema.optional(Schema.Boolean),\n inputBody: Schema.optional(Schema.String),\n receiptId: Schema.String,\n runId: Schema.optional(RunId),\n handedTo: Schema.optional(RunHost)\n }),\n Schema.TaggedStruct(\"AlreadyApplied\", {\n receiptId: Schema.String,\n runId: Schema.optional(RunId),\n inputConsumed: Schema.optional(Schema.Boolean),\n inputBody: Schema.optional(Schema.String)\n }),\n Schema.TaggedStruct(\"Parked\", {\n receiptId: Schema.String,\n planId: Schema.String,\n status: Schema.Literal(\"waiting-approval\")\n }),\n Schema.TaggedStruct(\"Conflict\", { message: Schema.String }),\n Schema.TaggedStruct(\"Terminal\", { runId: RunId, status: RunStatus })\n])\n\n/**\n * The idempotent outcome returned by every control mutation.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Receipt = typeof Receipt.Type\n"]}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * RPC server layers for the control service.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import { Cause, Effect, Layer } from "effect";
7
+ import { HttpRouter } from "effect/unstable/http";
8
+ import { RpcServer } from "effect/unstable/rpc";
9
+ import { Control } from "./Control.ts";
10
+ /**
11
+ * Logs the raw defect of a failed RPC handler on the server, and nothing for
12
+ * a typed failure or an interruption. `ControlRpcs.ControlDefect` sends
13
+ * clients only the designed sentence, so this log is where the detail lives.
14
+ * Pass it to `Effect.tapCause` or `Stream.tapCause` around a handler.
15
+ *
16
+ * @category logging
17
+ * @since 1.0.0
18
+ */
19
+ export declare const logDefect: (cause: Cause.Cause<unknown>) => Effect.Effect<void>;
20
+ /**
21
+ * Control RPC handlers delegating to the transport-independent service.
22
+ *
23
+ * Every mutation that records who asked reads `ControlPrincipal` and stamps
24
+ * it, rather than forwarding whatever the client sent. The identity the
25
+ * middleware authenticated is the only one the server can stand behind, and it
26
+ * is what reaches the journal, `RunSummary.cancellation`, and a steer's
27
+ * notification provenance.
28
+ *
29
+ * `List`, `Watch` and every run mutation read it too: a principal
30
+ * `ControlRpcs.RunVisibility` does not make an operator reads and mutates only
31
+ * the runs it launched; any other run answers `RunNotFound`.
32
+ *
33
+ * @category layers
34
+ * @since 0.1.0
35
+ */
36
+ export declare const layer: Layer.Layer<import("effect/unstable/rpc/Rpc").Handler<"Plan"> | import("effect/unstable/rpc/Rpc").Handler<"Run"> | import("effect/unstable/rpc/Rpc").Handler<"Approve"> | import("effect/unstable/rpc/Rpc").Handler<"Deny"> | import("effect/unstable/rpc/Rpc").Handler<"Steer"> | import("effect/unstable/rpc/Rpc").Handler<"Signal"> | import("effect/unstable/rpc/Rpc").Handler<"Cancel"> | import("effect/unstable/rpc/Rpc").Handler<"Resume"> | import("effect/unstable/rpc/Rpc").Handler<"List"> | import("effect/unstable/rpc/Rpc").Handler<"Watch">, never, Control>;
37
+ /**
38
+ * Mounts control RPC on the ambient `HttpRouter`: unary procedures over POST
39
+ * `/rpc` and the `watch` stream over WebSocket `/rpc/ws`. Both protocols are
40
+ * mounted together because `ControlClient` projects the same `Control` vtable
41
+ * across the two transports.
42
+ *
43
+ * A request carrying a browser `Origin` that does not match its `Host` is
44
+ * refused with 403 before authentication, so a page on another site cannot
45
+ * open the socket or post to `/rpc` with a credential a proxy attaches.
46
+ *
47
+ * @category layers
48
+ * @since 0.1.0
49
+ */
50
+ export declare const layerHttp: Layer.Layer<RpcServer.Protocol, never, Control | import("./ControlRpcs.ts").ControlAuth | import("effect/unstable/rpc/RpcSerialization").RpcSerialization | HttpRouter.HttpRouter>;
51
+ //# sourceMappingURL=ControlServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ControlServer.d.ts","sourceRoot":"","sources":["../../src/ControlServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAA;AACrD,OAAO,EAAE,UAAU,EAAyC,MAAM,sBAAsB,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAItC;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CACiB,CAAA;AAI3F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,KAAK,8iBAwEjB,CAAA;AAkDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,oLAGrB,CAAA"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * RPC server layers for the control service.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+ import { Cause, Effect, Layer, Stream } from "effect";
7
+ import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
8
+ import { RpcServer } from "effect/unstable/rpc";
9
+ import { Control } from "./Control.js";
10
+ import { Unauthorized } from "./ControlError.js";
11
+ import { ControlPrincipal, ControlRpcs, RunVisibility } from "./ControlRpcs.js";
12
+ /**
13
+ * Logs the raw defect of a failed RPC handler on the server, and nothing for
14
+ * a typed failure or an interruption. `ControlRpcs.ControlDefect` sends
15
+ * clients only the designed sentence, so this log is where the detail lives.
16
+ * Pass it to `Effect.tapCause` or `Stream.tapCause` around a handler.
17
+ *
18
+ * @category logging
19
+ * @since 1.0.0
20
+ */
21
+ export const logDefect = (cause) => Cause.hasDies(cause) ? Effect.logError("A control RPC handler died", cause) : Effect.void;
22
+ const logged = (effect) => Effect.tapCause(effect, logDefect);
23
+ /**
24
+ * Control RPC handlers delegating to the transport-independent service.
25
+ *
26
+ * Every mutation that records who asked reads `ControlPrincipal` and stamps
27
+ * it, rather than forwarding whatever the client sent. The identity the
28
+ * middleware authenticated is the only one the server can stand behind, and it
29
+ * is what reaches the journal, `RunSummary.cancellation`, and a steer's
30
+ * notification provenance.
31
+ *
32
+ * `List`, `Watch` and every run mutation read it too: a principal
33
+ * `ControlRpcs.RunVisibility` does not make an operator reads and mutates only
34
+ * the runs it launched; any other run answers `RunNotFound`.
35
+ *
36
+ * @category layers
37
+ * @since 0.1.0
38
+ */
39
+ export const layer = ControlRpcs.toLayer(Effect.gen(function* () {
40
+ const control = yield* Control;
41
+ // A reader that is not an operator is restricted to the runs its own
42
+ // principal launched. `reader` is not on the wire, so only this stamp sets
43
+ // it. The authentication middleware provides the rule with the principal.
44
+ const reader = Effect.gen(function* () {
45
+ const principal = yield* ControlPrincipal;
46
+ const visibility = yield* RunVisibility;
47
+ return visibility.seesAllRuns(principal) ? {} : { reader: principal };
48
+ });
49
+ return ControlRpcs.of({
50
+ Plan: Effect.fn("Control.plan")((input) => control.plan(input), logged),
51
+ Run: Effect.fn("Control.run")((input) => Effect.gen(function* () {
52
+ const principal = yield* ControlPrincipal;
53
+ return yield* control.run({ ...input, principal });
54
+ }), logged),
55
+ Approve: Effect.fn("Control.approve")((input) => Effect.gen(function* () {
56
+ const principal = yield* ControlPrincipal;
57
+ if (principal.id === "loopback" && principal.kind === "anonymous") {
58
+ return yield* new Unauthorized({ message: "An operator credential is required" });
59
+ }
60
+ return yield* control.approve({ ...input, principal });
61
+ }), logged),
62
+ Deny: Effect.fn("Control.deny")((input) => Effect.gen(function* () {
63
+ const principal = yield* ControlPrincipal;
64
+ if (principal.id === "loopback" && principal.kind === "anonymous") {
65
+ return yield* new Unauthorized({ message: "An operator credential is required" });
66
+ }
67
+ return yield* control.deny({ ...input, principal });
68
+ }), logged),
69
+ Steer: Effect.fn("Control.steer")((input) => Effect.gen(function* () {
70
+ const principal = yield* ControlPrincipal;
71
+ // A steer carries a principal on the wire because an in-process
72
+ // caller names one that is not an operator: `agent/send` attributes
73
+ // a child's steer to the parent flow. A remote client may not, so
74
+ // the authenticated identity replaces whatever arrived. It reaches
75
+ // the notification's `sourceActor` and the run transcript, which is
76
+ // exactly where a spoofed name would be read as truth.
77
+ const { attribution: _attribution, ...message } = input.message;
78
+ return yield* control.steer({ ...input, message: { ...message, principal }, ...yield* reader });
79
+ }), logged),
80
+ Signal: Effect.fn("Control.signal")((input) => Effect.gen(function* () {
81
+ const principal = yield* ControlPrincipal;
82
+ return yield* control.signal({ ...input, principal, ...yield* reader });
83
+ }), logged),
84
+ Cancel: Effect.fn("Control.cancel")((input) => Effect.gen(function* () {
85
+ const principal = yield* ControlPrincipal;
86
+ return yield* control.cancel({ ...input, principal, ...yield* reader });
87
+ }), logged),
88
+ Resume: Effect.fn("Control.resume")((input) => Effect.gen(function* () {
89
+ const principal = yield* ControlPrincipal;
90
+ return yield* control.resume({ ...input, principal, ...yield* reader });
91
+ }), logged),
92
+ List: Effect.fn("Control.list")((input) => Effect.flatMap(reader, (restriction) => control.list({ ...input, ...restriction })), logged),
93
+ Watch: (input) => Stream.tapCause(Stream.unwrap(Effect.map(reader, (restriction) => control.watch({ ...input, ...restriction }))), logDefect)
94
+ });
95
+ }));
96
+ /**
97
+ * Whether a request's `Origin` may reach the control mounts.
98
+ *
99
+ * Non-browser clients send no `Origin`. A browser always sends one, on POST
100
+ * and on the WebSocket upgrade, and a cross-site page cannot forge it. Refusing
101
+ * any `Origin` whose authority differs from `Host` stops a page on another site
102
+ * from riding a credential that a proxy or cookie attaches on the victim's
103
+ * behalf (cross-site WebSocket hijacking of the `Watch` stream).
104
+ */
105
+ const sameOrigin = (headers) => {
106
+ const origin = headers.origin;
107
+ if (origin === undefined)
108
+ return true;
109
+ const host = headers.host;
110
+ const parsed = URL.parse(origin);
111
+ return host !== undefined && parsed !== null &&
112
+ (parsed.protocol === "http:" || parsed.protocol === "https:") &&
113
+ parsed.origin === origin && parsed.host === host.toLowerCase();
114
+ };
115
+ /**
116
+ * Route middleware on the two control mounts only, so the router's own path
117
+ * matching decides what it guards, and a host's stricter global policy (the
118
+ * gateway's ingress) still answers first with its own typed refusal.
119
+ */
120
+ const originGuard = HttpRouter.middleware((httpEffect) => Effect.gen(function* () {
121
+ const request = yield* HttpServerRequest.HttpServerRequest;
122
+ if (sameOrigin(request.headers))
123
+ return yield* httpEffect;
124
+ return HttpServerResponse.text("The browser Origin must match the control server Host", { status: 403 });
125
+ })).layer;
126
+ const server = RpcServer.layer(ControlRpcs, {
127
+ disableFatalDefects: true
128
+ });
129
+ const http = server.pipe(Layer.provide(layer), Layer.provideMerge(RpcServer.layerProtocolHttp({ path: "/rpc" }).pipe(Layer.provide(originGuard))), Layer.fresh);
130
+ const websocket = server.pipe(Layer.provide(layer), Layer.provideMerge(RpcServer.layerProtocolWebsocket({ path: "/rpc/ws" }).pipe(Layer.provide(originGuard))), Layer.fresh);
131
+ /**
132
+ * Mounts control RPC on the ambient `HttpRouter`: unary procedures over POST
133
+ * `/rpc` and the `watch` stream over WebSocket `/rpc/ws`. Both protocols are
134
+ * mounted together because `ControlClient` projects the same `Control` vtable
135
+ * across the two transports.
136
+ *
137
+ * A request carrying a browser `Origin` that does not match its `Host` is
138
+ * refused with 403 before authentication, so a page on another site cannot
139
+ * open the socket or post to `/rpc` with a credential a proxy attaches.
140
+ *
141
+ * @category layers
142
+ * @since 0.1.0
143
+ */
144
+ export const layerHttp = Layer.mergeAll(http, websocket);
145
+ //# sourceMappingURL=ControlServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ControlServer.js","sourceRoot":"","sources":["../../src/ControlServer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC server layers for the control service.\n *\n * @since 0.1.0\n */\n\nimport { Cause, Effect, Layer, Stream } from \"effect\"\nimport { HttpRouter, HttpServerRequest, HttpServerResponse } from \"effect/unstable/http\"\nimport { RpcServer } from \"effect/unstable/rpc\"\nimport { Control } from \"./Control.ts\"\nimport { Unauthorized } from \"./ControlError.ts\"\nimport { ControlPrincipal, ControlRpcs, RunVisibility } from \"./ControlRpcs.ts\"\n\n/**\n * Logs the raw defect of a failed RPC handler on the server, and nothing for\n * a typed failure or an interruption. `ControlRpcs.ControlDefect` sends\n * clients only the designed sentence, so this log is where the detail lives.\n * Pass it to `Effect.tapCause` or `Stream.tapCause` around a handler.\n *\n * @category logging\n * @since 1.0.0\n */\nexport const logDefect = (cause: Cause.Cause<unknown>): Effect.Effect<void> =>\n Cause.hasDies(cause) ? Effect.logError(\"A control RPC handler died\", cause) : Effect.void\n\nconst logged = <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.tapCause(effect, logDefect)\n\n/**\n * Control RPC handlers delegating to the transport-independent service.\n *\n * Every mutation that records who asked reads `ControlPrincipal` and stamps\n * it, rather than forwarding whatever the client sent. The identity the\n * middleware authenticated is the only one the server can stand behind, and it\n * is what reaches the journal, `RunSummary.cancellation`, and a steer's\n * notification provenance.\n *\n * `List`, `Watch` and every run mutation read it too: a principal\n * `ControlRpcs.RunVisibility` does not make an operator reads and mutates only\n * the runs it launched; any other run answers `RunNotFound`.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer = ControlRpcs.toLayer(\n Effect.gen(function*() {\n const control = yield* Control\n // A reader that is not an operator is restricted to the runs its own\n // principal launched. `reader` is not on the wire, so only this stamp sets\n // it. The authentication middleware provides the rule with the principal.\n const reader = Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n const visibility = yield* RunVisibility\n return visibility.seesAllRuns(principal) ? {} : { reader: principal }\n })\n return ControlRpcs.of({\n Plan: Effect.fn(\"Control.plan\")((input) => control.plan(input), logged),\n Run: Effect.fn(\"Control.run\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n return yield* control.run({ ...input, principal })\n }), logged),\n Approve: Effect.fn(\"Control.approve\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n if (principal.id === \"loopback\" && principal.kind === \"anonymous\") {\n return yield* new Unauthorized({ message: \"An operator credential is required\" })\n }\n return yield* control.approve({ ...input, principal })\n }), logged),\n Deny: Effect.fn(\"Control.deny\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n if (principal.id === \"loopback\" && principal.kind === \"anonymous\") {\n return yield* new Unauthorized({ message: \"An operator credential is required\" })\n }\n return yield* control.deny({ ...input, principal })\n }), logged),\n Steer: Effect.fn(\"Control.steer\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n // A steer carries a principal on the wire because an in-process\n // caller names one that is not an operator: `agent/send` attributes\n // a child's steer to the parent flow. A remote client may not, so\n // the authenticated identity replaces whatever arrived. It reaches\n // the notification's `sourceActor` and the run transcript, which is\n // exactly where a spoofed name would be read as truth.\n const { attribution: _attribution, ...message } = input.message\n return yield* control.steer({ ...input, message: { ...message, principal }, ...yield* reader })\n }), logged),\n Signal: Effect.fn(\"Control.signal\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n return yield* control.signal({ ...input, principal, ...yield* reader })\n }), logged),\n Cancel: Effect.fn(\"Control.cancel\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n return yield* control.cancel({ ...input, principal, ...yield* reader })\n }), logged),\n Resume: Effect.fn(\"Control.resume\")((input) =>\n Effect.gen(function*() {\n const principal = yield* ControlPrincipal\n return yield* control.resume({ ...input, principal, ...yield* reader })\n }), logged),\n List: Effect.fn(\"Control.list\")(\n (input) => Effect.flatMap(reader, (restriction) => control.list({ ...input, ...restriction })),\n logged\n ),\n Watch: (input) =>\n Stream.tapCause(\n Stream.unwrap(Effect.map(reader, (restriction) => control.watch({ ...input, ...restriction }))),\n logDefect\n )\n })\n })\n)\n\n/**\n * Whether a request's `Origin` may reach the control mounts.\n *\n * Non-browser clients send no `Origin`. A browser always sends one, on POST\n * and on the WebSocket upgrade, and a cross-site page cannot forge it. Refusing\n * any `Origin` whose authority differs from `Host` stops a page on another site\n * from riding a credential that a proxy or cookie attaches on the victim's\n * behalf (cross-site WebSocket hijacking of the `Watch` stream).\n */\nconst sameOrigin = (headers: Readonly<Record<string, string>>): boolean => {\n const origin = headers.origin\n if (origin === undefined) return true\n const host = headers.host\n const parsed = URL.parse(origin)\n return host !== undefined && parsed !== null &&\n (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") &&\n parsed.origin === origin && parsed.host === host.toLowerCase()\n}\n\n/**\n * Route middleware on the two control mounts only, so the router's own path\n * matching decides what it guards, and a host's stricter global policy (the\n * gateway's ingress) still answers first with its own typed refusal.\n */\nconst originGuard = HttpRouter.middleware((httpEffect) =>\n Effect.gen(function*() {\n const request = yield* HttpServerRequest.HttpServerRequest\n if (sameOrigin(request.headers)) return yield* httpEffect\n return HttpServerResponse.text(\"The browser Origin must match the control server Host\", { status: 403 })\n })\n).layer\n\nconst server = RpcServer.layer(ControlRpcs, {\n disableFatalDefects: true\n})\n\nconst http = server.pipe(\n Layer.provide(layer),\n Layer.provideMerge(RpcServer.layerProtocolHttp({ path: \"/rpc\" }).pipe(Layer.provide(originGuard))),\n Layer.fresh\n)\n\nconst websocket = server.pipe(\n Layer.provide(layer),\n Layer.provideMerge(RpcServer.layerProtocolWebsocket({ path: \"/rpc/ws\" }).pipe(Layer.provide(originGuard))),\n Layer.fresh\n)\n\n/**\n * Mounts control RPC on the ambient `HttpRouter`: unary procedures over POST\n * `/rpc` and the `watch` stream over WebSocket `/rpc/ws`. Both protocols are\n * mounted together because `ControlClient` projects the same `Control` vtable\n * across the two transports.\n *\n * A request carrying a browser `Origin` that does not match its `Host` is\n * refused with 403 before authentication, so a page on another site cannot\n * open the socket or post to `/rpc` with a credential a proxy attaches.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layerHttp = Layer.mergeAll(\n http,\n websocket\n)\n"]}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Credential storage boundary.
3
+ *
4
+ * Credentials are capabilities. They must never enter flow input, plan
5
+ * digests, journal payloads, or model context, so only a {@link CredentialRef}
6
+ * — an id and a human-readable connection name — crosses the browser-safe
7
+ * contract. Plaintext exists in exactly two places: inside a `Redacted` handed
8
+ * to `create`/`rotate`, and inside the `Redacted` returned by `resolve`.
9
+ *
10
+ * The implementation composes two ports:
11
+ *
12
+ * - {@link CredentialStore} persists an opaque sealed record and enforces
13
+ * compare-and-set on writes, so concurrent rotations cannot interleave.
14
+ * `rotate` with `expected` extends that compare to the secret itself: the
15
+ * secret it checks and the version it writes over come from one read, so a
16
+ * writer that commits in between, in any process, is refused.
17
+ * - {@link CredentialCipher} seals and opens the secret under host-managed
18
+ * keys. `WebCryptoCipher` is the browser and Node adapter; a host with no
19
+ * secure key material fails with the typed `Unavailable`.
20
+ *
21
+ * Authorization is a host decision, injected as {@link Options.authorize}. A
22
+ * reference is also authenticated on every operation: caller-owned fields are
23
+ * snapshotted before policy effects run, and a caller cannot present a forged
24
+ * or stale `CredentialRef` because the snapshotted name must still match the
25
+ * stored record.
26
+ *
27
+ * @since 0.1.0
28
+ */
29
+ import { Context, Effect, Layer, Option, Redacted } from "effect";
30
+ import { CredentialConflict, InvalidInput, type PersistenceError, Unauthorized, Unavailable } from "./ControlError.ts";
31
+ import * as CredentialCipher from "./CredentialCipher.ts";
32
+ import * as CredentialStore from "./CredentialStore.ts";
33
+ /**
34
+ * A journal-safe name for a stored connection credential.
35
+ *
36
+ * @category models
37
+ * @since 0.1.0
38
+ */
39
+ export interface CredentialRef {
40
+ readonly id: string;
41
+ readonly name: string;
42
+ }
43
+ /**
44
+ * One credential operation, as seen by a host authorization policy.
45
+ *
46
+ * @category models
47
+ * @since 0.1.0
48
+ */
49
+ export type Operation = "list" | "get" | "create" | "resolve" | "rotate" | "revoke";
50
+ /**
51
+ * How {@link Credential.rotate} compares before it writes.
52
+ *
53
+ * @category models
54
+ * @since 1.0.0
55
+ */
56
+ export interface RotateOptions {
57
+ /** The secret the caller last saw; the rotation commits only over it. */
58
+ readonly expected?: Redacted.Redacted<string> | undefined;
59
+ }
60
+ /**
61
+ * Adapter-bound credential resolution. References are safe to list and
62
+ * persist; only `resolve` crosses into a secret-bearing adapter boundary.
63
+ *
64
+ * @category services
65
+ * @since 0.1.0
66
+ */
67
+ export interface Credential {
68
+ readonly list: () => Effect.Effect<ReadonlyArray<CredentialRef>, Unavailable | Unauthorized>;
69
+ readonly get: (id: string) => Effect.Effect<CredentialRef, Unavailable | Unauthorized>;
70
+ readonly create: (options: {
71
+ readonly id: string;
72
+ readonly name: string;
73
+ readonly secret: Redacted.Redacted<string>;
74
+ }) => Effect.Effect<CredentialRef, Unavailable | Unauthorized | CredentialConflict | InvalidInput>;
75
+ readonly resolve: (reference: CredentialRef) => Effect.Effect<Redacted.Redacted<string>, Unavailable | Unauthorized | PersistenceError>;
76
+ /**
77
+ * Replaces the secret. With `expected`, replaces it only while the stored
78
+ * secret still equals `expected`, and otherwise fails `CredentialConflict`
79
+ * at the stored version without writing.
80
+ */
81
+ readonly rotate: (reference: CredentialRef, secret: Redacted.Redacted<string>, options?: RotateOptions | undefined) => Effect.Effect<CredentialRef, Unavailable | Unauthorized | CredentialConflict | InvalidInput | PersistenceError>;
82
+ readonly revoke: (reference: CredentialRef) => Effect.Effect<void, Unavailable | Unauthorized>;
83
+ }
84
+ /**
85
+ * Service tag for credential resolution.
86
+ *
87
+ * @category services
88
+ * @since 0.1.0
89
+ */
90
+ export declare const Credential: Context.Service<Credential, Credential>;
91
+ /**
92
+ * A credential implementation that explicitly reports unavailable storage.
93
+ *
94
+ * @category constructors
95
+ * @since 0.1.0
96
+ */
97
+ export declare const makeNoop: () => Credential;
98
+ /**
99
+ * Layer for the unavailable credential-storage boundary.
100
+ *
101
+ * @category layers
102
+ * @since 0.1.0
103
+ */
104
+ export declare const layerNoop: Layer.Layer<Credential, never, never>;
105
+ /**
106
+ * The collaborators a working credential boundary needs.
107
+ *
108
+ * `authorize` is the host's policy hook. It defaults to allowing every
109
+ * operation, which is correct for a single-principal local process; a server
110
+ * composition supplies its own and gets typed `Unauthorized` failures for free.
111
+ *
112
+ * @category models
113
+ * @since 0.1.0
114
+ */
115
+ export interface Options {
116
+ readonly store: CredentialStore.Service;
117
+ readonly cipher: CredentialCipher.Service;
118
+ readonly authorize?: ((operation: Operation, reference: Option.Option<CredentialRef>) => Effect.Effect<void, Unauthorized>) | undefined;
119
+ }
120
+ /**
121
+ * Constructs a working credential boundary over a store and a cipher.
122
+ *
123
+ * @category constructors
124
+ * @since 0.1.0
125
+ */
126
+ export declare const make: (options: Options) => Credential;
127
+ /**
128
+ * Provides a working credential boundary over the ambient store and cipher.
129
+ *
130
+ * @category layers
131
+ * @since 0.1.0
132
+ */
133
+ export declare const layer: (options?: {
134
+ readonly authorize?: Options["authorize"];
135
+ }) => Layer.Layer<Credential, never, CredentialStore.CredentialStore | CredentialCipher.CredentialCipher>;
136
+ //# sourceMappingURL=Credential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Credential.d.ts","sourceRoot":"","sources":["../../src/Credential.ts"],"names":[],"mappings":"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"}