@claudexor/review 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/convergence.d.ts +22 -0
- package/dist/convergence.d.ts.map +1 -0
- package/dist/convergence.js +35 -0
- package/dist/convergence.js.map +1 -0
- package/dist/findings.d.ts +22 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +239 -0
- package/dist/findings.js.map +1 -0
- package/dist/gates.d.ts +19 -0
- package/dist/gates.d.ts.map +1 -0
- package/dist/gates.js +72 -0
- package/dist/gates.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/readiness.d.ts +20 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +28 -0
- package/dist/readiness.js.map +1 -0
- package/dist/revalidate.d.ts +22 -0
- package/dist/revalidate.d.ts.map +1 -0
- package/dist/revalidate.js +95 -0
- package/dist/revalidate.js.map +1 -0
- package/dist/reviewEngine.d.ts +85 -0
- package/dist/reviewEngine.d.ts.map +1 -0
- package/dist/reviewEngine.js +1097 -0
- package/dist/reviewEngine.js.map +1 -0
- package/dist/route.d.ts +25 -0
- package/dist/route.d.ts.map +1 -0
- package/dist/route.js +54 -0
- package/dist/route.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
2
|
+
function hasEvidence(f) {
|
|
3
|
+
return (f.evidence.files.length > 0 ||
|
|
4
|
+
f.evidence.diff_hunks.length > 0 ||
|
|
5
|
+
f.evidence.commands.length > 0 ||
|
|
6
|
+
f.evidence.logs.length > 0);
|
|
7
|
+
}
|
|
8
|
+
function isSameOrInside(parent, target) {
|
|
9
|
+
const rel = relative(resolve(parent), resolve(target));
|
|
10
|
+
const firstPart = rel.split(/[\\/]+/)[0];
|
|
11
|
+
return rel === "" || (!!rel && firstPart !== ".." && !isAbsolute(rel));
|
|
12
|
+
}
|
|
13
|
+
function hasTraversalSegment(pathValue) {
|
|
14
|
+
return pathValue.split(/[\\/]+/).some((part) => part === "..");
|
|
15
|
+
}
|
|
16
|
+
function isSafeRelativeEvidencePath(pathValue, options) {
|
|
17
|
+
if (!pathValue || hasTraversalSegment(pathValue))
|
|
18
|
+
return false;
|
|
19
|
+
if (isAbsolute(pathValue))
|
|
20
|
+
return false;
|
|
21
|
+
const roots = [options.candidateRoot, options.evidenceDir].filter((value) => typeof value === "string" && value.length > 0);
|
|
22
|
+
if (roots.length === 0)
|
|
23
|
+
return true;
|
|
24
|
+
return roots.some((root) => isSameOrInside(root, resolve(root, pathValue)));
|
|
25
|
+
}
|
|
26
|
+
function validateEvidence(evidence, options) {
|
|
27
|
+
let invalidPathCount = 0;
|
|
28
|
+
const files = evidence.files.filter((file) => {
|
|
29
|
+
const ok = isSafeRelativeEvidencePath(file.path, options);
|
|
30
|
+
if (!ok)
|
|
31
|
+
invalidPathCount++;
|
|
32
|
+
return ok;
|
|
33
|
+
});
|
|
34
|
+
const logs = evidence.logs.filter((log) => {
|
|
35
|
+
const ok = isSafeRelativeEvidencePath(log.path, options);
|
|
36
|
+
if (!ok)
|
|
37
|
+
invalidPathCount++;
|
|
38
|
+
return ok;
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
evidence: {
|
|
42
|
+
files,
|
|
43
|
+
logs,
|
|
44
|
+
diff_hunks: evidence.diff_hunks,
|
|
45
|
+
commands: evidence.commands,
|
|
46
|
+
},
|
|
47
|
+
invalidPathCount,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Deterministic revalidation (no LLM): enforces the evidence invariants that
|
|
52
|
+
* always hold — no evidence -> cannot block; out-of-scope/insufficient pass
|
|
53
|
+
* through; a NEEDS_HUMAN escalation stays a blocking human gate.
|
|
54
|
+
*/
|
|
55
|
+
export function deterministicDecision(f, options = {}) {
|
|
56
|
+
if (["fixed", "rebutted", "accepted_risk", "duplicate"].includes(f.status)) {
|
|
57
|
+
return { status: f.status };
|
|
58
|
+
}
|
|
59
|
+
if (f.severity === "OUT_OF_SCOPE")
|
|
60
|
+
return { status: "out_of_scope" };
|
|
61
|
+
if (f.severity === "INSUFFICIENT_EVIDENCE")
|
|
62
|
+
return { status: "insufficient_evidence" };
|
|
63
|
+
// A reviewer escalation to a human BLOCKS until a human decides — it must
|
|
64
|
+
// never silently downgrade to a non-blocking accepted risk.
|
|
65
|
+
if (f.severity === "NEEDS_HUMAN")
|
|
66
|
+
return { status: "accepted", note: "human decision required" };
|
|
67
|
+
if (f.severity === "BLOCK" || f.severity === "FIX_FIRST") {
|
|
68
|
+
const validated = validateEvidence(f.evidence, options);
|
|
69
|
+
const candidate = { ...f, evidence: validated.evidence };
|
|
70
|
+
if (!hasEvidence(candidate)) {
|
|
71
|
+
return {
|
|
72
|
+
status: "insufficient_evidence",
|
|
73
|
+
note: validated.invalidPathCount > 0
|
|
74
|
+
? "invalid evidence paths -> cannot block"
|
|
75
|
+
: "no evidence -> cannot block",
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { status: "accepted" };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Revalidate every finding deterministically. Each finding's status is recorded;
|
|
83
|
+
* the evidence-free BLOCK/FIX_FIRST invariant is applied so a reviewer cannot
|
|
84
|
+
* leave an evidence-free finding in a blocking state.
|
|
85
|
+
*/
|
|
86
|
+
export async function revalidateFindings(findings, options = {}) {
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const f of findings) {
|
|
89
|
+
const validated = validateEvidence(f.evidence, options);
|
|
90
|
+
const d = deterministicDecision(f, options);
|
|
91
|
+
out.push({ ...f, evidence: validated.evidence, status: d.status, revalidation_note: d.note });
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=revalidate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revalidate.js","sourceRoot":"","sources":["../src/revalidate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type HarnessAdapter } from "@claudexor/core";
|
|
2
|
+
import type { AuthPreference, EffortHint, ProviderFamily, ReviewFinding, RouteProof } from "@claudexor/schema";
|
|
3
|
+
import { FallbackReason } from "@claudexor/schema";
|
|
4
|
+
export interface ReviewerSpec {
|
|
5
|
+
adapter: HarnessAdapter;
|
|
6
|
+
providerFamily: ProviderFamily;
|
|
7
|
+
requestedModel?: string | null;
|
|
8
|
+
requestedEffort?: EffortHint | null;
|
|
9
|
+
authPreference?: AuthPreference | null;
|
|
10
|
+
}
|
|
11
|
+
export interface ReviewCandidateInput {
|
|
12
|
+
/** Anonymized label (e.g. "Candidate A") — never reveal which model produced it. */
|
|
13
|
+
candidateLabel: string;
|
|
14
|
+
diff: string;
|
|
15
|
+
evidenceDir: string;
|
|
16
|
+
/** Persistent local artifact directory for raw reviewer telemetry. Defaults under evidenceDir for tests. */
|
|
17
|
+
artifactsDir?: string;
|
|
18
|
+
cwd: string;
|
|
19
|
+
reviewers: ReviewerSpec[];
|
|
20
|
+
reviewerTimeoutMs?: number;
|
|
21
|
+
transientRetryPolicy?: TransientRetryPolicy;
|
|
22
|
+
/** Child-env composition for the reviewer harnesses (defaults to mirror_native).
|
|
23
|
+
* Reviewer runs are paid harness children too, so they must honor the configured
|
|
24
|
+
* env isolation (clean) the same way candidate runs do. */
|
|
25
|
+
envInheritance?: "mirror_native" | "clean";
|
|
26
|
+
/** Scoped harness HOME/config-dir env (HOME, CODEX_HOME, CLAUDE_CONFIG_DIR, …)
|
|
27
|
+
* for the reviewer children, so a reviewer's native state (codex session
|
|
28
|
+
* rollouts, claude config) is contained in a per-review scoped home instead of
|
|
29
|
+
* the operator's real ~/.codex / ~/.claude (CLAUDEXOR_BIBLE §6). The codex
|
|
30
|
+
* route-proof transcript is read from this same CODEX_HOME, so route proof still
|
|
31
|
+
* verifies. Adapters seed auth into these dirs. */
|
|
32
|
+
env?: Record<string, string>;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
onReviewerEvent?: (event: ReviewerProgressEvent) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface ReviewCandidateResult {
|
|
37
|
+
findings: ReviewFinding[];
|
|
38
|
+
routeProofs: RouteProof[];
|
|
39
|
+
reviewerRequests: {
|
|
40
|
+
harness_id: string;
|
|
41
|
+
provider_family: ProviderFamily;
|
|
42
|
+
requested_model: string | null;
|
|
43
|
+
requested_effort: string | null;
|
|
44
|
+
}[];
|
|
45
|
+
/** True only when >=2 distinct provider families returned parseable JSON. Not a route-proof claim. */
|
|
46
|
+
crossFamilyHealthy: boolean;
|
|
47
|
+
healthyProviders: ProviderFamily[];
|
|
48
|
+
/** True only when >=2 distinct provider families have verified route proofs. */
|
|
49
|
+
crossFamilyVerified: boolean;
|
|
50
|
+
distinctProviders: ProviderFamily[];
|
|
51
|
+
/** Observed reviewer panel spend (budget truth: reviewers are paid work). */
|
|
52
|
+
reviewSpendUsd: number;
|
|
53
|
+
reviewSpendEstimated: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface TransientRetryPolicy {
|
|
56
|
+
maxRetries: number;
|
|
57
|
+
initialDelayMs: number;
|
|
58
|
+
maxDelayMs: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ReviewerProgressEvent {
|
|
61
|
+
type: "reviewer.started" | "reviewer.first_event" | "reviewer.auth_switched" | "reviewer.completed" | "reviewer.timed_out" | "reviewer.failed";
|
|
62
|
+
harness_id: string;
|
|
63
|
+
provider_family: ProviderFamily;
|
|
64
|
+
requested_model: string | null;
|
|
65
|
+
requested_effort: EffortHint | null;
|
|
66
|
+
observed_model?: string | null;
|
|
67
|
+
observed_source?: RouteProof["observed"]["evidence_source"];
|
|
68
|
+
route_proof_status?: RouteProof["status"];
|
|
69
|
+
from_auth_mode?: string;
|
|
70
|
+
to_auth_mode?: string;
|
|
71
|
+
reason?: FallbackReason;
|
|
72
|
+
artifact_dir: string;
|
|
73
|
+
at: string;
|
|
74
|
+
duration_ms?: number;
|
|
75
|
+
message?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Cross-family review of one anonymized candidate. Each reviewer runs its review
|
|
79
|
+
* intent and emits JSON findings; we attach route proofs and verify the
|
|
80
|
+
* reviewers span >= 2 distinct provider families.
|
|
81
|
+
*/
|
|
82
|
+
export declare function reviewCandidate(input: ReviewCandidateInput): Promise<ReviewCandidateResult>;
|
|
83
|
+
/** Test-only alias for the preserve-set extractor. */
|
|
84
|
+
export declare function __testExtractDiffTouchedPaths(diff: string): Set<string>;
|
|
85
|
+
//# sourceMappingURL=reviewEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewEngine.d.ts","sourceRoot":"","sources":["../src/reviewEngine.ts"],"names":[],"mappings":"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"}
|