okengine 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +91 -0
- package/README.md +327 -0
- package/docs/spec/complete-example.md +1188 -0
- package/docs/spec/console.md +739 -0
- package/docs/spec/four-applications.md +1188 -0
- package/docs/spec/unified-theory.md +489 -0
- package/package.json +152 -0
- package/spec/manifest.v1.schema.json +624 -0
- package/src/auth/api-keys.ts +168 -0
- package/src/auth/attenuation.ts +116 -0
- package/src/auth/auth.test.ts +273 -0
- package/src/auth/cross-plane.ts +98 -0
- package/src/auth/index.ts +112 -0
- package/src/auth/invites.ts +66 -0
- package/src/auth/invoke-as.ts +49 -0
- package/src/auth/operator.ts +178 -0
- package/src/auth/planes.ts +102 -0
- package/src/auth/plugin.ts +44 -0
- package/src/auth/roles.ts +84 -0
- package/src/auth/sessions.ts +418 -0
- package/src/auth/tables.ts +131 -0
- package/src/cli/args.ts +50 -0
- package/src/cli/branch.ts +75 -0
- package/src/cli/build.ts +86 -0
- package/src/cli/client-add.test.ts +140 -0
- package/src/cli/client-add.ts +164 -0
- package/src/cli/completion.test.ts +58 -0
- package/src/cli/completion.ts +296 -0
- package/src/cli/dev-app-runner.ts +77 -0
- package/src/cli/dev.test.ts +435 -0
- package/src/cli/dev.ts +594 -0
- package/src/cli/doc-drift.test.ts +146 -0
- package/src/cli/doc-drift.ts +397 -0
- package/src/cli/docker-cli.test.ts +221 -0
- package/src/cli/docker.ts +127 -0
- package/src/cli/doctor-diff-examples.ts +92 -0
- package/src/cli/doctor-diff.test.ts +91 -0
- package/src/cli/doctor-diff.ts +274 -0
- package/src/cli/doctor-pii.test.ts +98 -0
- package/src/cli/doctor-pii.ts +151 -0
- package/src/cli/doctor.test.ts +150 -0
- package/src/cli/doctor.ts +223 -0
- package/src/cli/eval.ts +122 -0
- package/src/cli/exit.ts +19 -0
- package/src/cli/gates-list.test.ts +47 -0
- package/src/cli/gates-list.ts +84 -0
- package/src/cli/images.ts +277 -0
- package/src/cli/index.ts +99 -0
- package/src/cli/json-out.test.ts +129 -0
- package/src/cli/load-config.ts +71 -0
- package/src/cli/mcp-from-console.ts +50 -0
- package/src/cli/privacy-erase.ts +73 -0
- package/src/cli/registry.ts +455 -0
- package/src/cli/safe-defaults.test.ts +92 -0
- package/src/cli/schema.ts +196 -0
- package/src/cli/stack.ts +82 -0
- package/src/cli/start.ts +106 -0
- package/src/cli/upgrade.ts +105 -0
- package/src/cli/vault-cmd.ts +140 -0
- package/src/client/budget-entry.ts +34 -0
- package/src/client/budget.test.ts +17 -0
- package/src/client/create.test.ts +159 -0
- package/src/client/create.ts +152 -0
- package/src/client/errors.ts +60 -0
- package/src/client/index.ts +35 -0
- package/src/client/notes-contract.test.ts +289 -0
- package/src/client/transport.test.ts +123 -0
- package/src/client/transport.ts +254 -0
- package/src/client/types.ts +282 -0
- package/src/compiler/aot.test.ts +248 -0
- package/src/compiler/aot.ts +182 -0
- package/src/compiler/differential.test.ts +241 -0
- package/src/compiler/dynamic.ts +54 -0
- package/src/compiler/effects-infer.ts +541 -0
- package/src/compiler/emit.ts +40 -0
- package/src/compiler/extract.test.ts +177 -0
- package/src/compiler/extract.ts +1368 -0
- package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
- package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
- package/src/compiler/fixtures/skyport/src/app.ts +10 -0
- package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
- package/src/compiler/fixtures/skyport/src/core.ts +3 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
- package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
- package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
- package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
- package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
- package/src/compiler/fixtures/skyport.expected.json +241 -0
- package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
- package/src/compiler/http-parse.ts +214 -0
- package/src/compiler/index.ts +67 -0
- package/src/compiler/response.ts +89 -0
- package/src/compiler/sucrose.ts +238 -0
- package/src/config/index.ts +167 -0
- package/src/console/budget.test.ts +73 -0
- package/src/console/index.ts +30 -0
- package/src/console/server/access.test.ts +370 -0
- package/src/console/server/access.ts +777 -0
- package/src/console/server/ai.test.ts +172 -0
- package/src/console/server/ai.ts +632 -0
- package/src/console/server/app.ts +294 -0
- package/src/console/server/auth-rate.test.ts +81 -0
- package/src/console/server/auth-rate.ts +72 -0
- package/src/console/server/bind.ts +25 -0
- package/src/console/server/channels.test.ts +179 -0
- package/src/console/server/channels.ts +469 -0
- package/src/console/server/claim.test.ts +66 -0
- package/src/console/server/claim.ts +134 -0
- package/src/console/server/clock.test.ts +239 -0
- package/src/console/server/clock.ts +390 -0
- package/src/console/server/console.test.ts +338 -0
- package/src/console/server/diff.test.ts +299 -0
- package/src/console/server/diff.ts +352 -0
- package/src/console/server/dry-run.audit.test.ts +118 -0
- package/src/console/server/flows-invoke.test.ts +148 -0
- package/src/console/server/flows.ts +3633 -0
- package/src/console/server/gates.test.ts +360 -0
- package/src/console/server/gates.ts +869 -0
- package/src/console/server/index.ts +141 -0
- package/src/console/server/live.test.ts +30 -0
- package/src/console/server/live.ts +109 -0
- package/src/console/server/plugin.ts +50 -0
- package/src/console/server/plugins.test.ts +131 -0
- package/src/console/server/plugins.ts +429 -0
- package/src/console/server/runs-pii.ts +98 -0
- package/src/console/server/security-headers.ts +97 -0
- package/src/console/server/security.gate.test.ts +286 -0
- package/src/console/server/serve.ts +319 -0
- package/src/console/server/signals.test.ts +88 -0
- package/src/console/server/signals.ts +282 -0
- package/src/console/server/state.ts +982 -0
- package/src/console/server/store.test.ts +233 -0
- package/src/console/server/store.ts +861 -0
- package/src/console/server/structural.ts +95 -0
- package/src/console/server/vault.test.ts +251 -0
- package/src/console/server/vault.ts +430 -0
- package/src/console/ui/access/AccessA11yView.tsx +237 -0
- package/src/console/ui/access/a11y.test.tsx +122 -0
- package/src/console/ui/access/acknowledgement.test.ts +13 -0
- package/src/console/ui/access/acknowledgement.ts +35 -0
- package/src/console/ui/access/blast-radius.test.ts +26 -0
- package/src/console/ui/access/blast-radius.ts +40 -0
- package/src/console/ui/access/confirmation.test.ts +38 -0
- package/src/console/ui/access/confirmation.ts +36 -0
- package/src/console/ui/access/fixture.ts +203 -0
- package/src/console/ui/access/grantable.test.ts +17 -0
- package/src/console/ui/access/grantable.ts +36 -0
- package/src/console/ui/access/hygiene.test.ts +12 -0
- package/src/console/ui/access/hygiene.ts +39 -0
- package/src/console/ui/access/index.ts +54 -0
- package/src/console/ui/access/provenance.test.ts +12 -0
- package/src/console/ui/access/provenance.ts +29 -0
- package/src/console/ui/access/search.test.ts +17 -0
- package/src/console/ui/access/search.ts +72 -0
- package/src/console/ui/access/types.ts +111 -0
- package/src/console/ui/ai/AiA11yView.tsx +265 -0
- package/src/console/ui/ai/a11y.test.tsx +99 -0
- package/src/console/ui/ai/findings.ts +41 -0
- package/src/console/ui/ai/fixture.ts +182 -0
- package/src/console/ui/ai/format.ts +90 -0
- package/src/console/ui/ai/group.test.ts +37 -0
- package/src/console/ui/ai/group.ts +88 -0
- package/src/console/ui/ai/index.ts +66 -0
- package/src/console/ui/ai/promotion.test.ts +77 -0
- package/src/console/ui/ai/promotion.ts +150 -0
- package/src/console/ui/ai/search.test.ts +40 -0
- package/src/console/ui/ai/search.ts +89 -0
- package/src/console/ui/ai/types.ts +139 -0
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
- package/src/console/ui/architecture/a11y.test.tsx +97 -0
- package/src/console/ui/architecture/boundary.ts +42 -0
- package/src/console/ui/architecture/declared.ts +165 -0
- package/src/console/ui/architecture/fixture.ts +74 -0
- package/src/console/ui/architecture/index.ts +84 -0
- package/src/console/ui/architecture/layers.ts +64 -0
- package/src/console/ui/architecture/layout.ts +68 -0
- package/src/console/ui/architecture/pathologies.ts +260 -0
- package/src/console/ui/architecture/search.ts +145 -0
- package/src/console/ui/architecture/traffic.ts +102 -0
- package/src/console/ui/architecture/types.ts +144 -0
- package/src/console/ui/architecture/view.test.ts +165 -0
- package/src/console/ui/architecture/view.ts +516 -0
- package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
- package/src/console/ui/channels/a11y.test.tsx +96 -0
- package/src/console/ui/channels/confirmation.test.ts +37 -0
- package/src/console/ui/channels/confirmation.ts +27 -0
- package/src/console/ui/channels/fallback.test.ts +15 -0
- package/src/console/ui/channels/fallback.ts +20 -0
- package/src/console/ui/channels/findings.ts +38 -0
- package/src/console/ui/channels/fixture.ts +134 -0
- package/src/console/ui/channels/group.ts +25 -0
- package/src/console/ui/channels/index.ts +57 -0
- package/src/console/ui/channels/locale.test.ts +17 -0
- package/src/console/ui/channels/locale.ts +31 -0
- package/src/console/ui/channels/mask.test.ts +14 -0
- package/src/console/ui/channels/mask.ts +12 -0
- package/src/console/ui/channels/search.ts +58 -0
- package/src/console/ui/channels/taxonomy.test.ts +17 -0
- package/src/console/ui/channels/taxonomy.ts +49 -0
- package/src/console/ui/channels/types.ts +117 -0
- package/src/console/ui/clock/ClockA11yView.tsx +182 -0
- package/src/console/ui/clock/a11y.test.tsx +99 -0
- package/src/console/ui/clock/confirmation.test.ts +32 -0
- package/src/console/ui/clock/confirmation.ts +34 -0
- package/src/console/ui/clock/findings.ts +40 -0
- package/src/console/ui/clock/fixture.ts +111 -0
- package/src/console/ui/clock/health.test.ts +25 -0
- package/src/console/ui/clock/health.ts +61 -0
- package/src/console/ui/clock/index.ts +49 -0
- package/src/console/ui/clock/search.test.ts +39 -0
- package/src/console/ui/clock/search.ts +76 -0
- package/src/console/ui/clock/timeline.test.ts +44 -0
- package/src/console/ui/clock/timeline.ts +41 -0
- package/src/console/ui/clock/types.ts +78 -0
- package/src/console/ui/clock/waiting-on.test.ts +34 -0
- package/src/console/ui/clock/waiting-on.ts +83 -0
- package/src/console/ui/confirmation.unify.test.ts +92 -0
- package/src/console/ui/diff/DiffA11yView.tsx +85 -0
- package/src/console/ui/diff/a11y.test.tsx +99 -0
- package/src/console/ui/diff/fixture.ts +85 -0
- package/src/console/ui/diff/group.test.ts +58 -0
- package/src/console/ui/diff/group.ts +97 -0
- package/src/console/ui/diff/index.ts +38 -0
- package/src/console/ui/diff/search.test.ts +32 -0
- package/src/console/ui/diff/search.ts +75 -0
- package/src/console/ui/diff/summary.ts +74 -0
- package/src/console/ui/diff/types.ts +48 -0
- package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
- package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
- package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
- package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
- package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
- package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
- package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
- package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
- package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
- package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
- package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
- package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
- package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
- package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
- package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
- package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
- package/src/console/ui/dist/index.html +14 -0
- package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
- package/src/console/ui/flows/a11y.test.tsx +105 -0
- package/src/console/ui/flows/buffer.test.ts +91 -0
- package/src/console/ui/flows/buffer.ts +118 -0
- package/src/console/ui/flows/confirmation.ts +131 -0
- package/src/console/ui/flows/contract.test.ts +89 -0
- package/src/console/ui/flows/contract.ts +353 -0
- package/src/console/ui/flows/fixture.ts +81 -0
- package/src/console/ui/flows/graph.test.ts +101 -0
- package/src/console/ui/flows/graph.ts +549 -0
- package/src/console/ui/flows/index.ts +87 -0
- package/src/console/ui/flows/save-as-test.test.ts +47 -0
- package/src/console/ui/flows/save-as-test.ts +99 -0
- package/src/console/ui/flows/search.ts +255 -0
- package/src/console/ui/flows/tiers.ts +140 -0
- package/src/console/ui/gates/GatesA11yView.tsx +192 -0
- package/src/console/ui/gates/a11y.test.tsx +116 -0
- package/src/console/ui/gates/audit.test.ts +40 -0
- package/src/console/ui/gates/audit.ts +63 -0
- package/src/console/ui/gates/denial.test.ts +36 -0
- package/src/console/ui/gates/denial.ts +51 -0
- package/src/console/ui/gates/findings.ts +19 -0
- package/src/console/ui/gates/fixture.ts +189 -0
- package/src/console/ui/gates/group.test.ts +30 -0
- package/src/console/ui/gates/group.ts +102 -0
- package/src/console/ui/gates/index.ts +47 -0
- package/src/console/ui/gates/search.test.ts +49 -0
- package/src/console/ui/gates/search.ts +115 -0
- package/src/console/ui/gates/types.ts +121 -0
- package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
- package/src/console/ui/overview/a11y.test.tsx +113 -0
- package/src/console/ui/overview/busiest.ts +26 -0
- package/src/console/ui/overview/compose.ts +133 -0
- package/src/console/ui/overview/cost.test.ts +39 -0
- package/src/console/ui/overview/cost.ts +138 -0
- package/src/console/ui/overview/fixture.ts +161 -0
- package/src/console/ui/overview/golden.ts +57 -0
- package/src/console/ui/overview/index.ts +59 -0
- package/src/console/ui/overview/rank.test.ts +136 -0
- package/src/console/ui/overview/rank.ts +210 -0
- package/src/console/ui/overview/slo.test.ts +73 -0
- package/src/console/ui/overview/slo.ts +229 -0
- package/src/console/ui/overview/types.ts +121 -0
- package/src/console/ui/overview/verdict.ts +131 -0
- package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
- package/src/console/ui/plugins/a11y.test.tsx +97 -0
- package/src/console/ui/plugins/command.test.ts +22 -0
- package/src/console/ui/plugins/command.ts +27 -0
- package/src/console/ui/plugins/findings.ts +39 -0
- package/src/console/ui/plugins/fixture.ts +233 -0
- package/src/console/ui/plugins/group.test.ts +38 -0
- package/src/console/ui/plugins/group.ts +67 -0
- package/src/console/ui/plugins/index.ts +40 -0
- package/src/console/ui/plugins/search.ts +67 -0
- package/src/console/ui/plugins/types.ts +115 -0
- package/src/console/ui/runs/RunsA11yView.tsx +267 -0
- package/src/console/ui/runs/a11y.test.tsx +99 -0
- package/src/console/ui/runs/explain.test.ts +23 -0
- package/src/console/ui/runs/explain.ts +32 -0
- package/src/console/ui/runs/fixture.ts +189 -0
- package/src/console/ui/runs/group.test.ts +24 -0
- package/src/console/ui/runs/group.ts +85 -0
- package/src/console/ui/runs/histogram.test.ts +31 -0
- package/src/console/ui/runs/histogram.ts +85 -0
- package/src/console/ui/runs/index.ts +75 -0
- package/src/console/ui/runs/project.ts +122 -0
- package/src/console/ui/runs/query.test.ts +50 -0
- package/src/console/ui/runs/query.ts +283 -0
- package/src/console/ui/runs/search.test.ts +45 -0
- package/src/console/ui/runs/search.ts +141 -0
- package/src/console/ui/runs/trace-link.test.ts +30 -0
- package/src/console/ui/runs/trace-link.ts +99 -0
- package/src/console/ui/runs/types.ts +137 -0
- package/src/console/ui/shell/App.tsx +56 -0
- package/src/console/ui/shell/client.ts +1715 -0
- package/src/console/ui/shell/components/ui.tsx +110 -0
- package/src/console/ui/shell/index.html +12 -0
- package/src/console/ui/shell/layout/Shell.tsx +95 -0
- package/src/console/ui/shell/main.tsx +281 -0
- package/src/console/ui/shell/panels/Access.tsx +5 -0
- package/src/console/ui/shell/panels/Ai.tsx +5 -0
- package/src/console/ui/shell/panels/Architecture.tsx +5 -0
- package/src/console/ui/shell/panels/Channels.tsx +5 -0
- package/src/console/ui/shell/panels/Clock.tsx +5 -0
- package/src/console/ui/shell/panels/Diff.tsx +5 -0
- package/src/console/ui/shell/panels/Flows.tsx +5 -0
- package/src/console/ui/shell/panels/Gates.tsx +5 -0
- package/src/console/ui/shell/panels/Overview.tsx +6 -0
- package/src/console/ui/shell/panels/Plugins.tsx +5 -0
- package/src/console/ui/shell/panels/Runs.tsx +5 -0
- package/src/console/ui/shell/panels/Signals.tsx +5 -0
- package/src/console/ui/shell/panels/Store.tsx +5 -0
- package/src/console/ui/shell/panels/Traces.tsx +5 -0
- package/src/console/ui/shell/panels/Vault.tsx +5 -0
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
- package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
- package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
- package/src/console/ui/shell/setup/Wizard.tsx +189 -0
- package/src/console/ui/shell/styles.css +75 -0
- package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
- package/src/console/ui/signals/a11y.test.tsx +99 -0
- package/src/console/ui/signals/confirmation.test.ts +39 -0
- package/src/console/ui/signals/confirmation.ts +63 -0
- package/src/console/ui/signals/dry-run.test.ts +18 -0
- package/src/console/ui/signals/dry-run.ts +36 -0
- package/src/console/ui/signals/durable.test.ts +22 -0
- package/src/console/ui/signals/durable.ts +41 -0
- package/src/console/ui/signals/findings.ts +33 -0
- package/src/console/ui/signals/fixture.ts +242 -0
- package/src/console/ui/signals/group.test.ts +32 -0
- package/src/console/ui/signals/group.ts +49 -0
- package/src/console/ui/signals/index.ts +52 -0
- package/src/console/ui/signals/monitor.test.ts +30 -0
- package/src/console/ui/signals/monitor.ts +79 -0
- package/src/console/ui/signals/schema-form.test.ts +34 -0
- package/src/console/ui/signals/schema-form.ts +112 -0
- package/src/console/ui/signals/search.ts +102 -0
- package/src/console/ui/signals/types.ts +71 -0
- package/src/console/ui/store/StoreA11yView.tsx +199 -0
- package/src/console/ui/store/a11y.test.tsx +99 -0
- package/src/console/ui/store/cache-view.test.ts +13 -0
- package/src/console/ui/store/cache-view.ts +36 -0
- package/src/console/ui/store/confirmation.test.ts +38 -0
- package/src/console/ui/store/confirmation.ts +55 -0
- package/src/console/ui/store/dry-run.test.ts +15 -0
- package/src/console/ui/store/dry-run.ts +29 -0
- package/src/console/ui/store/fixture.ts +163 -0
- package/src/console/ui/store/group.test.ts +21 -0
- package/src/console/ui/store/group.ts +41 -0
- package/src/console/ui/store/index.ts +40 -0
- package/src/console/ui/store/search.ts +78 -0
- package/src/console/ui/store/types.ts +65 -0
- package/src/console/ui/store/will-not-fire.test.ts +19 -0
- package/src/console/ui/store/will-not-fire.ts +40 -0
- package/src/console/ui/traces/TracesA11yView.tsx +200 -0
- package/src/console/ui/traces/a11y.test.tsx +97 -0
- package/src/console/ui/traces/chain.test.ts +61 -0
- package/src/console/ui/traces/chain.ts +144 -0
- package/src/console/ui/traces/critical-path.test.ts +24 -0
- package/src/console/ui/traces/critical-path.ts +59 -0
- package/src/console/ui/traces/filter.test.ts +78 -0
- package/src/console/ui/traces/filter.ts +112 -0
- package/src/console/ui/traces/fixture.ts +126 -0
- package/src/console/ui/traces/fold.test.ts +67 -0
- package/src/console/ui/traces/fold.ts +170 -0
- package/src/console/ui/traces/index.ts +64 -0
- package/src/console/ui/traces/mini.ts +65 -0
- package/src/console/ui/traces/replay.test.ts +24 -0
- package/src/console/ui/traces/replay.ts +35 -0
- package/src/console/ui/traces/sampling.test.ts +26 -0
- package/src/console/ui/traces/sampling.ts +66 -0
- package/src/console/ui/traces/search.ts +148 -0
- package/src/console/ui/traces/tier.ts +72 -0
- package/src/console/ui/traces/types.ts +125 -0
- package/src/console/ui/tsconfig.json +20 -0
- package/src/console/ui/vault/VaultA11yView.tsx +177 -0
- package/src/console/ui/vault/a11y.test.tsx +97 -0
- package/src/console/ui/vault/blast-radius.test.ts +35 -0
- package/src/console/ui/vault/blast-radius.ts +55 -0
- package/src/console/ui/vault/confirmation.test.ts +41 -0
- package/src/console/ui/vault/confirmation.ts +39 -0
- package/src/console/ui/vault/dormant.test.ts +37 -0
- package/src/console/ui/vault/dormant.ts +28 -0
- package/src/console/ui/vault/export-safe.test.ts +30 -0
- package/src/console/ui/vault/export-safe.ts +65 -0
- package/src/console/ui/vault/fixture.ts +75 -0
- package/src/console/ui/vault/group.test.ts +25 -0
- package/src/console/ui/vault/group.ts +50 -0
- package/src/console/ui/vault/index.ts +45 -0
- package/src/console/ui/vault/search.ts +62 -0
- package/src/console/ui/vault/types.ts +57 -0
- package/src/console/ui/vite.config.ts +84 -0
- package/src/console/xss.gate.test.ts +118 -0
- package/src/docker/compose.ts +226 -0
- package/src/docker/credentials.ts +25 -0
- package/src/docker/derive.ts +83 -0
- package/src/docker/docker.test.ts +185 -0
- package/src/docker/dockerfile.integration.test.ts +170 -0
- package/src/docker/dockerfile.ts +39 -0
- package/src/docker/helpers.ts +103 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/pin.ts +90 -0
- package/src/docker/recipes/index.ts +33 -0
- package/src/docker/recipes/postgres.ts +18 -0
- package/src/docker/recipes/redis.ts +18 -0
- package/src/docker/stack.integration.test.ts +140 -0
- package/src/docker/stack.ts +62 -0
- package/src/docker/types.ts +134 -0
- package/src/drivers/ai-anthropic.ts +128 -0
- package/src/drivers/ai-mock.ts +82 -0
- package/src/drivers/ai-openai-compatible.ts +139 -0
- package/src/drivers/ai-providers.test.ts +163 -0
- package/src/drivers/ai-types.ts +83 -0
- package/src/drivers/bun-native-completeness.test.ts +155 -0
- package/src/drivers/channel-console.ts +118 -0
- package/src/drivers/channel-fcm.ts +96 -0
- package/src/drivers/channel-resend.ts +27 -0
- package/src/drivers/channel-smtp.ts +33 -0
- package/src/drivers/channel-types.ts +160 -0
- package/src/drivers/channel-unifonic.ts +79 -0
- package/src/drivers/channel-wa-cloud.ts +84 -0
- package/src/drivers/channel-webpush.ts +317 -0
- package/src/drivers/conformance.test.ts +89 -0
- package/src/drivers/conformance.ts +162 -0
- package/src/drivers/fs.ts +73 -0
- package/src/drivers/index.ts +194 -0
- package/src/drivers/kv-lua.ts +222 -0
- package/src/drivers/memory.ts +472 -0
- package/src/drivers/pgvector.ts +130 -0
- package/src/drivers/postgres.ts +221 -0
- package/src/drivers/redis.ts +254 -0
- package/src/drivers/s3.ts +129 -0
- package/src/drivers/signal-engine.ts +690 -0
- package/src/drivers/signal-memory.ts +27 -0
- package/src/drivers/signal-nats.ts +131 -0
- package/src/drivers/signal-postgres.ts +1089 -0
- package/src/drivers/signal-redis.ts +275 -0
- package/src/drivers/signal-types.ts +328 -0
- package/src/drivers/sqlite.ts +53 -0
- package/src/drivers/types.ts +334 -0
- package/src/drivers/vault-dotenv-parse.ts +56 -0
- package/src/drivers/vault-env.ts +101 -0
- package/src/drivers/vault-infisical.ts +61 -0
- package/src/drivers/vault-managed.ts +42 -0
- package/src/drivers/vault-memory.ts +38 -0
- package/src/drivers/vault-openbao.ts +80 -0
- package/src/drivers/vault-sops.ts +252 -0
- package/src/drivers/vault-types.ts +84 -0
- package/src/elements/ai/declare.ts +206 -0
- package/src/elements/ai/eval.ts +113 -0
- package/src/elements/ai/pii.ts +108 -0
- package/src/elements/ai/runtime.ts +540 -0
- package/src/elements/ai/schema.ts +194 -0
- package/src/elements/ai.test.ts +393 -0
- package/src/elements/ai.ts +56 -0
- package/src/elements/channel/consent.ts +81 -0
- package/src/elements/channel/costs.test.ts +62 -0
- package/src/elements/channel/costs.ts +130 -0
- package/src/elements/channel/declare.ts +141 -0
- package/src/elements/channel/email-auth.test.ts +47 -0
- package/src/elements/channel/email-auth.ts +109 -0
- package/src/elements/channel/locale.ts +97 -0
- package/src/elements/channel/mask.test.ts +19 -0
- package/src/elements/channel/mask.ts +60 -0
- package/src/elements/channel/mime.ts +23 -0
- package/src/elements/channel/outcomes.test.ts +40 -0
- package/src/elements/channel/outcomes.ts +126 -0
- package/src/elements/channel/receipts.ts +121 -0
- package/src/elements/channel/runtime.ts +500 -0
- package/src/elements/channel/suppression.ts +136 -0
- package/src/elements/channel.test.ts +232 -0
- package/src/elements/channel.ts +109 -0
- package/src/elements/clock/actions.ts +170 -0
- package/src/elements/clock/declare.ts +58 -0
- package/src/elements/clock/dst.ts +197 -0
- package/src/elements/clock/durable.ts +140 -0
- package/src/elements/clock/duration.ts +29 -0
- package/src/elements/clock/health.test.ts +103 -0
- package/src/elements/clock/health.ts +112 -0
- package/src/elements/clock/leader.ts +127 -0
- package/src/elements/clock/reconcile.ts +241 -0
- package/src/elements/clock/runtime.ts +243 -0
- package/src/elements/clock/schedule.ts +262 -0
- package/src/elements/clock/time-travel.ts +53 -0
- package/src/elements/clock.test.ts +365 -0
- package/src/elements/clock.ts +80 -0
- package/src/elements/gate/declare.ts +134 -0
- package/src/elements/gate/permissions.ts +104 -0
- package/src/elements/gate/runtime.ts +177 -0
- package/src/elements/gate/strategies.ts +388 -0
- package/src/elements/gate.test.ts +145 -0
- package/src/elements/gate.ts +41 -0
- package/src/elements/index.ts +169 -0
- package/src/elements/signal/chaos-child.ts +47 -0
- package/src/elements/signal/declare.ts +77 -0
- package/src/elements/signal/dry-run-replay.test.ts +95 -0
- package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
- package/src/elements/signal/reconcile.test.ts +23 -0
- package/src/elements/signal/reconcile.ts +122 -0
- package/src/elements/signal/runtime.ts +94 -0
- package/src/elements/signal.test.ts +457 -0
- package/src/elements/signal.ts +26 -0
- package/src/elements/store/cache.ts +197 -0
- package/src/elements/store/classify.ts +125 -0
- package/src/elements/store/declare.ts +200 -0
- package/src/elements/store/files-policy.test.ts +31 -0
- package/src/elements/store/files-policy.ts +70 -0
- package/src/elements/store/replica.ts +68 -0
- package/src/elements/store/runtime.ts +393 -0
- package/src/elements/store/sql-condition.ts +205 -0
- package/src/elements/store/sql-session.ts +579 -0
- package/src/elements/store/table.ts +282 -0
- package/src/elements/store.test.ts +370 -0
- package/src/elements/store.ts +99 -0
- package/src/elements/vault/declare.ts +143 -0
- package/src/elements/vault/fingerprint.ts +30 -0
- package/src/elements/vault/redact.ts +52 -0
- package/src/elements/vault/runtime.ts +461 -0
- package/src/elements/vault.test.ts +296 -0
- package/src/elements/vault.ts +44 -0
- package/src/index.ts +183 -0
- package/src/kernel/adopt-routes.ts +194 -0
- package/src/kernel/app.ts +1068 -0
- package/src/kernel/auth-resolve.ts +93 -0
- package/src/kernel/boot.test.ts +173 -0
- package/src/kernel/boot.ts +439 -0
- package/src/kernel/budget-entry.ts +55 -0
- package/src/kernel/budget.test.ts +19 -0
- package/src/kernel/call.test.ts +83 -0
- package/src/kernel/capability.ts +113 -0
- package/src/kernel/dry-run.test.ts +64 -0
- package/src/kernel/dry-run.ts +171 -0
- package/src/kernel/effects.test.ts +89 -0
- package/src/kernel/effects.ts +140 -0
- package/src/kernel/errors.registry.test.ts +39 -0
- package/src/kernel/errors.ts +225 -0
- package/src/kernel/flow.test.ts +154 -0
- package/src/kernel/flow.ts +290 -0
- package/src/kernel/fx.test.ts +245 -0
- package/src/kernel/fx.ts +996 -0
- package/src/kernel/hook-timing.test.ts +72 -0
- package/src/kernel/hook-timing.ts +190 -0
- package/src/kernel/hooks.test.ts +181 -0
- package/src/kernel/hooks.ts +275 -0
- package/src/kernel/index.ts +278 -0
- package/src/kernel/journal.ts +405 -0
- package/src/kernel/journey.ts +75 -0
- package/src/kernel/on.ts +74 -0
- package/src/kernel/pipeline.test.ts +349 -0
- package/src/kernel/pipeline.ts +245 -0
- package/src/kernel/plug.ts +82 -0
- package/src/kernel/plugin/capabilities.test.ts +84 -0
- package/src/kernel/plugin/conflicts.test.ts +106 -0
- package/src/kernel/plugin/decorate.test.ts +111 -0
- package/src/kernel/plugin/scoping.test.ts +138 -0
- package/src/kernel/plugin.ts +485 -0
- package/src/kernel/rate-limit.ts +25 -0
- package/src/kernel/registry.ts +398 -0
- package/src/kernel/router.test.ts +114 -0
- package/src/kernel/router.ts +556 -0
- package/src/kernel/routing-budget.test.ts +19 -0
- package/src/kernel/run-telemetry.ts +70 -0
- package/src/kernel/triggers.ts +324 -0
- package/src/kernel/unit.ts +88 -0
- package/src/manifest/diff.test.ts +866 -0
- package/src/manifest/diff.ts +1670 -0
- package/src/manifest/fixtures/base.manifest.json +112 -0
- package/src/manifest/fixtures/skyport.excerpt.json +51 -0
- package/src/manifest/fixtures/skyport.manifest.json +153 -0
- package/src/manifest/index.ts +27 -0
- package/src/manifest/types.ts +358 -0
- package/src/manifest/undeclared.test.ts +82 -0
- package/src/manifest/undeclared.ts +65 -0
- package/src/manifest/validate.test.ts +105 -0
- package/src/manifest/validate.ts +174 -0
- package/src/mcp/authorization.ts +340 -0
- package/src/mcp/confirmation.ts +174 -0
- package/src/mcp/data.ts +90 -0
- package/src/mcp/index.ts +80 -0
- package/src/mcp/injection.gate.test.ts +176 -0
- package/src/mcp/mcp.test.ts +348 -0
- package/src/mcp/protocol.ts +172 -0
- package/src/mcp/server.ts +283 -0
- package/src/mcp/session.ts +139 -0
- package/src/mcp/tools.ts +391 -0
- package/src/plugins/catalogue.test.ts +48 -0
- package/src/plugins/catalogue.ts +113 -0
- package/src/plugins/node-import-scan.test.ts +28 -0
- package/src/plugins/node-import-scan.ts +98 -0
- package/src/plugins/supply-chain.test.ts +48 -0
- package/src/plugins/supply-chain.ts +460 -0
- package/src/release/index.ts +30 -0
- package/src/release/limits.ts +20 -0
- package/src/release/measure.ts +443 -0
- package/src/release/publish.ts +56 -0
- package/src/runs/bench.test.ts +93 -0
- package/src/runs/collect.ts +144 -0
- package/src/runs/drivers/clickhouse.ts +108 -0
- package/src/runs/drivers/files.ts +201 -0
- package/src/runs/drivers/memory.ts +94 -0
- package/src/runs/drivers/postgres.ts +110 -0
- package/src/runs/duckdb.ts +99 -0
- package/src/runs/index.ts +82 -0
- package/src/runs/outlier.ts +180 -0
- package/src/runs/parquet.ts +210 -0
- package/src/runs/privacy.ts +49 -0
- package/src/runs/runs.test.ts +324 -0
- package/src/runs/runtime.ts +229 -0
- package/src/runs/shred.ts +243 -0
- package/src/runs/telemetry.ts +10 -0
- package/src/runs/types.ts +179 -0
- package/src/runtime/bun.ts +140 -0
- package/src/runtime/cold-start.bench.ts +20 -0
- package/src/runtime/index.ts +46 -0
- package/src/runtime/primitives.ts +242 -0
- package/src/runtime/security.test.ts +170 -0
- package/src/runtime/security.ts +168 -0
- package/src/runtime/serve.test.ts +223 -0
- package/src/runtime/types.ts +217 -0
- package/src/runtime/web-standard.ts +77 -0
- package/src/test/create-test-app.test.ts +161 -0
- package/src/test/create-test-app.ts +533 -0
- package/src/test/index.ts +21 -0
- package/src/test/provisions.integration.test.ts +174 -0
- package/src/upgrade/codemods.test.ts +58 -0
- package/src/upgrade/codemods.ts +83 -0
- package/src/validation/index.ts +23 -0
- package/src/validation/standard-schema.test.ts +96 -0
- package/src/validation/standard-schema.ts +316 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth: built-in flagship (hybrid JWT + revocable refresh, ABAC, MFA)
|
|
3
|
+
* plus a provider seam. Subpath: `okengine/auth`.
|
|
4
|
+
*
|
|
5
|
+
* Two planes — `fx.operator` vs `fx.auth` — permanently separated.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { auth, type AuthPluginOptions } from "./plugin.ts";
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
assertPlaneAccess,
|
|
12
|
+
operatorPrincipal,
|
|
13
|
+
userPrincipal,
|
|
14
|
+
CrossPlaneError,
|
|
15
|
+
type AuthPlane,
|
|
16
|
+
type OperatorPrincipal,
|
|
17
|
+
type Principal,
|
|
18
|
+
type UserPrincipal,
|
|
19
|
+
} from "./planes.ts";
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
assertCrossPlane,
|
|
23
|
+
checkCrossPlane,
|
|
24
|
+
type CrossPlaneDiagnostic,
|
|
25
|
+
type PlaneSourceFile,
|
|
26
|
+
} from "./cross-plane.ts";
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
attenuateScopes,
|
|
30
|
+
assertAttenuated,
|
|
31
|
+
expandHeldScopes,
|
|
32
|
+
grantableScopes,
|
|
33
|
+
AttenuationError,
|
|
34
|
+
type AttenuationResult,
|
|
35
|
+
} from "./attenuation.ts";
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
createApiKey,
|
|
39
|
+
createApiKeyStore,
|
|
40
|
+
authenticateApiKey,
|
|
41
|
+
hashApiKeySecret,
|
|
42
|
+
revokeApiKey,
|
|
43
|
+
rotateApiKey,
|
|
44
|
+
type ApiKeyStore,
|
|
45
|
+
type CreateApiKeyOptions,
|
|
46
|
+
type CreatedApiKey,
|
|
47
|
+
} from "./api-keys.ts";
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
createOperatorInviteStore,
|
|
51
|
+
createOperatorInvite,
|
|
52
|
+
isInviteExpired,
|
|
53
|
+
INVITE_TTL_MS,
|
|
54
|
+
type CreateInviteOptions,
|
|
55
|
+
type OperatorInviteStore,
|
|
56
|
+
} from "./invites.ts";
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
createSessionStore,
|
|
60
|
+
issueSession,
|
|
61
|
+
issueSessionWithScopes,
|
|
62
|
+
rotateRefresh,
|
|
63
|
+
verifyAccess,
|
|
64
|
+
revokeFamily,
|
|
65
|
+
bindSessionScopes,
|
|
66
|
+
bindSessionAudience,
|
|
67
|
+
ACCESS_TTL_MS,
|
|
68
|
+
REFRESH_TTL_MS,
|
|
69
|
+
SessionError,
|
|
70
|
+
type AccessClaims,
|
|
71
|
+
type IssuedSession,
|
|
72
|
+
type SessionCrypto,
|
|
73
|
+
type SessionStore,
|
|
74
|
+
type VerifyAccessOptions,
|
|
75
|
+
} from "./sessions.ts";
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
createOperatorStore,
|
|
79
|
+
createOperator,
|
|
80
|
+
removeOperatorCredential,
|
|
81
|
+
linkOperatorSso,
|
|
82
|
+
authenticateOperator,
|
|
83
|
+
OperatorError,
|
|
84
|
+
type CreateOperatorOptions,
|
|
85
|
+
type OperatorStore,
|
|
86
|
+
} from "./operator.ts";
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
createRoleStore,
|
|
90
|
+
upsertRole,
|
|
91
|
+
setRoleGrants,
|
|
92
|
+
scopesForRoles,
|
|
93
|
+
listRoleGrants,
|
|
94
|
+
type RoleStore,
|
|
95
|
+
} from "./roles.ts";
|
|
96
|
+
|
|
97
|
+
export { invokeAs, type InvokeAsOptions } from "./invoke-as.ts";
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
AUTH_TABLES,
|
|
101
|
+
type ApiKeyRow,
|
|
102
|
+
type IdentityRow,
|
|
103
|
+
type OperatorCredentialRow,
|
|
104
|
+
type OperatorInviteRow,
|
|
105
|
+
type OperatorRow,
|
|
106
|
+
type OperatorSsoLinkRow,
|
|
107
|
+
type RefreshTokenRow,
|
|
108
|
+
type RoleGrantRow,
|
|
109
|
+
type RoleRow,
|
|
110
|
+
type SessionRow,
|
|
111
|
+
type TablePlane,
|
|
112
|
+
} from "./tables.ts";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator invitations — invite-only plane (console §2.2 · §9.14).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { OperatorInviteRow } from "./tables.ts";
|
|
6
|
+
|
|
7
|
+
/** Default invitation TTL (7 days). */
|
|
8
|
+
export const INVITE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
9
|
+
|
|
10
|
+
/** In-memory operator invite store. */
|
|
11
|
+
export interface OperatorInviteStore {
|
|
12
|
+
invites: Map<string, OperatorInviteRow>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create an empty invite store.
|
|
17
|
+
*/
|
|
18
|
+
export function createOperatorInviteStore(): OperatorInviteStore {
|
|
19
|
+
return { invites: new Map() };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Options when creating an invitation. */
|
|
23
|
+
export interface CreateInviteOptions {
|
|
24
|
+
readonly email: string;
|
|
25
|
+
readonly invitedBy: string;
|
|
26
|
+
readonly id?: string;
|
|
27
|
+
readonly ttlMs?: number;
|
|
28
|
+
readonly now?: () => number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a pending operator invitation.
|
|
33
|
+
*
|
|
34
|
+
* @param store - Invite store
|
|
35
|
+
* @param options - Invite fields
|
|
36
|
+
*/
|
|
37
|
+
export function createOperatorInvite(
|
|
38
|
+
store: OperatorInviteStore,
|
|
39
|
+
options: CreateInviteOptions,
|
|
40
|
+
): OperatorInviteRow {
|
|
41
|
+
const now = options.now ?? (() => Date.now());
|
|
42
|
+
const t = now();
|
|
43
|
+
const row: OperatorInviteRow = {
|
|
44
|
+
id: options.id ?? crypto.randomUUID(),
|
|
45
|
+
email: options.email,
|
|
46
|
+
invitedBy: options.invitedBy,
|
|
47
|
+
createdAt: t,
|
|
48
|
+
expiresAt: t + (options.ttlMs ?? INVITE_TTL_MS),
|
|
49
|
+
acceptedAt: null,
|
|
50
|
+
};
|
|
51
|
+
store.invites.set(row.id, row);
|
|
52
|
+
return row;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Whether an invite is expired and still unaccepted.
|
|
57
|
+
*
|
|
58
|
+
* @param row - Invite row
|
|
59
|
+
* @param now - Clock
|
|
60
|
+
*/
|
|
61
|
+
export function isInviteExpired(
|
|
62
|
+
row: OperatorInviteRow,
|
|
63
|
+
now: () => number = () => Date.now(),
|
|
64
|
+
): boolean {
|
|
65
|
+
return row.acceptedAt === null && row.expiresAt <= now();
|
|
66
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `console:flows:invoke-as` — attenuated exactly like an API key.
|
|
3
|
+
*
|
|
4
|
+
* An operator cannot assume a scope set they could not grant.
|
|
5
|
+
* Impersonating a real user is development-only.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/spec/console.md §10.4
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { assertAttenuated } from "./attenuation.ts";
|
|
11
|
+
import { userPrincipal, type UserPrincipal } from "./planes.ts";
|
|
12
|
+
|
|
13
|
+
/** Options for invoke-as. */
|
|
14
|
+
export interface InvokeAsOptions {
|
|
15
|
+
/** Operator's own scopes (attenuation ceiling). */
|
|
16
|
+
readonly operatorScopes: ReadonlySet<string> | Iterable<string>;
|
|
17
|
+
/** Requested application scopes for the assumed principal. */
|
|
18
|
+
readonly scopes: readonly string[];
|
|
19
|
+
/** Synthetic user id (required). */
|
|
20
|
+
readonly userId: string;
|
|
21
|
+
/**
|
|
22
|
+
* When true, allows binding to a real identity id.
|
|
23
|
+
* Impersonating a real user is development-only.
|
|
24
|
+
*/
|
|
25
|
+
readonly impersonateRealUser?: boolean;
|
|
26
|
+
/** Production / development flag. */
|
|
27
|
+
readonly development?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build an attenuated user principal for console invoke-as.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Operator ceiling + requested scopes
|
|
34
|
+
*/
|
|
35
|
+
export function invokeAs(options: InvokeAsOptions): UserPrincipal {
|
|
36
|
+
assertAttenuated(options.operatorScopes, options.scopes, "invoke-as");
|
|
37
|
+
|
|
38
|
+
if (options.impersonateRealUser && !options.development) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"invoke-as: impersonating a real user is development-only",
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return userPrincipal({
|
|
45
|
+
userId: options.userId,
|
|
46
|
+
scopes: options.scopes,
|
|
47
|
+
verified: true,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator plane — local credential always present; SSO is additive.
|
|
3
|
+
*
|
|
4
|
+
* The local password hash can never be removed. Enterprise SSO links a
|
|
5
|
+
* provider as an *additional* authentication method.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/spec/console.md §2.2–2.3
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createBunCrypto } from "../runtime/primitives.ts";
|
|
11
|
+
import type {
|
|
12
|
+
OperatorCredentialRow,
|
|
13
|
+
OperatorRow,
|
|
14
|
+
OperatorSsoLinkRow,
|
|
15
|
+
} from "./tables.ts";
|
|
16
|
+
|
|
17
|
+
/** Operator-plane store. */
|
|
18
|
+
export interface OperatorStore {
|
|
19
|
+
operators: Map<string, OperatorRow>;
|
|
20
|
+
credentials: Map<string, OperatorCredentialRow>;
|
|
21
|
+
ssoLinks: Map<string, OperatorSsoLinkRow[]>;
|
|
22
|
+
roles: Map<string, string[]>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create an empty operator store.
|
|
27
|
+
*/
|
|
28
|
+
export function createOperatorStore(): OperatorStore {
|
|
29
|
+
return {
|
|
30
|
+
operators: new Map(),
|
|
31
|
+
credentials: new Map(),
|
|
32
|
+
ssoLinks: new Map(),
|
|
33
|
+
roles: new Map(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Options for creating an operator. */
|
|
38
|
+
export interface CreateOperatorOptions {
|
|
39
|
+
readonly email: string;
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly password: string;
|
|
42
|
+
readonly invitedBy?: string | null;
|
|
43
|
+
readonly id?: string;
|
|
44
|
+
readonly roles?: readonly string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create an operator with a mandatory local credential.
|
|
49
|
+
*
|
|
50
|
+
* @param store - Operator store
|
|
51
|
+
* @param options - Identity + password
|
|
52
|
+
*/
|
|
53
|
+
export async function createOperator(
|
|
54
|
+
store: OperatorStore,
|
|
55
|
+
options: CreateOperatorOptions,
|
|
56
|
+
): Promise<OperatorRow> {
|
|
57
|
+
const crypto = createBunCrypto();
|
|
58
|
+
const id = options.id ?? crypto.randomUUID();
|
|
59
|
+
const row: OperatorRow = {
|
|
60
|
+
id,
|
|
61
|
+
email: options.email,
|
|
62
|
+
name: options.name,
|
|
63
|
+
status: "active",
|
|
64
|
+
mfaEnabled: false,
|
|
65
|
+
invitedBy: options.invitedBy ?? null,
|
|
66
|
+
lastSeenAt: null,
|
|
67
|
+
};
|
|
68
|
+
store.operators.set(id, row);
|
|
69
|
+
store.credentials.set(id, {
|
|
70
|
+
operatorId: id,
|
|
71
|
+
passwordHash: await crypto.hashPassword(options.password, "argon2id"),
|
|
72
|
+
loginEnabled: true,
|
|
73
|
+
});
|
|
74
|
+
store.ssoLinks.set(id, []);
|
|
75
|
+
store.roles.set(id, [...(options.roles ?? [])]);
|
|
76
|
+
return row;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Refuse removal of the local credential — SSO never becomes the sole path.
|
|
81
|
+
*
|
|
82
|
+
* @param store - Operator store
|
|
83
|
+
* @param operatorId - Operator id
|
|
84
|
+
*/
|
|
85
|
+
export function removeOperatorCredential(
|
|
86
|
+
store: OperatorStore,
|
|
87
|
+
operatorId: string,
|
|
88
|
+
): never {
|
|
89
|
+
void store;
|
|
90
|
+
void operatorId;
|
|
91
|
+
throw new OperatorError(
|
|
92
|
+
"operator local credential cannot be removed; SSO is additive only",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Link an SSO identity as an additional method (local credential remains).
|
|
98
|
+
*
|
|
99
|
+
* @param store - Operator store
|
|
100
|
+
* @param operatorId - Operator id
|
|
101
|
+
* @param provider - Provider id
|
|
102
|
+
* @param subject - Provider subject
|
|
103
|
+
*/
|
|
104
|
+
export function linkOperatorSso(
|
|
105
|
+
store: OperatorStore,
|
|
106
|
+
operatorId: string,
|
|
107
|
+
provider: string,
|
|
108
|
+
subject: string,
|
|
109
|
+
): OperatorSsoLinkRow {
|
|
110
|
+
if (!store.operators.has(operatorId)) {
|
|
111
|
+
throw new OperatorError(`unknown operator: ${operatorId}`);
|
|
112
|
+
}
|
|
113
|
+
if (!store.credentials.has(operatorId)) {
|
|
114
|
+
throw new OperatorError(
|
|
115
|
+
"operator is missing local credential — invariant violated",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const link: OperatorSsoLinkRow = { operatorId, provider, subject };
|
|
119
|
+
const list = store.ssoLinks.get(operatorId) ?? [];
|
|
120
|
+
list.push(link);
|
|
121
|
+
store.ssoLinks.set(operatorId, list);
|
|
122
|
+
return link;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Dummy argon2id hash used when no credential exists so missing-user and
|
|
127
|
+
* bad-password paths both pay a verify round-trip (timing oracle defence).
|
|
128
|
+
*/
|
|
129
|
+
let dummyPasswordHash: string | null = null;
|
|
130
|
+
|
|
131
|
+
async function dummyHash(
|
|
132
|
+
crypto: ReturnType<typeof createBunCrypto>,
|
|
133
|
+
): Promise<string> {
|
|
134
|
+
if (dummyPasswordHash === null) {
|
|
135
|
+
dummyPasswordHash = await crypto.hashPassword(
|
|
136
|
+
"oke-operator-timing-dummy",
|
|
137
|
+
"argon2id",
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return dummyPasswordHash;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Verify local password login.
|
|
145
|
+
*
|
|
146
|
+
* Always runs a password verify (against a dummy hash when the account is
|
|
147
|
+
* missing / disabled) so response time does not reveal account existence.
|
|
148
|
+
*
|
|
149
|
+
* @param store - Operator store
|
|
150
|
+
* @param email - Email
|
|
151
|
+
* @param password - Password
|
|
152
|
+
*/
|
|
153
|
+
export async function authenticateOperator(
|
|
154
|
+
store: OperatorStore,
|
|
155
|
+
email: string,
|
|
156
|
+
password: string,
|
|
157
|
+
): Promise<OperatorRow | null> {
|
|
158
|
+
const crypto = createBunCrypto();
|
|
159
|
+
const op = [...store.operators.values()].find((o) => o.email === email);
|
|
160
|
+
const cred =
|
|
161
|
+
op && op.status === "active" ? store.credentials.get(op.id) : undefined;
|
|
162
|
+
const hash =
|
|
163
|
+
cred && cred.loginEnabled ? cred.passwordHash : await dummyHash(crypto);
|
|
164
|
+
const ok = await crypto.verifyPassword(password, hash);
|
|
165
|
+
if (!ok || !op || !cred || !cred.loginEnabled || op.status !== "active") {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
return op;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Operator-plane error. */
|
|
172
|
+
export class OperatorError extends Error {
|
|
173
|
+
/** @param message - Diagnostic */
|
|
174
|
+
constructor(message: string) {
|
|
175
|
+
super(message);
|
|
176
|
+
this.name = "OperatorError";
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two planes, permanently separated — operator vs user.
|
|
3
|
+
*
|
|
4
|
+
* Cross-plane invocation is a compile error. Principals never mix:
|
|
5
|
+
* `fx.operator` on the Console plane, `fx.auth` on the application plane.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/spec/console.md §2.2
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Auth plane identifiers. */
|
|
11
|
+
export type AuthPlane = "user" | "operator";
|
|
12
|
+
|
|
13
|
+
/** Brand so user and operator principals are not assignable. */
|
|
14
|
+
const planeBrand: unique symbol = Symbol("oke.plane");
|
|
15
|
+
|
|
16
|
+
/** User-plane principal (`fx.auth`). */
|
|
17
|
+
export interface UserPrincipal {
|
|
18
|
+
readonly [planeBrand]: "user";
|
|
19
|
+
readonly plane: "user";
|
|
20
|
+
readonly userId: string;
|
|
21
|
+
readonly scopes: ReadonlySet<string>;
|
|
22
|
+
readonly verified: boolean;
|
|
23
|
+
readonly roles: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Operator-plane principal (`fx.operator`). */
|
|
27
|
+
export interface OperatorPrincipal {
|
|
28
|
+
readonly [planeBrand]: "operator";
|
|
29
|
+
readonly plane: "operator";
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly scopes: ReadonlySet<string>;
|
|
32
|
+
readonly roles: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Any principal — discriminated by `plane`. */
|
|
36
|
+
export type Principal = UserPrincipal | OperatorPrincipal;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create a user-plane principal.
|
|
40
|
+
*
|
|
41
|
+
* @param fields - Identity fields
|
|
42
|
+
*/
|
|
43
|
+
export function userPrincipal(fields: {
|
|
44
|
+
readonly userId: string;
|
|
45
|
+
readonly scopes?: Iterable<string>;
|
|
46
|
+
readonly verified?: boolean;
|
|
47
|
+
readonly roles?: readonly string[];
|
|
48
|
+
}): UserPrincipal {
|
|
49
|
+
return {
|
|
50
|
+
[planeBrand]: "user",
|
|
51
|
+
plane: "user",
|
|
52
|
+
userId: fields.userId,
|
|
53
|
+
scopes: new Set(fields.scopes ?? []),
|
|
54
|
+
verified: fields.verified ?? false,
|
|
55
|
+
roles: fields.roles ?? [],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create an operator-plane principal.
|
|
61
|
+
*
|
|
62
|
+
* @param fields - Identity fields
|
|
63
|
+
*/
|
|
64
|
+
export function operatorPrincipal(fields: {
|
|
65
|
+
readonly id: string;
|
|
66
|
+
readonly scopes?: Iterable<string>;
|
|
67
|
+
readonly roles?: readonly string[];
|
|
68
|
+
}): OperatorPrincipal {
|
|
69
|
+
return {
|
|
70
|
+
[planeBrand]: "operator",
|
|
71
|
+
plane: "operator",
|
|
72
|
+
id: fields.id,
|
|
73
|
+
scopes: new Set(fields.scopes ?? []),
|
|
74
|
+
roles: fields.roles ?? [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Type-level / runtime guard: application principals cannot reach console flows.
|
|
80
|
+
*
|
|
81
|
+
* @param principal - Acting principal
|
|
82
|
+
* @param flowPlane - Target flow plane
|
|
83
|
+
*/
|
|
84
|
+
export function assertPlaneAccess(
|
|
85
|
+
principal: Principal,
|
|
86
|
+
flowPlane: AuthPlane,
|
|
87
|
+
): void {
|
|
88
|
+
if (principal.plane === "user" && flowPlane === "operator") {
|
|
89
|
+
throw new CrossPlaneError(
|
|
90
|
+
"application principal cannot reach a console (operator) flow",
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Cross-plane invocation error (also raised at compile time). */
|
|
96
|
+
export class CrossPlaneError extends Error {
|
|
97
|
+
/** @param message - Diagnostic */
|
|
98
|
+
constructor(message: string) {
|
|
99
|
+
super(message);
|
|
100
|
+
this.name = "CrossPlaneError";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builtin auth plugin — hybrid session, two planes, roles as data.
|
|
3
|
+
*
|
|
4
|
+
* Uses only the public plugin API (unified-theory §14).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { plugin, type PluginDef } from "../kernel/plugin.ts";
|
|
8
|
+
import { AUTH_TABLES } from "./tables.ts";
|
|
9
|
+
|
|
10
|
+
/** Options for {@link auth}. */
|
|
11
|
+
export interface AuthPluginOptions {
|
|
12
|
+
/** HMAC secret for access tokens (required in production). */
|
|
13
|
+
readonly secret?: string;
|
|
14
|
+
/** Access-token TTL override (ms). */
|
|
15
|
+
readonly accessTtlMs?: number;
|
|
16
|
+
/** Refresh-token TTL override (ms). */
|
|
17
|
+
readonly refreshTtlMs?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Builtin auth plugin.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Session crypto options
|
|
24
|
+
*/
|
|
25
|
+
export function auth(options: AuthPluginOptions = {}): PluginDef {
|
|
26
|
+
let builder = plugin("auth", { version: "0.0.1", config: options }).hook(
|
|
27
|
+
"onAuth",
|
|
28
|
+
(_ctx) => {
|
|
29
|
+
/* principals resolved by session / API key middleware at runtime */
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
for (const name of Object.values(AUTH_TABLES)) {
|
|
34
|
+
builder = builder.table(name, {
|
|
35
|
+
plane: name.includes("operator")
|
|
36
|
+
? "operator"
|
|
37
|
+
: name.includes("identit") || name === AUTH_TABLES.credentials
|
|
38
|
+
? "user"
|
|
39
|
+
: "shared",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return builder.needs("store.sql");
|
|
44
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roles are data — any Module:Action set can be assigned without redeploy.
|
|
3
|
+
*
|
|
4
|
+
* @see docs/spec/console.md §3.2
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AuthPlane } from "./planes.ts";
|
|
8
|
+
import type { RoleGrantRow, RoleRow } from "./tables.ts";
|
|
9
|
+
|
|
10
|
+
/** In-memory role store for tests / builtin auth. */
|
|
11
|
+
export interface RoleStore {
|
|
12
|
+
roles: Map<string, RoleRow>;
|
|
13
|
+
grants: Map<string, Set<string>>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create an empty role store.
|
|
18
|
+
*/
|
|
19
|
+
export function createRoleStore(): RoleStore {
|
|
20
|
+
return { roles: new Map(), grants: new Map() };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Upsert a role (data, not code).
|
|
25
|
+
*
|
|
26
|
+
* @param store - Role store
|
|
27
|
+
* @param role - Role row
|
|
28
|
+
*/
|
|
29
|
+
export function upsertRole(store: RoleStore, role: RoleRow): void {
|
|
30
|
+
store.roles.set(role.id, role);
|
|
31
|
+
if (!store.grants.has(role.id)) store.grants.set(role.id, new Set());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Replace grants for a role with Module:Action pairs.
|
|
36
|
+
*
|
|
37
|
+
* @param store - Role store
|
|
38
|
+
* @param roleId - Role id
|
|
39
|
+
* @param actions - Module:Action pairs
|
|
40
|
+
*/
|
|
41
|
+
export function setRoleGrants(
|
|
42
|
+
store: RoleStore,
|
|
43
|
+
roleId: string,
|
|
44
|
+
actions: readonly string[],
|
|
45
|
+
): void {
|
|
46
|
+
if (!store.roles.has(roleId)) {
|
|
47
|
+
throw new Error(`unknown role: ${roleId}`);
|
|
48
|
+
}
|
|
49
|
+
store.grants.set(roleId, new Set(actions));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the union of Module:Action scopes for role ids on a plane.
|
|
54
|
+
*
|
|
55
|
+
* @param store - Role store
|
|
56
|
+
* @param roleIds - Role ids
|
|
57
|
+
* @param plane - Plane filter (roles from the other plane are ignored)
|
|
58
|
+
*/
|
|
59
|
+
export function scopesForRoles(
|
|
60
|
+
store: RoleStore,
|
|
61
|
+
roleIds: readonly string[],
|
|
62
|
+
plane: AuthPlane,
|
|
63
|
+
): Set<string> {
|
|
64
|
+
const scopes = new Set<string>();
|
|
65
|
+
for (const id of roleIds) {
|
|
66
|
+
const role = store.roles.get(id);
|
|
67
|
+
if (!role || role.plane !== plane) continue;
|
|
68
|
+
for (const a of store.grants.get(id) ?? []) scopes.add(a);
|
|
69
|
+
}
|
|
70
|
+
return scopes;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Snapshot grants as rows.
|
|
75
|
+
*
|
|
76
|
+
* @param store - Role store
|
|
77
|
+
*/
|
|
78
|
+
export function listRoleGrants(store: RoleStore): RoleGrantRow[] {
|
|
79
|
+
const out: RoleGrantRow[] = [];
|
|
80
|
+
for (const [roleId, actions] of store.grants) {
|
|
81
|
+
for (const action of actions) out.push({ roleId, action });
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|