@agentguard-run/spend 0.15.2 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/dashboard/aggregate.d.ts +90 -0
- package/dist/dashboard/aggregate.d.ts.map +1 -0
- package/dist/dashboard/aggregate.js +147 -0
- package/dist/dashboard/aggregate.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +60 -0
- package/dist/policy.js.map +1 -1
- package/dist/receipts/portability.d.ts +76 -0
- package/dist/receipts/portability.d.ts.map +1 -0
- package/dist/receipts/portability.js +88 -0
- package/dist/receipts/portability.js.map +1 -0
- package/dist/types.d.ts +50 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -4
- package/src/dashboard/aggregate.test.ts +103 -0
- package/src/dashboard/aggregate.ts +201 -0
- package/src/receipts/portability.test.ts +68 -0
- package/src/receipts/portability.ts +156 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatLineage = void 0;
|
|
4
|
+
exports.workloadProvenance = workloadProvenance;
|
|
5
|
+
const aggregate_1 = require("../dashboard/aggregate");
|
|
6
|
+
const defaultKeyOf = (d) => d.triggeredScopeKey ?? 'default';
|
|
7
|
+
/**
|
|
8
|
+
* Build the portable per-workload provenance manifest from signed ledger
|
|
9
|
+
* entries. Pass the async `verifyChain` result as `continuity` so this stays a
|
|
10
|
+
* pure, synchronous function (never null-continuity in production — a manifest
|
|
11
|
+
* without tamper evidence is not the product).
|
|
12
|
+
*/
|
|
13
|
+
function workloadProvenance(entries, continuity = { verified: false, entries: 0, reason: 'NOT_CHECKED' }, keyOf = defaultKeyOf) {
|
|
14
|
+
const groups = new Map();
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const d = entry.decision;
|
|
17
|
+
const kind = d.entryType ?? 'decision';
|
|
18
|
+
if (kind !== 'decision')
|
|
19
|
+
continue; // settlements/outcomes don't add model steps
|
|
20
|
+
const key = keyOf(d);
|
|
21
|
+
const grp = groups.get(key) ?? {
|
|
22
|
+
calls: 0, spent: 0, frontier: 0, dark: 0, first: null, last: null,
|
|
23
|
+
models: new Map(), ordered: [],
|
|
24
|
+
};
|
|
25
|
+
const model = d.modelResolved || d.modelRequested || 'unknown';
|
|
26
|
+
const { origin } = (0, aggregate_1.classifyOrigin)(d);
|
|
27
|
+
const cents = (0, aggregate_1.decisionCents)(d);
|
|
28
|
+
grp.calls += 1;
|
|
29
|
+
grp.spent += cents;
|
|
30
|
+
if (origin === 'frontier')
|
|
31
|
+
grp.frontier += cents;
|
|
32
|
+
else if (origin === 'dark')
|
|
33
|
+
grp.dark += cents;
|
|
34
|
+
if (d.timestamp) {
|
|
35
|
+
if (!grp.first || d.timestamp < grp.first)
|
|
36
|
+
grp.first = d.timestamp;
|
|
37
|
+
if (!grp.last || d.timestamp > grp.last)
|
|
38
|
+
grp.last = d.timestamp;
|
|
39
|
+
}
|
|
40
|
+
const mu = grp.models.get(model) ?? { model, origin, provider: d.provider ?? 'unknown', calls: 0, cents: 0 };
|
|
41
|
+
mu.calls += 1;
|
|
42
|
+
mu.cents += cents;
|
|
43
|
+
grp.models.set(model, mu);
|
|
44
|
+
grp.ordered.push({ seq: entry.sequence, model, origin });
|
|
45
|
+
groups.set(key, grp);
|
|
46
|
+
}
|
|
47
|
+
const workloads = [];
|
|
48
|
+
for (const [key, grp] of groups) {
|
|
49
|
+
grp.ordered.sort((a, b) => a.seq - b.seq);
|
|
50
|
+
const swaps = [];
|
|
51
|
+
for (let i = 1; i < grp.ordered.length; i++) {
|
|
52
|
+
const prev = grp.ordered[i - 1];
|
|
53
|
+
const cur = grp.ordered[i];
|
|
54
|
+
if (cur.model !== prev.model) {
|
|
55
|
+
swaps.push({
|
|
56
|
+
atSequence: cur.seq,
|
|
57
|
+
fromModel: prev.model, toModel: cur.model,
|
|
58
|
+
fromOrigin: prev.origin, toOrigin: cur.origin,
|
|
59
|
+
crossesBoundary: prev.origin !== cur.origin
|
|
60
|
+
&& prev.origin !== 'unknown' && cur.origin !== 'unknown',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// lineage = models in first-appearance order (collapse consecutive repeats)
|
|
65
|
+
const lineage = [];
|
|
66
|
+
for (const step of grp.ordered)
|
|
67
|
+
if (lineage[lineage.length - 1] !== step.model)
|
|
68
|
+
lineage.push(step.model);
|
|
69
|
+
workloads.push({
|
|
70
|
+
key,
|
|
71
|
+
calls: grp.calls,
|
|
72
|
+
spentCents: grp.spent,
|
|
73
|
+
frontierCents: grp.frontier,
|
|
74
|
+
darkCents: grp.dark,
|
|
75
|
+
firstAt: grp.first,
|
|
76
|
+
lastAt: grp.last,
|
|
77
|
+
models: [...grp.models.values()].sort((a, b) => b.cents - a.cents),
|
|
78
|
+
lineage,
|
|
79
|
+
swaps,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
workloads.sort((a, b) => b.spentCents - a.spentCents);
|
|
83
|
+
return { workloads, continuity };
|
|
84
|
+
}
|
|
85
|
+
/** Human-readable lineage, e.g. "claude-5 → gpt-5-mini → glm-5.2". */
|
|
86
|
+
const formatLineage = (w) => w.lineage.join(' → ');
|
|
87
|
+
exports.formatLineage = formatLineage;
|
|
88
|
+
//# sourceMappingURL=portability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portability.js","sourceRoot":"","sources":["../../src/receipts/portability.ts"],"names":[],"mappings":";;;AAwEA,gDAgFC;AA7HD,sDAAyF;AAqCzF,MAAM,YAAY,GAAG,CAAC,CAAgB,EAAU,EAAE,CAAC,CAAC,CAAC,iBAAiB,IAAI,SAAS,CAAC;AAEpF;;;;;GAKG;AACH,SAAgB,kBAAkB,CAChC,OAAiC,EACjC,aAAqD,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,EAC3G,QAAsC,YAAY;IAOlD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC;QACvC,IAAI,IAAI,KAAK,UAAU;YAAE,SAAS,CAAC,6CAA6C;QAEhF,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAU,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;YACpC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;YACjE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE;SAC/B,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,cAAc,IAAI,SAAS,CAAC;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,0BAAc,EAAC,CAAC,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,IAAA,yBAAa,EAAC,CAAC,CAAC,CAAC;QAE/B,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;QACf,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;QACnB,IAAI,MAAM,KAAK,UAAU;YAAE,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC;aAC5C,IAAI,MAAM,KAAK,MAAM;YAAE,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC;QAC9C,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,KAAK;gBAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC;YACnE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,IAAI;gBAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC;QAClE,CAAC;QACD,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC7G,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;QACd,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC;QAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,SAAS,GAAyB,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;QAChC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAgB,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC;oBACT,UAAU,EAAE,GAAG,CAAC,GAAG;oBACnB,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK;oBACzC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM;oBAC7C,eAAe,EAAE,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;2BACtC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;iBAC3D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,4EAA4E;QAC5E,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO;YAAE,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzG,SAAS,CAAC,IAAI,CAAC;YACb,GAAG;YACH,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,UAAU,EAAE,GAAG,CAAC,KAAK;YACrB,aAAa,EAAE,GAAG,CAAC,QAAQ;YAC3B,SAAS,EAAE,GAAG,CAAC,IAAI;YACnB,OAAO,EAAE,GAAG,CAAC,KAAK;YAClB,MAAM,EAAE,GAAG,CAAC,IAAI;YAChB,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YAClE,OAAO;YACP,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IACtD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACnC,CAAC;AAED,sEAAsE;AAC/D,MAAM,aAAa,GAAG,CAAC,CAAqB,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAAzE,QAAA,aAAa,iBAA4D"}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,6 +16,36 @@ export type SpendWindow = 'per_call' | 'per_minute' | 'per_hour' | 'per_day' | '
|
|
|
16
16
|
export type Provider = 'openai' | 'anthropic' | 'bedrock' | 'gemini' | 'unknown';
|
|
17
17
|
export type EnforcementMode = 'shadow' | 'canary' | 'enforce';
|
|
18
18
|
export type CapabilityTier = 'read_only' | 'data_write' | 'payment_initiate' | 'payment_execute';
|
|
19
|
+
/**
|
|
20
|
+
* DAG-TAT attestation requirement attached to a SpendPolicy.
|
|
21
|
+
*
|
|
22
|
+
* Claims listed in `requireFor` are no longer trusted as self-declared
|
|
23
|
+
* strings: the call must carry an attestation chain (a signed receipt DAG)
|
|
24
|
+
* that verifies under `signerKeys` and clears the trust/depth gate for the
|
|
25
|
+
* claimed tier. Node/envelope shapes are defined in receipts/dag.ts; they are
|
|
26
|
+
* typed structurally here to keep core types free of that dependency.
|
|
27
|
+
*/
|
|
28
|
+
export interface AttestationRequirement {
|
|
29
|
+
/** Capability claims that must be backed by a verified attestation chain. */
|
|
30
|
+
requireFor: CapabilityTier[];
|
|
31
|
+
/**
|
|
32
|
+
* Trusted Ed25519 signer public keys: a single hex/raw key, or a map of
|
|
33
|
+
* signer fingerprint -> key for multi-signer chains.
|
|
34
|
+
*/
|
|
35
|
+
signerKeys: Record<string, string> | string;
|
|
36
|
+
/**
|
|
37
|
+
* Optional per-level overrides of the trust/depth gate thresholds
|
|
38
|
+
* (levels: READ_ONLY | TRANSACT | ADMIN | ORCHESTRATE).
|
|
39
|
+
*/
|
|
40
|
+
thresholds?: Partial<Record<'READ_ONLY' | 'TRANSACT' | 'ADMIN' | 'ORCHESTRATE', {
|
|
41
|
+
minTrust?: number;
|
|
42
|
+
minDepth?: number;
|
|
43
|
+
}>>;
|
|
44
|
+
}
|
|
45
|
+
/** Structural shape for an attestation chain carried on a call. */
|
|
46
|
+
export type AttestationChainInput = ReadonlyArray<Record<string, unknown>> | {
|
|
47
|
+
nodes: ReadonlyArray<Record<string, unknown>>;
|
|
48
|
+
};
|
|
19
49
|
/**
|
|
20
50
|
* A spend cap with one or more thresholds across configurable windows.
|
|
21
51
|
* All amounts are USD cents (integer math, no floating-point cost drift).
|
|
@@ -97,12 +127,22 @@ export interface SpendPolicy {
|
|
|
97
127
|
*
|
|
98
128
|
* The tier set is informed by the capability-tier framework of Patent D
|
|
99
129
|
* §7.3 (App. No. 63/984,626). The SDK enforces a flat ordered comparison
|
|
100
|
-
* between the call's capability claim and this requirement.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
130
|
+
* between the call's capability claim and this requirement. To require the
|
|
131
|
+
* claim itself to be PROVEN rather than self-declared, also set
|
|
132
|
+
* `attestation`: listed claims must be backed by a verified receipt-DAG
|
|
133
|
+
* attestation chain (DAG-TAT) or the call is blocked.
|
|
104
134
|
*/
|
|
105
135
|
requiredCapability?: CapabilityTier;
|
|
136
|
+
/** Optional DAG-TAT attestation requirement for capability claims.
|
|
137
|
+
*
|
|
138
|
+
* When present, any call whose `capabilityClaim` is listed in
|
|
139
|
+
* `attestation.requireFor` must carry a `CallContext.attestation` chain
|
|
140
|
+
* that (a) verifies as a signed, acyclic receipt DAG under `signerKeys`
|
|
141
|
+
* and (b) clears the trust/depth gate for the claimed tier. Verification
|
|
142
|
+
* is local (Ed25519, no network). Fails closed: a listed claim without a
|
|
143
|
+
* valid chain blocks in every enforcement mode.
|
|
144
|
+
*/
|
|
145
|
+
attestation?: AttestationRequirement;
|
|
106
146
|
/** Optional governance posture used by Advisor and provenance policy. */
|
|
107
147
|
posture?: GovernancePosture;
|
|
108
148
|
/** Optional outcome definitions for Reviewer Cascade alpha policies. */
|
|
@@ -150,6 +190,12 @@ export interface CallContext {
|
|
|
150
190
|
builderCode?: string;
|
|
151
191
|
/** Optional capability tier the caller claims */
|
|
152
192
|
capabilityClaim?: CapabilityTier;
|
|
193
|
+
/**
|
|
194
|
+
* Optional DAG-TAT attestation chain backing the capability claim.
|
|
195
|
+
* Required when the policy's `attestation.requireFor` lists the claimed
|
|
196
|
+
* tier. An array of signed receipt-DAG nodes or an envelope of them.
|
|
197
|
+
*/
|
|
198
|
+
attestation?: AttestationChainInput;
|
|
153
199
|
/** Optional consent receipt for foreign origin model weights. */
|
|
154
200
|
foreignOriginConsentReceiptId?: string;
|
|
155
201
|
/** Captured provider provenance for the call. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentguard-run/spend",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.4",
|
|
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",
|
|
@@ -148,14 +148,18 @@
|
|
|
148
148
|
"src/cli/byo.ts",
|
|
149
149
|
"docs/patents/CLAIM_MAPPING.md",
|
|
150
150
|
"src/frameworks",
|
|
151
|
-
"src/operating-pack.ts"
|
|
151
|
+
"src/operating-pack.ts",
|
|
152
|
+
"src/dashboard"
|
|
152
153
|
],
|
|
153
154
|
"scripts": {
|
|
154
155
|
"build": "tsc",
|
|
155
156
|
"prepublishOnly": "npm run build",
|
|
156
157
|
"clean": "rm -rf dist dist-test",
|
|
157
|
-
"
|
|
158
|
-
"
|
|
158
|
+
"demo:attestation": "npx --yes tsx examples/dag-attestation-demo.ts",
|
|
159
|
+
"test": "AGENTGUARD_HOME=./dist-test/home tsc -p tsconfig.test.json && rm -rf dist-test/home && AGENTGUARD_HOME=./dist-test/home AGENTGUARD_LICENSE_ENDPOINT=http://127.0.0.1:9 node --test dist-test/**/*.test.js",
|
|
160
|
+
"verify": "node dist/verify-test-vector.js",
|
|
161
|
+
"demo:dashboard": "npx --yes tsx examples/cfo-dashboard-demo.ts",
|
|
162
|
+
"demo:hotswap": "npx --yes tsx examples/hot-swap-provenance-demo.ts"
|
|
159
163
|
},
|
|
160
164
|
"keywords": [
|
|
161
165
|
"ai-agent-security",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { aggregateLedger, classifyOrigin, decisionCents } from './aggregate';
|
|
4
|
+
import type { SignedDecisionLogEntry, SpendDecision, Provider } from '../types';
|
|
5
|
+
import type { ProvenanceProvider } from '../receipts/schema';
|
|
6
|
+
|
|
7
|
+
let seq = 0;
|
|
8
|
+
function entry(d: Partial<SpendDecision>): SignedDecisionLogEntry {
|
|
9
|
+
const decision: SpendDecision = {
|
|
10
|
+
decisionId: `d${seq}`,
|
|
11
|
+
timestamp: '2026-07-10T14:00:00.000Z',
|
|
12
|
+
action: 'allow',
|
|
13
|
+
triggeredCap: null,
|
|
14
|
+
triggeredScopeKey: null,
|
|
15
|
+
projectedCents: 0,
|
|
16
|
+
windowSpendBefore: 0,
|
|
17
|
+
windowSpendAfter: 0,
|
|
18
|
+
provider: 'openai',
|
|
19
|
+
modelRequested: 'gpt-5',
|
|
20
|
+
modelResolved: 'gpt-5',
|
|
21
|
+
policyId: 'p',
|
|
22
|
+
policyVersion: 1,
|
|
23
|
+
enforcementMode: 'enforce',
|
|
24
|
+
reasons: [],
|
|
25
|
+
...d,
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
sequence: seq++, decision, previousHash: '0'.repeat(64),
|
|
29
|
+
entryHash: 'x', signature: 'y', signerFingerprint: 'f',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function withProvenance(fam: ProvenanceProvider, route = 'api'): SpendDecision['provenance'] {
|
|
33
|
+
return {
|
|
34
|
+
model_identity: { provider: fam, model_id: 'm', model_version: '1', model_family: 'x', weights_origin_country: 'US' },
|
|
35
|
+
hosting: { provider_route: route, jurisdiction_country: 'US', jurisdiction_region: 'us' },
|
|
36
|
+
compliance: {
|
|
37
|
+
baa_in_force: false, baa_vendor: null, hipaa_eligible: false, data_retention_days: null,
|
|
38
|
+
data_residency_attested: false, foreign_origin_weight_flag: false,
|
|
39
|
+
foreign_origin_consent_receipt_id: null, inference_billing: 'customer_managed',
|
|
40
|
+
},
|
|
41
|
+
captured_at: '2026-07-10T14:00:00.000Z',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
test('classifyOrigin: self-hosted provenance = dark, not inferred', () => {
|
|
46
|
+
const d = entry({ provenance: withProvenance('self_hosted') }).decision;
|
|
47
|
+
assert.deepEqual(classifyOrigin(d), { origin: 'dark', inferred: false });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('classifyOrigin: open-weight family = dark; frontier family = frontier', () => {
|
|
51
|
+
assert.equal(classifyOrigin(entry({ provenance: withProvenance('deepseek') }).decision).origin, 'dark');
|
|
52
|
+
assert.equal(classifyOrigin(entry({ provenance: withProvenance('anthropic') }).decision).origin, 'frontier');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('classifyOrigin: no provenance falls back to provider and is flagged inferred', () => {
|
|
56
|
+
assert.deepEqual(classifyOrigin(entry({ provider: 'anthropic' }).decision), { origin: 'frontier', inferred: true });
|
|
57
|
+
assert.deepEqual(classifyOrigin(entry({ provider: 'unknown' as Provider }).decision), { origin: 'dark', inferred: true });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('decisionCents: blocked = 0, settled actual beats projection', () => {
|
|
61
|
+
assert.equal(decisionCents(entry({ action: 'block', projectedCents: 500 }).decision), 0);
|
|
62
|
+
assert.equal(decisionCents(entry({ projectedCents: 500, actualCents: 420 }).decision), 420);
|
|
63
|
+
assert.equal(decisionCents(entry({ projectedCents: 500 }).decision), 500);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('aggregate: dark share, savings, true-up, and buckets', () => {
|
|
67
|
+
seq = 0;
|
|
68
|
+
const entries = [
|
|
69
|
+
entry({ action: 'allow', provider: 'anthropic', modelResolved: 'claude-5', projectedCents: 100, actualCents: 100, provenance: withProvenance('anthropic') }),
|
|
70
|
+
entry({ action: 'allow', modelResolved: 'glm-5.2', projectedCents: 4, actualCents: 4, provider: 'unknown' as Provider, provenance: withProvenance('self_hosted', 'self-hosted-gpu') }),
|
|
71
|
+
entry({ action: 'downgrade', provider: 'openai', modelResolved: 'gpt-5-mini', projectedCents: 200, actualCents: 20 }),
|
|
72
|
+
entry({ action: 'block', provider: 'openai', modelResolved: 'gpt-5', projectedCents: 300 }),
|
|
73
|
+
entry({ entryType: 'settlement', actualCents: 98, projectedCents: 0 }),
|
|
74
|
+
];
|
|
75
|
+
const dash = aggregateLedger(entries, { verified: true, entries: entries.length });
|
|
76
|
+
|
|
77
|
+
// 4 enforcement decisions (settlement not counted as a call)
|
|
78
|
+
assert.equal(dash.totals.calls, 4);
|
|
79
|
+
// spend = 100 + 4 + 20 + 0(blocked) = 124
|
|
80
|
+
assert.equal(dash.totals.spentCents, 124);
|
|
81
|
+
assert.equal(dash.totals.darkCents, 4);
|
|
82
|
+
assert.equal(dash.totals.frontierCents, 120); // 100 anthropic + 20 downgraded openai(inferred frontier)
|
|
83
|
+
assert.equal(dash.totals.darkSharePct, Math.round((4 / 124) * 1000) / 10);
|
|
84
|
+
// savings = downgrade delta (200-20=180) + blocked projection (300) = 480
|
|
85
|
+
assert.equal(dash.enforcement.estimatedSavedCents, 480);
|
|
86
|
+
assert.equal(dash.enforcement.blocked, 1);
|
|
87
|
+
assert.equal(dash.enforcement.downgraded, 1);
|
|
88
|
+
// true-up: settled actual 98 vs reserved (100+4+200+300=604)
|
|
89
|
+
assert.equal(dash.trueUp.settledCents, 98);
|
|
90
|
+
assert.equal(dash.trueUp.reservedCents, 604);
|
|
91
|
+
assert.equal(dash.trueUp.driftCents, 98 - 604);
|
|
92
|
+
// integrity passthrough
|
|
93
|
+
assert.equal(dash.integrity.verified, true);
|
|
94
|
+
// model bucket present
|
|
95
|
+
assert.ok(dash.byModel.find(b => b.key === 'claude-5' && b.cents === 100));
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('aggregate: empty ledger is safe', () => {
|
|
99
|
+
const dash = aggregateLedger([]);
|
|
100
|
+
assert.equal(dash.totals.calls, 0);
|
|
101
|
+
assert.equal(dash.totals.darkSharePct, 0);
|
|
102
|
+
assert.equal(dash.integrity.verified, false);
|
|
103
|
+
});
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentGuard® — CFO cost dashboard, read side.
|
|
3
|
+
*
|
|
4
|
+
* Aggregates the signed, hash-chained decision log into a CFO-legible view:
|
|
5
|
+
* spend over time, by model, by provider, frontier-vs-"dark" (local /
|
|
6
|
+
* open-weight / self-hosted) tokens, reserved-vs-settled true-up, an
|
|
7
|
+
* enforcement/savings summary, and a tamper-evidence check. Everything is
|
|
8
|
+
* derived IN-PROCESS from the customer-held ledger — no proxy, no data plane,
|
|
9
|
+
* no provider billing API required.
|
|
10
|
+
*
|
|
11
|
+
* The "dark token" view is the differentiator: open-source / self-hosted usage
|
|
12
|
+
* never appears on any provider's bill, so a provider console structurally
|
|
13
|
+
* cannot show it. The signed ledger can, because the receipt is written where
|
|
14
|
+
* the call is made.
|
|
15
|
+
*
|
|
16
|
+
* Honest scope note: the signed SpendDecision carries time, provider, model,
|
|
17
|
+
* cents, action, builderCode, entryType and a provenance block — but NOT full
|
|
18
|
+
* tenant/agent identity (only the scope key a cap matched on). Per-agent /
|
|
19
|
+
* per-tenant breakdown therefore requires recording a metadata-only scope
|
|
20
|
+
* digest on the decision; see `scopeKeyBreakdown` (best-effort from
|
|
21
|
+
* triggeredScopeKey) and DASHBOARD.md. We do not invent attribution the ledger
|
|
22
|
+
* does not carry.
|
|
23
|
+
*
|
|
24
|
+
* Patent notice: signed hash-chained decision log (U.S. application filed May
|
|
25
|
+
* 2026); composes with DAG Trust Attestation, Patent D §7.3 (App. No.
|
|
26
|
+
* 63/984,626). AgentGuard® is a U.S. registered trademark (Reg. No. 8281464)
|
|
27
|
+
* of Dunecrest Ventures Inc.
|
|
28
|
+
*/
|
|
29
|
+
import type { Provider, SignedDecisionLogEntry, SpendDecision } from '../types';
|
|
30
|
+
import type { ProvenanceProvider } from '../receipts/schema';
|
|
31
|
+
|
|
32
|
+
/** Model families that are open-weight / self-hostable → "dark" when self-hosted. */
|
|
33
|
+
const OPEN_WEIGHT_FAMILIES = new Set<ProvenanceProvider>([
|
|
34
|
+
'meta', 'mistral', 'cohere', 'fireworks', 'baseten', 'together',
|
|
35
|
+
'deepseek', 'moonshot', 'alibaba', 'self_hosted',
|
|
36
|
+
]);
|
|
37
|
+
const FRONTIER_PROVIDERS = new Set<Provider>(['openai', 'anthropic', 'gemini', 'bedrock']);
|
|
38
|
+
|
|
39
|
+
export type TokenOrigin = 'frontier' | 'dark' | 'unknown';
|
|
40
|
+
|
|
41
|
+
/** Classify a decision as frontier vs dark (local/open-weight) spend.
|
|
42
|
+
* Prefers the signed provenance block; falls back to the coarse provider
|
|
43
|
+
* field and labels the result `inferred` so the UI never overstates. */
|
|
44
|
+
export function classifyOrigin(decision: SpendDecision): { origin: TokenOrigin; inferred: boolean } {
|
|
45
|
+
const prov = decision.provenance;
|
|
46
|
+
if (prov?.model_identity) {
|
|
47
|
+
const fam = prov.model_identity.provider;
|
|
48
|
+
if (fam === 'self_hosted') return { origin: 'dark', inferred: false };
|
|
49
|
+
const selfHosted = /self|local|on[-_]?prem|in[-_]?house/i.test(prov.hosting?.provider_route ?? '');
|
|
50
|
+
if (selfHosted) return { origin: 'dark', inferred: false };
|
|
51
|
+
if (OPEN_WEIGHT_FAMILIES.has(fam)) return { origin: 'dark', inferred: false };
|
|
52
|
+
if (fam === 'anthropic' || fam === 'openai' || fam === 'google') return { origin: 'frontier', inferred: false };
|
|
53
|
+
}
|
|
54
|
+
if (FRONTIER_PROVIDERS.has(decision.provider)) return { origin: 'frontier', inferred: true };
|
|
55
|
+
if (decision.provider === 'unknown') return { origin: 'dark', inferred: true };
|
|
56
|
+
return { origin: 'unknown', inferred: true };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Cents this decision actually cost the org: settled actuals win over the
|
|
60
|
+
* pre-dispatch projection; blocked calls cost zero. */
|
|
61
|
+
export function decisionCents(decision: SpendDecision): number {
|
|
62
|
+
if (decision.action === 'block') return 0;
|
|
63
|
+
if (typeof decision.actualCents === 'number') return decision.actualCents;
|
|
64
|
+
return decision.projectedCents ?? 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface BucketSpend {
|
|
68
|
+
key: string;
|
|
69
|
+
cents: number;
|
|
70
|
+
calls: number;
|
|
71
|
+
}
|
|
72
|
+
export interface CfoDashboard {
|
|
73
|
+
generatedAt: string;
|
|
74
|
+
windowStart: string | null;
|
|
75
|
+
windowEnd: string | null;
|
|
76
|
+
totals: {
|
|
77
|
+
calls: number;
|
|
78
|
+
spentCents: number;
|
|
79
|
+
frontierCents: number;
|
|
80
|
+
darkCents: number;
|
|
81
|
+
darkSharePct: number; // dark / total spend, 0..100
|
|
82
|
+
inferredCents: number; // spend whose origin was inferred, not from provenance
|
|
83
|
+
};
|
|
84
|
+
enforcement: {
|
|
85
|
+
allowed: number;
|
|
86
|
+
downgraded: number;
|
|
87
|
+
blocked: number;
|
|
88
|
+
shadow: number;
|
|
89
|
+
/** Cents NOT spent because a call was blocked or downgraded — the ROI line. */
|
|
90
|
+
estimatedSavedCents: number;
|
|
91
|
+
};
|
|
92
|
+
trueUp: {
|
|
93
|
+
reservedCents: number; // sum of projections on decision entries
|
|
94
|
+
settledCents: number; // sum of actuals on settlement entries
|
|
95
|
+
driftCents: number; // settled - reserved (over/under-estimate)
|
|
96
|
+
};
|
|
97
|
+
byHour: BucketSpend[]; // ISO hour → spend
|
|
98
|
+
byModel: BucketSpend[]; // modelResolved → spend, desc
|
|
99
|
+
byProvider: BucketSpend[];
|
|
100
|
+
byBuilderCode: BucketSpend[];
|
|
101
|
+
scopeKeyBreakdown: BucketSpend[]; // best-effort from triggeredScopeKey (may be sparse)
|
|
102
|
+
integrity: { verified: boolean; entries: number; reason?: string; sequence?: number };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function topBuckets(map: Map<string, BucketSpend>, limit = 50): BucketSpend[] {
|
|
106
|
+
return [...map.values()].sort((a, b) => b.cents - a.cents).slice(0, limit);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function bump(map: Map<string, BucketSpend>, key: string, cents: number) {
|
|
110
|
+
const cur = map.get(key) ?? { key, cents: 0, calls: 0 };
|
|
111
|
+
cur.cents += cents;
|
|
112
|
+
cur.calls += 1;
|
|
113
|
+
map.set(key, cur);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Build the CFO dashboard from signed ledger entries. Pure + synchronous.
|
|
118
|
+
* `integrity` is passed in (compute via verifyChain, which is async) so this
|
|
119
|
+
* stays a pure function; pass null to skip.
|
|
120
|
+
*/
|
|
121
|
+
export function aggregateLedger(
|
|
122
|
+
entries: SignedDecisionLogEntry[],
|
|
123
|
+
integrity: CfoDashboard['integrity'] | null = null,
|
|
124
|
+
now: string = new Date().toISOString(),
|
|
125
|
+
): CfoDashboard {
|
|
126
|
+
const byHour = new Map<string, BucketSpend>();
|
|
127
|
+
const byModel = new Map<string, BucketSpend>();
|
|
128
|
+
const byProvider = new Map<string, BucketSpend>();
|
|
129
|
+
const byBuilder = new Map<string, BucketSpend>();
|
|
130
|
+
const byScopeKey = new Map<string, BucketSpend>();
|
|
131
|
+
|
|
132
|
+
let calls = 0, spent = 0, frontier = 0, dark = 0, inferred = 0;
|
|
133
|
+
let allowed = 0, downgraded = 0, blocked = 0, shadow = 0, saved = 0;
|
|
134
|
+
let reserved = 0, settled = 0;
|
|
135
|
+
let minTs: string | null = null, maxTs: string | null = null;
|
|
136
|
+
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const d = entry.decision;
|
|
139
|
+
const kind = d.entryType ?? 'decision';
|
|
140
|
+
|
|
141
|
+
if (kind === 'settlement') {
|
|
142
|
+
if (typeof d.actualCents === 'number') settled += d.actualCents;
|
|
143
|
+
// settlement entries adjust true-up only; not double-counted as calls
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (kind === 'outcome' || kind === 'governance') continue;
|
|
147
|
+
|
|
148
|
+
// provider enforcement decision
|
|
149
|
+
calls += 1;
|
|
150
|
+
const cents = decisionCents(d);
|
|
151
|
+
spent += cents;
|
|
152
|
+
reserved += d.projectedCents ?? 0;
|
|
153
|
+
|
|
154
|
+
const { origin, inferred: wasInferred } = classifyOrigin(d);
|
|
155
|
+
if (origin === 'frontier') frontier += cents;
|
|
156
|
+
else if (origin === 'dark') dark += cents;
|
|
157
|
+
if (wasInferred) inferred += cents;
|
|
158
|
+
|
|
159
|
+
switch (d.action) {
|
|
160
|
+
case 'allow': allowed += 1; break;
|
|
161
|
+
case 'downgrade': downgraded += 1; saved += Math.max(0, (d.projectedCents ?? 0) - cents); break;
|
|
162
|
+
case 'block': blocked += 1; saved += d.projectedCents ?? 0; break;
|
|
163
|
+
case 'shadow': shadow += 1; break;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const ts = d.timestamp;
|
|
167
|
+
if (ts) {
|
|
168
|
+
if (!minTs || ts < minTs) minTs = ts;
|
|
169
|
+
if (!maxTs || ts > maxTs) maxTs = ts;
|
|
170
|
+
bump(byHour, ts.slice(0, 13) + ':00', cents); // ISO hour bucket
|
|
171
|
+
}
|
|
172
|
+
bump(byModel, d.modelResolved || d.modelRequested || 'unknown', cents);
|
|
173
|
+
bump(byProvider, d.provider || 'unknown', cents);
|
|
174
|
+
if (d.builderCode) bump(byBuilder, d.builderCode, cents);
|
|
175
|
+
if (d.triggeredScopeKey) bump(byScopeKey, d.triggeredScopeKey, cents);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
generatedAt: now,
|
|
180
|
+
windowStart: minTs,
|
|
181
|
+
windowEnd: maxTs,
|
|
182
|
+
totals: {
|
|
183
|
+
calls,
|
|
184
|
+
spentCents: spent,
|
|
185
|
+
frontierCents: frontier,
|
|
186
|
+
darkCents: dark,
|
|
187
|
+
darkSharePct: spent > 0 ? Math.round((dark / spent) * 1000) / 10 : 0,
|
|
188
|
+
inferredCents: inferred,
|
|
189
|
+
},
|
|
190
|
+
enforcement: { allowed, downgraded, blocked, shadow, estimatedSavedCents: saved },
|
|
191
|
+
trueUp: { reservedCents: reserved, settledCents: settled, driftCents: settled - reserved },
|
|
192
|
+
byHour: [...byHour.values()].sort((a, b) => a.key.localeCompare(b.key)),
|
|
193
|
+
byModel: topBuckets(byModel),
|
|
194
|
+
byProvider: topBuckets(byProvider),
|
|
195
|
+
byBuilderCode: topBuckets(byBuilder),
|
|
196
|
+
scopeKeyBreakdown: topBuckets(byScopeKey),
|
|
197
|
+
integrity: integrity ?? { verified: false, entries: entries.length, reason: 'NOT_CHECKED' },
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export const centsToUsd = (c: number): string => `$${(c / 100).toFixed(2)}`;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { workloadProvenance, formatLineage } from './portability';
|
|
4
|
+
import type { SignedDecisionLogEntry, SpendDecision, Provider } from '../types';
|
|
5
|
+
import type { ProvenanceProvider } from './schema';
|
|
6
|
+
|
|
7
|
+
let seq = 0;
|
|
8
|
+
function entry(model: string, fam: ProvenanceProvider, route: string, extra: Partial<SpendDecision> = {}): SignedDecisionLogEntry {
|
|
9
|
+
const decision: SpendDecision = {
|
|
10
|
+
decisionId: `d${seq}`, timestamp: `2026-07-10T14:${String(seq).padStart(2, '0')}:00.000Z`,
|
|
11
|
+
action: 'allow', triggeredCap: null, triggeredScopeKey: 'tenant:acme|agent:planner',
|
|
12
|
+
projectedCents: 10, actualCents: 10, windowSpendBefore: 0, windowSpendAfter: 0,
|
|
13
|
+
provider: (fam === 'self_hosted' ? 'unknown' : fam) as Provider,
|
|
14
|
+
modelRequested: model, modelResolved: model, policyId: 'p', policyVersion: 1,
|
|
15
|
+
enforcementMode: 'enforce', reasons: [],
|
|
16
|
+
provenance: {
|
|
17
|
+
model_identity: { provider: fam, model_id: model, model_version: '1', model_family: fam, weights_origin_country: 'US' },
|
|
18
|
+
hosting: { provider_route: route, jurisdiction_country: 'US', jurisdiction_region: 'us' },
|
|
19
|
+
compliance: { baa_in_force: false, baa_vendor: null, hipaa_eligible: false, data_retention_days: null, data_residency_attested: false, foreign_origin_weight_flag: false, foreign_origin_consent_receipt_id: null, inference_billing: 'customer_managed' },
|
|
20
|
+
captured_at: '2026-07-10T14:00:00.000Z',
|
|
21
|
+
},
|
|
22
|
+
...extra,
|
|
23
|
+
};
|
|
24
|
+
return { sequence: seq++, decision, previousHash: '0'.repeat(64), entryHash: 'x', signature: 'y', signerFingerprint: 'f' };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
test('lineage, swaps, and boundary crossing across a hot-swap sequence', () => {
|
|
28
|
+
seq = 0;
|
|
29
|
+
const entries = [
|
|
30
|
+
entry('claude-5', 'anthropic', 'anthropic-api'),
|
|
31
|
+
entry('claude-5', 'anthropic', 'anthropic-api'), // repeat: no swap
|
|
32
|
+
entry('gpt-5-mini', 'openai', 'openai-api'), // frontier→frontier swap
|
|
33
|
+
entry('glm-5.2', 'self_hosted', 'self-hosted-gpu'), // frontier→dark swap (boundary)
|
|
34
|
+
];
|
|
35
|
+
const report = workloadProvenance(entries, { verified: true, entries: entries.length });
|
|
36
|
+
assert.equal(report.workloads.length, 1);
|
|
37
|
+
const w = report.workloads[0];
|
|
38
|
+
assert.deepEqual(w.lineage, ['claude-5', 'gpt-5-mini', 'glm-5.2']);
|
|
39
|
+
assert.equal(formatLineage(w), 'claude-5 → gpt-5-mini → glm-5.2');
|
|
40
|
+
assert.equal(w.swaps.length, 2);
|
|
41
|
+
assert.equal(w.swaps[0].crossesBoundary, false); // frontier→frontier
|
|
42
|
+
assert.equal(w.swaps[1].crossesBoundary, true); // frontier→dark
|
|
43
|
+
assert.equal(w.swaps[1].fromModel, 'gpt-5-mini');
|
|
44
|
+
assert.equal(w.swaps[1].toModel, 'glm-5.2');
|
|
45
|
+
assert.equal(w.darkCents, 10);
|
|
46
|
+
assert.equal(w.frontierCents, 30);
|
|
47
|
+
assert.equal(report.continuity.verified, true); // one chain spans all swaps
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('groups by keyOf; separate workloads do not merge', () => {
|
|
51
|
+
seq = 0;
|
|
52
|
+
const a = entry('claude-5', 'anthropic', 'api', { triggeredScopeKey: 'wf:A' });
|
|
53
|
+
const b = entry('glm-5.2', 'self_hosted', 'self', { triggeredScopeKey: 'wf:B' });
|
|
54
|
+
const report = workloadProvenance([a, b], { verified: true, entries: 2 });
|
|
55
|
+
assert.equal(report.workloads.length, 2);
|
|
56
|
+
assert.ok(report.workloads.every(w => w.swaps.length === 0));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('settlement/outcome entries add no model steps', () => {
|
|
60
|
+
seq = 0;
|
|
61
|
+
const entries = [
|
|
62
|
+
entry('claude-5', 'anthropic', 'api'),
|
|
63
|
+
entry('claude-5', 'anthropic', 'api', { entryType: 'settlement', actualCents: 9 }),
|
|
64
|
+
];
|
|
65
|
+
const w = workloadProvenance(entries, { verified: true, entries: 2 }).workloads[0];
|
|
66
|
+
assert.equal(w.calls, 1);
|
|
67
|
+
assert.equal(w.swaps.length, 0);
|
|
68
|
+
});
|