'use strict'; process.env.MSD_TEST_MODE = '1'; // D3 below reads src/plan-scan.cts / msd-core/bin/lib/plan-scan.cjs and // src/verification.cts and regex-tests them for require/import statements. // This asserts a DEPENDENCY-DIRECTION invariant (the owner consumes plan // counts, never the reverse — ADR-3180 §7.4 HARD CONSTRAINT) that has no // behavioral/runtime surface: `require`-ing plan-scan.cjs in-process cannot // distinguish "verification.cjs is absent from its dependency graph" from // "verification.cjs happens to already be in require.cache because an // earlier test in this same file required it directly" (line 36 above does // exactly that) — only source inspection can tell which import edge exists. // #3186 review finding 6(a). /** * Unit + whole-repo coverage for the PHASE-COMPLETION drift guard * (scripts/lint-completion-predicate-drift.cjs, epic #3180, issue #3186, * ADR-3180 §7.4, Decision 4). Modelled on tests/milestone-window-drift-guard.test.cjs * / tests/completion-ratio-single-owner.test.cjs's guard sections: behavioral * throughout — every assertion drives the guard's exported pure functions * directly, never `readFileSync().includes()`. * * Covers 50-test-matrix.md section E (the guard) plus D3 (the dependency- * direction guard: plan-scan.cts does not import verification.cts). */ const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const drift = require('../scripts/lint-completion-predicate-drift.cjs'); const { sanitizeForReport } = require('../scripts/lib/drift-scan.cjs'); const { createTempDir, cleanup } = require('./helpers.cjs'); const ROOT = path.join(__dirname, '..'); const OWNER_RELPATH = drift.OWNER_FILE; // path.join('src', 'verification.cts') // ═════════════════════════════════════════════════════════════════════════ // E1 — the real repo tree, post-migration: 0 violations, earned per shape. // ═════════════════════════════════════════════════════════════════════════ describe('E1 — scanRepo(repoRoot) against the real repo: earned zero', () => { test('zero violations across the whole scan surface (src/ + prompt layer)', () => { const violations = drift.scanRepo(ROOT); assert.deepStrictEqual( violations, [], 'unsanctioned phase-completion re-derivation(s) — route through src/verification.cts ' + '`isPhaseComplete` (issue #3186, ADR-3180 §7.4):\n' + violations.map((d) => ` ${d.file}:${d.line} [shape ${d.shape}] ${d.found}`).join('\n'), ); }); test('per-shape proof: a deliberate (a)/(b)/(c) fixture is NOT silently swallowed by scanRepo', (t) => { // Distinguishes "0 because nothing to find" from "0 because the detector // is broken" — scanRepo on a synthetic tree carrying all three shapes // must report exactly 3, proving the same code path scanRepo(ROOT) took // is capable of finding violations at all. const root = createTempDir('msd-completion-predicate-drift-'); t.after(() => cleanup(root)); fs.mkdirSync(path.join(root, 'src'), { recursive: true }); fs.writeFileSync( path.join(root, 'src', 'fake.cts'), [ 'function fakeConsumer(roadmapComplete, planCount, summaryCount) {', " let status = 'pending';", ' if (roadmapComplete && status !== \'complete\') {', " status = 'complete';", ' }', ' const verificationStatus = planCount > 0', ' ? readVerificationStatus(phaseDir)', " : { status: 'not_required' };", ' const done = summaryCount >= planCount && planCount > 0;', ' return { status, verificationStatus, done };', '}', ].join('\n'), ); const violations = drift.scanRepo(root); const shapes = violations.map((v) => v.shape).sort(); assert.deepStrictEqual(shapes, ['a', 'b', 'c']); }); }); // ═════════════════════════════════════════════════════════════════════════ // E2 — fixture reintroducing shapes (a), (b), (c): each flagged, one hit // apiece. // ═════════════════════════════════════════════════════════════════════════ describe('E2 — each shape flagged in isolation, exactly one hit apiece', () => { test('shape (a): checkbox-derived completion override', () => { const text = [ 'function fakeConsumer(roadmapComplete) {', " let diskStatus = 'planned';", ' if (roadmapComplete && diskStatus !== \'complete\') {', " diskStatus = 'complete';", ' }', ' return diskStatus;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'a'); }); test('shape (b): plan-count precondition gating a verification read', () => { const text = [ 'function fakeConsumer(planCount, phaseDir) {', ' return planCount > 0', ' ? readVerificationStatus(phaseDir)', " : { status: 'not_required' };", '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'b'); }); test('shape (c): local re-implementation of "complete" from counts', () => { const text = [ 'function fakeConsumer(summaryCount, planCount) {', ' return summaryCount >= planCount && planCount > 0;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'c'); }); test('shape (c): the reversed operand order (planCount <= summaryCount) is also flagged', () => { const text = [ 'function fakeConsumer(summaryCount, planCount) {', ' return planCount <= summaryCount;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'c'); }); }); // ═════════════════════════════════════════════════════════════════════════ // E3 — shape (a) with a nested-paren if-condition: flagged. (The first draft // missed exactly this on cmdInitManager's `(completion.phase_complete || // planCount === 0)` nested group.) // ═════════════════════════════════════════════════════════════════════════ describe('E3 — shape (a): nested-paren if-condition', () => { test('a second parenthesised group inside the if-condition is still detected', () => { const text = [ 'function fakeConsumer(roadmapComplete, completion, planCount) {', " let diskStatus = 'planned';", ' if (roadmapComplete && (completion.phase_complete || planCount === 0) && diskStatus !== \'complete\') {', " diskStatus = 'complete';", ' }', ' return diskStatus;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'a'); }); }); // ═════════════════════════════════════════════════════════════════════════ // E4 — an unconditional readVerificationStatus( call (the cmdPhaseComplete // shape): NOT flagged. // ═════════════════════════════════════════════════════════════════════════ describe('E4 — an unconditional readVerificationStatus( call is not flagged', () => { test('no ternary gate on the call, no count-gate in the function: clean', () => { const text = [ 'function fakeConsumer(phaseDir) {', ' const verificationStatus = readVerificationStatus(phaseDir, { runtime: \'claude\' });', ' return verificationStatus;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.deepStrictEqual(out, []); }); test('a count-gate present elsewhere in the SAME function but the read is unconditional: still clean', () => { // Shape (b) requires the readVerificationStatus( call ITSELF to be // ternary-gated on the same line — a count-gate merely coexisting with // an unconditional call must not fire. const text = [ 'function fakeConsumer(phaseDir, retryCount) {', ' if (retryCount > 0) { /* retry bookkeeping, unrelated */ }', ' const verificationStatus = readVerificationStatus(phaseDir);', ' return verificationStatus;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.deepStrictEqual(out, []); }); }); // ═════════════════════════════════════════════════════════════════════════ // E5 — all three shapes inside `//` and `/* */` comments: NOT flagged. // ═════════════════════════════════════════════════════════════════════════ describe('E5 — commented-out shapes are not flagged', () => { test('shape (a) inside a // line comment', () => { const text = [ "// if (roadmapComplete && diskStatus !== 'complete') diskStatus = 'complete';", ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); test('shape (b) inside a /* */ block comment', () => { const text = [ '/*', ' const v = planCount > 0 ? readVerificationStatus(phaseDir) : { status: "not_required" };', '*/', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); test('shape (c) inside a JSDoc continuation comment', () => { const text = [ '/**', ' * e.g. `summaryCount >= planCount && planCount > 0` is the old shape.', ' */', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); }); // ═════════════════════════════════════════════════════════════════════════ // E6 — retryCount > 0 and other unrelated count gates: NOT flagged. // ═════════════════════════════════════════════════════════════════════════ describe('E6 — unrelated count gates alone are not flagged', () => { test('retryCount > 0 with no readVerificationStatus( call anywhere in the function', () => { const text = [ 'function fakeRetry(retryCount) {', ' if (retryCount > 0) return doRetry();', ' return doOnce();', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); test('itemCount > 0 gating an unrelated ternary (no verification call at all)', () => { const text = [ 'function fakeList(itemCount) {', " return itemCount > 0 ? 'has items' : 'empty';", '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); }); // ═════════════════════════════════════════════════════════════════════════ // E7 — owner file: `isPhaseComplete` exempt BY FUNCTION NAME, never whole-file. // ═════════════════════════════════════════════════════════════════════════ describe('E7 — owner-file exemption is function-scoped, not file-scoped', () => { test('the canonical isPhaseComplete body is exempt in the owner file', () => { const text = [ 'function isPhaseComplete(phaseDir, deps) {', ' const verification = readVerificationStatus(phaseDir, deps);', " return { value: { complete: verification.status === 'passed', verification }, scope: SCOPE.COMPLETE };", '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, OWNER_RELPATH), []); }); test('a differently-named function in the SAME owner file carrying shape (c) IS flagged', () => { const text = [ 'function isPhaseComplete(phaseDir) { return true; }', '', 'function someOtherHelper(summaryCount, planCount) {', ' return summaryCount >= planCount && planCount > 0;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, OWNER_RELPATH); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].fn, 'someOtherHelper'); }); }); // ═════════════════════════════════════════════════════════════════════════ // E8 — a SECOND, unrelated predicate added elsewhere IN THE OWNER FILE: // flagged (the Amendment-4 blind spot — a whole-file exemption on the owner // is precisely how a prior guard's owner grew an invisible second copy). // ═════════════════════════════════════════════════════════════════════════ describe('E8 — a second predicate elsewhere in the owner file is flagged (Amendment-4 blind spot)', () => { test('shape (a) added to a non-canonical function in src/verification.cts is caught', () => { const text = [ 'function isPhaseComplete(phaseDir) { return true; }', '', 'function cmdSomeNewVerb(roadmapComplete) {', " let status = 'pending';", ' if (roadmapComplete && status !== \'complete\') {', " status = 'complete';", ' }', ' return status;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, OWNER_RELPATH); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'a'); assert.strictEqual(out[0].fn, 'cmdSomeNewVerb'); }); }); // ═════════════════════════════════════════════════════════════════════════ // E9 — prompt-layer fixture reintroducing the checkbox OR: flagged (the // scan surface really covers msd-core/workflows, not just src/). // ═════════════════════════════════════════════════════════════════════════ describe('E9 — prompt-layer checkbox-OR re-derivation is flagged', () => { test('findPromptCompletionDrift flags the two-line assign/test pairing', () => { const lines = [ 'PHASE_COMPLETE=$(echo "$PHASE_INFO" | jq -r \'.roadmap_complete // false\')', 'DISK_STATUS=$(echo "$ANALYZE" | jq -r \'.disk_status\')', 'if [[ "$DISK_STATUS" == "complete" || "$PHASE_COMPLETE" == "true" ]]; then', ' STATUS="completed"', 'fi', ].join('\n'); const out = drift.findPromptCompletionDrift(lines, path.join('msd-core', 'workflows', 'fake.md')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'a'); }); test('scanRepo finds the same fixture when it is a real .md file under msd-core/workflows', (t) => { const root = createTempDir('msd-completion-predicate-drift-'); t.after(() => cleanup(root)); fs.mkdirSync(path.join(root, 'msd-core', 'workflows'), { recursive: true }); fs.writeFileSync( path.join(root, 'msd-core', 'workflows', 'fake.md'), [ 'PHASE_COMPLETE=$(echo "$PHASE_INFO" | jq -r \'.roadmap_complete // false\')', 'if [[ "$DISK_STATUS" == "complete" || "$PHASE_COMPLETE" == "true" ]]; then', ' STATUS="completed"', 'fi', ].join('\n'), ); const violations = drift.scanRepo(root); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].shape, 'a'); }); test('a DISK_STATUS-only check (no checkbox OR) is not flagged', () => { const lines = [ 'if [[ "$DISK_STATUS" == "complete" ]]; then', ' STATUS="completed"', 'fi', ].join('\n'); assert.deepStrictEqual(drift.findPromptCompletionDrift(lines, path.join('msd-core', 'workflows', 'fake.md')), []); }); }); // ═════════════════════════════════════════════════════════════════════════ // E10 — filename with control bytes / bidi: sanitized in report output. // ═════════════════════════════════════════════════════════════════════════ describe('E10 — sanitizeForReport neutralizes control bytes and bidi overrides', () => { test('a C0 control byte in a violation "found" fragment is escaped, not passed through raw', () => { const raw = 'diskStatus = \x1b[31m\'complete\'\x1b[0m;'; const sanitized = sanitizeForReport(raw); assert.ok(!sanitized.includes('\x1b'), 'raw ESC byte must not survive sanitization'); assert.ok(sanitized.includes('\\x1b'), 'ESC byte must be rendered as a visible \\xNN escape'); }); test('a bidi right-to-left override codepoint in a reported file path is escaped', () => { const raw = 'src/‮evil.cts'; const sanitized = sanitizeForReport(raw); assert.ok(!sanitized.includes('‮'), 'raw RLO codepoint must not survive sanitization'); assert.ok(sanitized.includes('\\u202e'), 'RLO codepoint must be rendered as a visible \\uNNNN escape'); }); }); // ═════════════════════════════════════════════════════════════════════════ // E11 — #3186 review finding 4: two evasion shapes the pre-review guard // produced ZERO hits on, now caught. // ═════════════════════════════════════════════════════════════════════════ describe('E11 — finding 4(a): the BLOCK form of shape (b) is now caught', () => { test('if (planCount > 0) { … readVerificationStatus(…) … } is flagged (was zero hits before)', () => { const text = [ 'function fakeConsumer(planCount, phaseDir) {', ' let verificationStatus = { status: \'not_required\' };', ' if (planCount > 0) {', ' verificationStatus = readVerificationStatus(phaseDir);', ' }', ' return verificationStatus;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'b'); }); test('an unrelated if-block (no count-gate condition) wrapping an unconditional call stays clean', () => { // A generic nested-brace check (not "is this specifically an if-block // whose OWN condition is a count-gate") would false-positive here. const text = [ 'function fakeConsumer(phaseDir, flag) {', ' let verificationStatus = null;', ' if (flag) {', ' verificationStatus = readVerificationStatus(phaseDir);', ' }', ' return verificationStatus;', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); test('a non-conditional wrapper (a callback passed to another function) is NOT treated as gating', () => { // Regression guard for the naive "any brace nesting deeper than the // function's own top level = gated" approach, which false-positived on // cmdPhaseComplete's real `withPlanningLock(cwd, () => { … })` shape: // an UNCONDITIONAL readVerificationStatus( call wrapped only in a // callback, with an unrelated count-gate elsewhere in the function. const text = [ 'function fakeConsumer(phaseDir, retryCount) {', ' if (retryCount > 0) { /* unrelated */ }', ' return withPlanningLock(phaseDir, () => {', ' return readVerificationStatus(phaseDir);', ' });', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); }); describe('E11 — finding 4(b): the algebraic-restatement evasion of shape (c) is now caught', () => { test('summaryCount - planCount >= 0 is flagged (was zero hits before)', () => { const text = [ 'function fakeConsumer(summaryCount, planCount) {', ' return summaryCount - planCount >= 0;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'c'); }); test('the mirrored form planCount - summaryCount <= 0 is also flagged', () => { const text = [ 'function fakeConsumer(summaryCount, planCount) {', ' return planCount - summaryCount <= 0;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'c'); }); test('an unrelated count-difference comparison (not summary/plan) stays clean', () => { const text = [ 'function fakeConsumer(retryCount, maxCount) {', ' return retryCount - maxCount >= 0;', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); }); // ═════════════════════════════════════════════════════════════════════════ // E12 — shape (d): a bare `.completed` read off a `scanPhasePlans(` result, // used as a completion verdict outside the owner (src/plan-scan.cts). The // #3186 remote-matrix finding: cmdStateSync (src/state.cts, now fixed) // destructured `scanPhasePlans(dirPath).completed` directly with no // comparison for shapes (a)/(b)/(c) to catch. // ═════════════════════════════════════════════════════════════════════════ describe('E12 — shape (d): scanPhasePlans(...).completed read as a completion verdict', () => { test('direct chained form: scanPhasePlans(dir).completed is flagged', () => { const text = [ 'function cmdSomeVerb(dirPath) {', ' return scanPhasePlans(dirPath).completed;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); assert.strictEqual(out[0].fn, 'cmdSomeVerb'); }); test('direct chained form with a nested-paren call argument is still flagged (path.join(...) inside the call)', () => { // A naive `[^)]*` regex would stop at path.join(...)'s OWN closing paren // and miss the `.completed` that follows the call's TRUE closing paren — // the real shape most scanPhasePlans( call sites in this tree use. const text = [ 'function cmdSomeVerb(phasesDir, dir) {', ' return scanPhasePlans(path.join(phasesDir, dir)).completed;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); }); test('destructured form: const { completed } = scanPhasePlans(dirPath) is flagged (the exact #3186 cmdStateSync shape)', () => { const text = [ 'function cmdStateSyncLike(dirPath) {', ' const { completed } = scanPhasePlans(dirPath);', ' return completed;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); assert.strictEqual(out[0].fn, 'cmdStateSyncLike'); }); test('destructured renamed-alias form: const { completed: isDone } = scanPhasePlans(dirPath) is flagged', () => { const text = [ 'function cmdSomeVerb(dirPath) {', ' const { completed: isDone } = scanPhasePlans(dirPath);', ' return isDone;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); }); test('indirect form: the call and the .completed read sit on DIFFERENT lines in the SAME function — flagged, proving no line window', () => { const text = [ 'function cmdSomeVerb(dirPath) {', ' const scan = scanPhasePlans(dirPath);', ' const summaryCount = scan.summaryFiles.length;', ' const planCount = scan.planFiles.length;', ' // several unrelated lines of bookkeeping in between', ' const x = summaryCount + planCount;', ' const y = x * 2;', ' return scan.completed;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); assert.strictEqual(out[0].line, 8); }); test('a `.completed` read inside src/plan-scan.cts itself (the owner, exempt function) is NOT flagged', () => { const text = [ 'function scanPhasePlans(phaseDir) {', ' const inner = scanPhasePlans(phaseDir);', ' return { completed: inner.completed, extra: true };', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'plan-scan.cts')), []); }); test('an exempted function is not flagged, but a DIFFERENT function in the SAME file still is (function-scoped, never whole-file)', () => { // OWNER_RELPATH (src/verification.cts) has `isPhaseComplete` exempt in // FUNCTION_SCOPED_EXEMPTIONS — reused here to prove shape (d) shares that // same per-function map rather than a whole-file allowlist. const text = [ 'function isPhaseComplete(phaseDir) {', ' const scan = scanPhasePlans(phaseDir);', ' return scan.completed;', '}', '', 'function cmdSomeNewVerb(phaseDir) {', ' return scanPhasePlans(phaseDir).completed;', '}', ].join('\n'); const out = drift.findCompletionPredicateDrift(text, OWNER_RELPATH); assert.strictEqual(out.length, 1); assert.strictEqual(out[0].shape, 'd'); assert.strictEqual(out[0].fn, 'cmdSomeNewVerb'); }); test('an unrelated .completed property on a non-scanPhasePlans object is NOT flagged', () => { const text = [ 'function cmdSomeVerb(job) {', ' const result = someOtherFunction(job);', ' return result.completed;', '}', ].join('\n'); assert.deepStrictEqual(drift.findCompletionPredicateDrift(text, path.join('src', 'unrelated.cts')), []); }); test('scanRepo against the real repo tree is capable of finding a deliberate shape (d) fixture (not silently swallowed)', (t) => { const root = createTempDir('msd-completion-predicate-drift-'); t.after(() => cleanup(root)); fs.mkdirSync(path.join(root, 'src'), { recursive: true }); fs.writeFileSync( path.join(root, 'src', 'fake-shape-d.cts'), [ 'function cmdSomeVerb(dirPath) {', ' const { completed } = scanPhasePlans(dirPath);', ' return completed;', '}', ].join('\n'), ); const violations = drift.scanRepo(root); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].shape, 'd'); }); }); // ═════════════════════════════════════════════════════════════════════════ // D3 — the 0.x-split over-consolidation guard: plan-scan.cts does NOT // import verification.cts (the owner consumes plan counts, never the // reverse — ADR-3180 §7.4 HARD CONSTRAINT). // ═════════════════════════════════════════════════════════════════════════ describe('D3 — dependency direction: plan-scan.cts does not import verification.cts', () => { test('the compiled plan-scan.cjs source contains no reference to verification.cjs', () => { const compiled = fs.readFileSync(path.join(ROOT, 'msd-core', 'bin', 'lib', 'plan-scan.cjs'), 'utf-8'); // allow-test-rule: structural-regression-guard — D3 reads compiled plan-scan.cjs and regex-tests it for a require() of verification.cjs; asserts a dependency-direction invariant (ADR-3180 §7.4) with no runtime/behavioral surface (see #3186) assert.ok(!/require\(['"]\.\/verification(\.cjs)?['"]\)/.test(compiled), 'plan-scan.cjs must not require verification.cjs'); }); test('the plan-scan.cts source has no import/require of verification.cjs/.cts (a prose comment MENTIONING it, e.g. explaining why a field is not routed through it, is not an import and must not false-positive)', () => { const source = fs.readFileSync(path.join(ROOT, 'src', 'plan-scan.cts'), 'utf-8'); assert.ok( // allow-test-rule: structural-regression-guard — same D3 dependency-direction invariant as above, checked against the .cts source instead of the compiled .cjs (see #3186) !/\b(?:require|import)\s*(?:\(|\{|[A-Za-z_$][\w$]*\s*=)[^;\r\n]*verification\.c(?:j|t)s/.test(source), 'src/plan-scan.cts must not import/require verification.cts/.cjs', ); }); test('src/verification.cts DOES import plan-scan.cjs (the direction that is allowed: owner consumes counts)', () => { // Documents the ALLOWED direction so the pair of assertions above reads // as a genuine one-way constraint, not an accidental total decoupling. const source = fs.readFileSync(path.join(ROOT, 'src', 'verification.cts'), 'utf-8'); // allow-test-rule: structural-regression-guard — documents the ALLOWED direction of the D3 dependency invariant: verification.cts consumes plan-scan.cjs (see #3186) assert.ok(/require\(['"]\.\/plan-scan\.cjs['"]\)/.test(source), 'src/verification.cts is expected to import plan-scan.cjs (for staleness-check summary listing, pre-existing/unrelated to isPhaseComplete)'); }); });