@momentiq/dark-factory-cli 0.1.0-alpha.4
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 +201 -0
- package/README.md +150 -0
- package/dist/adapters/_shared.d.ts +45 -0
- package/dist/adapters/_shared.d.ts.map +1 -0
- package/dist/adapters/_shared.js +200 -0
- package/dist/adapters/_shared.js.map +1 -0
- package/dist/adapters/codex-sdk.d.ts +279 -0
- package/dist/adapters/codex-sdk.d.ts.map +1 -0
- package/dist/adapters/codex-sdk.js +930 -0
- package/dist/adapters/codex-sdk.js.map +1 -0
- package/dist/adapters/critic-result-schema.d.ts +215 -0
- package/dist/adapters/critic-result-schema.d.ts.map +1 -0
- package/dist/adapters/critic-result-schema.js +153 -0
- package/dist/adapters/critic-result-schema.js.map +1 -0
- package/dist/adapters/critic.d.ts +62 -0
- package/dist/adapters/critic.d.ts.map +1 -0
- package/dist/adapters/critic.js +79 -0
- package/dist/adapters/critic.js.map +1 -0
- package/dist/adapters/cursor-sdk.d.ts +153 -0
- package/dist/adapters/cursor-sdk.d.ts.map +1 -0
- package/dist/adapters/cursor-sdk.js +818 -0
- package/dist/adapters/cursor-sdk.js.map +1 -0
- package/dist/adapters/gemini-sdk.d.ts +113 -0
- package/dist/adapters/gemini-sdk.d.ts.map +1 -0
- package/dist/adapters/gemini-sdk.js +532 -0
- package/dist/adapters/gemini-sdk.js.map +1 -0
- package/dist/adapters/grok-direct-sdk.d.ts +148 -0
- package/dist/adapters/grok-direct-sdk.d.ts.map +1 -0
- package/dist/adapters/grok-direct-sdk.js +694 -0
- package/dist/adapters/grok-direct-sdk.js.map +1 -0
- package/dist/branch-protection/audit_branch_protection.py +759 -0
- package/dist/branch-protection/index.d.ts +25 -0
- package/dist/branch-protection/index.d.ts.map +1 -0
- package/dist/branch-protection/index.js +70 -0
- package/dist/branch-protection/index.js.map +1 -0
- package/dist/branch-protection/spec-default.yaml +314 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +581 -0
- package/dist/cli.js.map +1 -0
- package/dist/cycle-doc-validator/index.d.ts +43 -0
- package/dist/cycle-doc-validator/index.d.ts.map +1 -0
- package/dist/cycle-doc-validator/index.js +69 -0
- package/dist/cycle-doc-validator/index.js.map +1 -0
- package/dist/cycle-doc-validator/validate_cycle_doc.py +1260 -0
- package/dist/cycle-tracker-sync/attribute_pr_cycle_ref.py +384 -0
- package/dist/cycle-tracker-sync/index.d.ts +20 -0
- package/dist/cycle-tracker-sync/index.d.ts.map +1 -0
- package/dist/cycle-tracker-sync/index.js +71 -0
- package/dist/cycle-tracker-sync/index.js.map +1 -0
- package/dist/cycle-tracker-sync/sync_cycle_trackers.py +1093 -0
- package/dist/evidence/audit-trail.d.ts +59 -0
- package/dist/evidence/audit-trail.d.ts.map +1 -0
- package/dist/evidence/audit-trail.js +283 -0
- package/dist/evidence/audit-trail.js.map +1 -0
- package/dist/evidence/index.d.ts +4 -0
- package/dist/evidence/index.d.ts.map +1 -0
- package/dist/evidence/index.js +29 -0
- package/dist/evidence/index.js.map +1 -0
- package/dist/evidence/per-sha.d.ts +13 -0
- package/dist/evidence/per-sha.d.ts.map +1 -0
- package/dist/evidence/per-sha.js +97 -0
- package/dist/evidence/per-sha.js.map +1 -0
- package/dist/evidence/quality-gates.d.ts +19 -0
- package/dist/evidence/quality-gates.d.ts.map +1 -0
- package/dist/evidence/quality-gates.js +212 -0
- package/dist/evidence/quality-gates.js.map +1 -0
- package/dist/git.d.ts +40 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +414 -0
- package/dist/git.js.map +1 -0
- package/dist/glob.d.ts +4 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +99 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +42 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy/baseline.d.ts +15 -0
- package/dist/policy/baseline.d.ts.map +1 -0
- package/dist/policy/baseline.js +115 -0
- package/dist/policy/baseline.js.map +1 -0
- package/dist/policy/config.d.ts +64 -0
- package/dist/policy/config.d.ts.map +1 -0
- package/dist/policy/config.js +363 -0
- package/dist/policy/config.js.map +1 -0
- package/dist/policy/gate.d.ts +80 -0
- package/dist/policy/gate.d.ts.map +1 -0
- package/dist/policy/gate.js +1019 -0
- package/dist/policy/gate.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +14 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/merge-queue.d.ts +183 -0
- package/dist/policy/merge-queue.d.ts.map +1 -0
- package/dist/policy/merge-queue.js +310 -0
- package/dist/policy/merge-queue.js.map +1 -0
- package/dist/policy/profile.d.ts +98 -0
- package/dist/policy/profile.d.ts.map +1 -0
- package/dist/policy/profile.js +156 -0
- package/dist/policy/profile.js.map +1 -0
- package/dist/policy/tdd-classifier.d.ts +18 -0
- package/dist/policy/tdd-classifier.d.ts.map +1 -0
- package/dist/policy/tdd-classifier.js +79 -0
- package/dist/policy/tdd-classifier.js.map +1 -0
- package/dist/prompt.d.ts +13 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +175 -0
- package/dist/prompt.js.map +1 -0
- package/dist/report.d.ts +88 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +376 -0
- package/dist/report.js.map +1 -0
- package/dist/runner.d.ts +30 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +456 -0
- package/dist/runner.js.map +1 -0
- package/dist/security.d.ts +2 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +19 -0
- package/dist/security.js.map +1 -0
- package/dist/trusted-surface/rebind.d.ts +10 -0
- package/dist/trusted-surface/rebind.d.ts.map +1 -0
- package/dist/trusted-surface/rebind.js +154 -0
- package/dist/trusted-surface/rebind.js.map +1 -0
- package/package.json +78 -0
package/dist/paths.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { gitCommonDir, gitDir } from "./git.js";
|
|
3
|
+
export async function resolveArtifactRoot(loaded) {
|
|
4
|
+
if (loaded.config.git.artifactScope === "git-common-dir") {
|
|
5
|
+
return gitCommonDir(loaded.repoRoot);
|
|
6
|
+
}
|
|
7
|
+
return gitDir(loaded.repoRoot);
|
|
8
|
+
}
|
|
9
|
+
export async function resolveArtifactDir(loaded) {
|
|
10
|
+
return resolve(await resolveArtifactRoot(loaded), loaded.config.git.artifactDir);
|
|
11
|
+
}
|
|
12
|
+
export function artifactJsonPath(artifactDir, sha) {
|
|
13
|
+
return resolve(artifactDir, `${sha}.json`);
|
|
14
|
+
}
|
|
15
|
+
export function artifactMarkdownPath(artifactDir, sha) {
|
|
16
|
+
return resolve(artifactDir, `${sha}.md`);
|
|
17
|
+
}
|
|
18
|
+
export function artifactLockPath(artifactDir, sha) {
|
|
19
|
+
return resolve(artifactDir, `${sha}.lock`);
|
|
20
|
+
}
|
|
21
|
+
export function diagnosticsDir(artifactDir) {
|
|
22
|
+
return resolve(artifactDir, "diagnostics");
|
|
23
|
+
}
|
|
24
|
+
export function telemetryPath(artifactDir) {
|
|
25
|
+
return resolve(artifactDir, "_runs.ndjson");
|
|
26
|
+
}
|
|
27
|
+
export async function resolveValidationResultPath(loaded) {
|
|
28
|
+
const root = await resolveArtifactRoot(loaded);
|
|
29
|
+
return resolve(root, loaded.config.validation.resultFile);
|
|
30
|
+
}
|
|
31
|
+
// Cycle 332 — per-PR finding-cache directory. Lives under the
|
|
32
|
+
// artifact dir (git-common-dir) so a single worktree can hold caches
|
|
33
|
+
// for multiple PRs simultaneously without collision. The CI runner
|
|
34
|
+
// is the primary writer; the local critic does not touch this path
|
|
35
|
+
// in Phase 2 (Q7 of the cycle doc).
|
|
36
|
+
export function findingCacheDir(artifactDir, prNumber) {
|
|
37
|
+
return resolve(artifactDir, `_pr-${prNumber}`);
|
|
38
|
+
}
|
|
39
|
+
export function findingCachePath(artifactDir, prNumber) {
|
|
40
|
+
return resolve(findingCacheDir(artifactDir, prNumber), "findings.ndjson");
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAoB;IAC5D,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,KAAK,gBAAgB,EAAE,CAAC;QACzD,OAAO,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAoB;IAC3D,OAAO,OAAO,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,GAAW;IAC/D,OAAO,OAAO,CAAC,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,WAAmB,EAAE,GAAW;IACnE,OAAO,OAAO,CAAC,WAAW,EAAE,GAAG,GAAG,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,GAAW;IAC/D,OAAO,OAAO,CAAC,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,OAAO,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,OAAO,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,MAAoB;IACpE,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC5D,CAAC;AAED,8DAA8D;AAC9D,qEAAqE;AACrE,mEAAmE;AACnE,mEAAmE;AACnE,oCAAoC;AACpC,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,QAAgB;IACnE,OAAO,OAAO,CAAC,WAAW,EAAE,OAAO,QAAQ,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,QAAgB;IACpE,OAAO,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type LoadedConfig } from "./config.js";
|
|
2
|
+
export declare const TRUSTED_SCRIPT_PATHS: ReadonlySet<string>;
|
|
3
|
+
export interface PolicyBaseline {
|
|
4
|
+
loaded: LoadedConfig;
|
|
5
|
+
baselineRef?: string;
|
|
6
|
+
triggeredBy: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ResolveBaselineOptions {
|
|
9
|
+
loaded: LoadedConfig;
|
|
10
|
+
sha: string;
|
|
11
|
+
cwd: string;
|
|
12
|
+
warn?: (message: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolvePolicyBaseline(options: ResolveBaselineOptions): Promise<PolicyBaseline>;
|
|
15
|
+
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/policy/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,aAAa,CAAC;AAiCrB,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAYnD,CAAC;AAcH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAC;IAIrB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IAGZ,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAuEzB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { CONFIG_RELATIVE_PATH, loadAgentReviewConfigFromRef, } from "./config.js";
|
|
2
|
+
import { changedFiles, commitParent } from "../git.js";
|
|
3
|
+
// Cycle 318.4 trusted-surface extension.
|
|
4
|
+
//
|
|
5
|
+
// Three different enforcement surfaces have OVERLAPPING-BUT-DIFFERENT
|
|
6
|
+
// concerns and therefore intentionally different path lists:
|
|
7
|
+
//
|
|
8
|
+
// 1. This file (`TRUSTED_SCRIPT_PATHS`) — paths that should trigger
|
|
9
|
+
// the LOCAL critic's self-modification guard (review against
|
|
10
|
+
// parent baseline). Limited to the declarative policy artifacts
|
|
11
|
+
// and the two enforcement scripts + their tests + the three
|
|
12
|
+
// workflows. Build-time files (Makefile, dist/, lockfiles) are
|
|
13
|
+
// excluded because they're not policy code per se.
|
|
14
|
+
//
|
|
15
|
+
// 2. `.github/workflows/branch-protection-audit.yml` "Detect spec-
|
|
16
|
+
// relevant changes" regex — paths that should trigger the LIVE
|
|
17
|
+
// ruleset audit (PR-time). Wider than (1): covers spec.yaml +
|
|
18
|
+
// ANY `.github/workflows/*.{yml,yaml}` (including `*.disabled`
|
|
19
|
+
// renames) + the audit/validator scripts. Broadened in issue
|
|
20
|
+
// #1385 (Codex P1 #1) so that a PR adding `[skip ci]` checks to
|
|
21
|
+
// ANY workflow (e.g. `pr.yml`) cannot bypass the audit.
|
|
22
|
+
//
|
|
23
|
+
// 3. `.github/workflows/agent-critic.yml` "Detect trusted-surface
|
|
24
|
+
// changes" regex — paths that could weaponize the workflow
|
|
25
|
+
// runtime to exfiltrate `CURSOR_API_KEY`. Broader: includes the
|
|
26
|
+
// Makefile, the entire `tools/agent-review/` source tree, and
|
|
27
|
+
// `.husky/` hooks, because any of those run during gate-prepare
|
|
28
|
+
// / review / gate-push with the secret in env.
|
|
29
|
+
//
|
|
30
|
+
// Codex P1 (PR #1380 review) flagged the surfaces as drifting; the
|
|
31
|
+
// drift is intentional. Updates to (1) MUST be considered for (2) and
|
|
32
|
+
// (3) too — but they don't have to match byte-for-byte.
|
|
33
|
+
export const TRUSTED_SCRIPT_PATHS = new Set([
|
|
34
|
+
"tools/branch-protection/spec.yaml",
|
|
35
|
+
"scripts/ci/audit_branch_protection.py",
|
|
36
|
+
"scripts/ci/test_audit_branch_protection.py",
|
|
37
|
+
"scripts/ci/validate_cycle_doc.py",
|
|
38
|
+
"scripts/ci/test_validate_cycle_doc.py",
|
|
39
|
+
// Cycle 318.4 workflow files themselves are merge-boundary policy.
|
|
40
|
+
// A commit that weakens these workflows is a policy change; force the
|
|
41
|
+
// critic baseline reload AND the live ruleset audit on that PR.
|
|
42
|
+
".github/workflows/agent-critic.yml",
|
|
43
|
+
".github/workflows/cycle-doc-validation.yml",
|
|
44
|
+
".github/workflows/branch-protection-audit.yml",
|
|
45
|
+
]);
|
|
46
|
+
export async function resolvePolicyBaseline(options) {
|
|
47
|
+
const { loaded, sha, cwd } = options;
|
|
48
|
+
const warn = options.warn ?? ((m) => process.stderr.write(m));
|
|
49
|
+
let parent;
|
|
50
|
+
try {
|
|
51
|
+
parent = await commitParent(sha, cwd);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return { loaded, triggeredBy: [] };
|
|
55
|
+
}
|
|
56
|
+
if (!parent)
|
|
57
|
+
return { loaded, triggeredBy: [] };
|
|
58
|
+
const files = await changedFiles(parent, sha, cwd, { readContent: false });
|
|
59
|
+
const trustedPaths = new Set([
|
|
60
|
+
CONFIG_RELATIVE_PATH,
|
|
61
|
+
...loaded.config.context.guidanceFiles,
|
|
62
|
+
...loaded.config.context.promptFragments,
|
|
63
|
+
]);
|
|
64
|
+
const triggeredBy = [];
|
|
65
|
+
for (const f of files) {
|
|
66
|
+
if (trustedPaths.has(f.path) || f.path.startsWith(".agent-review/")) {
|
|
67
|
+
triggeredBy.push(f.path);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Cycle 318.4: extend trusted-surface coverage to the branch-protection
|
|
71
|
+
// spec and the two policy-enforcement scripts (and their tests). This
|
|
72
|
+
// set is INTENTIONALLY NARROWER than the workflow regex in
|
|
73
|
+
// `.github/workflows/branch-protection-audit.yml`'s "Detect spec-
|
|
74
|
+
// relevant changes" step — issue #1385 broadened that regex to cover
|
|
75
|
+
// any `.github/workflows/*.{yml,yaml}` while this set still enumerates
|
|
76
|
+
// only the declarative policy artifacts + their enforcement scripts.
|
|
77
|
+
// See the header comment block above for why the two surfaces drift
|
|
78
|
+
// intentionally; the compensating control is that the PR-time live
|
|
79
|
+
// ruleset audit catches workflow edits that don't trigger the local
|
|
80
|
+
// policy-baseline reload.
|
|
81
|
+
if (TRUSTED_SCRIPT_PATHS.has(f.path)) {
|
|
82
|
+
triggeredBy.push(f.path);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (triggeredBy.length === 0)
|
|
86
|
+
return { loaded, triggeredBy: [] };
|
|
87
|
+
// Self-modification detected. Try to load policy from parent.
|
|
88
|
+
let parentLoaded;
|
|
89
|
+
try {
|
|
90
|
+
// Cycle 322.7 Phase C — thread the typo-guard `warn` callback through
|
|
91
|
+
// to the parent-ref load so an operator who mistyped
|
|
92
|
+
// `AGENT_REVIEW_AGGREGATION_POLICY` sees the diagnostic regardless of
|
|
93
|
+
// which load path the run took. Without this, the baseline-reload
|
|
94
|
+
// path would silently swallow the warning (Cursor critic MEDIUM on
|
|
95
|
+
// dce8fd9e).
|
|
96
|
+
parentLoaded = await loadAgentReviewConfigFromRef(loaded.repoRoot, parent, { warn });
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
// Parent has no config (commit introduces it for the first time) —
|
|
100
|
+
// fall back to HEAD policy with a loud warning. Self-modification
|
|
101
|
+
// check is skipped, but the warning makes this visible to operators
|
|
102
|
+
// (and to the artifact, since stderr is captured by the post-commit
|
|
103
|
+
// hook log).
|
|
104
|
+
warn(`agent-review: WARNING — commit ${sha.slice(0, 12)} modifies trusted policy ` +
|
|
105
|
+
`surface (${triggeredBy.join(", ")}) but parent policy is unavailable ` +
|
|
106
|
+
`(${err.message}); falling back to HEAD policy. ` +
|
|
107
|
+
`Self-modification check skipped.\n`);
|
|
108
|
+
return { loaded, triggeredBy };
|
|
109
|
+
}
|
|
110
|
+
warn(`agent-review: commit ${sha.slice(0, 12)} modifies trusted policy surface ` +
|
|
111
|
+
`(${triggeredBy.join(", ")}); reviewing against parent baseline ${parent.slice(0, 12)} ` +
|
|
112
|
+
`to prevent self-modification.\n`);
|
|
113
|
+
return { loaded: parentLoaded, baselineRef: parent, triggeredBy };
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/policy/baseline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type AgentReviewConfig, type AggregationPolicy } from "@momentiq/dark-factory-schemas";
|
|
2
|
+
export declare const CONFIG_RELATIVE_PATH = ".agent-review/config.json";
|
|
3
|
+
export declare const POLICY_OVERRIDE_ENV = "AGENT_REVIEW_AGGREGATION_POLICY";
|
|
4
|
+
export interface LoadedConfig {
|
|
5
|
+
config: AgentReviewConfig;
|
|
6
|
+
repoRoot: string;
|
|
7
|
+
configPath: string;
|
|
8
|
+
loadedFromRef?: string;
|
|
9
|
+
policyOverride?: PolicyOverrideRecord;
|
|
10
|
+
}
|
|
11
|
+
export interface PolicyOverrideRecord {
|
|
12
|
+
configured: AggregationPolicy;
|
|
13
|
+
overridden: AggregationPolicy;
|
|
14
|
+
autoPromotedCritics: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface ApplyEnvOverridesOptions {
|
|
17
|
+
warn?: (message: string) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface ApplyEnvOverridesResult {
|
|
20
|
+
config: AgentReviewConfig;
|
|
21
|
+
applied: boolean;
|
|
22
|
+
configured: AggregationPolicy;
|
|
23
|
+
overridden?: AggregationPolicy;
|
|
24
|
+
autoPromotedCritics: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Apply environment-variable overrides to a loaded config.
|
|
28
|
+
*
|
|
29
|
+
* Cycle 322.7 Phase C — Emergency revert toggle.
|
|
30
|
+
*
|
|
31
|
+
* Reads `AGENT_REVIEW_AGGREGATION_POLICY` from `env`. When set to a
|
|
32
|
+
* recognized AggregationPolicy value, returns a config with
|
|
33
|
+
* `aggregation.policy` stamped to the overridden value. When unset or
|
|
34
|
+
* unrecognized, returns the config unchanged (and warns on the
|
|
35
|
+
* unrecognized path so a typo doesn't silently fall through).
|
|
36
|
+
*
|
|
37
|
+
* Safety invariant — when the override is `block-if-any` AND no critic
|
|
38
|
+
* has `required: true` in the source config, auto-promote
|
|
39
|
+
* `cursor-local-chief-engineer` to `required: true`. Under `block-if-any`,
|
|
40
|
+
* `gate.ts:evaluateCommitGate` only blocks pushes on required critics;
|
|
41
|
+
* the auto-promotion preserves the "single trusted critic gates the
|
|
42
|
+
* push" semantics that operators expect during an emergency revert.
|
|
43
|
+
* This complements the load-time schema validation (which rejects a
|
|
44
|
+
* config with `policy: "block-if-any"` and zero required critics
|
|
45
|
+
* outright) — the runtime auto-promotion is the safety net for the
|
|
46
|
+
* env-override path specifically.
|
|
47
|
+
*
|
|
48
|
+
* Mutation-free: the returned config is a fresh object; the input is
|
|
49
|
+
* never modified. The returned record is suitable for emitting an
|
|
50
|
+
* `aggregation_policy_overridden` telemetry event when `applied: true`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function applyEnvOverrides(config: AgentReviewConfig, env: Record<string, string | undefined>, options?: ApplyEnvOverridesOptions): ApplyEnvOverridesResult;
|
|
53
|
+
export interface LoadConfigOptions {
|
|
54
|
+
cwd?: string;
|
|
55
|
+
validateGuidanceFiles?: boolean;
|
|
56
|
+
env?: Record<string, string | undefined>;
|
|
57
|
+
warn?: (message: string) => void;
|
|
58
|
+
}
|
|
59
|
+
export declare function loadAgentReviewConfig(options?: LoadConfigOptions): Promise<LoadedConfig>;
|
|
60
|
+
export declare function loadAgentReviewConfigFromRef(rootDir: string, ref: string, options?: {
|
|
61
|
+
env?: Record<string, string | undefined>;
|
|
62
|
+
warn?: (message: string) => void;
|
|
63
|
+
}): Promise<LoadedConfig>;
|
|
64
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/policy/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAC;AAExC,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAchE,eAAO,MAAM,mBAAmB,oCAAoC,CAAC;AAWrE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IAKnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAKvB,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAMD,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IAMvC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IAGtC,MAAM,EAAE,iBAAiB,CAAC;IAE1B,OAAO,EAAE,OAAO,CAAC;IAEjB,UAAU,EAAE,iBAAiB,CAAC;IAE9B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAK/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CA8NzB;AAMD,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAMhC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAKzC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAoDvB;AAWD,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GAC3F,OAAO,CAAC,YAAY,CAAC,CAkCvB"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { gitShowFile, repoRoot } from "../git.js";
|
|
4
|
+
import { AGGREGATION_POLICIES, parseAgentReviewConfig, } from "@momentiq/dark-factory-schemas";
|
|
5
|
+
export const CONFIG_RELATIVE_PATH = ".agent-review/config.json";
|
|
6
|
+
// Cycle 322.7 Phase C — Emergency revert env var. When set to a
|
|
7
|
+
// recognized AggregationPolicy value (`block-if-any` or
|
|
8
|
+
// `min-complete-quorum`), the config-load path overrides
|
|
9
|
+
// `aggregation.policy` at runtime so operators can revert the live
|
|
10
|
+
// policy WITHOUT shipping a new PR.
|
|
11
|
+
//
|
|
12
|
+
// Primary use case: a newly-added critic generates spurious blockers
|
|
13
|
+
// in the first 48h post-policy-flip; the team needs to roll back to
|
|
14
|
+
// the previous policy immediately. Setting this env var in the shell
|
|
15
|
+
// (or as part of a single `git push` invocation) accomplishes the
|
|
16
|
+
// revert; subsequent telemetry events surface the override as an
|
|
17
|
+
// `aggregation_policy_overridden` event for audit traceability.
|
|
18
|
+
export const POLICY_OVERRIDE_ENV = "AGENT_REVIEW_AGGREGATION_POLICY";
|
|
19
|
+
// Critic id that gets auto-promoted to `required: true` when the env
|
|
20
|
+
// override flips policy to `block-if-any` AND the source config has
|
|
21
|
+
// zero required critics. The historically-trusted critic (single
|
|
22
|
+
// blocker since the pre-multi-critic days) is the cleanest restoration
|
|
23
|
+
// of the "single trusted critic gates the push" semantics operators
|
|
24
|
+
// expect during an emergency revert. Documented in CONTRIBUTING.md
|
|
25
|
+
// "Reverting the agent-review aggregation policy (emergency)".
|
|
26
|
+
const AUTO_PROMOTE_CRITIC_ID = "cursor-local-chief-engineer";
|
|
27
|
+
/**
|
|
28
|
+
* Apply environment-variable overrides to a loaded config.
|
|
29
|
+
*
|
|
30
|
+
* Cycle 322.7 Phase C — Emergency revert toggle.
|
|
31
|
+
*
|
|
32
|
+
* Reads `AGENT_REVIEW_AGGREGATION_POLICY` from `env`. When set to a
|
|
33
|
+
* recognized AggregationPolicy value, returns a config with
|
|
34
|
+
* `aggregation.policy` stamped to the overridden value. When unset or
|
|
35
|
+
* unrecognized, returns the config unchanged (and warns on the
|
|
36
|
+
* unrecognized path so a typo doesn't silently fall through).
|
|
37
|
+
*
|
|
38
|
+
* Safety invariant — when the override is `block-if-any` AND no critic
|
|
39
|
+
* has `required: true` in the source config, auto-promote
|
|
40
|
+
* `cursor-local-chief-engineer` to `required: true`. Under `block-if-any`,
|
|
41
|
+
* `gate.ts:evaluateCommitGate` only blocks pushes on required critics;
|
|
42
|
+
* the auto-promotion preserves the "single trusted critic gates the
|
|
43
|
+
* push" semantics that operators expect during an emergency revert.
|
|
44
|
+
* This complements the load-time schema validation (which rejects a
|
|
45
|
+
* config with `policy: "block-if-any"` and zero required critics
|
|
46
|
+
* outright) — the runtime auto-promotion is the safety net for the
|
|
47
|
+
* env-override path specifically.
|
|
48
|
+
*
|
|
49
|
+
* Mutation-free: the returned config is a fresh object; the input is
|
|
50
|
+
* never modified. The returned record is suitable for emitting an
|
|
51
|
+
* `aggregation_policy_overridden` telemetry event when `applied: true`.
|
|
52
|
+
*/
|
|
53
|
+
export function applyEnvOverrides(config, env, options = {}) {
|
|
54
|
+
const configured = config.aggregation.policy;
|
|
55
|
+
const raw = env[POLICY_OVERRIDE_ENV];
|
|
56
|
+
// Unset OR empty-string: silent fall-through. Empty string is the
|
|
57
|
+
// "unset" sentinel in many shell pipelines (e.g., `VAR=${X:-} make`
|
|
58
|
+
// patterns) so we deliberately do NOT warn — that would create noise
|
|
59
|
+
// on every invocation that propagates env vars from a CI runner.
|
|
60
|
+
if (raw === undefined || raw === "") {
|
|
61
|
+
return {
|
|
62
|
+
config,
|
|
63
|
+
applied: false,
|
|
64
|
+
configured,
|
|
65
|
+
autoPromotedCritics: [],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (!isAggregationPolicy(raw)) {
|
|
69
|
+
// Unrecognized non-empty value: warn so the operator notices the
|
|
70
|
+
// typo, but never throw. The config policy stands (defense in depth
|
|
71
|
+
// against misconfiguration aborting the pre-commit critic).
|
|
72
|
+
if (options.warn) {
|
|
73
|
+
options.warn(`${POLICY_OVERRIDE_ENV}=${raw} is not a recognized aggregation policy; ` +
|
|
74
|
+
`expected one of: ${AGGREGATION_POLICIES.join(", ")}. ` +
|
|
75
|
+
`Falling through to configured policy "${configured}".`);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
config,
|
|
79
|
+
applied: false,
|
|
80
|
+
configured,
|
|
81
|
+
autoPromotedCritics: [],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Recognized override — apply it. Build the new critic list first
|
|
85
|
+
// so the resulting config is fully consistent.
|
|
86
|
+
const autoPromotedCritics = [];
|
|
87
|
+
let critics = config.critics;
|
|
88
|
+
if (raw === "block-if-any") {
|
|
89
|
+
// Safety invariant: under block-if-any, the gate only blocks pushes
|
|
90
|
+
// on `required: true` critics. Two ways the override path could
|
|
91
|
+
// produce an unsafe runtime:
|
|
92
|
+
//
|
|
93
|
+
// (a) FULL critic list has zero required critics → gate sees
|
|
94
|
+
// only optional critics in the artifact → blocker findings
|
|
95
|
+
// silently demote to warnings.
|
|
96
|
+
//
|
|
97
|
+
// (b) FULL list HAS a required critic, but the ACTIVE PROFILE
|
|
98
|
+
// narrows critics to an all-optional subset → same outcome
|
|
99
|
+
// in the profile-filtered runtime view. Schema validation
|
|
100
|
+
// (schema.ts:931-965) catches this for the on-disk
|
|
101
|
+
// `block-if-any` shape, but the env-override path needs its
|
|
102
|
+
// own runtime guarantee because the on-disk policy may be
|
|
103
|
+
// `min-complete-quorum` (which has no profile invariant) at
|
|
104
|
+
// the time of override.
|
|
105
|
+
//
|
|
106
|
+
// Handle (a) by auto-promoting `cursor-local-chief-engineer` (the
|
|
107
|
+
// historically-trusted critic) in the full list. Handle (b) by
|
|
108
|
+
// additionally promoting one critic per all-optional profile so
|
|
109
|
+
// every profile carries at least one required critic. The promoted
|
|
110
|
+
// ids surface in the `aggregation_policy_overridden` telemetry
|
|
111
|
+
// event's `autoPromotedCritics` array — that's the audit trail
|
|
112
|
+
// operators grep `_runs.ndjson` for (CONTRIBUTING.md "Audit trail"
|
|
113
|
+
// section). The stderr `warn` callback fires only on the
|
|
114
|
+
// REFUSED-fail-closed and unrecognized-value paths; successful
|
|
115
|
+
// promotions are observable in telemetry, not stderr (avoiding
|
|
116
|
+
// noise on every push when the override is the normal path).
|
|
117
|
+
// (Codex finding on 7e780bd3 / security §11 is closed by the
|
|
118
|
+
// promotion logic; visibility is via telemetry, not stderr.)
|
|
119
|
+
if (!critics.some((c) => c.required)) {
|
|
120
|
+
critics = critics.map((c) => c.id === AUTO_PROMOTE_CRITIC_ID ? { ...c, required: true } : c);
|
|
121
|
+
if (critics.some((c) => c.id === AUTO_PROMOTE_CRITIC_ID && c.required)) {
|
|
122
|
+
autoPromotedCritics.push(AUTO_PROMOTE_CRITIC_ID);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Profile coverage check — required for the case where the on-disk
|
|
126
|
+
// config has a required critic OUTSIDE the active-profile set, or
|
|
127
|
+
// where cursor (the auto-promotion target) isn't in every profile.
|
|
128
|
+
if (config.profiles) {
|
|
129
|
+
const requiredIds = new Set(critics.filter((c) => c.required).map((c) => c.id));
|
|
130
|
+
// Sort profile names for deterministic auto-promotion order
|
|
131
|
+
// (mirrors schema.ts:947 sort for determinism in error messages).
|
|
132
|
+
const profileNames = Object.keys(config.profiles).sort();
|
|
133
|
+
for (const name of profileNames) {
|
|
134
|
+
const profile = config.profiles[name];
|
|
135
|
+
const hasRequired = profile.criticIds.some((id) => requiredIds.has(id));
|
|
136
|
+
if (!hasRequired) {
|
|
137
|
+
// Promote the FIRST critic in the profile's `criticIds` list.
|
|
138
|
+
// The profile author defined this ordering; respecting it is
|
|
139
|
+
// less surprising than picking alphabetically or by adapter.
|
|
140
|
+
const promoteTarget = profile.criticIds[0];
|
|
141
|
+
if (promoteTarget !== undefined) {
|
|
142
|
+
critics = critics.map((c) => c.id === promoteTarget ? { ...c, required: true } : c);
|
|
143
|
+
if (!autoPromotedCritics.includes(promoteTarget)) {
|
|
144
|
+
autoPromotedCritics.push(promoteTarget);
|
|
145
|
+
}
|
|
146
|
+
requiredIds.add(promoteTarget);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// FAIL-CLOSED CHECK — Codex critic HIGH on 33dcb1b9 (security §0).
|
|
152
|
+
//
|
|
153
|
+
// If the override would result in a `block-if-any` config with ZERO
|
|
154
|
+
// required critics (neither the hard-coded cursor target nor any
|
|
155
|
+
// profile-first critic was promotable), refuse the override outright.
|
|
156
|
+
// Without this, the gate would silently downgrade blocker findings
|
|
157
|
+
// to warnings — the exact unsafe runtime state the auto-promotion
|
|
158
|
+
// is meant to prevent. Operators get a clear warning and the on-disk
|
|
159
|
+
// policy stands; they can re-apply after promoting a critic on-disk.
|
|
160
|
+
//
|
|
161
|
+
// This rejection only fires for the no-profiles + no-cursor edge
|
|
162
|
+
// case (the schema's profile-coverage invariant catches the rest at
|
|
163
|
+
// load time). Returning `applied: false` keeps the result type
|
|
164
|
+
// identical to the unset/garbage paths so the caller's audit code
|
|
165
|
+
// doesn't need a new branch.
|
|
166
|
+
if (!critics.some((c) => c.required)) {
|
|
167
|
+
if (options.warn) {
|
|
168
|
+
options.warn(`${POLICY_OVERRIDE_ENV}=block-if-any: REFUSED — no critic could be auto-promoted to required. ` +
|
|
169
|
+
`Neither "${AUTO_PROMOTE_CRITIC_ID}" nor any profile-first critic was available in this config. ` +
|
|
170
|
+
`Under block-if-any with zero required critics, the gate would silently downgrade blocker ` +
|
|
171
|
+
`findings to warnings, defeating the revert's safety purpose. ` +
|
|
172
|
+
`Falling through to configured policy "${configured}". ` +
|
|
173
|
+
`Promote a critic on-disk (set \`required: true\`) before re-applying the revert.`);
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
config,
|
|
177
|
+
applied: false,
|
|
178
|
+
configured,
|
|
179
|
+
autoPromotedCritics: [],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Build the new aggregation block. Schema invariants (per
|
|
184
|
+
// parseAgentReviewConfig):
|
|
185
|
+
// - `block-if-any` REJECTS a `quorum` field (a stale quorum after
|
|
186
|
+
// a policy roll-back would be a silent foot-gun).
|
|
187
|
+
// - `min-complete-quorum` REQUIRES a quorum integer >= 2.
|
|
188
|
+
//
|
|
189
|
+
// To keep the result config round-trippable through the same schema
|
|
190
|
+
// validation, strip `quorum` on `block-if-any` overrides. For
|
|
191
|
+
// `min-complete-quorum` overrides, preserve a pre-existing valid
|
|
192
|
+
// `quorum` OR synthesize one from the critic count when the source
|
|
193
|
+
// config had `block-if-any` shape (no quorum) — refusing the override
|
|
194
|
+
// would be hostile to operators who actually want to PIN
|
|
195
|
+
// min-complete-quorum during a calibration window. The synthesized
|
|
196
|
+
// value MUST satisfy the schema's `>= 2 && <= critics.length` bounds.
|
|
197
|
+
// (Codex HIGH on c849d47d / schema §0.)
|
|
198
|
+
let newAggregation;
|
|
199
|
+
if (raw === "block-if-any") {
|
|
200
|
+
newAggregation = {
|
|
201
|
+
policy: raw,
|
|
202
|
+
blockingSeverities: config.aggregation.blockingSeverities,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// raw === "min-complete-quorum"
|
|
207
|
+
const sourceQuorum = config.aggregation.quorum;
|
|
208
|
+
const valid = typeof sourceQuorum === "number" &&
|
|
209
|
+
Number.isInteger(sourceQuorum) &&
|
|
210
|
+
sourceQuorum >= 2 &&
|
|
211
|
+
sourceQuorum <= critics.length;
|
|
212
|
+
if (valid) {
|
|
213
|
+
newAggregation = {
|
|
214
|
+
...config.aggregation,
|
|
215
|
+
policy: raw,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else if (critics.length >= 2) {
|
|
219
|
+
// Synthesize a safe quorum: 2 (the schema minimum). The profile
|
|
220
|
+
// selector overrides this at runtime if a profile is active;
|
|
221
|
+
// otherwise the runner uses this for hypothetical-quorum
|
|
222
|
+
// telemetry. Safe per schema: 2 <= critics.length is guaranteed
|
|
223
|
+
// by the branch condition.
|
|
224
|
+
newAggregation = {
|
|
225
|
+
...config.aggregation,
|
|
226
|
+
policy: raw,
|
|
227
|
+
quorum: 2,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
// critics.length < 2 — cannot synthesize a schema-valid quorum.
|
|
232
|
+
// Refuse the override and fall through to configured policy.
|
|
233
|
+
if (options.warn) {
|
|
234
|
+
options.warn(`${POLICY_OVERRIDE_ENV}=min-complete-quorum: REFUSED — cannot synthesize a schema-valid quorum ` +
|
|
235
|
+
`(min-complete-quorum requires quorum >= 2 and <= critics.length, but only ${critics.length} ` +
|
|
236
|
+
`critic(s) are configured). Falling through to configured policy "${configured}". ` +
|
|
237
|
+
`Add a second critic to the config or pin quorum on-disk before re-applying the revert.`);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
config,
|
|
241
|
+
applied: false,
|
|
242
|
+
configured,
|
|
243
|
+
autoPromotedCritics: [],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const newConfig = {
|
|
248
|
+
...config,
|
|
249
|
+
critics,
|
|
250
|
+
aggregation: newAggregation,
|
|
251
|
+
};
|
|
252
|
+
return {
|
|
253
|
+
config: newConfig,
|
|
254
|
+
applied: true,
|
|
255
|
+
configured,
|
|
256
|
+
overridden: raw,
|
|
257
|
+
autoPromotedCritics,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function isAggregationPolicy(s) {
|
|
261
|
+
return AGGREGATION_POLICIES.includes(s);
|
|
262
|
+
}
|
|
263
|
+
export async function loadAgentReviewConfig(options = {}) {
|
|
264
|
+
const root = await repoRoot(options.cwd ?? process.cwd());
|
|
265
|
+
const configPath = resolve(root, CONFIG_RELATIVE_PATH);
|
|
266
|
+
if (!existsSync(configPath)) {
|
|
267
|
+
throw new Error(`agent-review config not found at ${configPath}. ` +
|
|
268
|
+
"Run from a repository that contains .agent-review/config.json or copy the template.");
|
|
269
|
+
}
|
|
270
|
+
const raw = readFileSync(configPath, "utf8");
|
|
271
|
+
const parsedConfig = parseConfigJson(raw, configPath);
|
|
272
|
+
if (options.validateGuidanceFiles ?? true) {
|
|
273
|
+
const missing = [];
|
|
274
|
+
for (const rel of parsedConfig.context.guidanceFiles) {
|
|
275
|
+
if (!existsSync(resolve(root, rel)))
|
|
276
|
+
missing.push(rel);
|
|
277
|
+
}
|
|
278
|
+
for (const rel of parsedConfig.context.promptFragments) {
|
|
279
|
+
if (!existsSync(resolve(root, rel)))
|
|
280
|
+
missing.push(rel);
|
|
281
|
+
}
|
|
282
|
+
if (missing.length > 0) {
|
|
283
|
+
throw new Error(`agent-review config references missing guidance files: ${missing.join(", ")}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Cycle 322.7 Phase C — apply env-var overrides AFTER schema parse
|
|
287
|
+
// but BEFORE the runner sees the config. The override path is
|
|
288
|
+
// applied here (not deeper) so all consumers of `LoadedConfig`
|
|
289
|
+
// (runReview, runCommitGate, evals) see the overridden policy
|
|
290
|
+
// automatically without needing to re-thread the env source.
|
|
291
|
+
const overrideResult = applyEnvOverrides(parsedConfig, options.env ?? process.env, {
|
|
292
|
+
...(options.warn !== undefined ? { warn: options.warn } : {}),
|
|
293
|
+
});
|
|
294
|
+
return {
|
|
295
|
+
config: overrideResult.config,
|
|
296
|
+
repoRoot: root,
|
|
297
|
+
configPath,
|
|
298
|
+
...(overrideResult.applied
|
|
299
|
+
? {
|
|
300
|
+
policyOverride: {
|
|
301
|
+
configured: overrideResult.configured,
|
|
302
|
+
// `overridden` is guaranteed-set when applied=true; the
|
|
303
|
+
// type system can't see that, so we assert here.
|
|
304
|
+
overridden: overrideResult.overridden,
|
|
305
|
+
autoPromotedCritics: overrideResult.autoPromotedCritics,
|
|
306
|
+
},
|
|
307
|
+
}
|
|
308
|
+
: {}),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
// Load config from a specific git ref (e.g., the parent of the reviewed
|
|
312
|
+
// commit). Used by the self-modification guard in `runReview`: if the
|
|
313
|
+
// commit being reviewed touches `.agent-review/**`, we refuse to use HEAD's
|
|
314
|
+
// (potentially-weakened) policy and instead review against the prior baseline.
|
|
315
|
+
//
|
|
316
|
+
// Throws if the ref doesn't have the config file, leaving the caller to
|
|
317
|
+
// decide how to handle (typically: fall back to working-tree policy with a
|
|
318
|
+
// loud warning, since the commit is introducing the config for the first
|
|
319
|
+
// time).
|
|
320
|
+
export async function loadAgentReviewConfigFromRef(rootDir, ref, options = {}) {
|
|
321
|
+
const raw = await gitShowFile(ref, CONFIG_RELATIVE_PATH, rootDir);
|
|
322
|
+
if (raw === null) {
|
|
323
|
+
throw new Error(`agent-review config not present at ref ${ref}:${CONFIG_RELATIVE_PATH}`);
|
|
324
|
+
}
|
|
325
|
+
const parsedConfig = parseConfigJson(raw, `${ref}:${CONFIG_RELATIVE_PATH}`);
|
|
326
|
+
// Cycle 322.7 Phase C — env override applies to the policy-baseline
|
|
327
|
+
// path too. The self-modification guard wants to evaluate against
|
|
328
|
+
// the parent ref's config, but the operator's emergency revert
|
|
329
|
+
// still applies: if the env says block-if-any, the parent-ref
|
|
330
|
+
// policy is also stamped to block-if-any. Without this, an operator
|
|
331
|
+
// who reverted to block-if-any via env would see the gate run
|
|
332
|
+
// min-complete-quorum against a baseline that triggered the
|
|
333
|
+
// self-modification guard — inconsistent and confusing.
|
|
334
|
+
const overrideResult = applyEnvOverrides(parsedConfig, options.env ?? process.env, {
|
|
335
|
+
...(options.warn !== undefined ? { warn: options.warn } : {}),
|
|
336
|
+
});
|
|
337
|
+
return {
|
|
338
|
+
config: overrideResult.config,
|
|
339
|
+
repoRoot: rootDir,
|
|
340
|
+
configPath: `${ref}:${CONFIG_RELATIVE_PATH}`,
|
|
341
|
+
loadedFromRef: ref,
|
|
342
|
+
...(overrideResult.applied
|
|
343
|
+
? {
|
|
344
|
+
policyOverride: {
|
|
345
|
+
configured: overrideResult.configured,
|
|
346
|
+
overridden: overrideResult.overridden,
|
|
347
|
+
autoPromotedCritics: overrideResult.autoPromotedCritics,
|
|
348
|
+
},
|
|
349
|
+
}
|
|
350
|
+
: {}),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function parseConfigJson(raw, source) {
|
|
354
|
+
let parsed;
|
|
355
|
+
try {
|
|
356
|
+
parsed = JSON.parse(raw);
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
throw new Error(`agent-review config at ${source} is not valid JSON: ${err.message}`);
|
|
360
|
+
}
|
|
361
|
+
return parseAgentReviewConfig(parsed);
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/policy/config.ts"],"names":[],"mappings":"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"}
|