okengine 0.2.6 → 0.2.8

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 (584) hide show
  1. package/AGENTS.md +24 -23
  2. package/README.md +52 -346
  3. package/docs/spec/console.md +165 -142
  4. package/docs/spec/example.md +490 -312
  5. package/docs/spec/four-applications.md +495 -314
  6. package/docs/spec/unified-theory.md +184 -175
  7. package/package.json +45 -37
  8. package/spec/manifest.v1.schema.json +40 -9
  9. package/src/auth/api-keys.ts +2 -5
  10. package/src/auth/attenuation.ts +2 -6
  11. package/src/auth/auth.test.ts +53 -31
  12. package/src/auth/invoke-as.ts +1 -3
  13. package/src/auth/operator.ts +8 -26
  14. package/src/auth/planes.ts +2 -7
  15. package/src/auth/plugin.ts +4 -7
  16. package/src/auth/roles.ts +1 -5
  17. package/src/auth/sessions.ts +10 -39
  18. package/src/cli/args.ts +1 -5
  19. package/src/cli/ask-dev-mode.ts +40 -0
  20. package/src/cli/build.ts +1 -2
  21. package/src/cli/client-add.test.ts +8 -15
  22. package/src/cli/client-add.ts +5 -14
  23. package/src/cli/completion.test.ts +1 -5
  24. package/src/cli/completion.ts +4 -17
  25. package/src/cli/db-auto-push.test.ts +64 -0
  26. package/src/cli/db-auto-push.ts +72 -0
  27. package/src/cli/db.test.ts +189 -0
  28. package/src/cli/db.ts +386 -0
  29. package/src/cli/dev-app-runner.ts +2 -8
  30. package/src/cli/dev-db-push.test.ts +163 -0
  31. package/src/cli/dev-mode.test.ts +45 -0
  32. package/src/cli/dev-mode.ts +78 -0
  33. package/src/cli/dev.test.ts +148 -21
  34. package/src/cli/dev.ts +208 -134
  35. package/src/cli/doc-drift.test.ts +3 -2
  36. package/src/cli/doc-drift.ts +21 -50
  37. package/src/cli/doc-staleness.test.ts +69 -0
  38. package/src/cli/docker-cli.test.ts +7 -8
  39. package/src/cli/docker.ts +1 -3
  40. package/src/cli/doctor-diff-examples.ts +1 -3
  41. package/src/cli/doctor-diff.test.ts +1 -5
  42. package/src/cli/doctor-diff.ts +17 -46
  43. package/src/cli/doctor-pii.ts +2 -7
  44. package/src/cli/doctor.test.ts +26 -4
  45. package/src/cli/doctor.ts +35 -11
  46. package/src/cli/eval.ts +4 -14
  47. package/src/cli/gates-list.ts +1 -4
  48. package/src/cli/hero-meta.test.ts +17 -19
  49. package/src/cli/hero-meta.ts +20 -30
  50. package/src/cli/images.ts +3 -8
  51. package/src/cli/index.ts +11 -2
  52. package/src/cli/load-config.images.test.ts +14 -14
  53. package/src/cli/load-config.ts +41 -47
  54. package/src/cli/mcp-from-console.ts +1 -4
  55. package/src/cli/mode.ts +45 -0
  56. package/src/cli/ports.test.ts +4 -13
  57. package/src/cli/ports.ts +1 -3
  58. package/src/cli/privacy-erase.ts +1 -3
  59. package/src/cli/registry.ts +75 -25
  60. package/src/cli/schema.ts +3 -10
  61. package/src/cli/stack.ts +2 -7
  62. package/src/cli/start.ts +4 -15
  63. package/src/cli/upgrade.ts +1 -4
  64. package/src/client/budget-entry.ts +1 -6
  65. package/src/client/create.test.ts +6 -12
  66. package/src/client/create.ts +2 -8
  67. package/src/client/errors.ts +1 -4
  68. package/src/client/index.ts +1 -6
  69. package/src/client/notes-contract.test.ts +4 -13
  70. package/src/client/transport.ts +9 -30
  71. package/src/client/types.ts +8 -29
  72. package/src/compiler/aot.test.ts +2 -9
  73. package/src/compiler/aot.ts +1 -4
  74. package/src/compiler/differential.test.ts +3 -11
  75. package/src/compiler/dynamic.ts +1 -4
  76. package/src/compiler/effects-infer.ts +8 -34
  77. package/src/compiler/emit.ts +1 -3
  78. package/src/compiler/extract.test.ts +96 -30
  79. package/src/compiler/extract.ts +362 -156
  80. package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
  81. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
  82. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
  83. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
  84. package/src/compiler/fixtures/skyport.expected.json +24 -83
  85. package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
  86. package/src/compiler/http-parse.ts +2 -9
  87. package/src/compiler/index.ts +1 -5
  88. package/src/compiler/response.ts +4 -7
  89. package/src/compiler/sucrose.ts +11 -31
  90. package/src/config/define-config.test.ts +57 -34
  91. package/src/config/index.ts +181 -37
  92. package/src/config/resolve-driver.test.ts +28 -17
  93. package/src/console/budget.test.ts +1 -4
  94. package/src/console/index.ts +1 -4
  95. package/src/console/server/access.test.ts +15 -43
  96. package/src/console/server/access.ts +19 -49
  97. package/src/console/server/ai.test.ts +3 -11
  98. package/src/console/server/ai.ts +23 -46
  99. package/src/console/server/app.ts +14 -45
  100. package/src/console/server/auth-rate.test.ts +4 -12
  101. package/src/console/server/bind.ts +1 -5
  102. package/src/console/server/channels.test.ts +2 -6
  103. package/src/console/server/channels.ts +10 -35
  104. package/src/console/server/claim.ts +2 -8
  105. package/src/console/server/clock.test.ts +2 -6
  106. package/src/console/server/clock.ts +8 -26
  107. package/src/console/server/console.test.ts +1 -3
  108. package/src/console/server/diff.test.ts +5 -17
  109. package/src/console/server/diff.ts +10 -31
  110. package/src/console/server/dry-run.audit.test.ts +2 -8
  111. package/src/console/server/flows.ts +64 -233
  112. package/src/console/server/gates.test.ts +14 -50
  113. package/src/console/server/gates.ts +13 -48
  114. package/src/console/server/index.ts +2 -9
  115. package/src/console/server/live.ts +3 -12
  116. package/src/console/server/operator-db.test.ts +4 -15
  117. package/src/console/server/operator-db.ts +13 -32
  118. package/src/console/server/plugin.ts +50 -53
  119. package/src/console/server/plugins.test.ts +2 -6
  120. package/src/console/server/plugins.ts +17 -56
  121. package/src/console/server/runs-pii.ts +2 -7
  122. package/src/console/server/security.gate.test.ts +18 -40
  123. package/src/console/server/serve.ts +10 -25
  124. package/src/console/server/signals.test.ts +1 -3
  125. package/src/console/server/signals.ts +17 -40
  126. package/src/console/server/state.ts +21 -59
  127. package/src/console/server/store.test.ts +20 -22
  128. package/src/console/server/store.ts +31 -76
  129. package/src/console/server/vault.test.ts +12 -29
  130. package/src/console/server/vault.ts +23 -60
  131. package/src/console/ui/access/AccessA11yView.tsx +6 -21
  132. package/src/console/ui/access/a11y.test.tsx +3 -12
  133. package/src/console/ui/access/acknowledgement.test.ts +1 -4
  134. package/src/console/ui/access/acknowledgement.ts +1 -3
  135. package/src/console/ui/access/blast-radius.ts +1 -3
  136. package/src/console/ui/access/confirmation.test.ts +1 -5
  137. package/src/console/ui/access/confirmation.ts +1 -4
  138. package/src/console/ui/access/fixture.ts +1 -5
  139. package/src/console/ui/access/grantable.test.ts +1 -3
  140. package/src/console/ui/access/grantable.ts +2 -7
  141. package/src/console/ui/access/index.ts +2 -9
  142. package/src/console/ui/access/provenance.test.ts +1 -3
  143. package/src/console/ui/access/provenance.ts +2 -6
  144. package/src/console/ui/access/search.test.ts +1 -5
  145. package/src/console/ui/access/search.ts +2 -6
  146. package/src/console/ui/ai/AiA11yView.tsx +6 -17
  147. package/src/console/ui/ai/a11y.test.tsx +2 -5
  148. package/src/console/ui/ai/fixture.ts +2 -7
  149. package/src/console/ui/ai/format.ts +1 -3
  150. package/src/console/ui/ai/group.test.ts +1 -3
  151. package/src/console/ui/ai/group.ts +4 -12
  152. package/src/console/ui/ai/index.ts +2 -9
  153. package/src/console/ui/ai/promotion.test.ts +2 -7
  154. package/src/console/ui/ai/promotion.ts +4 -13
  155. package/src/console/ui/ai/search.test.ts +2 -11
  156. package/src/console/ui/ai/search.ts +3 -13
  157. package/src/console/ui/ai/types.ts +1 -8
  158. package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
  159. package/src/console/ui/architecture/a11y.test.tsx +1 -2
  160. package/src/console/ui/architecture/declared.ts +1 -5
  161. package/src/console/ui/architecture/index.ts +7 -35
  162. package/src/console/ui/architecture/layout.ts +1 -3
  163. package/src/console/ui/architecture/pathologies.ts +10 -19
  164. package/src/console/ui/architecture/search.ts +6 -15
  165. package/src/console/ui/architecture/traffic.ts +4 -14
  166. package/src/console/ui/architecture/types.ts +2 -10
  167. package/src/console/ui/architecture/view.test.ts +7 -19
  168. package/src/console/ui/architecture/view.ts +9 -36
  169. package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
  170. package/src/console/ui/channels/a11y.test.tsx +1 -2
  171. package/src/console/ui/channels/confirmation.test.ts +1 -4
  172. package/src/console/ui/channels/confirmation.ts +1 -4
  173. package/src/console/ui/channels/findings.ts +1 -5
  174. package/src/console/ui/channels/index.ts +2 -8
  175. package/src/console/ui/channels/locale.test.ts +1 -3
  176. package/src/console/ui/channels/locale.ts +2 -8
  177. package/src/console/ui/channels/search.ts +4 -13
  178. package/src/console/ui/channels/taxonomy.ts +1 -3
  179. package/src/console/ui/clock/ClockA11yView.tsx +9 -26
  180. package/src/console/ui/clock/a11y.test.tsx +2 -5
  181. package/src/console/ui/clock/confirmation.test.ts +1 -3
  182. package/src/console/ui/clock/confirmation.ts +1 -4
  183. package/src/console/ui/clock/findings.ts +1 -4
  184. package/src/console/ui/clock/health.ts +2 -7
  185. package/src/console/ui/clock/index.ts +2 -10
  186. package/src/console/ui/clock/search.test.ts +1 -3
  187. package/src/console/ui/clock/search.ts +2 -6
  188. package/src/console/ui/clock/timeline.test.ts +1 -3
  189. package/src/console/ui/clock/waiting-on.test.ts +1 -5
  190. package/src/console/ui/clock/waiting-on.ts +2 -7
  191. package/src/console/ui/diff/DiffA11yView.tsx +8 -17
  192. package/src/console/ui/diff/a11y.test.tsx +2 -5
  193. package/src/console/ui/diff/group.test.ts +3 -13
  194. package/src/console/ui/diff/group.ts +2 -8
  195. package/src/console/ui/diff/index.ts +2 -8
  196. package/src/console/ui/diff/search.test.ts +1 -5
  197. package/src/console/ui/diff/search.ts +4 -16
  198. package/src/console/ui/diff/summary.ts +1 -2
  199. package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
  200. package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
  201. package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
  202. package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
  203. package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
  204. package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
  205. package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
  206. package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
  207. package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
  208. package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
  209. package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
  210. package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
  211. package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
  212. package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
  213. package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
  214. package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
  215. package/src/console/ui/dist/index.html +1 -1
  216. package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
  217. package/src/console/ui/flows/a11y.test.tsx +2 -8
  218. package/src/console/ui/flows/buffer.test.ts +3 -11
  219. package/src/console/ui/flows/buffer.ts +4 -11
  220. package/src/console/ui/flows/confirmation.ts +1 -3
  221. package/src/console/ui/flows/contract.test.ts +3 -7
  222. package/src/console/ui/flows/contract.ts +12 -36
  223. package/src/console/ui/flows/graph.test.ts +3 -11
  224. package/src/console/ui/flows/graph.ts +5 -15
  225. package/src/console/ui/flows/index.ts +1 -6
  226. package/src/console/ui/flows/save-as-test.ts +1 -3
  227. package/src/console/ui/flows/search.ts +8 -25
  228. package/src/console/ui/flows/tiers.ts +2 -9
  229. package/src/console/ui/gates/GatesA11yView.tsx +4 -13
  230. package/src/console/ui/gates/a11y.test.tsx +2 -5
  231. package/src/console/ui/gates/audit.ts +1 -3
  232. package/src/console/ui/gates/denial.test.ts +1 -3
  233. package/src/console/ui/gates/denial.ts +4 -12
  234. package/src/console/ui/gates/findings.ts +1 -3
  235. package/src/console/ui/gates/group.test.ts +3 -3
  236. package/src/console/ui/gates/group.ts +3 -11
  237. package/src/console/ui/gates/index.ts +2 -10
  238. package/src/console/ui/gates/search.ts +3 -10
  239. package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
  240. package/src/console/ui/overview/a11y.test.tsx +1 -2
  241. package/src/console/ui/overview/busiest.ts +1 -3
  242. package/src/console/ui/overview/compose.ts +1 -13
  243. package/src/console/ui/overview/cost.ts +34 -38
  244. package/src/console/ui/overview/fixture.ts +21 -26
  245. package/src/console/ui/overview/golden.ts +4 -14
  246. package/src/console/ui/overview/index.ts +2 -9
  247. package/src/console/ui/overview/rank.test.ts +3 -10
  248. package/src/console/ui/overview/rank.ts +2 -7
  249. package/src/console/ui/overview/slo.test.ts +5 -9
  250. package/src/console/ui/overview/slo.ts +6 -23
  251. package/src/console/ui/overview/verdict.ts +3 -10
  252. package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
  253. package/src/console/ui/plugins/a11y.test.tsx +1 -2
  254. package/src/console/ui/plugins/fixture.ts +2 -4
  255. package/src/console/ui/plugins/group.test.ts +1 -3
  256. package/src/console/ui/plugins/group.ts +1 -6
  257. package/src/console/ui/plugins/index.ts +3 -13
  258. package/src/console/ui/plugins/search.ts +7 -19
  259. package/src/console/ui/runs/RunsA11yView.tsx +5 -20
  260. package/src/console/ui/runs/a11y.test.tsx +2 -5
  261. package/src/console/ui/runs/explain.ts +2 -6
  262. package/src/console/ui/runs/group.ts +3 -12
  263. package/src/console/ui/runs/histogram.test.ts +2 -11
  264. package/src/console/ui/runs/histogram.ts +1 -4
  265. package/src/console/ui/runs/index.ts +4 -18
  266. package/src/console/ui/runs/project.ts +2 -6
  267. package/src/console/ui/runs/query.test.ts +1 -3
  268. package/src/console/ui/runs/query.ts +12 -35
  269. package/src/console/ui/runs/search.ts +5 -19
  270. package/src/console/ui/runs/trace-link.test.ts +2 -6
  271. package/src/console/ui/runs/trace-link.ts +4 -16
  272. package/src/console/ui/runs/types.ts +1 -3
  273. package/src/console/ui/shell/App.tsx +2 -10
  274. package/src/console/ui/shell/client.ts +22 -115
  275. package/src/console/ui/shell/components/ui.tsx +1 -4
  276. package/src/console/ui/shell/layout/Shell.tsx +2 -4
  277. package/src/console/ui/shell/main.tsx +31 -96
  278. package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
  279. package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
  280. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
  281. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
  282. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
  283. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
  284. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
  285. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
  286. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
  287. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
  288. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
  289. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
  290. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
  291. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
  292. package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
  293. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
  294. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
  295. package/src/console/ui/shell/setup/Wizard.tsx +3 -5
  296. package/src/console/ui/shell/styles.css +1 -2
  297. package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
  298. package/src/console/ui/signals/a11y.test.tsx +2 -5
  299. package/src/console/ui/signals/confirmation.test.ts +1 -5
  300. package/src/console/ui/signals/confirmation.ts +2 -6
  301. package/src/console/ui/signals/dry-run.ts +1 -3
  302. package/src/console/ui/signals/durable.ts +1 -3
  303. package/src/console/ui/signals/findings.ts +1 -3
  304. package/src/console/ui/signals/group.test.ts +2 -8
  305. package/src/console/ui/signals/group.ts +2 -10
  306. package/src/console/ui/signals/index.ts +1 -4
  307. package/src/console/ui/signals/monitor.ts +2 -7
  308. package/src/console/ui/signals/schema-form.test.ts +3 -14
  309. package/src/console/ui/signals/schema-form.ts +1 -4
  310. package/src/console/ui/signals/search.ts +4 -13
  311. package/src/console/ui/store/StoreA11yView.tsx +3 -9
  312. package/src/console/ui/store/a11y.test.tsx +2 -5
  313. package/src/console/ui/store/confirmation.test.ts +1 -3
  314. package/src/console/ui/store/confirmation.ts +1 -4
  315. package/src/console/ui/store/dry-run.ts +2 -5
  316. package/src/console/ui/store/fixture.ts +1 -2
  317. package/src/console/ui/store/group.test.ts +1 -6
  318. package/src/console/ui/store/group.ts +1 -4
  319. package/src/console/ui/store/index.ts +1 -5
  320. package/src/console/ui/store/search.ts +2 -6
  321. package/src/console/ui/store/will-not-fire.ts +1 -2
  322. package/src/console/ui/traces/TracesA11yView.tsx +10 -29
  323. package/src/console/ui/traces/a11y.test.tsx +1 -2
  324. package/src/console/ui/traces/chain.test.ts +5 -19
  325. package/src/console/ui/traces/chain.ts +1 -3
  326. package/src/console/ui/traces/critical-path.test.ts +1 -3
  327. package/src/console/ui/traces/critical-path.ts +2 -6
  328. package/src/console/ui/traces/filter.test.ts +2 -6
  329. package/src/console/ui/traces/filter.ts +5 -13
  330. package/src/console/ui/traces/fold.test.ts +4 -12
  331. package/src/console/ui/traces/fold.ts +1 -3
  332. package/src/console/ui/traces/mini.ts +1 -3
  333. package/src/console/ui/traces/replay.test.ts +1 -3
  334. package/src/console/ui/traces/replay.ts +1 -3
  335. package/src/console/ui/traces/sampling.ts +1 -4
  336. package/src/console/ui/traces/search.ts +4 -17
  337. package/src/console/ui/traces/tier.ts +1 -3
  338. package/src/console/ui/vault/VaultA11yView.tsx +5 -17
  339. package/src/console/ui/vault/a11y.test.tsx +1 -2
  340. package/src/console/ui/vault/blast-radius.ts +1 -3
  341. package/src/console/ui/vault/confirmation.test.ts +1 -5
  342. package/src/console/ui/vault/confirmation.ts +1 -4
  343. package/src/console/ui/vault/dormant.test.ts +1 -4
  344. package/src/console/ui/vault/export-safe.test.ts +1 -5
  345. package/src/console/ui/vault/export-safe.ts +1 -4
  346. package/src/console/ui/vault/fixture.ts +3 -3
  347. package/src/console/ui/vault/group.ts +1 -2
  348. package/src/console/ui/vault/index.ts +2 -10
  349. package/src/console/ui/vault/search.ts +2 -6
  350. package/src/console/ui/vault/types.ts +1 -1
  351. package/src/console/xss.gate.test.ts +1 -3
  352. package/src/docker/compose.ts +112 -20
  353. package/src/docker/derive.ts +5 -19
  354. package/src/docker/docker.test.ts +15 -15
  355. package/src/docker/dockerfile.integration.test.ts +12 -21
  356. package/src/docker/helpers.ts +5 -4
  357. package/src/docker/index.ts +4 -11
  358. package/src/docker/pin.ts +1 -9
  359. package/src/docker/recipes/index.ts +5 -6
  360. package/src/docker/recipes/mailpit.ts +22 -0
  361. package/src/docker/recipes/postgres.ts +17 -6
  362. package/src/docker/recipes/redis.ts +6 -1
  363. package/src/docker/recipes/rustfs.ts +33 -0
  364. package/src/docker/stack-id.test.ts +33 -0
  365. package/src/docker/stack-id.ts +25 -13
  366. package/src/docker/stack.integration.test.ts +6 -21
  367. package/src/docker/types.ts +13 -4
  368. package/src/drivers/ai-anthropic.ts +5 -14
  369. package/src/drivers/ai-mock.ts +2 -5
  370. package/src/drivers/ai-openai-compatible.ts +4 -10
  371. package/src/drivers/ai-providers.test.ts +6 -13
  372. package/src/drivers/bun-native-completeness.test.ts +6 -15
  373. package/src/drivers/channel-console.ts +6 -7
  374. package/src/drivers/channel-fcm.ts +20 -30
  375. package/src/drivers/channel-resend.ts +1 -3
  376. package/src/drivers/channel-smtp.ts +2 -6
  377. package/src/drivers/channel-types.ts +2 -12
  378. package/src/drivers/channel-unifonic.ts +2 -6
  379. package/src/drivers/channel-wa-cloud.ts +2 -6
  380. package/src/drivers/channel-webpush.ts +21 -60
  381. package/src/drivers/conformance.test.ts +2 -10
  382. package/src/drivers/conformance.ts +8 -21
  383. package/src/drivers/fs.ts +2 -8
  384. package/src/drivers/index.ts +12 -56
  385. package/src/drivers/memory.ts +14 -41
  386. package/src/drivers/pgvector.ts +7 -11
  387. package/src/drivers/postgres.ts +7 -13
  388. package/src/drivers/redis.ts +13 -37
  389. package/src/drivers/s3.ts +5 -17
  390. package/src/drivers/signal-engine.ts +12 -49
  391. package/src/drivers/signal-memory.ts +2 -8
  392. package/src/drivers/signal-nats.ts +4 -9
  393. package/src/drivers/signal-postgres.ts +62 -129
  394. package/src/drivers/signal-redis.ts +7 -21
  395. package/src/drivers/signal-types.ts +1 -4
  396. package/src/drivers/sqlite.ts +3 -12
  397. package/src/drivers/types.ts +4 -23
  398. package/src/drivers/vault-env.ts +2 -6
  399. package/src/drivers/vault-infisical.ts +1 -5
  400. package/src/drivers/vault-managed.ts +1 -5
  401. package/src/drivers/vault-memory.ts +1 -5
  402. package/src/drivers/vault-openbao.ts +1 -5
  403. package/src/drivers/vault-sops.ts +10 -35
  404. package/src/drivers/vault-types.ts +1 -7
  405. package/src/elements/ai/declare.ts +4 -14
  406. package/src/elements/ai/eval.ts +2 -6
  407. package/src/elements/ai/pii.ts +1 -3
  408. package/src/elements/ai/runtime.ts +12 -50
  409. package/src/elements/ai/schema.ts +4 -15
  410. package/src/elements/ai.test.ts +13 -24
  411. package/src/elements/ai.ts +1 -5
  412. package/src/elements/channel/consent.ts +3 -12
  413. package/src/elements/channel/costs.ts +4 -15
  414. package/src/elements/channel/declare.ts +1 -4
  415. package/src/elements/channel/email-auth.ts +1 -4
  416. package/src/elements/channel/locale.ts +2 -10
  417. package/src/elements/channel/mask.ts +1 -3
  418. package/src/elements/channel/mime.ts +2 -12
  419. package/src/elements/channel/outcomes.test.ts +1 -5
  420. package/src/elements/channel/outcomes.ts +5 -15
  421. package/src/elements/channel/receipts.ts +2 -7
  422. package/src/elements/channel/runtime.ts +28 -74
  423. package/src/elements/channel/suppression.ts +8 -14
  424. package/src/elements/channel.test.ts +8 -31
  425. package/src/elements/channel.ts +3 -14
  426. package/src/elements/clock/actions.ts +6 -18
  427. package/src/elements/clock/declare.ts +1 -3
  428. package/src/elements/clock/dst.ts +1 -5
  429. package/src/elements/clock/durable.ts +4 -16
  430. package/src/elements/clock/health.ts +2 -7
  431. package/src/elements/clock/leader.ts +2 -9
  432. package/src/elements/clock/reconcile.ts +4 -15
  433. package/src/elements/clock/runtime.ts +2 -5
  434. package/src/elements/clock/schedule.ts +4 -20
  435. package/src/elements/clock.test.ts +2 -7
  436. package/src/elements/clock.ts +5 -23
  437. package/src/elements/gate/permissions.ts +1 -4
  438. package/src/elements/gate/runtime.ts +7 -28
  439. package/src/elements/gate.ts +1 -5
  440. package/src/elements/index.ts +9 -7
  441. package/src/elements/signal/declare.ts +2 -7
  442. package/src/elements/signal/reconcile.test.ts +1 -4
  443. package/src/elements/signal/runtime.ts +1 -3
  444. package/src/elements/signal.test.ts +3 -15
  445. package/src/elements/signal.ts +2 -8
  446. package/src/elements/store/cache.test.ts +46 -0
  447. package/src/elements/store/cache.ts +3 -11
  448. package/src/elements/store/classify.ts +5 -22
  449. package/src/elements/store/declare.ts +8 -17
  450. package/src/elements/store/domain-ddl.test.ts +86 -0
  451. package/src/elements/store/emit-drizzle.ts +363 -0
  452. package/src/elements/store/files-policy.test.ts +1 -5
  453. package/src/elements/store/files-policy.ts +4 -12
  454. package/src/elements/store/load-plugin-tables.ts +103 -0
  455. package/src/elements/store/missing-relation.test.ts +83 -0
  456. package/src/elements/store/missing-relation.ts +38 -0
  457. package/src/elements/store/replica.ts +1 -4
  458. package/src/elements/store/runtime.ts +25 -28
  459. package/src/elements/store/schema-decl.test.ts +227 -0
  460. package/src/elements/store/schema-decl.ts +516 -0
  461. package/src/elements/store/sql-condition.ts +11 -21
  462. package/src/elements/store/sql-session.test.ts +50 -0
  463. package/src/elements/store/sql-session.ts +60 -63
  464. package/src/elements/store/table.ts +35 -19
  465. package/src/elements/store.test.ts +17 -39
  466. package/src/elements/store.ts +37 -31
  467. package/src/elements/vault/chain.ts +34 -0
  468. package/src/elements/vault/declare.ts +22 -32
  469. package/src/elements/vault/fingerprint.ts +2 -7
  470. package/src/elements/vault/redact.ts +2 -6
  471. package/src/elements/vault/runtime.ts +18 -32
  472. package/src/elements/vault.test.ts +12 -28
  473. package/src/elements/vault.ts +8 -12
  474. package/src/index.ts +5 -2
  475. package/src/kernel/adopt-routes.ts +15 -29
  476. package/src/kernel/app.ts +34 -94
  477. package/src/kernel/auth-resolve.ts +2 -9
  478. package/src/kernel/boot-bind/ai.ts +1 -4
  479. package/src/kernel/boot-bind/channel.ts +2 -8
  480. package/src/kernel/boot-bind/clock.ts +2 -6
  481. package/src/kernel/boot-bind/gate.ts +2 -8
  482. package/src/kernel/boot-bind/runs.ts +1 -3
  483. package/src/kernel/boot-bind/signal.ts +3 -10
  484. package/src/kernel/boot-bind/store.test.ts +17 -17
  485. package/src/kernel/boot-bind/store.ts +44 -50
  486. package/src/kernel/boot-bind/vault.ts +2 -8
  487. package/src/kernel/boot.test.ts +4 -9
  488. package/src/kernel/boot.ts +29 -76
  489. package/src/kernel/budget.test.ts +1 -3
  490. package/src/kernel/capability.ts +3 -10
  491. package/src/kernel/dry-run.test.ts +1 -4
  492. package/src/kernel/dry-run.ts +3 -11
  493. package/src/kernel/effects.test.ts +1 -5
  494. package/src/kernel/effects.ts +4 -11
  495. package/src/kernel/errors.registry.test.ts +2 -8
  496. package/src/kernel/errors.ts +23 -32
  497. package/src/kernel/flow.test.ts +12 -25
  498. package/src/kernel/flow.ts +5 -25
  499. package/src/kernel/fx.test.ts +15 -44
  500. package/src/kernel/fx.ts +27 -79
  501. package/src/kernel/hook-timing.test.ts +3 -6
  502. package/src/kernel/hook-timing.ts +5 -14
  503. package/src/kernel/hooks.test.ts +10 -10
  504. package/src/kernel/hooks.ts +3 -12
  505. package/src/kernel/index.ts +4 -17
  506. package/src/kernel/journal.ts +7 -31
  507. package/src/kernel/on.ts +1 -6
  508. package/src/kernel/pipeline.test.ts +10 -19
  509. package/src/kernel/pipeline.ts +5 -17
  510. package/src/kernel/plug.ts +4 -11
  511. package/src/kernel/plugin/conflicts.test.ts +13 -25
  512. package/src/kernel/plugin/decorate.test.ts +8 -13
  513. package/src/kernel/plugin/scoping.test.ts +4 -11
  514. package/src/kernel/plugin.ts +48 -24
  515. package/src/kernel/registry.ts +80 -29
  516. package/src/kernel/router.test.ts +15 -13
  517. package/src/kernel/router.ts +9 -29
  518. package/src/kernel/routing-budget.test.ts +1 -3
  519. package/src/kernel/run-telemetry.ts +1 -3
  520. package/src/kernel/triggers.ts +4 -21
  521. package/src/manifest/diff.test.ts +26 -91
  522. package/src/manifest/diff.ts +95 -225
  523. package/src/manifest/index.ts +2 -9
  524. package/src/manifest/types.ts +29 -5
  525. package/src/manifest/undeclared.test.ts +4 -12
  526. package/src/manifest/undeclared.ts +1 -2
  527. package/src/manifest/validate.test.ts +2 -6
  528. package/src/manifest/validate.ts +4 -14
  529. package/src/mcp/authorization.ts +8 -27
  530. package/src/mcp/confirmation.ts +3 -10
  531. package/src/mcp/data.ts +2 -6
  532. package/src/mcp/docs-index.ts +4 -7
  533. package/src/mcp/docs-mcp.test.ts +3 -12
  534. package/src/mcp/docs-server.ts +7 -27
  535. package/src/mcp/docs-tools.ts +2 -6
  536. package/src/mcp/index.ts +1 -6
  537. package/src/mcp/injection.gate.test.ts +4 -18
  538. package/src/mcp/mcp.test.ts +18 -49
  539. package/src/mcp/protocol.ts +3 -10
  540. package/src/mcp/server.ts +11 -52
  541. package/src/mcp/session.ts +4 -14
  542. package/src/mcp/tools.ts +14 -50
  543. package/src/plugins/catalogue.test.ts +3 -7
  544. package/src/plugins/catalogue.ts +1 -3
  545. package/src/plugins/node-import-scan.ts +2 -5
  546. package/src/plugins/supply-chain.ts +5 -17
  547. package/src/release/exports.ts +3 -8
  548. package/src/release/measure.exports.test.ts +1 -3
  549. package/src/release/measure.ts +15 -43
  550. package/src/runs/bench.test.ts +1 -3
  551. package/src/runs/collect.ts +8 -25
  552. package/src/runs/drivers/clickhouse.ts +2 -9
  553. package/src/runs/drivers/files.ts +9 -31
  554. package/src/runs/drivers/memory.ts +5 -22
  555. package/src/runs/drivers/postgres.ts +8 -20
  556. package/src/runs/duckdb.ts +2 -8
  557. package/src/runs/index.ts +3 -14
  558. package/src/runs/outlier.ts +3 -10
  559. package/src/runs/parquet.ts +8 -26
  560. package/src/runs/privacy.ts +2 -8
  561. package/src/runs/runs.test.ts +3 -9
  562. package/src/runs/runtime.ts +7 -32
  563. package/src/runs/shred.ts +10 -29
  564. package/src/runs/types.ts +1 -4
  565. package/src/runtime/bun.ts +4 -15
  566. package/src/runtime/cold-start.bench.ts +1 -3
  567. package/src/runtime/dev-request-log.test.ts +1 -4
  568. package/src/runtime/dev-request-log.ts +1 -4
  569. package/src/runtime/index.ts +1 -6
  570. package/src/runtime/primitives.ts +5 -4
  571. package/src/runtime/security.ts +3 -13
  572. package/src/runtime/serve.test.ts +4 -7
  573. package/src/runtime/types.ts +1 -4
  574. package/src/runtime/web-standard.ts +3 -15
  575. package/src/term.test.ts +4 -6
  576. package/src/term.ts +49 -98
  577. package/src/test/create-test-app.test.ts +4 -14
  578. package/src/test/create-test-app.ts +13 -31
  579. package/src/test/provisions.integration.test.ts +3 -11
  580. package/src/upgrade/codemods.test.ts +25 -6
  581. package/src/upgrade/codemods.ts +116 -3
  582. package/src/validation/standard-schema.test.ts +2 -5
  583. package/src/validation/standard-schema.ts +13 -33
  584. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
@@ -13,7 +13,7 @@
13
13
 
14
14
  Hono, Elysia, Encore, iii, NestJS, Nitro — and everything before them — share one hidden flaw: **they are collections of separate inventions bundled behind a single logo.** A router, plus a queue library, plus a cron library, plus a websocket layer, plus a tracing integration. The concepts don't derive from one another; they merely ship together.
15
15
 
16
- That is why frameworks bloat, why their documentation sprawls into dozens of unrelated pages, and why none of them survives a decade intact. Each new infrastructure fashion adds a *concept*, and concepts never get removed.
16
+ That is why frameworks bloat, why their documentation sprawls into dozens of unrelated pages, and why none of them survives a decade intact. Each new infrastructure fashion adds a _concept_, and concepts never get removed.
17
17
 
18
18
  ## 2. The move
19
19
 
@@ -25,21 +25,19 @@ If the laws are right, the framework stays complete for a hundred years regardle
25
25
 
26
26
  > **OKE is the batteries-included TypeScript backend for the Bun era:** contract-first APIs with end-to-end type safety, declarative infrastructure primitives, an OpenTelemetry-native Console, secure-by-default auth and ABAC — pure TypeScript, Web-Standards portable, MIT-licensed, self-hostable with zero cloud lock-in.
27
27
 
28
- *"Encore's batteries and dashboard, Elysia's speed and DX, Hono's portability — without the Rust lock-in, the cloud gravity, or the source-available license."*
29
-
30
- | | Hono | Elysia | Encore.ts | iii | **OKE** |
31
- |---|---|---|---|---|---|
32
- | Primary runtime | Multi (Web Std) | Bun-first | Node + Rust core | Rust engine, polyglot | **Bun-first, Web-Std portable** |
33
- | License | MIT | MIT | MPL-2.0 | ELv2 engine | **MIT** |
34
- | Typed client | hc RPC | Eden Treaty | generated | SDK | **contract-first + live queries** |
35
- | DB · queue · cron · storage | ❌ | ❌ | ✅ | ✅ | **✅ (7 elements)** |
36
- | Durable workflows | ❌ | ❌ | ❌ | partial | **✅ (a flag)** |
37
- | Local Console | ❌ | ❌ | | | **✅ (dev + prod)** |
38
- | Auto cache invalidation | ❌ | ❌ | ❌ | ❌ | **✅ (from effects)** |
39
- | Least-privilege by compiler | ❌ | ❌ | ❌ | ❌ | **✅** |
40
- | Human channels (email/SMS/WA) | | | | | **✅ (7th element)** |
41
- | AI in the application (models, prompts, agents) | ❌ | ❌ | ❌ | ❌ | **✅ (8th element)** |
42
- | Self-host, no lock-in | ✅ | ✅ | ✅ (Cloud optional) | ⚠️ | **✅ first-class** |
28
+ | | Hono | Elysia | Encore.ts | iii | **OKE** |
29
+ | ----------------------------------------------- | --------------- | ----------- | ------------------- | --------------------- | --------------------------------- |
30
+ | Primary runtime | Multi (Web Std) | Bun-first | Node + Rust core | Rust engine, polyglot | **Bun-first, Web-Std portable** |
31
+ | License | MIT | MIT | MPL-2.0 | ELv2 engine | **MIT** |
32
+ | Typed client | hc RPC | Eden Treaty | generated | SDK | **contract-first + live queries** |
33
+ | DB · queue · cron · storage | ❌ | | ✅ | | **✅ (7 elements)** |
34
+ | Durable workflows | | | | partial | **✅ (a flag)** |
35
+ | Local Console | ❌ | ❌ | ✅ | ✅ | **✅ (dev + prod)** |
36
+ | Auto cache invalidation | ❌ | ❌ | ❌ | | **✅ (from effects)** |
37
+ | Least-privilege by compiler | ❌ | ❌ | | | **✅** |
38
+ | Human channels (email/SMS/WA) | ❌ | ❌ | ❌ | ❌ | **✅ (7th element)** |
39
+ | AI in the application (models, prompts, agents) | ❌ | ❌ | ❌ | ❌ | **✅ (8th element)** |
40
+ | Self-host, no lock-in | | | (Cloud optional) | ⚠️ | **✅ first-class** |
43
41
 
44
42
  ---
45
43
 
@@ -52,9 +50,9 @@ If the laws are right, the framework stays complete for a hundred years regardle
52
50
  There are no separate species called "endpoints", "handlers", "consumers", "jobs", "subscribers", or "workflows". There is one species — the **Flow** — and triggers are typed values:
53
51
 
54
52
  ```typescript
55
- on(http.post("/bookings"), createBooking); // "an API endpoint"
56
- on(every("10m"), expireStale); // "a cron job"
57
- on(orderPlaced, sendReceipt); // "a queue consumer"
53
+ on(http.post("/bookings"), createBooking); // "an API endpoint"
54
+ on(every("10m"), expireStale); // "a cron job"
55
+ on(orderPlaced, sendReceipt); // "a queue consumer"
58
56
  on(db.table(users).changed("email"), reverify); // "a CDC trigger"
59
57
  ```
60
58
 
@@ -66,16 +64,16 @@ One law → one mental model → one documentation page → one hook pipeline
66
64
 
67
65
  Everything a backend has ever needed reduces to eight typed elements. An element earns its place **only if it has irreducible physics.** New infrastructure becomes a new driver for an existing element — never a ninth element.
68
66
 
69
- | Element | Replaces the zoo of | Essence |
70
- |---|---|---|
71
- | **Flow** | endpoint · handler · consumer · job · workflow · webhook | behavior |
72
- | **Signal** | queue · pub/sub · stream · websocket · SSE · event bus | data in motion |
73
- | **Store** | database · cache · KV · file storage · search index | data at rest (`sql` · `kv` · `files` · `index`) |
74
- | **Clock** | cron · delay · timeout · durable sleep · TTL | time |
75
- | **Gate** | auth · session · ABAC · rate limit · quota · feature flag | permission to act |
76
- | **Vault** | secrets · config · environment | protected knowledge |
77
- | **Channel** | email · SMS · WhatsApp · push | reaching humans |
78
- | **AI** | model calls · prompts · embeddings · agents · RAG | reaching machine intelligence |
67
+ | Element | Replaces the zoo of | Essence |
68
+ | ----------- | --------------------------------------------------------- | ----------------------------------------------- |
69
+ | **Flow** | endpoint · handler · consumer · job · workflow · webhook | behavior |
70
+ | **Signal** | queue · pub/sub · stream · websocket · SSE · event bus | data in motion |
71
+ | **Store** | database · cache · KV · file storage · search index | data at rest (`sql` · `kv` · `files` · `index`) |
72
+ | **Clock** | cron · delay · timeout · durable sleep · TTL | time |
73
+ | **Gate** | auth · session · ABAC · rate limit · quota · feature flag | permission to act |
74
+ | **Vault** | secrets · config · environment | protected knowledge |
75
+ | **Channel** | email · SMS · WhatsApp · push | reaching humans |
76
+ | **AI** | model calls · prompts · embeddings · agents · RAG | reaching machine intelligence |
79
77
 
80
78
  ### Why queue, pub/sub, and stream collapse into one Signal
81
79
 
@@ -84,10 +82,11 @@ They were always the same object with different **delivery physics**. So deliver
84
82
  ```typescript
85
83
  export const orderPlaced = signal("order-placed", {
86
84
  schema: z.object({ orderId: z.string() }),
87
- delivery: "once", // "once" → queue semantics: competing consumers, retries, DLQ
88
- // "broadcast" → pub/sub semantics: fan-out to every subscriber
89
- // "live" → stream semantics: client-subscribable, replayable
90
- retries: 5, deadLetter: true,
85
+ delivery: "once", // "once" → queue semantics: competing consumers, retries, DLQ
86
+ // "broadcast" → pub/sub semantics: fan-out to every subscriber
87
+ // "live" → stream semantics: client-subscribable, replayable
88
+ retries: 5,
89
+ deadLetter: true,
91
90
  });
92
91
  ```
93
92
 
@@ -101,21 +100,21 @@ Reaching a human has physics that machine messaging does not: localized template
101
100
 
102
101
  Apply the same test — does it have physics no existing element expresses?
103
102
 
104
- | What an AI-powered backend needs | Covered by an existing element? |
105
- |---|---|
106
- | streaming tokens to the client | ✅ `Signal` with `delivery: "live"` |
107
- | an agent loop with steps | ✅ `Flow` with `durable: true` |
108
- | vector search for RAG | ✅ `Store` facet `index` |
109
- | provider fallback chains | ✅ same pattern as `Channel` |
110
- | **non-determinism** (same input ≠ same output) | ❌ breaks caching, testing, and replay |
111
- | **cost as a first-class dimension** | ❌ no element has a concept of price per call |
112
- | **prompts as versioned, evaluated artifacts** | ❌ neither a template nor a schema |
113
- | **egress privacy boundaries** to third parties | ❌ Gates guard entry, not exit |
114
- | **testing a non-deterministic output** | ❌ entirely different test physics |
103
+ | What an AI-powered backend needs | Covered by an existing element? |
104
+ | ---------------------------------------------- | --------------------------------------------- |
105
+ | streaming tokens to the client | ✅ `Signal` with `delivery: "live"` |
106
+ | an agent loop with steps | ✅ `Flow` with `durable: true` |
107
+ | vector search for RAG | ✅ `Store` facet `index` |
108
+ | provider fallback chains | ✅ same pattern as `Channel` |
109
+ | **non-determinism** (same input ≠ same output) | ❌ breaks caching, testing, and replay |
110
+ | **cost as a first-class dimension** | ❌ no element has a concept of price per call |
111
+ | **prompts as versioned, evaluated artifacts** | ❌ neither a template nor a schema |
112
+ | **egress privacy boundaries** to third parties | ❌ Gates guard entry, not exit |
113
+ | **testing a non-deterministic output** | ❌ entirely different test physics |
115
114
 
116
115
  Five properties are irreducible, so AI earns the eighth slot.
117
116
 
118
- **On the tension with our own rule.** "New technology is a driver, not a concept" still holds — Anthropic → Bedrock → a 2030 provider are all drivers. But probabilistic inference is not new *infrastructure*; it is a new *category of interaction*. The symmetry is exact: **Channel reaches humans, AI reaches machine intelligence.** Neither can be expressed by Store or Signal.
117
+ **On the tension with our own rule.** "New technology is a driver, not a concept" still holds — Anthropic → Bedrock → a 2030 provider are all drivers. But probabilistic inference is not new _infrastructure_; it is a new _category of interaction_. The symmetry is exact: **Channel reaches humans, AI reaches machine intelligence.** Neither can be expressed by Store or Signal.
119
118
 
120
119
  ## 6. Ten exports
121
120
 
@@ -135,12 +134,17 @@ Every Flow's **effects are part of its type**, inferred by the compiler from wha
135
134
 
136
135
  ```typescript
137
136
  const createBooking = flow({
138
- in: CreateBooking, out: BookingId, errors: { FlightFull },
137
+ in: CreateBooking,
138
+ out: BookingId,
139
+ errors: { FlightFull },
139
140
  do: async (input, fx) => {
140
141
  const left = await fx.store(db).countAvailable(input.flightId);
141
142
  if (left < input.seats) return fx.fail("FlightFull", { seatsLeft: left });
142
143
  const id = fx.id();
143
- await fx.store(db).insert(bookings).values({ id, ...input });
144
+ await fx
145
+ .store(db)
146
+ .insert(bookings)
147
+ .values({ id, ...input });
144
148
  await fx.emit(orderPlaced, { orderId: id });
145
149
  return { id };
146
150
  },
@@ -150,24 +154,26 @@ const createBooking = flow({
150
154
 
151
155
  Because effects are known statically, the following are **derived with zero extra code** — no framework has combined them before:
152
156
 
153
- | # | Capability | How it falls out |
154
- |---|---|---|
155
- | 1 | **Automatic cache invalidation** | The compiler knows which writes touch the same keys a read used. Invalidation is *computed*, never hand-written. |
156
- | 2 | **Live queries** | Mark a read `.live()`; clients re-render on exactly the writes that affect it. Realtime stops being a separate system. |
157
- | 3 | **Durability as a flag** | `durable: true` journals every effect call; `fx.clock.sleep("7d")` survives deploys. Workflows are ordinary Flows with one option. |
158
- | 4 | **Least privilege by construction** | Each Flow receives a capability token for only its declared effects. A compromised handler cannot touch what it never declared. |
159
- | 5 | **Provably true architecture diagrams** | Edges *are* the declared effects. "What breaks if I change this table?" becomes a compiler query. |
160
- | 6 | **Deterministic tests** | `fx` is the only door — swap it wholesale: memory drivers, frozen clock, recorded effects, golden effect-stream diffs. |
161
- | 7 | **Semantic tree-shaking** | The manifest lists exactly which elements and drivers are used; the build emits only those. |
162
- | 8 | **Transactional messaging** | `fx.emit()` enrolls in the same transaction as `fx.store()` writes — the dual-write bug is eliminated by default. |
163
- | 9 | **Automatic replica routing** | Read-only flows route to read replicas without annotations. |
164
- | 10 | **Time as a dimension** | Journaled effects enable `oke branch prod --at "yesterday"` and replay of a single flow against fixed code. |
165
- | 11 | **Compile-time AI data governance** | Fields tagged `pii` cannot reach a third-party model: the build **fails** unless the flow masks them or declares `allowPii` explicitly. |
166
- | 12 | **Provably bounded agents** | An agent's tools are your own flows, carrying their own gates and capabilities — so an agent physically cannot exceed what the code declares. Safety by structure, not by trusting the model. |
167
- | 13 | **Cost as a visible effect** | The compiler knows which paths call a model, enabling per-flow and per-tenant budgets, cost per endpoint in the Console, and a Manifest Diff that warns *before* deploy: "this release adds ~$0.02 per request." |
157
+ | # | Capability | How it falls out |
158
+ | --- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
159
+ | 1 | **Automatic cache invalidation** | The compiler knows which writes touch the same keys a read used. Invalidation is _computed_, never hand-written. |
160
+ | 2 | **Live queries** | Mark a read `.live()`; clients re-render on exactly the writes that affect it. Realtime stops being a separate system. |
161
+ | 3 | **Durability as a flag** | `durable: true` journals every effect call; `fx.clock.sleep("7d")` survives deploys. Workflows are ordinary Flows with one option. |
162
+ | 4 | **Least privilege by construction** | Each Flow receives a capability token for only its declared effects. A compromised handler cannot touch what it never declared. |
163
+ | 5 | **Provably true architecture diagrams** | Edges _are_ the declared effects. "What breaks if I change this table?" becomes a compiler query. |
164
+ | 6 | **Deterministic tests** | `fx` is the only door — swap it wholesale: memory drivers, frozen clock, recorded effects, golden effect-stream diffs. |
165
+ | 7 | **Semantic tree-shaking** | The manifest lists exactly which elements and drivers are used; the build emits only those. |
166
+ | 8 | **Transactional messaging** | `fx.emit()` enrolls in the same transaction as `fx.store()` writes — the dual-write bug is eliminated by default. |
167
+ | 9 | **Automatic replica routing** | Read-only flows route to read replicas without annotations. |
168
+ | 10 | **Time as a dimension** | Journaled effects enable `oke branch prod --at "yesterday"` and replay of a single flow against fixed code. |
169
+ | 11 | **Compile-time AI data governance** | Fields tagged `pii` cannot reach a third-party model: the build **fails** unless the flow masks them or declares `allowPii` explicitly. |
170
+ | 12 | **Provably bounded agents** | An agent's tools are your own flows, carrying their own gates and capabilities — so an agent physically cannot exceed what the code declares. Safety by structure, not by trusting the model. |
171
+ | 13 | **Cost as a visible effect** | The compiler knows which paths call a model, enabling per-flow and per-tenant budgets, cost per endpoint in the Console, and a Manifest Diff that warns _before_ deploy: "this release adds ~$0.02 per request." |
168
172
 
169
173
  Any one of these would headline a framework launch. All ten follow from one decision: **effects live in the types.**
170
174
 
175
+ **Store constraint:** `fx.store` is a single-table session — one table per call. Multi-table relational queries (Drizzle RQB `db.query.*.findMany({ with: … })`) are outside `fx.store`; effect inference, cache keys, and PII masking all assume a single table. Effects stay exact by composing single-table calls (`fx.store` reads, or `fx.call`), so every table touched appears explicitly in the Manifest.
176
+
171
177
  ## 8. The Manifest — the 100-year artifact
172
178
 
173
179
  Code dies. Frameworks die. **Data formats survive** — SQL is from 1974, HTTP from 1991. So OKE's true product is not the runtime; it is the **Manifest**: a versioned, runtime-neutral, machine-readable description of your entire system, extracted from your TypeScript at build time.
@@ -200,10 +206,10 @@ The Manifest schema is a small formal spec, versioned independently of the runti
200
206
 
201
207
  Two things get called "native." We mean the first, never the second:
202
208
 
203
- | ✅ Native = runtime clients (what we do) | ❌ Native = our own reimplementation (what we don't) |
204
- |---|---|
205
- | `Bun.sql` · `bun:sqlite` · `Bun.redis` · `Bun.S3` · `Bun.password` · `node:crypto` | writing our own cache server, broker, object store, or secrets manager |
206
- | zero npm client dependencies, maximum speed, one runtime API | duplicated effort, worse quality, a decade of other people's bugs to re-fix |
209
+ | ✅ Native = runtime clients (what we do) | ❌ Native = our own reimplementation (what we don't) |
210
+ | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
211
+ | `Bun.sql` · `bun:sqlite` · `Bun.redis` · `Bun.S3` · `Bun.password` · `node:crypto` | writing our own cache server, broker, object store, or secrets manager |
212
+ | zero npm client dependencies, maximum speed, one runtime API | duplicated effort, worse quality, a decade of other people's bugs to re-fix |
207
213
 
208
214
  **We build only what genuinely does not exist:** the effect system, the Manifest and its derivations, the Console, the AoT compiler, the plugin engine, and the thin adapters connecting eight elements to real software.
209
215
 
@@ -213,17 +219,17 @@ Two things get called "native." We mean the first, never the second:
213
219
 
214
220
  Welding a vendor name into the architecture is a design bug. `kv: "dragonfly"` is wrong; `kv: "redis"` is right — it is a protocol, and Valkey, Dragonfly, KeyDB, and Upstash all speak it.
215
221
 
216
- | Element | Driver (protocol / standard) | Any of these work, unchanged |
217
- |---|---|---|
218
- | `store.sql` | `sqlite` · `postgres` | Postgres · Neon · Supabase · RDS · Timescale · pgvector |
219
- | `store.kv` | `memory` · `redis` | Redis · Valkey · Dragonfly · KeyDB · Upstash |
220
- | `store.files` | `fs` · `s3` | AWS S3 · R2 · MinIO · SeaweedFS · RustFS · Garage · Backblaze |
221
- | `signal` | `memory` · `postgres` · `redis` · `nats` · `kafka` | the matching servers, any vendor |
222
- | `clock` | `memory` · `postgres` | — |
223
- | `vault` | `env` · `sops` · `openbao` · `infisical` · managed | — |
224
- | `channel.*` | `smtp` · `resend` · `ses` · `unifonic` · `twilio` · `wa-cloud` · `fcm` | any SMTP server |
225
- | `store.index` | `pgvector` · `qdrant` · `meilisearch` · `typesense` | vector + full-text search for RAG |
226
- | `ai` | `mock` · `anthropic` · `openai-compatible` · `bedrock` · `vertex` · `ollama` | `openai-compatible` covers vLLM, Groq, Together, LM Studio, and most self-hosted servers |
222
+ | Element | Driver (protocol / standard) | Any of these work, unchanged |
223
+ | ------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
224
+ | `store.sql` | `sqlite` · `postgres` | Postgres · Neon · Supabase · RDS · Timescale · pgvector |
225
+ | `store.kv` | `memory` · `redis` | Redis · Valkey · Dragonfly · KeyDB · Upstash |
226
+ | `store.files` | `fs` · `s3` | AWS S3 · R2 · MinIO · SeaweedFS · RustFS · Garage · Backblaze |
227
+ | `signal` | `memory` · `postgres` · `redis` · `nats` · `kafka` | the matching servers, any vendor |
228
+ | `clock` | `memory` · `postgres` | — |
229
+ | `vault` | `env` · `sops` · `openbao` · `infisical` · managed | — |
230
+ | `channel.*` | `smtp` · `resend` · `ses` · `unifonic` · `twilio` · `wa-cloud` · `fcm` | any SMTP server |
231
+ | `store.index` | `pgvector` · `qdrant` · `meilisearch` · `typesense` | vector + full-text search for RAG |
232
+ | `ai` | `mock` · `anthropic` · `openai-compatible` · `bedrock` · `vertex` · `ollama` | `openai-compatible` covers vLLM, Groq, Together, LM Studio, and most self-hosted servers |
227
233
 
228
234
  Vendor choice lives in `images`, keyed by **role**:
229
235
 
@@ -233,11 +239,11 @@ images: { "store.sql": "pgvector/pgvector:pg17", "store.kv": "valkey/valkey:8-al
233
239
 
234
240
  ## 11. Always latest — in three tiers
235
241
 
236
- | Tier | Rule | Why |
237
- |---|---|---|
238
- | **Our own toolchain** | latest always (TypeScript 7, Bun, oxc) | greenfield, no legacy; speed is part of the promise |
239
- | **What we require of users** | conservative floor + day-one support for new majors | a framework demanding bleeding edge loses adoption |
240
- | **Adopted infrastructure** | latest **stable**, pinned by digest | `latest` tags destroy reproducibility |
242
+ | Tier | Rule | Why |
243
+ | ---------------------------- | --------------------------------------------------- | --------------------------------------------------- |
244
+ | **Our own toolchain** | latest always (TypeScript 7, Bun, oxc) | greenfield, no legacy; speed is part of the promise |
245
+ | **What we require of users** | conservative floor + day-one support for new majors | a framework demanding bleeding edge loses adoption |
246
+ | **Adopted infrastructure** | latest **stable**, pinned by digest | `latest` tags destroy reproducibility |
241
247
 
242
248
  **Toolchain decision with teeth:** TypeScript 7 went GA on 8 July 2026 (Go-native, 8–12× faster builds) but ships **without a stable programmatic API until 7.1**. Therefore the Manifest extractor **never uses the TypeScript compiler API** — it uses **oxc** (Rust parser). We gain independence from TypeScript's release cycle, higher speed, and zero exposure to that gap. `tsc` is used for type-checking only.
243
249
 
@@ -267,40 +273,42 @@ images: { "store.sql": "pgvector/pgvector:pg17", "store.kv": "valkey/valkey:8-al
267
273
 
268
274
  ## 13. Core design decisions
269
275
 
270
- | Layer | Decision |
271
- |---|---|
272
- | **Runtime** | Bun-first via `Bun.serve`; Web-Standards adapters for Node/Deno/Edge; target WinterTC Minimum Common Web API |
273
- | **Router** | compiled RegExp matching with a Trie fallback (Hono's SmartRouter idea), linear preset for cold-start edge |
274
- | **Validation** | Standard Schema — bring Zod 4, Valibot, ArkType, TypeBox |
275
- | **AoT compiler** | Sucrose-style static analysis generates a minimal per-route parse/validate handler; **`aot: false` dynamic fallback** for `eval`-restricted runtimes |
276
- | **Context** | per-request `fx` object with typed composition (`derive`/`decorate`); no decorator DI |
277
- | **Infrastructure** | driver model (Nitro/unstorage-style): dev = memory/sqlite/fs ⇄ prod = real software |
278
- | **Contracts** | schema in / schema out / typed errors → end-to-end types, OpenAPI, AsyncAPI, typed client |
279
- | **Auth** | built-in flagship (hybrid JWT + revocable refresh, ABAC, MFA); provider seam for better-auth, Clerk, Supabase, Auth0, Kinde |
280
- | **AI** | MCP server exposing catalog, schemas, effects, traces, and safe runtime actions |
276
+ | Layer | Decision |
277
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
278
+ | **Runtime** | Bun-first via `Bun.serve`; Web-Standards adapters for Node/Deno/Edge; target WinterTC Minimum Common Web API |
279
+ | **Router** | compiled RegExp matching with a Trie fallback (Hono's SmartRouter idea), linear preset for cold-start edge |
280
+ | **Validation** | Standard Schema — bring Zod 4, Valibot, ArkType, TypeBox |
281
+ | **AoT compiler** | Sucrose-style static analysis generates a minimal per-route parse/validate handler; **`aot: false` dynamic fallback** for `eval`-restricted runtimes |
282
+ | **Context** | per-request `fx` object with typed composition (`derive`/`decorate`); no decorator DI |
283
+ | **Infrastructure** | driver model (Nitro/unstorage-style): dev = memory/sqlite/fs ⇄ prod = real software |
284
+ | **Contracts** | schema in / schema out / typed errors → end-to-end types, OpenAPI, AsyncAPI, typed client |
285
+ | **Auth** | built-in flagship (hybrid JWT + revocable refresh, ABAC, MFA); provider seam for better-auth, Clerk, Supabase, Auth0, Kinde |
286
+ | **AI** | MCP server exposing catalog, schemas, effects, traces, and safe runtime actions |
281
287
 
282
288
  ## 14. Plugins — the extensibility law
283
289
 
284
290
  A plugin is a function that receives the app, adds capabilities, and returns it **with accumulated types.** A plugin may contribute: flows, hooks, context decorations, elements, drivers, image recipes, DB schema, typed errors, client extensions, CLI commands, and Console panels.
285
291
 
292
+ Plugins may declare additional tables (with columns) that are merged into the generated domain schema. At `oke db` time the CLI loads the live app entry (`src/app.ts` / `db.entry`), reads plugged plugins’ table contributions, and emits them alongside app `store.schema.table` decls into `schema.generated.ts`. Extending an existing app-owned table with plugin columns is not supported in v1 — contribute a separate table instead.
293
+
286
294
  > **Guarantee:** every built-in feature — auth, Console, docker derivation, channels — uses only the public plugin API. If the core team ever needs a private hook, the API is broken and gets fixed.
287
295
 
288
296
  ## 15. The Console (`:6533`)
289
297
 
290
298
  Reads truth from the Manifest + OpenTelemetry. Runs in **development and production** (production behind authentication).
291
299
 
292
- | Panel | Answers |
293
- |---|---|
294
- | **Catalog** | what exists — every flow, trigger, gate, schema, effect |
295
- | **Architecture** | how it connects — a diagram that *is* the code |
296
- | **API Explorer** | typed request forms; impersonate any scope set |
297
- | **Traces** | one OTel trace across http → store → signal → durable steps |
298
- | **Store** | DB explorer, files browser, replica lag, computed cache keys |
299
- | **Signals** | queue depth, in-flight, DLQ contents, live-feed monitors |
300
- | **Clock** | upcoming crons, sleeping durable flows ("wakes in 6d 22h") |
301
- | **Gates** | permission matrix, rate-limit counters, MFA enforcement |
302
- | **Channels** | outbound messages, delivery receipts, bounces, opt-outs |
303
- | **Manifest Diff** | blast radius of a deploy: new effects, widened permissions |
300
+ | Panel | Answers |
301
+ | ----------------- | ------------------------------------------------------------ |
302
+ | **Catalog** | what exists — every flow, trigger, gate, schema, effect |
303
+ | **Architecture** | how it connects — a diagram that _is_ the code |
304
+ | **API Explorer** | typed request forms; impersonate any scope set |
305
+ | **Traces** | one OTel trace across http → store → signal → durable steps |
306
+ | **Store** | DB explorer, files browser, replica lag, computed cache keys |
307
+ | **Signals** | queue depth, in-flight, DLQ contents, live-feed monitors |
308
+ | **Clock** | upcoming crons, sleeping durable flows ("wakes in 6d 22h") |
309
+ | **Gates** | permission matrix, rate-limit counters, MFA enforcement |
310
+ | **Channels** | outbound messages, delivery receipts, bounces, opt-outs |
311
+ | **Manifest Diff** | blast radius of a deploy: new effects, widened permissions |
304
312
 
305
313
  **The constitutional rule:** the Console **reads truth and writes only through git.** Runtime actions (replay a DLQ message, trigger a cron, wake a durable flow) execute directly. Structural changes (add an index, raise retries) are emitted as **reviewable diffs into your working tree** — you approve, git records. Every element deep-links to the exact line in Cursor.
306
314
 
@@ -310,37 +318,37 @@ Reads truth from the Manifest + OpenTelemetry. Runs in **development and product
310
318
 
311
319
  ## 16. The default table
312
320
 
313
- | Area | Default | Alternatives | Rationale |
314
- |---|---|---|---|
315
- | Runtime | Bun | Node · Deno · Edge | speed, native clients |
316
- | Language | TypeScript 7, ESM only, strict | — | no CJS, no compromise |
317
- | Manifest parser | oxc | SWC | independent of the TS release cycle |
318
- | Validation | Standard Schema (Zod 4 in templates) | Valibot (edge) · ArkType · TypeBox | familiarity; AoT neutralizes runtime differences |
319
- | ORM | Drizzle (peer dependency) | adapters later | never bundled, always yours |
320
- | `store.sql` | dev `sqlite` · prod `postgres` | Neon · Supabase · RDS | `Bun.sql`, `bun:sqlite` |
321
- | `store.kv` | dev `memory` · prod `redis` | Valkey · Dragonfly · KeyDB | protocol, not vendor |
322
- | `store.files` | dev `fs` · prod `s3` | SeaweedFS · RustFS (beta) · MinIO · R2 | `Bun.S3` |
323
- | `signal` | dev `memory` · prod **`postgres`** | `redis` · `nats` · `kafka` (explicit) | transactional with your data |
324
- | `clock` | `postgres` | — | durability needs transactional storage |
325
- | `vault` | dev `.env.local` · prod `sops`/age | OpenBao · Infisical · managed | existing standard, no invented format |
326
- | `channel.email` | dev `console` · prod `smtp` | Resend · SES | no vendor lock-in |
327
- | `delivery` | **none — must be declared** | — | semantic decision, never guessed |
328
- | `store.index` | `pgvector` | Qdrant · Meilisearch · Typesense | RAG without another service |
329
- | `ai` | dev `mock` · prod **none — must be declared** | Anthropic · openai-compatible · Bedrock · Vertex · Ollama | model choice is never guessed; `mock` keeps dev deterministic |
330
- | AI + `pii` | **denied** | explicit `allowPii` | egress governance enforced at build time |
331
- | AI caching | off (semantic cache opt-in) | — | non-deterministic output must not be silently reused |
332
- | Auth | built-in, hybrid session, argon2id | better-auth · Clerk · Supabase · Auth0 · Kinde | works with zero config |
333
- | Topology | `monolith` | `services` | start simple |
334
- | Tenancy | off | row · schema · database | no complexity without need |
335
- | Cache | automatic for live/read flows only | flag · manual | no surprises |
336
- | Rate limit | `sliding-window-counter` | fixed-window · sliding-log · token-bucket · leaky-bucket | best accuracy/cost balance |
337
- | i18n | `en` (configurable) | any locale | global default, user overrides |
338
- | Errors | `{ data, error }` values | — | errors are values |
339
- | Telemetry | on; dev 100%, prod 10% + all errors | any ratio | observability without cost |
340
- | Migrations | manual in production | auto in dev | never touches your data |
341
- | Console | dev on · prod on **behind auth** | off | it is your eyes in production |
342
- | Ports | 6530 app · 6533 Console · 6535 MCP | configurable | O·K·E = 6·5·3 |
343
- | License | MIT | — | no BSL/SSPL |
321
+ | Area | Default | Alternatives | Rationale |
322
+ | --------------- | --------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
323
+ | Runtime | Bun | Node · Deno · Edge | speed, native clients |
324
+ | Language | TypeScript 7, ESM only, strict | — | no CJS, no compromise |
325
+ | Manifest parser | oxc | SWC | independent of the TS release cycle |
326
+ | Validation | Standard Schema (Zod 4 in templates) | Valibot (edge) · ArkType · TypeBox | familiarity; AoT neutralizes runtime differences |
327
+ | ORM | Drizzle (peer dependency) | adapters later | never bundled, always yours |
328
+ | `store.sql` | dev `sqlite` · prod `postgres` | Neon · Supabase · RDS | `Bun.sql`, `bun:sqlite` |
329
+ | `store.kv` | dev `memory` · prod `redis` | Valkey · Dragonfly · KeyDB | protocol, not vendor |
330
+ | `store.files` | dev `fs` · prod `s3` | SeaweedFS · RustFS (beta) · MinIO · R2 | `Bun.S3` |
331
+ | `signal` | dev `memory` · prod **`postgres`** | `redis` · `nats` · `kafka` (explicit) | transactional with your data |
332
+ | `clock` | `postgres` | — | durability needs transactional storage |
333
+ | `vault` | dev `.env.local` · prod `sops`/age | OpenBao · Infisical · managed | existing standard, no invented format |
334
+ | `channel.email` | dev `console` · prod `smtp` | Resend · SES | no vendor lock-in |
335
+ | `delivery` | **none — must be declared** | — | semantic decision, never guessed |
336
+ | `store.index` | `pgvector` | Qdrant · Meilisearch · Typesense | RAG without another service |
337
+ | `ai` | dev `mock` · prod **none — must be declared** | Anthropic · openai-compatible · Bedrock · Vertex · Ollama | model choice is never guessed; `mock` keeps dev deterministic |
338
+ | AI + `pii` | **denied** | explicit `allowPii` | egress governance enforced at build time |
339
+ | AI caching | off (semantic cache opt-in) | — | non-deterministic output must not be silently reused |
340
+ | Auth | built-in, hybrid session, argon2id | better-auth · Clerk · Supabase · Auth0 · Kinde | works with zero config |
341
+ | Topology | `monolith` | `services` | start simple |
342
+ | Tenancy | off | row · schema · database | no complexity without need |
343
+ | Cache | automatic for live/read flows only | flag · manual | no surprises |
344
+ | Rate limit | `sliding-window-counter` | fixed-window · sliding-log · token-bucket · leaky-bucket | best accuracy/cost balance |
345
+ | i18n | `en` (configurable) | any locale | global default, user overrides |
346
+ | Errors | `{ data, error }` values | — | errors are values |
347
+ | Telemetry | on; dev 100%, prod 10% + all errors | any ratio | observability without cost |
348
+ | Migrations | manual in production | auto in dev | never touches your data |
349
+ | Console | dev on · prod on **behind auth** | off | it is your eyes in production |
350
+ | Ports | 6530 app · 6533 Console · 6535 MCP | configurable | O·K·E = 6·5·3 |
351
+ | License | MIT | — | no BSL/SSPL |
344
352
 
345
353
  ## 17. Why `signal` defaults to Postgres
346
354
 
@@ -350,13 +358,13 @@ With Postgres, `fx.emit()` runs **inside the same transaction** as `fx.store()`,
350
358
 
351
359
  When you explicitly choose `redis` or `nats` for throughput, the driver keeps the outbox relay internally, so semantics do not regress. Upgrading is a pure performance decision.
352
360
 
353
- | | Postgres | Redis Streams | NATS JetStream |
354
- |---|---|---|---|
355
- | Throughput | ~1k–10k/s | 100k+/s | millions/s |
356
- | **Transactional with your data** | **yes** | no | no |
357
- | Extra service | no | yes | yes |
358
- | Fan-out / live | weak | excellent | excellent |
359
- | DLQ inspection | plain SQL | tooling | tooling |
361
+ | | Postgres | Redis Streams | NATS JetStream |
362
+ | -------------------------------- | --------- | ------------- | -------------- |
363
+ | Throughput | ~1k–10k/s | 100k+/s | millions/s |
364
+ | **Transactional with your data** | **yes** | no | no |
365
+ | Extra service | no | yes | yes |
366
+ | Fan-out / live | weak | excellent | excellent |
367
+ | DLQ inspection | plain SQL | tooling | tooling |
360
368
 
361
369
  ---
362
370
 
@@ -364,16 +372,16 @@ When you explicitly choose `redis` or `nats` for throughput, the driver keeps th
364
372
 
365
373
  ## 18. Three scaling axes (never conflated)
366
374
 
367
- | Axis | Question | Mechanism |
368
- |---|---|---|
369
- | **Split** (`topology`) | one deployable, or one per unit? | `monolith` = in-process calls · `services` = one container per unit, `fx.call` becomes network — code unchanged |
370
- | **Clone** (horizontal) | how many copies of the app? | run N instances: `once` signals deliver to exactly one, crons leader-elect, live queries fan out. `oke docker --prod` emits `deploy.replicas` |
371
- | **Data replicas** | how many copies of the data? | `replicas:` on the driver; read-only flows auto-route (derived from effects) |
375
+ | Axis | Question | Mechanism |
376
+ | ---------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
377
+ | **Split** (`topology`) | one deployable, or one per unit? | `monolith` = in-process calls · `services` = one container per unit, `fx.call` becomes network — code unchanged |
378
+ | **Clone** (horizontal) | how many copies of the app? | run N instances: `once` signals deliver to exactly one, crons leader-elect, live queries fan out. `oke docker --prod` emits `deploy.replicas` |
379
+ | **Data replicas** | how many copies of the data? | `replicas:` on the driver; read-only flows auto-route (derived from effects) |
372
380
 
373
381
  ## 19. Multi-tenancy as a dimension of `fx`
374
382
 
375
383
  ```typescript
376
- oke({ tenancy: { resolve: (ctx) => ctx.auth.orgId, isolation: "row" } }) // row | schema | database
384
+ oke({ tenancy: { resolve: (ctx) => ctx.auth.orgId, isolation: "row" } }); // row | schema | database
377
385
  ```
378
386
 
379
387
  Because every store call passes through `fx`, tenant scoping applies automatically — no forgotten `WHERE org_id`. Rate limits, caches, secrets, and channel branding become per-tenant for free. **`oke doctor` fails the build** if any flow reads a tenant-scoped table without a tenant in context. Cross-tenant leaks become structurally hard.
@@ -404,20 +412,21 @@ Stable, permanent, searchable codes with a cause, a suggested fix, and a docs li
404
412
  ## 23. Adoption on-ramps
405
413
 
406
414
  ```typescript
407
- mount(honoApp) // existing app runs inside OKE, untouched
408
- mount(elysiaApp) // new work uses flows; old routes keep serving; one deployable
409
- mount(expressApp)
415
+ mount(honoApp); // existing app runs inside OKE, untouched
416
+ mount(elysiaApp); // new work uses flows; old routes keep serving; one deployable
417
+ mount(expressApp);
410
418
  ```
419
+
411
420
  Plus `oke import express|hono|elysia` codemods for the mechanical parts. Migration becomes incremental — the only kind that actually happens.
412
421
 
413
422
  ## 24. Budgets enforced in CI, published per release
414
423
 
415
- | Budget | Limit |
416
- |---|---|
417
- | Kernel (edge profile) | < 15 kB |
418
- | Client runtime | < 3 kB |
419
- | Cold start on Bun | < 75 ms in CI (GitHub Actions runners are less predictable than a dev machine); measured ~25–30 ms on real hardware |
420
- | p99 routing overhead | < 1 ms |
424
+ | Budget | Limit |
425
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------- |
426
+ | Kernel (edge profile) | < 15 kB |
427
+ | Client runtime | < 3 kB |
428
+ | Cold start on Bun | < 75 ms in CI (GitHub Actions runners are less predictable than a dev machine); measured ~25–30 ms on real hardware |
429
+ | p99 routing overhead | < 1 ms |
421
430
 
422
431
  A regression fails OKE's own build. Claims we cannot measure, we do not make.
423
432
 
@@ -427,7 +436,7 @@ A regression fails OKE's own build. Claims we cannot measure, we do not make.
427
436
 
428
437
  OKE is the first backend an AI can fully read, safely operate, and provably not break.
429
438
 
430
- **Two directions, one design.** §25 covers AI *for the developer* (agents operating your system through MCP). The AI element (§5) covers AI *inside the application* (models, prompts, agents your users trigger). Both rest on the same foundation — declared effects and least-privilege capabilities — which is why an agent in either direction is bounded by construction rather than by policy.
439
+ **Two directions, one design.** §25 covers AI _for the developer_ (agents operating your system through MCP). The AI element (§5) covers AI _inside the application_ (models, prompts, agents your users trigger). Both rest on the same foundation — declared effects and least-privilege capabilities — which is why an agent in either direction is bounded by construction rather than by policy.
431
440
 
432
441
  ---
433
442
 
@@ -435,11 +444,11 @@ OKE is the first backend an AI can fully read, safely operate, and provably not
435
444
 
436
445
  ## 26. Roadmap
437
446
 
438
- | Phase | Contents |
439
- |---|---|
440
- | **MVP (0.1–0.4)** | Bun adapter · router · Standard Schema + AoT (with dynamic fallback) · `fx` and the effect system · `on`/`flow` · typed errors · typed client · OTel baseline · plugin engine · `create-oke` |
441
- | **v1 (0.5–1.0)** | all eight elements + drivers · Manifest + derivations · Console · auth + ABAC · schema generation · docker/compose derivation · durability · live queries · i18n · MCP · Node + Edge adapters |
442
- | **Ecosystem (1.x)** | more drivers and image recipes · `mount()` adapters and import codemods · tenancy · privacy tooling · `@oke/react` · community plugin registry |
447
+ | Phase | Contents |
448
+ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
449
+ | **MVP (0.1–0.4)** | Bun adapter · router · Standard Schema + AoT (with dynamic fallback) · `fx` and the effect system · `on`/`flow` · typed errors · typed client · OTel baseline · plugin engine · `create-oke` |
450
+ | **v1 (0.5–1.0)** | all eight elements + drivers · Manifest + derivations · Console · auth + ABAC · schema generation · docker/compose derivation · durability · live queries · i18n · MCP · Node + Edge adapters |
451
+ | **Ecosystem (1.x)** | more drivers and image recipes · `mount()` adapters and import codemods · tenancy · privacy tooling · `@oke/react` · community plugin registry |
443
452
 
444
453
  ## 27. Package structure (one published package)
445
454
 
@@ -463,27 +472,27 @@ okengine/ # ONE npm package, subpath exports, "sideEffects":
463
472
 
464
473
  ## 28. Risks, honestly
465
474
 
466
- | Risk | Mitigation |
467
- |---|---|
468
- | `eval`-based AoT blocked on some edge runtimes | first-class `aot: false` dynamic mode; AoT is a Bun/Node optimization, not a requirement |
469
- | TypeScript inference depth at scale | budget inference performance work early; codegen fallback for very large apps |
470
- | Scope is enormous for a small team | driver model keeps each element small; adopt rather than build; sequence ruthlessly |
471
- | Raw throughput below Encore's Rust runtime | accepted — compete on DX, portability, license, batteries, and derived capabilities |
472
- | Ecosystem cold start | `mount()` interop so Hono/Elysia middleware remains usable from day one |
473
- | Auto cache invalidation edge cases | raw SQL requires explicit effect annotation, otherwise that flow opts out of auto-caching; correctness never silently breaks |
475
+ | Risk | Mitigation |
476
+ | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
477
+ | `eval`-based AoT blocked on some edge runtimes | first-class `aot: false` dynamic mode; AoT is a Bun/Node optimization, not a requirement |
478
+ | TypeScript inference depth at scale | budget inference performance work early; codegen fallback for very large apps |
479
+ | Scope is enormous for a small team | driver model keeps each element small; adopt rather than build; sequence ruthlessly |
480
+ | Raw throughput below Encore's Rust runtime | accepted — compete on DX, portability, license, batteries, and derived capabilities |
481
+ | Ecosystem cold start | `mount()` interop so Hono/Elysia middleware remains usable from day one |
482
+ | Auto cache invalidation edge cases | raw SQL requires explicit effect annotation, otherwise that flow opts out of auto-caching; correctness never silently breaks |
474
483
 
475
484
  ---
476
485
 
477
486
  ## 29. Why this survives a hundred years
478
487
 
479
- 1. **Laws, not features.** Eight elements cover the *categories* of backend need. The future changes drivers, never elements.
488
+ 1. **Laws, not features.** Eight elements cover the _categories_ of backend need. The future changes drivers, never elements.
480
489
  2. **The Manifest outlives runtimes.** A versioned, runtime-neutral description; the kernel compiles to WASM for hosts that do not exist yet.
481
490
  3. **Effects-in-types is a ratchet.** Every future capability derives from the same static knowledge instead of adding API surface.
482
- 4. **One package, one law, ten exports** — small enough to be *finished*. Finished software can be maintained for a century; sprawling software cannot.
491
+ 4. **One package, one law, ten exports** — small enough to be _finished_. Finished software can be maintained for a century; sprawling software cannot.
483
492
  5. **Adopt, don't reinvent.** We inherit the longevity of Postgres, Redis, S3, SOPS, and OpenTelemetry instead of competing with it.
484
493
  6. **MIT, self-host first, drivers as the community surface.** No company's death can kill it.
485
494
 
486
495
  ---
487
496
 
488
497
  **One law · eight elements · ten exports · one package · one manifest.**
489
- *Adopt what exists. Build only what doesn't. Name things after standards.*
498
+ _Adopt what exists. Build only what doesn't. Name things after standards._