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.
- package/AGENTS.md +24 -23
- package/README.md +52 -346
- package/docs/spec/console.md +165 -142
- package/docs/spec/example.md +490 -312
- package/docs/spec/four-applications.md +495 -314
- package/docs/spec/unified-theory.md +184 -175
- package/package.json +45 -37
- package/spec/manifest.v1.schema.json +40 -9
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +53 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +386 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +163 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev.test.ts +148 -21
- package/src/cli/dev.ts +208 -134
- package/src/cli/doc-drift.test.ts +3 -2
- package/src/cli/doc-drift.ts +21 -50
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +7 -8
- package/src/cli/docker.ts +1 -3
- package/src/cli/doctor-diff-examples.ts +1 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +41 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +45 -0
- package/src/cli/ports.test.ts +4 -13
- package/src/cli/ports.ts +1 -3
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +2 -7
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +8 -29
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +96 -30
- package/src/compiler/extract.ts +362 -156
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +4 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +57 -34
- package/src/config/index.ts +181 -37
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +14 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +23 -60
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +112 -20
- package/src/docker/derive.ts +5 -19
- package/src/docker/docker.test.ts +15 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +4 -11
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +5 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +6 -1
- package/src/docker/recipes/rustfs.ts +33 -0
- package/src/docker/stack-id.test.ts +33 -0
- package/src/docker/stack-id.ts +25 -13
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/types.ts +13 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -56
- package/src/drivers/memory.ts +14 -41
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +5 -17
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.ts +1 -5
- package/src/drivers/vault-sops.ts +10 -35
- package/src/drivers/vault-types.ts +1 -7
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +8 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.ts +11 -21
- package/src/elements/store/sql-session.test.ts +50 -0
- package/src/elements/store/sql-session.ts +60 -63
- package/src/elements/store/table.ts +35 -19
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +37 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +18 -32
- package/src/elements/vault.test.ts +12 -28
- package/src/elements/vault.ts +8 -12
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +34 -94
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.ts +2 -8
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +17 -17
- package/src/kernel/boot-bind/store.ts +44 -50
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -9
- package/src/kernel/boot.ts +29 -76
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +5 -25
- package/src/kernel/fx.test.ts +15 -44
- package/src/kernel/fx.ts +27 -79
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +10 -10
- package/src/kernel/hooks.ts +3 -12
- package/src/kernel/index.ts +4 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +1 -6
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +48 -24
- package/src/kernel/registry.ts +80 -29
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +4 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/index.ts +2 -9
- package/src/manifest/types.ts +29 -5
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +4 -14
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +15 -43
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +13 -31
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- 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
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
| |
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
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);
|
|
56
|
-
on(every("10m"), expireStale);
|
|
57
|
-
on(orderPlaced, sendReceipt);
|
|
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
|
|
70
|
-
|
|
71
|
-
| **Flow**
|
|
72
|
-
| **Signal**
|
|
73
|
-
| **Store**
|
|
74
|
-
| **Clock**
|
|
75
|
-
| **Gate**
|
|
76
|
-
| **Vault**
|
|
77
|
-
| **Channel** | email · SMS · WhatsApp · push
|
|
78
|
-
| **AI**
|
|
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",
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
retries: 5,
|
|
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
|
|
105
|
-
|
|
106
|
-
| streaming tokens to the client
|
|
107
|
-
| an agent loop with steps
|
|
108
|
-
| vector search for RAG
|
|
109
|
-
| provider fallback chains
|
|
110
|
-
| **non-determinism** (same input ≠ same output) | ❌ breaks caching, testing, and replay
|
|
111
|
-
| **cost as a first-class dimension**
|
|
112
|
-
| **prompts as versioned, evaluated artifacts**
|
|
113
|
-
| **egress privacy boundaries** to third parties | ❌ Gates guard entry, not exit
|
|
114
|
-
| **testing a non-deterministic output**
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
| #
|
|
154
|
-
|
|
155
|
-
| 1
|
|
156
|
-
| 2
|
|
157
|
-
| 3
|
|
158
|
-
| 4
|
|
159
|
-
| 5
|
|
160
|
-
| 6
|
|
161
|
-
| 7
|
|
162
|
-
| 8
|
|
163
|
-
| 9
|
|
164
|
-
| 10
|
|
165
|
-
| 11
|
|
166
|
-
| 12
|
|
167
|
-
| 13
|
|
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)
|
|
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
|
|
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
|
|
217
|
-
|
|
218
|
-
| `store.sql`
|
|
219
|
-
| `store.kv`
|
|
220
|
-
| `store.files` | `fs` · `s3`
|
|
221
|
-
| `signal`
|
|
222
|
-
| `clock`
|
|
223
|
-
| `vault`
|
|
224
|
-
| `channel.*`
|
|
225
|
-
| `store.index` | `pgvector` · `qdrant` · `meilisearch` · `typesense`
|
|
226
|
-
| `ai`
|
|
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
|
|
237
|
-
|
|
238
|
-
| **Our own toolchain**
|
|
239
|
-
| **What we require of users** | conservative floor + day-one support for new majors | a framework demanding bleeding edge loses adoption
|
|
240
|
-
| **Adopted infrastructure**
|
|
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
|
|
271
|
-
|
|
272
|
-
| **Runtime**
|
|
273
|
-
| **Router**
|
|
274
|
-
| **Validation**
|
|
275
|
-
| **AoT compiler**
|
|
276
|
-
| **Context**
|
|
277
|
-
| **Infrastructure** | driver model (Nitro/unstorage-style): dev = memory/sqlite/fs ⇄ prod = real software
|
|
278
|
-
| **Contracts**
|
|
279
|
-
| **Auth**
|
|
280
|
-
| **AI**
|
|
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
|
|
293
|
-
|
|
294
|
-
| **Catalog**
|
|
295
|
-
| **Architecture**
|
|
296
|
-
| **API Explorer**
|
|
297
|
-
| **Traces**
|
|
298
|
-
| **Store**
|
|
299
|
-
| **Signals**
|
|
300
|
-
| **Clock**
|
|
301
|
-
| **Gates**
|
|
302
|
-
| **Channels**
|
|
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
|
|
314
|
-
|
|
315
|
-
| Runtime
|
|
316
|
-
| Language
|
|
317
|
-
| Manifest parser | oxc
|
|
318
|
-
| Validation
|
|
319
|
-
| ORM
|
|
320
|
-
| `store.sql`
|
|
321
|
-
| `store.kv`
|
|
322
|
-
| `store.files`
|
|
323
|
-
| `signal`
|
|
324
|
-
| `clock`
|
|
325
|
-
| `vault`
|
|
326
|
-
| `channel.email` | dev `console` · prod `smtp`
|
|
327
|
-
| `delivery`
|
|
328
|
-
| `store.index`
|
|
329
|
-
| `ai`
|
|
330
|
-
| AI + `pii`
|
|
331
|
-
| AI caching
|
|
332
|
-
| Auth
|
|
333
|
-
| Topology
|
|
334
|
-
| Tenancy
|
|
335
|
-
| Cache
|
|
336
|
-
| Rate limit
|
|
337
|
-
| i18n
|
|
338
|
-
| Errors
|
|
339
|
-
| Telemetry
|
|
340
|
-
| Migrations
|
|
341
|
-
| Console
|
|
342
|
-
| Ports
|
|
343
|
-
| License
|
|
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
|
-
|
|
|
354
|
-
|
|
355
|
-
| Throughput
|
|
356
|
-
| **Transactional with your data** | **yes**
|
|
357
|
-
| Extra service
|
|
358
|
-
| Fan-out / live
|
|
359
|
-
| DLQ inspection
|
|
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
|
|
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?
|
|
371
|
-
| **Data replicas**
|
|
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" } })
|
|
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)
|
|
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
|
|
416
|
-
|
|
417
|
-
| Kernel (edge profile) | < 15 kB
|
|
418
|
-
| Client runtime
|
|
419
|
-
| Cold start on Bun
|
|
420
|
-
| p99 routing overhead
|
|
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
|
|
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
|
|
439
|
-
|
|
440
|
-
| **MVP (0.1–0.4)**
|
|
441
|
-
| **v1 (0.5–1.0)**
|
|
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
|
|
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
|
|
470
|
-
| Scope is enormous for a small team
|
|
471
|
-
| Raw throughput below Encore's Rust runtime
|
|
472
|
-
| Ecosystem cold start
|
|
473
|
-
| Auto cache invalidation edge cases
|
|
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
|
|
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
|
|
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
|
-
|
|
498
|
+
_Adopt what exists. Build only what doesn't. Name things after standards._
|