@agentguard-run/spend 0.15.7 → 0.15.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.
Files changed (61) hide show
  1. package/README.md +61 -1
  2. package/dist/anchor/index.d.ts +35 -0
  3. package/dist/anchor/index.d.ts.map +1 -0
  4. package/dist/anchor/index.js +80 -0
  5. package/dist/anchor/index.js.map +1 -0
  6. package/dist/anchor/opentimestamps.d.ts +55 -0
  7. package/dist/anchor/opentimestamps.d.ts.map +1 -0
  8. package/dist/anchor/opentimestamps.js +179 -0
  9. package/dist/anchor/opentimestamps.js.map +1 -0
  10. package/dist/anchor/store.d.ts +25 -0
  11. package/dist/anchor/store.d.ts.map +1 -0
  12. package/dist/anchor/store.js +112 -0
  13. package/dist/anchor/store.js.map +1 -0
  14. package/dist/anchor/types.d.ts +84 -0
  15. package/dist/anchor/types.d.ts.map +1 -0
  16. package/dist/anchor/types.js +28 -0
  17. package/dist/anchor/types.js.map +1 -0
  18. package/dist/cli/anchor.d.ts +10 -0
  19. package/dist/cli/anchor.d.ts.map +1 -0
  20. package/dist/cli/anchor.js +126 -0
  21. package/dist/cli/anchor.js.map +1 -0
  22. package/dist/cli/colors.d.ts +1 -0
  23. package/dist/cli/colors.d.ts.map +1 -1
  24. package/dist/cli/colors.js +4 -0
  25. package/dist/cli/colors.js.map +1 -1
  26. package/dist/cli/main.d.ts.map +1 -1
  27. package/dist/cli/main.js +10 -0
  28. package/dist/cli/main.js.map +1 -1
  29. package/dist/cli/sample.d.ts +43 -0
  30. package/dist/cli/sample.d.ts.map +1 -0
  31. package/dist/cli/sample.js +154 -0
  32. package/dist/cli/sample.js.map +1 -0
  33. package/dist/cli/serve.d.ts +1 -1
  34. package/dist/cli/serve.d.ts.map +1 -1
  35. package/dist/cli/serve.js +10 -4
  36. package/dist/cli/serve.js.map +1 -1
  37. package/dist/cli/verify.d.ts.map +1 -1
  38. package/dist/cli/verify.js +57 -0
  39. package/dist/cli/verify.js.map +1 -1
  40. package/dist/dashboard/aggregate.d.ts +2 -0
  41. package/dist/dashboard/aggregate.d.ts.map +1 -1
  42. package/dist/dashboard/aggregate.js.map +1 -1
  43. package/dist/decision-log.d.ts +28 -0
  44. package/dist/decision-log.d.ts.map +1 -1
  45. package/dist/decision-log.js +34 -0
  46. package/dist/decision-log.js.map +1 -1
  47. package/dist/index.d.ts +5 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +27 -4
  50. package/dist/index.js.map +1 -1
  51. package/dist/samples/flows.d.ts +28 -0
  52. package/dist/samples/flows.d.ts.map +1 -0
  53. package/dist/samples/flows.js +151 -0
  54. package/dist/samples/flows.js.map +1 -0
  55. package/dist/samples/verifier-html.d.ts +29 -0
  56. package/dist/samples/verifier-html.d.ts.map +1 -0
  57. package/dist/samples/verifier-html.js +188 -0
  58. package/dist/samples/verifier-html.js.map +1 -0
  59. package/package.json +1 -1
  60. package/src/bindings/bindings-enforce.test.ts +97 -0
  61. package/src/dashboard/aggregate.ts +8 -1
package/dist/index.js CHANGED
@@ -21,9 +21,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
21
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.compressReceiptDag = exports.receiptSchemaVersion = exports.isReceiptV3 = exports.assertReceiptV3 = exports.isOpenRouterHost = exports.clearManagedOpenRouterKeyCache = exports.fetchManagedOpenRouterKey = exports.modelCostFromOpenRouter = exports.persistOverrides = exports.syncPricingIntoCostTable = exports.getCachedCatalog = exports.fetchCatalog = exports.recordTelemetryEvent = exports.resetTelemetryInstallId = exports.disableTelemetry = exports.enableTelemetry = exports.telemetryStatus = exports.licenseKeyFingerprint = exports.clearConfiguredLicenseKey = exports.writeConfiguredLicenseKey = exports.readConfiguredLicenseKey = exports.validateAndRegisterLicense = exports.validateLicenseKey = exports.AgentGuardLicenseRequiredError = exports.NdjsonDecisionLogStore = exports.InMemorySpendStore = exports.InMemoryDecisionLogStore = exports.GENESIS_PREVIOUS_HASH = exports.verifyChain = exports.verifyEntry = exports.signDecision = exports.computeSignerFingerprint = exports.computeEntryHash = exports.sha256Hex = exports.canonicalJson = exports.BUILT_IN_KEYWORD_WATCHLISTS = exports.findCustomKeywordWatchlists = exports.enforcePolicyLicenseGates = exports.adjustPolicyWindowSpend = exports.buildScopeKey = exports.evaluatePolicy = exports.knownModelCosts = exports.persistCostOverrides = exports.loadPersistedCostOverrides = exports.listCostOverrides = exports.inferProvider = exports.computeCallCents = exports.clearCostOverrides = exports.setCostOverride = exports.getModelCost = void 0;
25
- exports.t = exports.resolveLocale = exports.TRANSLATIONS = exports.SUPPORTED_LOCALES = exports.DEFAULT_LOCALE = exports.defaultKey = exports.recommend = exports.withSpendGuardBedrock = exports.withSpendGuardAnthropic = exports.AgentGuardBlockedError = exports.withSpendGuard = exports.SpendGuard = exports.writeAdvisorOutputs = exports.createAdvisorSessionLogger = exports.resolveAdvisorApiKey = exports.createAdvisorClient = exports.projectedSavings = exports.buildPolicyFromProfile = exports.buildBusinessProfile = exports.AdvisorConversation = exports.AgentGuardWorkflowStateError = exports.AgentGuardDurationCapError = exports.AgentGuardChainCorruptError = exports.AgentGuardBudgetCapError = exports.validateReceiptChain = exports.computeChainHash = exports.WorkflowContext = exports.workflow = exports.verifyConsentReceipt = exports.enforceCompliance = exports.AgentGuardConsentRequiredError = exports.AgentGuardComplianceError = exports.isForeignOriginModel = exports.inferCompliance = exports.inferHosting = exports.inferModelIdentity = exports.inferProviderRoute = exports.PROVIDER_REGISTRY = exports.captureProvenance = exports.verifyReceiptDag = exports.verifyInclusion = exports.signDagNode = exports.msgHashForDecision = exports.merkleRoot = exports.merkleInclusionProof = exports.gateCapability = exports.deriveTrustScore = exports.deriveCapability = exports.dagEnvelopeFromEntries = exports.computeDagEntryHash = void 0;
26
- exports.formatLineage = exports.workloadProvenance = exports.BONUS_THRESHOLD_PCT = exports.DEFAULT_FREE_LIMIT = exports.bonusMessage = exports.readFreeTierState = exports.maybeGrantFirstTimeBonus = exports.getMonthlyUsage = exports.centsToUsd = exports.decisionCents = exports.classifyOrigin = exports.aggregateLedger = exports.PATENT_NOTICE = exports.agentguard = exports.AGENTGUARD_SPEND_VERSION = exports.formatBlockedTrace = void 0;
24
+ exports.receiptSchemaVersion = exports.isReceiptV3 = exports.assertReceiptV3 = exports.isOpenRouterHost = exports.clearManagedOpenRouterKeyCache = exports.fetchManagedOpenRouterKey = exports.modelCostFromOpenRouter = exports.persistOverrides = exports.syncPricingIntoCostTable = exports.getCachedCatalog = exports.fetchCatalog = exports.recordTelemetryEvent = exports.resetTelemetryInstallId = exports.disableTelemetry = exports.enableTelemetry = exports.telemetryStatus = exports.licenseKeyFingerprint = exports.clearConfiguredLicenseKey = exports.writeConfiguredLicenseKey = exports.readConfiguredLicenseKey = exports.validateAndRegisterLicense = exports.validateLicenseKey = exports.AgentGuardLicenseRequiredError = exports.NdjsonDecisionLogStore = exports.InMemorySpendStore = exports.InMemoryDecisionLogStore = exports.GENESIS_PREVIOUS_HASH = exports.detectSequenceGaps = exports.verifyChain = exports.verifyEntry = exports.signDecision = exports.computeSignerFingerprint = exports.computeEntryHash = exports.sha256Hex = exports.canonicalJson = exports.BUILT_IN_KEYWORD_WATCHLISTS = exports.findCustomKeywordWatchlists = exports.enforcePolicyLicenseGates = exports.adjustPolicyWindowSpend = exports.buildScopeKey = exports.evaluatePolicy = exports.knownModelCosts = exports.persistCostOverrides = exports.loadPersistedCostOverrides = exports.listCostOverrides = exports.inferProvider = exports.computeCallCents = exports.clearCostOverrides = exports.setCostOverride = exports.getModelCost = void 0;
25
+ exports.resolveLocale = exports.TRANSLATIONS = exports.SUPPORTED_LOCALES = exports.DEFAULT_LOCALE = exports.defaultKey = exports.recommend = exports.withSpendGuardBedrock = exports.withSpendGuardAnthropic = exports.AgentGuardBlockedError = exports.withSpendGuard = exports.SpendGuard = exports.writeAdvisorOutputs = exports.createAdvisorSessionLogger = exports.resolveAdvisorApiKey = exports.createAdvisorClient = exports.projectedSavings = exports.buildPolicyFromProfile = exports.buildBusinessProfile = exports.AdvisorConversation = exports.AgentGuardWorkflowStateError = exports.AgentGuardDurationCapError = exports.AgentGuardChainCorruptError = exports.AgentGuardBudgetCapError = exports.validateReceiptChain = exports.computeChainHash = exports.WorkflowContext = exports.workflow = exports.verifyConsentReceipt = exports.enforceCompliance = exports.AgentGuardConsentRequiredError = exports.AgentGuardComplianceError = exports.isForeignOriginModel = exports.inferCompliance = exports.inferHosting = exports.inferModelIdentity = exports.inferProviderRoute = exports.PROVIDER_REGISTRY = exports.captureProvenance = exports.verifyReceiptDag = exports.verifyInclusion = exports.signDagNode = exports.msgHashForDecision = exports.merkleRoot = exports.merkleInclusionProof = exports.gateCapability = exports.deriveTrustScore = exports.deriveCapability = exports.dagEnvelopeFromEntries = exports.computeDagEntryHash = exports.compressReceiptDag = void 0;
26
+ exports.formatLineage = exports.workloadProvenance = exports.buildSampleVerifierHtml = exports.SAMPLE_FLOWS = exports.isSampleFlow = exports.buildSampleReceipt = exports.anchorDir = exports.anchorProofPath = exports.anchorIndexPath = exports.findAnchorForHead = exports.readAnchorIndexAt = exports.readAnchorIndex = exports.writeAnchorProof = exports.DEFAULT_OTS_CALENDARS = exports.OpenTimestampsAnchor = exports.merkleRootHex = exports.chainHeadDigestHex = exports.createAnchorFromEnv = exports.createAnchor = exports.BONUS_THRESHOLD_PCT = exports.DEFAULT_FREE_LIMIT = exports.bonusMessage = exports.readFreeTierState = exports.maybeGrantFirstTimeBonus = exports.getMonthlyUsage = exports.centsToUsd = exports.decisionCents = exports.classifyOrigin = exports.aggregateLedger = exports.PATENT_NOTICE = exports.agentguard = exports.AGENTGUARD_SPEND_VERSION = exports.formatBlockedTrace = exports.t = void 0;
27
27
  const context_1 = require("./workflow/context");
28
28
  // Cost table
29
29
  var cost_table_1 = require("./cost-table");
@@ -53,6 +53,7 @@ Object.defineProperty(exports, "computeSignerFingerprint", { enumerable: true, g
53
53
  Object.defineProperty(exports, "signDecision", { enumerable: true, get: function () { return decision_log_1.signDecision; } });
54
54
  Object.defineProperty(exports, "verifyEntry", { enumerable: true, get: function () { return decision_log_1.verifyEntry; } });
55
55
  Object.defineProperty(exports, "verifyChain", { enumerable: true, get: function () { return decision_log_1.verifyChain; } });
56
+ Object.defineProperty(exports, "detectSequenceGaps", { enumerable: true, get: function () { return decision_log_1.detectSequenceGaps; } });
56
57
  Object.defineProperty(exports, "GENESIS_PREVIOUS_HASH", { enumerable: true, get: function () { return decision_log_1.GENESIS_PREVIOUS_HASH; } });
57
58
  Object.defineProperty(exports, "InMemoryDecisionLogStore", { enumerable: true, get: function () { return decision_log_1.InMemoryDecisionLogStore; } });
58
59
  // In-memory spend store
@@ -163,7 +164,7 @@ Object.defineProperty(exports, "TRANSLATIONS", { enumerable: true, get: function
163
164
  Object.defineProperty(exports, "resolveLocale", { enumerable: true, get: function () { return i18n_1.resolveLocale; } });
164
165
  Object.defineProperty(exports, "t", { enumerable: true, get: function () { return i18n_1.t; } });
165
166
  Object.defineProperty(exports, "formatBlockedTrace", { enumerable: true, get: function () { return i18n_1.formatBlockedTrace; } });
166
- exports.AGENTGUARD_SPEND_VERSION = '0.15.7';
167
+ exports.AGENTGUARD_SPEND_VERSION = '0.15.8';
167
168
  exports.agentguard = {
168
169
  workflow: context_1.workflow,
169
170
  };
@@ -191,6 +192,28 @@ Object.defineProperty(exports, "readFreeTierState", { enumerable: true, get: fun
191
192
  Object.defineProperty(exports, "bonusMessage", { enumerable: true, get: function () { return usage_1.bonusMessage; } });
192
193
  Object.defineProperty(exports, "DEFAULT_FREE_LIMIT", { enumerable: true, get: function () { return usage_1.DEFAULT_FREE_LIMIT; } });
193
194
  Object.defineProperty(exports, "BONUS_THRESHOLD_PCT", { enumerable: true, get: function () { return usage_1.BONUS_THRESHOLD_PCT; } });
195
+ // External timestamp anchoring (opt-in; zero data plane — only a hash leaves the machine)
196
+ var anchor_1 = require("./anchor");
197
+ Object.defineProperty(exports, "createAnchor", { enumerable: true, get: function () { return anchor_1.createAnchor; } });
198
+ Object.defineProperty(exports, "createAnchorFromEnv", { enumerable: true, get: function () { return anchor_1.createAnchorFromEnv; } });
199
+ Object.defineProperty(exports, "chainHeadDigestHex", { enumerable: true, get: function () { return anchor_1.chainHeadDigestHex; } });
200
+ Object.defineProperty(exports, "merkleRootHex", { enumerable: true, get: function () { return anchor_1.merkleRootHex; } });
201
+ Object.defineProperty(exports, "OpenTimestampsAnchor", { enumerable: true, get: function () { return anchor_1.OpenTimestampsAnchor; } });
202
+ Object.defineProperty(exports, "DEFAULT_OTS_CALENDARS", { enumerable: true, get: function () { return anchor_1.DEFAULT_OTS_CALENDARS; } });
203
+ Object.defineProperty(exports, "writeAnchorProof", { enumerable: true, get: function () { return anchor_1.writeAnchorProof; } });
204
+ Object.defineProperty(exports, "readAnchorIndex", { enumerable: true, get: function () { return anchor_1.readAnchorIndex; } });
205
+ Object.defineProperty(exports, "readAnchorIndexAt", { enumerable: true, get: function () { return anchor_1.readAnchorIndexAt; } });
206
+ Object.defineProperty(exports, "findAnchorForHead", { enumerable: true, get: function () { return anchor_1.findAnchorForHead; } });
207
+ Object.defineProperty(exports, "anchorIndexPath", { enumerable: true, get: function () { return anchor_1.anchorIndexPath; } });
208
+ Object.defineProperty(exports, "anchorProofPath", { enumerable: true, get: function () { return anchor_1.anchorProofPath; } });
209
+ Object.defineProperty(exports, "anchorDir", { enumerable: true, get: function () { return anchor_1.anchorDir; } });
210
+ // Sample receipt artifacts (self-verifying; outreach)
211
+ var flows_1 = require("./samples/flows");
212
+ Object.defineProperty(exports, "buildSampleReceipt", { enumerable: true, get: function () { return flows_1.buildSampleReceipt; } });
213
+ Object.defineProperty(exports, "isSampleFlow", { enumerable: true, get: function () { return flows_1.isSampleFlow; } });
214
+ Object.defineProperty(exports, "SAMPLE_FLOWS", { enumerable: true, get: function () { return flows_1.SAMPLE_FLOWS; } });
215
+ var verifier_html_1 = require("./samples/verifier-html");
216
+ Object.defineProperty(exports, "buildSampleVerifierHtml", { enumerable: true, get: function () { return verifier_html_1.buildSampleVerifierHtml; } });
194
217
  // Model-agnostic provenance that survives hot-swap
195
218
  var portability_1 = require("./receipts/portability");
196
219
  Object.defineProperty(exports, "workloadProvenance", { enumerable: true, get: function () { return portability_1.workloadProvenance; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Sample receipt flows.
3
+ *
4
+ * Realistic, self-contained example receipts for the three flows a prospect's
5
+ * counterparty would actually be handed: an x402 machine payment, a refund, and
6
+ * an agent purchase. Each carries a policy version, a delegated scope, a
7
+ * decision, a transaction reference, a provider, and an amount.
8
+ *
9
+ * These are SAMPLE parameters (fixed, illustrative). The signature and hash are
10
+ * REAL when signed by the CLI. Metadata only — never any prompt/completion.
11
+ *
12
+ * Patent notice: Protected by U.S. patent-pending technology
13
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
14
+ * 64/071,781; 64/071,789).
15
+ */
16
+ import type { SpendDecision, SpendScope } from '../types';
17
+ export type SampleFlow = 'x402-payment' | 'refund' | 'agent-purchase';
18
+ export declare const SAMPLE_FLOWS: SampleFlow[];
19
+ export declare function isSampleFlow(value: string): value is SampleFlow;
20
+ export interface SampleReceiptSpec {
21
+ flow: SampleFlow;
22
+ scope: SpendScope;
23
+ decision: SpendDecision;
24
+ /** Metadata-only context describing the flow (delegated scope, tx ref, etc.). */
25
+ context: Record<string, unknown>;
26
+ }
27
+ export declare function buildSampleReceipt(flow: SampleFlow): SampleReceiptSpec;
28
+ //# sourceMappingURL=flows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/samples/flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE1D,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,QAAQ,GAAG,gBAAgB,CAAC;AAEtE,eAAO,MAAM,YAAY,EAAE,UAAU,EAAiD,CAAC;AAEvF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC;IACxB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAKD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CA2HtE"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ /**
3
+ * Sample receipt flows.
4
+ *
5
+ * Realistic, self-contained example receipts for the three flows a prospect's
6
+ * counterparty would actually be handed: an x402 machine payment, a refund, and
7
+ * an agent purchase. Each carries a policy version, a delegated scope, a
8
+ * decision, a transaction reference, a provider, and an amount.
9
+ *
10
+ * These are SAMPLE parameters (fixed, illustrative). The signature and hash are
11
+ * REAL when signed by the CLI. Metadata only — never any prompt/completion.
12
+ *
13
+ * Patent notice: Protected by U.S. patent-pending technology
14
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
15
+ * 64/071,781; 64/071,789).
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.SAMPLE_FLOWS = void 0;
19
+ exports.isSampleFlow = isSampleFlow;
20
+ exports.buildSampleReceipt = buildSampleReceipt;
21
+ exports.SAMPLE_FLOWS = ['x402-payment', 'refund', 'agent-purchase'];
22
+ function isSampleFlow(value) {
23
+ return exports.SAMPLE_FLOWS.includes(value);
24
+ }
25
+ /** Deterministic ISO timestamp so sample artifacts are reproducible. */
26
+ const SAMPLE_TS = '2026-07-16T15:30:00.000Z';
27
+ function buildSampleReceipt(flow) {
28
+ switch (flow) {
29
+ case 'x402-payment':
30
+ return {
31
+ flow,
32
+ scope: { tenantId: 'acme-agents', agentId: 'checkout-bot-v2', provider: 'openai' },
33
+ decision: {
34
+ decisionId: 'sample-x402-payment-0001',
35
+ timestamp: SAMPLE_TS,
36
+ action: 'allow',
37
+ triggeredCap: null,
38
+ triggeredScopeKey: 'tenantId=acme-agents|agentId=checkout-bot-v2',
39
+ projectedCents: 1299,
40
+ windowSpendBefore: 0,
41
+ windowSpendAfter: 1299,
42
+ provider: 'openai',
43
+ modelRequested: 'gpt-5',
44
+ modelResolved: 'gpt-5',
45
+ policyId: 'payments-x402-v3',
46
+ policyVersion: 3,
47
+ enforcementMode: 'enforce',
48
+ reasons: ['Within per_day cap ($500.00)', 'capability=payment_execute satisfied'],
49
+ entryType: 'outcome',
50
+ outcomeReceipt: {
51
+ flow: 'x402-payment',
52
+ protocol: 'x402',
53
+ transactionReference: '0x9f2c4a7b3e1d8c6f0a5b2e9d4c7f1a3b6e8d0c2f4a7b9e1d3c5f8a0b2e4d6c9f',
54
+ settlementRail: 'USDC (base)',
55
+ amountCents: 1299,
56
+ currency: 'USD',
57
+ delegatedScope: ['payment_execute', 'read_only'],
58
+ capabilityTier: 'payment_execute',
59
+ counterparty: 'api.example-merchant.com',
60
+ outcome: 'settled',
61
+ },
62
+ },
63
+ context: {
64
+ summary: 'Autonomous agent paid $12.99 to an x402-gated API under a delegated payment scope.',
65
+ },
66
+ };
67
+ case 'refund':
68
+ return {
69
+ flow,
70
+ scope: { tenantId: 'acme-agents', agentId: 'support-bot-v4', provider: 'anthropic' },
71
+ decision: {
72
+ decisionId: 'sample-refund-0001',
73
+ timestamp: SAMPLE_TS,
74
+ action: 'allow',
75
+ triggeredCap: null,
76
+ triggeredScopeKey: 'tenantId=acme-agents|agentId=support-bot-v4',
77
+ projectedCents: 4500,
78
+ windowSpendBefore: 12000,
79
+ windowSpendAfter: 16500,
80
+ provider: 'anthropic',
81
+ modelRequested: 'claude-sonnet-4-6',
82
+ modelResolved: 'claude-sonnet-4-6',
83
+ policyId: 'refunds-support-v2',
84
+ policyVersion: 2,
85
+ enforcementMode: 'enforce',
86
+ reasons: ['Refund under $50.00 auto-approval threshold', 'capability=payment_initiate satisfied'],
87
+ entryType: 'outcome',
88
+ outcomeReceipt: {
89
+ flow: 'refund',
90
+ transactionReference: 're_3PqL8k2eZvKYlo2C1a4b7c9d',
91
+ originalChargeReference: 'ch_3PqK1j9dYuJXkn1B0z3a6b8c',
92
+ provider: 'stripe',
93
+ amountCents: 4500,
94
+ currency: 'USD',
95
+ delegatedScope: ['payment_initiate', 'read_only'],
96
+ capabilityTier: 'payment_initiate',
97
+ reasonCode: 'requested_by_customer',
98
+ outcome: 'settled',
99
+ },
100
+ },
101
+ context: {
102
+ summary: 'Support agent issued a $45.00 refund within a delegated refund scope and auto-approval cap.',
103
+ },
104
+ };
105
+ case 'agent-purchase':
106
+ return {
107
+ flow,
108
+ scope: { tenantId: 'acme-agents', agentId: 'procurement-bot-v1', provider: 'bedrock' },
109
+ decision: {
110
+ decisionId: 'sample-agent-purchase-0001',
111
+ timestamp: SAMPLE_TS,
112
+ action: 'downgrade',
113
+ triggeredCap: {
114
+ amountCents: 20000,
115
+ window: 'per_day',
116
+ action: 'downgrade',
117
+ downgradeTo: 'amazon.nova-lite-v1:0',
118
+ reason: 'Daily model budget reached; routing to fallback model',
119
+ },
120
+ triggeredScopeKey: 'tenantId=acme-agents|agentId=procurement-bot-v1',
121
+ projectedCents: 8800,
122
+ windowSpendBefore: 19500,
123
+ windowSpendAfter: 19980,
124
+ provider: 'bedrock',
125
+ modelRequested: 'anthropic.claude-opus-4-v1:0',
126
+ modelResolved: 'amazon.nova-lite-v1:0',
127
+ policyId: 'procurement-agent-v5',
128
+ policyVersion: 5,
129
+ enforcementMode: 'enforce',
130
+ reasons: ['Per_day model budget reached, routed to fallback model', 'capability=data_write satisfied'],
131
+ entryType: 'outcome',
132
+ actualCents: 480,
133
+ outcomeReceipt: {
134
+ flow: 'agent-purchase',
135
+ transactionReference: 'po-2026-07-16-000482',
136
+ provider: 'internal-procurement-api',
137
+ amountCents: 480,
138
+ currency: 'USD',
139
+ delegatedScope: ['data_write', 'read_only'],
140
+ capabilityTier: 'data_write',
141
+ item: 'SKU-44821 (office supplies, qty 3)',
142
+ outcome: 'settled',
143
+ },
144
+ },
145
+ context: {
146
+ summary: 'Procurement agent purchase was allowed but auto-downgraded to a cheaper model when the daily model budget was hit.',
147
+ },
148
+ };
149
+ }
150
+ }
151
+ //# sourceMappingURL=flows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flows.js","sourceRoot":"","sources":["../../src/samples/flows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Standalone, self-verifying HTML for a sample receipt.
3
+ *
4
+ * The generated page embeds the receipt and, on load, re-derives the entry hash
5
+ * from the receipt's canonical JSON (SubtleCrypto SHA-256) and verifies the
6
+ * Ed25519 signature (SubtleCrypto Ed25519, where supported) — entirely
7
+ * in-browser, no network. If the browser lacks WebCrypto Ed25519, the hash
8
+ * chain is still checked and the page links to agentguard.run/verify with the
9
+ * receipt prefilled for signature verification.
10
+ *
11
+ * The in-browser canonicalJson MUST match src/decision-log.ts canonicalJson so
12
+ * the recomputed hash equals the signed entryHash.
13
+ */
14
+ export interface SampleVerifierData {
15
+ flow: string;
16
+ version: string;
17
+ entry: {
18
+ sequence: number;
19
+ decision: unknown;
20
+ previousHash: string;
21
+ entryHash: string;
22
+ signature: string;
23
+ signerFingerprint: string;
24
+ };
25
+ publicKeyHex: string;
26
+ context: Record<string, unknown>;
27
+ }
28
+ export declare function buildSampleVerifierHtml(data: SampleVerifierData): string;
29
+ //# sourceMappingURL=verifier-html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier-html.d.ts","sourceRoot":"","sources":["../../src/samples/verifier-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAuKxE"}
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ /**
3
+ * Standalone, self-verifying HTML for a sample receipt.
4
+ *
5
+ * The generated page embeds the receipt and, on load, re-derives the entry hash
6
+ * from the receipt's canonical JSON (SubtleCrypto SHA-256) and verifies the
7
+ * Ed25519 signature (SubtleCrypto Ed25519, where supported) — entirely
8
+ * in-browser, no network. If the browser lacks WebCrypto Ed25519, the hash
9
+ * chain is still checked and the page links to agentguard.run/verify with the
10
+ * receipt prefilled for signature verification.
11
+ *
12
+ * The in-browser canonicalJson MUST match src/decision-log.ts canonicalJson so
13
+ * the recomputed hash equals the signed entryHash.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.buildSampleVerifierHtml = buildSampleVerifierHtml;
17
+ function buildSampleVerifierHtml(data) {
18
+ // Embed as JSON in a script tag (safe against </script> injection).
19
+ const payload = JSON.stringify(data).replace(/</g, '\\u003c');
20
+ return `<!doctype html>
21
+ <html lang="en"><head><meta charset="utf-8" />
22
+ <title>AgentGuard Sample Receipt · ${escapeHtml(data.flow)}</title>
23
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
24
+ <style>
25
+ :root { --bg:#07101E; --surface:#0C1828; --border:rgba(42,188,180,0.22); --teal:#2abcb4; --text:#EAF2F6; --muted:#8AA0B3; --green:#4ade80; --red:#FF6B6B; --amber:#F1C40F; }
26
+ * { box-sizing:border-box; margin:0; padding:0; }
27
+ body { background:var(--bg); color:var(--text); font-family:-apple-system,system-ui,'DM Sans',sans-serif; line-height:1.5; padding:32px 16px; }
28
+ .wrap { max-width:820px; margin:0 auto; }
29
+ .brand { display:flex; align-items:center; gap:10px; margin-bottom:8px; }
30
+ .hex { width:22px; height:22px; background:var(--teal); color:var(--bg); display:inline-flex; align-items:center; justify-content:center; font-weight:800; border-radius:4px; }
31
+ h1 { font-size:20px; font-weight:800; }
32
+ .sub { color:var(--muted); font-size:13px; margin-bottom:22px; }
33
+ .card { background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:20px 22px; margin-bottom:18px; }
34
+ .card h2 { font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--teal); margin-bottom:14px; font-family:ui-monospace,monospace; }
35
+ .row { display:flex; justify-content:space-between; gap:16px; padding:7px 0; border-bottom:1px solid rgba(255,255,255,.06); font-size:14px; }
36
+ .row:last-child { border-bottom:none; }
37
+ .row .k { color:var(--muted); }
38
+ .row .v { font-family:ui-monospace,monospace; text-align:right; word-break:break-all; }
39
+ .check { display:flex; align-items:flex-start; gap:10px; padding:9px 0; font-size:14px; }
40
+ .check .dot { width:18px; flex:0 0 18px; }
41
+ .ok { color:var(--green); } .bad { color:var(--red); } .warn { color:var(--amber); } .pending { color:var(--muted); }
42
+ pre { background:#050b14; border:1px solid rgba(255,255,255,.08); border-radius:8px; padding:14px; overflow-x:auto; font-size:12px; color:#cfe; }
43
+ a { color:var(--teal); }
44
+ .foot { color:var(--muted); font-size:12px; text-align:center; margin-top:24px; }
45
+ .badge { display:inline-block; font-family:ui-monospace,monospace; font-size:12px; padding:4px 10px; border-radius:4px; border:1px solid var(--border); }
46
+ </style></head>
47
+ <body><div class="wrap">
48
+ <div class="brand"><span class="hex">&#9187;</span><h1>AgentGuard&#174; Sample Receipt</h1></div>
49
+ <div class="sub">Flow: <b>${escapeHtml(data.flow)}</b> &middot; Self-verifying, offline. This is exactly what your counterparty would receive.</div>
50
+
51
+ <div class="card">
52
+ <h2>Verification</h2>
53
+ <div id="verdict" class="badge pending">verifying&hellip;</div>
54
+ <div id="checks" style="margin-top:12px"></div>
55
+ <div id="fallback" style="margin-top:12px; display:none" class="sub"></div>
56
+ </div>
57
+
58
+ <div class="card">
59
+ <h2>Receipt summary</h2>
60
+ <div id="summary"></div>
61
+ </div>
62
+
63
+ <div class="card">
64
+ <h2>Raw signed entry</h2>
65
+ <pre id="raw"></pre>
66
+ </div>
67
+
68
+ <div class="foot">
69
+ Signature scheme: Ed25519 over SHA-256 of canonical JSON. Zero data plane &mdash; no prompt or completion content is present.<br/>
70
+ <a href="https://agentguard.run/verify">agentguard.run/verify</a> &middot; <a href="https://www.npmjs.com/package/@agentguard-run/spend">npm: @agentguard-run/spend</a>
71
+ </div>
72
+ </div>
73
+
74
+ <script type="application/json" id="agentguard-receipt">${payload}</script>
75
+ <script>
76
+ (function () {
77
+ var DATA = JSON.parse(document.getElementById('agentguard-receipt').textContent);
78
+ var entry = DATA.entry;
79
+
80
+ // canonicalJson MUST match src/decision-log.ts exactly.
81
+ function canonicalJson(value) {
82
+ if (value === null || typeof value !== 'object') {
83
+ if (typeof value === 'number' && !isFinite(value)) throw new Error('non-finite');
84
+ return JSON.stringify(value);
85
+ }
86
+ if (Array.isArray(value)) return '[' + value.map(canonicalJson).join(',') + ']';
87
+ var keys = Object.keys(value).sort();
88
+ return '{' + keys.map(function (k) { return JSON.stringify(k) + ':' + canonicalJson(value[k]); }).join(',') + '}';
89
+ }
90
+ function hexToBytes(hex) {
91
+ var out = new Uint8Array(hex.length / 2);
92
+ for (var i = 0; i < out.length; i++) out[i] = parseInt(hex.substr(i * 2, 2), 16);
93
+ return out;
94
+ }
95
+ function bytesToHex(buf) {
96
+ var b = new Uint8Array(buf), s = '';
97
+ for (var i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, '0');
98
+ return s;
99
+ }
100
+ function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c]; }); }
101
+
102
+ var checksEl = document.getElementById('checks');
103
+ var results = [];
104
+ function addCheck(state, text) {
105
+ results.push(state);
106
+ var cls = state === true ? 'ok' : state === 'pending' ? 'pending' : state === 'warn' ? 'warn' : 'bad';
107
+ var mark = state === true ? '&#10003;' : state === 'pending' ? '&#8987;' : state === 'warn' ? '&#9888;' : '&#10007;';
108
+ checksEl.innerHTML += '<div class="check ' + cls + '"><span class="dot">' + mark + '</span><span>' + text + '</span></div>';
109
+ }
110
+
111
+ function renderSummary() {
112
+ var d = entry.decision || {};
113
+ var oc = d.outcomeReceipt || {};
114
+ var rows = [
115
+ ['Flow', DATA.flow],
116
+ ['Decision', d.action],
117
+ ['Provider', d.provider],
118
+ ['Model (requested)', d.modelRequested],
119
+ ['Model (resolved)', d.modelResolved],
120
+ ['Policy', d.policyId + ' v' + d.policyVersion],
121
+ ['Delegated scope', (oc.delegatedScope || []).join(', ')],
122
+ ['Capability tier', oc.capabilityTier],
123
+ ['Transaction reference', oc.transactionReference],
124
+ ['Amount', oc.amountCents != null ? ('$' + (oc.amountCents / 100).toFixed(2) + ' ' + (oc.currency || '')) : ''],
125
+ ['Signer fingerprint', entry.signerFingerprint]
126
+ ];
127
+ document.getElementById('summary').innerHTML = rows.filter(function (r) { return r[1]; }).map(function (r) {
128
+ return '<div class="row"><span class="k">' + esc(r[0]) + '</span><span class="v">' + esc(r[1]) + '</span></div>';
129
+ }).join('');
130
+ document.getElementById('raw').textContent = JSON.stringify(entry, null, 2);
131
+ }
132
+
133
+ function setVerdict() {
134
+ var el = document.getElementById('verdict');
135
+ var anyBad = results.indexOf(false) !== -1;
136
+ var anyPending = results.indexOf('pending') !== -1;
137
+ if (anyBad) { el.textContent = '✗ verification FAILED'; el.className = 'badge bad'; el.style.borderColor = 'var(--red)'; }
138
+ else if (anyPending) { el.textContent = '⚠ hash chain valid; signature not checked here'; el.className = 'badge warn'; el.style.borderColor = 'var(--amber)'; }
139
+ else { el.textContent = '✓ receipt verified'; el.className = 'badge ok'; el.style.borderColor = 'var(--green)'; }
140
+ }
141
+
142
+ function showFallback() {
143
+ var fb = document.getElementById('fallback');
144
+ fb.style.display = 'block';
145
+ fb.innerHTML = 'This browser lacks WebCrypto Ed25519, so the signature was not checked locally. ' +
146
+ 'Verify the signature at <a href="https://agentguard.run/verify" target="_blank" rel="noopener">agentguard.run/verify</a> ' +
147
+ 'or run <code>agentguard verify</code> on the receipt.json.';
148
+ }
149
+
150
+ (async function run() {
151
+ renderSummary();
152
+ // 1) Genesis linkage
153
+ var isGenesis = entry.previousHash === '0'.repeat(64);
154
+ addCheck(isGenesis ? true : 'warn', 'previousHash is ' + (isGenesis ? 'genesis (chain start)' : 'a prior entry hash'));
155
+
156
+ // 2) Entry hash recomputation
157
+ var payload = { sequence: entry.sequence, decision: entry.decision, previousHash: entry.previousHash, signerFingerprint: entry.signerFingerprint };
158
+ var enc = new TextEncoder().encode(canonicalJson(payload));
159
+ var digest = await crypto.subtle.digest('SHA-256', enc);
160
+ var recomputed = bytesToHex(digest);
161
+ var hashOk = recomputed === entry.entryHash;
162
+ addCheck(hashOk, 'entry hash matches canonical JSON (SHA-256)' + (hashOk ? '' : ' &mdash; MISMATCH'));
163
+
164
+ // 3) Ed25519 signature (WebCrypto where available)
165
+ var sigChecked = false;
166
+ try {
167
+ var pub = await crypto.subtle.importKey('raw', hexToBytes(DATA.publicKeyHex), { name: 'Ed25519' }, false, ['verify']);
168
+ var okSig = await crypto.subtle.verify('Ed25519', pub, hexToBytes(entry.signature), hexToBytes(entry.entryHash));
169
+ addCheck(okSig, 'Ed25519 signature ' + (okSig ? 'valid for the embedded public key' : 'INVALID'));
170
+ sigChecked = true;
171
+ } catch (e) {
172
+ addCheck('pending', 'Ed25519 signature not checked (browser lacks WebCrypto Ed25519)');
173
+ }
174
+ if (!sigChecked) showFallback();
175
+ setVerdict();
176
+ })().catch(function (e) {
177
+ addCheck(false, 'verifier error: ' + esc(e && e.message || e));
178
+ setVerdict();
179
+ });
180
+ })();
181
+ </script>
182
+ </body></html>
183
+ `;
184
+ }
185
+ function escapeHtml(value) {
186
+ return String(value == null ? '' : value).replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
187
+ }
188
+ //# sourceMappingURL=verifier-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier-html.js","sourceRoot":"","sources":["../../src/samples/verifier-html.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;AAiBH,0DAuKC;AAvKD,SAAgB,uBAAuB,CAAC,IAAwB;IAC9D,oEAAoE;IACpE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9D,OAAO;;qCAE4B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA2B5B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;0DAyBO,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6GhE,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAClE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAY,CAAA,CACvF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentguard-run/spend",
3
- "version": "0.15.7",
3
+ "version": "0.15.8",
4
4
  "description": "All terminology and labels used in AgentGuard materials are descriptive of software functionality only, not legal definitions or guarantees of compliance. Terms like receipt, audit log, evidence, audit trail, and attestation refer solely to cryptographically-signed records produced by the software. Full functional-use disclaimer in README.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,97 @@
1
+ import test from 'node:test';
2
+ import { strict as assert } from 'assert';
3
+ import { withSpendGuard, AgentGuardBlockedError } from '../spend-guard';
4
+ import { withSpendGuardAnthropic } from './anthropic';
5
+ import { withSpendGuardBedrock } from './bedrock';
6
+ import { InMemorySpendStore } from '../store-memory';
7
+ import { InMemoryDecisionLogStore } from '../decision-log';
8
+ import { clearCostOverrides, setCostOverride } from '../cost-table';
9
+ import type { SpendPolicy } from '../types';
10
+
11
+ const scope = { tenantId: 'enforce-test' };
12
+
13
+ // A per_call cap of 1c that blocks: any priced call (>1c) is denied. Enforcement
14
+ // is a hard deterministic limit — identical semantics across every binding.
15
+ function blockPolicy(): SpendPolicy {
16
+ return {
17
+ id: 'enforce-block',
18
+ name: 'enforce block',
19
+ scope,
20
+ caps: [{ window: 'per_call', amountCents: 1, action: 'block' }],
21
+ mode: 'enforce',
22
+ version: 1,
23
+ effectiveFrom: '2026-07-16T00:00:00.000Z',
24
+ };
25
+ }
26
+
27
+ function harness() {
28
+ clearCostOverrides();
29
+ // Deterministic priced models per provider family.
30
+ setCostOverride('gpt-price-test', { inputCentsPerKtok: 100, outputCentsPerKtok: 100 });
31
+ setCostOverride('claude-price-test', { inputCentsPerKtok: 100, outputCentsPerKtok: 100 });
32
+ setCostOverride('amazon.price-test', { inputCentsPerKtok: 100, outputCentsPerKtok: 100 });
33
+ return {
34
+ spendStore: new InMemorySpendStore(),
35
+ logStore: new InMemoryDecisionLogStore(),
36
+ tokenEstimator: () => 1000,
37
+ };
38
+ }
39
+
40
+ test('OpenAI binding: priced call over the cap is BLOCKED and provider never called', async () => {
41
+ const cfg = harness();
42
+ let providerCalled = false;
43
+ const client = withSpendGuard(
44
+ { chat: { completions: { create: async () => { providerCalled = true; return {}; } } } },
45
+ { policy: blockPolicy(), scope, config: cfg },
46
+ );
47
+ await assert.rejects(
48
+ () => client.chat.completions.create({ model: 'gpt-price-test', messages: [{ content: 'x' }], max_tokens: 1000 }),
49
+ (e) => e instanceof AgentGuardBlockedError && e.decision.action === 'block' && e.decision.projectedCents === 200,
50
+ );
51
+ assert.equal(providerCalled, false, 'block prevents the provider dispatch');
52
+ });
53
+
54
+ test('Anthropic binding: priced call over the cap is BLOCKED', async () => {
55
+ const cfg = harness();
56
+ let providerCalled = false;
57
+ const client = withSpendGuardAnthropic(
58
+ { messages: { create: async () => { providerCalled = true; return {}; } } },
59
+ { policy: blockPolicy(), scope, config: cfg },
60
+ );
61
+ await assert.rejects(
62
+ () => client.messages.create({ model: 'claude-price-test', messages: [{ role: 'user', content: 'x' }], max_tokens: 1000 }),
63
+ (e) => e instanceof AgentGuardBlockedError && e.decision.projectedCents === 200,
64
+ );
65
+ assert.equal(providerCalled, false);
66
+ });
67
+
68
+ test('Bedrock binding: priced InvokeModel call over the cap is BLOCKED', async () => {
69
+ const cfg = harness();
70
+ let providerCalled = false;
71
+ class InvokeModelCommand { constructor(public input: Record<string, unknown>) {} }
72
+ const client = withSpendGuardBedrock(
73
+ { send: async () => { providerCalled = true; return {}; } },
74
+ { policy: blockPolicy(), scope, config: cfg },
75
+ );
76
+ await assert.rejects(
77
+ () => client.send(new InvokeModelCommand({
78
+ modelId: 'amazon.price-test',
79
+ body: JSON.stringify({ max_tokens: 1000, messages: [{ role: 'user', content: [{ type: 'text', text: 'x' }] }] }),
80
+ })),
81
+ (e) => e instanceof AgentGuardBlockedError && e.decision.projectedCents === 200,
82
+ );
83
+ assert.equal(providerCalled, false);
84
+ });
85
+
86
+ test('non-InvokeModel Bedrock commands pass through ungated (cost/enforce only on inference)', async () => {
87
+ const cfg = harness();
88
+ let passed = false;
89
+ class ListFoundationModelsCommand { constructor(public input: Record<string, unknown>) {} }
90
+ const client = withSpendGuardBedrock(
91
+ { send: async () => { passed = true; return { models: [] }; } },
92
+ { policy: blockPolicy(), scope, config: cfg },
93
+ );
94
+ const res = await client.send(new ListFoundationModelsCommand({}));
95
+ assert.deepEqual(res, { models: [] });
96
+ assert.equal(passed, true);
97
+ });
@@ -99,7 +99,14 @@ export interface CfoDashboard {
99
99
  byProvider: BucketSpend[];
100
100
  byBuilderCode: BucketSpend[];
101
101
  scopeKeyBreakdown: BucketSpend[]; // best-effort from triggeredScopeKey (may be sparse)
102
- integrity: { verified: boolean; entries: number; reason?: string; sequence?: number };
102
+ integrity: {
103
+ verified: boolean;
104
+ entries: number;
105
+ reason?: string;
106
+ sequence?: number;
107
+ /** Completeness signal: missing per-signer sequence numbers (possible omitted actions). */
108
+ sequenceGaps?: number[];
109
+ };
103
110
  }
104
111
 
105
112
  function topBuckets(map: Map<string, BucketSpend>, limit = 50): BucketSpend[] {