@dougharness/codex 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eric Schwartz
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/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ // codex-review: Codex CLI as an adversarial reviewer for one change.
3
+ // Prints a ReviewResult JSON object to stdout. Exit 0 = no blockers, 1 = blockers/fail, 2 = could not review, 64 = usage.
4
+ import { readFileSync } from "node:fs";
5
+ import { runCodexReview } from "./run.js";
6
+ import { exitCodeFor } from "./schema.js";
7
+ import { parseArgs, HELP } from "./cli.js";
8
+ async function main() {
9
+ const parsed = parseArgs(process.argv.slice(2));
10
+ if (typeof parsed === "string") {
11
+ process.stderr.write(`codex-review: ${parsed}\n\n${HELP}`);
12
+ return 64;
13
+ }
14
+ if (parsed.help) {
15
+ process.stdout.write(HELP);
16
+ return 0;
17
+ }
18
+ const spec = parsed.specStdin ? readFileSync(0, "utf8") : readFileSync(parsed.specFile, "utf8");
19
+ if (!spec.trim()) {
20
+ process.stderr.write("codex-review: the spec is empty\n");
21
+ return 64;
22
+ }
23
+ const result = await runCodexReview({
24
+ spec,
25
+ base: parsed.base,
26
+ head: parsed.head,
27
+ dir: parsed.dir || process.cwd(),
28
+ model: parsed.model,
29
+ effort: parsed.effort,
30
+ timeoutMs: parsed.timeoutMs,
31
+ verifyCommands: parsed.verify,
32
+ keepMcpServers: parsed.keepMcp,
33
+ codexBin: parsed.codex,
34
+ sandbox: parsed.sandbox,
35
+ networkAccess: parsed.networkAccess,
36
+ });
37
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
38
+ return exitCodeFor(result);
39
+ }
40
+ main().then((code) => process.exit(code), (err) => {
41
+ process.stderr.write(`codex-review: ${err && err.stack ? err.stack : String(err)}\n`);
42
+ process.exit(2);
43
+ });
44
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,qEAAqE;AACrE,0HAA0H;AAE1H,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,MAAM,OAAO,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,QAAS,EAAE,MAAM,CAAC,CAAC;IACjG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;QAClC,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,IAAK;QAClB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;QAChC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,MAAM;QAC7B,cAAc,EAAE,MAAM,CAAC,OAAO;QAC9B,QAAQ,EAAE,MAAM,CAAC,KAAK;QACtB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7D,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAC5B,CAAC,GAAG,EAAE,EAAE;IACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CACF,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { Sandbox, ReasoningEffort } from "./schema.js";
2
+ export declare const HELP = "codex-review \u2014 run Codex read-only as an adversarial reviewer of a change\n\nUsage:\n codex-review --base <ref> [--head <ref>] [--dir <path>] (--spec-file <file> | --spec -)\n [--verify <cmd>]... [--model <name>] [--effort <level>] [--timeout-ms <n>] [--keep-mcp]\n [--sandbox <mode>] [--network-access | --no-network-access] [--codex <bin>]\n\n --base <ref> Ref the change is measured against (required). Diff is base...head.\n --head <ref> Ref holding the change. Default HEAD.\n --dir <path> Repository or worktree directory. Default cwd. Codex runs inside it, read-only.\n --spec-file <file> The task spec the change claims to implement.\n --spec - Read the spec from stdin.\n --verify <cmd> A command the reviewer must run; non-zero exit is a blocker. Repeatable.\n --model <name> Codex model override.\n --effort <level> One of minimal, low, medium, high, xhigh. Maps to -c model_reasoning_effort=<level>.\n --timeout-ms <n> Kill codex after n ms (default 900000). Yields verdict \"inconclusive\".\n --keep-mcp Keep MCP servers from ~/.codex/config.toml (default: none are started).\n --sandbox <mode> workspace-write (default; test runners need scratch files) or read-only.\n Either way the working tree is compared before and after; a change voids the review.\n --network-access Pass -c sandbox_workspace_write.network_access=true so a verify command may bind a\n localhost port. Default: on under workspace-write when at least one --verify is given.\n Never passed under read-only, where Codex ignores it, even with --network-access.\n --no-network-access turns it off.\n --codex <bin> Codex executable (default: codex on PATH).\n\nOutput: one JSON object with verdict (pass|fail|inconclusive), summary, issues[{severity,file,line?,description,evidence?}],\ncommandsRun[{command,exitCode,ok,outputTail?}] taken from Codex's own event stream, changedFiles from git, and error when\nthe review could not run (codex-not-found, timeout, codex-failed, no-final-message, unparseable, git).\n\nExit codes: 0 no blockers, 1 fail verdict or blocker issue, 2 could not review, 64 usage error.\n";
3
+ export interface CliArgs {
4
+ base?: string;
5
+ head?: string;
6
+ dir?: string;
7
+ specFile?: string;
8
+ specStdin: boolean;
9
+ verify: string[];
10
+ model?: string;
11
+ effort?: ReasoningEffort;
12
+ timeoutMs?: number;
13
+ keepMcp: boolean;
14
+ codex?: string;
15
+ sandbox?: Sandbox;
16
+ networkAccess?: boolean;
17
+ help: boolean;
18
+ }
19
+ /** Returns parsed args, or an error message string for usage problems. */
20
+ export declare function parseArgs(argv: string[]): CliArgs | string;
package/dist/cli.js ADDED
@@ -0,0 +1,108 @@
1
+ // Argument parsing for the codex-review binary. Pure so it can be unit-tested without spawning.
2
+ import { SANDBOXES, REASONING_EFFORTS } from "./schema.js";
3
+ export const HELP = `codex-review — run Codex read-only as an adversarial reviewer of a change
4
+
5
+ Usage:
6
+ codex-review --base <ref> [--head <ref>] [--dir <path>] (--spec-file <file> | --spec -)
7
+ [--verify <cmd>]... [--model <name>] [--effort <level>] [--timeout-ms <n>] [--keep-mcp]
8
+ [--sandbox <mode>] [--network-access | --no-network-access] [--codex <bin>]
9
+
10
+ --base <ref> Ref the change is measured against (required). Diff is base...head.
11
+ --head <ref> Ref holding the change. Default HEAD.
12
+ --dir <path> Repository or worktree directory. Default cwd. Codex runs inside it, read-only.
13
+ --spec-file <file> The task spec the change claims to implement.
14
+ --spec - Read the spec from stdin.
15
+ --verify <cmd> A command the reviewer must run; non-zero exit is a blocker. Repeatable.
16
+ --model <name> Codex model override.
17
+ --effort <level> One of minimal, low, medium, high, xhigh. Maps to -c model_reasoning_effort=<level>.
18
+ --timeout-ms <n> Kill codex after n ms (default 900000). Yields verdict "inconclusive".
19
+ --keep-mcp Keep MCP servers from ~/.codex/config.toml (default: none are started).
20
+ --sandbox <mode> workspace-write (default; test runners need scratch files) or read-only.
21
+ Either way the working tree is compared before and after; a change voids the review.
22
+ --network-access Pass -c sandbox_workspace_write.network_access=true so a verify command may bind a
23
+ localhost port. Default: on under workspace-write when at least one --verify is given.
24
+ Never passed under read-only, where Codex ignores it, even with --network-access.
25
+ --no-network-access turns it off.
26
+ --codex <bin> Codex executable (default: codex on PATH).
27
+
28
+ Output: one JSON object with verdict (pass|fail|inconclusive), summary, issues[{severity,file,line?,description,evidence?}],
29
+ commandsRun[{command,exitCode,ok,outputTail?}] taken from Codex's own event stream, changedFiles from git, and error when
30
+ the review could not run (codex-not-found, timeout, codex-failed, no-final-message, unparseable, git).
31
+
32
+ Exit codes: 0 no blockers, 1 fail verdict or blocker issue, 2 could not review, 64 usage error.
33
+ `;
34
+ /** Returns parsed args, or an error message string for usage problems. */
35
+ export function parseArgs(argv) {
36
+ const a = { specStdin: false, verify: [], keepMcp: false, help: false };
37
+ for (let i = 0; i < argv.length; i++) {
38
+ const k = argv[i];
39
+ const next = () => {
40
+ const v = argv[++i];
41
+ if (v === undefined)
42
+ throw new Error(`${k} needs a value`);
43
+ return v;
44
+ };
45
+ try {
46
+ if (k === "--help" || k === "-h")
47
+ a.help = true;
48
+ else if (k === "--base")
49
+ a.base = next();
50
+ else if (k === "--head")
51
+ a.head = next();
52
+ else if (k === "--dir")
53
+ a.dir = next();
54
+ else if (k === "--spec-file")
55
+ a.specFile = next();
56
+ else if (k === "--spec") {
57
+ const v = next();
58
+ if (v === "-")
59
+ a.specStdin = true;
60
+ else
61
+ a.specFile = v;
62
+ }
63
+ else if (k === "--verify")
64
+ a.verify.push(next());
65
+ else if (k === "--model")
66
+ a.model = next();
67
+ else if (k === "--effort") {
68
+ const v = next();
69
+ if (!REASONING_EFFORTS.includes(v))
70
+ return `--effort must be one of ${REASONING_EFFORTS.join(", ")}`;
71
+ a.effort = v;
72
+ }
73
+ else if (k === "--timeout-ms") {
74
+ const n = Number(next());
75
+ if (!Number.isFinite(n) || n <= 0)
76
+ return "--timeout-ms must be a positive number";
77
+ a.timeoutMs = n;
78
+ }
79
+ else if (k === "--keep-mcp")
80
+ a.keepMcp = true;
81
+ else if (k === "--codex")
82
+ a.codex = next();
83
+ else if (k === "--sandbox") {
84
+ const v = next();
85
+ if (!SANDBOXES.includes(v))
86
+ return `--sandbox must be one of ${SANDBOXES.join(", ")}`;
87
+ a.sandbox = v;
88
+ }
89
+ else if (k === "--network-access")
90
+ a.networkAccess = true;
91
+ else if (k === "--no-network-access")
92
+ a.networkAccess = false;
93
+ else
94
+ return `unknown argument: ${k}`;
95
+ }
96
+ catch (e) {
97
+ return String(e.message);
98
+ }
99
+ }
100
+ if (a.help)
101
+ return a;
102
+ if (!a.base)
103
+ return "--base is required";
104
+ if (!a.specFile && !a.specStdin)
105
+ return "give the spec with --spec-file <file> or --spec -";
106
+ return a;
107
+ }
108
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { type ReviewResult } from "./schema.js";
2
+ export declare const ERROR_KINDS: readonly ["codex-not-found", "codex-failed", "timeout", "no-final-message", "unparseable", "git", "worktree-modified"];
3
+ /** Rule ids, in the order the document lists them. */
4
+ export declare const CONTRACT_RULES: {
5
+ readonly R1: "verdict is pass | fail | inconclusive; every error is reported as inconclusive";
6
+ readonly R2: "issues are typed: severity in blocker | major | minor, file, non-empty description, optional integer line and string evidence";
7
+ readonly R3: "commandsRun is evidence: each entry has the command, the exit code the runtime observed (or null), and ok that is true only for exit 0";
8
+ readonly R4: "changedFiles is what git computed for base...head: unique, sorted, relative paths";
9
+ readonly R5: "base, head, and dir are non-empty; dir is absolute";
10
+ readonly R6: "the worker names itself: reviewer non-empty, model a string or null, sandbox one of the declared sandboxes";
11
+ readonly R7: "error is null or a typed failure with a kind from the declared list and a non-empty message, plus the kind's own evidence field";
12
+ readonly R8: "measurements are real numbers or null: exit code of the runtime, non-negative duration, token usage";
13
+ readonly R9: "exit codes: 0 no blockers, 1 fail verdict or a blocker issue, 2 could not review (error or inconclusive)";
14
+ readonly R10: "a review that changed the working tree it was reviewing is void: error kind worktree-modified and verdict inconclusive";
15
+ readonly R11: "marker records the nesting guard: name is DOUG_CODEX_REVIEW, passed and inherited are booleans";
16
+ readonly R12: "a blocker cites a command in commandsRun that shows the failure: its evidence names a command that ran, or quotes a line of that command's output (16+ characters), and that command exited non-zero or the evidence quotes a line of its output";
17
+ readonly R13: "partial is absent or a boolean; when true, handoff is an object with completed (array of strings), remaining (non-empty array of non-empty strings), next (non-empty string), and verify (non-empty string), and the result is not a pass (verdict is inconclusive)";
18
+ };
19
+ export type RuleId = keyof typeof CONTRACT_RULES;
20
+ export declare const OUTPUT_CITATION_MIN_CHARS = 16;
21
+ /** The commandsRun entries a piece of evidence names: the whole recorded command, the command inside its
22
+ * shell wrapper, or (at OUTPUT_CITATION_MIN_CHARS or more) a quoted line of its recorded output. */
23
+ export declare function citedCommands(evidence: string, commandsRun: {
24
+ command: string;
25
+ exitCode: number | null;
26
+ outputTail?: string;
27
+ }[]): typeof commandsRun;
28
+ /** True when the evidence quotes a line of the command's recorded output at least minChars long (squashed). */
29
+ export declare function quotesOutput(evidence: string, outputTail: string | undefined, minChars?: number): boolean;
30
+ /**
31
+ * R12 for one issue, assumed already known to be a blocker: null when its evidence names a command in
32
+ * commandsRun that exited non-zero or whose output it quotes; otherwise the reason it fails (no index,
33
+ * so a caller wanting "issues[i] <reason>" prepends that itself). Shared by checkReviewResult and
34
+ * enforceBlockerEvidence so the two never drift on what counts as evidence.
35
+ */
36
+ export declare function blockerEvidenceProblem(issue: {
37
+ evidence?: unknown;
38
+ }, commandsRun: {
39
+ command: string;
40
+ exitCode: number | null;
41
+ outputTail?: string;
42
+ }[]): string | null;
43
+ /**
44
+ * R12 enforcement: a blocker whose evidence does not meet blockerEvidenceProblem's bar is downgraded to
45
+ * major rather than silently dropped, its description prefixed so the workflow report carries why, and
46
+ * recorded in the returned result's `downgraded`. A `fail` verdict with no blocker left becomes `pass`
47
+ * (the prompt's own rule); `inconclusive` is never changed. Pure: does not mutate `result`.
48
+ */
49
+ export declare function enforceBlockerEvidence(result: ReviewResult): ReviewResult;
50
+ /**
51
+ * Returns every violated rule as "R<n>: <detail>". Empty means the result conforms.
52
+ * Accepts unknown so a raw JSON object from a future adapter can be checked without a cast.
53
+ */
54
+ export declare function checkReviewResult(value: unknown): string[];
@@ -0,0 +1,305 @@
1
+ // The worker contract as code: every rule in docs/worker-contract.md that can be checked on a result
2
+ // object is checked here, so any adapter (Codex today; Codex-as-implementer, OpenRouter, local models
3
+ // later) is held to the same definition of "diff plus evidence out". The document explains the rules;
4
+ // this file is the test oracle. Keep the rule ids in sync with the document.
5
+ import { SANDBOXES, SEVERITIES, VERDICTS, exitCodeFor } from "./schema.js";
6
+ export const ERROR_KINDS = ["codex-not-found", "codex-failed", "timeout", "no-final-message", "unparseable", "git", "worktree-modified"];
7
+ /** Rule ids, in the order the document lists them. */
8
+ export const CONTRACT_RULES = {
9
+ R1: "verdict is pass | fail | inconclusive; every error is reported as inconclusive",
10
+ R2: "issues are typed: severity in blocker | major | minor, file, non-empty description, optional integer line and string evidence",
11
+ R3: "commandsRun is evidence: each entry has the command, the exit code the runtime observed (or null), and ok that is true only for exit 0",
12
+ R4: "changedFiles is what git computed for base...head: unique, sorted, relative paths",
13
+ R5: "base, head, and dir are non-empty; dir is absolute",
14
+ R6: "the worker names itself: reviewer non-empty, model a string or null, sandbox one of the declared sandboxes",
15
+ R7: "error is null or a typed failure with a kind from the declared list and a non-empty message, plus the kind's own evidence field",
16
+ R8: "measurements are real numbers or null: exit code of the runtime, non-negative duration, token usage",
17
+ R9: "exit codes: 0 no blockers, 1 fail verdict or a blocker issue, 2 could not review (error or inconclusive)",
18
+ R10: "a review that changed the working tree it was reviewing is void: error kind worktree-modified and verdict inconclusive",
19
+ R11: "marker records the nesting guard: name is DOUG_CODEX_REVIEW, passed and inherited are booleans",
20
+ R12: "a blocker cites a command in commandsRun that shows the failure: its evidence names a command that ran, or quotes a line of that command's output (16+ characters), and that command exited non-zero or the evidence quotes a line of its output",
21
+ R13: "partial is absent or a boolean; when true, handoff is an object with completed (array of strings), remaining (non-empty array of non-empty strings), next (non-empty string), and verify (non-empty string), and the result is not a pass (verdict is inconclusive)",
22
+ };
23
+ function isInt(v) {
24
+ return typeof v === "number" && Number.isInteger(v);
25
+ }
26
+ // The shell wrapper the runtime records around a command (`/bin/zsh -lc '<inner>'`), so evidence that names the
27
+ // inner command still matches the entry.
28
+ function innerCommand(command) {
29
+ const m = /^\/bin\/(?:ba|z)?sh\s+-l?c\s+'([\s\S]*)'$/.exec(command.trim());
30
+ return (m ? m[1] : command).trim();
31
+ }
32
+ function squash(s) {
33
+ return s.replace(/\s+/g, " ").trim();
34
+ }
35
+ // The recorded command a reviewer runs can be an unpasteable, hundreds-of-characters shell wrapper (a
36
+ // double-quoted `/bin/zsh -lc "..."` probe, which innerCommand() cannot unwrap); the printed output it
37
+ // produced is what a reviewer actually quotes. quotesOutput's 4-char floor is fine once a command is
38
+ // already named, but as the sole link between evidence and command a 4-char line ("ok 1", "done") would
39
+ // let any blocker cite almost any command, so citing a command by its output alone needs a higher floor.
40
+ export const OUTPUT_CITATION_MIN_CHARS = 16;
41
+ /** The commandsRun entries a piece of evidence names: the whole recorded command, the command inside its
42
+ * shell wrapper, or (at OUTPUT_CITATION_MIN_CHARS or more) a quoted line of its recorded output. */
43
+ export function citedCommands(evidence, commandsRun) {
44
+ const ev = squash(evidence);
45
+ return commandsRun.filter((c) => {
46
+ const whole = squash(c.command);
47
+ const inner = squash(innerCommand(c.command));
48
+ return (whole.length > 0 && ev.includes(whole)) || (inner.length >= 4 && ev.includes(inner)) || quotesOutput(evidence, c.outputTail, OUTPUT_CITATION_MIN_CHARS);
49
+ });
50
+ }
51
+ /** True when the evidence quotes a line of the command's recorded output at least minChars long (squashed). */
52
+ export function quotesOutput(evidence, outputTail, minChars = 4) {
53
+ if (!outputTail)
54
+ return false;
55
+ const ev = squash(evidence);
56
+ return outputTail.split("\n").map((l) => squash(l)).some((l) => l.length >= minChars && ev.includes(l));
57
+ }
58
+ /**
59
+ * R12 for one issue, assumed already known to be a blocker: null when its evidence names a command in
60
+ * commandsRun that exited non-zero or whose output it quotes; otherwise the reason it fails (no index,
61
+ * so a caller wanting "issues[i] <reason>" prepends that itself). Shared by checkReviewResult and
62
+ * enforceBlockerEvidence so the two never drift on what counts as evidence.
63
+ */
64
+ export function blockerEvidenceProblem(issue, commandsRun) {
65
+ const evidence = typeof issue.evidence === "string" ? issue.evidence.trim() : "";
66
+ if (!evidence)
67
+ return "is a blocker with no evidence; a blocker cites a command in commandsRun that shows the failure";
68
+ const cited = citedCommands(evidence, commandsRun);
69
+ if (!cited.length)
70
+ return "is a blocker whose evidence names no command in commandsRun and quotes no line of any command's output; static inspection alone is major at most";
71
+ if (!cited.some((c) => (c.exitCode !== null && c.exitCode !== 0) || quotesOutput(evidence, c.outputTail))) {
72
+ const named = cited.map((c) => `${JSON.stringify(innerCommand(c.command))}, which ${c.exitCode === null ? "did not complete" : "exited 0"}`).join(", ");
73
+ return `cites ${named}, and quotes none of its output`;
74
+ }
75
+ return null;
76
+ }
77
+ /**
78
+ * R12 enforcement: a blocker whose evidence does not meet blockerEvidenceProblem's bar is downgraded to
79
+ * major rather than silently dropped, its description prefixed so the workflow report carries why, and
80
+ * recorded in the returned result's `downgraded`. A `fail` verdict with no blocker left becomes `pass`
81
+ * (the prompt's own rule); `inconclusive` is never changed. Pure: does not mutate `result`.
82
+ */
83
+ export function enforceBlockerEvidence(result) {
84
+ const downgraded = [];
85
+ const issues = result.issues.map((issue, index) => {
86
+ if (issue.severity !== "blocker")
87
+ return issue;
88
+ const reason = blockerEvidenceProblem(issue, result.commandsRun);
89
+ if (!reason)
90
+ return issue;
91
+ downgraded.push({ index, reason });
92
+ return { ...issue, severity: "major", description: `[codex-review: downgraded from blocker, R12: ${reason}] ${issue.description}` };
93
+ });
94
+ const stillBlocked = issues.some((it) => it.severity === "blocker");
95
+ const verdict = result.verdict === "fail" && downgraded.length > 0 && !stillBlocked ? "pass" : result.verdict;
96
+ return { ...result, issues, verdict, ...(downgraded.length ? { downgraded } : {}) };
97
+ }
98
+ function relPath(p) {
99
+ return typeof p === "string" && p.length > 0 && !p.startsWith("/") && !/^[A-Za-z]:[\\/]/.test(p) && !p.split(/[\\/]/).includes("..");
100
+ }
101
+ /**
102
+ * Returns every violated rule as "R<n>: <detail>". Empty means the result conforms.
103
+ * Accepts unknown so a raw JSON object from a future adapter can be checked without a cast.
104
+ */
105
+ export function checkReviewResult(value) {
106
+ const out = [];
107
+ const bad = (rule, detail) => out.push(`${rule}: ${detail}`);
108
+ if (!value || typeof value !== "object" || Array.isArray(value))
109
+ return ["R1: result is not an object"];
110
+ const r = value;
111
+ // R1
112
+ if (!VERDICTS.includes(r.verdict))
113
+ bad("R1", `verdict ${JSON.stringify(r.verdict)} is not one of ${VERDICTS.join(", ")}`);
114
+ if (r.error !== null && r.verdict !== "inconclusive")
115
+ bad("R1", `error is set but verdict is ${JSON.stringify(r.verdict)}, not inconclusive`);
116
+ if (typeof r.summary !== "string")
117
+ bad("R1", "summary must be a string");
118
+ // R2
119
+ if (!Array.isArray(r.issues))
120
+ bad("R2", "issues must be an array");
121
+ else {
122
+ r.issues.forEach((raw, i) => {
123
+ if (!raw || typeof raw !== "object")
124
+ return bad("R2", `issues[${i}] is not an object`);
125
+ const it = raw;
126
+ if (!SEVERITIES.includes(it.severity))
127
+ bad("R2", `issues[${i}].severity ${JSON.stringify(it.severity)} is not one of ${SEVERITIES.join(", ")}`);
128
+ if (typeof it.file !== "string")
129
+ bad("R2", `issues[${i}].file must be a string`);
130
+ if (typeof it.description !== "string" || !it.description.trim())
131
+ bad("R2", `issues[${i}].description must be a non-empty string`);
132
+ if (it.line !== undefined && !isInt(it.line))
133
+ bad("R2", `issues[${i}].line must be an integer when present`);
134
+ if (it.evidence !== undefined && typeof it.evidence !== "string")
135
+ bad("R2", `issues[${i}].evidence must be a string when present`);
136
+ });
137
+ }
138
+ // R3
139
+ if (!Array.isArray(r.commandsRun))
140
+ bad("R3", "commandsRun must be an array");
141
+ else {
142
+ r.commandsRun.forEach((raw, i) => {
143
+ if (!raw || typeof raw !== "object")
144
+ return bad("R3", `commandsRun[${i}] is not an object`);
145
+ const c = raw;
146
+ if (typeof c.command !== "string" || !c.command)
147
+ bad("R3", `commandsRun[${i}].command must be a non-empty string`);
148
+ if (c.exitCode !== null && !isInt(c.exitCode))
149
+ bad("R3", `commandsRun[${i}].exitCode must be an integer or null`);
150
+ if (typeof c.ok !== "boolean")
151
+ bad("R3", `commandsRun[${i}].ok must be a boolean`);
152
+ else if (c.ok !== (c.exitCode === 0))
153
+ bad("R3", `commandsRun[${i}].ok is ${c.ok} but exitCode is ${JSON.stringify(c.exitCode)}`);
154
+ if (c.outputTail !== undefined && typeof c.outputTail !== "string")
155
+ bad("R3", `commandsRun[${i}].outputTail must be a string when present`);
156
+ });
157
+ }
158
+ // R4
159
+ if (!Array.isArray(r.changedFiles))
160
+ bad("R4", "changedFiles must be an array");
161
+ else {
162
+ const files = r.changedFiles;
163
+ files.forEach((f, i) => {
164
+ if (!relPath(f))
165
+ bad("R4", `changedFiles[${i}] ${JSON.stringify(f)} is not a relative path`);
166
+ });
167
+ const strs = files.filter((f) => typeof f === "string");
168
+ if (new Set(strs).size !== strs.length)
169
+ bad("R4", "changedFiles has duplicates");
170
+ if (strs.some((f, i) => i > 0 && f < strs[i - 1]))
171
+ bad("R4", "changedFiles is not sorted");
172
+ }
173
+ // R5
174
+ for (const k of ["base", "head", "dir"])
175
+ if (typeof r[k] !== "string" || !r[k].trim())
176
+ bad("R5", `${k} must be a non-empty string`);
177
+ if (typeof r.dir === "string" && !(r.dir.startsWith("/") || /^[A-Za-z]:[\\/]/.test(r.dir)))
178
+ bad("R5", "dir must be absolute");
179
+ // R6
180
+ if (typeof r.reviewer !== "string" || !r.reviewer)
181
+ bad("R6", "reviewer must be a non-empty string");
182
+ if (r.model !== null && typeof r.model !== "string")
183
+ bad("R6", "model must be a string or null");
184
+ if (!SANDBOXES.includes(r.sandbox))
185
+ bad("R6", `sandbox ${JSON.stringify(r.sandbox)} is not one of ${SANDBOXES.join(", ")}`);
186
+ // R7
187
+ if (r.error !== null) {
188
+ if (!r.error || typeof r.error !== "object")
189
+ bad("R7", "error must be null or an object");
190
+ else {
191
+ const e = r.error;
192
+ if (!ERROR_KINDS.includes(e.kind))
193
+ bad("R7", `error.kind ${JSON.stringify(e.kind)} is not one of ${ERROR_KINDS.join(", ")}`);
194
+ if (typeof e.message !== "string" || !e.message.trim())
195
+ bad("R7", "error.message must be a non-empty string");
196
+ if (e.kind === "codex-failed" && typeof e.stderrTail !== "string")
197
+ bad("R7", "error.stderrTail must be a string for kind codex-failed");
198
+ if (e.kind === "unparseable" && typeof e.raw !== "string")
199
+ bad("R7", "error.raw must be a string for kind unparseable");
200
+ if (e.kind === "worktree-modified" && (!Array.isArray(e.changes) || e.changes.length === 0))
201
+ bad("R7", "error.changes must be a non-empty array for kind worktree-modified");
202
+ }
203
+ }
204
+ // R8
205
+ if (r.codexExitCode !== null && !isInt(r.codexExitCode))
206
+ bad("R8", "codexExitCode must be an integer or null");
207
+ if (!isInt(r.durationMs) || r.durationMs < 0)
208
+ bad("R8", "durationMs must be a non-negative integer");
209
+ if (r.usage !== null) {
210
+ const u = r.usage;
211
+ if (!u || typeof u !== "object" || !isInt(u.inputTokens) || u.inputTokens < 0 || !isInt(u.outputTokens) || u.outputTokens < 0)
212
+ bad("R8", "usage must be null or { inputTokens, outputTokens } with non-negative integers");
213
+ }
214
+ // R12: a blocker is a demonstrated failure. Its evidence names a command the runtime recorded, or quotes a line
215
+ // of that command's output of OUTPUT_CITATION_MIN_CHARS or more, and that command either exited non-zero or the
216
+ // evidence quotes a line of its output. Static inspection alone is major at most.
217
+ if (Array.isArray(r.issues) && Array.isArray(r.commandsRun)) {
218
+ const runs = r.commandsRun.filter((c) => !!c && typeof c === "object" && typeof c.command === "string");
219
+ r.issues.forEach((raw, i) => {
220
+ if (!raw || typeof raw !== "object")
221
+ return;
222
+ const it = raw;
223
+ if (it.severity !== "blocker")
224
+ return;
225
+ const reason = blockerEvidenceProblem(it, runs);
226
+ if (reason)
227
+ bad("R12", `issues[${i}] ${reason}`);
228
+ });
229
+ }
230
+ // R12 (downgraded): when present, every entry is an integer index into issues that points at a major
231
+ // issue, with a non-empty reason. enforceBlockerEvidence (contract.ts) is what produces this field.
232
+ if (r.downgraded !== undefined) {
233
+ if (!Array.isArray(r.downgraded))
234
+ bad("R12", "downgraded must be an array when present");
235
+ else {
236
+ const issues = Array.isArray(r.issues) ? r.issues : [];
237
+ r.downgraded.forEach((raw, i) => {
238
+ if (!raw || typeof raw !== "object")
239
+ return bad("R12", `downgraded[${i}] is not an object`);
240
+ const d = raw;
241
+ if (!isInt(d.index)) {
242
+ bad("R12", `downgraded[${i}].index must be an integer`);
243
+ }
244
+ else {
245
+ const target = issues[d.index];
246
+ if (!target || typeof target !== "object" || target.severity !== "major")
247
+ bad("R12", `downgraded[${i}].index must point at a major issue`);
248
+ }
249
+ if (typeof d.reason !== "string" || !d.reason.trim())
250
+ bad("R12", `downgraded[${i}].reason must be a non-empty string`);
251
+ });
252
+ }
253
+ }
254
+ // R13: partial is graceful degradation, not a pass. A worker (or reviewer) that claims it stopped
255
+ // partway must hand off enough for a fresh worker to pick the remaining work up.
256
+ if (r.partial !== undefined && typeof r.partial !== "boolean")
257
+ bad("R13", "partial must be a boolean when present");
258
+ if (r.partial === true) {
259
+ const h = r.handoff;
260
+ if (!h || typeof h !== "object" || Array.isArray(h)) {
261
+ bad("R13", "handoff must be an object when partial is true");
262
+ }
263
+ else {
264
+ const ho = h;
265
+ if (!Array.isArray(ho.completed) || ho.completed.some((c) => typeof c !== "string"))
266
+ bad("R13", "handoff.completed must be an array of strings");
267
+ if (!Array.isArray(ho.remaining) || ho.remaining.length === 0 || ho.remaining.some((c) => typeof c !== "string" || !c.trim()))
268
+ bad("R13", "handoff.remaining must be a non-empty array of non-empty strings");
269
+ if (typeof ho.next !== "string" || !ho.next.trim())
270
+ bad("R13", "handoff.next must be a non-empty string");
271
+ if (typeof ho.verify !== "string" || !ho.verify.trim())
272
+ bad("R13", "handoff.verify must be a non-empty string");
273
+ }
274
+ if (r.verdict !== "inconclusive")
275
+ bad("R13", "a partial result is not a pass: verdict must be inconclusive");
276
+ }
277
+ // R9 (only meaningful once the shape checks above pass)
278
+ if (out.length === 0) {
279
+ const rr = r;
280
+ const code = exitCodeFor(rr);
281
+ const blocker = rr.issues.some((i) => i.severity === "blocker");
282
+ const expected = rr.error || rr.verdict === "inconclusive" ? 2 : rr.verdict === "fail" || blocker ? 1 : 0;
283
+ if (code !== expected)
284
+ bad("R9", `exit code ${code} for verdict ${rr.verdict}, error ${rr.error ? rr.error.kind : "null"}, blocker ${blocker}; expected ${expected}`);
285
+ }
286
+ // R10
287
+ if (r.error && typeof r.error === "object" && r.error.kind === "worktree-modified" && r.verdict !== "inconclusive") {
288
+ bad("R10", "a worktree-modified review must be inconclusive");
289
+ }
290
+ // R11
291
+ if (!r.marker || typeof r.marker !== "object" || Array.isArray(r.marker)) {
292
+ bad("R11", "marker must be an object");
293
+ }
294
+ else {
295
+ const m = r.marker;
296
+ if (m.name !== "DOUG_CODEX_REVIEW")
297
+ bad("R11", "marker.name must be DOUG_CODEX_REVIEW");
298
+ if (typeof m.passed !== "boolean")
299
+ bad("R11", "marker.passed must be a boolean");
300
+ if (typeof m.inherited !== "boolean")
301
+ bad("R11", "marker.inherited must be a boolean");
302
+ }
303
+ return out;
304
+ }
305
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export interface ChangeFacts {
2
+ changedFiles: string[];
3
+ diff: string;
4
+ diffBytes: number;
5
+ }
6
+ /** `git status --porcelain` lines, sorted, so two snapshots can be compared. Untracked files included. */
7
+ export declare function statusSnapshot(dir: string): string[];
8
+ /**
9
+ * The commit checked out in dir versus the commit `head` names. The reviewer runs commands in dir,
10
+ * so they must be the same tree; otherwise every test it runs exercises the wrong code.
11
+ */
12
+ export declare function checkedOutMismatch(dir: string, head: string): string | null;
13
+ /** Throws with git's own message when a ref does not resolve or dir is not a repository. */
14
+ export declare function changeFacts(dir: string, base: string, head: string): ChangeFacts;