@tangle-network/agent-app 0.45.54 → 0.45.56
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/README.md +1 -1
- package/dist/alerting/index.d.ts +5 -175
- package/dist/alerting/slack.d.ts +176 -0
- package/dist/app-auth/index.d.ts +14 -17
- package/dist/assets/index.d.ts +2 -504
- package/dist/assets/schema.d.ts +264 -0
- package/dist/assets/types.d.ts +237 -0
- package/dist/assistant/AssistantDock.d.ts +56 -0
- package/dist/assistant/AssistantHistory.d.ts +41 -0
- package/dist/assistant/AssistantPanel.d.ts +84 -0
- package/dist/assistant/ProposalCard.d.ts +41 -0
- package/dist/assistant/ResizeHandle.d.ts +19 -0
- package/dist/assistant/client-context.d.ts +20 -0
- package/dist/assistant/client.d.ts +117 -0
- package/dist/assistant/index.d.ts +19 -848
- package/dist/assistant/index.js +3 -3
- package/dist/assistant/launcher.d.ts +23 -0
- package/dist/assistant/persistence.d.ts +26 -0
- package/dist/assistant/presentation.d.ts +99 -0
- package/dist/assistant/provider-label.d.ts +7 -0
- package/dist/assistant/reducer.d.ts +130 -0
- package/dist/assistant/sse.d.ts +24 -0
- package/dist/assistant/time-ago.d.ts +6 -0
- package/dist/assistant/transcript.d.ts +97 -0
- package/dist/assistant/types.d.ts +291 -0
- package/dist/assistant/use-stick-to-bottom.d.ts +28 -0
- package/dist/assistant/useAssistantChat.d.ts +63 -0
- package/dist/assistant/useAssistantModels.d.ts +22 -0
- package/dist/assistant/useAssistantThreads.d.ts +47 -0
- package/dist/assistant/usePanelPrefs.d.ts +55 -0
- package/dist/billing/index.d.ts +19 -21
- package/dist/brand/index.d.ts +16 -10
- package/dist/brand-extraction/extract.d.ts +34 -0
- package/dist/brand-extraction/index.d.ts +12 -214
- package/dist/brand-extraction/map.d.ts +58 -0
- package/dist/brand-extraction/types.d.ts +119 -0
- package/dist/catalog/index.d.ts +11 -101
- package/dist/chat-react/composer-mode-controls.d.ts +14 -0
- package/dist/chat-react/entry-composer.d.ts +92 -0
- package/dist/chat-react/index.d.ts +22 -118
- package/dist/chat-react/index.js +2 -2
- package/dist/chat-react/types.d.ts +11 -0
- package/dist/chat-routes/attachment-store.d.ts +84 -0
- package/dist/chat-routes/attachment-upload.d.ts +89 -0
- package/dist/chat-routes/attachment-validation.d.ts +95 -0
- package/dist/chat-routes/binary-sniff.d.ts +45 -0
- package/dist/chat-routes/completed-sandbox-turn.d.ts +25 -0
- package/dist/chat-routes/detached-turn.d.ts +197 -0
- package/dist/chat-routes/dispatch-parts.d.ts +101 -0
- package/dist/chat-routes/draft-persistence.d.ts +189 -0
- package/dist/chat-routes/durable-projection.d.ts +18 -0
- package/dist/chat-routes/file-index.d.ts +115 -0
- package/dist/chat-routes/index.d.ts +25 -1840
- package/dist/chat-routes/index.js +6 -2
- package/dist/chat-routes/index.js.map +1 -1
- package/dist/chat-routes/model-failover-stream.d.ts +206 -0
- package/dist/chat-routes/promote-file-part.d.ts +84 -0
- package/dist/chat-routes/resolve-attachments.d.ts +72 -0
- package/dist/chat-routes/sandbox-producer.d.ts +146 -0
- package/dist/chat-routes/sandbox-turn-usage.d.ts +4 -0
- package/dist/{stale-turn-lock-DucQzvXu.d.ts → chat-routes/stale-turn-lock.d.ts} +7 -9
- package/dist/chat-routes/turn-routes.d.ts +540 -0
- package/dist/chat-routes/upload.d.ts +84 -0
- package/dist/{wire-DOZ-O6hD.d.ts → chat-routes/wire.d.ts} +41 -44
- package/dist/chat-store/core.d.ts +19 -0
- package/dist/chat-store/index.d.ts +22 -322
- package/dist/{parts-BqIHMdyu.d.ts → chat-store/parts.d.ts} +49 -47
- package/dist/chat-store/schema.d.ts +157 -0
- package/dist/chat-store/store.d.ts +177 -0
- package/dist/{chunk-PVP57G3S.js → chunk-2IFGVBNI.js} +2 -2
- package/dist/{chunk-MQO5ML66.js → chunk-KJ2Q27U7.js} +2 -2
- package/dist/{chunk-CCVG2TL6.js → chunk-YNMPMW3G.js} +64 -2
- package/dist/chunk-YNMPMW3G.js.map +1 -0
- package/dist/config/index.d.ts +13 -18
- package/dist/crypto/index.d.ts +10 -12
- package/dist/crypto/web-token.d.ts +22 -0
- package/dist/design-canvas/apply.d.ts +70 -0
- package/dist/design-canvas/drizzle-store.d.ts +29 -0
- package/dist/design-canvas/drizzle.d.ts +7 -575
- package/dist/{export-presets-mgVulRaV.d.ts → design-canvas/export-presets.d.ts} +18 -22
- package/dist/design-canvas/index.d.ts +22 -268
- package/dist/design-canvas/mcp-entry.d.ts +15 -0
- package/dist/design-canvas/mcp-handler.d.ts +34 -0
- package/dist/design-canvas/mcp-tools.d.ts +30 -0
- package/dist/{model-DnfO_PdJ.d.ts → design-canvas/model.d.ts} +33 -35
- package/dist/{operations-ByJ6yXOW.d.ts → design-canvas/operations.d.ts} +21 -25
- package/dist/design-canvas/schema.d.ts +558 -0
- package/dist/{store-CqfDtnPQ.d.ts → design-canvas/store.d.ts} +8 -12
- package/dist/design-canvas/templates.d.ts +72 -0
- package/dist/design-canvas/validate.d.ts +32 -0
- package/dist/design-canvas-react/components/BleedTrimOverlay.d.ts +22 -0
- package/dist/design-canvas-react/components/BrandKnot.d.ts +11 -0
- package/dist/design-canvas-react/components/CanvasEmptyState.d.ts +32 -0
- package/dist/design-canvas-react/components/CanvasInsertPanel.d.ts +53 -0
- package/dist/{lazy-DrkVyDpe.d.ts → design-canvas-react/components/DesignCanvas.d.ts} +27 -20
- package/dist/design-canvas-react/components/DesignCanvasEditor.d.ts +23 -0
- package/dist/design-canvas-react/components/ElementNode.d.ts +51 -0
- package/dist/design-canvas-react/components/ExportControl.d.ts +21 -0
- package/dist/design-canvas-react/components/GridLayer.d.ts +47 -0
- package/dist/design-canvas-react/components/InlineTextEditor.d.ts +25 -0
- package/dist/design-canvas-react/components/LayersPanel.d.ts +20 -0
- package/dist/design-canvas-react/components/PagesStrip.d.ts +34 -0
- package/dist/design-canvas-react/components/Rulers.d.ts +31 -0
- package/dist/design-canvas-react/components/SelectionLayer.d.ts +51 -0
- package/dist/design-canvas-react/components/SnapGuidesOverlay.d.ts +25 -0
- package/dist/design-canvas-react/components/Toolbar.d.ts +64 -0
- package/dist/design-canvas-react/components/Workspace.d.ts +92 -0
- package/dist/design-canvas-react/components/ZoomControls.d.ts +14 -0
- package/dist/design-canvas-react/components/glyphs.d.ts +46 -0
- package/dist/design-canvas-react/components/icon-button.d.ts +22 -0
- package/dist/design-canvas-react/components/index.d.ts +27 -0
- package/dist/design-canvas-react/components/layer-tree.d.ts +34 -0
- package/dist/design-canvas-react/components/ruler-math.d.ts +78 -0
- package/dist/design-canvas-react/components/transform-math.d.ts +168 -0
- package/dist/{command-stack-TNPWJCzW.d.ts → design-canvas-react/contracts.d.ts} +16 -63
- package/dist/design-canvas-react/engine/command-stack.d.ts +43 -0
- package/dist/design-canvas-react/engine/commands.d.ts +154 -0
- package/dist/design-canvas-react/engine/selection.d.ts +48 -0
- package/dist/design-canvas-react/engine/snap.d.ts +24 -0
- package/dist/design-canvas-react/engine/zoom-pan.d.ts +18 -0
- package/dist/design-canvas-react/engine.d.ts +21 -399
- package/dist/design-canvas-react/export-math.d.ts +104 -0
- package/dist/design-canvas-react/export.d.ts +89 -0
- package/dist/design-canvas-react/index.d.ts +16 -586
- package/dist/design-canvas-react/insert-builders.d.ts +61 -0
- package/dist/design-canvas-react/lazy.d.ts +21 -6
- package/dist/documents/docx.d.ts +50 -0
- package/dist/documents/extract.d.ts +87 -0
- package/dist/documents/index.d.ts +26 -232
- package/dist/documents/media-type.d.ts +33 -0
- package/dist/documents/pdf-inspector.d.ts +5 -9
- package/dist/{types-DrBidf3O.d.ts → documents/types.d.ts} +13 -15
- package/dist/documents/zip.d.ts +56 -0
- package/dist/eval/calibration.d.ts +106 -0
- package/dist/eval/index.d.ts +8 -116
- package/dist/eval-campaign/index.d.ts +11 -12
- package/dist/{trust-gate-Dcm5xSva.d.ts → eval-campaign/trust-gate.d.ts} +5 -9
- package/dist/forms/blank.d.ts +48 -0
- package/dist/forms/fill.d.ts +105 -0
- package/dist/forms/index.d.ts +58 -332
- package/dist/forms/registry.d.ts +115 -0
- package/dist/forms/verify.d.ts +58 -0
- package/dist/harness/index.d.ts +21 -19
- package/dist/intakes/api.d.ts +5 -11
- package/dist/{completion-CvcNUz07.d.ts → intakes/completion.d.ts} +7 -11
- package/dist/intakes/context-sufficiency.d.ts +113 -0
- package/dist/intakes/drizzle/schema.d.ts +338 -0
- package/dist/intakes/drizzle/store.d.ts +75 -0
- package/dist/intakes/drizzle.d.ts +12 -391
- package/dist/intakes/index.d.ts +23 -113
- package/dist/{model-C8U0HZxL.d.ts → intakes/model.d.ts} +15 -17
- package/dist/intakes-react/components/BrandMark.d.ts +10 -0
- package/dist/intakes-react/components/IntakeInterview.d.ts +15 -0
- package/dist/intakes-react/components/index.d.ts +1 -0
- package/dist/intakes-react/contracts.d.ts +42 -0
- package/dist/intakes-react/index.d.ts +12 -47
- package/dist/intakes-react/lazy.d.ts +9 -8
- package/dist/integrations/index.d.ts +10 -12
- package/dist/{contract-OxG_jVMx.d.ts → interactions/contract.d.ts} +40 -42
- package/dist/interactions/index.d.ts +16 -256
- package/dist/interactions/route.d.ts +151 -0
- package/dist/interactions/sidecar.d.ts +100 -0
- package/dist/knowledge/index.d.ts +7 -11
- package/dist/knowledge-loop/index.d.ts +13 -20
- package/dist/legibility/checks/empty-state.d.ts +59 -0
- package/dist/legibility/checks/reachability.d.ts +103 -0
- package/dist/legibility/checks/silent-failure.d.ts +57 -0
- package/dist/legibility/checks/success.d.ts +38 -0
- package/dist/legibility/checks/vocabulary.d.ts +65 -0
- package/dist/legibility/cli-args.d.ts +30 -0
- package/dist/legibility/cli.d.ts +25 -0
- package/dist/legibility/index.d.ts +10 -530
- package/dist/legibility/report.d.ts +22 -0
- package/dist/legibility/scan.d.ts +29 -0
- package/dist/legibility/source.d.ts +132 -0
- package/dist/legibility/suppress.d.ts +36 -0
- package/dist/legibility/types.d.ts +168 -0
- package/dist/legibility/walk-sources.d.ts +21 -0
- package/dist/{agent-activity-C8ZG0F0M.d.ts → missions/agent-activity.d.ts} +3 -5
- package/dist/missions/engine.d.ts +251 -0
- package/dist/missions/events.d.ts +195 -0
- package/dist/missions/index.d.ts +12 -765
- package/dist/missions/plan-parse.d.ts +50 -0
- package/dist/missions/service.d.ts +265 -0
- package/dist/{failover-D-3UXXTb.d.ts → model-resolution/failover.d.ts} +10 -12
- package/dist/model-resolution/index.d.ts +15 -18
- package/dist/object-store/index.d.ts +15 -17
- package/dist/openui/action.d.ts +54 -0
- package/dist/openui/authoring.d.ts +25 -0
- package/dist/openui/index.d.ts +24 -206
- package/dist/openui/route.d.ts +124 -0
- package/dist/openui/segments.d.ts +71 -0
- package/dist/openui/values.d.ts +82 -0
- package/dist/openui-react/index.d.ts +9 -13
- package/dist/peer-floors/check.d.ts +9 -190
- package/dist/peer-floors/cli.d.ts +2 -3
- package/dist/peer-floors/dependency-source.d.ts +178 -0
- package/dist/plans/index.d.ts +13 -14
- package/dist/{billing-BuNlaKlE.d.ts → platform/billing.d.ts} +28 -32
- package/dist/platform/guards.d.ts +79 -0
- package/dist/platform/hub.d.ts +107 -0
- package/dist/platform/index.d.ts +7 -112
- package/dist/{sso-Cm00S61u.d.ts → platform/sso.d.ts} +15 -97
- package/dist/preflight/cli.d.ts +3 -6
- package/dist/preflight/index.d.ts +16 -18
- package/dist/preset-cloudflare/headers.d.ts +12 -0
- package/dist/preset-cloudflare/index.d.ts +22 -74
- package/dist/preset-cloudflare/workflow-instance.d.ts +35 -0
- package/dist/profile/budget.d.ts +72 -0
- package/dist/profile/fingerprint.d.ts +65 -0
- package/dist/profile/index.d.ts +27 -19
- package/dist/prompt/index.d.ts +3 -5
- package/dist/record/drizzle/schema.d.ts +488 -0
- package/dist/record/drizzle/store.d.ts +224 -0
- package/dist/record/drizzle.d.ts +10 -679
- package/dist/record/fold.d.ts +99 -0
- package/dist/record/index.d.ts +13 -13
- package/dist/{fold-DACU7gtf.d.ts → record/model.d.ts} +22 -124
- package/dist/record/ulid.d.ts +12 -0
- package/dist/redact/index.d.ts +14 -16
- package/dist/run/index.d.ts +11 -16
- package/dist/runtime/agent.d.ts +23 -0
- package/dist/runtime/certified-delivery.d.ts +57 -0
- package/dist/runtime/index.d.ts +17 -367
- package/dist/runtime/loop.d.ts +58 -0
- package/dist/runtime/model-catalog.d.ts +103 -0
- package/dist/{model-CdCDfBA9.d.ts → runtime/model.d.ts} +25 -27
- package/dist/runtime/openai-stream.d.ts +126 -0
- package/dist/runtime/surface-profile.d.ts +115 -0
- package/dist/sandbox/binary-read.d.ts +63 -0
- package/dist/sandbox/diagnostics.d.ts +69 -0
- package/dist/sandbox/index.d.ts +103 -1085
- package/dist/sandbox/model.d.ts +179 -0
- package/dist/sandbox/outcome.d.ts +10 -0
- package/dist/sandbox/prewarm-claim-d1.d.ts +80 -0
- package/dist/sandbox/prewarm.d.ts +193 -0
- package/dist/sandbox/recovery.d.ts +216 -0
- package/dist/sandbox/terminal-connection.d.ts +145 -0
- package/dist/sandbox/workspace-sandbox-manager.d.ts +44 -0
- package/dist/sequences/apply.d.ts +54 -0
- package/dist/sequences/captions.d.ts +91 -0
- package/dist/sequences/drizzle-store.d.ts +36 -0
- package/dist/sequences/drizzle.d.ts +7 -1252
- package/dist/sequences/exports.d.ts +138 -0
- package/dist/sequences/index.d.ts +19 -340
- package/dist/sequences/mcp-entry.d.ts +15 -0
- package/dist/sequences/mcp-handler.d.ts +39 -0
- package/dist/sequences/mcp-tools.d.ts +47 -0
- package/dist/{store-B7LLlk9p.d.ts → sequences/model.d.ts} +26 -110
- package/dist/sequences/operations.d.ts +126 -0
- package/dist/sequences/schema.d.ts +1231 -0
- package/dist/sequences/store.d.ts +81 -0
- package/dist/sequences/validate.d.ts +98 -0
- package/dist/sequences-react/components/BrandMark.d.ts +10 -0
- package/dist/sequences-react/components/PreviewCanvas.d.ts +26 -0
- package/dist/sequences-react/components/SnapIndicatorLine.d.ts +11 -0
- package/dist/sequences-react/components/TimelineClipChip.d.ts +80 -0
- package/dist/sequences-react/components/TimelineEditor.d.ts +44 -0
- package/dist/sequences-react/components/TimelineEmptyState.d.ts +21 -0
- package/dist/sequences-react/components/TimelineGhostLanes.d.ts +14 -0
- package/dist/sequences-react/components/TimelinePlayhead.d.ts +11 -0
- package/dist/sequences-react/components/TimelineRuler.d.ts +16 -0
- package/dist/sequences-react/components/TimelineSmallScreenGate.d.ts +12 -0
- package/dist/sequences-react/components/TimelineTrackRow.d.ts +51 -0
- package/dist/sequences-react/components/ZoomControl.d.ts +15 -0
- package/dist/sequences-react/components/composite-command.d.ts +8 -0
- package/dist/sequences-react/components/glyphs.d.ts +26 -0
- package/dist/sequences-react/components/index.d.ts +31 -0
- package/dist/sequences-react/components/interaction-math.d.ts +103 -0
- package/dist/sequences-react/contracts.d.ts +187 -0
- package/dist/sequences-react/engine/command-stack.d.ts +18 -0
- package/dist/sequences-react/engine/commands.d.ts +146 -0
- package/dist/sequences-react/engine/playback.d.ts +18 -0
- package/dist/sequences-react/engine/snap.d.ts +29 -0
- package/dist/sequences-react/engine/zoom.d.ts +29 -0
- package/dist/sequences-react/index.d.ts +20 -880
- package/dist/sequences-react/lazy.d.ts +8 -0
- package/dist/sequences-react/media/frame-provider.d.ts +70 -0
- package/dist/sequences-react/media/transcription.d.ts +33 -0
- package/dist/sequences-react/media/waveform.d.ts +34 -0
- package/dist/session-shell/index.d.ts +31 -204
- package/dist/session-shell/nav-guard.d.ts +170 -0
- package/dist/session-shell/path.d.ts +19 -0
- package/dist/signoff/cli.d.ts +4 -7
- package/dist/signoff/config.d.ts +12 -0
- package/dist/signoff/exec.d.ts +44 -0
- package/dist/signoff/index.d.ts +56 -14
- package/dist/signoff/invoked-as-script.d.ts +25 -0
- package/dist/signoff/node-version.d.ts +50 -0
- package/dist/signoff/proof-attach.d.ts +88 -0
- package/dist/signoff/proof-cli.d.ts +1 -0
- package/dist/signoff/proof-fixture.d.ts +13 -0
- package/dist/signoff/proof-from-report.d.ts +22 -0
- package/dist/signoff/proof-git.d.ts +57 -0
- package/dist/signoff/proof-record.d.ts +202 -0
- package/dist/signoff/proof-verify.d.ts +103 -0
- package/dist/signoff/proof.d.ts +35 -310
- package/dist/signoff/report.d.ts +7 -0
- package/dist/{run-D80hoLKh.d.ts → signoff/run.d.ts} +3 -6
- package/dist/signoff/schedule.d.ts +55 -0
- package/dist/signoff/seeds.d.ts +50 -0
- package/dist/signoff/store.d.ts +22 -0
- package/dist/{types-Bd6uW9vQ.d.ts → signoff/types.d.ts} +15 -17
- package/dist/signoff/workflow-pin.d.ts +56 -0
- package/dist/signoff/workspace.d.ts +40 -0
- package/dist/skills/index.d.ts +28 -32
- package/dist/skills-placement/index.d.ts +7 -11
- package/dist/spend/budget.d.ts +123 -0
- package/dist/spend/ceiling.d.ts +51 -0
- package/dist/spend/cli-args.d.ts +20 -0
- package/dist/spend/cli.d.ts +1 -0
- package/dist/spend/fixtures/incident-parked-time.d.ts +55 -0
- package/dist/spend/index.d.ts +38 -1144
- package/dist/spend/liveness.d.ts +131 -0
- package/dist/spend/ownership.d.ts +87 -0
- package/dist/spend/reconcile.d.ts +109 -0
- package/dist/spend/reference.d.ts +42 -0
- package/dist/spend/report.d.ts +12 -0
- package/dist/spend/store.d.ts +123 -0
- package/dist/spend/types.d.ts +466 -0
- package/dist/store/index.d.ts +10 -12
- package/dist/stories/app-shell/fixtures.d.ts +43 -0
- package/dist/stories/app-shell/shell.d.ts +81 -0
- package/dist/stories/assistant/fixtures.d.ts +73 -0
- package/dist/stories/chat/fixtures.d.ts +70 -0
- package/dist/stories/chat/markdown.d.ts +11 -0
- package/dist/stories/chat/run-drill-in.d.ts +19 -0
- package/dist/stories/chat-controls/fixtures.d.ts +116 -0
- package/dist/stories/design-canvas/fixtures.d.ts +57 -0
- package/dist/stories/fixtures/canvas.d.ts +10 -0
- package/dist/stories/fixtures/catalog.d.ts +7 -0
- package/dist/stories/fixtures/chat.d.ts +39 -0
- package/dist/stories/fixtures/index.d.ts +4 -0
- package/dist/stories/fixtures/sequences.d.ts +17 -0
- package/dist/stories/panels/fixtures.d.ts +63 -0
- package/dist/stories/sequences/fixtures.d.ts +30 -0
- package/dist/stories/studio/fixtures.d.ts +22 -0
- package/dist/stream/index.d.ts +10 -56
- package/dist/{stream-normalizer-DKRxyVlZ.d.ts → stream/stream-normalizer.d.ts} +23 -26
- package/dist/{turn-buffer-COMQUwO2.d.ts → stream/turn-buffer.d.ts} +21 -23
- package/dist/stream/turn-identity.d.ts +49 -0
- package/dist/studio/generation.d.ts +179 -0
- package/dist/studio/index.d.ts +12 -181
- package/dist/studio-react/avatar-composer.d.ts +8 -0
- package/dist/studio-react/composer-hero.d.ts +12 -0
- package/dist/studio-react/composer-shell.d.ts +18 -0
- package/dist/studio-react/generation-card.d.ts +9 -0
- package/dist/studio-react/generation-detail-modal.d.ts +11 -0
- package/dist/studio-react/generation-detail.d.ts +6 -0
- package/dist/studio-react/generation-grid.d.ts +15 -0
- package/dist/studio-react/image-composer.d.ts +8 -0
- package/dist/studio-react/index.d.ts +32 -245
- package/dist/studio-react/library-drawer.d.ts +12 -0
- package/dist/studio-react/library-panel.d.ts +15 -0
- package/dist/studio-react/publish-package-composer.d.ts +18 -0
- package/dist/studio-react/result-canvas.d.ts +6 -0
- package/dist/studio-react/speech-composer.d.ts +4 -0
- package/dist/studio-react/studio-header.d.ts +5 -0
- package/dist/studio-react/studio-sheet.d.ts +12 -0
- package/dist/studio-react/studio-workspace.d.ts +23 -0
- package/dist/studio-react/transcription-composer.d.ts +12 -0
- package/dist/studio-react/type-config.d.ts +11 -0
- package/dist/studio-react/use-studio-generations.d.ts +20 -0
- package/dist/studio-react/video-composer.d.ts +10 -0
- package/dist/tangle/index.d.ts +7 -9
- package/dist/teams/drizzle/access.d.ts +82 -0
- package/dist/{invitations-schema-_fI7HkJP.d.ts → teams/drizzle/invitations-schema.d.ts} +39 -27
- package/dist/teams/drizzle/personal-organization.d.ts +41 -0
- package/dist/{access-490O6aOU.d.ts → teams/drizzle/schema.d.ts} +57 -122
- package/dist/teams/drizzle.d.ts +12 -44
- package/dist/teams/index.d.ts +20 -44
- package/dist/teams/invitations-api.d.ts +17 -21
- package/dist/{invitations-DoYMvXea.d.ts → teams/invitations.d.ts} +14 -18
- package/dist/teams/invite.d.ts +42 -0
- package/dist/teams/members-api.d.ts +12 -16
- package/dist/teams/resend.d.ts +3 -13
- package/dist/{roles-B4nU3jDi.d.ts → teams/roles.d.ts} +18 -20
- package/dist/teams-react/components/BrandMark.d.ts +10 -0
- package/dist/teams-react/components/InvitationsPanel.d.ts +13 -0
- package/dist/teams-react/components/InviteAcceptPage.d.ts +10 -0
- package/dist/teams-react/components/MembersPanel.d.ts +14 -0
- package/dist/teams-react/components/RoleSelect.d.ts +17 -0
- package/dist/teams-react/components/index.d.ts +3 -0
- package/dist/teams-react/contracts.d.ts +134 -0
- package/dist/teams-react/index.d.ts +12 -143
- package/dist/teams-react/lazy.d.ts +11 -11
- package/dist/test-setup.d.ts +1 -0
- package/dist/theme/index.d.ts +6 -104
- package/dist/theme/tailwind-preset.d.ts +1 -2
- package/dist/theme/theme.d.ts +106 -0
- package/dist/theme-contract/cli.d.ts +21 -0
- package/dist/theme-contract/index.d.ts +4 -6
- package/dist/{auth-BYtiazA4.d.ts → tools/auth.d.ts} +8 -11
- package/dist/tools/capability.d.ts +54 -0
- package/dist/tools/dispatch.d.ts +37 -0
- package/dist/tools/errors.d.ts +8 -0
- package/dist/tools/gating.d.ts +62 -0
- package/dist/tools/http.d.ts +27 -0
- package/dist/tools/index.d.ts +12 -217
- package/dist/{mcp-rpc-DYwPlYbZ.d.ts → tools/mcp-rpc.d.ts} +7 -9
- package/dist/{mcp-xxoZZfor.d.ts → tools/mcp.d.ts} +14 -16
- package/dist/tools/openai.d.ts +28 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/runtime.d.ts +22 -0
- package/dist/{types-B25Mib1r.d.ts → tools/types.d.ts} +15 -83
- package/dist/{flow-types-CJxEmaRy.d.ts → trace/flow-types.d.ts} +2 -4
- package/dist/trace/index.d.ts +11 -148
- package/dist/trace/mission-flow.d.ts +82 -0
- package/dist/trace/mission-trace.d.ts +52 -0
- package/dist/turn-health/classify.d.ts +207 -0
- package/dist/turn-health/index.d.ts +29 -637
- package/dist/turn-health/lifecycle.d.ts +75 -0
- package/dist/turn-health/sink.d.ts +122 -0
- package/dist/turn-health/sweep.d.ts +245 -0
- package/dist/turn-stream/adapters.d.ts +257 -0
- package/dist/turn-stream/core.d.ts +293 -0
- package/dist/turn-stream/do.d.ts +144 -0
- package/dist/turn-stream/index.d.ts +62 -738
- package/dist/turn-stream/memory.d.ts +41 -0
- package/dist/vault/ConfirmDialog.d.ts +22 -0
- package/dist/vault/VaultPane.d.ts +15 -0
- package/dist/{VaultPane-BDP6SB_K.d.ts → vault/contracts.d.ts} +15 -22
- package/dist/vault/index.d.ts +15 -22
- package/dist/vault/lazy.d.ts +9 -7
- package/dist/vault/server.d.ts +8 -10
- package/dist/web/free-route-limit.d.ts +187 -0
- package/dist/web/index.d.ts +15 -207
- package/dist/{rate-limit-BOVmJRXZ.d.ts → web/rate-limit.d.ts} +3 -5
- package/dist/web-react/agent-session-controls.d.ts +105 -0
- package/dist/web-react/async/async-view.d.ts +69 -0
- package/dist/web-react/async/index.d.ts +13 -305
- package/dist/web-react/async/state.d.ts +107 -0
- package/dist/web-react/async/use-async-resource.d.ts +41 -0
- package/dist/web-react/async/use-confirmed-mutation.d.ts +90 -0
- package/dist/web-react/brand-mark.d.ts +11 -0
- package/dist/web-react/chat-attachments.d.ts +21 -0
- package/dist/web-react/chat-composer.d.ts +174 -0
- package/dist/web-react/chat-interactions.d.ts +1 -0
- package/dist/web-react/chat-mentions.d.ts +48 -0
- package/dist/web-react/chat-stream.d.ts +106 -0
- package/dist/web-react/class-names.d.ts +10 -0
- package/dist/web-react/controls.d.ts +265 -0
- package/dist/web-react/durable-chat-cards.d.ts +40 -0
- package/dist/web-react/durable-interaction-submit.d.ts +22 -0
- package/dist/web-react/durable-plan-card.d.ts +13 -0
- package/dist/web-react/durable-plan-flow.d.ts +77 -0
- package/dist/web-react/harness-glyphs.d.ts +28 -0
- package/dist/web-react/index.d.ts +80 -2347
- package/dist/web-react/index.js +3 -3
- package/dist/web-react/inert.d.ts +39 -0
- package/dist/web-react/insight-card.d.ts +203 -0
- package/dist/web-react/interaction-card-support.d.ts +115 -0
- package/dist/web-react/interaction-plan-card.d.ts +39 -0
- package/dist/web-react/interaction-question-card.d.ts +100 -0
- package/dist/web-react/message-attachments.d.ts +56 -0
- package/dist/web-react/mission-activity.d.ts +96 -0
- package/dist/web-react/motion.d.ts +43 -0
- package/dist/web-react/provenance-model.d.ts +195 -0
- package/dist/web-react/provenance.d.ts +82 -0
- package/dist/web-react/provider-logo.d.ts +14 -0
- package/dist/web-react/record-grid-model.d.ts +257 -0
- package/dist/web-react/record-grid.d.ts +108 -0
- package/dist/web-react/sandbox-terminal.d.ts +90 -0
- package/dist/web-react/seat-paywall.d.ts +47 -0
- package/dist/web-react/session-history.d.ts +196 -0
- package/dist/web-react/smooth-text.d.ts +29 -0
- package/dist/web-react/sparkline.d.ts +150 -0
- package/dist/web-react/terminal.d.ts +1 -92
- package/dist/web-react/use-chat-interactions.d.ts +78 -0
- package/dist/web-react/use-composer-attachments.d.ts +111 -0
- package/dist/web-react/use-file-mentions.d.ts +94 -0
- package/dist/web-react/work-product.d.ts +105 -0
- package/dist/work-product/claim-support.d.ts +288 -0
- package/dist/work-product/index.d.ts +16 -849
- package/dist/work-product/provenance.d.ts +61 -0
- package/dist/{queue-VTBA5ONX.d.ts → work-product/queue.d.ts} +10 -12
- package/dist/work-product/quote.d.ts +139 -0
- package/dist/work-product/route.d.ts +88 -0
- package/dist/work-product/service.d.ts +123 -0
- package/dist/work-product/tools.d.ts +144 -0
- package/dist/{types-CCeYywdS.d.ts → work-product/types.d.ts} +29 -31
- package/dist/work-product-react/index.d.ts +19 -8
- package/dist/workspace-react/index.d.ts +8 -11
- package/package.json +4 -3
- package/dist/agent-session-controls-CmlXwp_H.d.ts +0 -384
- package/dist/apply-6wlMOLf8.d.ts +0 -280
- package/dist/attachment-validation-BfJDBU1g.d.ts +0 -261
- package/dist/budget-BOucfcb_.d.ts +0 -142
- package/dist/chunk-CCVG2TL6.js.map +0 -1
- package/dist/values-C7RidJuI.d.ts +0 -156
- /package/dist/{chunk-PVP57G3S.js.map → chunk-2IFGVBNI.js.map} +0 -0
- /package/dist/{chunk-MQO5ML66.js.map → chunk-KJ2Q27U7.js.map} +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { SpendBoxLiveness, SpendBoxRecord, SpendExpectationSummary, SpendReport, SpendWindow } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Expectation liveness: what the product BELIEVES it should have been billed for.
|
|
4
|
+
*
|
|
5
|
+
* ## The hole this closes
|
|
6
|
+
*
|
|
7
|
+
* `reconcileSpend` compares settlements against expectations, and every one of
|
|
8
|
+
* its rules is driven by a settlement row. That makes it able to answer exactly
|
|
9
|
+
* one direction of the question:
|
|
10
|
+
*
|
|
11
|
+
* > were we billed for something we did not ask for, or for more than allowed?
|
|
12
|
+
*
|
|
13
|
+
* It cannot answer the other direction — *were we NOT billed for something we
|
|
14
|
+
* DID ask for* — because with no row there is nothing to iterate. Three real
|
|
15
|
+
* shapes fall straight through that hole and every one of them renders as a
|
|
16
|
+
* clean bill:
|
|
17
|
+
*
|
|
18
|
+
* - the expectation ledger names no box, so the pass examines nobody → `ok:true`;
|
|
19
|
+
* - the billing endpoint quietly starts returning zero rows → `ok:true`,
|
|
20
|
+
* `rowsExamined:0`;
|
|
21
|
+
* - a stale or rotated key list excludes every box → `ok:true` with everything
|
|
22
|
+
* `foreign`.
|
|
23
|
+
*
|
|
24
|
+
* In all three the check stopped checking while looking green. That is the exact
|
|
25
|
+
* failure class the module exists to prevent, reproduced inside the module.
|
|
26
|
+
*
|
|
27
|
+
* ## The discriminator, and why it is not a new store
|
|
28
|
+
*
|
|
29
|
+
* The expectation ledger already records the only fact needed: when the product
|
|
30
|
+
* first saw a box (`createdAt`), the last work it observed (`lastActivityAt`),
|
|
31
|
+
* and any stop or delete it knows about. Those are precisely the inputs
|
|
32
|
+
* {@link computeExpectedCeiling} already folds into a horizon — the latest
|
|
33
|
+
* instant a box could still have been billable. So a box's LIVE INTERVAL is
|
|
34
|
+
* `[createdAt, horizon]`, derived from the same fold the ceiling uses rather
|
|
35
|
+
* than from a second, drift-prone definition of "running".
|
|
36
|
+
*
|
|
37
|
+
* A box whose live interval overlaps the reconciliation window is a box the
|
|
38
|
+
* product expected to be billed for. The absence of a settlement against it is
|
|
39
|
+
* then a first-class outcome, not silence.
|
|
40
|
+
*
|
|
41
|
+
* ## Why the grace period is load-bearing
|
|
42
|
+
*
|
|
43
|
+
* Settlement lags provisioning. A box that came up ninety seconds before the
|
|
44
|
+
* window closed has no settlement yet and never should have — expecting one
|
|
45
|
+
* would manufacture a finding out of the platform's ordinary queue behaviour.
|
|
46
|
+
* So expectation is asserted only for boxes with at least
|
|
47
|
+
* {@link DEFAULT_EXPECTATION_GRACE_MS} of live time INSIDE the window, which is
|
|
48
|
+
* the platform's own declared-normal settlement lag (see the constant).
|
|
49
|
+
*
|
|
50
|
+
* The asymmetry the rest of the module runs on holds here too, but it points the
|
|
51
|
+
* other way and that is deliberate: an over-tight liveness derivation produces a
|
|
52
|
+
* false ALARM about the check, never a false clean bill. Nothing in this file
|
|
53
|
+
* can make a report cleaner than it would otherwise be.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* How much live time a box needs inside the window before a settlement is
|
|
57
|
+
* EXPECTED for it. 15 minutes.
|
|
58
|
+
*
|
|
59
|
+
* Same number and same justification as {@link DEFAULT_CEILING_TOLERANCE_MS},
|
|
60
|
+
* arrived at from the other side: the platform's runbook clears a compute
|
|
61
|
+
* settlement incident when `/health computeSettlement.oldestAgeSeconds` is "back
|
|
62
|
+
* under 900", so 900 s is lag the platform has already declared normal. A box
|
|
63
|
+
* live for less than that inside the window may legitimately have settled
|
|
64
|
+
* nothing yet, and demanding a row for it would report the platform's own queue
|
|
65
|
+
* as a defect.
|
|
66
|
+
*
|
|
67
|
+
* A caller parameter, because a product reconciling a very short window must
|
|
68
|
+
* shrink it or the window expects nothing at all.
|
|
69
|
+
*/
|
|
70
|
+
export declare const DEFAULT_EXPECTATION_GRACE_MS = 900000;
|
|
71
|
+
/** Options for {@link boxLivenessInWindow}. */
|
|
72
|
+
export interface BoxLivenessOptions {
|
|
73
|
+
/** Live ms inside the window before a settlement is expected. Default {@link DEFAULT_EXPECTATION_GRACE_MS}. */
|
|
74
|
+
readonly graceMs?: number;
|
|
75
|
+
}
|
|
76
|
+
/** Reject a window that cannot be reconciled, rather than examining nobody inside it. */
|
|
77
|
+
export declare function assertSpendWindow(window: SpendWindow): void;
|
|
78
|
+
/**
|
|
79
|
+
* One box's live interval, and whether the product should have been billed for
|
|
80
|
+
* it inside this window.
|
|
81
|
+
*
|
|
82
|
+
* The live interval's end is {@link computeExpectedCeiling}'s horizon evaluated
|
|
83
|
+
* at the window's end — the SAME derivation the ceiling check uses, so a box
|
|
84
|
+
* cannot be considered live here and dead there. `toleranceMs` is zero because
|
|
85
|
+
* tolerance is slack allowed to the PLATFORM's clock, and widening a box's life
|
|
86
|
+
* by it would expect settlements for boxes that were already gone.
|
|
87
|
+
*/
|
|
88
|
+
export declare function boxLivenessInWindow(record: SpendBoxRecord, window: SpendWindow, options?: BoxLivenessOptions): SpendBoxLiveness;
|
|
89
|
+
/** Why {@link assessAllExcluded} answered the way it did. */
|
|
90
|
+
export type AllExcludedBasis =
|
|
91
|
+
/** Not every box was excluded — the pass examined some of this product's own. */
|
|
92
|
+
'not-all-excluded'
|
|
93
|
+
/** Boxes of this product's were live in the window, so an all-foreign pass is wrong. */
|
|
94
|
+
| 'expected-boxes-live'
|
|
95
|
+
/** Expectation was declared and nothing was live: an idle product, not a defect. */
|
|
96
|
+
| 'nothing-expected'
|
|
97
|
+
/** No expectation was declared, so the question cannot be answered. Fails closed. */
|
|
98
|
+
| 'not-declared';
|
|
99
|
+
/** {@link assessAllExcluded}'s verdict, with the reason a pager message needs. */
|
|
100
|
+
export interface AllExcludedAssessment {
|
|
101
|
+
/** True when the caller should raise. */
|
|
102
|
+
readonly pathological: boolean;
|
|
103
|
+
readonly basis: AllExcludedBasis;
|
|
104
|
+
/** One sentence naming the numbers behind the verdict. */
|
|
105
|
+
readonly reason: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Should "we saw settlements but none of them were ours" page a human?
|
|
109
|
+
*
|
|
110
|
+
* Consumers raise this pathology on `boxesExamined > 0 && ownedBoxes === 0`.
|
|
111
|
+
* That shape has two completely different causes and the naive test cannot tell
|
|
112
|
+
* them apart:
|
|
113
|
+
*
|
|
114
|
+
* - an ownership rule that has gone stale — a rotated key, a new deployment key
|
|
115
|
+
* nobody added — so every one of the product's OWN boxes now reads as a
|
|
116
|
+
* sibling's. The check has stopped checking.
|
|
117
|
+
* - a product that was legitimately idle while a sibling settled on the same
|
|
118
|
+
* wallet. Nothing is wrong, and paging on it pages EVERY day the product is
|
|
119
|
+
* quiet, which is how a real alert gets muted.
|
|
120
|
+
*
|
|
121
|
+
* The discriminator is expectation liveness: did this product have a box alive
|
|
122
|
+
* during the window? Only then is an all-excluded pass pathological.
|
|
123
|
+
*
|
|
124
|
+
* Fails closed when no expectation was declared — that is today's behaviour, and
|
|
125
|
+
* a pass that cannot answer the question must not answer it optimistically. The
|
|
126
|
+
* `reason` says so, and the fix (declare `window`, implement `listLiveBetween`)
|
|
127
|
+
* is in the string a human reads.
|
|
128
|
+
*/
|
|
129
|
+
export declare function assessAllExcluded(report: SpendReport): AllExcludedAssessment;
|
|
130
|
+
/** The expectation summary a pass that declared none reports. Loud, never absent. */
|
|
131
|
+
export declare function undeclaredExpectation(graceMs: number): SpendExpectationSummary;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { SettlementRow, SpendOwnershipRule, SpendOwnershipVerdict } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Which settlements belong to the product running the reconciliation.
|
|
4
|
+
*
|
|
5
|
+
* ## The problem this module is the answer to
|
|
6
|
+
*
|
|
7
|
+
* A product fetches its settled rows from `/v1/billing/transactions`, scoped to
|
|
8
|
+
* the BILLING OWNER — the wallet whose key paid. `product: 'sandbox'` narrows
|
|
9
|
+
* that to compute, but `sandbox` is the PLATFORM's service taxonomy: every
|
|
10
|
+
* consumer app's box compute wears it. So a Tangle account running two of our
|
|
11
|
+
* products hands each product's reconciliation the other product's boxes, and
|
|
12
|
+
* `unknown-box` — correctly, by its own rule — reports one finding per sibling
|
|
13
|
+
* box. Two products on one wallet make each other's spend check useless.
|
|
14
|
+
*
|
|
15
|
+
* ## Why the obvious fix is the wrong fix
|
|
16
|
+
*
|
|
17
|
+
* The obvious fix is to reconcile only the boxes already in the product's
|
|
18
|
+
* expectation ledger. That removes the false findings and removes the check:
|
|
19
|
+
* `unknown-box` exists to catch "we were billed for a box we never asked for",
|
|
20
|
+
* which is the 2026-08-05 incident's day-one signature and the ONLY thing a
|
|
21
|
+
* product with no lifecycle bookkeeping can catch at all. Filtering to the
|
|
22
|
+
* ledger makes a phantom charge unrepresentable — the ledger's own contents
|
|
23
|
+
* would define the answer.
|
|
24
|
+
*
|
|
25
|
+
* So the residue — settlements against boxes with no ledger record — has to be
|
|
26
|
+
* SPLIT, not dropped. A sibling's box and a phantom charge are indistinguishable
|
|
27
|
+
* unless something outside the product's own bookkeeping tells them apart.
|
|
28
|
+
*
|
|
29
|
+
* ## What can tell them apart
|
|
30
|
+
*
|
|
31
|
+
* Exactly one field on a settlement row, and it is not the sandbox id. The
|
|
32
|
+
* platform mints that id as `sandbox-<12 hex>` — a hash of (owner, idempotency
|
|
33
|
+
* key) — so a product's own box naming never reaches the ledger row, and the
|
|
34
|
+
* charge's `description` carries only the resource spec. What does survive is
|
|
35
|
+
* `credit_transactions.key_id`: the platform API key the box was created under,
|
|
36
|
+
* stamped from the box's own creation metadata at settlement and filterable on
|
|
37
|
+
* the transactions endpoint. Each product deploys with its own key, so the key
|
|
38
|
+
* is the product's billing identity as the PLATFORM recorded it — not as the
|
|
39
|
+
* product asserts it after the fact.
|
|
40
|
+
*
|
|
41
|
+
* That asymmetry is what makes the split safe. A product cannot widen its own
|
|
42
|
+
* claim by claiming; it can only recognise a stamp the platform already wrote.
|
|
43
|
+
*
|
|
44
|
+
* ## The three rules that keep the detection intact
|
|
45
|
+
*
|
|
46
|
+
* 1. **A recorded box is never excluded.** Ownership is consulted only for
|
|
47
|
+
* boxes with no ledger record. A rule that is wrong or over-narrow therefore
|
|
48
|
+
* cannot hide an `over-ceiling` finding on a box the product recorded — the
|
|
49
|
+
* incident's own 23 findings survive any rule at all.
|
|
50
|
+
* 2. **Undecidable fails closed.** A row with no key attribution is `mine`, so
|
|
51
|
+
* an unattributable charge on a shared wallet is reported. Silence is never
|
|
52
|
+
* the answer to "I don't know."
|
|
53
|
+
* 3. **A box is claimed if ANY of its rows claims it.** The fold is
|
|
54
|
+
* `mine > undecidable > foreign`, which is the module's standing asymmetry:
|
|
55
|
+
* every derivation error pushes toward a false alarm, never toward a missed
|
|
56
|
+
* charge.
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Claim every settlement the platform stamped with one of these API keys.
|
|
60
|
+
*
|
|
61
|
+
* The shipped rule, because it is the only one built on a field the PLATFORM
|
|
62
|
+
* writes. Give each product its own platform key and this separates them
|
|
63
|
+
* exactly; give two products the same key and no consumer-side rule can tell
|
|
64
|
+
* them apart, because after settlement there is nothing left that differs — the
|
|
65
|
+
* fix then is a second key, not a cleverer predicate.
|
|
66
|
+
*
|
|
67
|
+
* A row with no `keyId` (a legacy row, or an export that drops the column) is
|
|
68
|
+
* `undecidable`, never `foreign`: the absence of an attribution is not evidence
|
|
69
|
+
* that the charge is someone else's.
|
|
70
|
+
*
|
|
71
|
+
* @param keyIds The product's own platform API key ids. Must be non-empty — a
|
|
72
|
+
* rule that owns nothing would classify every settlement as another product's
|
|
73
|
+
* and report a clean bill for an account nobody is checking.
|
|
74
|
+
*/
|
|
75
|
+
export declare function ownedByBillingKeys(keyIds: readonly string[]): SpendOwnershipRule;
|
|
76
|
+
/**
|
|
77
|
+
* One box's verdict, folded over every row that settled against it.
|
|
78
|
+
*
|
|
79
|
+
* `mine` wins over `undecidable`, which wins over `foreign`: it takes one row
|
|
80
|
+
* attributable to this product to make the box this product's problem, and one
|
|
81
|
+
* unattributable row to stop the box being excluded. Both directions push
|
|
82
|
+
* toward reporting, which is the only direction that cannot lose money.
|
|
83
|
+
*
|
|
84
|
+
* Exported because a product auditing its own scoping wants the same answer the
|
|
85
|
+
* reconciler reached, not a re-derivation of it.
|
|
86
|
+
*/
|
|
87
|
+
export declare function decideBoxOwnership(rule: SpendOwnershipRule, sandboxId: string, rows: readonly SettlementRow[]): SpendOwnershipVerdict;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { SpendLedgerStorePort } from './store';
|
|
2
|
+
import { type SettlementRow, type SpendBoxRecord, type SpendCheckId, type SpendOwnershipRule, type SpendReport, type SpendWindow } from './types';
|
|
3
|
+
export interface VelocityOptions {
|
|
4
|
+
/** Bucket width for a spend window, ms. Default 24 h. */
|
|
5
|
+
readonly windowMs?: number;
|
|
6
|
+
/** Fire when a window exceeds this multiple of the trailing median. Default 5. */
|
|
7
|
+
readonly multiple?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Windows of history required before a median means anything. Default 3.
|
|
10
|
+
* Below this the rule stays silent, so a product's genuine first days of
|
|
11
|
+
* usage are not reported as an anomaly.
|
|
12
|
+
*/
|
|
13
|
+
readonly minTrailingWindows?: number;
|
|
14
|
+
/**
|
|
15
|
+
* A window under this never fires, whatever the ratio. Default $1.00.
|
|
16
|
+
*
|
|
17
|
+
* Without a floor the rule is useless: a trailing median of a tenth of a cent
|
|
18
|
+
* makes every ordinary day a 5x outlier. $1.00 is set from the incident's own
|
|
19
|
+
* distribution — the smallest of the eight affected wallets took $1.98, and
|
|
20
|
+
* the two rows in the same window that were GENUINE were sub-cent. So the
|
|
21
|
+
* floor sits above the noise and below every real finding.
|
|
22
|
+
*/
|
|
23
|
+
readonly minAbsoluteNanoUsd?: number;
|
|
24
|
+
}
|
|
25
|
+
/** The balance the product observes, and the floor it must not cross. */
|
|
26
|
+
export interface ObservedBalance {
|
|
27
|
+
/** Signed nanodollars, as the platform reports it. */
|
|
28
|
+
readonly nanoUsd: number;
|
|
29
|
+
/** Below this is a finding. Default 0. */
|
|
30
|
+
readonly floorNanoUsd?: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A box's price, nanodollars per hour, used to derive an EXACT billed duration
|
|
34
|
+
* from a charge. Return null when the product does not know the box's rate; the
|
|
35
|
+
* reconciler then falls back to the reference span.
|
|
36
|
+
*/
|
|
37
|
+
export type BoxRateResolver = (record: SpendBoxRecord | null, sandboxId: string) => number | null | undefined;
|
|
38
|
+
export interface ReconcileSpendOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Settled ledger rows, supplied by the product's own authenticated fetch.
|
|
41
|
+
*
|
|
42
|
+
* The fetch can only scope to a WALLET — `product: 'sandbox'` is the
|
|
43
|
+
* platform's service taxonomy, not this product's — so on an account running
|
|
44
|
+
* more than one of our products these rows carry the siblings' boxes too.
|
|
45
|
+
* {@link ReconcileSpendOptions.ownership} is what separates them.
|
|
46
|
+
*/
|
|
47
|
+
readonly rows: readonly SettlementRow[];
|
|
48
|
+
/** The product's expectation ledger. */
|
|
49
|
+
readonly store: SpendLedgerStorePort;
|
|
50
|
+
/**
|
|
51
|
+
* Which of those rows are THIS product's — see {@link SpendOwnershipRule} and
|
|
52
|
+
* the shipped `ownedByBillingKeys`.
|
|
53
|
+
*
|
|
54
|
+
* Omitting it is safe and changes nothing: the pass claims every box, which is
|
|
55
|
+
* the behaviour that shipped, and the direction that over-reports rather than
|
|
56
|
+
* under-reports. It is not silent about it — `report.ownership.declared` is
|
|
57
|
+
* `false`, `formatSpendReport` says so above the findings, and every
|
|
58
|
+
* `unknown-box` finding states on its face that a sibling product's box is
|
|
59
|
+
* indistinguishable from a charge that is not ours.
|
|
60
|
+
*
|
|
61
|
+
* Declaring it never weakens the ledger-backed checks: ownership is consulted
|
|
62
|
+
* ONLY for boxes with no expectation record, so `over-ceiling` on a recorded
|
|
63
|
+
* box fires whatever the rule says.
|
|
64
|
+
*/
|
|
65
|
+
readonly ownership?: SpendOwnershipRule;
|
|
66
|
+
/** Treated as "now". Default `Date.now()`. */
|
|
67
|
+
readonly asOf?: number;
|
|
68
|
+
/** Ceiling slack. Default {@link DEFAULT_CEILING_TOLERANCE_MS}. */
|
|
69
|
+
readonly toleranceMs?: number;
|
|
70
|
+
/** Box price, for the exact duration basis. A number applies to every box. */
|
|
71
|
+
readonly nanoUsdPerHour?: number | BoxRateResolver;
|
|
72
|
+
/** Velocity tuning, or `false` to skip the rule. */
|
|
73
|
+
readonly velocity?: VelocityOptions | false;
|
|
74
|
+
/** The workspace balance, when the product can see one. Omitted skips the rule. */
|
|
75
|
+
readonly balance?: ObservedBalance;
|
|
76
|
+
/** Stamped onto findings so an alert names the tenant. */
|
|
77
|
+
readonly workspaceId?: string;
|
|
78
|
+
/** Checks to leave out of this pass. */
|
|
79
|
+
readonly skip?: readonly SpendCheckId[];
|
|
80
|
+
/**
|
|
81
|
+
* The stretch of time these `rows` were fetched for.
|
|
82
|
+
*
|
|
83
|
+
* Declaring it — together with a store that implements `listLiveBetween` — is
|
|
84
|
+
* what lets the pass answer the direction every settlement-driven rule is
|
|
85
|
+
* blind to: *were we NOT billed for something we DID ask for*. The expectation
|
|
86
|
+
* ledger already holds the answer; nothing new is stored for it.
|
|
87
|
+
*
|
|
88
|
+
* Omitting it is additive and changes no existing finding. It is not silent:
|
|
89
|
+
* `report.expectation.declared` is `false`, `formatSpendReport` prints
|
|
90
|
+
* `expectation: NOT DECLARED` above the findings, and a pass that also
|
|
91
|
+
* examined none of this product's settlements reports `coverage: 'unverified'`
|
|
92
|
+
* and cannot render as a clean bill.
|
|
93
|
+
*/
|
|
94
|
+
readonly window?: SpendWindow;
|
|
95
|
+
/**
|
|
96
|
+
* Live ms a box needs inside the window before a settlement is EXPECTED of it.
|
|
97
|
+
* Default {@link DEFAULT_EXPECTATION_GRACE_MS} (15 min — the platform's own
|
|
98
|
+
* declared-normal settlement lag). Shrink it for a short window.
|
|
99
|
+
*/
|
|
100
|
+
readonly expectationGraceMs?: number;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Diff what the platform charged against what the product believes it asked for.
|
|
104
|
+
*
|
|
105
|
+
* Never disputes anything and never writes: the output is a report a human acts
|
|
106
|
+
* on. The platform's ledger stays authoritative — this only ever produces the
|
|
107
|
+
* evidence for a conversation with it.
|
|
108
|
+
*/
|
|
109
|
+
export declare function reconcileSpend(options: ReconcileSpendOptions): Promise<SpendReport>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SettlementReference, SettlementRow } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse the platform's settlement idempotency key.
|
|
4
|
+
*
|
|
5
|
+
* The platform mints it as `sandbox:<kind>:<resourceId>:<intervalStart>`
|
|
6
|
+
* (`d1-usage-service.ts`), where `intervalStart` is the interval cursor in epoch
|
|
7
|
+
* ms — the SAME `last_started_at` the settlement subtracts from to get its
|
|
8
|
+
* billed duration. That makes this string the only place a consumer can read the
|
|
9
|
+
* billed interval's start, because the ledger row itself stores no duration.
|
|
10
|
+
*
|
|
11
|
+
* Kinds seen in production: `stop` (an interval closing), `compute` (a heartbeat
|
|
12
|
+
* claim), `egress`, `gpu-lease`. `stop` deliberately covers both a settle and a
|
|
13
|
+
* late stop racing over the same claim, so the two derive one reference id and
|
|
14
|
+
* the ledger's uniqueness constraint makes the overlap safe.
|
|
15
|
+
*
|
|
16
|
+
* Returns null for anything that is not a sandbox reference — a router
|
|
17
|
+
* inference row, a grant, a refund — rather than guessing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseSettlementReference(referenceId: string | null | undefined): SettlementReference | null;
|
|
20
|
+
/**
|
|
21
|
+
* Read the sandbox id out of the platform's aggregation key, `sandbox:<id>`.
|
|
22
|
+
*
|
|
23
|
+
* Distinct from the reference id: `groupKey` is the unit a billing statement
|
|
24
|
+
* groups by and is deliberately NOT unique per row, while `referenceId` is
|
|
25
|
+
* unique per interval. A null group key means "do not aggregate" (grants,
|
|
26
|
+
* top-ups, refunds, transfers) and is not an error.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseSandboxGroupKey(groupKey: string | null | undefined): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* The sandbox a settlement row is attributable to.
|
|
31
|
+
*
|
|
32
|
+
* The reference id wins over the group key because it is the field the platform
|
|
33
|
+
* dedups on, so it is the one guaranteed present and correct on a compute
|
|
34
|
+
* settlement; the group key is the fallback for rows written before a producer
|
|
35
|
+
* stamped a reference, and for kinds whose reference names something else (a GPU
|
|
36
|
+
* lease id, not a box).
|
|
37
|
+
*/
|
|
38
|
+
export declare function settlementSandboxId(row: SettlementRow): string | null;
|
|
39
|
+
/** True when a row is a charge (the ledger stores charges as negative amounts). */
|
|
40
|
+
export declare function isCharge(row: SettlementRow): boolean;
|
|
41
|
+
/** A charge's magnitude in unsigned nanodollars; 0 for credits. */
|
|
42
|
+
export declare function chargeNanoUsd(row: SettlementRow): number;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SpendReport } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Render a reconciliation for a human deciding whether to open a dispute.
|
|
4
|
+
*
|
|
5
|
+
* Every finding prints its numbers, not a summary of them: the reader's next
|
|
6
|
+
* action is a conversation with the platform about specific reference ids, and a
|
|
7
|
+
* report that made them re-derive the durations would just be re-read alongside
|
|
8
|
+
* the raw rows anyway.
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatSpendReport(report: SpendReport): string;
|
|
11
|
+
/** The report as a plain JSON value, for an alerting pipeline. */
|
|
12
|
+
export declare function spendReportToJson(report: SpendReport): string;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { SpendBoxPatch, SpendBoxRecord, SpendWindow } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Persistence seam for the expectation ledger — the product implements it over
|
|
4
|
+
* its own tables.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately NOT compare-and-set, unlike `MissionStorePort`. A mission has one
|
|
7
|
+
* serialized owner and a lost write corrupts a state machine; a box record is a
|
|
8
|
+
* MONOTONIC FOLD (activity takes a max, a detached-run id joins or leaves a set,
|
|
9
|
+
* delete is set-once) so concurrent writers converge no matter what order they
|
|
10
|
+
* land in. The worst a lost race can do here is leave `lastActivityAt` behind
|
|
11
|
+
* the truth — which makes the derived ceiling TIGHTER, so the failure mode is a
|
|
12
|
+
* false alarm a human dismisses, never a missed charge. That asymmetry is the
|
|
13
|
+
* whole reason the fold is shaped this way.
|
|
14
|
+
*
|
|
15
|
+
* `update` returns null when the row does not exist, never a throw.
|
|
16
|
+
*/
|
|
17
|
+
export interface SpendLedgerStorePort {
|
|
18
|
+
load(sandboxId: string): Promise<SpendBoxRecord | null>;
|
|
19
|
+
/** `extras` are the opaque product-column values — write them in the SAME
|
|
20
|
+
* statement as the record, or ignore them if the table has no extra columns. */
|
|
21
|
+
insert(record: SpendBoxRecord, extras?: Record<string, unknown>): Promise<SpendBoxRecord>;
|
|
22
|
+
update(sandboxId: string, patch: SpendBoxPatch): Promise<SpendBoxRecord | null>;
|
|
23
|
+
/**
|
|
24
|
+
* OPTIONAL — every box that could have been live during the window.
|
|
25
|
+
*
|
|
26
|
+
* This is the one capability that lets a reconciliation answer "were we NOT
|
|
27
|
+
* billed for something we DID ask for". Without it the pass is driven entirely
|
|
28
|
+
* by settlement rows, so a feed that returns nothing fires nothing and reads
|
|
29
|
+
* as a clean bill. Omitting it is safe and additive: the pass reports
|
|
30
|
+
* `expectation.declared: false` and refuses to certify a bill it could not
|
|
31
|
+
* check (see {@link SpendReport.coverage}).
|
|
32
|
+
*
|
|
33
|
+
* **It may over-return.** The reconciler re-derives liveness itself with
|
|
34
|
+
* `boxLivenessInWindow`, so a store that returns every row it has is correct,
|
|
35
|
+
* merely slower. That is deliberate: the definition of "live" must live in one
|
|
36
|
+
* place, not once per product's SQL. The intended predicate is the coarse one
|
|
37
|
+
* a WHERE clause can express —
|
|
38
|
+
*
|
|
39
|
+
* ```sql
|
|
40
|
+
* WHERE created_at <= :endAt AND (deleted_at IS NULL OR deleted_at >= :startAt)
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* — and the exact answer (idle timeout, max lifetime, stop, open detached run)
|
|
44
|
+
* is the reconciler's.
|
|
45
|
+
*/
|
|
46
|
+
listLiveBetween?(window: SpendWindow): Promise<readonly SpendBoxRecord[]>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Apply one fold step. Exported so a SQL implementation and an in-memory one
|
|
50
|
+
* reach the same record, and so a product can unit-test its own store against
|
|
51
|
+
* the canonical answer.
|
|
52
|
+
*
|
|
53
|
+
* The two rules worth stating out loud:
|
|
54
|
+
*
|
|
55
|
+
* - `observedActivityAt` only ever moves `lastActivityAt` FORWARD. A replayed
|
|
56
|
+
* or out-of-order event cannot rewind the ceiling.
|
|
57
|
+
* - activity later than a recorded `stoppedAt` CLEARS the stop. A box that
|
|
58
|
+
* worked after the product thought it stopped is running again, and keeping
|
|
59
|
+
* the stale stop would make the ceiling too tight — inventing an over-ceiling
|
|
60
|
+
* finding out of the product's own bookkeeping rather than the platform's.
|
|
61
|
+
*/
|
|
62
|
+
export declare function foldSpendBoxRecord(record: SpendBoxRecord, patch: SpendBoxPatch): SpendBoxRecord;
|
|
63
|
+
/** An in-memory store that also lets a test inspect and force state. */
|
|
64
|
+
export interface InMemorySpendLedgerStore extends SpendLedgerStorePort {
|
|
65
|
+
/** Every record, insertion order. */
|
|
66
|
+
records(): SpendBoxRecord[];
|
|
67
|
+
/** Unguarded direct write — simulates a crash-shaped or platform-seeded row. */
|
|
68
|
+
put(record: SpendBoxRecord): void;
|
|
69
|
+
}
|
|
70
|
+
/** Create an in-memory expectation ledger. Production writers use the same port. */
|
|
71
|
+
export declare function createInMemorySpendLedgerStore(): InMemorySpendLedgerStore;
|
|
72
|
+
/** What the product tells the ledger when it first sees a box. */
|
|
73
|
+
export interface ObserveSandboxInput {
|
|
74
|
+
readonly sandboxId: string;
|
|
75
|
+
readonly workspaceId: string;
|
|
76
|
+
/** The idle timeout the product asked the platform for, seconds. */
|
|
77
|
+
readonly idleTimeoutSeconds: number;
|
|
78
|
+
/** The max lifetime the product asked for, seconds, when it asked for one. */
|
|
79
|
+
readonly maxLifetimeSeconds?: number | null;
|
|
80
|
+
/** Defaults to the ledger's clock. */
|
|
81
|
+
readonly at?: number;
|
|
82
|
+
}
|
|
83
|
+
export interface SpendLedgerOptions {
|
|
84
|
+
readonly store: SpendLedgerStorePort;
|
|
85
|
+
/** Injectable clock (epoch ms). Default `Date.now`. */
|
|
86
|
+
readonly now?: () => number;
|
|
87
|
+
/** Product columns written verbatim on every insert. */
|
|
88
|
+
readonly extras?: Record<string, unknown>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The recording half of spend verification: the product's own account of what
|
|
92
|
+
* it asked the platform for.
|
|
93
|
+
*
|
|
94
|
+
* Every method is best-effort from the caller's point of view — a product wires
|
|
95
|
+
* these into paths that must not fail because bookkeeping failed. They still
|
|
96
|
+
* reject on a store error rather than swallowing it, so a caller that wants
|
|
97
|
+
* fire-and-forget says so at the call site (`/sandbox`'s hook does).
|
|
98
|
+
*/
|
|
99
|
+
export interface SpendLedger {
|
|
100
|
+
/**
|
|
101
|
+
* Record that a box exists and is billable from now. Inserts on first sight,
|
|
102
|
+
* and otherwise records activity — reuse and resume are both "the platform is
|
|
103
|
+
* charging for this box again", and the record's own existence is what
|
|
104
|
+
* distinguishes them, so no caller has to know which happened.
|
|
105
|
+
*/
|
|
106
|
+
observeSandbox(input: ObserveSandboxInput): Promise<SpendBoxRecord>;
|
|
107
|
+
/** Record that the product saw this box do work. */
|
|
108
|
+
recordActivity(sandboxId: string, at?: number): Promise<SpendBoxRecord | null>;
|
|
109
|
+
/**
|
|
110
|
+
* Record that the product handed the platform work it will NOT watch finish.
|
|
111
|
+
* Until the matching end is recorded, this box's ceiling cannot rest on
|
|
112
|
+
* observed activity — see `computeExpectedCeiling`.
|
|
113
|
+
*/
|
|
114
|
+
recordDetachedRunStarted(sandboxId: string, runId: string, at?: number): Promise<SpendBoxRecord | null>;
|
|
115
|
+
/** Record that a detached run was confirmed finished. */
|
|
116
|
+
recordDetachedRunEnded(sandboxId: string, runId: string, at?: number): Promise<SpendBoxRecord | null>;
|
|
117
|
+
/** Record that the product knows this box stopped. */
|
|
118
|
+
recordStopped(sandboxId: string, at?: number): Promise<SpendBoxRecord | null>;
|
|
119
|
+
/** Record that the product knows this box was deleted. */
|
|
120
|
+
recordDeleted(sandboxId: string, at?: number): Promise<SpendBoxRecord | null>;
|
|
121
|
+
}
|
|
122
|
+
/** Create the recording half over a product-supplied store. */
|
|
123
|
+
export declare function createSpendLedger(options: SpendLedgerOptions): SpendLedger;
|