@claudexor/orchestrator 1.0.1 → 2.1.2

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 (75) hide show
  1. package/dist/attemptTelemetry.d.ts +38 -2
  2. package/dist/attemptTelemetry.d.ts.map +1 -1
  3. package/dist/attemptTelemetry.js +75 -2
  4. package/dist/attemptTelemetry.js.map +1 -1
  5. package/dist/contract-gates.d.ts +21 -0
  6. package/dist/contract-gates.d.ts.map +1 -0
  7. package/dist/contract-gates.js +93 -0
  8. package/dist/contract-gates.js.map +1 -0
  9. package/dist/credential-profiles.d.ts +152 -0
  10. package/dist/credential-profiles.d.ts.map +1 -0
  11. package/dist/credential-profiles.js +270 -0
  12. package/dist/credential-profiles.js.map +1 -0
  13. package/dist/diffReview.d.ts +9 -1
  14. package/dist/diffReview.d.ts.map +1 -1
  15. package/dist/diffReview.js +114 -18
  16. package/dist/diffReview.js.map +1 -1
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/modelGovernance.d.ts +6 -1
  22. package/dist/modelGovernance.d.ts.map +1 -1
  23. package/dist/modelGovernance.js +8 -2
  24. package/dist/modelGovernance.js.map +1 -1
  25. package/dist/orchestrateExecutor.d.ts +43 -0
  26. package/dist/orchestrateExecutor.d.ts.map +1 -0
  27. package/dist/orchestrateExecutor.js +207 -0
  28. package/dist/orchestrateExecutor.js.map +1 -0
  29. package/dist/orchestratePlanner.d.ts.map +1 -1
  30. package/dist/orchestratePlanner.js.map +1 -1
  31. package/dist/orchestrator.d.ts +100 -83
  32. package/dist/orchestrator.d.ts.map +1 -1
  33. package/dist/orchestrator.js +1008 -993
  34. package/dist/orchestrator.js.map +1 -1
  35. package/dist/outcomeReducer.d.ts +25 -0
  36. package/dist/outcomeReducer.d.ts.map +1 -0
  37. package/dist/outcomeReducer.js +121 -0
  38. package/dist/outcomeReducer.js.map +1 -0
  39. package/dist/policyFindings.d.ts +18 -0
  40. package/dist/policyFindings.d.ts.map +1 -0
  41. package/dist/policyFindings.js +166 -0
  42. package/dist/policyFindings.js.map +1 -0
  43. package/dist/requestRequirements.d.ts +38 -0
  44. package/dist/requestRequirements.d.ts.map +1 -0
  45. package/dist/requestRequirements.js +127 -0
  46. package/dist/requestRequirements.js.map +1 -0
  47. package/dist/reviewerPanel.d.ts +15 -1
  48. package/dist/reviewerPanel.d.ts.map +1 -1
  49. package/dist/reviewerPanel.js +85 -2
  50. package/dist/reviewerPanel.js.map +1 -1
  51. package/dist/routeContext.d.ts +37 -0
  52. package/dist/routeContext.d.ts.map +1 -0
  53. package/dist/routeContext.js +38 -0
  54. package/dist/routeContext.js.map +1 -0
  55. package/dist/runSupport.d.ts +37 -21
  56. package/dist/runSupport.d.ts.map +1 -1
  57. package/dist/runSupport.js +102 -78
  58. package/dist/runSupport.js.map +1 -1
  59. package/dist/runTelemetryWriter.d.ts +20 -0
  60. package/dist/runTelemetryWriter.d.ts.map +1 -0
  61. package/dist/runTelemetryWriter.js +68 -0
  62. package/dist/runTelemetryWriter.js.map +1 -0
  63. package/dist/runTerminals.d.ts +7 -1
  64. package/dist/runTerminals.d.ts.map +1 -1
  65. package/dist/runTerminals.js +42 -4
  66. package/dist/runTerminals.js.map +1 -1
  67. package/dist/structuredOutput.d.ts +33 -0
  68. package/dist/structuredOutput.d.ts.map +1 -0
  69. package/dist/structuredOutput.js +106 -0
  70. package/dist/structuredOutput.js.map +1 -0
  71. package/package.json +19 -18
  72. package/dist/finalVerifier.d.ts +0 -25
  73. package/dist/finalVerifier.d.ts.map +0 -1
  74. package/dist/finalVerifier.js +0 -110
  75. package/dist/finalVerifier.js.map +0 -1
@@ -0,0 +1,270 @@
1
+ import { HarnessRunSpec as HarnessRunSpecSchema } from "@claudexor/schema";
2
+ /**
3
+ * The ONE resolve owner for credential profiles (INV-135): explicit id →
4
+ * durable registry entry for exactly this harness. Unknown, disabled, or
5
+ * harness-mismatched ids throw a typed refusal — an explicit profile must
6
+ * never silently become the default credential ladder.
7
+ */
8
+ export function resolveCredentialProfile(registry, wanted, harnessId) {
9
+ const match = registry.find((p) => p.profile_id === wanted && p.harness_id === harnessId);
10
+ if (!match) {
11
+ throw new Error(`credential profile "${wanted}" is not registered for harness "${harnessId}"`);
12
+ }
13
+ if (!match.enabled) {
14
+ throw new Error(`credential profile "${wanted}" (${harnessId}) is disabled`);
15
+ }
16
+ return match;
17
+ }
18
+ /**
19
+ * Proactive headroom check (W5.4 `profile_headroom_preflight`): the SELECTED
20
+ * profile's freshest snapshot windows against the policy threshold. Unknown
21
+ * usage is NOT a breach — rotation never triggers on missing data.
22
+ */
23
+ export function profileHeadroomBreach(snapshots, harnessId, profileId, threshold) {
24
+ for (const snapshot of snapshots) {
25
+ // FRESH evidence only (release wave tier1 #3): a stale or unknown reading
26
+ // must never breach headroom, rotate a profile away, or fail selection.
27
+ if (snapshot.freshness !== "fresh")
28
+ continue;
29
+ if (snapshot.subject.harness !== harnessId)
30
+ continue;
31
+ if ((snapshot.subject.subject_id ?? null) !== profileId)
32
+ continue;
33
+ for (const constraint of snapshot.constraints) {
34
+ if (constraint.used_ratio !== null && constraint.used_ratio >= threshold) {
35
+ return {
36
+ constraint_id: constraint.id,
37
+ used_ratio: constraint.used_ratio,
38
+ threshold,
39
+ resets_at: constraint.resets_at,
40
+ };
41
+ }
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ /**
47
+ * The next rotation target after `currentProfileId` (W5.4): policy order wins
48
+ * (`rotation_eligible`), else every enabled profile of the harness in registry
49
+ * order. The current profile and disabled/unknown ids never come back; a
50
+ * profile already over the headroom bound is skipped (rotating INTO a spent
51
+ * subscription is not a failover). Cross-subscription rotation of one vendor
52
+ * is allowed by owner decision — but rotation NEVER crosses credential kinds
53
+ * (release wave round-16 BLOCK): a subscription→API-key swap silently changes
54
+ * the payment model mid-attempt, and the attempt's first-wins auth-route
55
+ * receipt (decided once before spawn) would misvalue metered usage as
56
+ * subscription entitlement, bypassing a finite cash cap.
57
+ */
58
+ export function nextEligibleProfile(registry, harnessId, policy, current, snapshots, excluded = new Set()) {
59
+ const pool = registry.filter((p) => p.harness_id === harnessId && p.enabled);
60
+ const ordered = policy.rotation_eligible.length > 0
61
+ ? policy.rotation_eligible
62
+ .map((id) => pool.find((p) => p.profile_id === id))
63
+ .filter((p) => p !== undefined)
64
+ : pool;
65
+ for (const candidate of ordered) {
66
+ if (candidate.profile_id === current?.profile_id)
67
+ continue;
68
+ if (excluded.has(candidate.profile_id))
69
+ continue;
70
+ // Fail-CLOSED kind guard (round-17 hardening of the round-16 BLOCK): the
71
+ // kind comes from the TYPED current profile in hand — never re-found in
72
+ // a freshly reloaded pool, where a mid-flight disable/remove of the
73
+ // current profile would have silently dropped the cross-kind prohibition.
74
+ if (current !== null && candidate.credential_kind !== current.credential_kind)
75
+ continue;
76
+ // `current === null` is the DEFAULT subject (the vendor-native store): the
77
+ // same round-16 BLOCK applies — rotating the subscription default INTO an
78
+ // api_key profile would silently change the payment model mid-attempt.
79
+ if (current === null && candidate.credential_kind === "api_key")
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
+ /**
96
+ * `profile_headroom_preflight` (W5.4): BEFORE spawn, the selected profile's
97
+ * freshest quota windows are checked against the policy threshold. A breach
98
+ * is always a typed event; `rotate` swaps to the next eligible profile with
99
+ * provenance, `ask`/`fail` proceed on the selected profile — the runtime
100
+ * `vendor_limit_rejected` evidence stays the terminating truth.
101
+ */
102
+ export function preflightCredentialProfile(args) {
103
+ const { profile, harnessId, policy, registry, snapshots, emit } = args;
104
+ const breach = profileHeadroomBreach(snapshots, harnessId, profile.profile_id, policy.headroom_threshold);
105
+ if (!breach)
106
+ return profile;
107
+ emit("route.profile.headroom_exceeded", {
108
+ harness_id: harnessId,
109
+ profile_id: profile.profile_id,
110
+ action: policy.limit_action,
111
+ constraint_id: breach.constraint_id,
112
+ used_ratio: breach.used_ratio,
113
+ threshold: breach.threshold,
114
+ resets_at: breach.resets_at,
115
+ });
116
+ if (policy.limit_action === "fail") {
117
+ // The documented FAIL action fails (release wave tier1 #4): a FRESH breach
118
+ // under fail refuses before spawn with the evidence, instead of silently
119
+ // proceeding into a vendor rejection.
120
+ throw new Error(`credential profile "${profile.profile_id}" (${harnessId}) is over its headroom threshold ` +
121
+ `(${breach.constraint_id} at ${Math.round(breach.used_ratio * 100)}% >= ${Math.round(breach.threshold * 100)}%; ` +
122
+ `limit_action=fail${breach.resets_at ? `; resets ${breach.resets_at}` : ""})`);
123
+ }
124
+ if (policy.limit_action !== "rotate")
125
+ return profile;
126
+ const next = nextEligibleProfile(registry, harnessId, policy, profile, snapshots);
127
+ if (!next)
128
+ return profile;
129
+ emit("route.profile.rotated", {
130
+ harness_id: harnessId,
131
+ from_profile_id: profile.profile_id,
132
+ to_profile_id: next.profile_id,
133
+ reason: "profile_headroom_preflight",
134
+ constraint_id: breach.constraint_id,
135
+ used_ratio: breach.used_ratio,
136
+ resets_at: breach.resets_at,
137
+ });
138
+ return next;
139
+ }
140
+ /**
141
+ * Default-subject start selection (INV-135, owner scope "auto-balance"): when
142
+ * NO profile is pinned, the policy is `rotate`, and the DEFAULT store's own
143
+ * fresh quota window is at/over the headroom bound, pick the first eligible
144
+ * SUBSCRIPTION profile instead of spawning into a near-certain vendor limit.
145
+ * Strictly opt-in: `fail`/`ask` keep today's default-user behavior untouched
146
+ * (the profile engine's fail action governs PINNED profiles only — throwing
147
+ * here would brick every default user at 90% quota). Unknown or stale usage
148
+ * never rotates.
149
+ */
150
+ export function preflightDefaultSubject(args) {
151
+ const { harnessId, policy, registry, snapshots, emit } = args;
152
+ if (policy.limit_action !== "rotate")
153
+ return null;
154
+ const breach = profileHeadroomBreach(snapshots, harnessId, null, policy.headroom_threshold);
155
+ if (!breach)
156
+ return null;
157
+ emit("route.profile.headroom_exceeded", {
158
+ harness_id: harnessId,
159
+ profile_id: null,
160
+ action: policy.limit_action,
161
+ constraint_id: breach.constraint_id,
162
+ used_ratio: breach.used_ratio,
163
+ threshold: breach.threshold,
164
+ resets_at: breach.resets_at,
165
+ });
166
+ const next = nextEligibleProfile(registry, harnessId, policy, null, snapshots);
167
+ if (!next)
168
+ return null;
169
+ emit("route.profile.rotated", {
170
+ harness_id: harnessId,
171
+ from_profile_id: null,
172
+ to_profile_id: next.profile_id,
173
+ reason: "profile_headroom_preflight",
174
+ constraint_id: breach.constraint_id,
175
+ used_ratio: breach.used_ratio,
176
+ resets_at: breach.resets_at,
177
+ });
178
+ return next;
179
+ }
180
+ /**
181
+ * Reactive failover plan (`vendor_limit_rejected`, W5.4): rotation fires ONLY
182
+ * on the typed predicate under a `rotate` policy, marks the current profile
183
+ * tried (at most once per attempt each), and returns the next target with
184
+ * provenance already emitted — or null when the attempt must fail as-is.
185
+ * `currentProfile: null` is the DEFAULT subject: allowed ONLY when the caller
186
+ * proves the attempt's pre-spawn route was vendor_native (a metered default
187
+ * hitting a limit is a budget fact, not a subscription to fail over from).
188
+ */
189
+ export function planReactiveRotation(args) {
190
+ if (!rotationRetryEligible(args))
191
+ return null;
192
+ if (args.policy.limit_action !== "rotate")
193
+ return null;
194
+ if (args.currentProfile === null && args.defaultRouteWasVendorNative !== true)
195
+ return null;
196
+ if (args.currentProfile)
197
+ args.triedProfiles.add(args.currentProfile.profile_id);
198
+ const next = nextEligibleProfile(args.registry, args.harnessId, args.policy, args.currentProfile, args.snapshots, args.triedProfiles);
199
+ if (!next)
200
+ return null;
201
+ args.emit("route.profile.rotated", {
202
+ harness_id: args.harnessId,
203
+ attempt_id: args.attemptId,
204
+ from_profile_id: args.currentProfile?.profile_id ?? null,
205
+ to_profile_id: next.profile_id,
206
+ reason: "vendor_limit_rejected",
207
+ retry_delay_ms: args.lastLimit?.retryDelayMs ?? null,
208
+ resets_at: args.lastLimit?.resetsAt ?? null,
209
+ });
210
+ return next;
211
+ }
212
+ /**
213
+ * INV-135 at the engine boundary: a cached vendor session resumes ONLY under
214
+ * exactly the profile it was recorded with (null-default equality included) —
215
+ * regardless of what the caller's map claims. Preflight rotation changing the
216
+ * profile therefore starts fresh.
217
+ */
218
+ export function resumeSessionForProfile(cached, profile) {
219
+ if (!cached)
220
+ return null;
221
+ return (cached.profileId ?? null) === (profile?.profile_id ?? null) ? cached.sessionId : null;
222
+ }
223
+ /**
224
+ * Record a harness-emitted native session id for future thread resume; the
225
+ * observer never fails the run. profileId is the adapter's per-event stamp —
226
+ * the EFFECTIVE profile (rotation makes it differ from the requested id).
227
+ */
228
+ export function observeNativeSessionEvent(input, harnessId, ev) {
229
+ if (!input?.onSessionObserved || ev.type !== "started")
230
+ return;
231
+ const nid = ev.payload?.["native_session_id"];
232
+ if (typeof nid === "string" && nid.length > 0) {
233
+ try {
234
+ input.onSessionObserved(harnessId, nid, ev.observed_model ?? null, ev.credential_profile_id ?? null);
235
+ }
236
+ catch {
237
+ /* observer errors must never fail the run */
238
+ }
239
+ }
240
+ }
241
+ /**
242
+ * Shared reactive-failover step for BOTH lanes: given the attempt's typed
243
+ * evidence, plan a rotation and rebuild the spec on a NEW vendor session
244
+ * under the next profile — or return null when the attempt must fail as-is.
245
+ */
246
+ export function rotateSpecOnTypedLimit(args) {
247
+ const rotation = planReactiveRotation({
248
+ currentProfile: args.spec.credential_profile ?? null,
249
+ defaultRouteWasVendorNative: args.defaultRouteWasVendorNative,
250
+ harnessId: args.harnessId,
251
+ attemptId: args.attemptId,
252
+ policy: args.policy,
253
+ registry: args.registry,
254
+ snapshots: args.snapshots,
255
+ triedProfiles: args.triedProfiles,
256
+ sawTypedLimit: args.sawTypedLimit,
257
+ deliverableEmpty: args.deliverableEmpty,
258
+ lastLimit: args.lastLimit,
259
+ emit: args.emit,
260
+ });
261
+ if (!rotation)
262
+ return null;
263
+ return HarnessRunSpecSchema.parse({
264
+ ...args.spec,
265
+ session_id: args.newSessionId(),
266
+ credential_profile: rotation,
267
+ resume_session_id: null,
268
+ });
269
+ }
270
+ //# sourceMappingURL=credential-profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-profiles.js","sourceRoot":"","sources":["../src/credential-profiles.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,19 @@
1
1
  import type { AuthPreference, ProviderFamily, ReviewFinding } from "@claudexor/schema";
2
2
  import { type ReviewerSpec, type reviewCandidate } from "@claudexor/review";
3
+ export interface FrozenDiffReviewInput {
4
+ evidenceDir: string;
5
+ artifactsDir: string;
6
+ candidateSha: string;
7
+ candidateTree: string;
8
+ packetManifestSha256: string;
9
+ }
3
10
  export interface DiffReviewInput {
4
11
  repoRoot: string;
5
- diff: string;
12
+ diff?: string;
6
13
  userIntent?: string;
7
14
  tests?: string;
8
15
  decidedTradeoffs?: string;
16
+ frozen?: FrozenDiffReviewInput;
9
17
  authPreference?: AuthPreference;
10
18
  signal?: AbortSignal;
11
19
  onReviewerEvent?: (event: {
@@ -1 +1 @@
1
- {"version":3,"file":"diffReview.d.ts","sourceRoot":"","sources":["../src/diffReview.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvF,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhG,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACjG,YAAY,EAAE,CACZ,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KACtD,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IACxC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,eAAe,GAAG,OAAO,CAAC;CACjE;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuD3G"}
1
+ {"version":3,"file":"diffReview.d.ts","sourceRoot":"","sources":["../src/diffReview.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvF,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhG,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACjG,YAAY,EAAE,CACZ,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KACtD,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IACxC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,eAAe,GAAG,OAAO,CAAC;CACjE;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAwF3B"}
@@ -5,21 +5,29 @@
5
5
  * resolution, evidence packaging, revalidation, and typed results; the CLI
6
6
  * verb stays a thin surface.
7
7
  */
8
- import { join } from "node:path";
9
- import { HarnessUnavailableError } from "@claudexor/core";
8
+ import { existsSync, realpathSync } from "node:fs";
9
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
10
+ import { HarnessUnavailableError, runCapture, runCaptureRaw } from "@claudexor/core";
10
11
  import { revalidateFindings } from "@claudexor/review";
11
- import { writeEvidencePacket } from "@claudexor/context";
12
+ import { verifySealedEvidencePacket, writeEvidencePacket } from "@claudexor/context";
12
13
  import { containsSecretLikeToken, redactSecrets } from "@claudexor/util";
13
14
  export async function runDiffReview(input, deps) {
14
- if (!input.diff.trim()) {
15
+ if (input.frozen && input.diff !== undefined) {
16
+ throw new Error("reviewDiff: frozen review consumes DIFF.patch from the sealed packet");
17
+ }
18
+ if (!input.frozen && !input.diff?.trim()) {
15
19
  throw new Error("reviewDiff: the diff is empty — nothing to review");
16
20
  }
21
+ const frozen = input.frozen
22
+ ? await verifyFrozenReviewPacket(input.repoRoot, input.frozen, true)
23
+ : undefined;
24
+ const diff = frozen?.diff ?? input.diff ?? "";
17
25
  // INV-062: raw secrets must never become review artifacts. The fence lives
18
26
  // HERE so every caller (CLI verb, commit gate, future surfaces) is covered
19
27
  // before any evidence write or reviewer call — and it covers EVERY
20
28
  // artifact-bound string, not just the diff.
21
29
  for (const [label, text] of [
22
- ["diff", input.diff],
30
+ ["diff", diff],
23
31
  ["userIntent", input.userIntent],
24
32
  ["tests", input.tests],
25
33
  ["decidedTradeoffs", input.decidedTradeoffs],
@@ -33,25 +41,45 @@ export async function runDiffReview(input, deps) {
33
41
  throw new HarnessUnavailableError("no eligible reviewers (doctor-OK, review-capable) are available");
34
42
  }
35
43
  const stamp = new Date().toISOString().replace(/[:.]/g, "-");
36
- const baseDir = join(deps.execRootOf(input.repoRoot), ".claudexor", "reviews", `diff-${stamp}`);
37
- const evidenceDir = join(baseDir, "evidence");
38
- writeEvidencePacket(evidenceDir, {
39
- userIntent: redactSecrets(input.userIntent ?? "Review this staged diff for defects before commit."),
40
- diff: input.diff,
41
- tests: input.tests ?? "(no test evidence supplied)",
42
- decidedTradeoffs: input.decidedTradeoffs,
43
- });
44
+ const baseDir = input.frozen
45
+ ? undefined
46
+ : join(deps.execRootOf(input.repoRoot), ".claudexor", "reviews", `diff-${stamp}`);
47
+ const evidenceDir = frozen?.evidenceDir ?? join(baseDir, "evidence");
48
+ const artifactsDir = input.frozen?.artifactsDir ?? join(baseDir, "reviewers");
49
+ if (!input.frozen) {
50
+ writeEvidencePacket(evidenceDir, {
51
+ userIntent: redactSecrets(input.userIntent ?? "Review this staged diff for defects before commit."),
52
+ diff,
53
+ tests: input.tests ?? "(no test evidence supplied)",
54
+ decidedTradeoffs: input.decidedTradeoffs,
55
+ });
56
+ }
44
57
  const result = await deps.reviewScoped({
45
- candidateLabel: "Staged diff",
46
- diff: input.diff,
58
+ candidateLabel: input.frozen ? "Frozen candidate" : "Staged diff",
59
+ diff,
47
60
  evidenceDir,
48
- artifactsDir: join(baseDir, "reviewers"),
61
+ artifactsDir,
62
+ evidenceReadOnly: input.frozen !== undefined,
63
+ ...(frozen
64
+ ? {
65
+ frozenIdentity: {
66
+ candidateSha: input.frozen.candidateSha,
67
+ candidateTree: input.frozen.candidateTree,
68
+ packetManifestSha256: frozen.manifestSha256,
69
+ },
70
+ }
71
+ : {}),
49
72
  cwd: input.repoRoot,
50
73
  reviewers,
51
74
  envInheritance: deps.envInheritance(input.repoRoot),
52
75
  signal: input.signal,
53
- onReviewerEvent: input.onReviewerEvent ? (event) => input.onReviewerEvent?.({ ...event }) : undefined,
76
+ onReviewerEvent: input.onReviewerEvent
77
+ ? (event) => input.onReviewerEvent?.({ ...event })
78
+ : undefined,
54
79
  });
80
+ if (input.frozen) {
81
+ await verifyFrozenReviewPacket(input.repoRoot, input.frozen, false);
82
+ }
55
83
  const findings = await revalidateFindings(result.findings, {
56
84
  candidateRoot: input.repoRoot,
57
85
  evidenceDir,
@@ -63,7 +91,75 @@ export async function runDiffReview(input, deps) {
63
91
  distinctProviders: result.distinctProviders,
64
92
  routeProofs: result.routeProofs,
65
93
  reviewSpendUsd: result.reviewSpendUsd,
66
- artifactsDir: join(baseDir, "reviewers"),
94
+ artifactsDir,
95
+ };
96
+ }
97
+ async function verifyFrozenReviewPacket(repoRootInput, frozen, artifactsMustNotExist) {
98
+ const repoRoot = realpathSync(repoRootInput);
99
+ const evidenceDir = realpathSync(frozen.evidenceDir);
100
+ const artifactsDir = resolve(frozen.artifactsDir);
101
+ if (artifactsMustNotExist && existsSync(artifactsDir)) {
102
+ throw new Error("reviewDiff: reviewer artifacts directory already exists");
103
+ }
104
+ if (isWithin(repoRoot, evidenceDir)) {
105
+ throw new Error("reviewDiff: frozen evidence directory must be outside the candidate tree");
106
+ }
107
+ if (isWithin(repoRoot, artifactsDir)) {
108
+ throw new Error("reviewDiff: reviewer artifacts directory must be outside the candidate tree");
109
+ }
110
+ if (isWithin(evidenceDir, artifactsDir) || isWithin(artifactsDir, evidenceDir)) {
111
+ throw new Error("reviewDiff: sealed evidence and reviewer artifacts directories must not overlap");
112
+ }
113
+ const [actualSha, actualTree, status] = await Promise.all([
114
+ git(repoRoot, ["rev-parse", "HEAD"]),
115
+ git(repoRoot, ["rev-parse", "HEAD^{tree}"]),
116
+ git(repoRoot, ["status", "--porcelain=v1", "--untracked-files=all"]),
117
+ ]);
118
+ if (actualSha !== frozen.candidateSha) {
119
+ throw new Error(`reviewDiff: candidate SHA mismatch (expected ${frozen.candidateSha}, got ${actualSha})`);
120
+ }
121
+ if (actualTree !== frozen.candidateTree) {
122
+ throw new Error(`reviewDiff: candidate tree mismatch (expected ${frozen.candidateTree}, got ${actualTree})`);
123
+ }
124
+ if (status !== "") {
125
+ throw new Error("reviewDiff: frozen candidate worktree is dirty or stale");
126
+ }
127
+ const packet = verifySealedEvidencePacket({
128
+ evidenceDir,
129
+ candidateSha: frozen.candidateSha,
130
+ candidateTree: frozen.candidateTree,
131
+ expectedManifestSha256: frozen.packetManifestSha256,
132
+ });
133
+ const actualDiff = await gitRaw(repoRoot, [
134
+ "diff",
135
+ "--binary",
136
+ `${packet.baseSha}..${frozen.candidateSha}`,
137
+ ]);
138
+ if (packet.diff !== actualDiff) {
139
+ throw new Error("reviewDiff: sealed DIFF.patch does not match base..candidate");
140
+ }
141
+ return {
142
+ evidenceDir: packet.evidenceDir,
143
+ diff: packet.diff,
144
+ manifestSha256: packet.manifestSha256,
67
145
  };
68
146
  }
147
+ async function git(cwd, args) {
148
+ const result = await runCapture("git", args, { cwd });
149
+ if (result.code !== 0) {
150
+ throw new Error(`reviewDiff: git ${args.join(" ")} failed: ${(result.stderr || result.stdout).trim()}`);
151
+ }
152
+ return result.stdout.trim();
153
+ }
154
+ async function gitRaw(cwd, args) {
155
+ const result = await runCaptureRaw("git", args, { cwd });
156
+ if (result.code !== 0) {
157
+ throw new Error(`reviewDiff: git ${args.join(" ")} failed: ${(result.stderr || result.stdout).trim()}`);
158
+ }
159
+ return result.stdout;
160
+ }
161
+ function isWithin(root, candidate) {
162
+ const path = relative(root, candidate);
163
+ return path === "" || (path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path));
164
+ }
69
165
  //# sourceMappingURL=diffReview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diffReview.js","sourceRoot":"","sources":["../src/diffReview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diffReview.js","sourceRoot":"","sources":["../src/diffReview.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./orchestrator.js";
2
+ export * from "./requestRequirements.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./orchestrator.js";
2
+ export * from "./requestRequirements.js";
2
3
  //# 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,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC"}
@@ -9,10 +9,15 @@
9
9
  * cannot run is a config bug better caught before the run than mid-run.
10
10
  */
11
11
  import type { HarnessAdapter } from "@claudexor/core";
12
+ import { type KnownModelEntry } from "@claudexor/schema";
12
13
  export interface ModelGovernedRoute {
13
14
  adapter: HarnessAdapter;
14
15
  /** Manifest model truth source (used when the adapter has no live models()). */
15
- knownModels: readonly string[];
16
+ knownModels: readonly KnownModelEntry[];
17
+ /** Pre-spawn credential-route estimate: route-annotated manifest models are
18
+ * filtered by it, and stay EXCLUDED when it is null (fail-closed — a
19
+ * route-scoped model never passes the gate on an undecidable route). */
20
+ authRouteEstimate: "local_session" | "api_key" | null;
16
21
  settings: {
17
22
  defaultModel: string | null;
18
23
  fallbackModel: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"modelGovernance.d.ts","sourceRoot":"","sources":["../src/modelGovernance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,gFAAgF;IAChF,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAChF;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
1
+ {"version":3,"file":"modelGovernance.d.ts","sourceRoot":"","sources":["../src/modelGovernance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,gFAAgF;IAChF,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;IACxC;;4EAEwE;IACxE,iBAAiB,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IACtD,QAAQ,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAChF;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAkCf"}
@@ -1,4 +1,5 @@
1
1
  import { HarnessUnavailableError, validateModel } from "@claudexor/core";
2
+ import { knownModelIdsForRoute } from "@claudexor/schema";
2
3
  export async function assertRouteModelsAllowed(routes, models, cwd) {
3
4
  const checked = new Set();
4
5
  for (const routed of routes) {
@@ -19,12 +20,17 @@ export async function assertRouteModelsAllowed(routes, models, cwd) {
19
20
  truth = { list: inventory.map((m) => m.id), source: "api" };
20
21
  }
21
22
  else {
22
- truth = { list: routed.knownModels, source: "manifest" };
23
+ // Route-aware manifest truth (INV-104 x INV-061): route-annotated models
24
+ // count only on their routes; an undecidable route excludes them.
25
+ truth = {
26
+ list: knownModelIdsForRoute(routed.knownModels, routed.authRouteEstimate),
27
+ source: "manifest",
28
+ };
23
29
  }
24
30
  for (const { role, model } of candidates) {
25
31
  const check = validateModel(model, truth.list, truth.source);
26
32
  if (check.status !== "ok") {
27
- throw new HarnessUnavailableError(`harness '${id}' refused ${role} '${model}' (truth source: ${truth.source}): ${check.message}; ` +
33
+ throw new HarnessUnavailableError(`harness '${id}' refused ${role} '${model}' (truth source: ${truth.source}${truth.source === "manifest" ? `, route: ${routed.authRouteEstimate ?? "undecided"}` : ""}): ${check.message}; ` +
28
34
  `run \`claudexor models --harness ${id}\``);
29
35
  }
30
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"modelGovernance.js","sourceRoot":"","sources":["../src/modelGovernance.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AASzE,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAqC,EACrC,MAA0C,EAC1C,GAAW;IAEX,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,YAAY,IAAI,IAAI,CAAC;QACvE,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;YAClC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,aAAa,IAAI,IAAI,EAAE;SAC1E,CAAC,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACtC,IAAI,KAA8D,CAAC;QACnE,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAChD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAC3D,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,uBAAuB,CAC/B,YAAY,EAAE,aAAa,IAAI,KAAK,KAAK,oBAAoB,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,OAAO,IAAI;oBAC9F,oCAAoC,EAAE,IAAI,CAC7C,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"modelGovernance.js","sourceRoot":"","sources":["../src/modelGovernance.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAwB,MAAM,mBAAmB,CAAC;AAahF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAqC,EACrC,MAA0C,EAC1C,GAAW;IAEX,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,YAAY,IAAI,IAAI,CAAC;QACvE,MAAM,UAAU,GAAG;YACjB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;YAClC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,aAAa,IAAI,IAAI,EAAE;SAC1E,CAAC,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACtC,IAAI,KAA8D,CAAC;QACnE,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAChD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,yEAAyE;YACzE,kEAAkE;YAClE,KAAK,GAAG;gBACN,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,iBAAiB,CAAC;gBACzE,MAAM,EAAE,UAAU;aACnB,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,uBAAuB,CAC/B,YAAY,EAAE,aAAa,IAAI,KAAK,KAAK,oBAAoB,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,iBAAiB,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,OAAO,IAAI;oBACzL,oCAAoC,EAAE,IAAI,CAC7C,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { ArtifactStore } from "@claudexor/artifact-store";
2
+ import type { EventLog } from "@claudexor/event-log";
3
+ import type { BudgetLedger } from "@claudexor/budget";
4
+ import { type DeliveryReceipt, type OrchestrateAutonomy, type OrchestratePlan, type OrchestratePlanCall, type OrchestrateStepStatus, type RunStatus } from "@claudexor/schema";
5
+ export interface OrchestrateSafeStepResult {
6
+ status: OrchestrateStepStatus;
7
+ terminalStatus: RunStatus | null;
8
+ terminalSource: "subrun" | "review" | "executor";
9
+ evidenceRefs: string[];
10
+ runId: string | null;
11
+ detail: string | null;
12
+ spendUsd?: number | null;
13
+ }
14
+ export interface OrchestrateApplyStepResult {
15
+ ok: boolean;
16
+ runId: string;
17
+ detail: string;
18
+ receipt: DeliveryReceipt | null;
19
+ }
20
+ interface ExecuteOrchestratePlanInput {
21
+ plan: OrchestratePlan;
22
+ autonomy: OrchestrateAutonomy;
23
+ maxToolCalls: number | null;
24
+ ledger: BudgetLedger;
25
+ signal?: AbortSignal;
26
+ store: ArtifactStore;
27
+ paths: ReturnType<ArtifactStore["runPaths"]>;
28
+ log: EventLog;
29
+ executeSafeStep(call: OrchestratePlanCall): Promise<OrchestrateSafeStepResult>;
30
+ executeApplyStep(call: Extract<OrchestratePlanCall, {
31
+ tool: "apply";
32
+ }>): Promise<OrchestrateApplyStepResult>;
33
+ }
34
+ export interface OrchestrateExecutionResult {
35
+ terminal: RunStatus;
36
+ note: string;
37
+ readOnly: boolean;
38
+ receiptRefs: string[];
39
+ }
40
+ /** Ordered executor; terminal truth is delegated to the exhaustive outcome reducer. */
41
+ export declare function executeOrchestratePlan(input: ExecuteOrchestratePlanInput): Promise<OrchestrateExecutionResult>;
42
+ export {};
43
+ //# sourceMappingURL=orchestrateExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrateExecutor.d.ts","sourceRoot":"","sources":["../src/orchestrateExecutor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAExB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAO3B,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,cAAc,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACjD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;CACjC;AAED,UAAU,2BAA2B;IACnC,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7C,GAAG,EAAE,QAAQ,CAAC;IACd,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC/E,gBAAgB,CACd,IAAI,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,GACpD,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,uFAAuF;AACvF,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,0BAA0B,CAAC,CAuMrC"}