@tokenfactory/acc-runner 0.42.0 → 0.44.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/README.md +52 -3
- package/dist/companion-run.d.ts.map +1 -1
- package/dist/companion-run.js +20 -0
- package/dist/companion-run.js.map +1 -1
- package/dist/config.d.ts +72 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +117 -3
- package/dist/config.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +13 -3
- package/dist/doctor.js.map +1 -1
- package/dist/engines/account-probe.d.ts +24 -0
- package/dist/engines/account-probe.d.ts.map +1 -1
- package/dist/engines/account-probe.js +18 -1
- package/dist/engines/account-probe.js.map +1 -1
- package/dist/engines/registry.d.ts +17 -6
- package/dist/engines/registry.d.ts.map +1 -1
- package/dist/engines/registry.js +38 -13
- package/dist/engines/registry.js.map +1 -1
- package/dist/git-auth/github-token-source.d.ts +54 -0
- package/dist/git-auth/github-token-source.d.ts.map +1 -0
- package/dist/git-auth/github-token-source.js +44 -0
- package/dist/git-auth/github-token-source.js.map +1 -0
- package/dist/git-auth/index.d.ts +4 -0
- package/dist/git-auth/index.d.ts.map +1 -1
- package/dist/git-auth/index.js +4 -0
- package/dist/git-auth/index.js.map +1 -1
- package/dist/git-auth/installation-token.d.ts +95 -0
- package/dist/git-auth/installation-token.d.ts.map +1 -0
- package/dist/git-auth/installation-token.js +192 -0
- package/dist/git-auth/installation-token.js.map +1 -0
- package/dist/local-repo/command.d.ts +28 -0
- package/dist/local-repo/command.d.ts.map +1 -0
- package/dist/local-repo/command.js +178 -0
- package/dist/local-repo/command.js.map +1 -0
- package/dist/local-repo/index.d.ts +119 -0
- package/dist/local-repo/index.d.ts.map +1 -0
- package/dist/local-repo/index.js +141 -0
- package/dist/local-repo/index.js.map +1 -0
- package/dist/machine-capabilities/index.d.ts +21 -0
- package/dist/machine-capabilities/index.d.ts.map +1 -0
- package/dist/machine-capabilities/index.js +21 -0
- package/dist/machine-capabilities/index.js.map +1 -0
- package/dist/machine-capabilities/probe.d.ts +61 -0
- package/dist/machine-capabilities/probe.d.ts.map +1 -0
- package/dist/machine-capabilities/probe.js +243 -0
- package/dist/machine-capabilities/probe.js.map +1 -0
- package/dist/machine-capabilities/redact.d.ts +42 -0
- package/dist/machine-capabilities/redact.d.ts.map +1 -0
- package/dist/machine-capabilities/redact.js +160 -0
- package/dist/machine-capabilities/redact.js.map +1 -0
- package/dist/machine-capabilities/report.d.ts +107 -0
- package/dist/machine-capabilities/report.d.ts.map +1 -0
- package/dist/machine-capabilities/report.js +211 -0
- package/dist/machine-capabilities/report.js.map +1 -0
- package/dist/machine-capabilities/types.d.ts +115 -0
- package/dist/machine-capabilities/types.d.ts.map +1 -0
- package/dist/machine-capabilities/types.js +11 -0
- package/dist/machine-capabilities/types.js.map +1 -0
- package/dist/mcp-spawn.d.ts +19 -0
- package/dist/mcp-spawn.d.ts.map +1 -1
- package/dist/mcp-spawn.js +52 -26
- package/dist/mcp-spawn.js.map +1 -1
- package/dist/migration-seq-guard.d.ts +78 -0
- package/dist/migration-seq-guard.d.ts.map +1 -0
- package/dist/migration-seq-guard.js +304 -0
- package/dist/migration-seq-guard.js.map +1 -0
- package/dist/node-version.d.ts +132 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +318 -0
- package/dist/node-version.js.map +1 -0
- package/dist/prepr-gate.d.ts +120 -0
- package/dist/prepr-gate.d.ts.map +1 -1
- package/dist/prepr-gate.js +202 -3
- package/dist/prepr-gate.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +34 -0
- package/dist/program.js.map +1 -1
- package/dist/provider-auth.d.ts +51 -1
- package/dist/provider-auth.d.ts.map +1 -1
- package/dist/provider-auth.js +83 -2
- package/dist/provider-auth.js.map +1 -1
- package/dist/runtime/review-chunking.d.ts +101 -0
- package/dist/runtime/review-chunking.d.ts.map +1 -0
- package/dist/runtime/review-chunking.js +192 -0
- package/dist/runtime/review-chunking.js.map +1 -0
- package/dist/runtime/review-diff.d.ts +30 -0
- package/dist/runtime/review-diff.d.ts.map +1 -0
- package/dist/runtime/review-diff.js +59 -0
- package/dist/runtime/review-diff.js.map +1 -0
- package/dist/runtime/reviewer.d.ts +40 -19
- package/dist/runtime/reviewer.d.ts.map +1 -1
- package/dist/runtime/reviewer.js +283 -68
- package/dist/runtime/reviewer.js.map +1 -1
- package/dist/serve-scope/command.d.ts +12 -0
- package/dist/serve-scope/command.d.ts.map +1 -0
- package/dist/serve-scope/command.js +89 -0
- package/dist/serve-scope/command.js.map +1 -0
- package/dist/serve-scope/index.d.ts +130 -0
- package/dist/serve-scope/index.d.ts.map +1 -0
- package/dist/serve-scope/index.js +148 -0
- package/dist/serve-scope/index.js.map +1 -0
- package/dist/task-runner.d.ts +22 -2
- package/dist/task-runner.d.ts.map +1 -1
- package/dist/task-runner.js +142 -25
- package/dist/task-runner.js.map +1 -1
- package/dist/watch.d.ts +21 -0
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +109 -1
- package/dist/watch.js.map +1 -1
- package/package.json +1 -1
package/dist/provider-auth.js
CHANGED
|
@@ -29,9 +29,30 @@
|
|
|
29
29
|
import os from "node:os";
|
|
30
30
|
import path from "node:path";
|
|
31
31
|
import { RUNNER_KEYCHAIN_SERVICE } from "./types.js";
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* NS RUN-3: the vault-sourced key cached by hydrateAnthropicApiKey (below),
|
|
34
|
+
* when ACC_RUNNER_ANTHROPIC_KEY_SOURCE=secret-store resolved one at startup.
|
|
35
|
+
* Deliberately NOT process.env — the ambient-key guard
|
|
36
|
+
* (scripts/ci/no-ambient-anthropic-key.mjs) is STRICT for this tree: zero
|
|
37
|
+
* literal `process.env.ANTHROPIC_API_KEY` reads OR writes, no allowlist. A
|
|
38
|
+
* module-level cache, consulted only through the parameterised
|
|
39
|
+
* anthropicApiKey() below, keeps every consumer (resolveAuthMode,
|
|
40
|
+
* withAnthropicAuth, authPrecedenceHint) on the same sanctioned resolution
|
|
41
|
+
* path without ever touching the ambient global.
|
|
42
|
+
*/
|
|
43
|
+
let vaultAnthropicApiKey = null;
|
|
44
|
+
/** Test-only: clear the vault-sourced key cache between tests. */
|
|
45
|
+
export function __resetVaultAnthropicApiKeyForTests() {
|
|
46
|
+
vaultAnthropicApiKey = null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Trimmed ANTHROPIC_API_KEY from `env`, or the NS RUN-3 vault-sourced key
|
|
50
|
+
* (see hydrateAnthropicApiKey) when `env` doesn't carry one, or "" when
|
|
51
|
+
* neither is set. An explicit value in `env` always wins.
|
|
52
|
+
*/
|
|
33
53
|
export function anthropicApiKey(env = process.env) {
|
|
34
|
-
|
|
54
|
+
const fromEnv = (env.ANTHROPIC_API_KEY ?? "").trim();
|
|
55
|
+
return fromEnv || vaultAnthropicApiKey || "";
|
|
35
56
|
}
|
|
36
57
|
/**
|
|
37
58
|
* Opt-in claude-config isolation. Even with ANTHROPIC_API_KEY
|
|
@@ -172,6 +193,66 @@ export function authPrecedenceHint(env = process.env) {
|
|
|
172
193
|
return ("if you still hit 429 session caps, a claude.ai login is shadowing the API key — " +
|
|
173
194
|
"run `claude /logout` or set ACC_RUNNER_ISOLATE_CLAUDE_CONFIG=1");
|
|
174
195
|
}
|
|
196
|
+
export const ANTHROPIC_KEY_SOURCE_ENV = "ACC_RUNNER_ANTHROPIC_KEY_SOURCE";
|
|
197
|
+
/** Vault secret name the operator stores the Anthropic key under. */
|
|
198
|
+
export const ANTHROPIC_API_KEY_SECRET_NAME = "ANTHROPIC_API_KEY";
|
|
199
|
+
/**
|
|
200
|
+
* Resolve which source ANTHROPIC_API_KEY should come from. Defaults to
|
|
201
|
+
* "env" (today's behaviour, unchanged) so existing desktop runners and
|
|
202
|
+
* containers with the key baked into their launch env see no change — the
|
|
203
|
+
* secret-store path is opt-in via ACC_RUNNER_ANTHROPIC_KEY_SOURCE=secret-store.
|
|
204
|
+
*/
|
|
205
|
+
export function resolveAnthropicKeySource(env = process.env) {
|
|
206
|
+
const v = (env[ANTHROPIC_KEY_SOURCE_ENV] ?? "").trim().toLowerCase();
|
|
207
|
+
return v === "secret-store" || v === "secret_store" || v === "vault" ? "secret-store" : "env";
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Fetch ANTHROPIC_API_KEY from the vault via the supplied fetcher and trim
|
|
211
|
+
* it. Propagates the fetcher's `secret_unavailable: …` error verbatim on
|
|
212
|
+
* failure — never adds the plaintext to a message.
|
|
213
|
+
*/
|
|
214
|
+
export async function anthropicApiKeyFromSecretStore(opts) {
|
|
215
|
+
const plaintext = await opts.fetcher(ANTHROPIC_API_KEY_SECRET_NAME, opts.agentId, opts.toolName);
|
|
216
|
+
return plaintext.trim();
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Startup-time env hydration: when ACC_RUNNER_ANTHROPIC_KEY_SOURCE is
|
|
220
|
+
* "secret-store", resolves ANTHROPIC_API_KEY from the vault, caches it (see
|
|
221
|
+
* vaultAnthropicApiKey above) so anthropicApiKey()'s fallback picks it up for
|
|
222
|
+
* every later call, and returns `base` with it set too; otherwise returns
|
|
223
|
+
* `base` unchanged. An ANTHROPIC_API_KEY already present in `base` always
|
|
224
|
+
* wins and is never clobbered, so a local override for debugging still works
|
|
225
|
+
* even with the source flag flipped. Never mutates `base`.
|
|
226
|
+
*
|
|
227
|
+
* Wired into watch.ts's and companion-run.ts's startup paths (both call this
|
|
228
|
+
* ONCE at process startup, before the first withAnthropicAuth call / claude
|
|
229
|
+
* spawn, and rely on the module cache rather than assigning the result to
|
|
230
|
+
* process.env — see the ambient-key guard note above anthropicApiKey()).
|
|
231
|
+
*/
|
|
232
|
+
export async function hydrateAnthropicApiKey(base = process.env, storeOpts) {
|
|
233
|
+
if (resolveAnthropicKeySource(base) !== "secret-store")
|
|
234
|
+
return base;
|
|
235
|
+
// Local-override check: base's OWN property, not the vault-cache fallback
|
|
236
|
+
// anthropicApiKey() also consults — an explicit env value always wins here,
|
|
237
|
+
// regardless of anything already cached from a prior hydration.
|
|
238
|
+
if ((base.ANTHROPIC_API_KEY ?? "").trim())
|
|
239
|
+
return base;
|
|
240
|
+
if (!storeOpts) {
|
|
241
|
+
throw new Error(`${ANTHROPIC_KEY_SOURCE_ENV}=secret-store requires a vault fetcher at startup (agentId + fetcher)`);
|
|
242
|
+
}
|
|
243
|
+
const key = await anthropicApiKeyFromSecretStore(storeOpts);
|
|
244
|
+
if (!key) {
|
|
245
|
+
throw new Error(`anthropic_secret_unavailable: ${ANTHROPIC_API_KEY_SECRET_NAME} resolved to an empty value`);
|
|
246
|
+
}
|
|
247
|
+
// NS RUN-3: cache it for anthropicApiKey()'s fallback so downstream
|
|
248
|
+
// consumers (withAnthropicAuth, resolveAuthMode, …) resolve the vault key
|
|
249
|
+
// WITHOUT the runner ever writing process.env.ANTHROPIC_API_KEY directly
|
|
250
|
+
// (see the module-cache doc comment above anthropicApiKey()). The returned
|
|
251
|
+
// env object still carries it explicitly too, for a caller that reads the
|
|
252
|
+
// return value directly.
|
|
253
|
+
vaultAnthropicApiKey = key;
|
|
254
|
+
return { ...base, ANTHROPIC_API_KEY: key };
|
|
255
|
+
}
|
|
175
256
|
/**
|
|
176
257
|
* The per-provider keychain account under the frozen `acc-runner` service.
|
|
177
258
|
* FROZEN-CONTRACT EXTENSION (Track-A note): this ADDS a namespaced account
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-auth.js","sourceRoot":"","sources":["../src/provider-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"provider-auth.js","sourceRoot":"","sources":["../src/provider-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REVIEWER-DIFF-CAP — make a large PR REVIEWABLE instead of unreviewable.
|
|
3
|
+
*
|
|
4
|
+
* MEASURED FAULT (PR #1815, 140,456 chars / 13 files against a 60,000-char cap):
|
|
5
|
+
* the runner-local reviewer truncated the diff, then spent three review cycles
|
|
6
|
+
* turning that truncation into code verdicts —
|
|
7
|
+
* 1. an advisory hold (infra),
|
|
8
|
+
* 2. a reject citing files "not present in the reviewable diff",
|
|
9
|
+
* 3. a reject stating "more than half the PR is not visible and cannot be
|
|
10
|
+
* verified".
|
|
11
|
+
* Zero defects were ever demonstrated, the PR deadlocked mergeable, and the
|
|
12
|
+
* rework loop it triggered could never succeed — reworking code does not shrink
|
|
13
|
+
* a diff. A reviewer must never convert its own tooling limitation into a code
|
|
14
|
+
* verdict.
|
|
15
|
+
*
|
|
16
|
+
* This module is the pure half of the fix. It provides:
|
|
17
|
+
*
|
|
18
|
+
* 1. `planReviewChunks` — split an over-cap diff into whole-file chunks that
|
|
19
|
+
* each fit under the cap, so EVERY file is actually read by some pass. The
|
|
20
|
+
* split is BYTE-EXACT: `chunks.map(c => c.text).join("") === diff`, which is
|
|
21
|
+
* what makes "nothing was withheld" a provable property rather than a claim.
|
|
22
|
+
* 2. The ABSENCE-CLAIM guard — patterns + partitioner that recognise a reason
|
|
23
|
+
* asserting content is missing/invisible/unverifiable. The runner had no such
|
|
24
|
+
* guard (the server path has had one since the #1665/#1679/#1690 wave); that
|
|
25
|
+
* absence is why #1815's two rejects stood.
|
|
26
|
+
*
|
|
27
|
+
* The absence-claim half is a MIRROR of `api/_lib/reviewer/absence-claims.ts` —
|
|
28
|
+
* the runner is a standalone published package and cannot import from `api/_lib`.
|
|
29
|
+
* // keep in sync with api/_lib/reviewer/absence-claims.ts
|
|
30
|
+
*
|
|
31
|
+
* PURE. No I/O, no clock, no client. The wiring lives in `reviewer.ts`.
|
|
32
|
+
*/
|
|
33
|
+
/** One reviewable slice of an over-cap diff. `text` is a verbatim byte range. */
|
|
34
|
+
export interface ReviewChunk {
|
|
35
|
+
/** 1-based position in the chunk sequence. */
|
|
36
|
+
index: number;
|
|
37
|
+
/** Total chunks in the sequence (same value on every chunk). */
|
|
38
|
+
total: number;
|
|
39
|
+
/** File paths whose content this chunk carries (whole or partial). */
|
|
40
|
+
paths: string[];
|
|
41
|
+
/** The verbatim diff bytes this chunk carries. */
|
|
42
|
+
text: string;
|
|
43
|
+
/**
|
|
44
|
+
* True when this chunk carries only PART of a single file that exceeded the
|
|
45
|
+
* per-chunk cap on its own. The remaining parts ride the adjacent chunks, so
|
|
46
|
+
* the file is still fully covered ACROSS the sequence — never withheld.
|
|
47
|
+
*/
|
|
48
|
+
partial: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hard ceiling on chunk count. A diff needing more passes than this is not a
|
|
52
|
+
* review problem the runner can solve by spending more subscription budget — it
|
|
53
|
+
* is reported as an INFRA outcome by the caller (never a reject), so the
|
|
54
|
+
* escalation path owns it. 8 chunks × 60,000 chars ≈ 480 KB of diff.
|
|
55
|
+
*/
|
|
56
|
+
export declare const MAX_REVIEW_CHUNKS = 8;
|
|
57
|
+
/**
|
|
58
|
+
* Split `diff` into chunks that each fit within `maxChars`, cutting at whole-file
|
|
59
|
+
* boundaries wherever possible.
|
|
60
|
+
*
|
|
61
|
+
* INVARIANTS (all asserted by the wave's tests):
|
|
62
|
+
* - byte-exact: `chunks.map(c => c.text).join("") === diff`;
|
|
63
|
+
* - every chunk's `text.length <= maxChars` (except the degenerate `maxChars <= 0`);
|
|
64
|
+
* - a diff at or under the cap yields exactly ONE chunk holding the whole diff,
|
|
65
|
+
* so the caller's single-pass path stays byte-identical to before.
|
|
66
|
+
*
|
|
67
|
+
* A file larger than `maxChars` on its own is sliced into contiguous parts rather
|
|
68
|
+
* than dropped — a partly-shown file across two passes still gets fully read,
|
|
69
|
+
* which a truncating cap never achieved.
|
|
70
|
+
*/
|
|
71
|
+
export declare function planReviewChunks(diff: string, maxChars: number): ReviewChunk[];
|
|
72
|
+
export declare const ABSENCE_CLAIM_PATTERNS: RegExp[];
|
|
73
|
+
/**
|
|
74
|
+
* True when one reviewer reason asserts that content is ABSENT from — or
|
|
75
|
+
* unverifiable within — what the reviewer was shown, rather than describing a
|
|
76
|
+
* defect in what it read. Only meaningful when coverage was incomplete; callers
|
|
77
|
+
* MUST gate on that before acting on it.
|
|
78
|
+
*/
|
|
79
|
+
export declare function isAbsenceClaimReason(reason: string | null | undefined): boolean;
|
|
80
|
+
/** Sub-marker identifying this class inside the escalation headline. */
|
|
81
|
+
export declare const TRUNCATED_ABSENCE_MARKER = "truncated-diff absence claim";
|
|
82
|
+
/**
|
|
83
|
+
* Headline stamped on a verdict the absence guard escalates. Opens with RR-3's
|
|
84
|
+
* `reviewer tooling failure:` marker so every existing consumer
|
|
85
|
+
* (`isToolingFailureReviewerOutcome`, the budget exemption in
|
|
86
|
+
* `countReviewerErrors`, the neutral `acc/review` publish) routes it as INFRA.
|
|
87
|
+
*
|
|
88
|
+
* Phrased to match none of the patterns above (asserted by the wave's test), so
|
|
89
|
+
* a re-scan of a stored row can never re-classify our own headline as a claim.
|
|
90
|
+
*/
|
|
91
|
+
export declare const REVIEWER_ABSENCE_ESCALATION_REASON: string;
|
|
92
|
+
/** Prefix marking a discarded claim in the audit trail (never re-emitted as a finding). */
|
|
93
|
+
export declare const DISCARDED_CLAIM_PREFIX = "discarded (unsound \u2014 a read-coverage claim, not a defect): ";
|
|
94
|
+
/** True when a completed review row is an absence-guard escalation. */
|
|
95
|
+
export declare function isAbsenceEscalatedOutcome(decision: string | null | undefined, reasons: string[] | null | undefined): boolean;
|
|
96
|
+
/** Split a reason list into the substantive findings and the absence claims. */
|
|
97
|
+
export declare function partitionAbsenceClaims(reasons: string[] | null | undefined): {
|
|
98
|
+
substantive: string[];
|
|
99
|
+
absence: string[];
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=review-chunking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-chunking.d.ts","sourceRoot":"","sources":["../../src/runtime/review-chunking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAMH,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,WAAW,EAAE,CAoDf;AAiBD,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAS1C,CAAC;AAgBF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAK/E;AAED,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAEvE;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,QAM4B,CAAC;AAE5E,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,qEAAgE,CAAC;AAEpG,uEAAuE;AACvE,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAKT;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG;IAC5E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAQA"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REVIEWER-DIFF-CAP — make a large PR REVIEWABLE instead of unreviewable.
|
|
3
|
+
*
|
|
4
|
+
* MEASURED FAULT (PR #1815, 140,456 chars / 13 files against a 60,000-char cap):
|
|
5
|
+
* the runner-local reviewer truncated the diff, then spent three review cycles
|
|
6
|
+
* turning that truncation into code verdicts —
|
|
7
|
+
* 1. an advisory hold (infra),
|
|
8
|
+
* 2. a reject citing files "not present in the reviewable diff",
|
|
9
|
+
* 3. a reject stating "more than half the PR is not visible and cannot be
|
|
10
|
+
* verified".
|
|
11
|
+
* Zero defects were ever demonstrated, the PR deadlocked mergeable, and the
|
|
12
|
+
* rework loop it triggered could never succeed — reworking code does not shrink
|
|
13
|
+
* a diff. A reviewer must never convert its own tooling limitation into a code
|
|
14
|
+
* verdict.
|
|
15
|
+
*
|
|
16
|
+
* This module is the pure half of the fix. It provides:
|
|
17
|
+
*
|
|
18
|
+
* 1. `planReviewChunks` — split an over-cap diff into whole-file chunks that
|
|
19
|
+
* each fit under the cap, so EVERY file is actually read by some pass. The
|
|
20
|
+
* split is BYTE-EXACT: `chunks.map(c => c.text).join("") === diff`, which is
|
|
21
|
+
* what makes "nothing was withheld" a provable property rather than a claim.
|
|
22
|
+
* 2. The ABSENCE-CLAIM guard — patterns + partitioner that recognise a reason
|
|
23
|
+
* asserting content is missing/invisible/unverifiable. The runner had no such
|
|
24
|
+
* guard (the server path has had one since the #1665/#1679/#1690 wave); that
|
|
25
|
+
* absence is why #1815's two rejects stood.
|
|
26
|
+
*
|
|
27
|
+
* The absence-claim half is a MIRROR of `api/_lib/reviewer/absence-claims.ts` —
|
|
28
|
+
* the runner is a standalone published package and cannot import from `api/_lib`.
|
|
29
|
+
* // keep in sync with api/_lib/reviewer/absence-claims.ts
|
|
30
|
+
*
|
|
31
|
+
* PURE. No I/O, no clock, no client. The wiring lives in `reviewer.ts`.
|
|
32
|
+
*/
|
|
33
|
+
import { splitDiffByFile } from "./review-diff.js";
|
|
34
|
+
/**
|
|
35
|
+
* Hard ceiling on chunk count. A diff needing more passes than this is not a
|
|
36
|
+
* review problem the runner can solve by spending more subscription budget — it
|
|
37
|
+
* is reported as an INFRA outcome by the caller (never a reject), so the
|
|
38
|
+
* escalation path owns it. 8 chunks × 60,000 chars ≈ 480 KB of diff.
|
|
39
|
+
*/
|
|
40
|
+
export const MAX_REVIEW_CHUNKS = 8;
|
|
41
|
+
/**
|
|
42
|
+
* Split `diff` into chunks that each fit within `maxChars`, cutting at whole-file
|
|
43
|
+
* boundaries wherever possible.
|
|
44
|
+
*
|
|
45
|
+
* INVARIANTS (all asserted by the wave's tests):
|
|
46
|
+
* - byte-exact: `chunks.map(c => c.text).join("") === diff`;
|
|
47
|
+
* - every chunk's `text.length <= maxChars` (except the degenerate `maxChars <= 0`);
|
|
48
|
+
* - a diff at or under the cap yields exactly ONE chunk holding the whole diff,
|
|
49
|
+
* so the caller's single-pass path stays byte-identical to before.
|
|
50
|
+
*
|
|
51
|
+
* A file larger than `maxChars` on its own is sliced into contiguous parts rather
|
|
52
|
+
* than dropped — a partly-shown file across two passes still gets fully read,
|
|
53
|
+
* which a truncating cap never achieved.
|
|
54
|
+
*/
|
|
55
|
+
export function planReviewChunks(diff, maxChars) {
|
|
56
|
+
const src = diff ?? "";
|
|
57
|
+
const cap = Number.isFinite(maxChars) && maxChars > 0 ? Math.floor(maxChars) : src.length;
|
|
58
|
+
if (src.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
if (src.length <= cap) {
|
|
61
|
+
return [{ index: 1, total: 1, paths: diffPathsOf(src), text: src, partial: false }];
|
|
62
|
+
}
|
|
63
|
+
// Units are the atoms we pack: the (usually empty) pre-first-file preamble,
|
|
64
|
+
// then one unit per `diff --git` file block. Concatenating every unit in order
|
|
65
|
+
// reproduces `src` exactly, which is what carries the byte-exactness invariant
|
|
66
|
+
// through the packing below.
|
|
67
|
+
const { preamble, files } = splitDiffByFile(src);
|
|
68
|
+
const units = files.length === 0
|
|
69
|
+
? [{ path: null, text: src }]
|
|
70
|
+
: [
|
|
71
|
+
...(preamble.length > 0 ? [{ path: null, text: preamble }] : []),
|
|
72
|
+
...files.map((f) => ({ path: f.path, text: f.text })),
|
|
73
|
+
];
|
|
74
|
+
const chunks = [];
|
|
75
|
+
let open = null;
|
|
76
|
+
const flush = () => {
|
|
77
|
+
if (open && open.text.length > 0) {
|
|
78
|
+
chunks.push({ paths: open.paths, text: open.text, partial: false });
|
|
79
|
+
}
|
|
80
|
+
open = null;
|
|
81
|
+
};
|
|
82
|
+
for (const unit of units) {
|
|
83
|
+
if (unit.text.length > cap) {
|
|
84
|
+
// Oversized single unit: close the open chunk, then emit contiguous slices.
|
|
85
|
+
flush();
|
|
86
|
+
for (let at = 0; at < unit.text.length; at += cap) {
|
|
87
|
+
chunks.push({
|
|
88
|
+
paths: unit.path ? [unit.path] : [],
|
|
89
|
+
text: unit.text.slice(at, at + cap),
|
|
90
|
+
partial: true,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (open && open.text.length + unit.text.length > cap)
|
|
96
|
+
flush();
|
|
97
|
+
if (!open)
|
|
98
|
+
open = { paths: [], text: "" };
|
|
99
|
+
if (unit.path)
|
|
100
|
+
open.paths.push(unit.path);
|
|
101
|
+
open.text += unit.text;
|
|
102
|
+
}
|
|
103
|
+
flush();
|
|
104
|
+
const total = chunks.length;
|
|
105
|
+
return chunks.map((c, i) => ({ ...c, index: i + 1, total }));
|
|
106
|
+
}
|
|
107
|
+
/** File paths a diff slice names, used to label a chunk. */
|
|
108
|
+
function diffPathsOf(diff) {
|
|
109
|
+
return splitDiffByFile(diff).files.map((f) => f.path);
|
|
110
|
+
}
|
|
111
|
+
/* ─────────────────────────── absence-claim detection ─────────────────────────
|
|
112
|
+
*
|
|
113
|
+
* // keep in sync with api/_lib/reviewer/absence-claims.ts ABSENCE_CLAIM_PATTERNS
|
|
114
|
+
*
|
|
115
|
+
* Each pattern is anchored on a visibility verb ("present", "visible", "shown",
|
|
116
|
+
* "included", "listed") or on an explicit diff subject, so a BEHAVIOURAL finding
|
|
117
|
+
* ("the handler does not rethrow") is never matched. Callers gate on
|
|
118
|
+
* not-full-coverage, which is what makes keeping these broad safe: on a complete
|
|
119
|
+
* single-pass review nothing here fires and the verdict is unchanged.
|
|
120
|
+
*/
|
|
121
|
+
export const ABSENCE_CLAIM_PATTERNS = [
|
|
122
|
+
/\bnot\s+shown\s+to\s+(?:exist|be)\b/i,
|
|
123
|
+
/\bnot\s+(?:fully\s+|clearly\s+|actually\s+|explicitly\s+|anywhere\s+)?(?:present|visible|shown|included|listed)\b/i,
|
|
124
|
+
/\b(?:absent|missing)\s+from\s+(?:the\s+)?(?:visible\s+|provided\s+|supplied\s+|shown\s+|reviewable\s+)?(?:diff|patch|changeset|pull\s+request|PR)\b/i,
|
|
125
|
+
/\b(?:diff|patch|changeset|pull\s+request)\b[^.;]{0,80}?\b(?:does|do|did)\s+not\s+(?:show|contain|include|reveal)\b/i,
|
|
126
|
+
/\bnowhere\s+(?:in|within)\s+(?:the\s+)?(?:visible\s+|provided\s+)?(?:diff|patch|changeset|PR)\b/i,
|
|
127
|
+
/\b(?:no|neither)\s+(?:such\s+)?(?:file|test|test\s+file|symbol|function|export|import|definition|proof)\b[^.;]{0,60}?\b(?:in|within)\s+the\s+(?:visible\s+|provided\s+)?(?:diff|patch|changeset|PR)\b/i,
|
|
128
|
+
/\bnot\s+(?:seen|observed)\s+in\s+the\s+(?:visible\s+|provided\s+)?(?:diff|patch|changeset|PR)\b/i,
|
|
129
|
+
/\bcould\s+not\s+(?:find|locate)\b[^.;]{0,60}?\b(?:in|within)\s+the\s+(?:visible\s+|provided\s+)?(?:diff|patch|changeset|PR)\b/i,
|
|
130
|
+
];
|
|
131
|
+
/**
|
|
132
|
+
* RUNNER-ONLY addition (no server counterpart): #1815's second reject read
|
|
133
|
+
* "more than half the PR is not visible and cannot be verified". The
|
|
134
|
+
* "cannot be verified" half is the class the task names explicitly, and the
|
|
135
|
+
* server patterns above only catch it via the "not visible" clause that happened
|
|
136
|
+
* to sit next to it. These two regexes catch it on its own — but ONLY in
|
|
137
|
+
* conjunction (both must match the same reason), so "the migration cannot be
|
|
138
|
+
* verified without a rollback plan" is a defect claim and stays a defect claim.
|
|
139
|
+
*/
|
|
140
|
+
const UNVERIFIABLE_RE = /\b(?:cannot|can\s?not|can't|could\s?not|couldn't|unable\s+to|no\s+way\s+to)\s+(?:be\s+)?(?:verif|confirm|assess|evaluat|review|read|inspect|judge|check)/i;
|
|
141
|
+
const VISIBILITY_SUBJECT_RE = /\b(?:truncat\w*|withheld|(?:in)?visible|not\s+shown|beyond\s+the\s+\w+|review\s+size\s+limit|diff\s+size|size\s+limit|reviewable\s+diff|60[,_]?000|60\s?k)\b/i;
|
|
142
|
+
/**
|
|
143
|
+
* True when one reviewer reason asserts that content is ABSENT from — or
|
|
144
|
+
* unverifiable within — what the reviewer was shown, rather than describing a
|
|
145
|
+
* defect in what it read. Only meaningful when coverage was incomplete; callers
|
|
146
|
+
* MUST gate on that before acting on it.
|
|
147
|
+
*/
|
|
148
|
+
export function isAbsenceClaimReason(reason) {
|
|
149
|
+
const text = reason ?? "";
|
|
150
|
+
if (text.trim().length === 0)
|
|
151
|
+
return false;
|
|
152
|
+
if (ABSENCE_CLAIM_PATTERNS.some((re) => re.test(text)))
|
|
153
|
+
return true;
|
|
154
|
+
return UNVERIFIABLE_RE.test(text) && VISIBILITY_SUBJECT_RE.test(text);
|
|
155
|
+
}
|
|
156
|
+
/** Sub-marker identifying this class inside the escalation headline. */
|
|
157
|
+
export const TRUNCATED_ABSENCE_MARKER = "truncated-diff absence claim";
|
|
158
|
+
/**
|
|
159
|
+
* Headline stamped on a verdict the absence guard escalates. Opens with RR-3's
|
|
160
|
+
* `reviewer tooling failure:` marker so every existing consumer
|
|
161
|
+
* (`isToolingFailureReviewerOutcome`, the budget exemption in
|
|
162
|
+
* `countReviewerErrors`, the neutral `acc/review` publish) routes it as INFRA.
|
|
163
|
+
*
|
|
164
|
+
* Phrased to match none of the patterns above (asserted by the wave's test), so
|
|
165
|
+
* a re-scan of a stored row can never re-classify our own headline as a claim.
|
|
166
|
+
*/
|
|
167
|
+
export const REVIEWER_ABSENCE_ESCALATION_REASON = `reviewer tooling failure: ${TRUNCATED_ABSENCE_MARKER} — every blocking reason this ` +
|
|
168
|
+
"review produced was a statement about what the harness did or did not show it, not a " +
|
|
169
|
+
"defect in the code. A reviewer may not convert its own read-coverage limit into a " +
|
|
170
|
+
"verdict: reworking the branch cannot shrink a diff, so such a reject deadlocks a " +
|
|
171
|
+
"mergeable PR (see #1815). Escalated to a budget-exempt infra outcome with acc/review " +
|
|
172
|
+
"held neutral. Remedy: widen review coverage; never re-assert the claim.";
|
|
173
|
+
/** Prefix marking a discarded claim in the audit trail (never re-emitted as a finding). */
|
|
174
|
+
export const DISCARDED_CLAIM_PREFIX = "discarded (unsound — a read-coverage claim, not a defect): ";
|
|
175
|
+
/** True when a completed review row is an absence-guard escalation. */
|
|
176
|
+
export function isAbsenceEscalatedOutcome(decision, reasons) {
|
|
177
|
+
if (decision !== "reviewer_error")
|
|
178
|
+
return false;
|
|
179
|
+
return (reasons ?? []).some((r) => typeof r === "string" && r.includes(TRUNCATED_ABSENCE_MARKER));
|
|
180
|
+
}
|
|
181
|
+
/** Split a reason list into the substantive findings and the absence claims. */
|
|
182
|
+
export function partitionAbsenceClaims(reasons) {
|
|
183
|
+
const substantive = [];
|
|
184
|
+
const absence = [];
|
|
185
|
+
for (const r of reasons ?? []) {
|
|
186
|
+
if (typeof r !== "string")
|
|
187
|
+
continue;
|
|
188
|
+
(isAbsenceClaimReason(r) ? absence : substantive).push(r);
|
|
189
|
+
}
|
|
190
|
+
return { substantive, absence };
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=review-chunking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-chunking.js","sourceRoot":"","sources":["../../src/runtime/review-chunking.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified-diff structure helpers shared by the reviewer's truncation path
|
|
3
|
+
* (`reviewer.ts`) and its chunk planner (`review-chunking.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Extracted verbatim from `reviewer.ts` so the two consumers share ONE parser
|
|
6
|
+
* instead of a copy each — `reviewer.ts` re-exports both names, so its public
|
|
7
|
+
* surface (and every test importing them from there) is unchanged.
|
|
8
|
+
*
|
|
9
|
+
* PURE. No I/O.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* RF-3: the file paths a unified diff touches, in order, from its
|
|
13
|
+
* `diff --git a/<path> b/<path>` headers (falling back to `+++ b/<path>`).
|
|
14
|
+
* Pure; tolerant of malformed headers (skips what it can't parse).
|
|
15
|
+
* // keep in sync with api/_lib/reviewer-agent.ts diffFilePaths
|
|
16
|
+
*/
|
|
17
|
+
export declare function diffFilePaths(diff: string): string[];
|
|
18
|
+
/**
|
|
19
|
+
* RF-3: split a unified diff into its per-file blocks. Byte-exact —
|
|
20
|
+
* `preamble + files.map(f => f.text).join("")` reproduces the input — so a
|
|
21
|
+
* reordered diff is still the same bytes, just in a different file order.
|
|
22
|
+
*/
|
|
23
|
+
export declare function splitDiffByFile(diff: string): {
|
|
24
|
+
preamble: string;
|
|
25
|
+
files: Array<{
|
|
26
|
+
path: string;
|
|
27
|
+
text: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=review-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-diff.d.ts","sourceRoot":"","sources":["../../src/runtime/review-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GACX;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAcpE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified-diff structure helpers shared by the reviewer's truncation path
|
|
3
|
+
* (`reviewer.ts`) and its chunk planner (`review-chunking.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Extracted verbatim from `reviewer.ts` so the two consumers share ONE parser
|
|
6
|
+
* instead of a copy each — `reviewer.ts` re-exports both names, so its public
|
|
7
|
+
* surface (and every test importing them from there) is unchanged.
|
|
8
|
+
*
|
|
9
|
+
* PURE. No I/O.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* RF-3: the file paths a unified diff touches, in order, from its
|
|
13
|
+
* `diff --git a/<path> b/<path>` headers (falling back to `+++ b/<path>`).
|
|
14
|
+
* Pure; tolerant of malformed headers (skips what it can't parse).
|
|
15
|
+
* // keep in sync with api/_lib/reviewer-agent.ts diffFilePaths
|
|
16
|
+
*/
|
|
17
|
+
export function diffFilePaths(diff) {
|
|
18
|
+
const paths = [];
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
for (const line of (diff ?? "").split("\n")) {
|
|
21
|
+
let p = null;
|
|
22
|
+
const git = /^diff --git a\/(.+?) b\/(.+)$/.exec(line);
|
|
23
|
+
if (git)
|
|
24
|
+
p = git[2];
|
|
25
|
+
else {
|
|
26
|
+
const plus = /^\+\+\+ b\/(.+)$/.exec(line);
|
|
27
|
+
if (plus && plus[1] !== "/dev/null")
|
|
28
|
+
p = plus[1];
|
|
29
|
+
}
|
|
30
|
+
if (p && !seen.has(p)) {
|
|
31
|
+
seen.add(p);
|
|
32
|
+
paths.push(p);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return paths;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* RF-3: split a unified diff into its per-file blocks. Byte-exact —
|
|
39
|
+
* `preamble + files.map(f => f.text).join("")` reproduces the input — so a
|
|
40
|
+
* reordered diff is still the same bytes, just in a different file order.
|
|
41
|
+
*/
|
|
42
|
+
export function splitDiffByFile(diff) {
|
|
43
|
+
const src = diff ?? "";
|
|
44
|
+
const headerRe = /^diff --git a\/(.+?) b\/(.+)$/gm;
|
|
45
|
+
const starts = [];
|
|
46
|
+
let m;
|
|
47
|
+
while ((m = headerRe.exec(src)) !== null)
|
|
48
|
+
starts.push({ index: m.index, path: m[2] });
|
|
49
|
+
if (starts.length === 0)
|
|
50
|
+
return { preamble: src, files: [] };
|
|
51
|
+
return {
|
|
52
|
+
preamble: src.slice(0, starts[0].index),
|
|
53
|
+
files: starts.map((s, i) => ({
|
|
54
|
+
path: s.path,
|
|
55
|
+
text: src.slice(s.index, i + 1 < starts.length ? starts[i + 1].index : src.length),
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=review-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-diff.js","sourceRoot":"","sources":["../../src/runtime/review-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,GAAkB,IAAI,CAAC;QAC5B,MAAM,GAAG,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,GAAG;YAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;aACf,CAAC;YACJ,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW;gBAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,iCAAiC,CAAC;IACnD,MAAM,MAAM,GAA2C,EAAE,CAAC;IAC1D,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC7D,OAAO;QACL,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;SACnF,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { type ExecaChildProcess } from "execa";
|
|
18
18
|
import { type ReviewerProbeResult } from "../failure-classifier.js";
|
|
19
|
+
import { type ReviewChunk } from "./review-chunking.js";
|
|
19
20
|
import { type TolerantRemoveResult } from "../review-worktree-cleanup.js";
|
|
20
21
|
import type { RunnerSupabaseClient } from "../supabase.js";
|
|
21
22
|
export interface ReviewAssignment {
|
|
@@ -102,25 +103,7 @@ export declare function normalizeReportHeading(line: string): string | null;
|
|
|
102
103
|
*/
|
|
103
104
|
export declare function scanCompletionSignals(prBody: string): CompletionSignalHit[];
|
|
104
105
|
export declare const REVIEWER_MAX_DIFF_CHARS = 60000;
|
|
105
|
-
|
|
106
|
-
* RF-3: the file paths a unified diff touches, in order, from its
|
|
107
|
-
* `diff --git a/<path> b/<path>` headers (falling back to `+++ b/<path>`).
|
|
108
|
-
* Pure; tolerant of malformed headers (skips what it can't parse).
|
|
109
|
-
* // keep in sync with api/_lib/reviewer-agent.ts diffFilePaths
|
|
110
|
-
*/
|
|
111
|
-
export declare function diffFilePaths(diff: string): string[];
|
|
112
|
-
/**
|
|
113
|
-
* RF-3: split a unified diff into its per-file blocks. Byte-exact —
|
|
114
|
-
* `preamble + files.map(f => f.text).join("")` reproduces the input — so a
|
|
115
|
-
* reordered diff is still the same bytes, just in a different file order.
|
|
116
|
-
*/
|
|
117
|
-
export declare function splitDiffByFile(diff: string): {
|
|
118
|
-
preamble: string;
|
|
119
|
-
files: Array<{
|
|
120
|
-
path: string;
|
|
121
|
-
text: string;
|
|
122
|
-
}>;
|
|
123
|
-
};
|
|
106
|
+
export { diffFilePaths, splitDiffByFile } from "./review-diff.js";
|
|
124
107
|
/**
|
|
125
108
|
* RF-3: the file paths the acceptance criteria explicitly NAME. These are the
|
|
126
109
|
* reviewer's proof files — an AC that says "a test proves X" and names the test
|
|
@@ -222,6 +205,44 @@ export declare function renderReviewerPrompt(args: {
|
|
|
222
205
|
pr_body: string;
|
|
223
206
|
pr_diff: string;
|
|
224
207
|
}): string;
|
|
208
|
+
/** The chunk-scope override appended to a PART pass's prompt. */
|
|
209
|
+
export declare function chunkScopeNotice(chunk: ReviewChunk): string;
|
|
210
|
+
/** The synthesis override appended to the FINAL pass's prompt. */
|
|
211
|
+
export declare function synthesisScopeNotice(totalChunks: number): string;
|
|
212
|
+
/**
|
|
213
|
+
* The evidence block the synthesis pass reads in place of a diff: the complete
|
|
214
|
+
* file inventory (so every path the PR touches is named) followed by each part
|
|
215
|
+
* pass's decision and findings.
|
|
216
|
+
*/
|
|
217
|
+
export declare function renderSynthesisEvidence(chunks: ReviewChunk[], passes: Array<{
|
|
218
|
+
decision: string;
|
|
219
|
+
reasons: string[];
|
|
220
|
+
confidence: number;
|
|
221
|
+
}>, allPaths: string[]): string;
|
|
222
|
+
/**
|
|
223
|
+
* REVIEWER-DIFF-CAP: one machine-readable coverage line, appended to every
|
|
224
|
+
* verdict a chunked review produces. Deliberately word-free of every
|
|
225
|
+
* absence-claim pattern (asserted by the wave's test) so this telemetry can
|
|
226
|
+
* never be re-read as a finding.
|
|
227
|
+
*/
|
|
228
|
+
export declare function chunkedCoverageReason(chunkCount: number, fileCount: number, diffChars: number): string;
|
|
229
|
+
/**
|
|
230
|
+
* REVIEWER-DIFF-CAP — the guard that makes the measured #1815 verdict
|
|
231
|
+
* IMPOSSIBLE: a reject whose reasons are exclusively read-coverage claims
|
|
232
|
+
* becomes an INFRA outcome (`reviewer_error`), never a code verdict.
|
|
233
|
+
*
|
|
234
|
+
* Applied ONLY when coverage was not a single full-diff pass, so a normal
|
|
235
|
+
* small-diff review is byte-identical to before (pinned by test). Within that
|
|
236
|
+
* gate:
|
|
237
|
+
* - reject, all reasons are coverage claims → `reviewer_error` (infra retry,
|
|
238
|
+
* budget-exempt via the RR-3 tooling-failure marker), claims kept as a
|
|
239
|
+
* DISCARDED audit trail rather than re-emitted as findings;
|
|
240
|
+
* - reject with at least one substantive defect → the reject STANDS on the
|
|
241
|
+
* substantive reasons alone (the coverage claims are still discarded);
|
|
242
|
+
* - approve → coverage claims stripped; the approve stands, because on the
|
|
243
|
+
* chunked path everything really was read.
|
|
244
|
+
*/
|
|
245
|
+
export declare function guardCoverageClaims(outcome: ReviewerOutcome): ReviewerOutcome;
|
|
225
246
|
export declare function extractReviewerDecision(text: string): {
|
|
226
247
|
decision: "approve" | "reject";
|
|
227
248
|
reasons: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../src/runtime/reviewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAS,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAMtD,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../src/runtime/reviewer.ts"],"names":[],"mappings":"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"}
|