@claudexor/orchestrator 1.0.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/attemptTelemetry.d.ts +82 -0
  4. package/dist/attemptTelemetry.d.ts.map +1 -0
  5. package/dist/attemptTelemetry.js +283 -0
  6. package/dist/attemptTelemetry.js.map +1 -0
  7. package/dist/diffReview.d.ts +32 -0
  8. package/dist/diffReview.d.ts.map +1 -0
  9. package/dist/diffReview.js +69 -0
  10. package/dist/diffReview.js.map +1 -0
  11. package/dist/finalVerifier.d.ts +25 -0
  12. package/dist/finalVerifier.d.ts.map +1 -0
  13. package/dist/finalVerifier.js +110 -0
  14. package/dist/finalVerifier.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/interaction.d.ts +22 -0
  20. package/dist/interaction.d.ts.map +1 -0
  21. package/dist/interaction.js +117 -0
  22. package/dist/interaction.js.map +1 -0
  23. package/dist/modelGovernance.d.ts +22 -0
  24. package/dist/modelGovernance.d.ts.map +1 -0
  25. package/dist/modelGovernance.js +33 -0
  26. package/dist/modelGovernance.js.map +1 -0
  27. package/dist/orchestratePlanner.d.ts +12 -0
  28. package/dist/orchestratePlanner.d.ts.map +1 -0
  29. package/dist/orchestratePlanner.js +91 -0
  30. package/dist/orchestratePlanner.js.map +1 -0
  31. package/dist/orchestrator.d.ts +380 -0
  32. package/dist/orchestrator.d.ts.map +1 -0
  33. package/dist/orchestrator.js +4927 -0
  34. package/dist/orchestrator.js.map +1 -0
  35. package/dist/reviewerPanel.d.ts +26 -0
  36. package/dist/reviewerPanel.d.ts.map +1 -0
  37. package/dist/reviewerPanel.js +146 -0
  38. package/dist/reviewerPanel.js.map +1 -0
  39. package/dist/runSupport.d.ts +178 -0
  40. package/dist/runSupport.d.ts.map +1 -0
  41. package/dist/runSupport.js +372 -0
  42. package/dist/runSupport.js.map +1 -0
  43. package/dist/runTerminals.d.ts +56 -0
  44. package/dist/runTerminals.d.ts.map +1 -0
  45. package/dist/runTerminals.js +124 -0
  46. package/dist/runTerminals.js.map +1 -0
  47. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 joi-lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @claudexor/orchestrator
2
+
3
+ Internal package of [Claudexor](https://github.com/razzant/claudexor) — Hub that composes all subsystems and implements the five canonical modes (ask, plan, audit, agent, orchestrate) with their strategy flags (best-of-N race, attempt caps, until-clean, swarm, create).
4
+
5
+ Published as part of the Claudexor toolchain; it follows the monorepo's
6
+ lockstep version and has no separate semver contract. Use the `claudexor`
7
+ CLI (or `@claudexor/cli`) as the supported entry point.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Attempt-level telemetry: the single owner of tool-error records, web
3
+ * evidence state, transient-failure observations, and the attempt outcome
4
+ * truth. Adapters emit typed events; the orchestrator observes them here —
5
+ * no regex over prose, and a tool error is "recovered" only when the SAME
6
+ * tool later succeeds against the SAME target.
7
+ */
8
+ import type { AttemptTelemetryRecord, ExternalContextPolicy, HarnessEvent, TaskContract, ToolKind } from "@claudexor/schema";
9
+ export interface ToolErrorRecord {
10
+ tool: string;
11
+ kind: ToolKind;
12
+ target: string | null;
13
+ summary: string;
14
+ toolUseId: string | null;
15
+ /** True when a later successful result of the SAME tool against the SAME target exists in this attempt (INV-043). */
16
+ recovered: boolean;
17
+ }
18
+ export type AttemptOutcomeStatus = "success" | "success_with_warnings" | "blocked" | "failed";
19
+ export interface AttemptOutcomeState {
20
+ deliverablePresent: boolean;
21
+ gatesPassed: boolean | null;
22
+ harnessErrored: boolean;
23
+ webRequiredUnsatisfied: boolean;
24
+ toolWarningsCount: number;
25
+ status: AttemptOutcomeStatus;
26
+ }
27
+ export interface WebEvidenceState {
28
+ required: boolean;
29
+ mode: ExternalContextPolicy;
30
+ effectiveMode: ExternalContextPolicy;
31
+ attempted: boolean;
32
+ satisfied: boolean;
33
+ failed: boolean;
34
+ tool: string | null;
35
+ target: string | null;
36
+ errorSummary: string | null;
37
+ }
38
+ export interface AttemptTelemetry {
39
+ toolErrors: ToolErrorRecord[];
40
+ /** tool_result events without a status field: never silently treated as ok. */
41
+ statuslessResults: number;
42
+ /** Native lines/events the adapter reported as dropped/unrecognized. */
43
+ droppedEvents: number;
44
+ web: WebEvidenceState;
45
+ /** Model identity the harness stream actually reported (route evidence). */
46
+ observedModel: string | null;
47
+ /** Adapter-declared transient failures seen during this attempt. */
48
+ transientFailures: {
49
+ kind: NonNullable<HarnessEvent["transient"]>["kind"];
50
+ retryDelayMs: number | null;
51
+ }[];
52
+ /** Contract/outcome truth for this attempt, produced by the orchestrator. */
53
+ outcome: AttemptOutcomeState | null;
54
+ }
55
+ export declare function createAttemptTelemetry(policy: ExternalContextPolicy, webRequired: boolean, effectiveMode?: ExternalContextPolicy): AttemptTelemetry;
56
+ /**
57
+ * Observe a normalized harness event into the attempt telemetry. Governance is
58
+ * fully typed: only the `tool` ToolRef on tool_call/tool_result/file_change
59
+ * events and the run-loop drop counters are consulted — never payload string
60
+ * matching or tool-name heuristics.
61
+ */
62
+ export declare function observeAttemptTelemetry(t: AttemptTelemetry, ev: HarnessEvent): void;
63
+ export declare function unrecoveredToolErrors(t: AttemptTelemetry): ToolErrorRecord[];
64
+ export declare function toolWarnings(t: AttemptTelemetry): ToolErrorRecord[];
65
+ export declare function setAttemptOutcome(t: AttemptTelemetry, opts: {
66
+ deliverablePresent: boolean;
67
+ gatesPassed: boolean | null;
68
+ harnessErrored: boolean;
69
+ webRequiredUnsatisfied: boolean;
70
+ }): void;
71
+ /** Bounded telemetry summary for events/artifacts (full detail lives in telemetry.yaml). */
72
+ export declare function telemetrySummary(t: AttemptTelemetry): Record<string, unknown>;
73
+ export declare function attemptTelemetryRecord(attemptId: string, harnessId: string, t: AttemptTelemetry): AttemptTelemetryRecord;
74
+ export declare function aggregateRunWebEvidence(records: AttemptTelemetryRecord[], contract: TaskContract): AttemptTelemetryRecord["web"];
75
+ /**
76
+ * Web evidence gating (locked v0.7 semantics):
77
+ * - web_required && !satisfied -> blocked, INCLUDING the never-attempted case;
78
+ * - attempted && failed && !satisfied -> blocked (a later successful web call
79
+ * is the verified recovery that clears it).
80
+ */
81
+ export declare function webUnsatisfied(t: AttemptTelemetry): boolean;
82
+ //# sourceMappingURL=attemptTelemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attemptTelemetry.d.ts","sourceRoot":"","sources":["../src/attemptTelemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,283 @@
1
+ import { redactSecrets } from "@claudexor/util";
2
+ export function createAttemptTelemetry(policy, webRequired, effectiveMode = policy) {
3
+ return {
4
+ toolErrors: [],
5
+ statuslessResults: 0,
6
+ droppedEvents: 0,
7
+ web: {
8
+ required: webRequired,
9
+ mode: policy,
10
+ effectiveMode,
11
+ attempted: false,
12
+ satisfied: false,
13
+ failed: false,
14
+ tool: null,
15
+ target: null,
16
+ errorSummary: null,
17
+ },
18
+ observedModel: null,
19
+ transientFailures: [],
20
+ outcome: null,
21
+ };
22
+ }
23
+ /**
24
+ * Observe a normalized harness event into the attempt telemetry. Governance is
25
+ * fully typed: only the `tool` ToolRef on tool_call/tool_result/file_change
26
+ * events and the run-loop drop counters are consulted — never payload string
27
+ * matching or tool-name heuristics.
28
+ */
29
+ export function observeAttemptTelemetry(t, ev) {
30
+ // Route evidence: remember the model identity the stream itself disclosed.
31
+ if (ev.observed_model && !t.observedModel)
32
+ t.observedModel = ev.observed_model;
33
+ if (ev.transient) {
34
+ t.transientFailures.push({
35
+ kind: ev.transient.kind,
36
+ retryDelayMs: ev.transient.retry_delay_ms ?? null,
37
+ });
38
+ }
39
+ if (ev.type === "completed") {
40
+ const dropped = Number(ev.payload?.["dropped_unparsed_lines"] ?? 0) +
41
+ Number(ev.payload?.["dropped_unrecognized_events"] ?? 0);
42
+ if (Number.isFinite(dropped) && dropped > 0)
43
+ t.droppedEvents += dropped;
44
+ return;
45
+ }
46
+ const tool = ev.tool;
47
+ if (!tool)
48
+ return;
49
+ if (ev.type === "tool_call" || ev.type === "file_change") {
50
+ if (tool.kind === "web") {
51
+ t.web.attempted = true;
52
+ t.web.tool = tool.name;
53
+ t.web.target = tool.target ?? t.web.target;
54
+ }
55
+ return;
56
+ }
57
+ if (ev.type !== "tool_result")
58
+ return;
59
+ if (tool.status === undefined) {
60
+ // A result without a status must never silently count as ok.
61
+ t.statuslessResults += 1;
62
+ return;
63
+ }
64
+ if (tool.status === "cancelled" || tool.status === "denied") {
65
+ if (tool.kind === "web") {
66
+ t.web.attempted = true;
67
+ t.web.tool = tool.name;
68
+ t.web.target = tool.target ?? t.web.target;
69
+ }
70
+ return;
71
+ }
72
+ if (tool.status === "error") {
73
+ t.toolErrors.push({
74
+ tool: tool.name,
75
+ kind: tool.kind,
76
+ target: tool.target ?? null,
77
+ summary: redactSecrets(tool.error_summary ?? tool.content_summary ?? "tool result marked error").slice(0, 1000),
78
+ toolUseId: tool.use_id ?? null,
79
+ recovered: false,
80
+ });
81
+ if (tool.kind === "web") {
82
+ t.web.failed = true;
83
+ t.web.attempted = true;
84
+ t.web.tool = tool.name;
85
+ t.web.target = tool.target ?? t.web.target;
86
+ t.web.errorSummary = redactSecrets(tool.error_summary ?? "web tool result marked error").slice(0, 1000);
87
+ }
88
+ return;
89
+ }
90
+ // status === "ok": a later success of the SAME tool against the SAME target
91
+ // is the verified recovery for that call's earlier errors within this
92
+ // attempt (keying fix: `bash echo done` must NOT launder an earlier
93
+ // `bash npm test` failure — the name alone proved nothing).
94
+ for (const err of t.toolErrors) {
95
+ // INV-043: recovery must be attributable to the failed operation — same
96
+ // tool, same KIND, same target (a non-web tool sharing a name with a web
97
+ // tool must not clear its web error).
98
+ if (!err.recovered && err.tool === tool.name && err.kind === tool.kind && err.target === (tool.target ?? null)) {
99
+ err.recovered = true;
100
+ }
101
+ }
102
+ if (tool.kind === "web") {
103
+ t.web.attempted = true;
104
+ // DECIDED SEMANTICS (round-19/20 reviews): the web-evidence gate asks
105
+ // "was web evidence OBTAINED", so ANY successful web call satisfies it —
106
+ // reformulating a failed query and succeeding on the new one is
107
+ // legitimate alternative-route recovery, not laundering (blocking it
108
+ // would false-block the most common web workflow). What must NOT vanish
109
+ // is the DISCLOSURE: `failed` clears only when the success matches the
110
+ // failed call's target (INV-043 keying), so telemetry.yaml keeps the
111
+ // unrecovered failure + errorSummary visible even on satisfied runs.
112
+ t.web.satisfied = true;
113
+ // Derived rollup, single source of truth: the tool+target-keyed
114
+ // toolErrors store (the recovery loop above already marked matching
115
+ // errors recovered). Multiple failed targets stay disclosed until EACH
116
+ // recovers; a missing target never wildcards (exact null==null match).
117
+ t.web.failed = t.toolErrors.some((e) => e.kind === "web" && !e.recovered);
118
+ // Keep the summary in lockstep with the rollup: point at a live
119
+ // unrecovered failure, or clear once everything recovered.
120
+ t.web.errorSummary = t.web.failed
121
+ ? (t.toolErrors.find((e) => e.kind === "web" && !e.recovered)?.summary ?? t.web.errorSummary)
122
+ : null;
123
+ t.web.tool = tool.name;
124
+ t.web.target = tool.target ?? t.web.target;
125
+ }
126
+ }
127
+ const TELEMETRY_TOOL_ERRORS_MAX = 20;
128
+ export function unrecoveredToolErrors(t) {
129
+ return t.toolErrors.filter((e) => !e.recovered);
130
+ }
131
+ export function toolWarnings(t) {
132
+ // Non-web tool errors are warnings once the attempt produced its contracted
133
+ // deliverable. Unrecovered WEB errors count as warnings too WHEN the
134
+ // evidence gate is satisfied by an alternative route (INV-043: the failure
135
+ // stays attributable and disclosed; a green claim becomes
136
+ // success_with_warnings, never a silent clean success). Unsatisfied web
137
+ // errors flow through the hard gate (webUnsatisfied) instead.
138
+ return unrecoveredToolErrors(t).filter((e) => e.kind !== "web" || t.web.satisfied);
139
+ }
140
+ export function setAttemptOutcome(t, opts) {
141
+ const warnings = toolWarnings(t).length;
142
+ const contractFailed = !opts.deliverablePresent || opts.gatesPassed === false;
143
+ const status = opts.webRequiredUnsatisfied
144
+ ? "blocked"
145
+ : opts.harnessErrored || contractFailed
146
+ ? "failed"
147
+ : warnings > 0
148
+ ? "success_with_warnings"
149
+ : "success";
150
+ t.outcome = {
151
+ deliverablePresent: opts.deliverablePresent,
152
+ gatesPassed: opts.gatesPassed,
153
+ harnessErrored: opts.harnessErrored,
154
+ webRequiredUnsatisfied: opts.webRequiredUnsatisfied,
155
+ toolWarningsCount: warnings,
156
+ status,
157
+ };
158
+ }
159
+ function webStatus(t) {
160
+ if (t.web.satisfied)
161
+ return "satisfied";
162
+ if (t.web.failed)
163
+ return "failed";
164
+ if (t.web.attempted)
165
+ return "attempted";
166
+ return t.web.required ? "unverified" : "none";
167
+ }
168
+ /** Bounded telemetry summary for events/artifacts (full detail lives in telemetry.yaml). */
169
+ export function telemetrySummary(t) {
170
+ const unrecovered = unrecoveredToolErrors(t);
171
+ const warnings = toolWarnings(t);
172
+ return {
173
+ web_evidence: {
174
+ required: t.web.required,
175
+ mode: t.web.mode,
176
+ effective_mode: t.web.effectiveMode,
177
+ attempted: t.web.attempted,
178
+ satisfied: t.web.satisfied,
179
+ status: webStatus(t),
180
+ tool: t.web.tool,
181
+ target: t.web.target,
182
+ error_summary: t.web.errorSummary,
183
+ },
184
+ tool_errors_total: t.toolErrors.length,
185
+ unrecovered_tool_errors: unrecovered.length,
186
+ tool_errors: unrecovered
187
+ .slice(-5)
188
+ .map((e) => ({ tool: e.tool, kind: e.kind, target: e.target, summary: e.summary })),
189
+ tool_warnings_count: warnings.length,
190
+ ...(warnings.length
191
+ ? {
192
+ tool_warnings: warnings
193
+ .slice(-5)
194
+ .map((e) => ({ tool: e.tool, kind: e.kind, target: e.target, summary: e.summary })),
195
+ }
196
+ : {}),
197
+ ...(t.outcome ? { outcome: t.outcome } : {}),
198
+ ...(t.transientFailures.length > 0
199
+ ? {
200
+ transient_failures: t.transientFailures
201
+ .slice(-5)
202
+ .map((e) => ({ kind: e.kind, retry_delay_ms: e.retryDelayMs })),
203
+ }
204
+ : {}),
205
+ ...(t.droppedEvents > 0 ? { dropped_events: t.droppedEvents } : {}),
206
+ ...(t.statuslessResults > 0 ? { statusless_tool_results: t.statuslessResults } : {}),
207
+ };
208
+ }
209
+ export function attemptTelemetryRecord(attemptId, harnessId, t) {
210
+ const errors = t.toolErrors.slice(-TELEMETRY_TOOL_ERRORS_MAX);
211
+ const warnings = toolWarnings(t);
212
+ return {
213
+ attempt_id: attemptId,
214
+ harness_id: harnessId,
215
+ observed_model: t.observedModel,
216
+ web: {
217
+ required: t.web.required,
218
+ policy: t.web.mode,
219
+ effective_mode: t.web.effectiveMode,
220
+ attempted: t.web.attempted,
221
+ satisfied: t.web.satisfied,
222
+ status: webStatus(t),
223
+ tool: t.web.tool,
224
+ target: t.web.target,
225
+ error_summary: t.web.errorSummary,
226
+ },
227
+ tool_errors: errors.map((e) => ({
228
+ tool: e.tool,
229
+ kind: e.kind,
230
+ target: e.target,
231
+ summary: e.summary,
232
+ recovered: e.recovered,
233
+ tool_use_id: e.toolUseId,
234
+ })),
235
+ tool_errors_total: t.toolErrors.length,
236
+ unrecovered_tool_errors: unrecoveredToolErrors(t).length,
237
+ statusless_tool_results: t.statuslessResults,
238
+ dropped_events: t.droppedEvents,
239
+ transient_failures: t.transientFailures
240
+ .slice(-TELEMETRY_TOOL_ERRORS_MAX)
241
+ .map((e) => ({ kind: e.kind, retry_delay_ms: e.retryDelayMs })),
242
+ outcome: {
243
+ deliverable_present: t.outcome?.deliverablePresent ?? false,
244
+ gates_passed: t.outcome?.gatesPassed ?? null,
245
+ harness_errored: t.outcome?.harnessErrored ?? false,
246
+ web_required_unsatisfied: t.outcome?.webRequiredUnsatisfied ?? false,
247
+ tool_warnings_count: t.outcome?.toolWarningsCount ?? warnings.length,
248
+ status: t.outcome?.status ?? (warnings.length > 0 ? "success_with_warnings" : "success"),
249
+ },
250
+ };
251
+ }
252
+ export function aggregateRunWebEvidence(records, contract) {
253
+ const satisfied = records.find((r) => r.web.satisfied);
254
+ if (satisfied)
255
+ return satisfied.web;
256
+ const severityRank = { none: 0, attempted: 1, unverified: 2, failed: 3, satisfied: 4 };
257
+ const worst = [...records].sort((a, b) => (severityRank[b.web.status] ?? 0) - (severityRank[a.web.status] ?? 0))[0];
258
+ return (worst?.web ?? {
259
+ required: contract.external_context.web_required,
260
+ policy: contract.external_context.policy,
261
+ effective_mode: contract.external_context.effective_mode,
262
+ attempted: false,
263
+ satisfied: false,
264
+ status: contract.external_context.web_required ? "unverified" : "none",
265
+ tool: null,
266
+ target: null,
267
+ error_summary: null,
268
+ });
269
+ }
270
+ /**
271
+ * Web evidence gating (locked v0.7 semantics):
272
+ * - web_required && !satisfied -> blocked, INCLUDING the never-attempted case;
273
+ * - attempted && failed && !satisfied -> blocked (a later successful web call
274
+ * is the verified recovery that clears it).
275
+ */
276
+ export function webUnsatisfied(t) {
277
+ if (t.web.satisfied)
278
+ return false;
279
+ if (t.web.required)
280
+ return true;
281
+ return t.web.attempted && t.web.failed;
282
+ }
283
+ //# sourceMappingURL=attemptTelemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attemptTelemetry.js","sourceRoot":"","sources":["../src/attemptTelemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { AuthPreference, ProviderFamily, ReviewFinding } from "@claudexor/schema";
2
+ import { type ReviewerSpec, type reviewCandidate } from "@claudexor/review";
3
+ export interface DiffReviewInput {
4
+ repoRoot: string;
5
+ diff: string;
6
+ userIntent?: string;
7
+ tests?: string;
8
+ decidedTradeoffs?: string;
9
+ authPreference?: AuthPreference;
10
+ signal?: AbortSignal;
11
+ onReviewerEvent?: (event: {
12
+ type: string;
13
+ [k: string]: unknown;
14
+ }) => void;
15
+ }
16
+ export interface DiffReviewResult {
17
+ findings: ReviewFinding[];
18
+ crossFamilyHealthy: boolean;
19
+ crossFamilyVerified: boolean;
20
+ distinctProviders: ProviderFamily[];
21
+ routeProofs: unknown[];
22
+ reviewSpendUsd: number;
23
+ artifactsDir: string;
24
+ }
25
+ export interface DiffReviewDeps {
26
+ resolveReviewers: (repoRoot: string, authPreference?: AuthPreference) => Promise<ReviewerSpec[]>;
27
+ reviewScoped: (input: Omit<Parameters<typeof reviewCandidate>[0], "env">) => ReturnType<typeof reviewCandidate>;
28
+ execRootOf: (repoRoot: string) => string;
29
+ envInheritance: (repoRoot: string) => "mirror_native" | "clean";
30
+ }
31
+ export declare function runDiffReview(input: DiffReviewInput, deps: DiffReviewDeps): Promise<DiffReviewResult>;
32
+ //# sourceMappingURL=diffReview.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Scoped DIFF review: review a caller-supplied diff (e.g. a staged
3
+ * commit) with the resolved reviewer panel — the same reviewCandidate
4
+ * machinery race candidates use, no run/envelope. The engine owns reviewer
5
+ * resolution, evidence packaging, revalidation, and typed results; the CLI
6
+ * verb stays a thin surface.
7
+ */
8
+ import { join } from "node:path";
9
+ import { HarnessUnavailableError } from "@claudexor/core";
10
+ import { revalidateFindings } from "@claudexor/review";
11
+ import { writeEvidencePacket } from "@claudexor/context";
12
+ import { containsSecretLikeToken, redactSecrets } from "@claudexor/util";
13
+ export async function runDiffReview(input, deps) {
14
+ if (!input.diff.trim()) {
15
+ throw new Error("reviewDiff: the diff is empty — nothing to review");
16
+ }
17
+ // INV-062: raw secrets must never become review artifacts. The fence lives
18
+ // HERE so every caller (CLI verb, commit gate, future surfaces) is covered
19
+ // before any evidence write or reviewer call — and it covers EVERY
20
+ // artifact-bound string, not just the diff.
21
+ for (const [label, text] of [
22
+ ["diff", input.diff],
23
+ ["userIntent", input.userIntent],
24
+ ["tests", input.tests],
25
+ ["decidedTradeoffs", input.decidedTradeoffs],
26
+ ]) {
27
+ if (typeof text === "string" && containsSecretLikeToken(text)) {
28
+ throw new Error(`reviewDiff: ${label} contains a secret-like token; refusing review (remove the secret first)`);
29
+ }
30
+ }
31
+ const reviewers = await deps.resolveReviewers(input.repoRoot, input.authPreference);
32
+ if (reviewers.length === 0) {
33
+ throw new HarnessUnavailableError("no eligible reviewers (doctor-OK, review-capable) are available");
34
+ }
35
+ 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 result = await deps.reviewScoped({
45
+ candidateLabel: "Staged diff",
46
+ diff: input.diff,
47
+ evidenceDir,
48
+ artifactsDir: join(baseDir, "reviewers"),
49
+ cwd: input.repoRoot,
50
+ reviewers,
51
+ envInheritance: deps.envInheritance(input.repoRoot),
52
+ signal: input.signal,
53
+ onReviewerEvent: input.onReviewerEvent ? (event) => input.onReviewerEvent?.({ ...event }) : undefined,
54
+ });
55
+ const findings = await revalidateFindings(result.findings, {
56
+ candidateRoot: input.repoRoot,
57
+ evidenceDir,
58
+ });
59
+ return {
60
+ findings,
61
+ crossFamilyHealthy: result.crossFamilyHealthy,
62
+ crossFamilyVerified: result.crossFamilyVerified,
63
+ distinctProviders: result.distinctProviders,
64
+ routeProofs: result.routeProofs,
65
+ reviewSpendUsd: result.reviewSpendUsd,
66
+ artifactsDir: join(baseDir, "reviewers"),
67
+ };
68
+ }
69
+ //# sourceMappingURL=diffReview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diffReview.js","sourceRoot":"","sources":["../src/diffReview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { FinalVerifyRecord } from "@claudexor/schema";
2
+ import { type GateSpec } from "@claudexor/review";
3
+ interface VerifiableWinner {
4
+ baseSha?: string;
5
+ diff: string;
6
+ }
7
+ interface VerifyEventLog {
8
+ emit(type: "gate.completed", payload: Record<string, unknown>): unknown;
9
+ }
10
+ /** FAIL-CLOSED verdict (INV-115): an attempted verify that did not PROVE
11
+ * applied_cleanly (false OR null/errored) or whose gates failed blocks the
12
+ * run. One owner — race and convergence consume the same rule. */
13
+ export declare function finalVerifyBlocks(finalVerify: FinalVerifyRecord | null): boolean;
14
+ /** The persisted decision must AGREE with a blocked terminal: status/outcome
15
+ * blocked, human_review recommendation, and an evidence fact naming the cause.
16
+ * One owner for the race and convergence decision writes. */
17
+ export declare function blockedDecisionOverride(evidenceFacts: string[], finalVerify: FinalVerifyRecord | null): {
18
+ status: "blocked";
19
+ outcome: "blocked";
20
+ apply_recommendation: "human_review";
21
+ evidence_facts: string[];
22
+ };
23
+ export declare function finalVerifyPatch(execRoot: string, winner: VerifiableWinner, specs: GateSpec[], log: VerifyEventLog): Promise<FinalVerifyRecord>;
24
+ export {};
25
+ //# sourceMappingURL=finalVerifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalVerifier.d.ts","sourceRoot":"","sources":["../src/finalVerifier.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,mBAAmB,CAAC;AAIzE,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CACzE;AAED;;kEAEkE;AAClE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAMhF;AAED;;6DAE6D;AAC7D,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EAAE,EACvB,WAAW,EAAE,iBAAiB,GAAG,IAAI,GACpC;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,SAAS,CAAC;IACnB,oBAAoB,EAAE,cAAc,CAAC;IACrC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAYA;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,QAAQ,EAAE,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAgE5B"}