refactor(review): simplify pass over E (reuse, simplification, efficiency)
Quality only, no behaviour change (four cleanup reviewers, one implementer; npm test 2480/0 on the working tree): - threat-model.mjs splitBacked(): the one known_outside backing check of plan-gate (record and bare gate), verdict-gate and review-finalize, with one why-text; the engines' security keys derived from ENGINES; isSecurity. - coordinator-contract: "not a security engine" read from ENGINES (a string engine only), not the code-review literal. - review-rounds owns trailingBlock, findingsBlockSha, isMajor, isBlocker; review-answers imports them (review-rounds still imports nothing from it). prepare keeps the archive bytes it read instead of reading the previous archive again. - engine-compare exports rowIn and payloadEngine; finalize uses them. - plan-gate: one accepted_open builder; the stop-rule check hoisted; one top-level lookup for --record --brief. - security-engine: notFullShas(), runCli's usage flag, readScopeList shared with engine-findings; findReport and reviewRoundSummary module-private; two dead defaults gone. - tests: shared plan-gate harness and threat-model brief helpers; the [CNV] table cases call convertReport in-process, one CLI case per exit path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b94b060035
commit
f820081bdc
18 changed files with 332 additions and 373 deletions
|
|
@ -23,45 +23,18 @@
|
|||
|
||||
import { test } from 'node:test';
|
||||
import { strict as assert } from 'node:assert';
|
||||
import { resolve, join } from 'node:path';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { mkdtempSync, writeFileSync, readFileSync, rmSync, realpathSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { join } from 'node:path';
|
||||
import { writeFileSync, readFileSync, rmSync } from 'node:fs';
|
||||
import {
|
||||
gatePlan, recordVerdict, planHash, operativeText, acceptOpen, extractVerdict, REVIEW_LOG_SECTIONS,
|
||||
gatePlan, recordVerdict, planHash, acceptOpen, extractVerdict, REVIEW_LOG_SECTIONS,
|
||||
} from '../../lib/validators/plan-gate.mjs';
|
||||
import { dedupFindings } from '../../lib/review/plan-review-dedup.mjs';
|
||||
import { buildPlan } from '../helpers/plan-v18-builder.mjs';
|
||||
import { childEnv } from '../helpers/child-env.mjs';
|
||||
import {
|
||||
PATHS, at, baseOf, recorder, dd, keyedFinding as f, R1_CHANGES, editA, runGate as run, lastJson, tempRepo,
|
||||
} from '../helpers/plan-gate-harness.mjs';
|
||||
|
||||
const NOW = '2026-11-08T00:00:00.000Z';
|
||||
const PLAN = resolve('plan.md');
|
||||
const PATHS = [PLAN];
|
||||
|
||||
function at(text, s) {
|
||||
const n = text.split('\n').findIndex(l => l.includes(s)) + 1;
|
||||
assert.ok(n > 0, `the plan holds ${JSON.stringify(s)}`);
|
||||
return n;
|
||||
}
|
||||
const baseOf = t => ({ sha256: planHash(t), text: operativeText(t) });
|
||||
function rec(text, d, opts = {}) {
|
||||
const r = recordVerdict(text, d, { reviewed: planHash(text), planPaths: PATHS, now: NOW, ...opts });
|
||||
assert.equal(r.code, 0, r.message);
|
||||
return r;
|
||||
}
|
||||
function dd({ pc = [], sg = [], pcPrev, sgPrev } = {}) {
|
||||
return dedupFindings([
|
||||
{ agent: 'plan-critic', payload: { findings: pc, ...(pcPrev ? { previous: pcPrev } : {}) } },
|
||||
{ agent: 'scope-guardian', payload: { findings: sg, ...(sgPrev ? { previous: sgPrev } : {}) } },
|
||||
]);
|
||||
}
|
||||
const f = (severity, line, text, rule_key, extra = {}) => ({ file: 'plan.md', line, rule_key, severity, text, ...extra });
|
||||
|
||||
const R2_CHANGES = '- **Changes:** Add `run2()` to `src/mod2.mjs`. (new file)';
|
||||
const R2_EDITED = '- **Changes:** Add `run2()` and its error path to `src/mod2.mjs`. (new file)\n - `run2()` throws on empty input.';
|
||||
const R1_CHANGES = 'Add `run1()`';
|
||||
const editA = t => { assert.ok(t.includes(R2_CHANGES)); return t.replace(R2_CHANGES, R2_EDITED); };
|
||||
const rec = recorder(NOW);
|
||||
|
||||
const B1 = 'The dependency on the parser module is never declared in the manifest list';
|
||||
const B2 = 'A second import chain reaches the CLI without passing through its argument checker';
|
||||
|
|
@ -327,19 +300,9 @@ test('the "Adversarial Pass 2 (v5.1.1 high-effort)" heading is no longer review
|
|||
|
||||
// ---- CLI ------------------------------------------------------------------------------
|
||||
|
||||
const ROOT = join(fileURLToPath(new URL('.', import.meta.url)), '..', '..');
|
||||
const GATE = join(ROOT, 'lib', 'validators', 'plan-gate.mjs');
|
||||
const GIT_CLEAN = { GIT_DIR: undefined, GIT_WORK_TREE: undefined, GIT_INDEX_FILE: undefined };
|
||||
const run = (cwd, args, input) => {
|
||||
const r = spawnSync(process.execPath, [GATE, ...args], { cwd, input, encoding: 'utf-8', env: childEnv(GIT_CLEAN) });
|
||||
return { code: r.status, out: r.stdout, err: r.stderr };
|
||||
};
|
||||
const lastJson = out => JSON.parse(out.split('\n').filter(l => l !== '').at(-1));
|
||||
|
||||
test('CLI: two rounds with a new dep blocker each -> the gate stops with PLAN_GATE_STOP_RULE and a third --record is refused', () => {
|
||||
const dir = realpathSync(mkdtempSync(join(tmpdir(), 'plan-gate-stop-')));
|
||||
const dir = tempRepo('plan-gate-stop-');
|
||||
try {
|
||||
assert.equal(spawnSync('git', ['init', '-q'], { cwd: dir, env: childEnv(GIT_CLEAN) }).status, 0);
|
||||
const p = join(dir, 'plan.md');
|
||||
writeFileSync(p, buildPlan());
|
||||
const round = (payload, extra = []) => run(dir, ['--record', p, '--reviewed', planHash(readFileSync(p, 'utf-8')), ...extra], JSON.stringify(dd(payload)));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue