okengine 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -23
- package/README.md +52 -346
- package/docs/spec/console.md +165 -142
- package/docs/spec/example.md +490 -312
- package/docs/spec/four-applications.md +495 -314
- package/docs/spec/unified-theory.md +184 -175
- package/package.json +45 -37
- package/spec/manifest.v1.schema.json +40 -9
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +53 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +386 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +163 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev.test.ts +148 -21
- package/src/cli/dev.ts +208 -134
- package/src/cli/doc-drift.test.ts +3 -2
- package/src/cli/doc-drift.ts +21 -50
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +7 -8
- package/src/cli/docker.ts +1 -3
- package/src/cli/doctor-diff-examples.ts +1 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +41 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +45 -0
- package/src/cli/ports.test.ts +4 -13
- package/src/cli/ports.ts +1 -3
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +2 -7
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +8 -29
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +96 -30
- package/src/compiler/extract.ts +362 -156
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +4 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +57 -34
- package/src/config/index.ts +181 -37
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +14 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +23 -60
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +112 -20
- package/src/docker/derive.ts +5 -19
- package/src/docker/docker.test.ts +15 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +4 -11
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +5 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +6 -1
- package/src/docker/recipes/rustfs.ts +33 -0
- package/src/docker/stack-id.test.ts +33 -0
- package/src/docker/stack-id.ts +25 -13
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/types.ts +13 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -56
- package/src/drivers/memory.ts +14 -41
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +5 -17
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.ts +1 -5
- package/src/drivers/vault-sops.ts +10 -35
- package/src/drivers/vault-types.ts +1 -7
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +8 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.ts +11 -21
- package/src/elements/store/sql-session.test.ts +50 -0
- package/src/elements/store/sql-session.ts +60 -63
- package/src/elements/store/table.ts +35 -19
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +37 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +18 -32
- package/src/elements/vault.test.ts +12 -28
- package/src/elements/vault.ts +8 -12
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +34 -94
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.ts +2 -8
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +17 -17
- package/src/kernel/boot-bind/store.ts +44 -50
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -9
- package/src/kernel/boot.ts +29 -76
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +5 -25
- package/src/kernel/fx.test.ts +15 -44
- package/src/kernel/fx.ts +27 -79
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +10 -10
- package/src/kernel/hooks.ts +3 -12
- package/src/kernel/index.ts +4 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +1 -6
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +48 -24
- package/src/kernel/registry.ts +80 -29
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +4 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/index.ts +2 -9
- package/src/manifest/types.ts +29 -5
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +4 -14
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +15 -43
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +13 -31
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
|
@@ -16,8 +16,7 @@ describe("Gates panel accessibility", () => {
|
|
|
16
16
|
let container: HTMLElement;
|
|
17
17
|
|
|
18
18
|
beforeEach(() => {
|
|
19
|
-
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT =
|
|
20
|
-
true;
|
|
19
|
+
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
21
20
|
window = new Window({ url: "http://console.test/gates" });
|
|
22
21
|
Object.defineProperty(globalThis, "window", {
|
|
23
22
|
value: window,
|
|
@@ -97,9 +96,7 @@ describe("Gates panel accessibility", () => {
|
|
|
97
96
|
|
|
98
97
|
test("axe reports zero violations at WCAG 2.2 AA (from principal)", async () => {
|
|
99
98
|
await act(async () => {
|
|
100
|
-
root.render(
|
|
101
|
-
<GatesA11yView from="principal" openPrincipal="role:role_member" />,
|
|
102
|
-
);
|
|
99
|
+
root.render(<GatesA11yView from="principal" openPrincipal="role:role_member" />);
|
|
103
100
|
});
|
|
104
101
|
|
|
105
102
|
await new Promise((r) => setTimeout(r, 10));
|
|
@@ -56,8 +56,6 @@ export function auditLines(audit: GateAuditRecord): readonly AuditLine[] {
|
|
|
56
56
|
*/
|
|
57
57
|
export function formatViolation(violation: PlaneViolationRecord): string {
|
|
58
58
|
const scopes = violation.applicationScopes.join(", ");
|
|
59
|
-
const who = violation.email
|
|
60
|
-
? `${violation.name} <${violation.email}>`
|
|
61
|
-
: violation.name;
|
|
59
|
+
const who = violation.email ? `${violation.name} <${violation.email}>` : violation.name;
|
|
62
60
|
return `${who} holds application scope(s): ${scopes}`;
|
|
63
61
|
}
|
|
@@ -26,9 +26,7 @@ describe("formatDenial", () => {
|
|
|
26
26
|
|
|
27
27
|
describe("formatEvaluationStep", () => {
|
|
28
28
|
test("preserves registration order marks", () => {
|
|
29
|
-
const steps = SIMULATE_RATE_FIXTURE.evaluations.map((e, i) =>
|
|
30
|
-
formatEvaluationStep(e, i),
|
|
31
|
-
);
|
|
29
|
+
const steps = SIMULATE_RATE_FIXTURE.evaluations.map((e, i) => formatEvaluationStep(e, i));
|
|
32
30
|
expect(steps[0]).toContain("pass");
|
|
33
31
|
expect(steps[2]).toContain("deny");
|
|
34
32
|
expect(steps[2]).toContain("retryAfterMs 12000");
|
|
@@ -12,17 +12,12 @@ import type { GateDenialRecord, GateEvaluationRecord } from "./types.ts";
|
|
|
12
12
|
export function formatDenial(denial: GateDenialRecord): string {
|
|
13
13
|
switch (denial.code) {
|
|
14
14
|
case "RateLimited": {
|
|
15
|
-
const ms =
|
|
16
|
-
typeof denial.data.retryAfterMs === "number"
|
|
17
|
-
? denial.data.retryAfterMs
|
|
18
|
-
: 0;
|
|
15
|
+
const ms = typeof denial.data.retryAfterMs === "number" ? denial.data.retryAfterMs : 0;
|
|
19
16
|
return `RateLimited { retryAfterMs: ${ms} } · HTTP ${denial.status}`;
|
|
20
17
|
}
|
|
21
18
|
case "Forbidden": {
|
|
22
|
-
const gate =
|
|
23
|
-
|
|
24
|
-
const reason =
|
|
25
|
-
typeof denial.data.reason === "string" ? denial.data.reason : "";
|
|
19
|
+
const gate = typeof denial.data.gate === "string" ? denial.data.gate : "?";
|
|
20
|
+
const reason = typeof denial.data.reason === "string" ? denial.data.reason : "";
|
|
26
21
|
return `Forbidden { gate: ${gate}${reason ? `, reason: ${reason}` : ""} } · HTTP ${denial.status}`;
|
|
27
22
|
}
|
|
28
23
|
case "Unauthorized":
|
|
@@ -36,10 +31,7 @@ export function formatDenial(denial: GateDenialRecord): string {
|
|
|
36
31
|
* @param evaluation - Step
|
|
37
32
|
* @param index - 0-based order
|
|
38
33
|
*/
|
|
39
|
-
export function formatEvaluationStep(
|
|
40
|
-
evaluation: GateEvaluationRecord,
|
|
41
|
-
index: number,
|
|
42
|
-
): string {
|
|
34
|
+
export function formatEvaluationStep(evaluation: GateEvaluationRecord, index: number): string {
|
|
43
35
|
const mark = evaluation.allowed ? "pass" : "deny";
|
|
44
36
|
const extra =
|
|
45
37
|
evaluation.kind === "rate" && evaluation.retryAfterMs !== undefined
|
|
@@ -12,8 +12,6 @@ import type { GateAuditRecord } from "./types.ts";
|
|
|
12
12
|
*
|
|
13
13
|
* @param audit - Gates audit record
|
|
14
14
|
*/
|
|
15
|
-
export function unguardedFlowFindings(
|
|
16
|
-
audit: GateAuditRecord,
|
|
17
|
-
): readonly AuditLine[] {
|
|
15
|
+
export function unguardedFlowFindings(audit: GateAuditRecord): readonly AuditLine[] {
|
|
18
16
|
return auditLines(audit).filter((line) => line.code === "unguarded");
|
|
19
17
|
}
|
|
@@ -23,8 +23,8 @@ describe("groupFlows", () => {
|
|
|
23
23
|
const groups = groupFlows(GATES_LIST_FIXTURE.flows);
|
|
24
24
|
const user = groups.find((g) => g.id === "user");
|
|
25
25
|
expect(user?.items.some((i) => i.flag === "unguarded")).toBe(true);
|
|
26
|
-
expect(
|
|
27
|
-
|
|
28
|
-
)
|
|
26
|
+
expect(user?.items.find((i) => i.id === "bookings.create")?.meta).toContain(
|
|
27
|
+
"member → booking:create",
|
|
28
|
+
);
|
|
29
29
|
});
|
|
30
30
|
});
|
|
@@ -4,11 +4,7 @@
|
|
|
4
4
|
* The roles × permissions matrix is refused as an entry point.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {
|
|
8
|
-
FlowGatesRecord,
|
|
9
|
-
GatesListGroup,
|
|
10
|
-
PrincipalRecord,
|
|
11
|
-
} from "./types.ts";
|
|
7
|
+
import type { FlowGatesRecord, GatesListGroup, PrincipalRecord } from "./types.ts";
|
|
12
8
|
|
|
13
9
|
/**
|
|
14
10
|
* Group principals by kind for the from-principal inquiry.
|
|
@@ -71,8 +67,7 @@ export function groupFlows(
|
|
|
71
67
|
const filtered = q
|
|
72
68
|
? flows.filter(
|
|
73
69
|
(f) =>
|
|
74
|
-
f.flowId.toLowerCase().includes(q) ||
|
|
75
|
-
f.gates.some((g) => g.toLowerCase().includes(q)),
|
|
70
|
+
f.flowId.toLowerCase().includes(q) || f.gates.some((g) => g.toLowerCase().includes(q)),
|
|
76
71
|
)
|
|
77
72
|
: flows;
|
|
78
73
|
|
|
@@ -91,10 +86,7 @@ export function groupFlows(
|
|
|
91
86
|
.map((f) => ({
|
|
92
87
|
id: f.flowId,
|
|
93
88
|
label: f.flowId,
|
|
94
|
-
meta:
|
|
95
|
-
f.gates.length === 0
|
|
96
|
-
? "ungated"
|
|
97
|
-
: f.gates.join(" → "),
|
|
89
|
+
meta: f.gates.length === 0 ? "ungated" : f.gates.join(" → "),
|
|
98
90
|
flag: f.unguarded ? "unguarded" : undefined,
|
|
99
91
|
})),
|
|
100
92
|
}))
|
|
@@ -18,11 +18,7 @@ export type {
|
|
|
18
18
|
WideningRecord,
|
|
19
19
|
} from "./types.ts";
|
|
20
20
|
|
|
21
|
-
export {
|
|
22
|
-
GATES_LIST_FIXTURE,
|
|
23
|
-
SIMULATE_ALLOW_FIXTURE,
|
|
24
|
-
SIMULATE_RATE_FIXTURE,
|
|
25
|
-
} from "./fixture.ts";
|
|
21
|
+
export { GATES_LIST_FIXTURE, SIMULATE_ALLOW_FIXTURE, SIMULATE_RATE_FIXTURE } from "./fixture.ts";
|
|
26
22
|
|
|
27
23
|
export {
|
|
28
24
|
parseGatesSearch,
|
|
@@ -36,11 +32,7 @@ export {
|
|
|
36
32
|
|
|
37
33
|
export { groupPrincipals, groupFlows } from "./group.ts";
|
|
38
34
|
|
|
39
|
-
export {
|
|
40
|
-
auditLines,
|
|
41
|
-
formatViolation,
|
|
42
|
-
type AuditLine,
|
|
43
|
-
} from "./audit.ts";
|
|
35
|
+
export { auditLines, formatViolation, type AuditLine } from "./audit.ts";
|
|
44
36
|
|
|
45
37
|
export { unguardedFlowFindings } from "./findings.ts";
|
|
46
38
|
|
|
@@ -24,9 +24,7 @@ export type GatesSearch = z.infer<typeof GatesSearchSchema>;
|
|
|
24
24
|
*
|
|
25
25
|
* @param search - Raw router search
|
|
26
26
|
*/
|
|
27
|
-
export function parseGatesSearch(
|
|
28
|
-
search: Record<string, unknown>,
|
|
29
|
-
): GatesSearch {
|
|
27
|
+
export function parseGatesSearch(search: Record<string, unknown>): GatesSearch {
|
|
30
28
|
const parsed = GatesSearchSchema.safeParse(search);
|
|
31
29
|
return parsed.success ? parsed.data : {};
|
|
32
30
|
}
|
|
@@ -36,9 +34,7 @@ export function parseGatesSearch(
|
|
|
36
34
|
*
|
|
37
35
|
* @param search - Search state
|
|
38
36
|
*/
|
|
39
|
-
export function serializeGatesSearch(
|
|
40
|
-
search: GatesSearch,
|
|
41
|
-
): Record<string, string> {
|
|
37
|
+
export function serializeGatesSearch(search: GatesSearch): Record<string, string> {
|
|
42
38
|
const out: Record<string, string> = {};
|
|
43
39
|
if (search.q) out.q = search.q;
|
|
44
40
|
if (search.from) out.from = search.from;
|
|
@@ -54,10 +50,7 @@ export function serializeGatesSearch(
|
|
|
54
50
|
* @param kind - Principal kind
|
|
55
51
|
* @param id - Principal id
|
|
56
52
|
*/
|
|
57
|
-
export function encodePrincipal(
|
|
58
|
-
kind: "role" | "key" | "user",
|
|
59
|
-
id: string,
|
|
60
|
-
): string {
|
|
53
|
+
export function encodePrincipal(kind: "role" | "key" | "user", id: string): string {
|
|
61
54
|
return `${kind}:${id}`;
|
|
62
55
|
}
|
|
63
56
|
|
|
@@ -4,14 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { composeOverview } from "./compose.ts";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
OVERVIEW_INPUTS_FIXTURE,
|
|
10
|
-
} from "./fixture.ts";
|
|
11
|
-
import {
|
|
12
|
-
formatBudgetDuration,
|
|
13
|
-
formatBurnRate,
|
|
14
|
-
} from "./verdict.ts";
|
|
7
|
+
import { OVERVIEW_DAY_ONE_INPUTS, OVERVIEW_INPUTS_FIXTURE } from "./fixture.ts";
|
|
8
|
+
import { formatBudgetDuration, formatBurnRate } from "./verdict.ts";
|
|
15
9
|
|
|
16
10
|
/** Props for {@link OverviewA11yView}. */
|
|
17
11
|
export interface OverviewA11yViewProps {
|
|
@@ -25,9 +19,7 @@ export interface OverviewA11yViewProps {
|
|
|
25
19
|
* @param props - Fixture selection
|
|
26
20
|
*/
|
|
27
21
|
export function OverviewA11yView(props: OverviewA11yViewProps = {}) {
|
|
28
|
-
const view = composeOverview(
|
|
29
|
-
props.dayOne ? OVERVIEW_DAY_ONE_INPUTS : OVERVIEW_INPUTS_FIXTURE,
|
|
30
|
-
);
|
|
22
|
+
const view = composeOverview(props.dayOne ? OVERVIEW_DAY_ONE_INPUTS : OVERVIEW_INPUTS_FIXTURE);
|
|
31
23
|
|
|
32
24
|
return (
|
|
33
25
|
<div className="overview-a11y">
|
|
@@ -50,13 +42,8 @@ export function OverviewA11yView(props: OverviewA11yViewProps = {}) {
|
|
|
50
42
|
</span>
|
|
51
43
|
<span> {s.availability}</span>
|
|
52
44
|
<span> burn {formatBurnRate(s.burnRate)}</span>
|
|
53
|
-
<span>
|
|
54
|
-
|
|
55
|
-
exhausts {formatBudgetDuration(s.timeToExhaustionMs)}
|
|
56
|
-
</span>
|
|
57
|
-
{s.ceremonial ? (
|
|
58
|
-
<span role="status"> CEREMONIAL</span>
|
|
59
|
-
) : null}
|
|
45
|
+
<span> exhausts {formatBudgetDuration(s.timeToExhaustionMs)}</span>
|
|
46
|
+
{s.ceremonial ? <span role="status"> CEREMONIAL</span> : null}
|
|
60
47
|
</li>
|
|
61
48
|
))}
|
|
62
49
|
</ul>
|
|
@@ -77,10 +64,7 @@ export function OverviewA11yView(props: OverviewA11yViewProps = {}) {
|
|
|
77
64
|
${c.spent.toFixed(2)} / ${c.declaredBudget.toFixed(2)}
|
|
78
65
|
</span>
|
|
79
66
|
<span> burn {formatBurnRate(c.burnRate)}</span>
|
|
80
|
-
<span>
|
|
81
|
-
{" "}
|
|
82
|
-
exhausts {formatBudgetDuration(c.timeToExhaustionMs)}
|
|
83
|
-
</span>
|
|
67
|
+
<span> exhausts {formatBudgetDuration(c.timeToExhaustionMs)}</span>
|
|
84
68
|
</li>
|
|
85
69
|
))}
|
|
86
70
|
</ul>
|
|
@@ -138,11 +122,9 @@ export function OverviewA11yView(props: OverviewA11yViewProps = {}) {
|
|
|
138
122
|
<h2>Declare a first objective</h2>
|
|
139
123
|
<p>
|
|
140
124
|
Your busiest flow is{" "}
|
|
141
|
-
<a href={view.firstSloInvite.href}>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
({view.firstSloInvite.runCount} runs). Add{" "}
|
|
145
|
-
<code>slo: {"{ availability: \"99.9%\" }"}</code> on that flow.
|
|
125
|
+
<a href={view.firstSloInvite.href}>{view.firstSloInvite.busiestFlow}</a> (
|
|
126
|
+
{view.firstSloInvite.runCount} runs). Add{" "}
|
|
127
|
+
<code>slo: {'{ availability: "99.9%" }'}</code> on that flow.
|
|
146
128
|
</p>
|
|
147
129
|
</section>
|
|
148
130
|
) : null}
|
|
@@ -16,8 +16,7 @@ describe("Overview panel accessibility", () => {
|
|
|
16
16
|
let container: HTMLElement;
|
|
17
17
|
|
|
18
18
|
beforeEach(() => {
|
|
19
|
-
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT =
|
|
20
|
-
true;
|
|
19
|
+
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
21
20
|
window = new Window({ url: "http://console.test/overview" });
|
|
22
21
|
Object.defineProperty(globalThis, "window", {
|
|
23
22
|
value: window,
|
|
@@ -11,9 +11,7 @@ import type { FirstSloInvite } from "./types.ts";
|
|
|
11
11
|
*
|
|
12
12
|
* @param runs - Real Runs population
|
|
13
13
|
*/
|
|
14
|
-
export function firstSloInvite(
|
|
15
|
-
runs: readonly RunRecord[],
|
|
16
|
-
): FirstSloInvite | null {
|
|
14
|
+
export function firstSloInvite(runs: readonly RunRecord[]): FirstSloInvite | null {
|
|
17
15
|
if (runs.length === 0) return null;
|
|
18
16
|
const groups = groupByDimension(runs, "flow");
|
|
19
17
|
const top = groups[0];
|
|
@@ -48,19 +48,7 @@ export interface OverviewInputs {
|
|
|
48
48
|
* @param inputs - Aggregated panel data
|
|
49
49
|
*/
|
|
50
50
|
export function composeOverview(inputs: OverviewInputs): OverviewView {
|
|
51
|
-
const {
|
|
52
|
-
manifest,
|
|
53
|
-
runs,
|
|
54
|
-
gates,
|
|
55
|
-
signals,
|
|
56
|
-
clock,
|
|
57
|
-
vault,
|
|
58
|
-
channels,
|
|
59
|
-
ai,
|
|
60
|
-
diff,
|
|
61
|
-
access,
|
|
62
|
-
now,
|
|
63
|
-
} = inputs;
|
|
51
|
+
const { manifest, runs, gates, signals, clock, vault, channels, ai, diff, access, now } = inputs;
|
|
64
52
|
|
|
65
53
|
const graph =
|
|
66
54
|
inputs.architectureGraph !== undefined
|
|
@@ -32,18 +32,18 @@ export function computeCostBudgets(options: {
|
|
|
32
32
|
const budget = flow.cost?.budget;
|
|
33
33
|
if (budget == null || budget <= 0) continue;
|
|
34
34
|
const spent = sumCost(
|
|
35
|
-
runs.filter(
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
runs.filter((r) => r.flow === name && r.startedAt >= from && r.startedAt <= now),
|
|
36
|
+
);
|
|
37
|
+
out.push(
|
|
38
|
+
budgetRow({
|
|
39
|
+
id: `flow:${name}`,
|
|
40
|
+
name,
|
|
41
|
+
kind: "flow",
|
|
42
|
+
declaredBudget: budget,
|
|
43
|
+
spent,
|
|
44
|
+
windowMs: COST_WINDOW_MS,
|
|
45
|
+
}),
|
|
38
46
|
);
|
|
39
|
-
out.push(budgetRow({
|
|
40
|
-
id: `flow:${name}`,
|
|
41
|
-
name,
|
|
42
|
-
kind: "flow",
|
|
43
|
-
declaredBudget: budget,
|
|
44
|
-
spent,
|
|
45
|
-
windowMs: COST_WINDOW_MS,
|
|
46
|
-
}));
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
if (ai) {
|
|
@@ -51,9 +51,7 @@ export function computeCostBudgets(options: {
|
|
|
51
51
|
const cap = prompt.budgetMaxCostPerCall;
|
|
52
52
|
if (cap == null || cap <= 0) continue;
|
|
53
53
|
const version =
|
|
54
|
-
ai.versions.find(
|
|
55
|
-
(v) => v.prompt === prompt.name && v.version === prompt.version,
|
|
56
|
-
) ??
|
|
54
|
+
ai.versions.find((v) => v.prompt === prompt.name && v.version === prompt.version) ??
|
|
57
55
|
ai.versions
|
|
58
56
|
.filter((v) => v.prompt === prompt.name)
|
|
59
57
|
.sort((a, b) => b.version - a.version)[0];
|
|
@@ -61,14 +59,16 @@ export function computeCostBudgets(options: {
|
|
|
61
59
|
// Per-call budget × samples in window ≈ declared period budget.
|
|
62
60
|
const declaredBudget = cap * version.sampleCount;
|
|
63
61
|
const spent = version.cost.mean * version.sampleCount;
|
|
64
|
-
out.push(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
out.push(
|
|
63
|
+
budgetRow({
|
|
64
|
+
id: `ai-prompt:${prompt.name}@${version.version}`,
|
|
65
|
+
name: `${prompt.name}@${version.version}`,
|
|
66
|
+
kind: "ai-prompt",
|
|
67
|
+
declaredBudget,
|
|
68
|
+
spent,
|
|
69
|
+
windowMs: COST_WINDOW_MS,
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
for (const agent of ai.agents) {
|
|
@@ -78,21 +78,20 @@ export function computeCostBudgets(options: {
|
|
|
78
78
|
if (agentRuns.length === 0) continue;
|
|
79
79
|
const declaredBudget = cap * agentRuns.length;
|
|
80
80
|
const spent = agentRuns.reduce((a, r) => a + r.cost, 0);
|
|
81
|
-
out.push(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
out.push(
|
|
82
|
+
budgetRow({
|
|
83
|
+
id: `ai-agent:${agent.name}`,
|
|
84
|
+
name: agent.name,
|
|
85
|
+
kind: "ai-agent",
|
|
86
|
+
declaredBudget,
|
|
87
|
+
spent,
|
|
88
|
+
windowMs: COST_WINDOW_MS,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
92
|
-
return out.sort(
|
|
93
|
-
(a, b) =>
|
|
94
|
-
b.burnRate - a.burnRate || a.name.localeCompare(b.name),
|
|
95
|
-
);
|
|
94
|
+
return out.sort((a, b) => b.burnRate - a.burnRate || a.name.localeCompare(b.name));
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
function budgetRow(input: {
|
|
@@ -105,10 +104,7 @@ function budgetRow(input: {
|
|
|
105
104
|
}): CostBudget {
|
|
106
105
|
const { declaredBudget, spent, windowMs } = input;
|
|
107
106
|
const burnRate = declaredBudget <= 0 ? 0 : spent / declaredBudget;
|
|
108
|
-
const remainingFraction = Math.max(
|
|
109
|
-
0,
|
|
110
|
-
1 - (declaredBudget <= 0 ? 0 : spent / declaredBudget),
|
|
111
|
-
);
|
|
107
|
+
const remainingFraction = Math.max(0, 1 - (declaredBudget <= 0 ? 0 : spent / declaredBudget));
|
|
112
108
|
let timeToExhaustionMs: number | null = null;
|
|
113
109
|
if (spent > 0 && burnRate > 0 && remainingFraction > 0) {
|
|
114
110
|
// At current spend pace, remaining budget lasts:
|
|
@@ -85,7 +85,7 @@ export const OVERVIEW_VAULT_FIXTURE = {
|
|
|
85
85
|
resolution: [
|
|
86
86
|
{ source: "process.env" as const, present: false, won: false },
|
|
87
87
|
{ source: ".env.local" as const, present: true, won: true },
|
|
88
|
-
{ source: ".env.
|
|
88
|
+
{ source: ".env.docker" as const, present: false, won: false },
|
|
89
89
|
{ source: "driver" as const, present: false, won: false },
|
|
90
90
|
{ source: "dev-fallback" as const, present: false, won: false },
|
|
91
91
|
],
|
|
@@ -106,28 +106,26 @@ export const OVERVIEW_VAULT_FIXTURE = {
|
|
|
106
106
|
* Runs that burn bookings.create in the short window
|
|
107
107
|
* (error rate ≫ 0.1% tolerable for 99.9%).
|
|
108
108
|
*/
|
|
109
|
-
export const OVERVIEW_BURN_RUNS: readonly RunRecord[] = Array.from(
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
export const OVERVIEW_BURN_RUNS: readonly RunRecord[] = Array.from({ length: 100 }, (_, i) =>
|
|
110
|
+
rowToRun({
|
|
111
|
+
id: `burn-${i}`,
|
|
112
|
+
flow: "bookings.create",
|
|
113
|
+
unit: "bookings",
|
|
114
|
+
trigger: "http",
|
|
115
|
+
plane: "user",
|
|
116
|
+
cache: "none",
|
|
117
|
+
cost: 0.05,
|
|
118
|
+
startedAt: OVERVIEW_NOW - 30 * 60_000 + i * 1_000,
|
|
119
|
+
endedAt: OVERVIEW_NOW - 30 * 60_000 + i * 1_000 + 40,
|
|
120
|
+
durationMs: 40,
|
|
121
|
+
error: i < 20 ? "Timeout" : null,
|
|
122
|
+
effects: [],
|
|
123
|
+
logs: [],
|
|
124
|
+
dimensions: {
|
|
114
125
|
flow: "bookings.create",
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
cache: "none",
|
|
119
|
-
cost: 0.05,
|
|
120
|
-
startedAt: OVERVIEW_NOW - 30 * 60_000 + i * 1_000,
|
|
121
|
-
endedAt: OVERVIEW_NOW - 30 * 60_000 + i * 1_000 + 40,
|
|
122
|
-
durationMs: 40,
|
|
123
|
-
error: i < 20 ? "Timeout" : null,
|
|
124
|
-
effects: [],
|
|
125
|
-
logs: [],
|
|
126
|
-
dimensions: {
|
|
127
|
-
flow: "bookings.create",
|
|
128
|
-
error_code: i < 20 ? "Timeout" : null,
|
|
129
|
-
},
|
|
130
|
-
}),
|
|
126
|
+
error_code: i < 20 ? "Timeout" : null,
|
|
127
|
+
},
|
|
128
|
+
}),
|
|
131
129
|
);
|
|
132
130
|
|
|
133
131
|
/** Full Overview inputs — burning SLO + multi-panel findings. */
|
|
@@ -151,10 +149,7 @@ export const OVERVIEW_DAY_ONE_INPUTS: OverviewInputs = {
|
|
|
151
149
|
manifest: {
|
|
152
150
|
...OVERVIEW_MANIFEST,
|
|
153
151
|
flows: Object.fromEntries(
|
|
154
|
-
Object.entries(OVERVIEW_MANIFEST.flows ?? {}).map(([k, f]) => [
|
|
155
|
-
k,
|
|
156
|
-
{ ...f, slo: undefined },
|
|
157
|
-
]),
|
|
152
|
+
Object.entries(OVERVIEW_MANIFEST.flows ?? {}).map(([k, f]) => [k, { ...f, slo: undefined }]),
|
|
158
153
|
),
|
|
159
154
|
journeys: undefined,
|
|
160
155
|
},
|
|
@@ -19,21 +19,14 @@ export const SATURATION_LAG_MS = 200;
|
|
|
19
19
|
* @param runs - Wide-event population
|
|
20
20
|
* @param now - Clock
|
|
21
21
|
*/
|
|
22
|
-
export function computeGoldenSignals(
|
|
23
|
-
runs: readonly RunRecord[],
|
|
24
|
-
now: number,
|
|
25
|
-
): GoldenSignals {
|
|
22
|
+
export function computeGoldenSignals(runs: readonly RunRecord[], now: number): GoldenSignals {
|
|
26
23
|
const from = now - GOLDEN_WINDOW_MS;
|
|
27
|
-
const window = runs.filter(
|
|
28
|
-
(r) => r.startedAt >= from && r.startedAt <= now,
|
|
29
|
-
);
|
|
24
|
+
const window = runs.filter((r) => r.startedAt >= from && r.startedAt <= now);
|
|
30
25
|
const n = window.length;
|
|
31
26
|
const errors = window.filter((r) => !!r.error).length;
|
|
32
27
|
const durations = window.map((r) => r.durationMs).sort((a, b) => a - b);
|
|
33
28
|
const saturated = window.filter(
|
|
34
|
-
(r) =>
|
|
35
|
-
(r.replicaLagMs != null && r.replicaLagMs > SATURATION_LAG_MS) ||
|
|
36
|
-
r.cache === "miss",
|
|
29
|
+
(r) => (r.replicaLagMs != null && r.replicaLagMs > SATURATION_LAG_MS) || r.cache === "miss",
|
|
37
30
|
).length;
|
|
38
31
|
|
|
39
32
|
return {
|
|
@@ -49,9 +42,6 @@ export function computeGoldenSignals(
|
|
|
49
42
|
function percentile(sorted: readonly number[], p: number): number {
|
|
50
43
|
if (sorted.length === 0) return 0;
|
|
51
44
|
if (sorted.length === 1) return sorted[0]!;
|
|
52
|
-
const idx = Math.min(
|
|
53
|
-
sorted.length - 1,
|
|
54
|
-
Math.max(0, Math.ceil(p * sorted.length) - 1),
|
|
55
|
-
);
|
|
45
|
+
const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1));
|
|
56
46
|
return sorted[idx]!;
|
|
57
47
|
}
|
|
@@ -14,10 +14,7 @@ export type {
|
|
|
14
14
|
WhatChanged,
|
|
15
15
|
} from "./types.ts";
|
|
16
16
|
|
|
17
|
-
export {
|
|
18
|
-
composeOverview,
|
|
19
|
-
type OverviewInputs,
|
|
20
|
-
} from "./compose.ts";
|
|
17
|
+
export { composeOverview, type OverviewInputs } from "./compose.ts";
|
|
21
18
|
|
|
22
19
|
export {
|
|
23
20
|
declaredSlos,
|
|
@@ -35,11 +32,7 @@ export { computeGoldenSignals, GOLDEN_WINDOW_MS } from "./golden.ts";
|
|
|
35
32
|
|
|
36
33
|
export { firstSloInvite } from "./busiest.ts";
|
|
37
34
|
|
|
38
|
-
export {
|
|
39
|
-
rankedFindings,
|
|
40
|
-
compareFindings,
|
|
41
|
-
type FindingInputs,
|
|
42
|
-
} from "./rank.ts";
|
|
35
|
+
export { rankedFindings, compareFindings, type FindingInputs } from "./rank.ts";
|
|
43
36
|
|
|
44
37
|
export {
|
|
45
38
|
composeVerdict,
|
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
6
|
import { buildCausalityGraph } from "../flows/graph.ts";
|
|
7
7
|
import { composeOverview } from "./compose.ts";
|
|
8
|
-
import {
|
|
9
|
-
OVERVIEW_DAY_ONE_INPUTS,
|
|
10
|
-
OVERVIEW_INPUTS_FIXTURE,
|
|
11
|
-
} from "./fixture.ts";
|
|
8
|
+
import { OVERVIEW_DAY_ONE_INPUTS, OVERVIEW_INPUTS_FIXTURE } from "./fixture.ts";
|
|
12
9
|
import { compareFindings, rankedFindings } from "./rank.ts";
|
|
13
10
|
|
|
14
11
|
describe("rankedFindings", () => {
|
|
@@ -35,9 +32,7 @@ describe("rankedFindings", () => {
|
|
|
35
32
|
expect(access.length).toBeGreaterThan(0);
|
|
36
33
|
expect(access.some((f) => f.detail.includes("unused 90d"))).toBe(true);
|
|
37
34
|
expect(access.some((f) => f.detail.includes("never signed in"))).toBe(true);
|
|
38
|
-
expect(access.some((f) => f.detail.includes("expired invitation"))).toBe(
|
|
39
|
-
true,
|
|
40
|
-
);
|
|
35
|
+
expect(access.some((f) => f.detail.includes("expired invitation"))).toBe(true);
|
|
41
36
|
expect(access.every((f) => f.href === "/access")).toBe(true);
|
|
42
37
|
});
|
|
43
38
|
|
|
@@ -114,9 +109,7 @@ describe("composeOverview day-one", () => {
|
|
|
114
109
|
expect(view.golden.sampleCount).toBeGreaterThan(0);
|
|
115
110
|
expect(view.firstSloInvite).not.toBeNull();
|
|
116
111
|
expect(view.firstSloInvite!.busiestFlow).toBe("bookings.create");
|
|
117
|
-
expect(view.verdict.tone === "warn" || view.verdict.tone === "critical").toBe(
|
|
118
|
-
true,
|
|
119
|
-
);
|
|
112
|
+
expect(view.verdict.tone === "warn" || view.verdict.tone === "critical").toBe(true);
|
|
120
113
|
expect(view.verdict.line.length).toBeGreaterThan(0);
|
|
121
114
|
});
|
|
122
115
|
|
|
@@ -115,10 +115,7 @@ function mapOverdue(crons: readonly ClockCronRecord[]): OverviewFinding[] {
|
|
|
115
115
|
}));
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
function mapDormant(
|
|
119
|
-
secrets: readonly VaultRecord[],
|
|
120
|
-
now: number,
|
|
121
|
-
): OverviewFinding[] {
|
|
118
|
+
function mapDormant(secrets: readonly VaultRecord[], now: number): OverviewFinding[] {
|
|
122
119
|
const dormant = dormantSecrets(secrets, now);
|
|
123
120
|
if (dormant.length === 0) return [];
|
|
124
121
|
return [
|
|
@@ -175,9 +172,7 @@ function mapPlugins(changes: readonly DiffChangeRecord[]): OverviewFinding[] {
|
|
|
175
172
|
}));
|
|
176
173
|
}
|
|
177
174
|
|
|
178
|
-
function mapAiBudget(
|
|
179
|
-
versions: readonly PromptVersionMetrics[],
|
|
180
|
-
): OverviewFinding[] {
|
|
175
|
+
function mapAiBudget(versions: readonly PromptVersionMetrics[]): OverviewFinding[] {
|
|
181
176
|
return overBudgetFindings(versions).map((f) => ({
|
|
182
177
|
id: `ai:budget:${f.prompt}@${f.version}`,
|
|
183
178
|
source: "ai" as const,
|
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
|
-
import {
|
|
7
|
-
computeSloBurns,
|
|
8
|
-
declaredSlos,
|
|
9
|
-
hasDeclaredSlos,
|
|
10
|
-
parseAvailability,
|
|
11
|
-
} from "./slo.ts";
|
|
6
|
+
import { computeSloBurns, declaredSlos, hasDeclaredSlos, parseAvailability } from "./slo.ts";
|
|
12
7
|
import {
|
|
13
8
|
OVERVIEW_BURN_RUNS,
|
|
14
9
|
OVERVIEW_DAY_ONE_INPUTS,
|
|
@@ -30,9 +25,10 @@ describe("declaredSlos", () => {
|
|
|
30
25
|
const slos = declaredSlos(OVERVIEW_MANIFEST);
|
|
31
26
|
expect(slos.some((s) => s.id === "flow:bookings.create")).toBe(true);
|
|
32
27
|
expect(slos.some((s) => s.id === "journey:book-a-flight")).toBe(true);
|
|
33
|
-
expect(
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
expect(slos.find((s) => s.id === "flow:bookings.create")?.tolerableErrorRate).toBeCloseTo(
|
|
29
|
+
0.001,
|
|
30
|
+
10,
|
|
31
|
+
);
|
|
36
32
|
});
|
|
37
33
|
|
|
38
34
|
test("day-one Manifest has no declared SLOs", () => {
|