@smthrs/gateway 0.34.0 → 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 (605) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/LICENSE +1 -1
  3. package/README.md +92 -0
  4. package/dist/cjs/Diagnosis.d.ts +275 -0
  5. package/dist/cjs/Diagnosis.d.ts.map +1 -0
  6. package/dist/cjs/Diagnosis.js +476 -0
  7. package/dist/cjs/Diagnosis.js.map +7 -0
  8. package/dist/cjs/EngineTrace.d.ts +76 -0
  9. package/dist/cjs/EngineTrace.d.ts.map +1 -0
  10. package/dist/cjs/EngineTrace.js +501 -0
  11. package/dist/cjs/EngineTrace.js.map +7 -0
  12. package/dist/cjs/GatewayError.d.ts +54 -0
  13. package/dist/cjs/GatewayError.d.ts.map +1 -0
  14. package/dist/cjs/GatewayError.js +51 -0
  15. package/dist/cjs/GatewayError.js.map +7 -0
  16. package/dist/cjs/GatewayProjection.d.ts +480 -0
  17. package/dist/cjs/GatewayProjection.d.ts.map +1 -0
  18. package/dist/cjs/GatewayProjection.js +462 -0
  19. package/dist/cjs/GatewayProjection.js.map +7 -0
  20. package/dist/cjs/GatewayRpcs.d.ts +1886 -0
  21. package/dist/cjs/GatewayRpcs.d.ts.map +1 -0
  22. package/dist/cjs/GatewayRpcs.js +121 -0
  23. package/dist/cjs/GatewayRpcs.js.map +7 -0
  24. package/dist/cjs/GatewaySchema.d.ts +3274 -0
  25. package/dist/cjs/GatewaySchema.d.ts.map +1 -0
  26. package/dist/cjs/GatewaySchema.js +141 -0
  27. package/dist/cjs/GatewaySchema.js.map +7 -0
  28. package/dist/cjs/GatewayServer.d.ts +427 -0
  29. package/dist/cjs/GatewayServer.d.ts.map +1 -0
  30. package/dist/cjs/GatewayServer.js +428 -0
  31. package/dist/cjs/GatewayServer.js.map +7 -0
  32. package/dist/cjs/HostBranchPresence.d.ts +12 -0
  33. package/dist/cjs/HostBranchPresence.d.ts.map +1 -0
  34. package/dist/cjs/HostBranchPresence.js +82 -0
  35. package/dist/cjs/HostBranchPresence.js.map +7 -0
  36. package/dist/cjs/Projections.d.ts +209 -0
  37. package/dist/cjs/Projections.d.ts.map +1 -0
  38. package/dist/cjs/Projections.js +906 -0
  39. package/dist/cjs/Projections.js.map +7 -0
  40. package/dist/cjs/RunDevTools.d.ts +181 -0
  41. package/dist/cjs/RunDevTools.d.ts.map +1 -0
  42. package/dist/cjs/RunDevTools.js +195 -0
  43. package/dist/cjs/RunDevTools.js.map +7 -0
  44. package/dist/cjs/RunHistory.d.ts +185 -0
  45. package/dist/cjs/RunHistory.d.ts.map +1 -0
  46. package/dist/cjs/RunHistory.js +68 -0
  47. package/dist/cjs/RunHistory.js.map +7 -0
  48. package/dist/cjs/RunTrace.d.ts +753 -0
  49. package/dist/cjs/RunTrace.d.ts.map +1 -0
  50. package/dist/cjs/RunTrace.js +1593 -0
  51. package/dist/cjs/RunTrace.js.map +7 -0
  52. package/dist/cjs/RuntimeBridge.d.ts +1386 -0
  53. package/dist/cjs/RuntimeBridge.d.ts.map +1 -0
  54. package/dist/cjs/RuntimeBridge.js +598 -0
  55. package/dist/cjs/RuntimeBridge.js.map +7 -0
  56. package/dist/cjs/bun/BunGateway.d.ts +20 -0
  57. package/dist/cjs/bun/BunGateway.d.ts.map +1 -0
  58. package/dist/cjs/bun/BunGateway.js +62 -0
  59. package/dist/cjs/bun/BunGateway.js.map +7 -0
  60. package/dist/cjs/index.d.ts +65 -0
  61. package/dist/cjs/index.d.ts.map +1 -0
  62. package/dist/cjs/index.js +59 -0
  63. package/dist/cjs/index.js.map +7 -0
  64. package/dist/cjs/internal/NativeGateway.d.ts +176 -0
  65. package/dist/cjs/internal/NativeGateway.d.ts.map +1 -0
  66. package/dist/cjs/internal/NativeGateway.js +187 -0
  67. package/dist/cjs/internal/NativeGateway.js.map +7 -0
  68. package/dist/cjs/internal/actionRenderings.d.ts +2 -0
  69. package/dist/cjs/internal/actionRenderings.d.ts.map +1 -0
  70. package/dist/cjs/internal/actionRenderings.js +224 -0
  71. package/dist/cjs/internal/actionRenderings.js.map +7 -0
  72. package/dist/cjs/internal/callEvents.d.ts +97 -0
  73. package/dist/cjs/internal/callEvents.d.ts.map +1 -0
  74. package/dist/cjs/internal/callEvents.js +169 -0
  75. package/dist/cjs/internal/callEvents.js.map +7 -0
  76. package/dist/cjs/internal/digestIndex.d.ts +31 -0
  77. package/dist/cjs/internal/digestIndex.d.ts.map +1 -0
  78. package/dist/cjs/internal/digestIndex.js +105 -0
  79. package/dist/cjs/internal/digestIndex.js.map +7 -0
  80. package/dist/cjs/internal/digestMemory.d.ts +19 -0
  81. package/dist/cjs/internal/digestMemory.d.ts.map +1 -0
  82. package/dist/cjs/internal/digestMemory.js +33 -0
  83. package/dist/cjs/internal/digestMemory.js.map +7 -0
  84. package/dist/cjs/internal/inspectLabels.d.ts +8 -0
  85. package/dist/cjs/internal/inspectLabels.d.ts.map +1 -0
  86. package/dist/cjs/internal/inspectLabels.js +29 -0
  87. package/dist/cjs/internal/inspectLabels.js.map +7 -0
  88. package/dist/cjs/internal/nativeResolution.d.ts +41 -0
  89. package/dist/cjs/internal/nativeResolution.d.ts.map +1 -0
  90. package/dist/cjs/internal/nativeResolution.js +62 -0
  91. package/dist/cjs/internal/nativeResolution.js.map +7 -0
  92. package/dist/cjs/internal/nodeEvents.d.ts +47 -0
  93. package/dist/cjs/internal/nodeEvents.d.ts.map +1 -0
  94. package/dist/cjs/internal/nodeEvents.js +60 -0
  95. package/dist/cjs/internal/nodeEvents.js.map +7 -0
  96. package/dist/cjs/node/NodeGateway.d.ts +16 -0
  97. package/dist/cjs/node/NodeGateway.d.ts.map +1 -0
  98. package/dist/cjs/node/NodeGateway.js +48 -0
  99. package/dist/cjs/node/NodeGateway.js.map +7 -0
  100. package/dist/cjs/package.json +1 -0
  101. package/dist/esm/Diagnosis.d.ts +275 -0
  102. package/dist/esm/Diagnosis.d.ts.map +1 -0
  103. package/dist/esm/Diagnosis.js +697 -0
  104. package/dist/esm/Diagnosis.js.map +1 -0
  105. package/dist/esm/EngineTrace.d.ts +76 -0
  106. package/dist/esm/EngineTrace.d.ts.map +1 -0
  107. package/dist/esm/EngineTrace.js +548 -0
  108. package/dist/esm/EngineTrace.js.map +1 -0
  109. package/dist/esm/GatewayError.d.ts +54 -0
  110. package/dist/esm/GatewayError.d.ts.map +1 -0
  111. package/dist/esm/GatewayError.js +60 -0
  112. package/dist/esm/GatewayError.js.map +1 -0
  113. package/dist/esm/GatewayProjection.d.ts +480 -0
  114. package/dist/esm/GatewayProjection.d.ts.map +1 -0
  115. package/dist/esm/GatewayProjection.js +792 -0
  116. package/dist/esm/GatewayProjection.js.map +1 -0
  117. package/dist/esm/GatewayRpcs.d.ts +1886 -0
  118. package/dist/esm/GatewayRpcs.d.ts.map +1 -0
  119. package/dist/esm/GatewayRpcs.js +145 -0
  120. package/dist/esm/GatewayRpcs.js.map +1 -0
  121. package/dist/esm/GatewaySchema.d.ts +3274 -0
  122. package/dist/esm/GatewaySchema.d.ts.map +1 -0
  123. package/dist/esm/GatewaySchema.js +244 -0
  124. package/dist/esm/GatewaySchema.js.map +1 -0
  125. package/dist/esm/GatewayServer.d.ts +427 -0
  126. package/dist/esm/GatewayServer.d.ts.map +1 -0
  127. package/dist/esm/GatewayServer.js +725 -0
  128. package/dist/esm/GatewayServer.js.map +1 -0
  129. package/dist/esm/HostBranchPresence.d.ts +12 -0
  130. package/dist/esm/HostBranchPresence.d.ts.map +1 -0
  131. package/dist/esm/HostBranchPresence.js +54 -0
  132. package/dist/esm/HostBranchPresence.js.map +1 -0
  133. package/dist/esm/Projections.d.ts +209 -0
  134. package/dist/esm/Projections.d.ts.map +1 -0
  135. package/dist/esm/Projections.js +1254 -0
  136. package/dist/esm/Projections.js.map +1 -0
  137. package/dist/esm/RunDevTools.d.ts +181 -0
  138. package/dist/esm/RunDevTools.d.ts.map +1 -0
  139. package/dist/esm/RunDevTools.js +281 -0
  140. package/dist/esm/RunDevTools.js.map +1 -0
  141. package/dist/esm/RunHistory.d.ts +185 -0
  142. package/dist/esm/RunHistory.d.ts.map +1 -0
  143. package/dist/esm/RunHistory.js +109 -0
  144. package/dist/esm/RunHistory.js.map +1 -0
  145. package/dist/esm/RunTrace.d.ts +753 -0
  146. package/dist/esm/RunTrace.d.ts.map +1 -0
  147. package/dist/esm/RunTrace.js +2105 -0
  148. package/dist/esm/RunTrace.js.map +1 -0
  149. package/dist/esm/RuntimeBridge.d.ts +1386 -0
  150. package/dist/esm/RuntimeBridge.d.ts.map +1 -0
  151. package/dist/esm/RuntimeBridge.js +659 -0
  152. package/dist/esm/RuntimeBridge.js.map +1 -0
  153. package/dist/esm/bun/BunGateway.d.ts +20 -0
  154. package/dist/esm/bun/BunGateway.d.ts.map +1 -0
  155. package/dist/esm/bun/BunGateway.js +32 -0
  156. package/dist/esm/bun/BunGateway.js.map +1 -0
  157. package/dist/esm/index.d.ts +65 -0
  158. package/dist/esm/index.d.ts.map +1 -0
  159. package/dist/esm/index.js +65 -0
  160. package/dist/esm/index.js.map +1 -0
  161. package/dist/esm/internal/NativeGateway.d.ts +176 -0
  162. package/dist/esm/internal/NativeGateway.d.ts.map +1 -0
  163. package/dist/esm/internal/NativeGateway.js +268 -0
  164. package/dist/esm/internal/NativeGateway.js.map +1 -0
  165. package/dist/esm/internal/actionRenderings.d.ts +2 -0
  166. package/dist/esm/internal/actionRenderings.d.ts.map +1 -0
  167. package/dist/esm/internal/actionRenderings.js +202 -0
  168. package/dist/esm/internal/actionRenderings.js.map +1 -0
  169. package/dist/esm/internal/callEvents.d.ts +97 -0
  170. package/dist/esm/internal/callEvents.d.ts.map +1 -0
  171. package/dist/esm/internal/callEvents.js +206 -0
  172. package/dist/esm/internal/callEvents.js.map +1 -0
  173. package/dist/esm/internal/digestIndex.d.ts +31 -0
  174. package/dist/esm/internal/digestIndex.d.ts.map +1 -0
  175. package/dist/esm/internal/digestIndex.js +87 -0
  176. package/dist/esm/internal/digestIndex.js.map +1 -0
  177. package/dist/esm/internal/digestMemory.d.ts +19 -0
  178. package/dist/esm/internal/digestMemory.d.ts.map +1 -0
  179. package/dist/esm/internal/digestMemory.js +23 -0
  180. package/dist/esm/internal/digestMemory.js.map +1 -0
  181. package/dist/esm/internal/inspectLabels.d.ts +8 -0
  182. package/dist/esm/internal/inspectLabels.d.ts.map +1 -0
  183. package/dist/esm/internal/inspectLabels.js +12 -0
  184. package/dist/esm/internal/inspectLabels.js.map +1 -0
  185. package/dist/esm/internal/nativeResolution.d.ts +41 -0
  186. package/dist/esm/internal/nativeResolution.d.ts.map +1 -0
  187. package/dist/esm/internal/nativeResolution.js +78 -0
  188. package/dist/esm/internal/nativeResolution.js.map +1 -0
  189. package/dist/esm/internal/nodeEvents.d.ts +47 -0
  190. package/dist/esm/internal/nodeEvents.d.ts.map +1 -0
  191. package/dist/esm/internal/nodeEvents.js +60 -0
  192. package/dist/esm/internal/nodeEvents.js.map +1 -0
  193. package/dist/esm/node/NodeGateway.d.ts +16 -0
  194. package/dist/esm/node/NodeGateway.d.ts.map +1 -0
  195. package/dist/esm/node/NodeGateway.js +13 -0
  196. package/dist/esm/node/NodeGateway.js.map +1 -0
  197. package/dist/vendor/adapters.json +2707 -0
  198. package/dist/vendor/bun/BunChildProcessSpawner.d.ts +7 -0
  199. package/dist/vendor/bun/BunChildProcessSpawner.js +14 -0
  200. package/dist/vendor/bun/BunClusterHttp.d.ts +83 -0
  201. package/dist/vendor/bun/BunClusterHttp.js +39 -0
  202. package/dist/vendor/bun/BunClusterSocket.d.ts +65 -0
  203. package/dist/vendor/bun/BunClusterSocket.js +22 -0
  204. package/dist/vendor/bun/BunCrypto.d.ts +10 -0
  205. package/dist/vendor/bun/BunCrypto.js +8 -0
  206. package/dist/vendor/bun/BunFileSystem.d.ts +10 -0
  207. package/dist/vendor/bun/BunFileSystem.js +9 -0
  208. package/dist/vendor/bun/BunHttpClient.d.ts +9 -0
  209. package/dist/vendor/bun/BunHttpClient.js +1 -0
  210. package/dist/vendor/bun/BunHttpPlatform.d.ts +10 -0
  211. package/dist/vendor/bun/BunHttpPlatform.js +11 -0
  212. package/dist/vendor/bun/BunHttpServer.d.ts +142 -0
  213. package/dist/vendor/bun/BunHttpServer.js +38 -0
  214. package/dist/vendor/bun/BunHttpServerRequest.d.ts +18 -0
  215. package/dist/vendor/bun/BunHttpServerRequest.js +7 -0
  216. package/dist/vendor/bun/BunMultipart.d.ts +31 -0
  217. package/dist/vendor/bun/BunMultipart.js +12 -0
  218. package/dist/vendor/bun/BunPath.d.ts +24 -0
  219. package/dist/vendor/bun/BunPath.js +12 -0
  220. package/dist/vendor/bun/BunRedis.d.ts +49 -0
  221. package/dist/vendor/bun/BunRedis.js +11 -0
  222. package/dist/vendor/bun/BunRuntime.d.ts +85 -0
  223. package/dist/vendor/bun/BunRuntime.js +8 -0
  224. package/dist/vendor/bun/BunServices.d.ts +34 -0
  225. package/dist/vendor/bun/BunServices.js +23 -0
  226. package/dist/vendor/bun/BunSink.d.ts +8 -0
  227. package/dist/vendor/bun/BunSink.js +12 -0
  228. package/dist/vendor/bun/BunSocket.d.ts +40 -0
  229. package/dist/vendor/bun/BunSocket.js +29 -0
  230. package/dist/vendor/bun/BunSocketServer.d.ts +8 -0
  231. package/dist/vendor/bun/BunSocketServer.js +21 -0
  232. package/dist/vendor/bun/BunStdio.d.ts +11 -0
  233. package/dist/vendor/bun/BunStdio.js +10 -0
  234. package/dist/vendor/bun/BunStream.d.ts +19 -0
  235. package/dist/vendor/bun/BunStream.js +30 -0
  236. package/dist/vendor/bun/BunTerminal.d.ts +21 -0
  237. package/dist/vendor/bun/BunTerminal.js +10 -0
  238. package/dist/vendor/bun/BunWorker.d.ts +20 -0
  239. package/dist/vendor/bun/BunWorker.js +9 -0
  240. package/dist/vendor/bun/BunWorkerRunner.d.ts +12 -0
  241. package/dist/vendor/bun/BunWorkerRunner.js +7 -0
  242. package/dist/vendor/bun/LICENSE +21 -0
  243. package/dist/vendor/bun/index.d.ts +92 -0
  244. package/dist/vendor/bun/index.js +107 -0
  245. package/dist/vendor/chunk-2GCOZTTW.js +48 -0
  246. package/dist/vendor/chunk-37CUR3PO.js +81 -0
  247. package/dist/vendor/chunk-3ARKKENZ.js +45 -0
  248. package/dist/vendor/chunk-3NV2UDBI.js +7 -0
  249. package/dist/vendor/chunk-3OSW7CT7.js +143 -0
  250. package/dist/vendor/chunk-62R63L74.js +62 -0
  251. package/dist/vendor/chunk-6AQLBC2I.js +118 -0
  252. package/dist/vendor/chunk-6C5H7S6B.js +18 -0
  253. package/dist/vendor/chunk-6DY5RBZD.js +85 -0
  254. package/dist/vendor/chunk-6UPBD47P.js +53 -0
  255. package/dist/vendor/chunk-AVVVN75Z.js +96 -0
  256. package/dist/vendor/chunk-B4DHEMBB.js +14 -0
  257. package/dist/vendor/chunk-BCK3NJOX.js +15 -0
  258. package/dist/vendor/chunk-BFBIHJ6X.js +0 -0
  259. package/dist/vendor/chunk-CES4OUM4.js +63 -0
  260. package/dist/vendor/chunk-D64L6YND.js +59 -0
  261. package/dist/vendor/chunk-DS2R6WOM.js +18 -0
  262. package/dist/vendor/chunk-DX4Z23DM.js +65 -0
  263. package/dist/vendor/chunk-DZ2VOUDP.js +564 -0
  264. package/dist/vendor/chunk-FOXN6JPJ.js +61 -0
  265. package/dist/vendor/chunk-FPQF7CR5.js +55 -0
  266. package/dist/vendor/chunk-FUTCTCEG.js +20 -0
  267. package/dist/vendor/chunk-GUPAV2YZ.js +18 -0
  268. package/dist/vendor/chunk-H2Z2Y4QH.js +70 -0
  269. package/dist/vendor/chunk-HAEDVSSM.js +129 -0
  270. package/dist/vendor/chunk-HY7BBL3K.js +93 -0
  271. package/dist/vendor/chunk-IFTTT6D5.js +31 -0
  272. package/dist/vendor/chunk-KQDSNB7M.js +26 -0
  273. package/dist/vendor/chunk-LIHLXXGQ.js +26 -0
  274. package/dist/vendor/chunk-LKCGQEE5.js +28 -0
  275. package/dist/vendor/chunk-MH2J3BYB.js +0 -0
  276. package/dist/vendor/chunk-ML2NAFH2.js +131 -0
  277. package/dist/vendor/chunk-MLFIZ5O2.js +0 -0
  278. package/dist/vendor/chunk-MLKGABMK.js +9 -0
  279. package/dist/vendor/chunk-MSCLEMYX.js +71 -0
  280. package/dist/vendor/chunk-OBWXQKVP.js +57 -0
  281. package/dist/vendor/chunk-QR557K66.js +20 -0
  282. package/dist/vendor/chunk-R4QUY7DH.js +18 -0
  283. package/dist/vendor/chunk-RGECXXJS.js +18 -0
  284. package/dist/vendor/chunk-TFY7W6D4.js +36 -0
  285. package/dist/vendor/chunk-TGPIVY4A.js +104 -0
  286. package/dist/vendor/chunk-TGXCX6W3.js +398 -0
  287. package/dist/vendor/chunk-TOHSFXMV.js +437 -0
  288. package/dist/vendor/chunk-UHIDPUFF.js +34 -0
  289. package/dist/vendor/chunk-ULT6CWUI.js +109 -0
  290. package/dist/vendor/chunk-UXBGYQR3.js +18 -0
  291. package/dist/vendor/chunk-V6LUGQ7O.js +21 -0
  292. package/dist/vendor/chunk-W4OASVX6.js +92 -0
  293. package/dist/vendor/chunk-WAII54GA.js +18 -0
  294. package/dist/vendor/chunk-WECQDT36.js +426 -0
  295. package/dist/vendor/chunk-WHKMOC7Z.js +28 -0
  296. package/dist/vendor/chunk-WVFOZ2UL.js +40 -0
  297. package/dist/vendor/chunk-X73E2UPI.js +18 -0
  298. package/dist/vendor/chunk-XCYARUII.js +63 -0
  299. package/dist/vendor/chunk-XFEVTDVD.js +34 -0
  300. package/dist/vendor/chunk-XFZZYSJ4.js +22 -0
  301. package/dist/vendor/chunk-XJWJXLXJ.js +18 -0
  302. package/dist/vendor/chunk-XY3Q62EO.js +18 -0
  303. package/dist/vendor/chunk-YDASSC75.js +394 -0
  304. package/dist/vendor/chunk-Z6C7SO5Z.js +507 -0
  305. package/dist/vendor/chunk-Z7QNPJEB.js +229 -0
  306. package/dist/vendor/chunk-Z7QPP4YH.js +249 -0
  307. package/dist/vendor/chunk-ZCHYLHJH.js +86 -0
  308. package/dist/vendor/chunk-ZIQVYVMA.js +22 -0
  309. package/dist/vendor/chunk-ZPIG2CUA.js +34 -0
  310. package/dist/vendor/cjs/bun/BunChildProcessSpawner.d.ts +7 -0
  311. package/dist/vendor/cjs/bun/BunChildProcessSpawner.js +1 -0
  312. package/dist/vendor/cjs/bun/BunClusterHttp.d.ts +83 -0
  313. package/dist/vendor/cjs/bun/BunClusterHttp.js +1 -0
  314. package/dist/vendor/cjs/bun/BunClusterSocket.d.ts +65 -0
  315. package/dist/vendor/cjs/bun/BunClusterSocket.js +1 -0
  316. package/dist/vendor/cjs/bun/BunCrypto.d.ts +10 -0
  317. package/dist/vendor/cjs/bun/BunCrypto.js +1 -0
  318. package/dist/vendor/cjs/bun/BunFileSystem.d.ts +10 -0
  319. package/dist/vendor/cjs/bun/BunFileSystem.js +1 -0
  320. package/dist/vendor/cjs/bun/BunHttpClient.d.ts +9 -0
  321. package/dist/vendor/cjs/bun/BunHttpClient.js +1 -0
  322. package/dist/vendor/cjs/bun/BunHttpPlatform.d.ts +10 -0
  323. package/dist/vendor/cjs/bun/BunHttpPlatform.js +1 -0
  324. package/dist/vendor/cjs/bun/BunHttpServer.d.ts +142 -0
  325. package/dist/vendor/cjs/bun/BunHttpServer.js +1 -0
  326. package/dist/vendor/cjs/bun/BunHttpServerRequest.d.ts +18 -0
  327. package/dist/vendor/cjs/bun/BunHttpServerRequest.js +1 -0
  328. package/dist/vendor/cjs/bun/BunMultipart.d.ts +31 -0
  329. package/dist/vendor/cjs/bun/BunMultipart.js +1 -0
  330. package/dist/vendor/cjs/bun/BunPath.d.ts +24 -0
  331. package/dist/vendor/cjs/bun/BunPath.js +1 -0
  332. package/dist/vendor/cjs/bun/BunRedis.d.ts +49 -0
  333. package/dist/vendor/cjs/bun/BunRedis.js +1 -0
  334. package/dist/vendor/cjs/bun/BunRuntime.d.ts +85 -0
  335. package/dist/vendor/cjs/bun/BunRuntime.js +1 -0
  336. package/dist/vendor/cjs/bun/BunServices.d.ts +34 -0
  337. package/dist/vendor/cjs/bun/BunServices.js +1 -0
  338. package/dist/vendor/cjs/bun/BunSink.d.ts +8 -0
  339. package/dist/vendor/cjs/bun/BunSink.js +1 -0
  340. package/dist/vendor/cjs/bun/BunSocket.d.ts +40 -0
  341. package/dist/vendor/cjs/bun/BunSocket.js +1 -0
  342. package/dist/vendor/cjs/bun/BunSocketServer.d.ts +8 -0
  343. package/dist/vendor/cjs/bun/BunSocketServer.js +1 -0
  344. package/dist/vendor/cjs/bun/BunStdio.d.ts +11 -0
  345. package/dist/vendor/cjs/bun/BunStdio.js +1 -0
  346. package/dist/vendor/cjs/bun/BunStream.d.ts +19 -0
  347. package/dist/vendor/cjs/bun/BunStream.js +1 -0
  348. package/dist/vendor/cjs/bun/BunTerminal.d.ts +21 -0
  349. package/dist/vendor/cjs/bun/BunTerminal.js +1 -0
  350. package/dist/vendor/cjs/bun/BunWorker.d.ts +20 -0
  351. package/dist/vendor/cjs/bun/BunWorker.js +1 -0
  352. package/dist/vendor/cjs/bun/BunWorkerRunner.d.ts +12 -0
  353. package/dist/vendor/cjs/bun/BunWorkerRunner.js +1 -0
  354. package/dist/vendor/cjs/bun/index.d.ts +92 -0
  355. package/dist/vendor/cjs/bun/index.js +1 -0
  356. package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
  357. package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
  358. package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
  359. package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
  360. package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
  361. package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
  362. package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
  363. package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
  364. package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
  365. package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
  366. package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
  367. package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
  368. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
  369. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
  370. package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
  371. package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
  372. package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
  373. package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
  374. package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
  375. package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
  376. package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
  377. package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
  378. package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
  379. package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
  380. package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
  381. package/dist/vendor/cjs/node/NodePath.js +1 -0
  382. package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
  383. package/dist/vendor/cjs/node/NodeRedis.js +1 -0
  384. package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
  385. package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
  386. package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
  387. package/dist/vendor/cjs/node/NodeServices.js +1 -0
  388. package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
  389. package/dist/vendor/cjs/node/NodeSink.js +1 -0
  390. package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
  391. package/dist/vendor/cjs/node/NodeSocket.js +1 -0
  392. package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
  393. package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
  394. package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
  395. package/dist/vendor/cjs/node/NodeStdio.js +1 -0
  396. package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
  397. package/dist/vendor/cjs/node/NodeStream.js +1 -0
  398. package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
  399. package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
  400. package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
  401. package/dist/vendor/cjs/node/NodeWorker.js +1 -0
  402. package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
  403. package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
  404. package/dist/vendor/cjs/node/Undici.d.ts +28 -0
  405. package/dist/vendor/cjs/node/Undici.js +1 -0
  406. package/dist/vendor/cjs/node/index.d.ts +100 -0
  407. package/dist/vendor/cjs/node/index.js +1 -0
  408. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  409. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
  410. package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
  411. package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
  412. package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
  413. package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
  414. package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
  415. package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
  416. package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
  417. package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
  418. package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
  419. package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
  420. package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
  421. package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
  422. package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
  423. package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
  424. package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
  425. package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
  426. package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
  427. package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
  428. package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
  429. package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
  430. package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
  431. package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
  432. package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
  433. package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
  434. package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
  435. package/dist/vendor/cjs/node-shared/index.js +1 -0
  436. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  437. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
  438. package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
  439. package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
  440. package/dist/vendor/cjs/package.json +1 -0
  441. package/dist/vendor/cjs/platform-bun.d.ts +92 -0
  442. package/dist/vendor/cjs/platform-bun.js +1 -0
  443. package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
  444. package/dist/vendor/cjs/platform-node-shared.js +1 -0
  445. package/dist/vendor/cjs/platform-node.d.ts +100 -0
  446. package/dist/vendor/cjs/platform-node.js +1 -0
  447. package/dist/vendor/node/LICENSE +21 -0
  448. package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
  449. package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
  450. package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
  451. package/dist/vendor/node/NodeClusterHttp.js +43 -0
  452. package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
  453. package/dist/vendor/node/NodeClusterSocket.js +30 -0
  454. package/dist/vendor/node/NodeCrypto.d.ts +10 -0
  455. package/dist/vendor/node/NodeCrypto.js +8 -0
  456. package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
  457. package/dist/vendor/node/NodeFileSystem.js +9 -0
  458. package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
  459. package/dist/vendor/node/NodeHttpClient.js +46 -0
  460. package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
  461. package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
  462. package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
  463. package/dist/vendor/node/NodeHttpPlatform.js +16 -0
  464. package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
  465. package/dist/vendor/node/NodeHttpServer.js +46 -0
  466. package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
  467. package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
  468. package/dist/vendor/node/NodeMultipart.d.ts +46 -0
  469. package/dist/vendor/node/NodeMultipart.js +15 -0
  470. package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
  471. package/dist/vendor/node/NodeMultipartParser.js +11 -0
  472. package/dist/vendor/node/NodePath.d.ts +27 -0
  473. package/dist/vendor/node/NodePath.js +12 -0
  474. package/dist/vendor/node/NodeRedis.d.ts +74 -0
  475. package/dist/vendor/node/NodeRedis.js +11 -0
  476. package/dist/vendor/node/NodeRuntime.d.ts +85 -0
  477. package/dist/vendor/node/NodeRuntime.js +8 -0
  478. package/dist/vendor/node/NodeServices.d.ts +34 -0
  479. package/dist/vendor/node/NodeServices.js +23 -0
  480. package/dist/vendor/node/NodeSink.d.ts +8 -0
  481. package/dist/vendor/node/NodeSink.js +12 -0
  482. package/dist/vendor/node/NodeSocket.d.ts +38 -0
  483. package/dist/vendor/node/NodeSocket.js +31 -0
  484. package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
  485. package/dist/vendor/node/NodeSocketServer.js +21 -0
  486. package/dist/vendor/node/NodeStdio.d.ts +11 -0
  487. package/dist/vendor/node/NodeStdio.js +10 -0
  488. package/dist/vendor/node/NodeStream.d.ts +8 -0
  489. package/dist/vendor/node/NodeStream.js +27 -0
  490. package/dist/vendor/node/NodeTerminal.d.ts +21 -0
  491. package/dist/vendor/node/NodeTerminal.js +10 -0
  492. package/dist/vendor/node/NodeWorker.d.ts +22 -0
  493. package/dist/vendor/node/NodeWorker.js +9 -0
  494. package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
  495. package/dist/vendor/node/NodeWorkerRunner.js +7 -0
  496. package/dist/vendor/node/Undici.d.ts +28 -0
  497. package/dist/vendor/node/Undici.js +9 -0
  498. package/dist/vendor/node/index.d.ts +100 -0
  499. package/dist/vendor/node/index.js +115 -0
  500. package/dist/vendor/node-shared/LICENSE +21 -0
  501. package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  502. package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
  503. package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
  504. package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
  505. package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
  506. package/dist/vendor/node-shared/NodeCrypto.js +9 -0
  507. package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
  508. package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
  509. package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
  510. package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
  511. package/dist/vendor/node-shared/NodePath.d.ts +27 -0
  512. package/dist/vendor/node-shared/NodePath.js +11 -0
  513. package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
  514. package/dist/vendor/node-shared/NodeRuntime.js +7 -0
  515. package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
  516. package/dist/vendor/node-shared/NodeSink.js +11 -0
  517. package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
  518. package/dist/vendor/node-shared/NodeSocket.js +23 -0
  519. package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
  520. package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
  521. package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
  522. package/dist/vendor/node-shared/NodeStdio.js +9 -0
  523. package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
  524. package/dist/vendor/node-shared/NodeStream.js +26 -0
  525. package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
  526. package/dist/vendor/node-shared/NodeTerminal.js +9 -0
  527. package/dist/vendor/node-shared/index.d.ts +56 -0
  528. package/dist/vendor/node-shared/index.js +58 -0
  529. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  530. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
  531. package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
  532. package/dist/vendor/node-shared/internal/utils.js +7 -0
  533. package/dist/vendor/platform-bun.d.ts +92 -0
  534. package/dist/vendor/platform-bun.js +107 -0
  535. package/dist/vendor/platform-node-shared.d.ts +56 -0
  536. package/dist/vendor/platform-node-shared.js +58 -0
  537. package/dist/vendor/platform-node.d.ts +100 -0
  538. package/dist/vendor/platform-node.js +115 -0
  539. package/docs/README.md +158 -0
  540. package/docs/api.md +601 -0
  541. package/docs/concepts/projections.md +250 -0
  542. package/docs/concepts/subscriptions.md +204 -0
  543. package/docs/concepts/trust-boundary.md +256 -0
  544. package/docs/guides/diagnose-a-run.md +115 -0
  545. package/docs/guides/follow-a-run.md +150 -0
  546. package/docs/guides/host-the-gateway.md +153 -0
  547. package/docs/guides/read-a-projection.md +138 -0
  548. package/docs/guides/serve-beyond-loopback.md +166 -0
  549. package/docs/guides/submit-an-approval.md +187 -0
  550. package/docs/guides/testing.md +148 -0
  551. package/docs/installation.md +89 -0
  552. package/docs/quickstart.md +200 -0
  553. package/docs/troubleshooting.md +355 -0
  554. package/package.json +264 -32
  555. package/src/Diagnosis.ts +892 -0
  556. package/src/EngineTrace.ts +605 -0
  557. package/src/GatewayError.ts +71 -0
  558. package/src/GatewayProjection.ts +948 -0
  559. package/src/GatewayRpcs.ts +179 -0
  560. package/src/GatewaySchema.ts +516 -0
  561. package/src/GatewayServer.ts +932 -0
  562. package/src/HostBranchPresence.ts +72 -0
  563. package/src/Projections.ts +1735 -0
  564. package/src/RunDevTools.ts +394 -0
  565. package/src/RunHistory.ts +174 -0
  566. package/src/RunTrace.ts +2793 -0
  567. package/src/RuntimeBridge.ts +835 -0
  568. package/src/bun/BunGateway.ts +52 -0
  569. package/src/index.ts +77 -0
  570. package/src/internal/NativeGateway.ts +360 -0
  571. package/src/internal/actionRenderings.ts +201 -0
  572. package/src/internal/callEvents.ts +257 -0
  573. package/src/internal/digestIndex.ts +134 -0
  574. package/src/internal/digestMemory.ts +27 -0
  575. package/src/internal/inspectLabels.ts +13 -0
  576. package/src/internal/nativeResolution.ts +103 -0
  577. package/src/internal/nodeEvents.ts +100 -0
  578. package/src/node/NodeGateway.ts +30 -0
  579. package/openapi.yaml +0 -29182
  580. package/src/README.md +0 -39
  581. package/src/api/README.md +0 -23
  582. package/src/api/apiCollectionNames.js +0 -10
  583. package/src/api/index.d.ts +0 -126
  584. package/src/api/index.js +0 -14
  585. package/src/api/normalizeApiRow.js +0 -36
  586. package/src/api/serializeAccountRow.js +0 -10
  587. package/src/api/serializeApprovalRow.js +0 -53
  588. package/src/api/serializeComparisonScoreRow.js +0 -18
  589. package/src/api/serializeCronRow.js +0 -30
  590. package/src/api/serializeDocRow.js +0 -20
  591. package/src/api/serializeMemoryFactRow.js +0 -21
  592. package/src/api/serializePromptRow.js +0 -10
  593. package/src/api/serializeRunEventRow.js +0 -28
  594. package/src/api/serializeRunRow.js +0 -61
  595. package/src/api/serializeScoreDetailRow.js +0 -25
  596. package/src/api/serializeScoreRow.js +0 -26
  597. package/src/api/serializeTicketRow.js +0 -20
  598. package/src/api/serializeWorkflowRow.js +0 -10
  599. package/src/auth/scopes.d.ts +0 -19
  600. package/src/auth/scopes.js +0 -164
  601. package/src/index.d.ts +0 -316
  602. package/src/index.js +0 -108
  603. package/src/rpc/gatewayRpcTypes.ts +0 -183
  604. package/src/rpc/index.d.ts +0 -221
  605. package/src/rpc/index.js +0 -2431
@@ -0,0 +1,138 @@
1
+ ---
2
+ title: "Read a projection over HTTP"
3
+ description: "Call Projection.Snapshot for each of the eight selectors, decode the rows with the schema the selector names, and keep the cursor the snapshot answers with."
4
+ sidebar:
5
+ order: 2
6
+ ---
7
+
8
+ `Projection.Snapshot` answers every row a selector currently projects, plus the
9
+ cursor they were read at. It is the request/response half of the read path, and
10
+ it is what a relay in front of a gateway uses, because a stream belongs on a
11
+ socket rather than in a buffered response.
12
+
13
+ ## Pick a selector
14
+
15
+ Each selector is a tagged struct. Build one as a value, never as a string:
16
+
17
+ ```ts
18
+ import * as GatewaySchema from "@smthrs/gateway/GatewaySchema"
19
+
20
+ const everyRun: GatewaySchema.ProjectionSelector = { _tag: "workspace-runs" }
21
+ const oneRun: GatewaySchema.ProjectionSelector = { _tag: "run-summary", runId }
22
+ const itsEvents: GatewaySchema.ProjectionSelector = { _tag: "run-events", runId }
23
+ const itsTranscript: GatewaySchema.ProjectionSelector = { _tag: "transcript", runId }
24
+ const itsCalls: GatewaySchema.ProjectionSelector = { _tag: "run-tree", runId }
25
+ const itsGates: GatewaySchema.ProjectionSelector = { _tag: "approvals", runId }
26
+ const theInbox: GatewaySchema.ProjectionSelector = { _tag: "approvals" }
27
+ const oneOutput: GatewaySchema.ProjectionSelector = { _tag: "node-output", runId, nodeId: "call-1" }
28
+ const itsDurations: GatewaySchema.ProjectionSelector = { _tag: "flow-durations", flowId }
29
+ ```
30
+
31
+ `approvals` is the one selector whose `runId` is optional, and the two forms
32
+ answer different questions. With a run it lists that run's gates including the
33
+ decided ones, which is what a run card renders: a gate a human already answered
34
+ still belongs on the card that asked. Without one it lists the workspace's
35
+ pending gates, which is the approvals inbox.
36
+
37
+ ## Read it in process
38
+
39
+ ```ts
40
+ import { Projections } from "@smthrs/gateway/Projections"
41
+ import { Effect } from "effect"
42
+
43
+ const rows = Effect.gen(function*() {
44
+ const projections = yield* Projections
45
+ const snapshot = yield* projections.snapshot({ _tag: "run-tree", runId })
46
+ return snapshot.rows
47
+ })
48
+ ```
49
+
50
+ The effect fails with a `GatewayError`. `run_not_found` means the control plane
51
+ does not have that run, and it is answered identically for every run-scoped
52
+ selector: reading a run's events alone cannot tell an unknown run from a run
53
+ with no events.
54
+
55
+ ## Read it over the wire
56
+
57
+ The mount speaks RPC over newline-delimited JSON. One request is one line:
58
+
59
+ ```bash
60
+ curl -s http://127.0.0.1:3000/projections \
61
+ -H 'content-type: application/json' \
62
+ --data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"run-tree","runId":"run-1"}},"headers":[]}
63
+ '
64
+ ```
65
+
66
+ ```text
67
+ {"_tag":"Exit","requestId":1,"exit":{"_tag":"Success","value":{"selector":{"_tag":"run-tree","runId":"run-1"},"cursor":{...},"rows":[...]}}}
68
+ ```
69
+
70
+ A failure arrives as the same envelope with a `Failure` exit carrying the typed
71
+ `GatewayError`. A refusal answered by the ingress guard instead, before the
72
+ mount saw the request, is a plain JSON body under an HTTP status: see
73
+ [the trust boundary](../concepts/trust-boundary.md#ingress-runs-before-the-transport-parses-anything).
74
+
75
+ If the gateway was bound with a credential, send it:
76
+
77
+ ```bash
78
+ curl -s http://127.0.0.1:3000/projections \
79
+ -H "authorization: Bearer $SMITHERS_TOKEN" \
80
+ -H 'content-type: application/json' \
81
+ --data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"workspace-runs"}},"headers":[]}
82
+ '
83
+ ```
84
+
85
+ ## Decode the rows, do not cast them
86
+
87
+ `GatewaySchema.rowSchemaFor` maps a selector to the schema its rows decode
88
+ under, so a client that already has the selector does not need a switch of its
89
+ own:
90
+
91
+ ```ts
92
+ import * as GatewaySchema from "@smthrs/gateway/GatewaySchema"
93
+ import { Schema } from "effect"
94
+
95
+ const decodeRows = (selector: GatewaySchema.ProjectionSelector, rows: unknown) =>
96
+ Schema.decodeUnknownSync(Schema.Array(GatewaySchema.rowSchemaFor(selector)))(rows)
97
+ ```
98
+
99
+ | Selector | Row schema |
100
+ | ------------------------------- | ----------------------------------- |
101
+ | `workspace-runs`, `run-summary` | `GatewayProjection.RunSummaryRow` |
102
+ | `run-events` | `ControlSchema.ControlEvent` |
103
+ | `transcript` | `GatewayProjection.TranscriptRow` |
104
+ | `run-tree` | `GatewayProjection.RunTreeRow` |
105
+ | `approvals` | `GatewayProjection.ApprovalRow` |
106
+ | `node-output` | `GatewayProjection.NodeOutputRow` |
107
+ | `flow-durations` | `GatewayProjection.FlowDurationRow` |
108
+
109
+ `GatewaySchema.ProjectionSnapshot` decodes the whole answer, selector and
110
+ cursor included, and it is a union correlated on the selector: a snapshot whose
111
+ rows do not belong to its selector does not decode at all.
112
+
113
+ ## Keep the cursor
114
+
115
+ Every snapshot carries the cursor its rows were read at. It is not decoration:
116
+ it is the position a subscription resumes from without a second snapshot, and
117
+ the read that produced the rows produced it, so the two cannot disagree. See
118
+ [Follow a run over a WebSocket](./follow-a-run.md).
119
+
120
+ A workspace cursor is always `value` 0 with a `null` run, and cannot resume
121
+ anything. That is a fact about control journal partitioning, not a gap: see
122
+ [Subscriptions and cursors](../concepts/subscriptions.md#workspace-subscriptions-do-not-resume).
123
+
124
+ ## Fold rows yourself
125
+
126
+ The folds are exported, so a client that already holds a run summary and its
127
+ events can compute the same rows without a gateway at all:
128
+
129
+ ```ts
130
+ import * as GatewayProjection from "@smthrs/gateway/GatewayProjection"
131
+
132
+ const tree = GatewayProjection.runTree(run, events)
133
+ const gates = GatewayProjection.approvals(events)
134
+ const lines = GatewayProjection.transcript(events)
135
+ ```
136
+
137
+ This is the same code path the served projection uses, which is what makes an
138
+ offline reader and a served reader agree.
@@ -0,0 +1,166 @@
1
+ ---
2
+ title: "Serve beyond loopback"
3
+ description: "Bind a gateway on a network address: the two opt-ins the policy requires, the credential every mount then enforces, and the request limits worth setting at the same time."
4
+ sidebar:
5
+ order: 5
6
+ ---
7
+
8
+ A loopback gateway needs no credential. Its ingress still accepts only a
9
+ loopback `Host` and, when present, a loopback browser `Origin`; Origin-less CLI
10
+ requests keep working. Anything reachable from another machine needs two
11
+ opt-ins, and the policy refuses the bind rather than serving without them.
12
+
13
+ ## The two rules
14
+
15
+ 1. **A non-loopback host requires an explicit `listen` opt-in.**
16
+
17
+ ```text
18
+ Refusing non-loopback gateway bind 0.0.0.0 without an explicit --listen opt-in
19
+ ```
20
+
21
+ 2. **A non-loopback bind requires a bearer credential.**
22
+
23
+ ```text
24
+ Refusing non-loopback gateway bind 0.0.0.0 without a bearer credential
25
+ ```
26
+
27
+ `NodeGateway.isLoopbackHost` accepts `127.0.0.1`, `::1`, and `localhost`.
28
+ Every other host, a LAN address and a public one alike, is treated as reachable
29
+ from elsewhere.
30
+
31
+ Both refusals are `bind_failed` `GatewayError` values, answered before anything
32
+ binds.
33
+
34
+ ## Bind it
35
+
36
+ ```ts
37
+ import * as NodeGateway from "@smthrs/gateway/node/NodeGateway"
38
+
39
+ const gateway = NodeGateway.layer(health, {
40
+ host: "0.0.0.0",
41
+ port: 7331,
42
+ listen: true,
43
+ credential: process.env.SMITHERS_TOKEN,
44
+ allowedHosts: ["gateway.example.com"],
45
+ // Optional, and worth setting behind a relay that cuts idle tunnels sooner
46
+ // than 600 seconds.
47
+ heartbeatMillis: 10_000,
48
+ // Optional. One MiB by default.
49
+ maxRequestBodyBytes: 256 * 1024
50
+ })
51
+ ```
52
+
53
+ From the command line, bind the machine's concrete LAN address so that address
54
+ is also admitted by the Host policy (replace this example with your address):
55
+
56
+ ```bash
57
+ export SMITHERS_TOKEN="<the bearer token from your secret manager>"
58
+ smthrs serve --host 192.168.1.10 --port 3000 --listen
59
+ ```
60
+
61
+ The server reads the bearer from `SMITHERS_TOKEN`, which keeps it out of the
62
+ long-lived process's argv. See
63
+ [Serve the workspace gateway](/pkg/cli/guides/serve-the-workspace-gateway).
64
+
65
+ ## What the credential then covers
66
+
67
+ One credential authenticates every mount and binds one principal,
68
+ `{ id: "gateway", kind: "bearer" }`. This authenticator has no per-user or
69
+ per-run identity. Approval authority is separately configured on the owning
70
+ Control runtime: by default the bearer cannot approve or deny. To delegate,
71
+ provide `ApprovalAuthority` with that exact identity and allowed target kinds
72
+ and scopes. Delegation applies to everyone holding the shared credential; it
73
+ does not distinguish a human from an agent. See
74
+ [the approval contract](/pkg/control/guides/approvals/#who-may-decide).
75
+
76
+ The loopback Host/Origin restriction belongs to the credential-less local
77
+ mode. A bearer-protected non-loopback gateway accepts the network hostname it
78
+ was deployed under and relies on the configured credential instead.
79
+
80
+ Clients send it as a bearer token:
81
+
82
+ ```bash
83
+ curl -s https://gateway.example.com/projections \
84
+ -H "authorization: Bearer $SMITHERS_TOKEN" \
85
+ -H 'content-type: application/json' \
86
+ --data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"workspace-runs"}},"headers":[]}
87
+ '
88
+ ```
89
+
90
+ A WebSocket client sends the same header on the upgrade request. A browser's
91
+ `WebSocket` cannot set headers on an upgrade, so it exchanges the credential for
92
+ a single-use ticket first and presents that on the upgrade instead:
93
+
94
+ ```js
95
+ const { ticket } = await (await fetch("https://gateway.example.com/auth/ticket", {
96
+ method: "POST",
97
+ headers: { authorization: `Bearer ${token}` }
98
+ })).json()
99
+ const socket = new WebSocket(`wss://gateway.example.com/rpc/ws?ticket=${ticket}`)
100
+ ```
101
+
102
+ The ticket opens one socket within thirty seconds and is refused on replay.
103
+ The socket runs as the credential the ticket was issued against.
104
+
105
+ ## Hand out less than the credential
106
+
107
+ `smthrs token mint --scope read:runs --ttl 1h` mints a token under
108
+ `SMITHERS_TOKEN` that this gateway accepts for the procedures the scope names
109
+ and nothing else, until it expires. `--run <id>` or `--flow <id>` confines it
110
+ further. The scopes are `read:runs`, `write:runs`, and `approve:runs`; a token
111
+ stamps `gateway/scoped`, so an `approve:runs` token decides only where the host
112
+ delegates to that identity. Rotating `SMITHERS_TOKEN` revokes every token
113
+ minted under it. See [the trust boundary](../concepts/trust-boundary.md#scoped-expiring-tokens).
114
+
115
+ `/health` stays unauthenticated even here. It answers identity and nothing
116
+ else: no token, no run, no path.
117
+
118
+ ## Two refusals that look alike and are not
119
+
120
+ `POST /rpc` is not edge-authenticated. It authenticates in band and answers
121
+ `@smthrs/control`'s typed `Unauthorized`, so a caller sees a control error
122
+ rather than a transport error, exactly as it would against a control server
123
+ hosting the same procedures. `/rpc/ws`, `/projections`, `/sync`, and both other
124
+ sockets are checked at the edge and answer 401 with a `unauthorized`
125
+ `GatewayError` body.
126
+
127
+ Why the two differ, and why it matters to a client's error handling, is in
128
+ [the trust boundary](../concepts/trust-boundary.md#edge-authentication-and-where-it-deliberately-stops).
129
+
130
+ ## Bound the requests while you are here
131
+
132
+ For a wildcard bind, set `allowedHosts: ["gateway.example.com"]` on
133
+ `NodeGateway.ServerOptions` to admit the hostname clients use. These entries
134
+ contain no ports or wildcards. A concrete bind host and the loopback names are
135
+ also accepted. The Host and Origin checks apply before bearer authentication;
136
+ a browser's Origin must match the requested authority, including its port.
137
+
138
+ This server binds plain HTTP. For network access, terminate TLS at a trusted
139
+ proxy or use an encrypted tunnel so the bearer token is not sent in cleartext.
140
+
141
+ An HTTP RPC body is capped at `GatewayServer.defaultMaxRequestBodyBytes`, one
142
+ MiB. A declared `content-length` over the limit is refused without reading the
143
+ body; a body that declares no length, or declares less than it sends, is
144
+ measured as it is read. Declared overflow is 413 `request_too_large`; the Node
145
+ host hard-closes a streaming overflow rather than draining attacker-controlled
146
+ bytes, so that client may see a connection reset. A body the server could not
147
+ read for another reason is 400 `malformed_request`.
148
+
149
+ `maxRequestBodyBytes` and `heartbeatMillis` are checked the same way and must
150
+ both be positive safe integers. A body limit of zero would refuse every request
151
+ and a cadence of zero would spin, so a composition that asks for either is
152
+ refused with `bind_failed` before it binds rather than after it is serving.
153
+
154
+ ## Check the policy without composing anything
155
+
156
+ ```ts
157
+ const refusal = NodeGateway.bindRefusal(options)
158
+ if (refusal !== undefined) {
159
+ // refusal.code === "bind_failed", refusal.message names the rule that refused
160
+ }
161
+ ```
162
+
163
+ `bindRefusal` is the same value `listenOptions` fails with and `layer` fails
164
+ through. Operating system listen failures, such as an address already in use,
165
+ are mapped to the same sanitized `bind_failed` shape, so a host has one failure
166
+ contract to handle rather than two.
@@ -0,0 +1,187 @@
1
+ ---
2
+ title: "Submit an approval from a client"
3
+ description: "Read a pending gate, submit Approval.Submit with independent approval authority, and handle its typed refusals."
4
+ sidebar:
5
+ order: 4
6
+ ---
7
+
8
+ `Approval.Submit` is the one mutation this package declares. Every other
9
+ mutation a client makes is [`@smthrs/control`](/api/control) `ControlRpcs`,
10
+ mounted unchanged on `/rpc`, so there is exactly one wire definition of `Plan`,
11
+ `Run`, `Approve`, `Deny`, `Cancel`, `Signal`, `Steer`, `Resume`, `List`, and
12
+ `Watch`.
13
+
14
+ This one exists because a decision is a composite act a client cannot
15
+ assemble safely on its own: the grant has to be recorded and the parked run
16
+ delegated to resume, atomically. Control owns that as a single domain command.
17
+ The gateway is a transport adapter over it and composes no second mutation.
18
+
19
+ ## Read the gate
20
+
21
+ The payload a decision needs is published by the `approvals` projection. Do not
22
+ build it:
23
+
24
+ ```ts
25
+ import { Projections } from "@smthrs/gateway/Projections"
26
+ import { Effect } from "effect"
27
+
28
+ const pending = Effect.gen(function*() {
29
+ const projections = yield* Projections
30
+ // No runId: the workspace inbox, which lists only gates a human still owes
31
+ // an answer to.
32
+ const snapshot = yield* projections.snapshot({ _tag: "approvals" })
33
+ return snapshot.rows
34
+ })
35
+ ```
36
+
37
+ Each `GatewayProjection.ApprovalRow` carries:
38
+
39
+ | Field | Holds |
40
+ | ------------- | --------------------------------------------------------------------- |
41
+ | `runId` | the run parked on this gate |
42
+ | `waitRunId` | the execution holding the wait, when it is held below `runId` |
43
+ | `requestId` | the gate's own id |
44
+ | `title` | the question, as the run asked it |
45
+ | `request` | the whole journaled request payload, for rendering |
46
+ | `payload` | the `ControlSchema.ApprovalPayload` a decision submits back unchanged |
47
+ | `requestedAt` | when the gate opened |
48
+ | `status` | `pending`, `approved`, or `denied` |
49
+
50
+ `payload` is the point. It is the exact `ApprovalTarget.Node` envelope the run
51
+ published, carrying the target, the grant scope, and the idempotency key. A
52
+ client submits it back byte for byte, so no client reconstructs authority for
53
+ itself.
54
+
55
+ ### Gates held by a nested execution
56
+
57
+ A flow that calls another flow parks the CHILD execution. A `HumanTask` in a
58
+ nested flow therefore parks a run an operator has never heard of, while the run
59
+ they did open sits at `waiting-approval` with nothing of its own to decide.
60
+
61
+ The control plane rolls those waits up: `ControlSchema.RunSummary.pendingWaits`
62
+ lists every open human wait in a run's tree, and the run's status rolls up with
63
+ them, so the ordinary `status: "waiting-approval"` filter finds the root. The
64
+ `approvals` projection turns each into a pending row of that root run.
65
+ `waitRunId` names the execution actually holding it; the workspace inbox lists
66
+ one question once, from the outermost run that carries it.
67
+
68
+ Such a row asks a QUESTION rather than for a grant, and its `request` says
69
+ what kind of answer:
70
+
71
+ | `request` field | Holds |
72
+ | --------------- | ------------------------------------------------------------- |
73
+ | `kind` | `ask`, `confirm`, `select`, or `json` |
74
+ | `prompt` | the question, which is also the row's `title` |
75
+ | `name` | the wait point's own name, which `Signal` addresses |
76
+ | `attempt` | which attempt of a re-asked question this is, counting from 1 |
77
+ | `maxAttempts` | the attempt budget the task declared |
78
+ | `options` | the choices, on a `select` |
79
+ | `token` | the durable wait address, for a client that prefers it |
80
+
81
+ ## Submit the decision
82
+
83
+ `GatewayRpcs.SubmitApprovalInput` is that payload plus one field:
84
+
85
+ ```json
86
+ {
87
+ "_tag": "Request",
88
+ "id": 1,
89
+ "tag": "Approval.Submit",
90
+ "payload": {
91
+ "target": {
92
+ "_tag": "Node",
93
+ "runId": "run-1",
94
+ "requestId": "gate",
95
+ "digest": "gate-digest",
96
+ "envelope": { "capabilities": ["model:call"], "flows": ["ask"], "budget": {} }
97
+ },
98
+ "scope": "run",
99
+ "idempotencyKey": "approve:gate",
100
+ "decision": "approve"
101
+ },
102
+ "headers": []
103
+ }
104
+ ```
105
+
106
+ Post it to `/projections`, or send it on `/projections/ws`. `decision` is
107
+ `"approve"` or `"deny"`; everything else is the row's `payload` spread in
108
+ place.
109
+
110
+ ### Answering a question
111
+
112
+ A gate that asks a question needs the value, not the word: add `answer`.
113
+
114
+ ```json
115
+ {
116
+ "target": {
117
+ "_tag": "Node",
118
+ "runId": "run-3",
119
+ "requestId": "coding-clarification#1",
120
+ "digest": "<the row's wait token>",
121
+ "envelope": { "capabilities": [], "flows": [], "budget": {} }
122
+ },
123
+ "scope": "once",
124
+ "idempotencyKey": "answer:run-3:coding-clarification#1",
125
+ "decision": "approve",
126
+ "answer": "the scheduler owns it"
127
+ }
128
+ ```
129
+
130
+ Shape the answer for the question's `kind`: prose for `ask`, a boolean for
131
+ `confirm`, one of `options` for `select`, and the decoded JSON value for
132
+ `json`. The mount routes it to `Control.signal`, addressed to `target.runId`
133
+ and naming `target.requestId`, and the control plane finds the execution
134
+ holding that wait. A denial carries no answer: it refuses the question rather
135
+ than answering it, and an unanswered question re-parks or times out on the
136
+ task's own budget.
137
+
138
+ The answer is `GatewayRpcs.SubmitApprovalOutput`: one field, `decision`, the
139
+ `ControlSchema.Receipt` that is the receipt for the grant or the refusal. There
140
+ is no second call. Approving a parked node delegates its durable resume in the
141
+ same command, and denying it records the refusal the same way.
142
+
143
+ ## Who the decision is journaled as
144
+
145
+ The handler reads the principal the shared `ControlAuth` middleware
146
+ authenticated and passes it through, exactly as `ControlServer` stamps it on
147
+ `Approve` and `Deny`. This mount is the same decision under a different
148
+ payload, so it is answerable to the same operator. A decision journaled under
149
+ the composition's default operator would name the wrong one.
150
+
151
+ Authentication is not approval authority. Control checks its host-owned
152
+ `ApprovalAuthority` before mutation or receipt replay, and again at resolution.
153
+ A shared bearer authenticates `gateway/bearer`, which is not an approver by
154
+ default. The host must explicitly delegate that identity and the requested
155
+ scope, or an authorized local operator must decide the gate. Both `/rpc` and
156
+ `/projections`, over HTTP and WebSocket, enforce the same policy. Supplying a
157
+ principal in the payload cannot override the authenticated actor.
158
+
159
+ ## The failures
160
+
161
+ `Approval.Submit` answers with exactly the union `Control.approve`,
162
+ `Control.deny`, and, for an answer, `Control.signal` declare, because the
163
+ handler adds no failure of its own. A member none of them raises would be a
164
+ recovery branch no client's code could ever reach.
165
+
166
+ | Failure | Means | What to do |
167
+ | -------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
168
+ | `Unauthorized` | the caller lacks approval authority for this target/scope | ask an authorized operator; do not keep retrying unchanged |
169
+ | `PlanDigestMismatch` | the plan changed since the gate was published | re-read the gate and show the new plan before deciding again |
170
+ | `EnvelopeMismatch` | the capability envelope is not the one that was approved | re-read the gate; do not widen the envelope client-side |
171
+ | `AlreadyResolved` | someone already decided this gate | refresh the row; the decision stands |
172
+ | `PlanNotFound` | the plan the target names is gone | re-plan |
173
+ | `RunNotFound` | the run the target names is gone | drop the gate from the inbox |
174
+ | `InvalidInput` | the payload is not a decidable approval payload | submit the row's `payload` unchanged |
175
+ | `PersistenceError` | the control plane could not write the decision | retry with the same `idempotencyKey` |
176
+ | `Unavailable` | the control plane is not serving this operation | retry later |
177
+ | `NoMatchingWait` | the question was answered after the run moved on | re-read the inbox; somebody answered it, or it timed out |
178
+
179
+ Retrying is safe. The payload carries an `idempotencyKey`, so a second
180
+ submission of the same decision lands one effect.
181
+
182
+ ## From the command line
183
+
184
+ The same decision from a terminal is [`smthrs approvals approve`](/cli/approvals) and
185
+ `smthrs approvals deny`, which take the same payload the projection
186
+ publishes. For the domain semantics behind both, see
187
+ [Approvals](/pkg/control/guides/approvals).
@@ -0,0 +1,148 @@
1
+ ---
2
+ title: "Test against a real gateway"
3
+ description: "Stand a gateway up over a real SQLite control plane on an ephemeral port, write the events a projection folds, and control the supervision port from a test."
4
+ sidebar:
5
+ order: 7
6
+ ---
7
+
8
+ Test a gateway client against one real stack: a durable journal, a durable run
9
+ store, the SQL control runtime, `ControlLive`, the served projections, the sync
10
+ read path, and the assembled HTTP surface bound to an ephemeral loopback port.
11
+ Stub nothing below the control plane.
12
+
13
+ The behaviours worth pinning are an approval projected out of a parked run, a
14
+ cancellation's attribution, and a child run's visibility. Those are exactly the
15
+ places a mocked control plane agrees with your assertion and disagrees with the
16
+ gateway a real workspace serves.
17
+
18
+ ## Compose the stack
19
+
20
+ The stack reaches below this package's own dependencies. Add the packages
21
+ that supply storage, the selected SQLite driver, and the control runtime's ports:
22
+
23
+ ```bash
24
+ pnpm add -D \
25
+ @smthrs/database@1.0.0-rc.0 \
26
+ @smthrs/journal@1.0.0-rc.0 \
27
+ @smthrs/notifications@1.0.0-rc.0 \
28
+ @smthrs/registry@1.0.0-rc.0 \
29
+ effect@4.0.0-rc.115 \
30
+ @effect/sql-sqlite-node@4.0.0-rc.115
31
+ ```
32
+
33
+ ```ts
34
+ import * as NodeCrypto from "@effect/platform-node/NodeCrypto"
35
+ import * as ControlExecutor from "@smthrs/control/ControlExecutor"
36
+ import * as ControlLive from "@smthrs/control/ControlLive"
37
+ import * as SqlControlRuntime from "@smthrs/control/SqlControlRuntime"
38
+ import * as DurableWriter from "@smthrs/database/DurableWriter"
39
+ import * as NodeDatabase from "@smthrs/database/node/NodeDatabase"
40
+ import * as Projections from "@smthrs/gateway/Projections"
41
+ import { Migrations, SqlJournal } from "@smthrs/journal"
42
+ import { NotificationQueue } from "@smthrs/notifications"
43
+ import { Registry } from "@smthrs/registry"
44
+ import { Migrations as RunStoreMigrations, RunStore } from "@smthrs/run-store"
45
+ import * as RunCatalog from "@smthrs/sync/RunCatalog"
46
+ import * as SyncAuth from "@smthrs/sync/SyncAuth"
47
+ import * as SyncServer from "@smthrs/sync/SyncServer"
48
+ import * as WorkspaceShare from "@smthrs/sync/WorkspaceShare"
49
+ import { Layer } from "effect"
50
+
51
+ const storage = (filename: string) =>
52
+ Layer.mergeAll(SqlJournal.layer({ capacity: 1024, overflow: "reject" }), RunStore.layer).pipe(
53
+ Layer.provideMerge(
54
+ Layer.provideMerge(
55
+ Layer.merge(Migrations.layer, RunStoreMigrations.layer),
56
+ Layer.provideMerge(DurableWriter.layer(), NodeDatabase.layer({ filename }))
57
+ )
58
+ )
59
+ )
60
+
61
+ export const stack = (filename: string) =>
62
+ Layer.mergeAll(
63
+ // A short cadence, so a keepalive assertion does not wait 30 seconds.
64
+ Projections.layerWith({ heartbeatMillis: 50 }),
65
+ SyncServer.layer,
66
+ SyncAuth.layer
67
+ ).pipe(
68
+ Layer.provideMerge(Layer.merge(RunCatalog.layerNoop, WorkspaceShare.layerNoop)),
69
+ Layer.provideMerge(ControlLive.layer),
70
+ Layer.provideMerge(
71
+ Layer.mergeAll(
72
+ SqlControlRuntime.layer({}).pipe(Layer.orDie),
73
+ NotificationQueue.layer,
74
+ ControlExecutor.layer(ControlExecutor.makeNoop()),
75
+ Registry.layerNoop()
76
+ )
77
+ ),
78
+ Layer.provideMerge(Layer.merge(storage(filename), NodeCrypto.layer))
79
+ )
80
+ ```
81
+
82
+ A worked version of this helper, with the temporary-file lifecycle around it,
83
+ is [`GatewayStack.ts`](https://github.com/smithersai/smithers/blob/main/packages/smithers/gateway/test/GatewayStack.ts)
84
+ in the package source.
85
+
86
+ ## Bind an ephemeral port and read it back
87
+
88
+ ```ts
89
+ import * as NodeGateway from "@smthrs/gateway/node/NodeGateway"
90
+ import { Effect, Layer } from "effect"
91
+ import { HttpServer } from "effect/unstable/http"
92
+
93
+ const served = NodeGateway.layer(health, { host: "127.0.0.1", port: 0 }).pipe(Layer.provideMerge(stack(filename)))
94
+
95
+ const baseUrl = Effect.map(HttpServer.HttpServer, (server) => {
96
+ if (server.address._tag !== "InetAddressV4" && server.address._tag !== "InetAddressV6") {
97
+ throw new Error("expected a TCP gateway")
98
+ }
99
+ return `http://127.0.0.1:${server.address.port}`
100
+ })
101
+ ```
102
+
103
+ Port 0 lets the operating system pick, and the layer retains the concrete
104
+ `HttpServer`, so a test reads the address it actually got rather than racing
105
+ for a fixed port.
106
+
107
+ ## Give a run something to project
108
+
109
+ Write events through the journal's durable channel, not its lossy one:
110
+
111
+ ```ts
112
+ import * as Journal from "@smthrs/journal/Journal"
113
+ import * as JournalEvent from "@smthrs/journal/JournalEvent"
114
+ import { Effect } from "effect"
115
+
116
+ const emit = (runId: string, eventType: string, payload: unknown, sourceSeq: number) =>
117
+ Effect.flatMap(Journal.Journal, (journal) =>
118
+ journal.emitDurableUnfenced(
119
+ new JournalEvent.Input({
120
+ runId: JournalEvent.RunId.make(runId),
121
+ sourceId: JournalEvent.SourceId.make("gateway-test"),
122
+ sourceSeq: JournalEvent.SourceSeq.make(sourceSeq),
123
+ eventType,
124
+ payload: JSON.parse(JSON.stringify(payload))
125
+ })
126
+ ))
127
+ ```
128
+
129
+ `emitLossy` returns once the optimistic queue accepts an entry, so a projection
130
+ read straight afterwards can legitimately miss it, and a suite built on that
131
+ races its own fixture. Give each event a monotonic `sourceSeq`, or two
132
+ identical fixture events will not both admit.
133
+
134
+ ## Fold without a stack at all
135
+
136
+ A test that only cares about a fold does not need any of the above. The folds
137
+ are pure functions of a run summary and its events:
138
+
139
+ ```ts
140
+ import * as GatewayProjection from "@smthrs/gateway/GatewayProjection"
141
+
142
+ const rows = GatewayProjection.runTree(run, events)
143
+ ```
144
+
145
+ This is the same code the served projection runs, so a fold test and an
146
+ end-to-end test cannot disagree about what a row means. Reach for the full
147
+ stack when what you are pinning is the _serving_: a status the run row owns, a
148
+ cursor, a refusal, or an HTTP status.