okengine 0.10.2 → 0.11.0

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 (343) hide show
  1. package/package.json +76 -10
  2. package/site/content/docs/ai/mcp.mdx +0 -1
  3. package/site/content/docs/deployment/docker-swarm.mdx +48 -111
  4. package/site/content/docs/deployment/docker.mdx +43 -36
  5. package/site/content/docs/deployment/index.mdx +9 -9
  6. package/site/content/docs/deployment/kubernetes.mdx +4 -4
  7. package/site/content/docs/elements/ai.mdx +7 -13
  8. package/site/content/docs/elements/channel.mdx +9 -13
  9. package/site/content/docs/elements/clock.mdx +8 -14
  10. package/site/content/docs/elements/flow.mdx +46 -54
  11. package/site/content/docs/elements/gate.mdx +6 -11
  12. package/site/content/docs/elements/signal.mdx +2 -8
  13. package/site/content/docs/elements/store.mdx +79 -93
  14. package/site/content/docs/elements/vault.mdx +89 -76
  15. package/site/content/docs/get-started/basic-usage.mdx +8 -14
  16. package/site/content/docs/get-started/installation.mdx +36 -36
  17. package/site/content/docs/get-started/introduction.mdx +11 -0
  18. package/site/content/docs/get-started/why.mdx +3 -4
  19. package/site/content/docs/index.mdx +0 -1
  20. package/site/content/docs/meta.json +0 -1
  21. package/site/content/docs/plugins/anonymous.mdx +1 -1
  22. package/site/content/docs/plugins/magic-link.mdx +11 -11
  23. package/site/content/docs/plugins/otp.mdx +2 -2
  24. package/site/content/docs/plugins/passkey.mdx +1 -1
  25. package/site/content/docs/plugins/two-factor.mdx +1 -1
  26. package/site/content/docs/plugins/username.mdx +1 -1
  27. package/site/content/docs/recipes/caddy.mdx +1 -1
  28. package/site/content/docs/recipes/cockroachdb.mdx +2 -2
  29. package/site/content/docs/recipes/dragonfly.mdx +1 -1
  30. package/site/content/docs/recipes/index.mdx +1 -2
  31. package/site/content/docs/recipes/llama-cpp.mdx +21 -23
  32. package/site/content/docs/recipes/mailpit.mdx +11 -11
  33. package/site/content/docs/recipes/meilisearch.mdx +10 -10
  34. package/site/content/docs/recipes/meta.json +0 -1
  35. package/site/content/docs/recipes/ollama.mdx +1 -1
  36. package/site/content/docs/recipes/pgdog.mdx +12 -9
  37. package/site/content/docs/recipes/postgres.mdx +3 -3
  38. package/site/content/docs/recipes/redis.mdx +2 -2
  39. package/site/content/docs/recipes/rustfs.mdx +10 -7
  40. package/site/content/docs/recipes/sglang.mdx +1 -1
  41. package/site/content/docs/recipes/supabase-docker.mdx +1 -1
  42. package/site/content/docs/recipes/timescale.mdx +2 -2
  43. package/site/content/docs/recipes/valkey.mdx +1 -1
  44. package/site/content/docs/recipes/vllm.mdx +1 -1
  45. package/site/content/docs/recipes/yugabytedb.mdx +2 -2
  46. package/site/content/docs/reference/cli.md +61 -38
  47. package/site/content/docs/reference/configuration.mdx +145 -70
  48. package/site/content/docs/reference/environment-variables.mdx +36 -28
  49. package/site/content/docs/reference/errors.mdx +28 -29
  50. package/site/content/docs/reference/fx.mdx +14 -7
  51. package/site/content/docs/reference/i18n.mdx +17 -6
  52. package/site/content/docs/reference/index.mdx +5 -0
  53. package/site/content/docs/reference/meta.json +1 -0
  54. package/site/content/docs/reference/migrating-environments.mdx +158 -0
  55. package/site/content/docs/reference/plugins.mdx +2 -2
  56. package/src/auth/gate-auth.test.ts +12 -10
  57. package/src/cli/ai-setup/ai-setup.test.ts +30 -16
  58. package/src/cli/ai-setup/apply.ts +111 -15
  59. package/src/cli/ai-setup/catalog.ts +3 -3
  60. package/src/cli/ai-setup/index.ts +1 -1
  61. package/src/cli/ai-setup/prompts.ts +1 -1
  62. package/src/cli/ai-setup/recommend.test.ts +1 -1
  63. package/src/cli/ask-seed.test.ts +3 -3
  64. package/src/cli/build.ts +8 -9
  65. package/src/cli/db-auto-push.test.ts +6 -3
  66. package/src/cli/db-auto-push.ts +7 -5
  67. package/src/cli/db-seed.ts +7 -8
  68. package/src/cli/db.test.ts +70 -71
  69. package/src/cli/db.ts +86 -12
  70. package/src/cli/dev-controller.test.ts +35 -0
  71. package/src/cli/dev-controller.ts +298 -0
  72. package/src/cli/dev-controls.ts +11 -65
  73. package/src/cli/dev-db-push.test.ts +47 -15
  74. package/src/cli/dev-schema-sync.test.ts +11 -11
  75. package/src/cli/dev-schema-sync.ts +10 -10
  76. package/src/cli/dev-session-lock.test.ts +106 -0
  77. package/src/cli/dev-session-lock.ts +209 -0
  78. package/src/cli/dev.test.ts +246 -114
  79. package/src/cli/dev.ts +153 -205
  80. package/src/cli/doc-staleness.test.ts +3 -6
  81. package/src/cli/docker-clean.test.ts +33 -1
  82. package/src/cli/docker-clean.ts +28 -33
  83. package/src/cli/docker-cli.test.ts +12 -11
  84. package/src/cli/docker.ts +95 -20
  85. package/src/cli/doctor.test.ts +40 -0
  86. package/src/cli/doctor.ts +142 -9
  87. package/src/cli/drizzle-env.test.ts +11 -13
  88. package/src/cli/drizzle-env.ts +18 -11
  89. package/src/cli/ensure-drizzle-config.ts +11 -14
  90. package/src/cli/hero-meta.test.ts +15 -15
  91. package/src/cli/hero-meta.ts +10 -9
  92. package/src/cli/index.ts +36 -6
  93. package/src/cli/load-config.images.test.ts +44 -10
  94. package/src/cli/load-config.source.test.ts +50 -0
  95. package/src/cli/load-config.ts +35 -29
  96. package/src/cli/meilisearch-local.ts +1 -2
  97. package/src/cli/mode.ts +7 -58
  98. package/src/cli/registry.ts +175 -19
  99. package/src/cli/resolve-dev-sql-env.test.ts +8 -16
  100. package/src/cli/resolve-dev-sql-env.ts +13 -15
  101. package/src/cli/safe-defaults.test.ts +29 -11
  102. package/src/cli/schema.ts +65 -16
  103. package/src/cli/test.ts +58 -0
  104. package/src/cli/tui/App.tsx +252 -0
  105. package/src/cli/tui/DevLive.tsx +116 -0
  106. package/src/cli/tui/components/ConfirmDialog.tsx +48 -0
  107. package/src/cli/tui/components/HeaderBar.tsx +67 -0
  108. package/src/cli/tui/components/LogStream.tsx +47 -0
  109. package/src/cli/tui/components/PanelCard.tsx +39 -0
  110. package/src/cli/tui/components/SelectRow.tsx +37 -0
  111. package/src/cli/tui/components/SlashPalette.tsx +172 -0
  112. package/src/cli/tui/components/Spinner.tsx +32 -0
  113. package/src/cli/tui/components/StatusBar.tsx +51 -0
  114. package/src/cli/tui/components/StatusDot.tsx +37 -0
  115. package/src/cli/tui/components/TabBar.tsx +49 -0
  116. package/src/cli/tui/components/Wordmark.tsx +43 -0
  117. package/src/cli/tui/format.ts +38 -0
  118. package/src/cli/tui/keys.test.ts +18 -0
  119. package/src/cli/tui/keys.ts +26 -0
  120. package/src/cli/tui/launch.test.ts +18 -0
  121. package/src/cli/tui/launch.ts +57 -0
  122. package/src/cli/tui/panels/Dashboard.tsx +201 -0
  123. package/src/cli/tui/panels/Database.tsx +198 -0
  124. package/src/cli/tui/panels/Dev.tsx +257 -0
  125. package/src/cli/tui/panels/Docker.tsx +357 -0
  126. package/src/cli/tui/panels/Navigator.test.ts +22 -0
  127. package/src/cli/tui/panels/Navigator.tsx +213 -0
  128. package/src/cli/tui/slash-catalog.test.ts +31 -0
  129. package/src/cli/tui/slash-catalog.ts +184 -0
  130. package/src/cli/tui/slash-run.ts +54 -0
  131. package/src/cli/tui/state/ports.ts +95 -0
  132. package/src/cli/tui/theme.ts +24 -0
  133. package/src/cli/vault-cmd.test.ts +402 -0
  134. package/src/cli/vault-cmd.ts +727 -69
  135. package/src/cli/vault-secure-input.test.ts +56 -0
  136. package/src/cli/vault-secure-input.ts +124 -0
  137. package/src/compiler/effects-infer.ts +7 -0
  138. package/src/compiler/extract.ts +12 -0
  139. package/src/compiler/fixtures/skyport/oke.config.ts +7 -5
  140. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -1
  141. package/src/compiler/fixtures/skyport.expected.json +1 -1
  142. package/src/compiler/generate-adopt.ts +27 -1
  143. package/src/compiler-entry.ts +7 -0
  144. package/src/config/define-config.test.ts +111 -47
  145. package/src/config/driver-defaults.test.ts +115 -0
  146. package/src/config/driver-defaults.ts +156 -0
  147. package/src/config/index.ts +246 -131
  148. package/src/config/resolve-driver.test.ts +14 -19
  149. package/src/console/server/app.ts +4 -2
  150. package/src/console/server/console.test.ts +58 -1
  151. package/src/console/server/flows.ts +22 -2
  152. package/src/console/server/index.ts +3 -0
  153. package/src/console/server/operator-db.test.ts +55 -13
  154. package/src/console/server/operator-db.ts +305 -263
  155. package/src/console/server/serve.ts +16 -7
  156. package/src/console/server/state.ts +31 -9
  157. package/src/console/server/vault.test.ts +120 -5
  158. package/src/console/server/vault.ts +208 -12
  159. package/src/console/ui/dist/assets/{index-D-9KFce5.js → index--Y0Uaz-m.js} +2 -2
  160. package/src/console/ui/dist/assets/panel-vault-BkZdJPX8.js +1 -0
  161. package/src/console/ui/dist/assets/style-C3L349iZ.css +3 -0
  162. package/src/console/ui/dist/index.html +2 -2
  163. package/src/console/ui/shell/client.ts +16 -0
  164. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +54 -1
  165. package/src/console/ui/vault/VaultA11yView.tsx +33 -1
  166. package/src/console/ui/vault/backend.test.ts +75 -0
  167. package/src/console/ui/vault/backend.ts +117 -0
  168. package/src/console/ui/vault/fixture.ts +21 -2
  169. package/src/console/ui/vault/index.ts +11 -1
  170. package/src/console/ui/vault/types.ts +26 -0
  171. package/src/docker/compose.ts +164 -61
  172. package/src/docker/derive.ts +106 -12
  173. package/src/docker/docker.test.ts +156 -110
  174. package/src/docker/helpers.ts +98 -0
  175. package/src/docker/images-config.test.ts +163 -0
  176. package/src/docker/index.ts +30 -5
  177. package/src/docker/recipes/index.ts +0 -3
  178. package/src/docker/recipes/llama-cpp.ts +4 -4
  179. package/src/docker/recipes/pgdog.ts +9 -2
  180. package/src/docker/resources.test.ts +71 -0
  181. package/src/docker/resources.ts +176 -0
  182. package/src/docker/stack-id.test.ts +11 -4
  183. package/src/docker/stack-id.ts +42 -32
  184. package/src/docker/stack.integration.test.ts +4 -15
  185. package/src/docker/types.ts +35 -3
  186. package/src/drivers/ai-ollama.integration.test.ts +2 -2
  187. package/src/drivers/conformance.test.ts +11 -12
  188. package/src/drivers/drizzle-dialect.test.ts +0 -4
  189. package/src/drivers/drizzle-dialect.ts +7 -13
  190. package/src/drivers/index.ts +24 -7
  191. package/src/drivers/journal-postgres.test.ts +3 -1
  192. package/src/drivers/journal-postgres.ts +4 -2
  193. package/src/drivers/meilisearch.ts +1 -1
  194. package/src/drivers/pglite.ts +28 -5
  195. package/src/drivers/types.ts +9 -11
  196. package/src/drivers/vault-aws-secrets-manager.test.ts +159 -0
  197. package/src/drivers/vault-aws-secrets-manager.ts +333 -0
  198. package/src/drivers/vault-builtin.test.ts +110 -0
  199. package/src/drivers/vault-builtin.ts +184 -0
  200. package/src/drivers/vault-driver-removal.test.ts +13 -0
  201. package/src/drivers/vault-managed.test.ts +95 -0
  202. package/src/drivers/vault-managed.ts +101 -25
  203. package/src/drivers/vault-types.ts +25 -5
  204. package/src/elements/ai/runtime.ts +1 -1
  205. package/src/elements/clock/chaos.test.ts +4 -1
  206. package/src/elements/clock/durable.ts +57 -4
  207. package/src/elements/clock.test.ts +13 -14
  208. package/src/elements/gate/constants.ts +18 -0
  209. package/src/elements/gate.test.ts +1 -1
  210. package/src/elements/gate.ts +2 -2
  211. package/src/elements/store/domain-ddl.test.ts +5 -12
  212. package/src/elements/store/emit-drizzle.ts +44 -19
  213. package/src/elements/store/index-boot.test.ts +15 -116
  214. package/src/elements/store/load-plugin-tables.ts +1 -1
  215. package/src/elements/store/resource-list-docs.fixture.ts +12 -6
  216. package/src/elements/store/resource-list-docs.test.ts +64 -44
  217. package/src/elements/store/resource.test.ts +17 -10
  218. package/src/elements/store/runtime.ts +9 -12
  219. package/src/elements/store/schema-decl.test.ts +16 -32
  220. package/src/elements/store/seed.test.ts +1 -2
  221. package/src/elements/store/seed.ts +7 -8
  222. package/src/elements/store/sql-condition.test.ts +2 -2
  223. package/src/elements/store/sql-session.test.ts +8 -10
  224. package/src/elements/store/sql-session.ts +10 -2
  225. package/src/elements/store.test.ts +13 -13
  226. package/src/elements/vault/audit.ts +233 -0
  227. package/src/elements/vault/boot-chain.test.ts +78 -0
  228. package/src/elements/vault/boot-chain.ts +43 -39
  229. package/src/elements/vault/builtin-adapter.test.ts +479 -0
  230. package/src/elements/vault/builtin-adapter.ts +1184 -0
  231. package/src/elements/vault/crypto.test.ts +237 -0
  232. package/src/elements/vault/crypto.ts +431 -0
  233. package/src/elements/vault/declare.ts +164 -3
  234. package/src/elements/vault/errors.ts +56 -0
  235. package/src/elements/vault/kms-unseal.test.ts +76 -0
  236. package/src/elements/vault/kms-unseal.ts +181 -0
  237. package/src/elements/vault/path.ts +90 -0
  238. package/src/elements/vault/resilience.test.ts +102 -0
  239. package/src/elements/vault/resilience.ts +107 -0
  240. package/src/elements/vault/runtime.ts +36 -4
  241. package/src/elements/vault/security-checklist.test.ts +130 -0
  242. package/src/elements/vault/storage.ts +448 -0
  243. package/src/elements/vault/types.ts +288 -0
  244. package/src/elements/vault/unseal.ts +150 -0
  245. package/src/elements/vault.test.ts +72 -4
  246. package/src/elements/vault.ts +91 -2
  247. package/src/full.ts +248 -0
  248. package/src/http.ts +41 -0
  249. package/src/i18n/interpolate-simple.ts +37 -0
  250. package/src/i18n/messages.ts +51 -4
  251. package/src/i18n-entry.ts +7 -0
  252. package/src/index.ts +35 -145
  253. package/src/journal-entry.ts +20 -0
  254. package/src/kernel/adopt-barrel-fresh.test.ts +25 -10
  255. package/src/kernel/app.ts +40 -42
  256. package/src/kernel/auto-registry.test.ts +2 -2
  257. package/src/kernel/boot-bind/ai.test.ts +5 -5
  258. package/src/kernel/boot-bind/ai.ts +2 -1
  259. package/src/kernel/boot-bind/channel.test.ts +6 -6
  260. package/src/kernel/boot-bind/channel.ts +5 -4
  261. package/src/kernel/boot-bind/clock.ts +5 -5
  262. package/src/kernel/boot-bind/gate.ts +6 -7
  263. package/src/kernel/boot-bind/honor-config.test.ts +42 -42
  264. package/src/kernel/boot-bind/journal.ts +5 -5
  265. package/src/kernel/boot-bind/signal.ts +3 -1
  266. package/src/kernel/boot-bind/store.test.ts +55 -37
  267. package/src/kernel/boot-bind/store.ts +24 -34
  268. package/src/kernel/boot-bind/vault.ts +19 -4
  269. package/src/kernel/boot.test.ts +12 -4
  270. package/src/kernel/boot.ts +31 -19
  271. package/src/kernel/budget-entry.ts +1 -1
  272. package/src/kernel/compensate.test.ts +288 -1
  273. package/src/kernel/compensate.ts +126 -0
  274. package/src/kernel/concurrency.test.ts +10 -9
  275. package/src/kernel/effects-stamping.test.ts +27 -2
  276. package/src/kernel/element-registries.ts +5 -3
  277. package/src/kernel/flow.ts +4 -2
  278. package/src/kernel/fx.test.ts +119 -3
  279. package/src/kernel/fx.ts +215 -40
  280. package/src/kernel/index.ts +14 -0
  281. package/src/kernel/journal.ts +130 -7
  282. package/src/kernel/pipeline.test.ts +20 -6
  283. package/src/kernel/redacted.test.ts +35 -0
  284. package/src/kernel/redacted.ts +24 -2
  285. package/src/kernel/router/create-default.ts +16 -0
  286. package/src/kernel/router/create-edge.ts +18 -0
  287. package/src/kernel/router/create.ts +23 -0
  288. package/src/kernel/router/index.ts +23 -0
  289. package/src/kernel/router/linear.ts +88 -0
  290. package/src/kernel/router/regexp.ts +188 -0
  291. package/src/kernel/router/smart.ts +120 -0
  292. package/src/kernel/router/trie.ts +108 -0
  293. package/src/kernel/router/types.ts +56 -0
  294. package/src/kernel/router.ts +18 -532
  295. package/src/kernel-entry.ts +43 -0
  296. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  297. package/src/manifest/fixtures/skyport.manifest.json +1 -1
  298. package/src/plugins/config-source.test.ts +7 -7
  299. package/src/release/build-lib.ts +58 -0
  300. package/src/release/exports.test.ts +4 -2
  301. package/src/release/exports.ts +30 -4
  302. package/src/release/measure.ts +101 -22
  303. package/src/runs/duckdb.ts +7 -2
  304. package/src/shared/optional-peer.ts +41 -0
  305. package/src/term.test.ts +3 -44
  306. package/src/test/create-test-app.ts +12 -0
  307. package/src/test/provisions.integration.test.ts +1 -1
  308. package/src/test/reset-element-registries.ts +2 -0
  309. package/src/upgrade/codemods.test.ts +7 -20
  310. package/src/upgrade/codemods.ts +93 -60
  311. package/site/content/docs/console/access.mdx +0 -29
  312. package/site/content/docs/console/ai.mdx +0 -35
  313. package/site/content/docs/console/architecture.mdx +0 -35
  314. package/site/content/docs/console/channels.mdx +0 -37
  315. package/site/content/docs/console/clock.mdx +0 -51
  316. package/site/content/docs/console/flows.mdx +0 -31
  317. package/site/content/docs/console/gates.mdx +0 -73
  318. package/site/content/docs/console/index.mdx +0 -54
  319. package/site/content/docs/console/manifest-diff.mdx +0 -34
  320. package/site/content/docs/console/meta.json +0 -24
  321. package/site/content/docs/console/overview.mdx +0 -40
  322. package/site/content/docs/console/plugins.mdx +0 -41
  323. package/site/content/docs/console/privacy.mdx +0 -32
  324. package/site/content/docs/console/runs.mdx +0 -50
  325. package/site/content/docs/console/signals.mdx +0 -40
  326. package/site/content/docs/console/store.mdx +0 -32
  327. package/site/content/docs/console/tenancy.mdx +0 -32
  328. package/site/content/docs/console/traces.mdx +0 -38
  329. package/site/content/docs/console/vault.mdx +0 -41
  330. package/site/content/docs/recipes/openbao.mdx +0 -141
  331. package/src/cli/ask-dev-mode.ts +0 -40
  332. package/src/cli/dev-mode.test.ts +0 -45
  333. package/src/cli/dev-mode.ts +0 -78
  334. package/src/cli/openbao-bootstrap.test.ts +0 -150
  335. package/src/cli/openbao-bootstrap.ts +0 -321
  336. package/src/cli/openbao-restart.integration.test.ts +0 -145
  337. package/src/console/ui/dist/assets/panel-vault-Za1GyJfM.js +0 -1
  338. package/src/console/ui/dist/assets/style-C8MxEWPd.css +0 -3
  339. package/src/docker/recipes/openbao.ts +0 -47
  340. package/src/drivers/libsql.ts +0 -179
  341. package/src/drivers/sqlite.ts +0 -44
  342. package/src/drivers/vault-openbao.test.ts +0 -97
  343. package/src/drivers/vault-openbao.ts +0 -143
@@ -31,7 +31,7 @@ sticky network id to preserve. Scale with `replicas: N`.
31
31
  <Step>
32
32
  ### Share backing services
33
33
 
34
- Pin docker/prod drivers to shared stores:
34
+ Pin `dev`/`prod` drivers to shared stores:
35
35
 
36
36
  | Concern | Driver | Shared backend |
37
37
  | ----------------------------- | ---------------------------- | ------------------------------------------------- |
@@ -59,7 +59,7 @@ Wire `readinessProbe` to `/_/ready` and `livenessProbe` to `/health`.
59
59
  Bun.SQL defaults to **10** connections per process — fine for one pod.
60
60
  Scale the Deployment and `N × pool` can exceed Postgres `max_connections`.
61
61
 
62
- When both `store.sql` and `pgdog` are pinned (docker/prod default in templates),
62
+ When both `store.sql` and `pgdog` are pinned (`dev`/`prod` default in templates),
63
63
  `DATABASE_URL` points at PgDog on port `6432` — transaction pooling, wire-protocol
64
64
  transparent to Bun.SQL / Drizzle. Point the cluster Service at that pooler.
65
65
 
@@ -137,12 +137,12 @@ so traffic does not hit a pod mid-takeover.
137
137
 
138
138
  `drivers.store.kv` must be `redis` with `REDIS_URL` set. A missing URL now
139
139
  **fails boot** (no silent memory fallback). Declaring `memory` for local is fine;
140
- docker/prod should stay on redis.
140
+ `dev`/`prod` should stay on redis.
141
141
 
142
142
  </Accordion>
143
143
  <Accordion title="Files uploaded on pod A are missing on pod B">
144
144
 
145
- `drivers.store.files: "fs"` is single-host. Switch docker/prod to `s3`
145
+ `drivers.store.files: "fs"` is single-host. Switch `dev`/`prod` to `s3`
146
146
  (create-oke templates already do).
147
147
 
148
148
  </Accordion>
@@ -132,7 +132,7 @@ Use `keyBy: "ip"` on public unauthenticated AI edges. Cost caps stay on prompt/a
132
132
 
133
133
  ## Secrets stay out of prompts
134
134
 
135
- `Redacted` values (e.g. from `fx.vault`) stringify to `[redacted]` in provider-facing messages — the same placeholder as logs. Never cleartext to a model.
135
+ `Redacted` values (e.g. from `fx.vault.get`) stringify to `[redacted]` in provider-facing messages — the same placeholder as logs. Never cleartext to a model.
136
136
 
137
137
  ## Streaming
138
138
 
@@ -176,8 +176,8 @@ oke ai setup --provider ollama --yes
176
176
  ```
177
177
 
178
178
  Writes `drivers.ai`, commented AI overrides in `.env.local` (so they do not
179
- shadow `docker/.env.docker`), and `src/core/ai.ts`. Uncomment `.env.local`
180
- lines only for a host-managed AI endpoint.
179
+ shadow `docker/.env.docker`), and AI models into `src/core.ts`. Uncomment
180
+ `.env.local` lines only for a host-managed AI endpoint.
181
181
 
182
182
  **Recommended** defaults to llama.cpp (lightest local footprint). Customize
183
183
  offers llama.cpp · Ollama · vLLM · SGLang · cloud providers.
@@ -209,7 +209,7 @@ import { defineConfig } from "okengine/config";
209
209
 
210
210
  export default defineConfig({
211
211
  drivers: {
212
- ai: { local: "openai-compatible", docker: "openai-compatible", prod: "anthropic" },
212
+ ai: { dev: "openai-compatible", test: "mock", prod: "anthropic" },
213
213
  },
214
214
  images: {
215
215
  ai: "ghcr.io/ggml-org/llama.cpp:server-b10290", // ≥ b8146; never :latest
@@ -217,10 +217,10 @@ export default defineConfig({
217
217
  });
218
218
  ```
219
219
 
220
- ```typescript title="src/core/ai.ts"
220
+ ```typescript title="src/core.ts"
221
221
  export const smart = ai.model("smart", {
222
222
  provider: "openai-compatible",
223
- model: process.env.OKE_AI_MODEL ?? "smollm2", // Docker Hub ai/ id
223
+ model: process.env.OKE_AI_MODEL ?? "granite3.3:2b", // Docker Hub ai/ id
224
224
  });
225
225
  ```
226
226
 
@@ -270,7 +270,7 @@ The one you declared. There is no fallback or guess — if `prod` has no AI driv
270
270
  </Accordion>
271
271
  <Accordion title="oke boot: ollama driver needs OKE_AI_URL">
272
272
 
273
- Docker mode expects `OKE_AI_URL` from `docker/.env.docker` (written when `images.ai` is pinned). Keep `OKE_AI_*` in `.env.local` commented — an active `OKE_AI_URL` there wins and shadows the compose URL. Locally, the Ollama default is `http://127.0.0.1:11434`. If asks fail with `OllamaUnavailableError`, confirm the server answers at that URL and that the model is listed under `GET /api/tags` (boot pulls via `POST /api/pull` against the container — do not rely on a host `ollama pull`, which may talk to a different install). Prefer `oke ai setup` to wire driver, commented env overrides, and `src/core/ai.ts` in one pass.
273
+ Docker mode expects `OKE_AI_URL` from `docker/.env.docker` (written when `images.ai` is pinned). Keep `OKE_AI_*` in `.env.local` commented — an active `OKE_AI_URL` there wins and shadows the compose URL. Locally, the Ollama default is `http://127.0.0.1:11434`. If asks fail with `OllamaUnavailableError`, confirm the server answers at that URL and that the model is listed under `GET /api/tags` (boot pulls via `POST /api/pull` against the container — do not rely on a host `ollama pull`, which may talk to a different install). Prefer `oke ai setup` to wire driver, commented env overrides, and AI models in `src/core.ts` in one pass.
274
274
 
275
275
  </Accordion>
276
276
  <Accordion title="A prompt edit made answers worse — how do I catch that pre-merge?">
@@ -289,7 +289,6 @@ Bound it at declaration: `maxSteps` caps iterations, `budget.maxCostPerRun` caps
289
289
 
290
290
  - [Flow](/docs/elements/flow) — `fx.ask` and `fx.search` inside `do`
291
291
  - [Store](/docs/elements/store) — `store.index`, the home of embeddings
292
- - [Console · AI](/docs/console/ai) — prompts, versions, cost per run
293
292
 
294
293
  ## Next
295
294
 
@@ -304,9 +303,4 @@ Bound it at declaration: `maxSteps` caps iterations, `budget.maxCostPerRun` caps
304
303
  description="Eight elements overview."
305
304
  href="/docs/get-started/introduction"
306
305
  />
307
- <Card
308
- title="Console"
309
- description="Panels derived from the Manifest."
310
- href="/docs/console/overview"
311
- />
312
306
  </Cards>
@@ -54,7 +54,9 @@ do: async (input, fx) => {
54
54
  <Step>
55
55
  ### Read it in development
56
56
 
57
- Locally the `console` driver captures mail into an inbox instead of sending; in docker mode the stack runs **Mailpit**, a real SMTP catcher with a web UI — so you see the exact rendered message without ever touching a real mailbox.
57
+ Under `oke test` the `console` driver captures mail into an inbox instead of sending; under `oke
58
+ dev` Compose runs **Mailpit**, a real SMTP catcher with a web UI — so you see the exact rendered
59
+ message without ever touching a real mailbox.
58
60
 
59
61
  </Step>
60
62
 
@@ -199,20 +201,20 @@ push drivers are passed via `BootOptions.channel.drivers` when you need them.
199
201
  ```typescript title="oke.config.ts"
200
202
  drivers: {
201
203
  channel: {
202
- email: { local: "console", docker: "smtp", test: "console", prod: "smtp" },
204
+ email: { dev: "smtp", test: "console", prod: "smtp" },
203
205
  // optional — omit until you need SMS at boot
204
- sms: { local: "console", docker: "taqnyat", test: "console", prod: "taqnyat" },
206
+ sms: { test: "console", prod: "taqnyat" },
205
207
  },
206
208
  },
207
209
  images: {
208
- "channel.email": "axllent/mailpit:v1.22.3",
210
+ channel: { email: "axllent/mailpit:v1.22.3" },
209
211
  },
210
212
  ```
211
213
 
212
214
  | Driver | Medium | Behavior |
213
215
  | -------------- | -------- | ------------------------------------------------------------------- |
214
- | `console` | any | Captures into a readable inbox — local + tests |
215
- | `smtp` | email | Real SMTP — Mailpit in docker, your provider in prod |
216
+ | `console` | any | Captures into a readable inbox — tests |
217
+ | `smtp` | email | Real SMTP — Mailpit under `oke dev`, your provider in prod |
216
218
  | `resend` | email | Resend HTTP API (`RESEND_API_KEY`) |
217
219
  | `sndr` | email | SNDR HTTP API (`SNDR_API_KEY`) |
218
220
  | `taqnyat-mail` | email | Taqnyat Mail API (`TAQNYAT_MAIL_TOKEN` + `TAQNYAT_CAMPAIGN`) |
@@ -258,7 +260,7 @@ openWebPushChannel({
258
260
  <Accordions>
259
261
  <Accordion title="I sent an email in dev but nothing arrived">
260
262
 
261
- Nothing _should_ arrive — the `console` driver captures mail instead of sending. Read the dev inbox, or run `oke dev --docker` and open Mailpit's web UI to see the rendered message.
263
+ Nothing _should_ arrive — the `console` driver captures mail instead of sending. Read the dev inbox, or run `oke dev` and open Mailpit's web UI to see the rendered message.
262
264
 
263
265
  </Accordion>
264
266
  <Accordion title="A user says they stopped receiving messages">
@@ -326,7 +328,6 @@ Confirm a visible OS notification titled `okengine webpush interop`.
326
328
  ## Learn more
327
329
 
328
330
  - [Flow](/docs/elements/flow) — `fx.send` inside `do`
329
- - [Console · Channels](/docs/console/channels) — receipts, attempts, suppression
330
331
  - [Environment Variables](/docs/reference/environment-variables) — Channel boot credentials
331
332
  - [Configuration](/docs/reference/configuration) — `drivers.channel.*` maps
332
333
  - [i18n](/docs/reference/i18n) — ICU / `fx.t` vs Channel `{{field}}` catalogs
@@ -341,9 +342,4 @@ Confirm a visible OS notification titled `okengine webpush interop`.
341
342
  description="Eight elements overview."
342
343
  href="/docs/get-started/introduction"
343
344
  />
344
- <Card
345
- title="Console"
346
- description="Panels derived from the Manifest."
347
- href="/docs/console/overview"
348
- />
349
345
  </Cards>
@@ -124,7 +124,7 @@ reclaimed after its lease expires and continues at the next unfinished step.
124
124
 
125
125
  **Leader election needs a shared store.** The default in-memory CronStore is per process. Multi-replica
126
126
  exclusivity holds when every instance opens the same durable CronStore — `postgres` (SKIP LOCKED +
127
- lease reclaim, docker/prod default) or `file` (shared volume, single-host / local).
127
+ lease reclaim, `dev`/`prod` default) or `file` (shared volume, single-host).
128
128
 
129
129
  **Catch-up example:** an hourly clock down for five hours reports `missedRuns: 5` and
130
130
  `catchUp: "one"`, then a single tick runs the handler once.
@@ -141,16 +141,16 @@ Detection attaches `dstAmbiguity` on the cron row and the Console shows it. `oke
141
141
 
142
142
  ```typescript title="oke.config.ts"
143
143
  drivers: {
144
- clock: { local: "memory", docker: "postgres", test: "frozen", prod: "postgres" },
144
+ clock: { dev: "postgres", test: "frozen", prod: "postgres" },
145
145
  },
146
146
  ```
147
147
 
148
- | Driver | Behavior |
149
- | ---------- | ---------------------------------------------------------------------------------------------- |
150
- | `memory` | In-process CronStore + timers — single process; lost on exit |
151
- | `postgres` | Postgres CronStore (`oke_crons`) — multi-host leader election via SKIP LOCKED + lease reclaim |
152
- | `file` | On-disk CronStore (`.oke/crons.json`) — multi-process on a shared volume (local / single-host) |
153
- | `frozen` | Deterministic test clock — time advances only when the test says so |
148
+ | Driver | Behavior |
149
+ | ---------- | --------------------------------------------------------------------------------------------- |
150
+ | `memory` | In-process CronStore + timers — single process; lost on exit |
151
+ | `postgres` | Postgres CronStore (`oke_crons`) — multi-host leader election via SKIP LOCKED + lease reclaim |
152
+ | `file` | On-disk CronStore (`.oke/crons.json`) — multi-process on a shared volume (single-host) |
153
+ | `frozen` | Deterministic test clock — time advances only when the test says so |
154
154
 
155
155
  `frozen` is why the no-`Date.now()` rule pays off: tests inject time travel through `fx.clock` and every flow obeys it automatically.
156
156
 
@@ -195,7 +195,6 @@ They are not sharing one CronStore. In-memory leases are per process. Point ever
195
195
 
196
196
  - [Flow](/docs/elements/flow) — `on(trigger, flow)` and the `fx` surface
197
197
  - [fx · Runs](/docs/reference/fx#runs-observability-read) — native SLO checkers via `on(every(…))` + `fx.runs`
198
- - [Console · Clock](/docs/console/clock) — health numbers, pause / edit / wake early
199
198
  - [Signal](/docs/elements/signal) — reacting to events instead of time
200
199
 
201
200
  ## Next
@@ -207,9 +206,4 @@ They are not sharing one CronStore. In-memory leases are per process. Point ever
207
206
  description="Eight elements overview."
208
207
  href="/docs/get-started/introduction"
209
208
  />
210
- <Card
211
- title="Console"
212
- description="Panels derived from the Manifest."
213
- href="/docs/console/overview"
214
- />
215
209
  </Cards>
@@ -71,15 +71,15 @@ curl -X POST localhost:6530/orders -d '{"sku":"SKU-1","qty":2}' -H 'content-type
71
71
 
72
72
  ## Anatomy of a Flow
73
73
 
74
- | Part | Role |
75
- | ------------ | --------------------------------------------------------------- |
76
- | trigger | What starts the flow — `http`, a signal, `every`, a row change |
77
- | `in` | Input contract — validated before `do` runs; bad input is a 422 |
78
- | `out` | Output contract — the return value is checked against it |
79
- | `errors` | Typed failures — **returned** with `fx.fail`, never thrown |
80
- | `retry` | Optional whole-`do` backoff on thrown errors (same journal) |
81
- | `do` | The work — every read, write, emit, and call goes through `fx` |
82
- | `compensate` | Durable only — undo phase after terminal failure (same journal) |
74
+ | Part | Role |
75
+ | ------------ | -------------------------------------------------------------------------- |
76
+ | trigger | What starts the flow — `http`, a signal, `every`, a row change |
77
+ | `in` | Input contract — validated before `do` runs; bad input is a 422 |
78
+ | `out` | Output contract — the return value is checked against it |
79
+ | `errors` | Typed failures — **returned** with `fx.fail`, never thrown |
80
+ | `retry` | Optional whole-`do` backoff on thrown errors (same journal) |
81
+ | `do` | The work — every read, write, emit, and call goes through `fx` |
82
+ | `compensate` | Durable only — optional hook after auto per-step `{ undo }` (same journal) |
83
83
 
84
84
  Failures are values, not exceptions:
85
85
 
@@ -181,22 +181,22 @@ const order = await fx.call(getOrder, { id: orderId }); // from any other flow
181
181
 
182
182
  Everything a flow may touch, on one object:
183
183
 
184
- | Surface | Effect recorded | What it does |
185
- | ------------------------------------------- | --------------- | -------------------------------------------- |
186
- | `fx.store(db).select/insert/…` | read / write | SQL, KV, files, index sessions |
187
- | `fx.emit(signal, payload)` | emit | Publish a signal (transactional with writes) |
188
- | `fx.send(template, opts)` | send | Reach a human (email · SMS · …) |
189
- | `fx.ask(prompt, input)` | ask | Call a versioned AI prompt |
190
- | `fx.run(agent, input)` | ask | Run a bounded agent |
191
- | `fx.call(flow, input)` | call | Invoke another flow |
192
- | `fx.vault(contract)` | read | Read a secret (`Redacted`; logs masked) |
193
- | `fx.clock.now()` / `.sleep(…)` | — | Injected time / durable sleep |
194
- | `fx.cache.get/set` | — | Shared cache with effect-aware invalidation |
195
- | `fx.step(name, fn)` | — | Named durable step — never re-runs on replay |
196
- | `fx.all` / `fx.race` / `fx.retry` | — | Structured concurrency + backoff retry |
197
- | `fx.signal` | — | Ambient `AbortSignal` for the current branch |
198
- | `fx.id()` · `fx.log` · `fx.t` · `fx.locale` | — | UUIDs, redacting logger, ICU i18n |
199
- | `fx.auth` · `fx.operator` · `fx.tenant` | — | Who is calling (user / operator / tenant) |
184
+ | Surface | Effect recorded | What it does |
185
+ | ------------------------------------------- | --------------- | -------------------------------------------------- |
186
+ | `fx.store(db).select/insert/…` | read / write | SQL, KV, files, index sessions |
187
+ | `fx.emit(signal, payload)` | emit | Publish a signal (transactional with writes) |
188
+ | `fx.send(template, opts)` | send | Reach a human (email · SMS · …) |
189
+ | `fx.ask(prompt, input)` | ask | Call a versioned AI prompt |
190
+ | `fx.run(agent, input)` | ask | Run a bounded agent |
191
+ | `fx.call(flow, input)` | call | Invoke another flow |
192
+ | `fx.vault.get(contract)` | secret | Read a secret (`Redacted`; logs masked) |
193
+ | `fx.clock.now()` / `.sleep(…)` | — | Injected time / durable sleep |
194
+ | `fx.cache.get/set` | — | Shared cache with effect-aware invalidation |
195
+ | `fx.step(name, fn, { undo? })` | — | Named durable step — optional LIFO undo on failure |
196
+ | `fx.all` / `fx.race` / `fx.retry` | — | Structured concurrency + backoff retry |
197
+ | `fx.signal` | — | Ambient `AbortSignal` for the current branch |
198
+ | `fx.id()` · `fx.log` · `fx.t` · `fx.locale` | — | UUIDs, redacting logger, ICU i18n |
199
+ | `fx.auth` · `fx.operator` · `fx.tenant` | — | Who is calling (user / operator / tenant) |
200
200
 
201
201
  <Callout title="Why this strictness pays off">
202
202
  Effects are inferred from `fx` usage, so the Manifest knows exactly which flows read `orders` or
@@ -216,28 +216,27 @@ export const chargeOrder = flow("payments.chargeOrder", {
216
216
  in: OrderRef,
217
217
  out: z.boolean(),
218
218
  do: async ({ orderId }, fx) => {
219
- const intent = await fx.step("create-intent", () =>
220
- stripe(fx.vault(stripeKey).reveal()).create(orderId),
221
- );
219
+ const key = await fx.vault.get(stripeKey);
220
+ const intent = await fx.step("create-intent", () => stripe(key.reveal()).create(orderId));
222
221
 
223
222
  await fx.clock.sleep("verify-window", "2m"); // journals wakeAt in a durable flow
224
223
 
225
- return fx.step("confirm", () => stripe(fx.vault(stripeKey).reveal()).confirm(intent));
224
+ return fx.step("confirm", () => stripe(key.reveal()).confirm(intent));
226
225
  },
227
226
  });
228
227
  ```
229
228
 
230
229
  **Consequence:** completed steps replay from the journal — on resume, `create-intent` does not re-run, so the card is not charged twice.
231
230
 
232
- **Crash recovery needs a shared journal.** Set `drivers.journal: "postgres"` (the docker/prod template default) and every run persists in `oke_journal_runs` under a per-run lease: boot scans for orphaned `running` / due `sleeping` runs and resumes them, and the lease lets exactly one instance execute a run at a time. The default `memory` journal is per process — replay holds for that process only.
231
+ **Crash recovery needs a shared journal.** Set `drivers.journal: "postgres"` (the `dev`/`prod` template default) and every run persists in `oke_journal_runs` under a per-run lease: boot scans for orphaned `running` / `compensating` / due `sleeping` runs and resumes them, and the lease lets exactly one instance execute a run at a time. The default `memory` journal is per process — replay holds for that process only.
233
232
 
234
233
  Replay is **at-least-once** for a step whose body never persisted (crash mid-step, lease overrun): that step re-runs on reclaim, so keep step bodies short or internally idempotent. A client transport retry starts a _new_ run with a fresh `runId` — request-level idempotency is an application concern, not the journal's.
235
234
 
236
235
  For flaky sub-steps, wrap the work in `fx.retry` **inside** `fx.step` so a completed charge is never retried on resume. Coarse whole-body retry is also available as `flow(name, { retry: { retries, delay, backoff, jitter } })` and reuses the same journal session.
237
236
 
238
- After a **terminal** failure (`fx.fail` or exhausted retries / uncaught throw), optional
239
- `compensate` runs under the same journal. Undo work must use **new** step names
240
- (`undo:…`) never rewind forward steps:
237
+ After a **terminal** failure (`fx.fail` or exhausted retries / uncaught throw), declare
238
+ undo next to each step. Only **persisted** steps undo (LIFO) if `charge` throws before
239
+ it journals, `undo:charge` does not run:
241
240
 
242
241
  ```typescript
243
242
  export const chargeOrder = flow("payments.chargeOrder", {
@@ -245,23 +244,23 @@ export const chargeOrder = flow("payments.chargeOrder", {
245
244
  in: OrderRef,
246
245
  out: z.boolean(),
247
246
  do: async ({ orderId }, fx) => {
248
- await fx.step("reserve", () => reserve(orderId));
249
- await fx.step("charge", () => charge(orderId));
247
+ await fx.step("reserve", () => reserve(orderId), {
248
+ undo: () => release(orderId),
249
+ });
250
+ await fx.step("charge", () => charge(orderId), {
251
+ undo: (intent) => refund(intent), // journaled value — resume-safe
252
+ });
250
253
  return true;
251
254
  },
252
- compensate: async ({ input, completedSteps }, fx) => {
253
- if (completedSteps.includes("charge")) {
254
- await fx.step("undo:charge", () => refund(input.orderId));
255
- }
256
- if (completedSteps.includes("reserve")) {
257
- await fx.step("undo:reserve", () => release(input.orderId));
258
- }
259
- },
260
255
  });
261
256
  ```
262
257
 
263
- Thrown errors on the durable execute path commit the journal as `failed` (and land on Runs).
264
- `JournalSuspend` (sleep) is park, not failure compensate does not run.
258
+ The runtime journals undos as `undo:<name>` under status `compensating`, then commits
259
+ `failed`. Orphan reclaim resumes that phase without re-entering forward work.
260
+ `flow.compensate` remains an optional hook after auto undos for cross-cutting cleanup.
261
+ `JournalSuspend` (sleep) is park, not failure — undo does not run.
262
+ Use `fx.using` for same-attempt cleanup; `{ undo }` for durable external effects — not both
263
+ for the same release.
265
264
 
266
265
  ## Composition is just calls
267
266
 
@@ -298,9 +297,9 @@ Use `fx.all` (or `fx.race`) with thunks. The first rejection aborts siblings thr
298
297
  Put `fx.retry` **inside** `fx.step`, not around it. Completed steps replay from the journal and never re-run. `flow(name, { retry })` is for coarse whole-body retries on the same session.
299
298
 
300
299
  </Accordion>
301
- <Accordion title="When does compensate run?">
300
+ <Accordion title="When does undo / compensate run?">
302
301
 
303
- Only after terminal failure for that journal attempt — not on sleep, not mid-retry, not on success. Undo bodies must be idempotent (`undo:*` steps resume like any other step). Irreversible effects (`send` / `ask`) need developer-declared undos or an explicit no-op.
302
+ Only after terminal failure for that journal attempt — not on sleep, not mid-retry, not on success. Per-step `{ undo }` runs first (LIFO, only for persisted steps), then optional `flow.compensate`. The run stays `compensating` until undos finish so a crash mid-undo resumes the undo phase, not forward `do`. Undo bodies must be idempotent. Irreversible effects (`send` / `ask`) need developer-declared undos or an explicit no-op.
304
303
 
305
304
  </Accordion>
306
305
  <Accordion title="How do I share logic between flows — a private function?">
@@ -320,8 +319,6 @@ Only that run fails — the schedule keeps firing and the process does not exit.
320
319
  - [fx](/docs/reference/fx) — full `fx` surface, including ICU `fx.t` / `fx.locale`
321
320
  - [Signal](/docs/elements/signal) — delivery physics (`once` · `broadcast` · `live`)
322
321
  - [Clock](/docs/elements/clock) — schedules and durable sleep
323
- - [Console · Flows](/docs/console/flows) — the Manifest-derived panel
324
- - [Runs](/docs/console/runs) — how a flow execution is observed
325
322
 
326
323
  ## Next
327
324
 
@@ -332,9 +329,4 @@ Only that run fails — the schedule keeps firing and the process does not exit.
332
329
  description="Eight elements overview."
333
330
  href="/docs/get-started/introduction"
334
331
  />
335
- <Card
336
- title="Console"
337
- description="Panels derived from the Manifest."
338
- href="/docs/console/overview"
339
- />
340
332
  </Cards>
@@ -48,7 +48,7 @@ import { member, canBook, fair } from "./gates";
48
48
 
49
49
  export const app = oke({
50
50
  name: "shop",
51
- env: "local",
51
+ env: "dev",
52
52
  gate: { policies: [member, canBook, fair] },
53
53
  });
54
54
  ```
@@ -166,7 +166,7 @@ Fine-grained authorization (`gate.scope`, roles) stays opt-in — attach it only
166
166
 
167
167
  All five run as atomic Lua on the kv driver — correct under concurrency, identical on the memory
168
168
  driver in tests. Boot opens a dedicated `oke:gates` namespace on **`drivers.store.kv`**
169
- (`memory` locally · `redis` in docker/prod) so multi-instance rate limits share counters.
169
+ (`memory` in test · `redis` in `dev`/`prod`) so multi-instance rate limits share counters.
170
170
 
171
171
  ## Auth posture at boot
172
172
 
@@ -183,7 +183,7 @@ on(http.post("/bookings").gate(member, canBook), flow("bookings.create", {/* …
183
183
  posture but does **not** authenticate.
184
184
 
185
185
  `gate: { unguardedHttp: "allow" }` skips the audit **only** when `env === "test"`.
186
- In `local` / `prod` / `docker` migrate with per-trigger `gate.public`.
186
+ In `dev` / `prod` migrate with per-trigger `gate.public`.
187
187
 
188
188
  ## Built-in auth (`gate.auth`)
189
189
 
@@ -196,7 +196,7 @@ import { member, canBook } from "./gates";
196
196
 
197
197
  export const app = oke({
198
198
  name: "shop",
199
- env: "local",
199
+ env: "dev",
200
200
  gate: {
201
201
  auth: {
202
202
  emailAndPassword: { enabled: true },
@@ -248,7 +248,8 @@ gate: {
248
248
  }
249
249
  ```
250
250
 
251
- Customize tables, then run `oke schema generate` (supports `--check` in CI). Extra sign-in
251
+ Customize tables, then run `oke schema generate` (writes `.oke/schema/oke.ts`;
252
+ supports `--check` in CI). Extra sign-in
252
253
  shapes: [Plugins](/docs/plugins) (username, magic link, OTP, TOTP, passkeys). Call auth from
253
254
  [createClient](/docs/reference/client) — one client, helpers in `okengine/client/auth`.
254
255
 
@@ -308,7 +309,6 @@ Keying an authenticated endpoint by IP punishes shared NAT.
308
309
  - [fx](/docs/reference/fx) — `fx.auth`, `fx.operator`, `fx.principal`
309
310
  - [Client](/docs/reference/client) — Bearer `createClient` + `okengine/client/auth`
310
311
  - [Plugins](/docs/plugins) — username, magic link, OTP, TOTP, passkeys
311
- - [Console · Gates](/docs/console/gates) — decision audit and posture
312
312
  - [Vault](/docs/elements/vault) — credentials your policies protect
313
313
 
314
314
  ## Next
@@ -316,9 +316,4 @@ Keying an authenticated endpoint by IP punishes shared NAT.
316
316
  <Cards>
317
317
  <Card title="Vault" description="Continue to Vault." href="/docs/elements/vault" />
318
318
  <Card title="Plugins" description="Sign-in method plugins under /auth." href="/docs/plugins" />
319
- <Card
320
- title="Console"
321
- description="Panels derived from the Manifest."
322
- href="/docs/console/overview"
323
- />
324
319
  </Cards>
@@ -238,13 +238,13 @@ When a signal disappears from code, reconciliation marks its config row `orphane
238
238
 
239
239
  ```typescript title="oke.config.ts"
240
240
  drivers: {
241
- signal: { local: "memory", docker: "redis", test: "memory", prod: "redis" },
241
+ signal: { dev: "redis", test: "memory", prod: "redis" },
242
242
  },
243
243
  ```
244
244
 
245
245
  | Driver | Runs as | Boot today |
246
246
  | ---------- | ------------------------------------ | --------------------------------------------------------------------------- |
247
- | `memory` | in-process | Local loop + tests — zero infrastructure |
247
+ | `memory` | in-process | Tests — zero infrastructure |
248
248
  | `redis` | Redis / Valkey / Dragonfly image pin | Boot-bound — **emit relay** via Streams / pub/sub; consume is process-local |
249
249
  | `postgres` | Postgres | Driver exists; boot **fails loud** until a LISTEN/NOTIFY SQL client binds |
250
250
  | `nats` | NATS | Driver exists; boot **fails loud** until a production NATS client binds |
@@ -291,7 +291,6 @@ At-least-once: crash-after-claim reclaims when the lease expires, and a handler
291
291
  ## Learn more
292
292
 
293
293
  - [Flow](/docs/elements/flow) — `on(trigger, flow)` and `fx.emit`
294
- - [Console · Signals](/docs/console/signals) — topology, delivery stats, DLQ replay
295
294
  - [Clock](/docs/elements/clock) — scheduled and delayed work
296
295
 
297
296
  ## Next
@@ -303,9 +302,4 @@ At-least-once: crash-after-claim reclaims when the lease expires, and a handler
303
302
  description="Eight elements overview."
304
303
  href="/docs/get-started/introduction"
305
304
  />
306
- <Card
307
- title="Console"
308
- description="Panels derived from the Manifest."
309
- href="/docs/console/overview"
310
- />
311
305
  </Cards>