@claudexor/budget 1.0.0 → 2.0.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @claudexor/budget
2
2
 
3
- Internal package of [Claudexor](https://github.com/razzant/claudexor) — Budget governor: pre-call lease reservation, loop detection, 3-tier circuit breaker, portfolio routing, observed quota.
3
+ Internal package of [Claudexor](https://github.com/razzant/claudexor) — Budget governor: pre-call lease reservation, loop detection, 3-tier circuit breaker, routing goals, observed quota.
4
4
 
5
5
  Published as part of the Claudexor toolchain; it follows the monorepo's
6
6
  lockstep version and has no separate semver contract. Use the `claudexor`
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./ledger.js";
2
2
  export * from "./router.js";
3
3
  export * from "./observe.js";
4
- export { loadHarnessMetrics, recordHarnessMetric, metricsPath, type HarnessMetric, type HarnessMetrics } from "./metrics.js";
4
+ export { loadHarnessMetrics, recordHarnessMetric, metricsPath, type HarnessMetric, type HarnessMetrics, } from "./metrics.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./ledger.js";
2
2
  export * from "./router.js";
3
3
  export * from "./observe.js";
4
- export { loadHarnessMetrics, recordHarnessMetric, metricsPath } from "./metrics.js";
4
+ export { loadHarnessMetrics, recordHarnessMetric, metricsPath, } from "./metrics.js";
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAA2C,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,GAGZ,MAAM,cAAc,CAAC"}
package/dist/ledger.d.ts CHANGED
@@ -1,8 +1,6 @@
1
- import type { BudgetLease, BudgetObservation, Intent } from "@claudexor/schema";
1
+ import type { BillingKnowledge, BudgetLease, BudgetObservation, CostEvidence, CostKnowledge, CredentialRoute, Intent, PaidBudget, QuotaSnapshot } from "@claudexor/schema";
2
2
  export type CircuitTier = "ok" | "soft" | "downgrade" | "hard";
3
- export interface BudgetLimits {
4
- maxUsd?: number | null;
5
- }
3
+ export type BudgetTerminal = "exhausted" | "exhausted_overshoot" | "cost_unverifiable" | null;
6
4
  export interface CircuitThresholds {
7
5
  soft: number;
8
6
  downgrade: number;
@@ -14,69 +12,72 @@ export interface ReserveInput {
14
12
  intent: Intent;
15
13
  harnessId: string;
16
14
  modelHint?: string | null;
17
- maxUsd?: number | null;
18
15
  reason?: string[];
19
- /**
20
- * Estimated USD the unit may spend, held against the cap until settled. Holds
21
- * make concurrent in-flight units visible to `tier()` so a parallel race wave
22
- * cannot blow past `max_usd` between settlements.
23
- */
24
- estimateUsd?: number;
16
+ cost?: CostEvidence;
17
+ }
18
+ export interface BudgetSettlement {
19
+ knowledge: CostKnowledge;
20
+ source: string;
21
+ provenance: string[];
22
+ cashUsd?: number;
23
+ valuationUsd?: number;
25
24
  }
26
25
  export interface ReserveResult {
27
26
  granted: boolean;
28
27
  tier: CircuitTier;
29
28
  lease?: BudgetLease;
30
29
  reason?: string;
31
- /** Typed denial cause (no string matching on `reason`): `hard_cap` = the
32
- * breaker already tripped; `estimate_headroom` = the DD-27 wave guard —
33
- * this slot's estimate does not fit, but already-granted work continues. */
34
- denied?: "hard_cap" | "estimate_headroom";
30
+ denied?: "hard_cap" | "estimate_headroom" | "finite_zero" | "unknown_paid_in_flight";
35
31
  }
36
32
  /** Stable fingerprint of a prompt for loop detection. */
37
33
  export declare function promptFingerprint(prompt: string): string;
38
- /**
39
- * Dollar-based budget ledger with pre-call reservation, prompt-fingerprint loop
40
- * detection, and a 3-tier circuit breaker (soft-warn -> downgrade -> hard-kill).
41
- * Sub-ledgers (children) roll their spend up to the parent.
42
- */
34
+ /** One root incremental-cash ledger. Nested work receives this same instance. */
43
35
  export declare class BudgetLedger {
44
- private readonly limits;
36
+ private readonly budget;
45
37
  private readonly thresholds;
46
- private readonly parent?;
47
38
  private readonly leases;
48
- /** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
49
39
  private readonly holds;
40
+ private readonly unknownPaidInFlight;
50
41
  private readonly observations;
42
+ private readonly quotaSnapshots;
51
43
  private readonly promptCounts;
52
44
  private spendUsd;
53
- constructor(limits?: BudgetLimits, thresholds?: CircuitThresholds, parent?: BudgetLedger | undefined);
54
- /** Create a child sub-ledger whose spend rolls up to this one. */
55
- child(limits?: BudgetLimits): BudgetLedger;
45
+ private valuationUsd;
46
+ private overshot;
47
+ private unverifiable;
48
+ constructor(budget?: PaidBudget, thresholds?: CircuitThresholds);
56
49
  private outstandingHolds;
50
+ private cap;
57
51
  tier(): CircuitTier;
58
- /** USD still available under the nearest cap in the ledger chain (null = uncapped). */
59
- private remainingHeadroomUsd;
52
+ remainingUsd(): number | null;
60
53
  reserve(input: ReserveInput): ReserveResult;
61
- /**
62
- * Raise a lease's hold to the cost streamed so far (never lowers it). Call from
63
- * the usage-event stream so `tier()` reflects in-flight spend mid-attempt.
64
- */
65
54
  updateHold(leaseId: string, streamedUsd: number): void;
66
- private setHold;
67
- private adjustRollupHold;
68
- private clearHold;
69
- settle(leaseId: string, actualUsd: number): void;
55
+ settle(leaseId: string, settlement: BudgetSettlement): void;
70
56
  cancel(leaseId: string): void;
71
- private addRollupSpend;
72
57
  spend(): number;
73
- observe(o: BudgetObservation): void;
58
+ valuation(): number;
59
+ terminal(): BudgetTerminal;
60
+ observe(observation: BudgetObservation): void;
61
+ /** Seed durable quota projection without collapsing credential identities. */
62
+ observeQuotaSnapshot(snapshot: QuotaSnapshot): void;
74
63
  observationsFor(harnessId: string): BudgetObservation[];
75
- /** True if the harness is in an active cooldown (from an observed rate-limit). */
76
- cooldownActive(harnessId: string, now?: number): boolean;
77
- /** Observed remaining headroom (0..1) for a harness, or 1 if unknown. */
78
- headroom(harnessId: string): number;
64
+ cooldownActive(harnessId: string, credentialRoute?: CredentialRoute, now?: number): boolean;
65
+ /** Binding pacing slack across applicable windows; null means honestly unknown. */
66
+ bindingPaceSlack(harnessId: string, credentialRoute?: CredentialRoute, now?: number): number | null;
67
+ private snapshotsFor;
79
68
  recordPrompt(fingerprint: string): number;
80
69
  isLoop(fingerprint: string, threshold?: number): boolean;
81
70
  }
71
+ export declare function routeCostEvidence(input: {
72
+ billing?: BillingKnowledge;
73
+ knowledge?: CostKnowledge;
74
+ source: string;
75
+ provenance: string[];
76
+ estimatedUsd?: number | null;
77
+ }): CostEvidence;
78
+ export declare function attemptCostEvidence(harnessId: string, attemptId: string, estimatedUsd?: number, billing?: BillingKnowledge): CostEvidence;
79
+ export declare function usageCostSettlement(cashUsd: number, estimated: boolean, source: string, provenance: string[]): BudgetSettlement;
80
+ export declare function attemptUsageCostSettlement(cashUsd: number, estimated: boolean, attemptId: string, harnessId: string, authMode?: "local_session" | "api_key" | null): BudgetSettlement;
81
+ export declare function unknownCostSettlement(source: string, cashUsd?: number): BudgetSettlement;
82
+ export declare function isBudgetTerminal(status: string | null): status is Exclude<BudgetTerminal, null>;
82
83
  //# sourceMappingURL=ledger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
package/dist/ledger.js CHANGED
@@ -1,91 +1,97 @@
1
- import { BudgetLease as BudgetLeaseSchema } from "@claudexor/schema";
1
+ import { BudgetLease as BudgetLeaseSchema, CostEvidence as CostEvidenceSchema, } from "@claudexor/schema";
2
2
  import { newId, nowIso, sha256 } from "@claudexor/util";
3
+ const UNKNOWN_COST = {
4
+ knowledge: "unknown",
5
+ billing: "unknown",
6
+ source: "route_preflight",
7
+ provenance: ["route:billing-unknown"],
8
+ estimatedUsd: null,
9
+ };
3
10
  /** Stable fingerprint of a prompt for loop detection. */
4
11
  export function promptFingerprint(prompt) {
5
12
  return sha256(prompt.trim().replace(/\s+/g, " ").toLowerCase());
6
13
  }
7
- /**
8
- * Dollar-based budget ledger with pre-call reservation, prompt-fingerprint loop
9
- * detection, and a 3-tier circuit breaker (soft-warn -> downgrade -> hard-kill).
10
- * Sub-ledgers (children) roll their spend up to the parent.
11
- */
14
+ /** One root incremental-cash ledger. Nested work receives this same instance. */
12
15
  export class BudgetLedger {
13
- limits;
16
+ budget;
14
17
  thresholds;
15
- parent;
16
18
  leases = new Map();
17
- /** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
18
19
  holds = new Map();
20
+ unknownPaidInFlight = new Set();
19
21
  observations = [];
22
+ quotaSnapshots = new Map();
20
23
  promptCounts = new Map();
21
24
  spendUsd = 0;
22
- constructor(limits = {}, thresholds = { soft: 0.75, downgrade: 0.9, hard: 1.0 }, parent) {
23
- this.limits = limits;
25
+ valuationUsd = 0;
26
+ overshot = false;
27
+ unverifiable = false;
28
+ constructor(budget = { kind: "unlimited" }, thresholds = { soft: 0.75, downgrade: 0.9, hard: 1 }) {
29
+ this.budget = budget;
24
30
  this.thresholds = thresholds;
25
- this.parent = parent;
26
- }
27
- /** Create a child sub-ledger whose spend rolls up to this one. */
28
- child(limits = {}) {
29
- return new BudgetLedger(limits, this.thresholds, this);
30
31
  }
31
32
  outstandingHolds() {
32
33
  let sum = 0;
33
- for (const v of this.holds.values())
34
- sum += v;
34
+ for (const value of this.holds.values())
35
+ sum += value;
35
36
  return sum;
36
37
  }
38
+ cap() {
39
+ return this.budget.kind === "finite" ? this.budget.maxUsd : null;
40
+ }
37
41
  tier() {
38
- const cap = this.limits.maxUsd ?? null;
39
- const localTier = (() => {
40
- if (cap === null || cap <= 0)
41
- return "ok";
42
- // Settled spend + outstanding in-flight holds: a parallel wave of
43
- // streaming candidates counts against the cap BEFORE settlement.
44
- const ratio = (this.spendUsd + this.outstandingHolds()) / cap;
45
- if (ratio >= this.thresholds.hard)
46
- return "hard";
47
- if (ratio >= this.thresholds.downgrade)
48
- return "downgrade";
49
- if (ratio >= this.thresholds.soft)
50
- return "soft";
42
+ const cap = this.cap();
43
+ if (cap === null)
51
44
  return "ok";
52
- })();
53
- const parentTier = this.parent?.tier() ?? "ok";
54
- return mostSevere(localTier, parentTier);
55
- }
56
- /** USD still available under the nearest cap in the ledger chain (null = uncapped). */
57
- remainingHeadroomUsd() {
58
- const cap = this.limits.maxUsd ?? null;
59
- const local = cap === null || cap <= 0 ? null : cap * this.thresholds.hard - (this.spendUsd + this.outstandingHolds());
60
- const parent = this.parent?.remainingHeadroomUsd() ?? null;
61
- if (local === null)
62
- return parent;
63
- if (parent === null)
64
- return local;
65
- return Math.min(local, parent);
45
+ if (this.overshot)
46
+ return "hard";
47
+ if (cap === 0)
48
+ return this.spendUsd > 0 || this.outstandingHolds() > 0 ? "hard" : "ok";
49
+ const ratio = (this.spendUsd + this.outstandingHolds()) / cap;
50
+ if (ratio >= this.thresholds.hard)
51
+ return "hard";
52
+ if (ratio >= this.thresholds.downgrade)
53
+ return "downgrade";
54
+ if (ratio >= this.thresholds.soft)
55
+ return "soft";
56
+ return "ok";
57
+ }
58
+ remainingUsd() {
59
+ const cap = this.cap();
60
+ return cap === null ? null : Math.max(0, cap - this.spendUsd - this.outstandingHolds());
66
61
  }
67
62
  reserve(input) {
68
- const tier = this.tier();
69
- if (tier === "hard") {
70
- return { granted: false, tier, reason: "budget exhausted (hard cap reached)", denied: "hard_cap" };
63
+ const cost = CostEvidenceSchema.parse(input.cost ?? UNKNOWN_COST);
64
+ const zeroCash = cost.billing === "proven_zero" || cost.billing === "subscription_entitlement";
65
+ const cap = this.cap();
66
+ if (cap === 0 && !zeroCash) {
67
+ return {
68
+ granted: false,
69
+ tier: "hard",
70
+ denied: "finite_zero",
71
+ reason: "finite(0) admits only proven-zero or subscription-entitlement work",
72
+ };
71
73
  }
72
- // DD-27 wave guard: an estimate-bearing reservation must FIT UNDER the
73
- // remaining headroom, or it is DENIED without recording the hold — a
74
- // denied slot must never poison the tier for candidates that were already
75
- // granted. `>=` on purpose: an estimate that exactly consumes headroom
76
- // would trip the hard tier the instant its hold lands, cancelling every
77
- // in-flight candidate with $0 real spend (the equality case is common —
78
- // caps and the floor are both round nickels).
79
- if (typeof input.estimateUsd === "number" && input.estimateUsd > 0) {
80
- const headroom = this.remainingHeadroomUsd();
81
- if (headroom !== null && input.estimateUsd >= headroom) {
82
- return {
83
- granted: false,
84
- tier,
85
- reason: `insufficient headroom for estimated cost (${input.estimateUsd.toFixed(2)} USD >= ${Math.max(headroom, 0).toFixed(2)} USD remaining)`,
86
- denied: "estimate_headroom",
87
- };
88
- }
74
+ if (this.tier() === "hard" && !zeroCash) {
75
+ return { granted: false, tier: "hard", denied: "hard_cap", reason: "budget exhausted" };
76
+ }
77
+ const unknownPaid = !zeroCash && cost.knowledge === "unknown";
78
+ if (cap !== null && cap > 0 && unknownPaid && this.unknownPaidInFlight.size > 0) {
79
+ return {
80
+ granted: false,
81
+ tier: this.tier(),
82
+ denied: "unknown_paid_in_flight",
83
+ reason: "one unknown-cost paid unit is already in flight",
84
+ };
85
+ }
86
+ const estimate = zeroCash ? 0 : (cost.estimatedUsd ?? 0);
87
+ const headroom = this.remainingUsd();
88
+ if (estimate > 0 && headroom !== null && estimate >= headroom) {
89
+ return {
90
+ granted: false,
91
+ tier: this.tier(),
92
+ denied: "estimate_headroom",
93
+ reason: `insufficient headroom for estimated cost (${estimate.toFixed(2)} USD >= ${headroom.toFixed(2)} USD remaining)`,
94
+ };
89
95
  }
90
96
  const lease = BudgetLeaseSchema.parse({
91
97
  lease_id: newId("lease"),
@@ -94,119 +100,207 @@ export class BudgetLedger {
94
100
  intent: input.intent,
95
101
  harness_id: input.harnessId,
96
102
  model_hint: input.modelHint ?? null,
97
- max_usd: input.maxUsd ?? null,
103
+ cost,
98
104
  reason: input.reason ?? [],
99
105
  created_at: nowIso(),
100
106
  state: "reserved",
101
107
  });
102
108
  this.leases.set(lease.lease_id, lease);
103
- if (typeof input.estimateUsd === "number" && input.estimateUsd > 0) {
104
- this.setHold(lease.lease_id, input.estimateUsd);
105
- }
106
- return { granted: true, tier, lease };
109
+ if (estimate > 0)
110
+ this.holds.set(lease.lease_id, estimate);
111
+ if (unknownPaid && cap !== null)
112
+ this.unknownPaidInFlight.add(lease.lease_id);
113
+ return { granted: true, tier: this.tier(), lease };
107
114
  }
108
- /**
109
- * Raise a lease's hold to the cost streamed so far (never lowers it). Call from
110
- * the usage-event stream so `tier()` reflects in-flight spend mid-attempt.
111
- */
112
115
  updateHold(leaseId, streamedUsd) {
113
- if (!this.leases.has(leaseId))
116
+ const lease = this.leases.get(leaseId);
117
+ if (!lease || lease.state !== "reserved")
118
+ return;
119
+ if (lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement")
114
120
  return;
115
121
  const current = this.holds.get(leaseId) ?? 0;
116
122
  if (streamedUsd > current)
117
- this.setHold(leaseId, streamedUsd);
118
- }
119
- setHold(leaseId, usd) {
120
- const prev = this.holds.get(leaseId) ?? 0;
121
- this.holds.set(leaseId, usd);
122
- this.parent?.adjustRollupHold(leaseId, usd - prev);
123
- }
124
- adjustRollupHold(leaseId, deltaUsd) {
125
- const key = `child:${leaseId}`;
126
- const prev = this.holds.get(key) ?? 0;
127
- const next = Math.max(0, prev + deltaUsd);
128
- if (next === 0)
129
- this.holds.delete(key);
130
- else
131
- this.holds.set(key, next);
132
- this.parent?.adjustRollupHold(leaseId, deltaUsd);
133
- }
134
- clearHold(leaseId) {
135
- const held = this.holds.get(leaseId) ?? 0;
136
- this.holds.delete(leaseId);
137
- if (held > 0)
138
- this.parent?.adjustRollupHold(leaseId, -held);
123
+ this.holds.set(leaseId, streamedUsd);
139
124
  }
140
- settle(leaseId, actualUsd) {
125
+ settle(leaseId, settlement) {
141
126
  const lease = this.leases.get(leaseId);
142
- // Fail loudly: settling a lease this ledger never granted would attribute
143
- // spend to nothing (a bookkeeping bug, not a runtime race).
144
127
  if (!lease)
145
128
  throw new Error(`cannot settle unknown lease: ${leaseId}`);
146
- // Idempotent for the spend add: a duplicate settle (success path followed
147
- // by a late error handler) must never double-count real spend. DECIDED
148
- // TRADEOFF: this no-op can also mask a genuine double-settle bug — spend
149
- // correctness wins because the duplicate-settle race is a real runtime
150
- // path (terminal handler + error handler), while a masked bug still
151
- // surfaces in the rollup totals a test would assert on.
152
129
  if (lease.state !== "reserved")
153
130
  return;
154
131
  lease.state = "settled";
155
- this.clearHold(leaseId);
156
- this.spendUsd += actualUsd;
157
- this.parent?.addRollupSpend(actualUsd);
132
+ this.holds.delete(leaseId);
133
+ this.unknownPaidInFlight.delete(leaseId);
134
+ const zeroCash = lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement";
135
+ const cashUsd = zeroCash ? 0 : Math.max(0, settlement.cashUsd ?? 0);
136
+ this.spendUsd += cashUsd;
137
+ this.valuationUsd += Math.max(0, settlement.valuationUsd ?? (zeroCash ? (settlement.cashUsd ?? 0) : 0));
138
+ if (this.budget.kind === "finite") {
139
+ if (!zeroCash && settlement.knowledge === "unknown")
140
+ this.unverifiable = true;
141
+ if (this.spendUsd > this.budget.maxUsd)
142
+ this.overshot = true;
143
+ }
158
144
  }
159
145
  cancel(leaseId) {
160
146
  const lease = this.leases.get(leaseId);
161
- if (lease)
147
+ if (lease?.state === "reserved")
162
148
  lease.state = "cancelled";
163
- this.clearHold(leaseId);
164
- }
165
- addRollupSpend(usd) {
166
- this.spendUsd += usd;
167
- this.parent?.addRollupSpend(usd);
149
+ this.holds.delete(leaseId);
150
+ this.unknownPaidInFlight.delete(leaseId);
168
151
  }
169
152
  spend() {
170
153
  return this.spendUsd;
171
154
  }
172
- observe(o) {
173
- this.observations.push(o);
155
+ valuation() {
156
+ return this.valuationUsd;
157
+ }
158
+ terminal() {
159
+ if (this.overshot)
160
+ return "exhausted_overshoot";
161
+ if (this.unverifiable)
162
+ return "cost_unverifiable";
163
+ return this.tier() === "hard" ? "exhausted" : null;
164
+ }
165
+ observe(observation) {
166
+ this.observations.push(observation);
167
+ }
168
+ /** Seed durable quota projection without collapsing credential identities. */
169
+ observeQuotaSnapshot(snapshot) {
170
+ const subject = snapshot.subject;
171
+ const key = [
172
+ subject.harness,
173
+ subject.credential_route,
174
+ subject.subject_id ?? "",
175
+ snapshot.source,
176
+ ].join("\0");
177
+ this.quotaSnapshots.set(key, snapshot);
174
178
  }
175
179
  observationsFor(harnessId) {
176
- return this.observations.filter((o) => o.harness_id === harnessId);
180
+ return this.observations.filter((observation) => observation.harness_id === harnessId);
177
181
  }
178
- /** True if the harness is in an active cooldown (from an observed rate-limit). */
179
- cooldownActive(harnessId, now = Date.now()) {
180
- return this.observationsFor(harnessId).some((o) => {
181
- if (!o.cooldown_until)
182
+ cooldownActive(harnessId, credentialRoute, now = Date.now()) {
183
+ const liveObservation = this.observationsFor(harnessId).some((observation) => {
184
+ if (!observation.cooldown_until)
182
185
  return false;
183
- const t = Date.parse(o.cooldown_until);
184
- return Number.isFinite(t) && t > now;
186
+ const time = Date.parse(observation.cooldown_until);
187
+ return Number.isFinite(time) && time > now;
185
188
  });
189
+ if (liveObservation)
190
+ return true;
191
+ if (!credentialRoute)
192
+ return false;
193
+ return this.snapshotsFor(harnessId, credentialRoute).some((snapshot) => snapshot.constraints.some((constraint) => {
194
+ const cooldown = constraint.cooldown_until
195
+ ? Date.parse(constraint.cooldown_until)
196
+ : Number.NaN;
197
+ const reset = constraint.resets_at ? Date.parse(constraint.resets_at) : Number.NaN;
198
+ return ((Number.isFinite(cooldown) && cooldown > now) ||
199
+ (constraint.used_ratio !== null &&
200
+ constraint.used_ratio >= 1 &&
201
+ Number.isFinite(reset) &&
202
+ reset > now));
203
+ }));
186
204
  }
187
- /** Observed remaining headroom (0..1) for a harness, or 1 if unknown. */
188
- headroom(harnessId) {
189
- const used = this.observationsFor(harnessId)
190
- .map((o) => o.used_percent)
191
- .filter((v) => typeof v === "number");
192
- if (used.length === 0)
193
- return 1;
194
- const maxUsed = Math.max(...used);
195
- return Math.max(0, 1 - maxUsed / 100);
205
+ /** Binding pacing slack across applicable windows; null means honestly unknown. */
206
+ bindingPaceSlack(harnessId, credentialRoute, now = Date.now()) {
207
+ const latest = new Map();
208
+ for (const observation of this.observationsFor(harnessId)) {
209
+ if (observation.kind !== "quota_constraint" || !observation.constraint_id)
210
+ continue;
211
+ latest.set(observation.constraint_id, observation);
212
+ }
213
+ const slacks = [];
214
+ for (const observation of latest.values()) {
215
+ if (typeof observation.used_ratio !== "number" ||
216
+ typeof observation.window_seconds !== "number" ||
217
+ !observation.resets_at)
218
+ continue;
219
+ const resetMs = Date.parse(observation.resets_at);
220
+ if (!Number.isFinite(resetMs) || resetMs <= now)
221
+ continue;
222
+ const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / observation.window_seconds));
223
+ const elapsedFraction = 1 - remaining;
224
+ slacks.push(elapsedFraction - observation.used_ratio);
225
+ }
226
+ if (credentialRoute) {
227
+ for (const snapshot of this.snapshotsFor(harnessId, credentialRoute)) {
228
+ for (const constraint of snapshot.constraints) {
229
+ if (typeof constraint.used_ratio !== "number" ||
230
+ typeof constraint.window_seconds !== "number" ||
231
+ !constraint.resets_at)
232
+ continue;
233
+ const resetMs = Date.parse(constraint.resets_at);
234
+ if (!Number.isFinite(resetMs) || resetMs <= now)
235
+ continue;
236
+ const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / constraint.window_seconds));
237
+ slacks.push(1 - remaining - constraint.used_ratio);
238
+ }
239
+ }
240
+ }
241
+ return slacks.length > 0 ? Math.min(...slacks) : null;
242
+ }
243
+ snapshotsFor(harnessId, credentialRoute) {
244
+ return [...this.quotaSnapshots.values()].filter((snapshot) => snapshot.freshness === "fresh" &&
245
+ snapshot.subject.harness === harnessId &&
246
+ snapshot.subject.credential_route === credentialRoute);
196
247
  }
197
248
  recordPrompt(fingerprint) {
198
- const n = (this.promptCounts.get(fingerprint) ?? 0) + 1;
199
- this.promptCounts.set(fingerprint, n);
200
- return n;
249
+ const count = (this.promptCounts.get(fingerprint) ?? 0) + 1;
250
+ this.promptCounts.set(fingerprint, count);
251
+ return count;
201
252
  }
202
253
  isLoop(fingerprint, threshold = 3) {
203
254
  return (this.promptCounts.get(fingerprint) ?? 0) >= threshold;
204
255
  }
205
256
  }
206
- function severity(t) {
207
- return { ok: 0, soft: 1, downgrade: 2, hard: 3 }[t];
257
+ export function routeCostEvidence(input) {
258
+ return CostEvidenceSchema.parse({
259
+ billing: input.billing ?? "unknown",
260
+ knowledge: input.knowledge ?? "unknown",
261
+ source: input.source,
262
+ provenance: input.provenance,
263
+ estimatedUsd: input.estimatedUsd ?? null,
264
+ });
265
+ }
266
+ export function attemptCostEvidence(harnessId, attemptId, estimatedUsd, billing = "unknown") {
267
+ return routeCostEvidence({
268
+ source: "route-preflight",
269
+ provenance: [`harness:${harnessId}`, `attempt:${attemptId}`, `billing:${billing}`],
270
+ billing,
271
+ knowledge: estimatedUsd === undefined ? "unknown" : "estimated",
272
+ estimatedUsd: estimatedUsd ?? null,
273
+ });
274
+ }
275
+ export function usageCostSettlement(cashUsd, estimated, source, provenance) {
276
+ return cashUsd > 0
277
+ ? { knowledge: estimated ? "estimated" : "exact", source, provenance, cashUsd }
278
+ : { knowledge: "unknown", source: `${source}-missing`, provenance };
279
+ }
280
+ export function attemptUsageCostSettlement(cashUsd, estimated, attemptId, harnessId, authMode) {
281
+ if (authMode === "local_session" && estimated) {
282
+ return {
283
+ knowledge: "unknown",
284
+ source: "harness-token-valuation",
285
+ provenance: [`attempt:${attemptId}`, `harness:${harnessId}`, "route:vendor_native"],
286
+ valuationUsd: cashUsd,
287
+ };
288
+ }
289
+ return usageCostSettlement(cashUsd, estimated, "harness-usage", [
290
+ `attempt:${attemptId}`,
291
+ `harness:${harnessId}`,
292
+ ...(authMode ? [`route:${authMode}`] : []),
293
+ ]);
294
+ }
295
+ export function unknownCostSettlement(source, cashUsd) {
296
+ return {
297
+ knowledge: "unknown",
298
+ source,
299
+ provenance: [`orchestrator:${source}`],
300
+ ...(cashUsd === undefined ? {} : { cashUsd }),
301
+ };
208
302
  }
209
- function mostSevere(a, b) {
210
- return severity(a) >= severity(b) ? a : b;
303
+ export function isBudgetTerminal(status) {
304
+ return (status === "exhausted" || status === "exhausted_overshoot" || status === "cost_unverifiable");
211
305
  }
212
306
  //# sourceMappingURL=ledger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
package/dist/metrics.d.ts CHANGED
@@ -2,13 +2,27 @@ export interface HarnessMetric {
2
2
  avg_cost_usd: number | null;
3
3
  avg_duration_ms: number | null;
4
4
  samples: number;
5
+ /**
6
+ * Auth route the harness's LAST settled attempt actually ran under
7
+ * (adapter-disclosed route evidence, not a manifest capability guess).
8
+ * Economy routing may consume settled cost as evidence; no quality prior is
9
+ * inferred. Null until any attempt disclosed a route.
10
+ */
11
+ last_auth_mode: "local_session" | "api_key" | null;
5
12
  }
6
13
  export type HarnessMetrics = Record<string, HarnessMetric>;
7
14
  export declare function metricsPath(configDir: string): string;
8
15
  export declare function loadHarnessMetrics(configDir: string): HarnessMetrics;
9
- /** Record one settled attempt (EMA update; atomic tmp+rename write). */
16
+ /**
17
+ * Record one settled attempt (EMA update; atomic tmp+rename write).
18
+ * `authMode` is route evidence and updates independently of the performance
19
+ * sample: an auth-only record (no cost/duration) refreshes `last_auth_mode`
20
+ * WITHOUT counting a sample, so errored attempts can still disclose the route
21
+ * they burned without earning a flattering latency average.
22
+ */
10
23
  export declare function recordHarnessMetric(configDir: string, harnessId: string, sample: {
11
24
  costUsd?: number | null;
12
25
  durationMs?: number | null;
26
+ authMode?: "local_session" | "api_key" | null;
13
27
  }): void;
14
28
  //# sourceMappingURL=metrics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAM3D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAiBpE;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9D,IAAI,CAyBN"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,cAAc,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAM3D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAiCpE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;CAC/C,GACA,IAAI,CAmCN"}
package/dist/metrics.js CHANGED
@@ -24,8 +24,15 @@ export function loadHarnessMetrics(configDir) {
24
24
  const m = v;
25
25
  out[id] = {
26
26
  avg_cost_usd: typeof m.avg_cost_usd === "number" && m.avg_cost_usd >= 0 ? m.avg_cost_usd : null,
27
- avg_duration_ms: typeof m.avg_duration_ms === "number" && m.avg_duration_ms >= 0 ? m.avg_duration_ms : null,
28
- samples: typeof m.samples === "number" && m.samples > 0 ? Math.min(m.samples, MAX_SAMPLES_COUNTED) : 0,
27
+ avg_duration_ms: typeof m.avg_duration_ms === "number" && m.avg_duration_ms >= 0
28
+ ? m.avg_duration_ms
29
+ : null,
30
+ samples: typeof m.samples === "number" && m.samples > 0
31
+ ? Math.min(m.samples, MAX_SAMPLES_COUNTED)
32
+ : 0,
33
+ last_auth_mode: m.last_auth_mode === "local_session" || m.last_auth_mode === "api_key"
34
+ ? m.last_auth_mode
35
+ : null,
29
36
  };
30
37
  }
31
38
  return out;
@@ -34,10 +41,21 @@ export function loadHarnessMetrics(configDir) {
34
41
  return {};
35
42
  }
36
43
  }
37
- /** Record one settled attempt (EMA update; atomic tmp+rename write). */
44
+ /**
45
+ * Record one settled attempt (EMA update; atomic tmp+rename write).
46
+ * `authMode` is route evidence and updates independently of the performance
47
+ * sample: an auth-only record (no cost/duration) refreshes `last_auth_mode`
48
+ * WITHOUT counting a sample, so errored attempts can still disclose the route
49
+ * they burned without earning a flattering latency average.
50
+ */
38
51
  export function recordHarnessMetric(configDir, harnessId, sample) {
39
52
  const all = loadHarnessMetrics(configDir);
40
- const prev = all[harnessId] ?? { avg_cost_usd: null, avg_duration_ms: null, samples: 0 };
53
+ const prev = all[harnessId] ?? {
54
+ avg_cost_usd: null,
55
+ avg_duration_ms: null,
56
+ samples: 0,
57
+ last_auth_mode: null,
58
+ };
41
59
  const ema = (old, next) => {
42
60
  if (typeof next !== "number" || !Number.isFinite(next) || next < 0)
43
61
  return old;
@@ -45,10 +63,14 @@ export function recordHarnessMetric(configDir, harnessId, sample) {
45
63
  return next;
46
64
  return old * (1 - EMA_ALPHA) + next * EMA_ALPHA;
47
65
  };
66
+ const isPerfSample = typeof sample.costUsd === "number" || typeof sample.durationMs === "number";
48
67
  all[harnessId] = {
49
68
  avg_cost_usd: ema(prev.avg_cost_usd, sample.costUsd),
50
69
  avg_duration_ms: ema(prev.avg_duration_ms, sample.durationMs),
51
- samples: Math.min(prev.samples + 1, MAX_SAMPLES_COUNTED),
70
+ samples: isPerfSample ? Math.min(prev.samples + 1, MAX_SAMPLES_COUNTED) : prev.samples,
71
+ last_auth_mode: sample.authMode === "local_session" || sample.authMode === "api_key"
72
+ ? sample.authMode
73
+ : prev.last_auth_mode,
52
74
  };
53
75
  const path = metricsPath(configDir);
54
76
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKzE;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,iBAAiB,EAAE,CAuB9F"}
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKzE;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,iBAAiB,EAAE,CAgC9F"}
package/dist/observe.js CHANGED
@@ -19,20 +19,29 @@ export function observationsFromEvent(harnessId, ev) {
19
19
  // Token-derived costs (e.g. codex) are honest estimates -> "observed"; only
20
20
  // natively-reported costs (e.g. claude) are "exact".
21
21
  const quality = ev.usage.estimated ? "observed" : "exact";
22
- out.push({ harness_id: harnessId, ts: nowIso(), quality, kind: "spend", usd: ev.usage.cost_usd });
23
- }
24
- if (ev.quota) {
25
- // The CLI's own machine-readable window record (codex rollout
26
- // token_count.rate_limits) -> "native" quality used_percent observation.
27
22
  out.push({
28
23
  harness_id: harnessId,
29
24
  ts: nowIso(),
30
- quality: "native",
31
- kind: "used_percent",
32
- used_percent: ev.quota.used_percent,
33
- resets_at: ev.quota.resets_at ?? null,
25
+ quality,
26
+ kind: "spend",
27
+ usd: ev.usage.cost_usd,
34
28
  });
35
29
  }
30
+ if (ev.quota) {
31
+ for (const constraint of ev.quota.constraints) {
32
+ out.push({
33
+ harness_id: harnessId,
34
+ ts: nowIso(),
35
+ quality: "native",
36
+ kind: "quota_constraint",
37
+ constraint_id: constraint.id,
38
+ used_ratio: constraint.used_ratio,
39
+ window_seconds: constraint.window_seconds,
40
+ resets_at: constraint.resets_at,
41
+ cooldown_until: constraint.cooldown_until,
42
+ });
43
+ }
44
+ }
36
45
  const single = singleObservationFromEvent(harnessId, ev);
37
46
  if (single)
38
47
  out.push(single);
@@ -42,7 +51,8 @@ function singleObservationFromEvent(harnessId, ev) {
42
51
  if (ev.rate_limit) {
43
52
  const resets = ev.rate_limit.resets_at ?? null;
44
53
  const delay = ev.rate_limit.retry_delay_ms ?? null;
45
- const cooldownUntil = resets ?? new Date(Date.now() + (typeof delay === "number" && delay > 0 ? delay : DEFAULT_COOLDOWN_MS)).toISOString();
54
+ const cooldownUntil = resets ??
55
+ new Date(Date.now() + (typeof delay === "number" && delay > 0 ? delay : DEFAULT_COOLDOWN_MS)).toISOString();
46
56
  return {
47
57
  harness_id: harnessId,
48
58
  ts: nowIso(),
@@ -1 +1 @@
1
- {"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C;;;;;;GAMG;AACH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,EAAgB;IACvE,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3F,4EAA4E;QAC5E,qDAAqD;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,8DAA8D;QAC9D,yEAAyE;QACzE,GAAG,CAAC,IAAI,CAAC;YACP,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,cAAc;YACpB,YAAY,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY;YACnC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI;SACtC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,MAAM;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,0BAA0B,CAAC,SAAiB,EAAE,EAAgB;IACrE,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC;QAC/C,MAAM,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,IAAI,IAAI,CAAC;QACnD,MAAM,aAAa,GACjB,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACxH,OAAO;YACL,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,aAAa;YAC7B,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,SAAS;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C;;;;;;GAMG;AACH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,EAAgB;IACvE,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3F,4EAA4E;QAC5E,qDAAqD;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC;YACP,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO;YACP,IAAI,EAAE,OAAO;YACb,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,KAAK,MAAM,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9C,GAAG,CAAC,IAAI,CAAC;gBACP,UAAU,EAAE,SAAS;gBACrB,EAAE,EAAE,MAAM,EAAE;gBACZ,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,kBAAkB;gBACxB,aAAa,EAAE,UAAU,CAAC,EAAE;gBAC5B,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,cAAc,EAAE,UAAU,CAAC,cAAc;gBACzC,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,cAAc,EAAE,UAAU,CAAC,cAAc;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,MAAM;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,0BAA0B,CAAC,SAAiB,EAAE,EAAgB;IACrE,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC;QAC/C,MAAM,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,IAAI,IAAI,CAAC;QACnD,MAAM,aAAa,GACjB,MAAM;YACN,IAAI,IAAI,CACN,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CACpF,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO;YACL,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,aAAa;YAC7B,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,SAAS;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/router.d.ts CHANGED
@@ -1,22 +1,25 @@
1
- import type { Portfolio, ProviderFamily } from "@claudexor/schema";
1
+ import type { BillingKnowledge, CredentialRoute, EffortHint, Intent, PaidFallback, QualityTierSet, RoutingGoal } from "@claudexor/schema";
2
2
  import type { BudgetLedger } from "./ledger.js";
3
3
  export interface RouterCandidate {
4
4
  harnessId: string;
5
- providerFamily: ProviderFamily;
6
5
  available: boolean;
7
- authMode?: "local_session" | "api_key" | "unknown";
8
- /** 0..1 expected quality for the target intent. */
9
- qualityForIntent?: number;
10
- costPerCall?: number;
11
- latencyMs?: number;
6
+ model?: string;
7
+ effort?: EffortHint;
8
+ billingKnowledge?: BillingKnowledge;
9
+ incrementalCostUsd?: number | null;
10
+ credentialRoute?: CredentialRoute;
12
11
  }
13
12
  export interface RouteContext {
14
- portfolio: Portfolio;
13
+ goal: RoutingGoal;
14
+ paidFallback: PaidFallback;
15
+ intent: Intent;
16
+ qualityTiers: QualityTierSet;
15
17
  ledger: BudgetLedger;
16
- /** Provider families already used (penalized, to encourage cross-family diversity). */
17
- diversityAgainst?: ProviderFamily[];
18
18
  }
19
- export declare function routeUtility(c: RouterCandidate, ctx: RouteContext): number;
20
- /** Choose the highest-utility available harness, or null if none are usable. */
19
+ export declare class RoutingPreflightError extends Error {
20
+ readonly code = "routing_preflight_refused";
21
+ }
22
+ /** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
23
+ export declare function rankHarnesses(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate[];
21
24
  export declare function selectHarness(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate | null;
22
25
  //# sourceMappingURL=router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAAC;IACnD,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;CACrC;AA2BD,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAkB1E;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,eAAe,GAAG,IAAI,CAWtG"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,cAAc,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,+BAA+B;CAC7C;AAiCD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,eAAe,EAAE,CA2BjG;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,EAAE,YAAY,GAChB,eAAe,GAAG,IAAI,CAExB"}
package/dist/router.js CHANGED
@@ -1,48 +1,56 @@
1
- function weights(p) {
2
- switch (p) {
3
- case "cheapest":
4
- return { quality: 0.5, cost: 2.0, latency: 1.0, preferSubscription: 1, preferApi: 1 };
5
- case "strongest":
6
- return { quality: 2.0, cost: 0.2, latency: 0.5, preferSubscription: 1, preferApi: 1 };
7
- case "burn":
8
- return { quality: 2.0, cost: 0.0, latency: 0.2, preferSubscription: 1, preferApi: 1 };
9
- case "subscription-first":
10
- return { quality: 1.0, cost: 0.5, latency: 0.5, preferSubscription: 1.6, preferApi: 0.6 };
11
- case "api-overflow":
12
- return { quality: 1.0, cost: 0.8, latency: 0.5, preferSubscription: 0.6, preferApi: 1.6 };
13
- default:
14
- return { quality: 1.0, cost: 0.7, latency: 0.5, preferSubscription: 1.1, preferApi: 1.0 };
15
- }
1
+ export class RoutingPreflightError extends Error {
2
+ code = "routing_preflight_refused";
16
3
  }
17
- export function routeUtility(c, ctx) {
18
- if (!c.available || ctx.ledger.cooldownActive(c.harnessId))
19
- return 0;
20
- const w = weights(ctx.portfolio);
21
- const quality = (c.qualityForIntent ?? 0.5) ** w.quality;
22
- const headroom = ctx.ledger.headroom(c.harnessId);
23
- const diversity = ctx.diversityAgainst?.includes(c.providerFamily) ? 0.5 : 1;
24
- const authPref = c.authMode === "local_session" ? w.preferSubscription : c.authMode === "api_key" ? w.preferApi : 1;
25
- const conserve = (ctx.portfolio === "conserve-claude" && c.providerFamily === "anthropic") ||
26
- (ctx.portfolio === "conserve-codex" && c.providerFamily === "openai")
27
- ? 0.4
28
- : 1;
29
- const cost = Math.max(0.0001, c.costPerCall ?? 0.01);
30
- const latency = Math.max(0.1, (c.latencyMs ?? 1000) / 1000);
31
- const costFactor = cost ** w.cost;
32
- const latencyFactor = latency ** w.latency;
33
- return (quality * headroom * diversity * authPref * conserve) / (costFactor * latencyFactor);
4
+ function tierIndex(candidate, ctx) {
5
+ const tiers = ctx.qualityTiers[ctx.intent] ?? [];
6
+ const index = tiers.findIndex((tier) => tier.some((route) => route.harness === candidate.harnessId &&
7
+ route.model === candidate.model &&
8
+ route.effort === candidate.effort));
9
+ return index < 0 ? null : index;
34
10
  }
35
- /** Choose the highest-utility available harness, or null if none are usable. */
36
- export function selectHarness(candidates, ctx) {
37
- let best = null;
38
- let bestU = 0;
39
- for (const c of candidates) {
40
- const u = routeUtility(c, ctx);
41
- if (u > bestU) {
42
- bestU = u;
43
- best = c;
44
- }
11
+ function isIncrementalPaid(candidate) {
12
+ return !["proven_zero", "subscription_entitlement"].includes(candidate.billingKnowledge ?? "unknown");
13
+ }
14
+ function eligible(candidates, ctx) {
15
+ const ready = candidates.filter((candidate) => candidate.available &&
16
+ !ctx.ledger.cooldownActive(candidate.harnessId, candidate.credentialRoute));
17
+ const free = ready.filter((candidate) => !isIncrementalPaid(candidate));
18
+ if (ctx.paidFallback === "never")
19
+ return free;
20
+ if (ctx.paidFallback === "when_unavailable" && free.length > 0)
21
+ return free;
22
+ return ready;
23
+ }
24
+ /** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
25
+ export function rankHarnesses(candidates, ctx) {
26
+ const routes = eligible(candidates, ctx);
27
+ if (ctx.goal === "quality" && routes.every((candidate) => tierIndex(candidate, ctx) === null)) {
28
+ throw new RoutingPreflightError(`quality routing requires a comparable user-declared tier for intent '${ctx.intent}'`);
45
29
  }
46
- return best;
30
+ return routes.toSorted((a, b) => {
31
+ const aTier = tierIndex(a, ctx) ?? Number.MAX_SAFE_INTEGER;
32
+ const bTier = tierIndex(b, ctx) ?? Number.MAX_SAFE_INTEGER;
33
+ if (ctx.goal === "quality")
34
+ return aTier - bTier;
35
+ if (ctx.goal === "economy") {
36
+ const aPaid = isIncrementalPaid(a) ? 1 : 0;
37
+ const bPaid = isIncrementalPaid(b) ? 1 : 0;
38
+ const paidOrder = aPaid - bPaid;
39
+ if (paidOrder !== 0)
40
+ return paidOrder;
41
+ const aCost = a.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
42
+ const bCost = b.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
43
+ return aCost - bCost || aTier - bTier;
44
+ }
45
+ const aSlack = ctx.ledger.bindingPaceSlack(a.harnessId, a.credentialRoute);
46
+ const bSlack = ctx.ledger.bindingPaceSlack(b.harnessId, b.credentialRoute);
47
+ if (aSlack !== null || bSlack !== null) {
48
+ return (bSlack ?? Number.NEGATIVE_INFINITY) - (aSlack ?? Number.NEGATIVE_INFINITY);
49
+ }
50
+ return aTier - bTier;
51
+ });
52
+ }
53
+ export function selectHarness(candidates, ctx) {
54
+ return rankHarnesses(candidates, ctx)[0] ?? null;
47
55
  }
48
56
  //# sourceMappingURL=router.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@claudexor/budget",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "license": "MIT",
5
- "description": "Budget governor: pre-call lease reservation, loop detection, 3-tier circuit breaker, portfolio routing, observed quota.",
5
+ "description": "Budget governor: pre-call leases, circuit breaker, evidence-based routing goals, and multi-window quota pacing.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
@@ -16,8 +16,8 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@claudexor/schema": "1.0.0",
20
- "@claudexor/util": "1.0.0"
19
+ "@claudexor/util": "2.0.0",
20
+ "@claudexor/schema": "2.0.0"
21
21
  },
22
22
  "repository": {
23
23
  "type": "git",