@claudexor/orchestrator 3.1.2 → 3.3.7-rc.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.
Files changed (137) hide show
  1. package/dist/attemptFinalize.d.ts +14 -11
  2. package/dist/attemptFinalize.d.ts.map +1 -1
  3. package/dist/attemptFinalize.js +41 -14
  4. package/dist/attemptFinalize.js.map +1 -1
  5. package/dist/attemptTelemetry.d.ts +7 -0
  6. package/dist/attemptTelemetry.d.ts.map +1 -1
  7. package/dist/attemptTelemetry.js +2 -1
  8. package/dist/attemptTelemetry.js.map +1 -1
  9. package/dist/attemptUsageCost.d.ts +24 -2
  10. package/dist/attemptUsageCost.d.ts.map +1 -1
  11. package/dist/attemptUsageCost.js +18 -2
  12. package/dist/attemptUsageCost.js.map +1 -1
  13. package/dist/budgetFailure.d.ts +1 -1
  14. package/dist/budgetFailure.d.ts.map +1 -1
  15. package/dist/budgetFailure.js.map +1 -1
  16. package/dist/candidateEvidence.d.ts +24 -0
  17. package/dist/candidateEvidence.d.ts.map +1 -1
  18. package/dist/candidateEvidence.js +26 -0
  19. package/dist/candidateEvidence.js.map +1 -1
  20. package/dist/credential-profile-rotation.d.ts +145 -0
  21. package/dist/credential-profile-rotation.d.ts.map +1 -0
  22. package/dist/credential-profile-rotation.js +335 -0
  23. package/dist/credential-profile-rotation.js.map +1 -0
  24. package/dist/credential-profiles.d.ts +90 -130
  25. package/dist/credential-profiles.d.ts.map +1 -1
  26. package/dist/credential-profiles.js +156 -290
  27. package/dist/credential-profiles.js.map +1 -1
  28. package/dist/decisionBudget.d.ts +2 -2
  29. package/dist/decisionBudget.d.ts.map +1 -1
  30. package/dist/deepScanReducer.d.ts +14 -44
  31. package/dist/deepScanReducer.d.ts.map +1 -1
  32. package/dist/deepScanReducer.js +240 -128
  33. package/dist/deepScanReducer.js.map +1 -1
  34. package/dist/delegatedHome.d.ts +156 -0
  35. package/dist/delegatedHome.d.ts.map +1 -0
  36. package/dist/delegatedHome.js +179 -0
  37. package/dist/delegatedHome.js.map +1 -0
  38. package/dist/delegationBudgetAuthority.d.ts.map +1 -1
  39. package/dist/delegationBudgetAuthority.js.map +1 -1
  40. package/dist/delegationFailure.d.ts.map +1 -1
  41. package/dist/git-precondition.d.ts +11 -0
  42. package/dist/git-precondition.d.ts.map +1 -0
  43. package/dist/git-precondition.js +69 -0
  44. package/dist/git-precondition.js.map +1 -0
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/interaction.d.ts +14 -6
  50. package/dist/interaction.d.ts.map +1 -1
  51. package/dist/interaction.js +106 -19
  52. package/dist/interaction.js.map +1 -1
  53. package/dist/orchestrator.d.ts +64 -83
  54. package/dist/orchestrator.d.ts.map +1 -1
  55. package/dist/orchestrator.js +578 -691
  56. package/dist/orchestrator.js.map +1 -1
  57. package/dist/planBrief.d.ts +27 -0
  58. package/dist/planBrief.d.ts.map +1 -0
  59. package/dist/planBrief.js +42 -0
  60. package/dist/planBrief.js.map +1 -0
  61. package/dist/planQuestions.js +4 -1
  62. package/dist/planQuestions.js.map +1 -1
  63. package/dist/planRun.d.ts +4 -3
  64. package/dist/planRun.d.ts.map +1 -1
  65. package/dist/planRun.js +33 -33
  66. package/dist/planRun.js.map +1 -1
  67. package/dist/plannerAttempt.d.ts +64 -0
  68. package/dist/plannerAttempt.d.ts.map +1 -0
  69. package/dist/plannerAttempt.js +235 -0
  70. package/dist/plannerAttempt.js.map +1 -0
  71. package/dist/policyFindings.js.map +1 -1
  72. package/dist/requestRequirements.d.ts +43 -3
  73. package/dist/requestRequirements.d.ts.map +1 -1
  74. package/dist/requestRequirements.js +106 -13
  75. package/dist/requestRequirements.js.map +1 -1
  76. package/dist/reviewerPanel.js.map +1 -1
  77. package/dist/root-ledger.d.ts.map +1 -1
  78. package/dist/root-ledger.js +2 -0
  79. package/dist/root-ledger.js.map +1 -1
  80. package/dist/run-bounded.d.ts.map +1 -1
  81. package/dist/run-bounded.js +7 -1
  82. package/dist/run-bounded.js.map +1 -1
  83. package/dist/run-input-resolution.d.ts.map +1 -1
  84. package/dist/run-input-resolution.js +26 -8
  85. package/dist/run-input-resolution.js.map +1 -1
  86. package/dist/runEventLog.d.ts +48 -0
  87. package/dist/runEventLog.d.ts.map +1 -0
  88. package/dist/runEventLog.js +63 -0
  89. package/dist/runEventLog.js.map +1 -0
  90. package/dist/runFacts.d.ts +23 -0
  91. package/dist/runFacts.d.ts.map +1 -0
  92. package/dist/runFacts.js +179 -0
  93. package/dist/runFacts.js.map +1 -0
  94. package/dist/runFactsBuilder.d.ts +5 -0
  95. package/dist/runFactsBuilder.d.ts.map +1 -0
  96. package/dist/runFactsBuilder.js +412 -0
  97. package/dist/runFactsBuilder.js.map +1 -0
  98. package/dist/runFactsDeliverable.d.ts +13 -0
  99. package/dist/runFactsDeliverable.d.ts.map +1 -0
  100. package/dist/runFactsDeliverable.js +94 -0
  101. package/dist/runFactsDeliverable.js.map +1 -0
  102. package/dist/runFactsPresentation.d.ts +7 -0
  103. package/dist/runFactsPresentation.d.ts.map +1 -0
  104. package/dist/runFactsPresentation.js +113 -0
  105. package/dist/runFactsPresentation.js.map +1 -0
  106. package/dist/runFactsReview.d.ts +7 -0
  107. package/dist/runFactsReview.d.ts.map +1 -0
  108. package/dist/runFactsReview.js +63 -0
  109. package/dist/runFactsReview.js.map +1 -0
  110. package/dist/runSupport.d.ts +17 -15
  111. package/dist/runSupport.d.ts.map +1 -1
  112. package/dist/runSupport.js +16 -0
  113. package/dist/runSupport.js.map +1 -1
  114. package/dist/runTerminalContext.d.ts +31 -0
  115. package/dist/runTerminalContext.d.ts.map +1 -0
  116. package/dist/runTerminalContext.js +12 -0
  117. package/dist/runTerminalContext.js.map +1 -0
  118. package/dist/runTerminalResults.d.ts +80 -0
  119. package/dist/runTerminalResults.d.ts.map +1 -0
  120. package/dist/runTerminalResults.js +164 -0
  121. package/dist/runTerminalResults.js.map +1 -0
  122. package/dist/runTerminals.d.ts +4 -80
  123. package/dist/runTerminals.d.ts.map +1 -1
  124. package/dist/runTerminals.js +357 -260
  125. package/dist/runTerminals.js.map +1 -1
  126. package/dist/secretDiff.d.ts +3 -0
  127. package/dist/secretDiff.d.ts.map +1 -1
  128. package/dist/secretDiff.js +7 -0
  129. package/dist/secretDiff.js.map +1 -1
  130. package/dist/structuredOutput.d.ts.map +1 -1
  131. package/dist/structuredOutput.js.map +1 -1
  132. package/dist/task-contract-builder.d.ts +35 -0
  133. package/dist/task-contract-builder.d.ts.map +1 -0
  134. package/dist/task-contract-builder.js +114 -0
  135. package/dist/task-contract-builder.js.map +1 -0
  136. package/dist/transientClassify.js.map +1 -1
  137. package/package.json +17 -17
@@ -1,5 +1,31 @@
1
1
  import { makeOutcomeFacts } from "@claudexor/schema";
2
2
  import { toolWarnings } from "./attemptTelemetry.js";
3
+ /**
4
+ * The one typed refusal a run may speak with when NO candidate produced work.
5
+ *
6
+ * UNANIMITY is the whole rule. Promoting one slot's refusal to speak for a run
7
+ * whose other slots died of something else would tell the caller to wait out a
8
+ * quota window for a failure no timer fixes — so mixed causes keep the honest
9
+ * mixed-cause harness terminal instead. When the causes DO agree, the run
10
+ * carries the LATEST reset: waiting for the earliest would leave every other
11
+ * exhausted window still exhausted. An unknown reset anywhere makes the run's
12
+ * reset unknown — a partial answer here is worse than none.
13
+ */
14
+ export function unanimousDeclaredFailure(runs) {
15
+ const first = runs[0]?.declaredFailure;
16
+ if (!first?.code)
17
+ return null;
18
+ const declared = runs.map((run) => run.declaredFailure);
19
+ const agrees = declared.every((d) => d?.code === first.code && d?.category === first.category);
20
+ if (!agrees)
21
+ return null;
22
+ const resets = declared.map((d) => d?.resetsAt ?? null);
23
+ const known = resets.filter((at) => at !== null);
24
+ const resetsAt = known.length > 0 && known.length === resets.length
25
+ ? known.reduce((latest, at) => (Date.parse(at) > Date.parse(latest) ? at : latest))
26
+ : null;
27
+ return { ...first, resetsAt };
28
+ }
3
29
  /** A pre-work corpse (harness error, no diff) AND an `interrupted` partial
4
30
  * (D-16 r7: terminal context exhaustion with NO completed WorkReport) are both
5
31
  * excluded from review: an interrupted candidate carries untrustworthy
@@ -1 +1 @@
1
- {"version":3,"file":"candidateEvidence.js","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"candidateEvidence.js","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import type { CredentialProfile, HarnessRunSpec, QuotaSnapshot } from "@claudexor/schema";
2
+ export interface ProfilePolicy {
3
+ limit_action: "fail" | "ask" | "rotate";
4
+ rotation_eligible: string[];
5
+ headroom_threshold: number;
6
+ }
7
+ /** Typed quota evidence for a profile over its headroom bound (provenance). */
8
+ export interface HeadroomBreach {
9
+ constraint_id: string;
10
+ used_ratio: number;
11
+ threshold: number;
12
+ resets_at: string | null;
13
+ }
14
+ /**
15
+ * Static rotation candidates, before any credential-backed readiness probe.
16
+ * One owner applies policy order, enabled/harness scope, current identity,
17
+ * already-tried exclusions, and the payment-kind fence. Callers then probe
18
+ * only identities that could actually be selected.
19
+ */
20
+ export declare function staticRotationCandidates(args: {
21
+ registry: readonly CredentialProfile[];
22
+ harnessId: string;
23
+ policy: ProfilePolicy;
24
+ current: Pick<CredentialProfile, "profile_id" | "credential_kind"> | null;
25
+ excluded?: ReadonlySet<string>;
26
+ }): CredentialProfile[];
27
+ /**
28
+ * Proactive headroom check (W5.4 `profile_headroom_preflight`): the SELECTED
29
+ * profile's freshest snapshot windows against the policy threshold. Unknown
30
+ * usage is NOT a breach — rotation never triggers on missing data.
31
+ */
32
+ export declare function profileHeadroomBreach(snapshots: readonly QuotaSnapshot[], harnessId: string, profileId: string | null, threshold: number): HeadroomBreach | null;
33
+ /**
34
+ * The next rotation target after `currentProfileId` (W5.4): policy order wins
35
+ * (`rotation_eligible`), else every enabled profile of the harness in registry
36
+ * order. The current profile and disabled/unknown ids never come back; a
37
+ * profile already over the headroom bound is skipped (rotating INTO a spent
38
+ * subscription is not a failover). Cross-subscription rotation of one vendor
39
+ * is allowed by owner decision — but rotation NEVER crosses credential kinds
40
+ * (release wave round-16 BLOCK): a subscription→API-key swap silently changes
41
+ * the payment model mid-attempt, and the attempt's first-wins auth-route
42
+ * receipt (decided once before spawn) would misvalue metered usage as
43
+ * subscription entitlement, bypassing a finite cash cap.
44
+ */
45
+ export declare function nextEligibleProfile(registry: readonly CredentialProfile[], harnessId: string, policy: ProfilePolicy, current: Pick<CredentialProfile, "profile_id" | "credential_kind"> | null, snapshots: readonly QuotaSnapshot[], readyProfileIds: ReadonlySet<string>, excluded?: ReadonlySet<string>): CredentialProfile | null;
46
+ /**
47
+ * `rotation_retry_eligible` (sol #30): a failover retry is allowed ONLY when
48
+ * the attempt saw a TYPED vendor limit AND produced no deliverable and no
49
+ * workspace mutation — a partially-acted attempt never silently reruns.
50
+ */
51
+ export declare function rotationRetryEligible(input: {
52
+ sawTypedLimit: boolean;
53
+ deliverableEmpty: boolean;
54
+ }): boolean;
55
+ type EmitFn = (type: "route.profile.headroom_exceeded" | "route.profile.rotated" | "route.profile.rotation_exhausted", payload: Record<string, unknown>) => void;
56
+ /**
57
+ * `profile_headroom_preflight` (W5.4): BEFORE spawn, the selected profile's
58
+ * freshest quota windows are checked against the policy threshold. A breach
59
+ * is always a typed event; `rotate` swaps to the next eligible profile with
60
+ * provenance, `ask`/`fail` proceed on the selected profile — the runtime
61
+ * `vendor_limit_rejected` evidence stays the terminating truth.
62
+ */
63
+ export declare function preflightCredentialProfile(args: {
64
+ profile: CredentialProfile;
65
+ harnessId: string;
66
+ policy: ProfilePolicy;
67
+ registry: readonly CredentialProfile[];
68
+ snapshots: readonly QuotaSnapshot[];
69
+ readyProfileIds: ReadonlySet<string>;
70
+ emit: EmitFn;
71
+ }): CredentialProfile;
72
+ /**
73
+ * Default-subject start selection (INV-135, owner scope "auto-balance"): when
74
+ * NO profile is pinned, the policy is `rotate`, and the DEFAULT store's own
75
+ * fresh quota window is at/over the headroom bound, pick the first eligible
76
+ * SUBSCRIPTION profile instead of spawning into a near-certain vendor limit.
77
+ * Strictly opt-in: `fail`/`ask` keep today's default-user behavior untouched
78
+ * (the profile engine's fail action governs PINNED profiles only — throwing
79
+ * here would brick every default user at 90% quota). Unknown or stale usage
80
+ * never rotates.
81
+ */
82
+ export declare function preflightDefaultSubject(args: {
83
+ harnessId: string;
84
+ policy: ProfilePolicy;
85
+ registry: readonly CredentialProfile[];
86
+ snapshots: readonly QuotaSnapshot[];
87
+ readyProfileIds: ReadonlySet<string>;
88
+ defaultRoute: "local_session" | "api_key" | null;
89
+ emit: EmitFn;
90
+ }): CredentialProfile | null;
91
+ /**
92
+ * Reactive failover plan (`vendor_limit_rejected`, W5.4): rotation fires ONLY
93
+ * on the typed predicate under a `rotate` policy, marks the current profile
94
+ * tried (at most once per attempt each), and returns the next target with
95
+ * provenance already emitted — or null when the attempt must fail as-is.
96
+ * `currentProfile: null` is the DEFAULT subject: allowed ONLY when the caller
97
+ * proves the attempt's pre-spawn route was vendor_native (a metered default
98
+ * hitting a limit is a budget fact, not a subscription to fail over from).
99
+ */
100
+ export declare function planReactiveRotation(args: {
101
+ currentProfile: CredentialProfile | null;
102
+ defaultRouteWasVendorNative?: boolean;
103
+ harnessId: string;
104
+ attemptId: string;
105
+ policy: ProfilePolicy;
106
+ registry: readonly CredentialProfile[];
107
+ snapshots: readonly QuotaSnapshot[];
108
+ readyProfileIds: ReadonlySet<string>;
109
+ triedProfiles: Set<string>;
110
+ sawTypedLimit: boolean;
111
+ deliverableEmpty: boolean;
112
+ lastLimit: {
113
+ retryDelayMs: number | null;
114
+ resetsAt: string | null;
115
+ } | null;
116
+ emit: EmitFn;
117
+ }): CredentialProfile | null;
118
+ /**
119
+ * Shared reactive-failover step for BOTH lanes: given the attempt's typed
120
+ * evidence, plan a rotation and rebuild the spec on a NEW vendor session
121
+ * under the next profile — or return null when the attempt must fail as-is.
122
+ */
123
+ export declare function rotateSpecOnTypedLimit(args: {
124
+ spec: HarnessRunSpec;
125
+ harnessId: string;
126
+ attemptId: string;
127
+ policy: ProfilePolicy;
128
+ registry: readonly CredentialProfile[];
129
+ snapshots: readonly QuotaSnapshot[];
130
+ readyProfileIds: ReadonlySet<string>;
131
+ triedProfiles: Set<string>;
132
+ sawTypedLimit: boolean;
133
+ deliverableEmpty: boolean;
134
+ lastLimit: {
135
+ retryDelayMs: number | null;
136
+ resetsAt: string | null;
137
+ } | null;
138
+ emit: EmitFn;
139
+ newSessionId: () => string;
140
+ /** Pre-spawn route estimate for a profile-less spec: default-subject
141
+ * rotation is allowed ONLY off a vendor_native attempt. */
142
+ defaultRouteWasVendorNative?: boolean;
143
+ }): HarnessRunSpec | null;
144
+ export {};
145
+ //# sourceMappingURL=credential-profile-rotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-profile-rotation.d.ts","sourceRoot":"","sources":["../src/credential-profile-rotation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG1F,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACxC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC1E,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChC,GAAG,iBAAiB,EAAE,CAsBtB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,aAAa,EAAE,EACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,SAAS,EAAE,MAAM,GAChB,cAAc,GAAG,IAAI,CAmBvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,iBAAiB,CAAC,GAAG,IAAI,EACzE,SAAS,EAAE,SAAS,aAAa,EAAE,EACnC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,EACpC,QAAQ,GAAE,WAAW,CAAC,MAAM,CAAa,GACxC,iBAAiB,GAAG,IAAI,CAgB1B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,GAAG,OAAO,CAEV;AAED,KAAK,MAAM,GAAG,CACZ,IAAI,EACA,iCAAiC,GACjC,uBAAuB,GACvB,kCAAkC,EACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC7B,IAAI,CAAC;AA0FV;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,iBAAiB,CAwDpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,YAAY,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,iBAAiB,GAAG,IAAI,CAsC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,cAAc,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACzC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,iBAAiB,GAAG,IAAI,CAuC3B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B;+DAC2D;IAC3D,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC,GAAG,cAAc,GAAG,IAAI,CAuBxB"}
@@ -0,0 +1,335 @@
1
+ import { HarnessRunSpec as HarnessRunSpecSchema } from "@claudexor/schema";
2
+ /**
3
+ * Static rotation candidates, before any credential-backed readiness probe.
4
+ * One owner applies policy order, enabled/harness scope, current identity,
5
+ * already-tried exclusions, and the payment-kind fence. Callers then probe
6
+ * only identities that could actually be selected.
7
+ */
8
+ export function staticRotationCandidates(args) {
9
+ const pool = args.registry.filter((profile) => profile.harness_id === args.harnessId && profile.enabled);
10
+ const ordered = args.policy.rotation_eligible.length > 0
11
+ ? args.policy.rotation_eligible
12
+ .map((id) => pool.find((profile) => profile.profile_id === id))
13
+ .filter((profile) => profile !== undefined)
14
+ : pool;
15
+ const excluded = args.excluded ?? new Set();
16
+ return ordered.filter((candidate) => {
17
+ if (candidate.profile_id === args.current?.profile_id)
18
+ return false;
19
+ if (excluded.has(candidate.profile_id))
20
+ return false;
21
+ if (args.current !== null && candidate.credential_kind !== args.current.credential_kind) {
22
+ return false;
23
+ }
24
+ // The default subject is vendor-native subscription state; it never probes
25
+ // or rotates into a metered API-key identity.
26
+ if (args.current === null && candidate.credential_kind === "api_key")
27
+ return false;
28
+ return true;
29
+ });
30
+ }
31
+ /**
32
+ * Proactive headroom check (W5.4 `profile_headroom_preflight`): the SELECTED
33
+ * profile's freshest snapshot windows against the policy threshold. Unknown
34
+ * usage is NOT a breach — rotation never triggers on missing data.
35
+ */
36
+ export function profileHeadroomBreach(snapshots, harnessId, profileId, threshold) {
37
+ for (const snapshot of snapshots) {
38
+ // FRESH evidence only (release wave tier1 #3): a stale or unknown reading
39
+ // must never breach headroom, rotate a profile away, or fail selection.
40
+ if (snapshot.freshness !== "fresh")
41
+ continue;
42
+ if (snapshot.subject.harness !== harnessId)
43
+ continue;
44
+ if ((snapshot.subject.subject_id ?? null) !== profileId)
45
+ continue;
46
+ for (const constraint of snapshot.constraints) {
47
+ if (constraint.used_ratio !== null && constraint.used_ratio >= threshold) {
48
+ return {
49
+ constraint_id: constraint.id,
50
+ used_ratio: constraint.used_ratio,
51
+ threshold,
52
+ resets_at: constraint.resets_at,
53
+ };
54
+ }
55
+ }
56
+ }
57
+ return null;
58
+ }
59
+ /**
60
+ * The next rotation target after `currentProfileId` (W5.4): policy order wins
61
+ * (`rotation_eligible`), else every enabled profile of the harness in registry
62
+ * order. The current profile and disabled/unknown ids never come back; a
63
+ * profile already over the headroom bound is skipped (rotating INTO a spent
64
+ * subscription is not a failover). Cross-subscription rotation of one vendor
65
+ * is allowed by owner decision — but rotation NEVER crosses credential kinds
66
+ * (release wave round-16 BLOCK): a subscription→API-key swap silently changes
67
+ * the payment model mid-attempt, and the attempt's first-wins auth-route
68
+ * receipt (decided once before spawn) would misvalue metered usage as
69
+ * subscription entitlement, bypassing a finite cash cap.
70
+ */
71
+ export function nextEligibleProfile(registry, harnessId, policy, current, snapshots, readyProfileIds, excluded = new Set()) {
72
+ for (const candidate of staticRotationCandidates({
73
+ registry,
74
+ harnessId,
75
+ policy,
76
+ current,
77
+ excluded,
78
+ })) {
79
+ if (!readyProfileIds.has(candidate.profile_id))
80
+ continue;
81
+ if (profileHeadroomBreach(snapshots, harnessId, candidate.profile_id, policy.headroom_threshold))
82
+ continue;
83
+ return candidate;
84
+ }
85
+ return null;
86
+ }
87
+ /**
88
+ * `rotation_retry_eligible` (sol #30): a failover retry is allowed ONLY when
89
+ * the attempt saw a TYPED vendor limit AND produced no deliverable and no
90
+ * workspace mutation — a partially-acted attempt never silently reruns.
91
+ */
92
+ export function rotationRetryEligible(input) {
93
+ return input.sawTypedLimit && input.deliverableEmpty;
94
+ }
95
+ function emitRotationExhausted(args) {
96
+ const excluded = args.excluded ?? new Set();
97
+ const candidates = args.registry
98
+ .filter((profile) => profile.harness_id === args.harnessId && profile.enabled)
99
+ .map((profile) => {
100
+ const breach = profileHeadroomBreach(args.snapshots, args.harnessId, profile.profile_id, args.policy.headroom_threshold);
101
+ const rejected = profile.profile_id === args.current?.profile_id
102
+ ? "current"
103
+ : args.policy.rotation_eligible.length > 0 &&
104
+ !args.policy.rotation_eligible.includes(profile.profile_id)
105
+ ? "not_in_rotation_policy"
106
+ : excluded.has(profile.profile_id)
107
+ ? "already_tried"
108
+ : args.current && profile.credential_kind !== args.current.credential_kind
109
+ ? "credential_kind_mismatch"
110
+ : args.current === null && profile.credential_kind === "api_key"
111
+ ? "credential_kind_mismatch"
112
+ : !args.readyProfileIds.has(profile.profile_id)
113
+ ? "not_ready"
114
+ : breach
115
+ ? "headroom_exceeded"
116
+ : "not_selected";
117
+ return {
118
+ profile_id: profile.profile_id,
119
+ credential_kind: profile.credential_kind,
120
+ rejected,
121
+ headroom: breach,
122
+ };
123
+ });
124
+ args.emit("route.profile.rotation_exhausted", {
125
+ harness_id: args.harnessId,
126
+ attempt_id: args.attemptId,
127
+ from_profile_id: args.current?.profile_id ?? null,
128
+ reason: args.reason,
129
+ threshold: args.policy.headroom_threshold,
130
+ candidates,
131
+ });
132
+ }
133
+ /**
134
+ * A spent subscription window, refused MACHINE-READABLY.
135
+ *
136
+ * The verdict a caller actually needs from this refusal is "not now, come back
137
+ * at T" — and the only honest way to deliver T is as a field. Gluing it into
138
+ * the sentence and shipping the terminal as `category: internal, code: null`
139
+ * left every consumer (a surface, a scheduler, an automating host) to regex
140
+ * the prose for a timestamp, which no contract in this repo permits. The
141
+ * message stays human-readable; the machine reads `code` and `resetsAt`, which
142
+ * the run terminal lifts onto `final/failure.yaml` verbatim.
143
+ */
144
+ function subscriptionWindowExhausted(profileId, harnessId, breach) {
145
+ return Object.assign(new Error(`credential profile "${profileId}" (${harnessId}) is over its headroom threshold ` +
146
+ `(${breach.constraint_id} at ${Math.round(breach.used_ratio * 100)}% >= ${Math.round(breach.threshold * 100)}%; ` +
147
+ `limit_action=fail${breach.resets_at ? `; resets ${breach.resets_at}` : ""})`), {
148
+ code: "subscription_window_exhausted",
149
+ // Not `internal`: nothing malfunctioned. The account cannot serve this
150
+ // run until its window reopens, which is what harness_unavailable means.
151
+ category: "harness_unavailable",
152
+ resetsAt: breach.resets_at,
153
+ });
154
+ }
155
+ /**
156
+ * `profile_headroom_preflight` (W5.4): BEFORE spawn, the selected profile's
157
+ * freshest quota windows are checked against the policy threshold. A breach
158
+ * is always a typed event; `rotate` swaps to the next eligible profile with
159
+ * provenance, `ask`/`fail` proceed on the selected profile — the runtime
160
+ * `vendor_limit_rejected` evidence stays the terminating truth.
161
+ */
162
+ export function preflightCredentialProfile(args) {
163
+ const { profile, harnessId, policy, registry, snapshots, readyProfileIds, emit } = args;
164
+ const breach = profileHeadroomBreach(snapshots, harnessId, profile.profile_id, policy.headroom_threshold);
165
+ if (!breach)
166
+ return profile;
167
+ emit("route.profile.headroom_exceeded", {
168
+ harness_id: harnessId,
169
+ profile_id: profile.profile_id,
170
+ action: policy.limit_action,
171
+ constraint_id: breach.constraint_id,
172
+ used_ratio: breach.used_ratio,
173
+ threshold: breach.threshold,
174
+ resets_at: breach.resets_at,
175
+ });
176
+ if (policy.limit_action === "fail") {
177
+ // The documented FAIL action fails (release wave tier1 #4): a FRESH breach
178
+ // under fail refuses before spawn with the evidence, instead of silently
179
+ // proceeding into a vendor rejection.
180
+ throw subscriptionWindowExhausted(profile.profile_id, harnessId, breach);
181
+ }
182
+ if (policy.limit_action !== "rotate")
183
+ return profile;
184
+ const next = nextEligibleProfile(registry, harnessId, policy, profile, snapshots, readyProfileIds);
185
+ if (!next) {
186
+ emitRotationExhausted({
187
+ current: profile,
188
+ harnessId,
189
+ policy,
190
+ registry,
191
+ snapshots,
192
+ readyProfileIds,
193
+ reason: "profile_headroom_preflight",
194
+ emit,
195
+ });
196
+ return profile;
197
+ }
198
+ emit("route.profile.rotated", {
199
+ harness_id: harnessId,
200
+ from_profile_id: profile.profile_id,
201
+ to_profile_id: next.profile_id,
202
+ reason: "profile_headroom_preflight",
203
+ constraint_id: breach.constraint_id,
204
+ used_ratio: breach.used_ratio,
205
+ resets_at: breach.resets_at,
206
+ });
207
+ return next;
208
+ }
209
+ /**
210
+ * Default-subject start selection (INV-135, owner scope "auto-balance"): when
211
+ * NO profile is pinned, the policy is `rotate`, and the DEFAULT store's own
212
+ * fresh quota window is at/over the headroom bound, pick the first eligible
213
+ * SUBSCRIPTION profile instead of spawning into a near-certain vendor limit.
214
+ * Strictly opt-in: `fail`/`ask` keep today's default-user behavior untouched
215
+ * (the profile engine's fail action governs PINNED profiles only — throwing
216
+ * here would brick every default user at 90% quota). Unknown or stale usage
217
+ * never rotates.
218
+ */
219
+ export function preflightDefaultSubject(args) {
220
+ const { harnessId, policy, registry, snapshots, readyProfileIds, defaultRoute, emit } = args;
221
+ if (policy.limit_action !== "rotate" || defaultRoute !== "local_session")
222
+ return null;
223
+ const breach = profileHeadroomBreach(snapshots, harnessId, null, policy.headroom_threshold);
224
+ if (!breach)
225
+ return null;
226
+ emit("route.profile.headroom_exceeded", {
227
+ harness_id: harnessId,
228
+ profile_id: null,
229
+ action: policy.limit_action,
230
+ constraint_id: breach.constraint_id,
231
+ used_ratio: breach.used_ratio,
232
+ threshold: breach.threshold,
233
+ resets_at: breach.resets_at,
234
+ });
235
+ const next = nextEligibleProfile(registry, harnessId, policy, null, snapshots, readyProfileIds);
236
+ if (!next) {
237
+ emitRotationExhausted({
238
+ current: null,
239
+ harnessId,
240
+ policy,
241
+ registry,
242
+ snapshots,
243
+ readyProfileIds,
244
+ reason: "profile_headroom_preflight",
245
+ emit,
246
+ });
247
+ return null;
248
+ }
249
+ emit("route.profile.rotated", {
250
+ harness_id: harnessId,
251
+ from_profile_id: null,
252
+ to_profile_id: next.profile_id,
253
+ reason: "profile_headroom_preflight",
254
+ constraint_id: breach.constraint_id,
255
+ used_ratio: breach.used_ratio,
256
+ resets_at: breach.resets_at,
257
+ });
258
+ return next;
259
+ }
260
+ /**
261
+ * Reactive failover plan (`vendor_limit_rejected`, W5.4): rotation fires ONLY
262
+ * on the typed predicate under a `rotate` policy, marks the current profile
263
+ * tried (at most once per attempt each), and returns the next target with
264
+ * provenance already emitted — or null when the attempt must fail as-is.
265
+ * `currentProfile: null` is the DEFAULT subject: allowed ONLY when the caller
266
+ * proves the attempt's pre-spawn route was vendor_native (a metered default
267
+ * hitting a limit is a budget fact, not a subscription to fail over from).
268
+ */
269
+ export function planReactiveRotation(args) {
270
+ if (!rotationRetryEligible(args))
271
+ return null;
272
+ if (args.policy.limit_action !== "rotate")
273
+ return null;
274
+ if (args.currentProfile === null && args.defaultRouteWasVendorNative !== true)
275
+ return null;
276
+ if (args.currentProfile)
277
+ args.triedProfiles.add(args.currentProfile.profile_id);
278
+ const next = nextEligibleProfile(args.registry, args.harnessId, args.policy, args.currentProfile, args.snapshots, args.readyProfileIds, args.triedProfiles);
279
+ if (!next) {
280
+ emitRotationExhausted({
281
+ current: args.currentProfile,
282
+ harnessId: args.harnessId,
283
+ policy: args.policy,
284
+ registry: args.registry,
285
+ snapshots: args.snapshots,
286
+ readyProfileIds: args.readyProfileIds,
287
+ excluded: args.triedProfiles,
288
+ attemptId: args.attemptId,
289
+ reason: "vendor_limit_rejected",
290
+ emit: args.emit,
291
+ });
292
+ return null;
293
+ }
294
+ args.emit("route.profile.rotated", {
295
+ harness_id: args.harnessId,
296
+ attempt_id: args.attemptId,
297
+ from_profile_id: args.currentProfile?.profile_id ?? null,
298
+ to_profile_id: next.profile_id,
299
+ reason: "vendor_limit_rejected",
300
+ retry_delay_ms: args.lastLimit?.retryDelayMs ?? null,
301
+ resets_at: args.lastLimit?.resetsAt ?? null,
302
+ });
303
+ return next;
304
+ }
305
+ /**
306
+ * Shared reactive-failover step for BOTH lanes: given the attempt's typed
307
+ * evidence, plan a rotation and rebuild the spec on a NEW vendor session
308
+ * under the next profile — or return null when the attempt must fail as-is.
309
+ */
310
+ export function rotateSpecOnTypedLimit(args) {
311
+ const rotation = planReactiveRotation({
312
+ currentProfile: args.spec.credential_profile ?? null,
313
+ defaultRouteWasVendorNative: args.defaultRouteWasVendorNative,
314
+ harnessId: args.harnessId,
315
+ attemptId: args.attemptId,
316
+ policy: args.policy,
317
+ registry: args.registry,
318
+ snapshots: args.snapshots,
319
+ readyProfileIds: args.readyProfileIds,
320
+ triedProfiles: args.triedProfiles,
321
+ sawTypedLimit: args.sawTypedLimit,
322
+ deliverableEmpty: args.deliverableEmpty,
323
+ lastLimit: args.lastLimit,
324
+ emit: args.emit,
325
+ });
326
+ if (!rotation)
327
+ return null;
328
+ return HarnessRunSpecSchema.parse({
329
+ ...args.spec,
330
+ session_id: args.newSessionId(),
331
+ credential_profile: rotation,
332
+ resume_session_id: null,
333
+ });
334
+ }
335
+ //# sourceMappingURL=credential-profile-rotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-profile-rotation.js","sourceRoot":"","sources":["../src/credential-profile-rotation.ts"],"names":[],"mappings":"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"}