/** * AgentGuard(TM) Spend: Core type definitions * * Patent notice: Protected by U.S. patent-pending technology * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626; * 64/071,781; 64/071,789). * * Design rule: NO DATA PLANE INVOLVEMENT. * All policy decisions are made locally in the customer runtime. * Prompts, completions, and provider API keys never leave the customer process. */ import type { ProvenanceBlock } from './receipts/schema'; import type { GovernancePosture } from './posture/enforce'; export type SpendAction = 'block' | 'downgrade' | 'shadow' | 'allow'; export type SpendWindow = 'per_call' | 'per_minute' | 'per_hour' | 'per_day' | 'per_month'; export type Provider = 'openai' | 'anthropic' | 'bedrock' | 'gemini' | 'unknown'; export type EnforcementMode = 'shadow' | 'canary' | 'enforce'; export type CapabilityTier = 'read_only' | 'data_write' | 'payment_initiate' | 'payment_execute'; /** * DAG-TAT attestation requirement attached to a SpendPolicy. * * Claims listed in `requireFor` are no longer trusted as self-declared * strings: the call must carry an attestation chain (a signed receipt DAG) * that verifies under `signerKeys` and clears the trust/depth gate for the * claimed tier. Node/envelope shapes are defined in receipts/dag.ts; they are * typed structurally here to keep core types free of that dependency. */ export interface AttestationRequirement { /** Capability claims that must be backed by a verified attestation chain. */ requireFor: CapabilityTier[]; /** * Trusted Ed25519 signer public keys: a single hex/raw key, or a map of * signer fingerprint -> key for multi-signer chains. */ signerKeys: Record | string; /** * Optional per-level overrides of the trust/depth gate thresholds * (levels: READ_ONLY | TRANSACT | ADMIN | ORCHESTRATE). */ thresholds?: Partial>; } /** Structural shape for an attestation chain carried on a call. */ export type AttestationChainInput = ReadonlyArray> | { nodes: ReadonlyArray>; }; /** * A spend cap with one or more thresholds across configurable windows. * All amounts are USD cents (integer math, no floating-point cost drift). */ export interface SpendCap { /** Maximum cents spent in the given window before the action fires */ amountCents: number; /** Time window over which the cap applies */ window: SpendWindow; /** What to do when the cap is reached or projected to be reached */ action: SpendAction; /** Optional model to downgrade to when action='downgrade' */ downgradeTo?: string; /** Optional reason string included in decision log */ reason?: string; } /** * Identity scope a cap applies to. Caps are matched on EVERY matching scope. * If any scope's cap is exceeded, the most restrictive action wins. */ export interface SpendScope { /** Tenant or organization ID. Required at top level. */ tenantId: string; /** Optional user ID for per-user limits */ userId?: string; /** Optional team ID */ teamId?: string; /** Optional project / agent ID */ agentId?: string; /** Optional task / job ID */ taskId?: string; /** Optional provider scope (e.g., only enforce on OpenAI) */ provider?: Provider; } export interface ReviewerCascadeModelStep { model: string; maxCostCents: number; } export type ReviewerCascadeTrigger = { drafter_confidence_below: number; } | { output_contains_any: string[]; } | { high_risk_classifier_score_above: number; } | { keyword_watchlist: string; }; export interface ReviewerCascadeOutcome { drafter: ReviewerCascadeModelStep; reviewer?: ReviewerCascadeModelStep & { trigger?: ReviewerCascadeTrigger[]; }; cap: number | string; capability: CapabilityTier; } export interface ReviewerCascadeReceipt { outcome: string; drafter: ReviewerCascadeModelStep; reviewer: ReviewerCascadeModelStep | null; triggerFired: string[]; reviewerVerdict: string; } /** * A full spend policy: name, scope, and ordered list of caps. * The first cap whose threshold is reached determines the action. */ export interface SpendPolicy { /** Stable identifier, e.g., 'finance-ops-v1' */ id: string; /** Human-readable name */ name: string; /** Scope this policy binds to */ scope: SpendScope; /** Ordered list of caps (evaluated in order, first match wins) */ caps: SpendCap[]; /** Enforcement mode for graduated rollout */ mode: EnforcementMode; /** Optional capability tier requirement. * * The tier set is informed by the capability-tier framework of Patent D * §7.3 (App. No. 63/984,626). The SDK enforces a flat ordered comparison * between the call's capability claim and this requirement. To require the * claim itself to be PROVEN rather than self-declared, also set * `attestation`: listed claims must be backed by a verified receipt-DAG * attestation chain (DAG-TAT) or the call is blocked. */ requiredCapability?: CapabilityTier; /** Optional DAG-TAT attestation requirement for capability claims. * * When present, any call whose `capabilityClaim` is listed in * `attestation.requireFor` must carry a `CallContext.attestation` chain * that (a) verifies as a signed, acyclic receipt DAG under `signerKeys` * and (b) clears the trust/depth gate for the claimed tier. Verification * is local (Ed25519, no network). Fails closed: a listed claim without a * valid chain blocks in every enforcement mode. */ attestation?: AttestationRequirement; /** Optional governance posture used by Advisor and provenance policy. */ posture?: GovernancePosture; /** Optional outcome definitions for Reviewer Cascade alpha policies. */ outcomes?: Record; /** Policy version, monotonically increasing */ version: number; /** ISO 8601 effective-from timestamp */ effectiveFrom: string; } /** * A single LLM call attempted under a policy. */ export interface CallContext { /** Provider being called */ provider: Provider; /** Model name as passed to the provider */ model: string; /** Input token count (estimated or measured) */ inputTokens: number; /** Output token count (estimated or measured) */ outputTokens: number; /** Identity scope of the caller (must include tenantId) */ scope: SpendScope; /** Optional human-readable label for the call */ label?: string; /** Optional workflow ID for run-level budget envelopes. */ workflowId?: string; /** Optional subagent ID for workflow metadata. */ subagentId?: string; /** Optional caller-supplied metadata-only fingerprint. */ callFingerprint?: string; /** Optional metadata-only request shape. Must not include prompt or completion content. */ requestShape?: Record; /** Optional tool name for destructive-action gating. */ toolName?: string; /** Optional tool args for destructive-action gating. */ toolArgs?: Record; /** Optional plan revision count for plan-churn detection. */ planRevision?: number; /** Optional reasoning step count for loop detection. */ reasoningStep?: number; /** True when the agent made durable progress since the prior plan revision. */ stateProgress?: boolean; /** Optional partner attribution code. Metadata only. */ builderCode?: string; /** Optional capability tier the caller claims */ capabilityClaim?: CapabilityTier; /** * Optional DAG-TAT attestation chain backing the capability claim. * Required when the policy's `attestation.requireFor` lists the claimed * tier. An array of signed receipt-DAG nodes or an envelope of them. */ attestation?: AttestationChainInput; /** Optional consent receipt for foreign origin model weights. */ foreignOriginConsentReceiptId?: string; /** Captured provider provenance for the call. */ provenance?: ProvenanceBlock; } /** * The policy decision for a given call. */ export interface SpendDecision { /** Unique decision ID (UUID v4) */ decisionId: string; /** ISO 8601 timestamp */ timestamp: string; /** The action taken */ action: SpendAction; /** The cap that triggered the action, if any */ triggeredCap: SpendCap | null; /** The scope key that the cap matched on */ triggeredScopeKey: string | null; /** Cents the call would have cost */ projectedCents: number; /** Cents spent in the relevant window before this call */ windowSpendBefore: number; /** Cents that would be spent in the window after allowing this call */ windowSpendAfter: number; /** Provider being called */ provider: Provider; /** Model originally requested */ modelRequested: string; /** Model actually used (differs from modelRequested on downgrade) */ modelResolved: string; /** Policy ID and version this decision was made under. */ policyId: string; policyVersion: number; /** Enforcement mode in effect at the time of the decision. */ enforcementMode: EnforcementMode; /** Human-readable reasons. */ reasons: string[]; /** Entry kind. Defaults to a provider enforcement decision. */ entryType?: 'decision' | 'settlement' | 'outcome' | 'governance' | 'routing'; /** Original enforcement decision settled by this entry. */ originalDecisionId?: string; /** Estimated tokens used for the initial reservation. */ estimatedInputTokens?: number; estimatedOutputTokens?: number; /** Actual tokens observed after provider completion or stream close. */ actualInputTokens?: number; actualOutputTokens?: number; /** Actual cents and true-up delta for settlement entries. */ actualCents?: number; deltaCents?: number; /** True when the stream ended before a provider completion event. */ partial?: boolean; /** Optional partner attribution code included in signed receipts when present. */ builderCode?: string; /** Provider and hosting provenance captured before bytes leave the process. */ provenance?: ProvenanceBlock; /** Metadata-only outcome receipt payload. Never includes prompt or completion content. */ outcomeReceipt?: Record; /** Metadata-only governance receipt payload. Never includes prompt or completion content. */ governanceReceipt?: Record; /** Metadata-only model-router receipt payload. Never includes prompt or completion content. */ routingReceipt?: Record; } /** * A signed, hash-chained decision log entry. * * The chain enables tamper-evident audit: each entry binds the previous * entry's hash, and the entire chain is verifiable with a public key. * * The capability-tier framework used here is informed by Patent D §7.3 * (App. No. 63/984,626). The flat tier comparison implemented in this SDK * does not by itself implement the full DAG-TAT cryptographic gating of * §7.3; integration with a DAG-TAT verifier is performed separately and * is not required for the spend-governance functions of this package. */ export interface SignedDecisionLogEntry { /** Monotonic chain sequence number (starts at 0) */ sequence: number; /** The decision itself */ decision: SpendDecision; /** SHA-256 hash of the previous entry, or 64 zeros for sequence=0 */ previousHash: string; /** SHA-256 hash of this entry's canonical JSON (without signature) */ entryHash: string; /** Ed25519 signature over entryHash, hex-encoded */ signature: string; /** Hex-encoded public key fingerprint (first 8 bytes of SHA-256(pubkey)) */ signerFingerprint: string; /** Optional partner attribution code covered by entryHash when present. */ builderCode?: string; } export interface SpendReservation { /** True when cents were reserved against the window. */ allowed: boolean; /** Cents spent in the window before this reservation attempt. */ before: number; /** Cents that would be or were spent after the reservation. */ after: number; } /** * Storage backend for spend state. Implementations may use Redis, Postgres, * SQLite, in-memory, or anything else. Spend state never leaves the customer * runtime in the no-data-plane configuration. */ export interface SpendStore { /** * Get the total cents spent for a given scope key + window since the window start. */ getWindowSpend(scopeKey: string, window: SpendWindow): Promise; /** * Atomically increment the cents spent for a given scope key + window. * Returns the new total. Implementations MUST be atomic to prevent races. */ incrementWindowSpend(scopeKey: string, window: SpendWindow, cents: number): Promise; /** * Atomically reserve cents if the post-reservation total is <= limitCents. * Implementations that omit this method will still work, but cannot provide * distributed cap safety under concurrent writers. */ reserveWindowSpend?(scopeKey: string, window: SpendWindow, cents: number, limitCents: number): Promise; /** * Adjust a prior reservation after provider usage is known. Negative deltas * must clamp at zero rather than creating negative spend. */ settleWindowSpend?(scopeKey: string, window: SpendWindow, deltaCents: number): Promise; } /** * Storage backend for the signed decision log. Implementations may append to a * local file, a database table, or any other append-only sink. */ export interface DecisionLogStore { /** Append a new signed entry to the chain. */ append(entry: SignedDecisionLogEntry): Promise; /** Get the most recent entry, or null if empty. */ getLatest(signerFingerprint?: string): Promise; /** Iterate from sequence onward (used by verification tools). */ read(fromSequence: number, limit: number, signerFingerprint?: string): Promise; } //# sourceMappingURL=types.d.ts.map