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,430 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console Vault projection — Manifest + VaultRuntime over `fx` (console §9.8).
|
|
3
|
+
*
|
|
4
|
+
* Secrets are write-only: fingerprints only, never cleartext. Config
|
|
5
|
+
* (non-sensitive) may appear in the clear. Resolution chain, readers, and
|
|
6
|
+
* rotation blast radius are derived — never reimplemented in the UI.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import type { ConfigEnv } from "../../config/index.ts";
|
|
11
|
+
import { envVaultDriver, memoryVaultDriver } from "../../drivers/index.ts";
|
|
12
|
+
import {
|
|
13
|
+
createVaultRuntime,
|
|
14
|
+
vault as declareVault,
|
|
15
|
+
type VaultResolutionSource,
|
|
16
|
+
type VaultResolutionStep,
|
|
17
|
+
type VaultRuntime,
|
|
18
|
+
type VaultSecretDecl,
|
|
19
|
+
} from "../../elements/vault.ts";
|
|
20
|
+
import type { JournalRun, JournalStore } from "../../kernel/journal.ts";
|
|
21
|
+
import type { Manifest } from "../../manifest/types.ts";
|
|
22
|
+
|
|
23
|
+
/** Environment label for fingerprint columns. */
|
|
24
|
+
export type VaultEnvLabel = ConfigEnv | "staging" | (string & {});
|
|
25
|
+
|
|
26
|
+
/** Fingerprints keyed by environment — never values. */
|
|
27
|
+
export type VaultFingerprintsByEnv = Readonly<
|
|
28
|
+
Partial<Record<VaultEnvLabel, string>>
|
|
29
|
+
>;
|
|
30
|
+
|
|
31
|
+
/** Rotation blast radius from the durable journal (queried, not estimated). */
|
|
32
|
+
export interface ConsoleVaultBlastRadius {
|
|
33
|
+
/** Count of in-flight sleeping durable runs that declare this secret. */
|
|
34
|
+
readonly count: number;
|
|
35
|
+
/** Absolute epoch-ms of the furthest outstanding wake (`null` when count=0). */
|
|
36
|
+
readonly longestWakeAt: number | null;
|
|
37
|
+
/** Milliseconds until {@link longestWakeAt} from `now` (clamped ≥ 0). */
|
|
38
|
+
readonly longestOutstandingMs: number | null;
|
|
39
|
+
/** Run ids contributing to the blast radius (for Clock deep-links). */
|
|
40
|
+
readonly runIds: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** One row in `console.vault.list`. */
|
|
44
|
+
export interface ConsoleVaultRow {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** `"secret"` is fingerprinted; `"config"` may show cleartext. */
|
|
47
|
+
readonly kind: "secret" | "config";
|
|
48
|
+
readonly sensitive: boolean;
|
|
49
|
+
readonly description?: string;
|
|
50
|
+
readonly rotate?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Per-environment fingerprints. Secrets only — config leaves this empty
|
|
53
|
+
* and uses {@link cleartext} instead.
|
|
54
|
+
*/
|
|
55
|
+
readonly fingerprints: VaultFingerprintsByEnv;
|
|
56
|
+
/** Current environment's fingerprint (convenience). */
|
|
57
|
+
readonly fingerprint: string | null;
|
|
58
|
+
/** Cleartext for non-sensitive config only; always `null` for secrets. */
|
|
59
|
+
readonly cleartext: string | null;
|
|
60
|
+
/** Which layer won in the current environment. */
|
|
61
|
+
readonly winner: VaultResolutionSource | null;
|
|
62
|
+
/** Full resolution chain for the current environment. */
|
|
63
|
+
readonly resolution: readonly VaultResolutionStep[];
|
|
64
|
+
/** Flow ids that declare `fx.vault(name)` in Manifest effects. */
|
|
65
|
+
readonly readers: readonly string[];
|
|
66
|
+
/** In-flight durable runs that will wake holding a new key after rotate. */
|
|
67
|
+
readonly blastRadius: ConsoleVaultBlastRadius;
|
|
68
|
+
/** Epoch-ms of last `fx.vault` / runtime read; `null` if never read. */
|
|
69
|
+
readonly lastReadAt: number | null;
|
|
70
|
+
/**
|
|
71
|
+
* When the current fingerprint equals another environment's — warning,
|
|
72
|
+
* not error (may be deliberate).
|
|
73
|
+
*/
|
|
74
|
+
readonly sharedFingerprintEnvs: readonly VaultEnvLabel[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Options when projecting the vault list. */
|
|
78
|
+
export interface ProjectVaultOptions {
|
|
79
|
+
readonly manifest: Manifest | null;
|
|
80
|
+
readonly runtime: VaultRuntime | null;
|
|
81
|
+
/** Current process environment label. */
|
|
82
|
+
readonly env?: VaultEnvLabel;
|
|
83
|
+
/**
|
|
84
|
+
* Optional peer-environment fingerprints (e.g. staging from a remote
|
|
85
|
+
* probe). Never values — fingerprints only.
|
|
86
|
+
*/
|
|
87
|
+
readonly peerFingerprints?: Readonly<
|
|
88
|
+
Record<string, VaultFingerprintsByEnv>
|
|
89
|
+
>;
|
|
90
|
+
/** Durable journal — blast radius is queried, not estimated. */
|
|
91
|
+
readonly journal?: JournalStore | null;
|
|
92
|
+
readonly now?: () => number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Project Manifest vault contracts into operator rows.
|
|
97
|
+
*
|
|
98
|
+
* @param options - Manifest, runtime, journal
|
|
99
|
+
*/
|
|
100
|
+
export async function projectVaultList(
|
|
101
|
+
options: ProjectVaultOptions,
|
|
102
|
+
): Promise<{
|
|
103
|
+
readonly secrets: readonly ConsoleVaultRow[];
|
|
104
|
+
readonly env: VaultEnvLabel;
|
|
105
|
+
}> {
|
|
106
|
+
const env = options.env ?? "dev";
|
|
107
|
+
const now = options.now ?? (() => Date.now());
|
|
108
|
+
const names = collectNames(options.manifest, options.runtime);
|
|
109
|
+
const journalRuns = options.journal
|
|
110
|
+
? await options.journal.list()
|
|
111
|
+
: ([] as readonly JournalRun[]);
|
|
112
|
+
|
|
113
|
+
const secrets: ConsoleVaultRow[] = [];
|
|
114
|
+
for (const name of names) {
|
|
115
|
+
const contract = contractOf(name, options.manifest, options.runtime);
|
|
116
|
+
const sensitive = contract.sensitive;
|
|
117
|
+
const readers = readersOf(options.manifest, name);
|
|
118
|
+
const blastRadius = blastRadiusOf(
|
|
119
|
+
journalRuns,
|
|
120
|
+
readers,
|
|
121
|
+
now(),
|
|
122
|
+
);
|
|
123
|
+
const winner = options.runtime?.resolution(name) ?? null;
|
|
124
|
+
const resolution = options.runtime?.resolutionChain(name) ?? [];
|
|
125
|
+
const lastReadAt = options.runtime?.lastReadAt(name) ?? null;
|
|
126
|
+
|
|
127
|
+
let fingerprint: string | null = null;
|
|
128
|
+
let cleartext: string | null = null;
|
|
129
|
+
const fingerprints: Record<string, string> = {};
|
|
130
|
+
|
|
131
|
+
if (sensitive) {
|
|
132
|
+
fingerprint = options.runtime?.fingerprint(name) ?? null;
|
|
133
|
+
if (fingerprint) fingerprints[env] = fingerprint;
|
|
134
|
+
const peers = options.peerFingerprints?.[name];
|
|
135
|
+
if (peers) {
|
|
136
|
+
for (const [e, fp] of Object.entries(peers)) {
|
|
137
|
+
if (typeof fp === "string" && fp.length > 0) fingerprints[e] = fp;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
cleartext = options.runtime?.cleartext(name) ?? null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const sharedFingerprintEnvs = sensitive
|
|
145
|
+
? sharedEnvs(fingerprints, env, fingerprint)
|
|
146
|
+
: [];
|
|
147
|
+
|
|
148
|
+
secrets.push({
|
|
149
|
+
name,
|
|
150
|
+
kind: contract.kind,
|
|
151
|
+
sensitive,
|
|
152
|
+
...(contract.description !== undefined
|
|
153
|
+
? { description: contract.description }
|
|
154
|
+
: {}),
|
|
155
|
+
...(contract.rotate !== undefined ? { rotate: contract.rotate } : {}),
|
|
156
|
+
fingerprints,
|
|
157
|
+
fingerprint,
|
|
158
|
+
cleartext,
|
|
159
|
+
winner,
|
|
160
|
+
resolution,
|
|
161
|
+
readers,
|
|
162
|
+
blastRadius,
|
|
163
|
+
lastReadAt,
|
|
164
|
+
sharedFingerprintEnvs,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return { secrets, env };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Input for set / rotate. */
|
|
172
|
+
export interface VaultWriteInput {
|
|
173
|
+
readonly name: string;
|
|
174
|
+
readonly value: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Set a vault value via the runtime (write-only — never returns the value).
|
|
179
|
+
*
|
|
180
|
+
* @param runtime - Vault runtime
|
|
181
|
+
* @param input - Name + new value
|
|
182
|
+
*/
|
|
183
|
+
export function setVaultValue(
|
|
184
|
+
runtime: VaultRuntime,
|
|
185
|
+
input: VaultWriteInput,
|
|
186
|
+
): { readonly name: string; readonly fingerprint: string | null } {
|
|
187
|
+
runtime.put(input.name, input.value);
|
|
188
|
+
return {
|
|
189
|
+
name: input.name,
|
|
190
|
+
fingerprint: runtime.isSensitive(input.name)
|
|
191
|
+
? (runtime.fingerprint(input.name) ?? null)
|
|
192
|
+
: null,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Rotate = set a new value (same write path; distinct Console action + confirm).
|
|
198
|
+
*
|
|
199
|
+
* @param runtime - Vault runtime
|
|
200
|
+
* @param input - Name + new value
|
|
201
|
+
*/
|
|
202
|
+
export function rotateVaultValue(
|
|
203
|
+
runtime: VaultRuntime,
|
|
204
|
+
input: VaultWriteInput,
|
|
205
|
+
): { readonly name: string; readonly fingerprint: string | null } {
|
|
206
|
+
return setVaultValue(runtime, input);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Build a VaultRuntime from Manifest contracts when no host runtime is attached.
|
|
211
|
+
*
|
|
212
|
+
* Uses the standard resolution chain: process.env → .env.local → .env.stack
|
|
213
|
+
* → memory driver → (optional) dev fallback. Does not parse dotenv in the UI.
|
|
214
|
+
*
|
|
215
|
+
* @param manifest - Manifest snapshot
|
|
216
|
+
* @param options - cwd / env / allowDevFallbacks / seed
|
|
217
|
+
*/
|
|
218
|
+
export async function createManifestVaultRuntime(
|
|
219
|
+
manifest: Manifest,
|
|
220
|
+
options: {
|
|
221
|
+
readonly cwd?: string;
|
|
222
|
+
readonly env?: ConfigEnv;
|
|
223
|
+
readonly allowDevFallbacks?: boolean;
|
|
224
|
+
readonly seed?: Readonly<Record<string, string>>;
|
|
225
|
+
readonly now?: () => number;
|
|
226
|
+
} = {},
|
|
227
|
+
): Promise<VaultRuntime | null> {
|
|
228
|
+
const entries = Object.entries(manifest.vault ?? {});
|
|
229
|
+
if (entries.length === 0) return null;
|
|
230
|
+
|
|
231
|
+
const cwd = options.cwd ?? process.cwd();
|
|
232
|
+
const secrets: VaultSecretDecl[] = entries.map(([name, c]) => {
|
|
233
|
+
const sensitive = c.sensitive !== false;
|
|
234
|
+
if (sensitive) {
|
|
235
|
+
return declareVault.secret(name, {
|
|
236
|
+
description: c.description,
|
|
237
|
+
rotate: c.rotate,
|
|
238
|
+
schema: c.schema,
|
|
239
|
+
sensitive: true,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return declareVault.config(name, {
|
|
243
|
+
description: c.description,
|
|
244
|
+
rotate: c.rotate,
|
|
245
|
+
schema: c.schema,
|
|
246
|
+
sensitive: false,
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const seed = options.seed ?? {};
|
|
251
|
+
const runtime = createVaultRuntime({
|
|
252
|
+
secrets,
|
|
253
|
+
allowDevFallbacks:
|
|
254
|
+
options.allowDevFallbacks ?? (options.env ?? "dev") !== "prod",
|
|
255
|
+
now: options.now,
|
|
256
|
+
chain: [
|
|
257
|
+
{ driver: envVaultDriver, source: "process.env" },
|
|
258
|
+
{
|
|
259
|
+
driver: envVaultDriver,
|
|
260
|
+
source: ".env.local",
|
|
261
|
+
options: { path: resolve(cwd, ".env.local") },
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
driver: envVaultDriver,
|
|
265
|
+
source: ".env.stack",
|
|
266
|
+
options: { path: resolve(cwd, ".env.stack") },
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
driver: memoryVaultDriver,
|
|
270
|
+
source: "driver",
|
|
271
|
+
options: { secrets: seed },
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
});
|
|
275
|
+
await runtime.boot();
|
|
276
|
+
return runtime;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Query journal for sleeping durable runs whose flows read `secretName`.
|
|
281
|
+
*
|
|
282
|
+
* @param runs - Journal runs
|
|
283
|
+
* @param readerFlowIds - Flows that declare the secret
|
|
284
|
+
* @param now - Clock
|
|
285
|
+
*/
|
|
286
|
+
export function blastRadiusOf(
|
|
287
|
+
runs: readonly JournalRun[],
|
|
288
|
+
readerFlowIds: readonly string[],
|
|
289
|
+
now: number,
|
|
290
|
+
): ConsoleVaultBlastRadius {
|
|
291
|
+
const readers = new Set(readerFlowIds);
|
|
292
|
+
const affected = runs.filter(
|
|
293
|
+
(r) =>
|
|
294
|
+
r.status === "sleeping" &&
|
|
295
|
+
r.wakeAt != null &&
|
|
296
|
+
readers.has(r.flow),
|
|
297
|
+
);
|
|
298
|
+
if (affected.length === 0) {
|
|
299
|
+
return {
|
|
300
|
+
count: 0,
|
|
301
|
+
longestWakeAt: null,
|
|
302
|
+
longestOutstandingMs: null,
|
|
303
|
+
runIds: [],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
let longestWakeAt = 0;
|
|
307
|
+
const runIds: string[] = [];
|
|
308
|
+
for (const r of affected) {
|
|
309
|
+
runIds.push(r.id);
|
|
310
|
+
if ((r.wakeAt ?? 0) > longestWakeAt) longestWakeAt = r.wakeAt ?? 0;
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
count: affected.length,
|
|
314
|
+
longestWakeAt,
|
|
315
|
+
longestOutstandingMs: Math.max(0, longestWakeAt - now),
|
|
316
|
+
runIds,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Flow ids that declare `effects.secrets` including `name`.
|
|
322
|
+
*
|
|
323
|
+
* @param manifest - Manifest
|
|
324
|
+
* @param name - Secret name
|
|
325
|
+
*/
|
|
326
|
+
export function readersOf(
|
|
327
|
+
manifest: Manifest | null,
|
|
328
|
+
name: string,
|
|
329
|
+
): readonly string[] {
|
|
330
|
+
if (!manifest?.flows) return [];
|
|
331
|
+
const out: string[] = [];
|
|
332
|
+
for (const [flowId, flow] of Object.entries(manifest.flows)) {
|
|
333
|
+
if (flow.effects?.secrets?.includes(name)) out.push(flowId);
|
|
334
|
+
}
|
|
335
|
+
return out.sort();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* @param manifest - Manifest
|
|
340
|
+
* @param runtime - Runtime
|
|
341
|
+
*/
|
|
342
|
+
function collectNames(
|
|
343
|
+
manifest: Manifest | null,
|
|
344
|
+
runtime: VaultRuntime | null,
|
|
345
|
+
): readonly string[] {
|
|
346
|
+
const set = new Set<string>();
|
|
347
|
+
for (const name of Object.keys(manifest?.vault ?? {})) set.add(name);
|
|
348
|
+
if (runtime) {
|
|
349
|
+
for (const name of runtime.contracts.keys()) set.add(name);
|
|
350
|
+
for (const name of runtime.names()) set.add(name);
|
|
351
|
+
}
|
|
352
|
+
return [...set].sort();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @param name - Contract name
|
|
357
|
+
* @param manifest - Manifest
|
|
358
|
+
* @param runtime - Runtime
|
|
359
|
+
*/
|
|
360
|
+
function contractOf(
|
|
361
|
+
name: string,
|
|
362
|
+
manifest: Manifest | null,
|
|
363
|
+
runtime: VaultRuntime | null,
|
|
364
|
+
): {
|
|
365
|
+
readonly kind: "secret" | "config";
|
|
366
|
+
readonly sensitive: boolean;
|
|
367
|
+
readonly description?: string;
|
|
368
|
+
readonly rotate?: string;
|
|
369
|
+
} {
|
|
370
|
+
const fromRuntime = runtime?.contracts.get(name);
|
|
371
|
+
if (fromRuntime) {
|
|
372
|
+
return {
|
|
373
|
+
kind: fromRuntime.kind,
|
|
374
|
+
sensitive: fromRuntime.sensitive,
|
|
375
|
+
...(fromRuntime.description !== undefined
|
|
376
|
+
? { description: fromRuntime.description }
|
|
377
|
+
: {}),
|
|
378
|
+
...(fromRuntime.rotate !== undefined
|
|
379
|
+
? { rotate: fromRuntime.rotate }
|
|
380
|
+
: {}),
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const fromManifest = manifest?.vault?.[name];
|
|
384
|
+
const sensitive = fromManifest?.sensitive !== false;
|
|
385
|
+
return {
|
|
386
|
+
kind: sensitive ? "secret" : "config",
|
|
387
|
+
sensitive,
|
|
388
|
+
...(fromManifest?.description !== undefined
|
|
389
|
+
? { description: fromManifest.description }
|
|
390
|
+
: {}),
|
|
391
|
+
...(fromManifest?.rotate !== undefined
|
|
392
|
+
? { rotate: fromManifest.rotate }
|
|
393
|
+
: {}),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Environments (other than current) that share the same fingerprint.
|
|
399
|
+
*
|
|
400
|
+
* @param fingerprints - By env
|
|
401
|
+
* @param env - Current env
|
|
402
|
+
* @param fingerprint - Current fingerprint
|
|
403
|
+
*/
|
|
404
|
+
function sharedEnvs(
|
|
405
|
+
fingerprints: Readonly<Record<string, string>>,
|
|
406
|
+
env: VaultEnvLabel,
|
|
407
|
+
fingerprint: string | null,
|
|
408
|
+
): readonly VaultEnvLabel[] {
|
|
409
|
+
if (!fingerprint) return [];
|
|
410
|
+
return Object.entries(fingerprints)
|
|
411
|
+
.filter(([e, fp]) => e !== env && fp === fingerprint)
|
|
412
|
+
.map(([e]) => e as VaultEnvLabel)
|
|
413
|
+
.sort();
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/** Assert a Console row never embeds a secret value (tests / export safety). */
|
|
417
|
+
export function assertNoSecretLeak(
|
|
418
|
+
row: ConsoleVaultRow,
|
|
419
|
+
knownSecrets: readonly string[],
|
|
420
|
+
): void {
|
|
421
|
+
const blob = JSON.stringify(row);
|
|
422
|
+
for (const secret of knownSecrets) {
|
|
423
|
+
if (secret.length === 0) continue;
|
|
424
|
+
if (blob.includes(secret)) {
|
|
425
|
+
throw new Error(
|
|
426
|
+
`vault console leak: secret value appears in row for ${row.name}`,
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Access markup for the axe gate — same landmarks as the live panel
|
|
3
|
+
* (console §9.14).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ONCE_SECRET_ACK_LABEL,
|
|
8
|
+
ONCE_SECRET_WARNING,
|
|
9
|
+
} from "./acknowledgement.ts";
|
|
10
|
+
import { formatAccessBlastRadius } from "./blast-radius.ts";
|
|
11
|
+
import {
|
|
12
|
+
ACCESS_BLAST_FIXTURE,
|
|
13
|
+
ACCESS_EFFECTIVE_FIXTURE,
|
|
14
|
+
ACCESS_LIST_FIXTURE,
|
|
15
|
+
} from "./fixture.ts";
|
|
16
|
+
import { hygieneLines } from "./hygiene.ts";
|
|
17
|
+
import { formatProvenance } from "./provenance.ts";
|
|
18
|
+
|
|
19
|
+
/** Props for {@link AccessA11yView}. */
|
|
20
|
+
export interface AccessA11yViewProps {
|
|
21
|
+
/** Focused plane. */
|
|
22
|
+
readonly plane?: "operator" | "user";
|
|
23
|
+
/** Open key id for revoke / once-secret surfaces. */
|
|
24
|
+
readonly openKeyId?: string;
|
|
25
|
+
/** Show once-secret acknowledgement surface. */
|
|
26
|
+
readonly showOnceSecret?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Accessible Access list + detail for CI.
|
|
31
|
+
*
|
|
32
|
+
* @param props - Plane / open key
|
|
33
|
+
*/
|
|
34
|
+
export function AccessA11yView(props: AccessA11yViewProps) {
|
|
35
|
+
const plane = props.plane ?? "user";
|
|
36
|
+
const section =
|
|
37
|
+
plane === "operator"
|
|
38
|
+
? ACCESS_LIST_FIXTURE.operatorPlane
|
|
39
|
+
: ACCESS_LIST_FIXTURE.userPlane;
|
|
40
|
+
const openKeyId = props.openKeyId ?? "key_demo";
|
|
41
|
+
const openKey = section.keys.find((k) => k.id === openKeyId);
|
|
42
|
+
const blast = formatAccessBlastRadius(ACCESS_BLAST_FIXTURE);
|
|
43
|
+
const lines = hygieneLines(ACCESS_LIST_FIXTURE.hygiene);
|
|
44
|
+
const provenance = formatProvenance(ACCESS_EFFECTIVE_FIXTURE);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className="access-a11y">
|
|
48
|
+
<a href="#access-main">Skip to main content</a>
|
|
49
|
+
<header>
|
|
50
|
+
<h1>Access</h1>
|
|
51
|
+
<p>Identities, roles, API keys — planes never merge</p>
|
|
52
|
+
<div role="group" aria-label="Plane">
|
|
53
|
+
<button type="button" aria-pressed={plane === "operator"}>
|
|
54
|
+
Operator plane
|
|
55
|
+
</button>
|
|
56
|
+
<button type="button" aria-pressed={plane === "user"}>
|
|
57
|
+
User plane
|
|
58
|
+
</button>
|
|
59
|
+
</div>
|
|
60
|
+
<label>
|
|
61
|
+
Filter access
|
|
62
|
+
<input aria-label="Filter access" defaultValue="" />
|
|
63
|
+
</label>
|
|
64
|
+
</header>
|
|
65
|
+
|
|
66
|
+
{lines.length > 0 ? (
|
|
67
|
+
<section aria-label="Access hygiene" role="status">
|
|
68
|
+
<h2>Hygiene</h2>
|
|
69
|
+
<ul>
|
|
70
|
+
{lines.map((line) => (
|
|
71
|
+
<li key={line.code}>{line.message}</li>
|
|
72
|
+
))}
|
|
73
|
+
</ul>
|
|
74
|
+
</section>
|
|
75
|
+
) : null}
|
|
76
|
+
|
|
77
|
+
<main id="access-main">
|
|
78
|
+
<section aria-label={`${plane} plane`}>
|
|
79
|
+
<h2>{plane === "operator" ? "Operator plane" : "User plane"}</h2>
|
|
80
|
+
|
|
81
|
+
{section.operators ? (
|
|
82
|
+
<section aria-label="Operators">
|
|
83
|
+
<h3>Operators</h3>
|
|
84
|
+
<ul>
|
|
85
|
+
{section.operators.map((op) => (
|
|
86
|
+
<li key={op.id}>
|
|
87
|
+
<button type="button" style={{ minHeight: 32, width: "100%" }}>
|
|
88
|
+
{op.name} ({op.email})
|
|
89
|
+
{op.neverSignedIn ? (
|
|
90
|
+
<span role="status"> never signed in</span>
|
|
91
|
+
) : null}
|
|
92
|
+
</button>
|
|
93
|
+
</li>
|
|
94
|
+
))}
|
|
95
|
+
</ul>
|
|
96
|
+
</section>
|
|
97
|
+
) : null}
|
|
98
|
+
|
|
99
|
+
{section.users ? (
|
|
100
|
+
<section aria-label="Users">
|
|
101
|
+
<h3>Users</h3>
|
|
102
|
+
<ul>
|
|
103
|
+
{section.users.map((u) => (
|
|
104
|
+
<li key={u.id}>
|
|
105
|
+
<button type="button" style={{ minHeight: 32, width: "100%" }}>
|
|
106
|
+
{u.name} ({u.email})
|
|
107
|
+
</button>
|
|
108
|
+
</li>
|
|
109
|
+
))}
|
|
110
|
+
</ul>
|
|
111
|
+
</section>
|
|
112
|
+
) : null}
|
|
113
|
+
|
|
114
|
+
<section aria-label="Roles">
|
|
115
|
+
<h3>Roles</h3>
|
|
116
|
+
<ul>
|
|
117
|
+
{section.roles.map((r) => (
|
|
118
|
+
<li key={r.id}>
|
|
119
|
+
<button type="button" style={{ minHeight: 32, width: "100%" }}>
|
|
120
|
+
{r.name} — {r.scopes.length} scopes
|
|
121
|
+
</button>
|
|
122
|
+
</li>
|
|
123
|
+
))}
|
|
124
|
+
</ul>
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
<section aria-label="API keys">
|
|
128
|
+
<h3>API keys</h3>
|
|
129
|
+
<ul>
|
|
130
|
+
{section.keys.map((k) => (
|
|
131
|
+
<li key={k.id}>
|
|
132
|
+
<button
|
|
133
|
+
type="button"
|
|
134
|
+
aria-pressed={k.id === openKeyId}
|
|
135
|
+
style={{ minHeight: 32, width: "100%" }}
|
|
136
|
+
>
|
|
137
|
+
{k.name}
|
|
138
|
+
{k.unused90d ? (
|
|
139
|
+
<span role="status"> unused 90d+</span>
|
|
140
|
+
) : null}
|
|
141
|
+
</button>
|
|
142
|
+
</li>
|
|
143
|
+
))}
|
|
144
|
+
</ul>
|
|
145
|
+
</section>
|
|
146
|
+
|
|
147
|
+
<section aria-label="Grantable scopes">
|
|
148
|
+
<h3>Grantable scopes</h3>
|
|
149
|
+
<p>
|
|
150
|
+
Only scopes you hold appear — impossibility taught by absence
|
|
151
|
+
</p>
|
|
152
|
+
<ul>
|
|
153
|
+
{section.grantableScopes.map((s) => (
|
|
154
|
+
<li key={s}>
|
|
155
|
+
<label>
|
|
156
|
+
<input type="checkbox" disabled /> {s}
|
|
157
|
+
</label>
|
|
158
|
+
</li>
|
|
159
|
+
))}
|
|
160
|
+
</ul>
|
|
161
|
+
</section>
|
|
162
|
+
</section>
|
|
163
|
+
|
|
164
|
+
{openKey ? (
|
|
165
|
+
<section aria-label="Key detail" aria-live="polite">
|
|
166
|
+
<h2>{openKey.name}</h2>
|
|
167
|
+
<p className="font-mono">{openKey.id}</p>
|
|
168
|
+
|
|
169
|
+
<section aria-label="Revocation blast radius">
|
|
170
|
+
<h3>Revocation blast radius</h3>
|
|
171
|
+
<p role={blast.warn ? "alert" : "status"}>{blast.volume}</p>
|
|
172
|
+
<p>{blast.lastUsed}</p>
|
|
173
|
+
<p>{blast.sources}</p>
|
|
174
|
+
<p role="status">{blast.residual}</p>
|
|
175
|
+
</section>
|
|
176
|
+
|
|
177
|
+
<section aria-label="Revoke key">
|
|
178
|
+
<h3>Revoke</h3>
|
|
179
|
+
<label>
|
|
180
|
+
Type REVOKE to confirm
|
|
181
|
+
<input aria-label="Type REVOKE to confirm" defaultValue="" />
|
|
182
|
+
</label>
|
|
183
|
+
<label>
|
|
184
|
+
Reason
|
|
185
|
+
<input aria-label="Revoke reason" defaultValue="" />
|
|
186
|
+
</label>
|
|
187
|
+
<button type="button">Revoke key</button>
|
|
188
|
+
</section>
|
|
189
|
+
</section>
|
|
190
|
+
) : null}
|
|
191
|
+
|
|
192
|
+
<section aria-label="Effective permissions">
|
|
193
|
+
<h2>Effective permissions</h2>
|
|
194
|
+
<p>Every permission with provenance — inverse of the Gates simulator</p>
|
|
195
|
+
<table>
|
|
196
|
+
<caption>Effective permissions with provenance</caption>
|
|
197
|
+
<thead>
|
|
198
|
+
<tr>
|
|
199
|
+
<th scope="col">Scope</th>
|
|
200
|
+
<th scope="col">Granted by</th>
|
|
201
|
+
</tr>
|
|
202
|
+
</thead>
|
|
203
|
+
<tbody>
|
|
204
|
+
{provenance.map((row) => (
|
|
205
|
+
<tr key={row.scope}>
|
|
206
|
+
<td>{row.scope}</td>
|
|
207
|
+
<td>{row.sources}</td>
|
|
208
|
+
</tr>
|
|
209
|
+
))}
|
|
210
|
+
</tbody>
|
|
211
|
+
</table>
|
|
212
|
+
</section>
|
|
213
|
+
|
|
214
|
+
{props.showOnceSecret ? (
|
|
215
|
+
<section
|
|
216
|
+
aria-label="New API key secret"
|
|
217
|
+
role="alertdialog"
|
|
218
|
+
aria-modal="true"
|
|
219
|
+
aria-labelledby="once-secret-title"
|
|
220
|
+
>
|
|
221
|
+
<h2 id="once-secret-title">New API key secret</h2>
|
|
222
|
+
<p role="alert">{ONCE_SECRET_WARNING}</p>
|
|
223
|
+
<p>
|
|
224
|
+
<code>oke_fixture_secret_shown_once</code>
|
|
225
|
+
</p>
|
|
226
|
+
<label>
|
|
227
|
+
<input type="checkbox" /> {ONCE_SECRET_ACK_LABEL}
|
|
228
|
+
</label>
|
|
229
|
+
<button type="button" disabled>
|
|
230
|
+
Dismiss secret
|
|
231
|
+
</button>
|
|
232
|
+
</section>
|
|
233
|
+
) : null}
|
|
234
|
+
</main>
|
|
235
|
+
</div>
|
|
236
|
+
);
|
|
237
|
+
}
|