@claudexor/budget 1.0.1 → 2.1.1

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,87 @@ 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?;
38
+ private readonly deps;
47
39
  private readonly leases;
48
- /** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
49
40
  private readonly holds;
41
+ private readonly unknownPaidInFlight;
50
42
  private readonly observations;
43
+ private readonly quotaSnapshots;
51
44
  private readonly promptCounts;
52
45
  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;
46
+ private valuationUsd;
47
+ private overshot;
48
+ private unverifiable;
49
+ constructor(budget?: PaidBudget, thresholds?: CircuitThresholds, deps?: {
50
+ /**
51
+ * Fires after every settle with the CUMULATIVE ledger truth. The ledger
52
+ * is the one owner of "how much real money this run has spent" —
53
+ * subscription-entitled work settles to cash 0 here (W4.3 sol #15), so
54
+ * consumers (run events → UI) render cash without inferring from route
55
+ * labels. Valuation rides along for telemetry, never for the cash fact.
56
+ */
57
+ onCashSettled?: (cashSpendUsd: number, valuationUsd: number) => void;
58
+ });
56
59
  private outstandingHolds;
60
+ private cap;
57
61
  tier(): CircuitTier;
58
- /** USD still available under the nearest cap in the ledger chain (null = uncapped). */
59
- private remainingHeadroomUsd;
62
+ remainingUsd(): number | null;
60
63
  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
64
  updateHold(leaseId: string, streamedUsd: number): void;
66
- private setHold;
67
- private adjustRollupHold;
68
- private clearHold;
69
- settle(leaseId: string, actualUsd: number): void;
65
+ settle(leaseId: string, settlement: BudgetSettlement): void;
70
66
  cancel(leaseId: string): void;
71
- private addRollupSpend;
72
67
  spend(): number;
73
- observe(o: BudgetObservation): void;
68
+ valuation(): number;
69
+ terminal(): BudgetTerminal;
70
+ observe(observation: BudgetObservation): void;
71
+ /** Seed durable quota projection without collapsing credential identities. */
72
+ observeQuotaSnapshot(snapshot: QuotaSnapshot): void;
74
73
  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;
74
+ cooldownActive(harnessId: string, credentialRoute?: CredentialRoute, credentialSubjectId?: string | null, now?: number): boolean;
75
+ /** Binding pacing slack across applicable windows; null means honestly unknown. */
76
+ bindingPaceSlack(harnessId: string, credentialRoute?: CredentialRoute, credentialSubjectId?: string | null, now?: number): number | null;
77
+ /** Fresh snapshots for a harness+route, optionally pinned to ONE credential
78
+ * subject (release wave round-16 #2): when the caller knows the effective
79
+ * subject — a profile id, or null for the engine default — only that
80
+ * subject's windows apply, so profile A's exhaustion never cools profile B
81
+ * or the default. `undefined` = subject unknown, conservative any-subject. */
82
+ private snapshotsFor;
79
83
  recordPrompt(fingerprint: string): number;
80
84
  isLoop(fingerprint: string, threshold?: number): boolean;
81
85
  }
86
+ export declare function routeCostEvidence(input: {
87
+ billing?: BillingKnowledge;
88
+ knowledge?: CostKnowledge;
89
+ source: string;
90
+ provenance: string[];
91
+ estimatedUsd?: number | null;
92
+ }): CostEvidence;
93
+ export declare function attemptCostEvidence(harnessId: string, attemptId: string, estimatedUsd?: number, billing?: BillingKnowledge): CostEvidence;
94
+ export declare function usageCostSettlement(cashUsd: number, estimated: boolean, source: string, provenance: string[]): BudgetSettlement;
95
+ export declare function attemptUsageCostSettlement(cashUsd: number, estimated: boolean, attemptId: string, harnessId: string, authMode?: "local_session" | "api_key" | null): BudgetSettlement;
96
+ export declare function unknownCostSettlement(source: string, cashUsd?: number): BudgetSettlement;
97
+ export declare function isBudgetTerminal(status: string | null): status is Exclude<BudgetTerminal, null>;
82
98
  //# 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,99 @@
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;
18
+ deps;
16
19
  leases = new Map();
17
- /** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
18
20
  holds = new Map();
21
+ unknownPaidInFlight = new Set();
19
22
  observations = [];
23
+ quotaSnapshots = new Map();
20
24
  promptCounts = new Map();
21
25
  spendUsd = 0;
22
- constructor(limits = {}, thresholds = { soft: 0.75, downgrade: 0.9, hard: 1.0 }, parent) {
23
- this.limits = limits;
26
+ valuationUsd = 0;
27
+ overshot = false;
28
+ unverifiable = false;
29
+ constructor(budget = { kind: "unlimited" }, thresholds = { soft: 0.75, downgrade: 0.9, hard: 1 }, deps = {}) {
30
+ this.budget = budget;
24
31
  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);
32
+ this.deps = deps;
30
33
  }
31
34
  outstandingHolds() {
32
35
  let sum = 0;
33
- for (const v of this.holds.values())
34
- sum += v;
36
+ for (const value of this.holds.values())
37
+ sum += value;
35
38
  return sum;
36
39
  }
40
+ cap() {
41
+ return this.budget.kind === "finite" ? this.budget.maxUsd : null;
42
+ }
37
43
  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";
44
+ const cap = this.cap();
45
+ if (cap === null)
51
46
  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);
47
+ if (this.overshot)
48
+ return "hard";
49
+ if (cap === 0)
50
+ return this.spendUsd > 0 || this.outstandingHolds() > 0 ? "hard" : "ok";
51
+ const ratio = (this.spendUsd + this.outstandingHolds()) / cap;
52
+ if (ratio >= this.thresholds.hard)
53
+ return "hard";
54
+ if (ratio >= this.thresholds.downgrade)
55
+ return "downgrade";
56
+ if (ratio >= this.thresholds.soft)
57
+ return "soft";
58
+ return "ok";
59
+ }
60
+ remainingUsd() {
61
+ const cap = this.cap();
62
+ return cap === null ? null : Math.max(0, cap - this.spendUsd - this.outstandingHolds());
66
63
  }
67
64
  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" };
65
+ const cost = CostEvidenceSchema.parse(input.cost ?? UNKNOWN_COST);
66
+ const zeroCash = cost.billing === "proven_zero" || cost.billing === "subscription_entitlement";
67
+ const cap = this.cap();
68
+ if (cap === 0 && !zeroCash) {
69
+ return {
70
+ granted: false,
71
+ tier: "hard",
72
+ denied: "finite_zero",
73
+ reason: "finite(0) admits only proven-zero or subscription-entitlement work",
74
+ };
71
75
  }
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
- }
76
+ if (this.tier() === "hard" && !zeroCash) {
77
+ return { granted: false, tier: "hard", denied: "hard_cap", reason: "budget exhausted" };
78
+ }
79
+ const unknownPaid = !zeroCash && cost.knowledge === "unknown";
80
+ if (cap !== null && cap > 0 && unknownPaid && this.unknownPaidInFlight.size > 0) {
81
+ return {
82
+ granted: false,
83
+ tier: this.tier(),
84
+ denied: "unknown_paid_in_flight",
85
+ reason: "one unknown-cost paid unit is already in flight",
86
+ };
87
+ }
88
+ const estimate = zeroCash ? 0 : (cost.estimatedUsd ?? 0);
89
+ const headroom = this.remainingUsd();
90
+ if (estimate > 0 && headroom !== null && estimate >= headroom) {
91
+ return {
92
+ granted: false,
93
+ tier: this.tier(),
94
+ denied: "estimate_headroom",
95
+ reason: `insufficient headroom for estimated cost (${estimate.toFixed(2)} USD >= ${headroom.toFixed(2)} USD remaining)`,
96
+ };
89
97
  }
90
98
  const lease = BudgetLeaseSchema.parse({
91
99
  lease_id: newId("lease"),
@@ -94,119 +102,237 @@ export class BudgetLedger {
94
102
  intent: input.intent,
95
103
  harness_id: input.harnessId,
96
104
  model_hint: input.modelHint ?? null,
97
- max_usd: input.maxUsd ?? null,
105
+ cost,
98
106
  reason: input.reason ?? [],
99
107
  created_at: nowIso(),
100
108
  state: "reserved",
101
109
  });
102
110
  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 };
111
+ if (estimate > 0)
112
+ this.holds.set(lease.lease_id, estimate);
113
+ if (unknownPaid && cap !== null)
114
+ this.unknownPaidInFlight.add(lease.lease_id);
115
+ return { granted: true, tier: this.tier(), lease };
107
116
  }
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
117
  updateHold(leaseId, streamedUsd) {
113
- if (!this.leases.has(leaseId))
118
+ const lease = this.leases.get(leaseId);
119
+ if (!lease || lease.state !== "reserved")
120
+ return;
121
+ if (lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement")
114
122
  return;
115
123
  const current = this.holds.get(leaseId) ?? 0;
116
124
  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);
125
+ this.holds.set(leaseId, streamedUsd);
139
126
  }
140
- settle(leaseId, actualUsd) {
127
+ settle(leaseId, settlement) {
141
128
  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
129
  if (!lease)
145
130
  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
131
  if (lease.state !== "reserved")
153
132
  return;
154
133
  lease.state = "settled";
155
- this.clearHold(leaseId);
156
- this.spendUsd += actualUsd;
157
- this.parent?.addRollupSpend(actualUsd);
134
+ this.holds.delete(leaseId);
135
+ this.unknownPaidInFlight.delete(leaseId);
136
+ const zeroCash = lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement";
137
+ const cashUsd = zeroCash ? 0 : Math.max(0, settlement.cashUsd ?? 0);
138
+ this.spendUsd += cashUsd;
139
+ this.valuationUsd += Math.max(0, settlement.valuationUsd ?? (zeroCash ? (settlement.cashUsd ?? 0) : 0));
140
+ if (this.budget.kind === "finite") {
141
+ if (!zeroCash && settlement.knowledge === "unknown")
142
+ this.unverifiable = true;
143
+ if (this.spendUsd > this.budget.maxUsd)
144
+ this.overshot = true;
145
+ }
146
+ this.deps.onCashSettled?.(this.spendUsd, this.valuationUsd);
158
147
  }
159
148
  cancel(leaseId) {
160
149
  const lease = this.leases.get(leaseId);
161
- if (lease)
150
+ if (lease?.state === "reserved")
162
151
  lease.state = "cancelled";
163
- this.clearHold(leaseId);
164
- }
165
- addRollupSpend(usd) {
166
- this.spendUsd += usd;
167
- this.parent?.addRollupSpend(usd);
152
+ this.holds.delete(leaseId);
153
+ this.unknownPaidInFlight.delete(leaseId);
168
154
  }
169
155
  spend() {
170
156
  return this.spendUsd;
171
157
  }
172
- observe(o) {
173
- this.observations.push(o);
158
+ valuation() {
159
+ return this.valuationUsd;
160
+ }
161
+ terminal() {
162
+ if (this.overshot)
163
+ return "exhausted_overshoot";
164
+ if (this.unverifiable)
165
+ return "cost_unverifiable";
166
+ return this.tier() === "hard" ? "exhausted" : null;
167
+ }
168
+ observe(observation) {
169
+ this.observations.push(observation);
170
+ }
171
+ /** Seed durable quota projection without collapsing credential identities. */
172
+ observeQuotaSnapshot(snapshot) {
173
+ const subject = snapshot.subject;
174
+ const key = [
175
+ subject.harness,
176
+ subject.credential_route,
177
+ subject.subject_id ?? "",
178
+ snapshot.source,
179
+ ].join("\0");
180
+ this.quotaSnapshots.set(key, snapshot);
174
181
  }
175
182
  observationsFor(harnessId) {
176
- return this.observations.filter((o) => o.harness_id === harnessId);
183
+ return this.observations.filter((observation) => observation.harness_id === harnessId);
177
184
  }
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)
185
+ cooldownActive(harnessId, credentialRoute, credentialSubjectId, now = Date.now()) {
186
+ // Live observations are subject- AND route-scoped like snapshots
187
+ // (rounds 17-18): a profiled or API-key rate-limit must never cool the
188
+ // same harness's other subjects or its healthy other route. `undefined`
189
+ // caller subject/route = conservative any; a LEGACY observation without
190
+ // a route stamp stays conservative (applies to every route).
191
+ const liveObservation = this.observationsFor(harnessId).some((observation) => {
192
+ if (credentialSubjectId !== undefined &&
193
+ (observation.subject_id ?? null) !== credentialSubjectId)
194
+ return false;
195
+ if (credentialRoute !== undefined &&
196
+ observation.credential_route !== undefined &&
197
+ observation.credential_route !== credentialRoute)
198
+ return false;
199
+ if (!observation.cooldown_until)
182
200
  return false;
183
- const t = Date.parse(o.cooldown_until);
184
- return Number.isFinite(t) && t > now;
201
+ const time = Date.parse(observation.cooldown_until);
202
+ return Number.isFinite(time) && time > now;
185
203
  });
204
+ if (liveObservation)
205
+ return true;
206
+ if (!credentialRoute)
207
+ return false;
208
+ return this.snapshotsFor(harnessId, credentialRoute, credentialSubjectId).some((snapshot) => snapshot.constraints.some((constraint) => {
209
+ const cooldown = constraint.cooldown_until
210
+ ? Date.parse(constraint.cooldown_until)
211
+ : Number.NaN;
212
+ const reset = constraint.resets_at ? Date.parse(constraint.resets_at) : Number.NaN;
213
+ return ((Number.isFinite(cooldown) && cooldown > now) ||
214
+ (constraint.used_ratio !== null &&
215
+ constraint.used_ratio >= 1 &&
216
+ Number.isFinite(reset) &&
217
+ reset > now));
218
+ }));
219
+ }
220
+ /** Binding pacing slack across applicable windows; null means honestly unknown. */
221
+ bindingPaceSlack(harnessId, credentialRoute, credentialSubjectId, now = Date.now()) {
222
+ const latest = new Map();
223
+ for (const observation of this.observationsFor(harnessId)) {
224
+ if (observation.kind !== "quota_constraint" || !observation.constraint_id)
225
+ continue;
226
+ // Subject- and route-scoped like cooldowns (rounds 17-18); the latest
227
+ // key includes route+subject so two routes' same-named windows never
228
+ // overwrite each other.
229
+ if (credentialSubjectId !== undefined &&
230
+ (observation.subject_id ?? null) !== credentialSubjectId)
231
+ continue;
232
+ if (credentialRoute !== undefined &&
233
+ observation.credential_route !== undefined &&
234
+ observation.credential_route !== credentialRoute)
235
+ continue;
236
+ latest.set(`${observation.credential_route ?? ""}\0${observation.subject_id ?? ""}\0${observation.constraint_id}`, observation);
237
+ }
238
+ const slacks = [];
239
+ for (const observation of latest.values()) {
240
+ if (typeof observation.used_ratio !== "number" ||
241
+ typeof observation.window_seconds !== "number" ||
242
+ !observation.resets_at)
243
+ continue;
244
+ const resetMs = Date.parse(observation.resets_at);
245
+ if (!Number.isFinite(resetMs) || resetMs <= now)
246
+ continue;
247
+ const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / observation.window_seconds));
248
+ const elapsedFraction = 1 - remaining;
249
+ slacks.push(elapsedFraction - observation.used_ratio);
250
+ }
251
+ if (credentialRoute) {
252
+ for (const snapshot of this.snapshotsFor(harnessId, credentialRoute, credentialSubjectId)) {
253
+ for (const constraint of snapshot.constraints) {
254
+ if (typeof constraint.used_ratio !== "number" ||
255
+ typeof constraint.window_seconds !== "number" ||
256
+ !constraint.resets_at)
257
+ continue;
258
+ const resetMs = Date.parse(constraint.resets_at);
259
+ if (!Number.isFinite(resetMs) || resetMs <= now)
260
+ continue;
261
+ const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / constraint.window_seconds));
262
+ slacks.push(1 - remaining - constraint.used_ratio);
263
+ }
264
+ }
265
+ }
266
+ return slacks.length > 0 ? Math.min(...slacks) : null;
186
267
  }
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);
268
+ /** Fresh snapshots for a harness+route, optionally pinned to ONE credential
269
+ * subject (release wave round-16 #2): when the caller knows the effective
270
+ * subject a profile id, or null for the engine default — only that
271
+ * subject's windows apply, so profile A's exhaustion never cools profile B
272
+ * or the default. `undefined` = subject unknown, conservative any-subject. */
273
+ snapshotsFor(harnessId, credentialRoute, credentialSubjectId) {
274
+ return [...this.quotaSnapshots.values()].filter((snapshot) => snapshot.freshness === "fresh" &&
275
+ snapshot.subject.harness === harnessId &&
276
+ snapshot.subject.credential_route === credentialRoute &&
277
+ (credentialSubjectId === undefined ||
278
+ (snapshot.subject.subject_id ?? null) === credentialSubjectId));
196
279
  }
197
280
  recordPrompt(fingerprint) {
198
- const n = (this.promptCounts.get(fingerprint) ?? 0) + 1;
199
- this.promptCounts.set(fingerprint, n);
200
- return n;
281
+ const count = (this.promptCounts.get(fingerprint) ?? 0) + 1;
282
+ this.promptCounts.set(fingerprint, count);
283
+ return count;
201
284
  }
202
285
  isLoop(fingerprint, threshold = 3) {
203
286
  return (this.promptCounts.get(fingerprint) ?? 0) >= threshold;
204
287
  }
205
288
  }
206
- function severity(t) {
207
- return { ok: 0, soft: 1, downgrade: 2, hard: 3 }[t];
289
+ export function routeCostEvidence(input) {
290
+ return CostEvidenceSchema.parse({
291
+ billing: input.billing ?? "unknown",
292
+ knowledge: input.knowledge ?? "unknown",
293
+ source: input.source,
294
+ provenance: input.provenance,
295
+ estimatedUsd: input.estimatedUsd ?? null,
296
+ });
297
+ }
298
+ export function attemptCostEvidence(harnessId, attemptId, estimatedUsd, billing = "unknown") {
299
+ return routeCostEvidence({
300
+ source: "route-preflight",
301
+ provenance: [`harness:${harnessId}`, `attempt:${attemptId}`, `billing:${billing}`],
302
+ billing,
303
+ knowledge: estimatedUsd === undefined ? "unknown" : "estimated",
304
+ estimatedUsd: estimatedUsd ?? null,
305
+ });
306
+ }
307
+ export function usageCostSettlement(cashUsd, estimated, source, provenance) {
308
+ return cashUsd > 0
309
+ ? { knowledge: estimated ? "estimated" : "exact", source, provenance, cashUsd }
310
+ : { knowledge: "unknown", source: `${source}-missing`, provenance };
311
+ }
312
+ export function attemptUsageCostSettlement(cashUsd, estimated, attemptId, harnessId, authMode) {
313
+ if (authMode === "local_session" && estimated) {
314
+ return {
315
+ knowledge: "unknown",
316
+ source: "harness-token-valuation",
317
+ provenance: [`attempt:${attemptId}`, `harness:${harnessId}`, "route:vendor_native"],
318
+ valuationUsd: cashUsd,
319
+ };
320
+ }
321
+ return usageCostSettlement(cashUsd, estimated, "harness-usage", [
322
+ `attempt:${attemptId}`,
323
+ `harness:${harnessId}`,
324
+ ...(authMode ? [`route:${authMode}`] : []),
325
+ ]);
326
+ }
327
+ export function unknownCostSettlement(source, cashUsd) {
328
+ return {
329
+ knowledge: "unknown",
330
+ source,
331
+ provenance: [`orchestrator:${source}`],
332
+ ...(cashUsd === undefined ? {} : { cashUsd }),
333
+ };
208
334
  }
209
- function mostSevere(a, b) {
210
- return severity(a) >= severity(b) ? a : b;
335
+ export function isBudgetTerminal(status) {
336
+ return (status === "exhausted" || status === "exhausted_overshoot" || status === "cost_unverifiable");
211
337
  }
212
338
  //# 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,CA0C9F"}
package/dist/observe.js CHANGED
@@ -15,34 +15,54 @@ const DEFAULT_COOLDOWN_MS = 5 * 60 * 1000;
15
15
  */
16
16
  export function observationsFromEvent(harnessId, ev) {
17
17
  const out = [];
18
+ // The credential subject rides EVERY observation (round-17 #2): a profiled
19
+ // run's rate-limit/quota signal belongs to that profile's account, and an
20
+ // unstamped observation would penalize the whole harness — profile B and
21
+ // the engine default included.
22
+ const subject = {
23
+ ...(ev.credential_route ? { credential_route: ev.credential_route } : {}),
24
+ subject_id: ev.credential_profile_id ?? null,
25
+ };
18
26
  if (ev.type === "usage" && typeof ev.usage?.cost_usd === "number" && ev.usage.cost_usd > 0) {
19
27
  // Token-derived costs (e.g. codex) are honest estimates -> "observed"; only
20
28
  // natively-reported costs (e.g. claude) are "exact".
21
29
  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
30
  out.push({
28
31
  harness_id: harnessId,
32
+ ...subject,
29
33
  ts: nowIso(),
30
- quality: "native",
31
- kind: "used_percent",
32
- used_percent: ev.quota.used_percent,
33
- resets_at: ev.quota.resets_at ?? null,
34
+ quality,
35
+ kind: "spend",
36
+ usd: ev.usage.cost_usd,
34
37
  });
35
38
  }
39
+ if (ev.quota) {
40
+ for (const constraint of ev.quota.constraints) {
41
+ out.push({
42
+ harness_id: harnessId,
43
+ ...subject,
44
+ ts: nowIso(),
45
+ quality: "native",
46
+ kind: "quota_constraint",
47
+ constraint_id: constraint.id,
48
+ used_ratio: constraint.used_ratio,
49
+ window_seconds: constraint.window_seconds,
50
+ resets_at: constraint.resets_at,
51
+ cooldown_until: constraint.cooldown_until,
52
+ });
53
+ }
54
+ }
36
55
  const single = singleObservationFromEvent(harnessId, ev);
37
56
  if (single)
38
- out.push(single);
57
+ out.push({ ...single, ...subject });
39
58
  return out;
40
59
  }
41
60
  function singleObservationFromEvent(harnessId, ev) {
42
61
  if (ev.rate_limit) {
43
62
  const resets = ev.rate_limit.resets_at ?? null;
44
63
  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();
64
+ const cooldownUntil = resets ??
65
+ new Date(Date.now() + (typeof delay === "number" && delay > 0 ? delay : DEFAULT_COOLDOWN_MS)).toISOString();
46
66
  return {
47
67
  harness_id: harnessId,
48
68
  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":"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"}
package/dist/router.d.ts CHANGED
@@ -1,22 +1,30 @@
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;
11
+ /** Effective credential subject for quota filtering (release wave round-16
12
+ * #2): a profile id, null for the engine default, undefined when unknown
13
+ * (conservative any-subject matching). Profile A's cooldown must never
14
+ * exclude profile B or the default on the same harness+route. */
15
+ credentialSubjectId?: string | null;
12
16
  }
13
17
  export interface RouteContext {
14
- portfolio: Portfolio;
18
+ goal: RoutingGoal;
19
+ paidFallback: PaidFallback;
20
+ intent: Intent;
21
+ qualityTiers: QualityTierSet;
15
22
  ledger: BudgetLedger;
16
- /** Provider families already used (penalized, to encourage cross-family diversity). */
17
- diversityAgainst?: ProviderFamily[];
18
23
  }
19
- export declare function routeUtility(c: RouterCandidate, ctx: RouteContext): number;
20
- /** Choose the highest-utility available harness, or null if none are usable. */
24
+ export declare class RoutingPreflightError extends Error {
25
+ readonly code = "routing_preflight_refused";
26
+ }
27
+ /** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
28
+ export declare function rankHarnesses(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate[];
21
29
  export declare function selectHarness(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate | null;
22
30
  //# 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;IAClC;;;qEAGiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;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;AAqCD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,eAAe,EAAE,CAmCjG;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, candidate.credentialSubjectId));
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, a.credentialSubjectId);
46
+ const bSlack = ctx.ledger.bindingPaceSlack(b.harnessId, b.credentialRoute, b.credentialSubjectId);
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":"AA6BA,SAAS,OAAO,CAAC,CAAY;IAC3B,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,UAAU;YACb,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACxF,KAAK,WAAW;YACd,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACxF,KAAK,MAAM;YACT,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACxF,KAAK,oBAAoB;YACvB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAC5F,KAAK,cAAc;YACjB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAC5F;YACE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC9F,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAkB,EAAE,GAAiB;IAChE,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAAE,OAAO,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;IACzD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,QAAQ,GACZ,CAAC,CAAC,QAAQ,KAAK,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,MAAM,QAAQ,GACZ,CAAC,GAAG,CAAC,SAAS,KAAK,iBAAiB,IAAI,CAAC,CAAC,cAAc,KAAK,WAAW,CAAC;QACzE,CAAC,GAAG,CAAC,SAAS,KAAK,gBAAgB,IAAI,CAAC,CAAC,cAAc,KAAK,QAAQ,CAAC;QACnE,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC;IAClC,MAAM,aAAa,GAAG,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC;IAC3C,OAAO,CAAC,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,GAAG,aAAa,CAAC,CAAC;AAC/F,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,UAA6B,EAAE,GAAiB;IAC5E,IAAI,IAAI,GAA2B,IAAI,CAAC;IACxC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC;YACd,KAAK,GAAG,CAAC,CAAC;YACV,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAkCA,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,IAAI,GAAG,2BAA2B,CAAC;CAC7C;AAED,SAAS,SAAS,CAAC,SAA0B,EAAE,GAAiB;IAC9D,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CACrC,IAAI,CAAC,IAAI,CACP,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,SAAS;QACrC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK;QAC/B,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,CACpC,CACF,CAAC;IACF,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAClC,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA0B;IACnD,OAAO,CAAC,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC,QAAQ,CAC1D,SAAS,CAAC,gBAAgB,IAAI,SAAS,CACxC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,UAA6B,EAAE,GAAiB;IAChE,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAC7B,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,SAAS;QACnB,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CACxB,SAAS,CAAC,SAAS,EACnB,SAAS,CAAC,eAAe,EACzB,SAAS,CAAC,mBAAmB,CAC9B,CACJ,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;IACxE,IAAI,GAAG,CAAC,YAAY,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,GAAG,CAAC,YAAY,KAAK,kBAAkB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,UAA6B,EAAE,GAAiB;IAC5E,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9F,MAAM,IAAI,qBAAqB,CAC7B,wEAAwE,GAAG,CAAC,MAAM,GAAG,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAC;QAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAC;QAC3D,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,GAAG,KAAK,CAAC;QACjD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC;YAChC,IAAI,SAAS,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACtC,MAAM,KAAK,GAAG,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC,iBAAiB,CAAC;YAC/D,MAAM,KAAK,GAAG,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC,iBAAiB,CAAC;YAC/D,OAAO,KAAK,GAAG,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC;QACxC,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,gBAAgB,CACxC,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,eAAe,EACjB,CAAC,CAAC,mBAAmB,CACtB,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,gBAAgB,CACxC,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,eAAe,EACjB,CAAC,CAAC,mBAAmB,CACtB,CAAC;QACF,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACvC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,UAA6B,EAC7B,GAAiB;IAEjB,OAAO,aAAa,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACnD,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@claudexor/budget",
3
- "version": "1.0.1",
3
+ "version": "2.1.1",
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.1",
20
- "@claudexor/util": "1.0.1"
19
+ "@claudexor/schema": "2.1.1",
20
+ "@claudexor/util": "2.1.1"
21
21
  },
22
22
  "repository": {
23
23
  "type": "git",