'use strict'; const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const fc = require('fast-check'); const { MSD_OWNED_ENTRIES, artifactTargets, MAX_DEPTH, resolveLiveConfigRoots, resolveExtraWatchTargets, snapshotLiveConfig, diffLiveConfig, formatViolations, newestMtime, } = require('../scripts/live-config-guard.cjs'); const { cleanup } = require('./helpers.cjs'); function tmpRoot() { return fs.mkdtempSync(path.join(os.tmpdir(), 'live-config-guard-')); } /** Create `n` flat files under a fresh dir; returns [dir, entryCount-including-dir]. */ function treeWithEntries(n) { const dir = tmpRoot(); for (let i = 0; i < n; i++) fs.writeFileSync(path.join(dir, `f${i}`), 'x'); return [dir, n + 1]; // +1: the directory itself is lstat'd and costs budget } describe('#2665: live-config hermeticity guard', () => { test('resolves real runtime config roots via the product resolver', () => { const roots = resolveLiveConfigRoots(); // Guards the guard: an empty set would make every downstream assertion // vacuous, and run-tests.cjs would silently skip the check. assert.ok(roots.length > 5, `expected many runtime config roots, got ${roots.length}`); for (const root of roots) { assert.ok(path.isAbsolute(root), `root must be absolute: ${root}`); } }); test('watches the HOME-derived fallback root, not only the ambient one', () => { // #2665 round 5: the guard resolves env-first, so it sees the AMBIENT root. // A child that blanks CLAUDE_CONFIG_DIR (which is exactly what TEST_ENV_BASE // does) falls back to /.claude instead. Watching only the ambient path // leaves that fallback unwatched -- the escape route this PR closes, one // process deeper. const ambient = tmpRoot(); const fakeHome = tmpRoot(); const saved = process.env.CLAUDE_CONFIG_DIR; try { process.env.CLAUDE_CONFIG_DIR = ambient; const roots = resolveLiveConfigRoots({ os: { homedir: () => fakeHome } }); assert.ok( roots.includes(path.resolve(ambient)), `ambient root missing from ${JSON.stringify(roots)}`, ); assert.ok( roots.includes(path.resolve(path.join(fakeHome, '.claude'))), `HOME-derived fallback root missing from ${JSON.stringify(roots)}`, ); } finally { if (saved === undefined) delete process.env.CLAUDE_CONFIG_DIR; else process.env.CLAUDE_CONFIG_DIR = saved; cleanup(ambient); cleanup(fakeHome); } }); test('a clean run produces no violations', () => { const root = tmpRoot(); try { fs.mkdirSync(path.join(root, 'msd-core', 'bin'), { recursive: true }); fs.writeFileSync(path.join(root, 'msd-core', 'bin', 'x.cjs'), 'x'); const before = snapshotLiveConfig([root]); const after = snapshotLiveConfig([root]); assert.deepStrictEqual(diffLiveConfig(before, after), []); } finally { cleanup(root); } }); test('detects a global install CREATED during the run', () => { const root = tmpRoot(); try { const before = snapshotLiveConfig([root]); // Exactly the Blocker 1 shape: an in-process install(true, …) landing a // full global install in a live config dir that was previously empty. fs.mkdirSync(path.join(root, 'msd-core'), { recursive: true }); fs.writeFileSync(path.join(root, 'msd-file-manifest.json'), '{}'); const violations = diffLiveConfig(before, snapshotLiveConfig([root])); const kinds = Object.fromEntries(violations.map((v) => [path.basename(v.path), v.kind])); assert.strictEqual(kinds['msd-core'], 'created'); assert.strictEqual(kinds['msd-file-manifest.json'], 'created'); } finally { cleanup(root); } }); test('detects an existing install MODIFIED during the run', () => { const root = tmpRoot(); try { const target = path.join(root, 'msd-core', 'bin'); fs.mkdirSync(target, { recursive: true }); const file = path.join(target, 'msd-tools.cjs'); fs.writeFileSync(file, 'original'); const before = snapshotLiveConfig([root]); // mtime resolution is coarse on some filesystems; set it forward explicitly // rather than racing the clock with a sleep. const future = new Date(Date.now() + 10000); fs.writeFileSync(file, 'clobbered'); fs.utimesSync(file, future, future); const violations = diffLiveConfig(before, snapshotLiveConfig([root])); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].kind, 'modified'); assert.strictEqual(path.basename(violations[0].path), 'msd-core'); } finally { cleanup(root); } }); test('ignores non-MSD writes in a shared config root', () => { const root = tmpRoot(); try { const before = snapshotLiveConfig([root]); // A concurrent host-agent session writing its own state must NOT trip the // guard — a guard that cries wolf gets disabled, and then catches nothing. fs.writeFileSync(path.join(root, 'history.jsonl'), '{}'); fs.mkdirSync(path.join(root, 'todos'), { recursive: true }); fs.writeFileSync(path.join(root, 'settings.json'), '{}'); assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([root])), []); } finally { cleanup(root); } }); test('watches exactly the MSD-owned entry set', () => { const root = tmpRoot(); try { const snap = snapshotLiveConfig([root]); const watched = Object.keys(snap).map((p) => path.relative(root, p)).sort(); // Top-level owned entries PLUS the nested paths MSD owns wholesale inside a // shared root; prefixed children contribute nothing in an empty root. const expected = [ ...MSD_OWNED_ENTRIES, ...artifactTargets().owned.map((o) => path.join(...o.split('/'))), ].sort(); assert.deepStrictEqual(watched, expected); } finally { cleanup(root); } }); test('detects a msd-prefixed artifact written into a SHARED dir', () => { const root = tmpRoot(); try { fs.mkdirSync(path.join(root, 'skills'), { recursive: true }); const before = snapshotLiveConfig([root]); // The exact leak the first version of this guard MISSED: a writer that // sandboxed HOME but inherited an ambient CLAUDE_CONFIG_DIR landed // /skills/msd-dev-preferences/SKILL.md, outside the three // top-level MSD entries. fs.mkdirSync(path.join(root, 'skills', 'msd-dev-preferences'), { recursive: true }); fs.writeFileSync(path.join(root, 'skills', 'msd-dev-preferences', 'SKILL.md'), '# x'); const violations = diffLiveConfig(before, snapshotLiveConfig([root])); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].kind, 'created'); assert.strictEqual(path.basename(violations[0].path), 'msd-dev-preferences'); } finally { cleanup(root); } }); test('ignores NON-msd artifacts in a shared dir', () => { const root = tmpRoot(); try { fs.mkdirSync(path.join(root, 'skills'), { recursive: true }); const before = snapshotLiveConfig([root]); // The host agent's own skills must not trip the guard. fs.mkdirSync(path.join(root, 'skills', 'my-personal-skill'), { recursive: true }); fs.writeFileSync(path.join(root, 'skills', 'my-personal-skill', 'SKILL.md'), '# mine'); assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([root])), []); } finally { cleanup(root); } }); test('detects a leaked hook script and the install marker files', () => { // Self-found by re-deriving the census at round 5 rather than by a review // finding. bin/install.js writes hooks/msd-*.js, .msd-source and .msd-profile // into the config ROOT; `hooks` was absent from MSD_PREFIXED_PARENTS and the // two dot-prefixed markers from MSD_OWNED_ENTRIES, so all three leaked past // the guard silently -- the same shape as the skills/msd-dev-preferences miss // that motivated the prefixed-parent scan in the first place. const root = tmpRoot(); try { fs.mkdirSync(path.join(root, 'hooks'), { recursive: true }); const before = snapshotLiveConfig([root]); fs.writeFileSync(path.join(root, 'hooks', 'msd-check-update.js'), '// x'); fs.writeFileSync(path.join(root, '.msd-source'), 'npm'); fs.writeFileSync(path.join(root, '.msd-profile'), 'default'); const created = diffLiveConfig(before, snapshotLiveConfig([root])) .filter((v) => v.kind === 'created') .map((v) => path.basename(v.path)) .sort(); assert.deepStrictEqual(created, ['.msd-profile', '.msd-source', 'msd-check-update.js']); } finally { cleanup(root); } }); test('a NON-msd hook belonging to the host agent is still ignored', () => { // Widening MSD_PREFIXED_PARENTS must not widen ownership: `hooks/` is shared // with the host agent, and a guard that flags its files gets switched off. const root = tmpRoot(); try { fs.mkdirSync(path.join(root, 'hooks'), { recursive: true }); const before = snapshotLiveConfig([root]); fs.writeFileSync(path.join(root, 'hooks', 'my-own-hook.js'), '// mine'); assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([root])), []); } finally { cleanup(root); } }); test('artifact parents are DERIVED from the registry, not hand-listed', () => { // Round 5's adversarial review refuted the completeness claim of the // hand-list: a fixed `msd-` prefix cannot reach artifacts whose layout // declares a different prefix. const { parents, owned } = artifactTargets(); // NB: the derivation walks artifactLayout.global only. for (const p of ['agents', 'commands', 'skills', 'hooks', 'plugins', 'scripts', 'extensions']) { assert.ok(p in parents, `expected derived parent ${p} in ${JSON.stringify(Object.keys(parents))}`); } // A runtime layout may declare the dotted `msd.` prefix; a fixed `msd-` // scan cannot see agents/msd.yaml, which is the defect this derivation closes. assert.ok( parents.agents.includes('msd.'), `agents must carry the 'msd.' prefix; got ${JSON.stringify(parents.agents)}`, ); // Exact MSD filenames only — never the shared directories that contain them. for (const o of ['scripts/fix-slash-commands.cjs', 'hooks/managed-hooks-registry.cjs']) { assert.ok(owned.includes(o), `expected owned nested ${o} in ${JSON.stringify(owned)}`); } for (const shared of ['hooks/lib', 'hooks/package.json', 'scripts/lib', 'scripts/changeset']) { assert.ok(!owned.includes(shared), `${shared} is shared ground and must NOT be watched wholesale`); } }); test('detects leaks a single hardcoded msd- prefix cannot see', () => { const root = tmpRoot(); try { for (const d of ['agents', 'plugins', 'extensions']) { fs.mkdirSync(path.join(root, ...d.split('/')), { recursive: true }); } const before = snapshotLiveConfig([root]); const future = new Date(Date.now() + 10000); // A dotted `msd.` prefix (agents/msd.yaml, extensions/msd.js) is invisible // to a fixed `msd-` scan. const leaks = [ ['agents', 'msd.yaml'], ['extensions', 'msd.js'], ['plugins', 'msd-core.js'], ]; for (const seg of leaks) { const f = path.join(root, ...seg); fs.writeFileSync(f, '// leaked'); fs.utimesSync(f, future, future); fs.utimesSync(path.dirname(f), future, future); } const hit = diffLiveConfig(before, snapshotLiveConfig([root])).map((v) => v.path); for (const expected of ['agents/msd.yaml', 'extensions/msd.js', 'plugins/msd-core.js']) { const abs = path.join(root, ...expected.split('/')); assert.ok(hit.includes(abs), `${expected} leaked undetected; got ${JSON.stringify(hit)}`); } } finally { cleanup(root); } }); test('a user editing their OWN files in a shared dir is not a violation', () => { // The false-positive case a prior commit shipped: hooks/lib, hooks/package.json, // scripts/lib and scripts/changeset were watched WHOLESALE, so touching a // user-authored helper in any of them tripped the guard. The installer itself // preserves foreign files in all four, so they are not MSD's to watch. const root = tmpRoot(); try { for (const d of ['hooks/lib', 'scripts/lib', 'scripts/changeset']) { fs.mkdirSync(path.join(root, ...d.split('/')), { recursive: true }); } const foreign = [ ['hooks', 'package.json'], ['hooks', 'lib', 'user-helper.js'], ['scripts', 'lib', 'user-helper.cjs'], ['scripts', 'changeset', 'user-tool.cjs'], ]; for (const seg of foreign) fs.writeFileSync(path.join(root, ...seg), 'mine'); const before = snapshotLiveConfig([root]); const future = new Date(Date.now() + 10000); for (const seg of foreign) { const f = path.join(root, ...seg); fs.writeFileSync(f, 'mine, edited'); fs.utimesSync(f, future, future); fs.utimesSync(path.dirname(f), future, future); } assert.deepStrictEqual( diffLiveConfig(before, snapshotLiveConfig([root])), [], 'editing user-owned files in a shared dir must not trip the guard', ); } finally { cleanup(root); } }); test('extra watch targets cover the fallback root as well as the ambient one', () => { // The MISSED finding from round 5's review: B3 closed this for the registry // roots and left the identical hole in resolveExtraWatchTargets. const targets = resolveExtraWatchTargets({ env: { MSD_HOME: '/ambient-msd-home' }, os: { homedir: () => '/fallback-home' }, }); assert.ok(targets.includes(path.resolve('/ambient-msd-home/.msd')), 'ambient $MSD_HOME/.msd'); assert.ok(targets.includes(path.resolve('/fallback-home/.msd')), 'HOME-derived .msd fallback'); }); test('detects a DELETED top-level MSD entry', () => { const root = tmpRoot(); try { // A fixed owned entry is recorded at BOTH ends whether or not it exists, // so a deletion reads {exists:true} -> {exists:false}. Before the union // walk that pair matched no branch at all and the run passed silently. fs.mkdirSync(path.join(root, 'msd-core'), { recursive: true }); fs.writeFileSync(path.join(root, 'msd-core', 'x'), 'x'); const before = snapshotLiveConfig([root]); cleanup(path.join(root, 'msd-core')); const violations = diffLiveConfig(before, snapshotLiveConfig([root])); const deleted = violations.filter((v) => v.kind === 'deleted'); assert.strictEqual(deleted.length, 1, JSON.stringify(violations)); assert.strictEqual(path.basename(deleted[0].path), 'msd-core'); } finally { cleanup(root); } }); test('detects a DELETED msd-prefixed child of a shared dir', () => { const root = tmpRoot(); try { // The shape a `pre.exists && !post.exists` branch cannot reach on its own: // prefixed children are DISCOVERED by readdir, so a deleted one is absent // from the `after` snapshot entirely and never enters an after-keyed loop. fs.mkdirSync(path.join(root, 'skills', 'msd-dev-preferences'), { recursive: true }); fs.writeFileSync(path.join(root, 'skills', 'msd-dev-preferences', 'SKILL.md'), '# x'); const before = snapshotLiveConfig([root]); cleanup(path.join(root, 'skills', 'msd-dev-preferences')); const violations = diffLiveConfig(before, snapshotLiveConfig([root])); const deleted = violations.filter((v) => v.kind === 'deleted'); assert.strictEqual(deleted.length, 1, JSON.stringify(violations)); assert.strictEqual(path.basename(deleted[0].path), 'msd-dev-preferences'); } finally { cleanup(root); } }); test('the scan budget is PER TARGET, so one big tree cannot cascade unverified', () => { // #2665 round 5: with a single running budget, target A exhausting it made // target B report `truncated` -> `unverified` -- a strict-mode FAILURE caused // by an unrelated directory. Each target now gets its own allotment. const [big] = treeWithEntries(8); const [small] = treeWithEntries(2); try { const snap = snapshotLiveConfig([], [big, small], { perTarget: 9, total: 1000 }); assert.strictEqual(snap[path.resolve(big)].truncated, false, 'big target should fit its own budget'); assert.strictEqual( snap[path.resolve(small)].truncated, false, 'small target must NOT inherit exhaustion from a target scanned before it', ); } finally { cleanup(big); cleanup(small); } }); test('the truncation verdict does not depend on target ORDER (below the global ceiling)', () => { const [big] = treeWithEntries(8); const [small] = treeWithEntries(2); try { const limits = { perTarget: 9, total: 1000 }; const a = snapshotLiveConfig([], [big, small], limits); const b = snapshotLiveConfig([], [small, big], limits); assert.strictEqual(a[path.resolve(small)].truncated, b[path.resolve(small)].truncated); assert.strictEqual(a[path.resolve(big)].truncated, b[path.resolve(big)].truncated); } finally { cleanup(big); cleanup(small); } }); test('a non-finite injected limit falls back to the real bound, never fails open', () => { // Math.max(0, NaN) is NaN, and every budget comparison against NaN is false, // so the walk becomes unbounded — the one thing the bound exists to prevent. // The discriminator has to be a case where the two behaviours DIFFER: pair a // NaN perTarget with a small finite ceiling. Fixed, perTarget falls back to // MAX_ENTRIES and the ceiling still bites (truncated). Broken, min(NaN, 3) is // NaN and nothing truncates at all. const [dir] = treeWithEntries(6); try { const snap = snapshotLiveConfig([], [dir], { perTarget: NaN, total: 3 }); assert.strictEqual( snap[path.resolve(dir)].truncated, true, 'a NaN perTarget must fall back to a real bound, not disable budgeting', ); } finally { cleanup(dir); } }); test('the GLOBAL ceiling still bounds the aggregate, and reports unverified', () => { // The bound the single budget was really for is kept -- but when it engages, // the curtailed target is reported rather than silently attested clean. const [a] = treeWithEntries(5); const [b] = treeWithEntries(5); try { const snap = snapshotLiveConfig([], [a, b], { perTarget: 6, total: 6 }); assert.strictEqual(snap[path.resolve(a)].truncated, false); assert.strictEqual(snap[path.resolve(b)].truncated, true, 'ceiling-curtailed target must be truncated'); const violations = diffLiveConfig(snap, snap); assert.ok( violations.some((v) => v.kind === 'unverified' && v.path === path.resolve(b)), `expected an unverified violation for the curtailed target: ${JSON.stringify(violations)}`, ); } finally { cleanup(a); cleanup(b); } }); test('the report names the path and the remedy', () => { const out = formatViolations([{ path: '/live/.claude/msd-core', kind: 'created' }]); assert.match(out, /HERMETICITY WARNING/); assert.match(out, /\/live\/\.claude\/msd-core/); assert.match(out, /scrubConfigLocationEnv/); assert.match(out, /MSD_SKIP_LIVE_CONFIG_GUARD/); assert.match(out, /MSD_STRICT_LIVE_CONFIG_GUARD/); }); }); // ── Round 3: the write surfaces that are not runtime config ROOTS ─────────── describe('#2665: guard watches non-root write surfaces', () => { test('resolveExtraWatchTargets covers $MSD_HOME/.msd', () => { const home = tmpRoot(); try { const targets = resolveExtraWatchTargets({ env: { MSD_HOME: home }, os: { homedir: () => home }, }); assert.ok( targets.includes(path.resolve(path.join(home, '.msd'))), `expected $MSD_HOME/.msd in ${JSON.stringify(targets)}`, ); } finally { cleanup(home); } }); test('MSD_HOME falls back to homedir when unset', () => { const home = tmpRoot(); try { const targets = resolveExtraWatchTargets({ env: {}, os: { homedir: () => home } }); assert.ok(targets.includes(path.resolve(path.join(home, '.msd')))); } finally { cleanup(home); } }); test('detects a consent/defaults write into $MSD_HOME/.msd', () => { const home = tmpRoot(); try { const target = path.join(home, '.msd'); const before = snapshotLiveConfig([], [target]); // The Blocker-1 shape one family over: an ambient MSD_HOME sends real // consent records and defaults.json into the developer's own store. fs.mkdirSync(target, { recursive: true }); fs.writeFileSync(path.join(target, 'consent.json'), '{}'); const violations = diffLiveConfig(before, snapshotLiveConfig([], [target])); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].kind, 'created'); } finally { cleanup(home); } }); test('NEGATIVE CONTROL: without the extras both leaks are silent', () => { const home = tmpRoot(); try { // This is the pre-round-3 guard shape — roots only. It is what let a leak // on either variable pass through the PR's own safety net unreported. const before = snapshotLiveConfig([]); fs.mkdirSync(path.join(home, '.msd'), { recursive: true }); fs.writeFileSync(path.join(home, '.msd', 'consent.json'), '{}'); assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([])), []); } finally { cleanup(home); } }); test('a whole-dir extra target does not watch unrelated siblings', () => { const home = tmpRoot(); try { const target = path.join(home, '.msd'); fs.mkdirSync(target, { recursive: true }); const before = snapshotLiveConfig([], [target]); // A sibling of .msd is outside the watched target entirely. fs.writeFileSync(path.join(home, 'unrelated.json'), '{}'); assert.deepStrictEqual(diffLiveConfig(before, snapshotLiveConfig([], [target])), []); } finally { cleanup(home); } }); }); // ── Round 3: the truncation budget — the module's own safety-critical case ─── describe('#2665: scan-budget truncation', () => { test('boundary: limit-1 truncates, limit and limit+1 do not', () => { const [dir, entries] = treeWithEntries(24); try { // RULESET.TESTS.boundary-coverage: N in {limit-1, limit, limit+1}. The // budget is injected, so the boundary is exercised at a real threshold // without materialising MAX_ENTRIES files. assert.strictEqual( newestMtime(dir, { remaining: entries - 1 }).truncated, true, 'one entry short of the tree size MUST truncate', ); assert.strictEqual( newestMtime(dir, { remaining: entries }).truncated, false, 'a budget exactly equal to the tree size must NOT truncate', ); assert.strictEqual( newestMtime(dir, { remaining: entries + 1 }).truncated, false, 'a budget above the tree size must NOT truncate', ); } finally { cleanup(dir); } }); // RULESET.TESTS.boundary-coverage asks for {limit-1, limit, limit+1}. This was // exercised only at limit+2, which pins neither side of the edge: an off-by-one // that truncated a legal depth would have passed. `nestedDepth(n)` builds a tree // whose deepest entry sits at walk-depth n below the scanned root, and // newestMtime truncates iff that depth EXCEEDS MAX_DEPTH. const nestedDepth = (n) => { const dir = tmpRoot(); let deep = dir; for (let i = 0; i < n; i++) deep = path.join(deep, `d${i}`); fs.mkdirSync(deep, { recursive: true }); return dir; }; test(`MAX_DEPTH boundary: depth ${MAX_DEPTH - 1} (limit-1) does NOT truncate`, () => { const dir = nestedDepth(MAX_DEPTH - 1); try { assert.strictEqual(newestMtime(dir, { remaining: 1e6 }).truncated, false); } finally { cleanup(dir); } }); test(`MAX_DEPTH boundary: depth ${MAX_DEPTH} (limit) does NOT truncate`, () => { const dir = nestedDepth(MAX_DEPTH); try { assert.strictEqual( newestMtime(dir, { remaining: 1e6 }).truncated, false, 'a tree exactly at MAX_DEPTH is within bounds and must be attested', ); } finally { cleanup(dir); } }); test(`MAX_DEPTH boundary: depth ${MAX_DEPTH + 1} (limit+1) truncates`, () => { const dir = nestedDepth(MAX_DEPTH + 1); try { assert.strictEqual( newestMtime(dir, { remaining: 1e6 }).truncated, true, 'a tree deeper than MAX_DEPTH must truncate', ); } finally { cleanup(dir); } }); test('a truncated scan reports UNVERIFIED, never clean', () => { const [dir, entries] = treeWithEntries(10); try { // The safety-critical branch named in this module's own docstring: a scan // that hit a bound must not read as an attestation of cleanliness. const snap = { [dir]: { exists: true, newest: 1, truncated: true } }; const violations = diffLiveConfig(snap, { [dir]: { exists: true, newest: 1, truncated: true }, }); assert.strictEqual(violations.length, 1); assert.strictEqual(violations[0].kind, 'unverified'); assert.match(formatViolations(violations), /UNVERIFIED \(scan bound hit/); assert.ok(entries > 0); } finally { cleanup(dir); } }); test('a modified path outranks unverified (a real leak is never downgraded)', () => { const p = '/live/.claude/msd-core'; const violations = diffLiveConfig( { [p]: { exists: true, newest: 1, truncated: true } }, { [p]: { exists: true, newest: 2, truncated: true } }, ); assert.strictEqual(violations[0].kind, 'modified'); }); test('property: truncation is monotone in the budget (boundary containment)', () => { const [dir, entries] = treeWithEntries(12); try { fc.assert( fc.property(fc.integer({ min: 1, max: entries * 3 }), (budget) => { const { truncated } = newestMtime(dir, { remaining: budget }); // The invariant: a budget at or above the tree size never truncates, // and one below it always does. A regression flipping `truncated` to // false on an exhausted budget — the exact silent-clean failure the // module warns about — breaks this for every budget < entries. return budget >= entries ? truncated === false : truncated === true; }), { numRuns: 100 }, ); } finally { cleanup(dir); } }); test('property: newest mtime never exceeds the true maximum', () => { const [dir, entries] = treeWithEntries(8); try { const trueMax = Math.max( ...fs.readdirSync(dir).map((f) => fs.lstatSync(path.join(dir, f)).mtimeMs), fs.lstatSync(dir).mtimeMs, ); fc.assert( fc.property(fc.integer({ min: 1, max: entries * 2 }), (budget) => { const { newest } = newestMtime(dir, { remaining: budget }); return newest <= trueMax; }), { numRuns: 50 }, ); } finally { cleanup(dir); } }); }); describe('#2665 round 4: CI wires the guard to strict mode', () => { // The reversion this guards: dropping MSD_STRICT_LIVE_CONFIG_GUARD from // test.yml silently demotes the guard back to report-only, and a future // leak of exactly the class #2665 closes prints a warning and CI stays // green. Windows lanes are deliberately report-only until the documented // pre-existing USERPROFILE leak class is swept (SEVERITY note in // scripts/live-config-guard.cjs) — so the assertion is per-OS, not global. test('both guard env vars are documented for humans, not just in the source', () => { // A skip-switch on a safety guard has to be discoverable: an undocumented // bypass is one people eventually set without knowing what they turned off. // The Docs Required gate gets satisfied by ANY docs/ file in the diff -- // including a generated index -- so it cannot stand in for this. const doc = fs.readFileSync(path.join(__dirname, '..', 'docs', 'TESTING-SUITES.md'), 'utf8'); for (const v of ['MSD_STRICT_LIVE_CONFIG_GUARD', 'MSD_SKIP_LIVE_CONFIG_GUARD']) { assert.ok(doc.includes(v), `${v} must be documented in docs/TESTING-SUITES.md`); } }); // DERIVED, not hand-listed. The previous version named three jobs as literals, // so it could not see a FOURTH lane that runs the suite — and there was one: // qa-loop-walk reaches run-tests.cjs through `npm run test:qa` and escaped // strict mode entirely while this test stayed green. A hand-list that certifies // its own completeness is the exact defect this PR exists to fix, reproduced in // the test that guards the fix. test('EVERY job that runs the suite wires MSD_STRICT_LIVE_CONFIG_GUARD', () => { const yaml = require('js-yaml'); const root = path.join(__dirname, '..'); const wf = yaml.load(fs.readFileSync(path.join(root, '.github', 'workflows', 'test.yml'), 'utf8')); const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')); // A step reaches the runner directly OR through an npm script, transitively. // Grepping the filename alone misses the indirection that hid qa-loop-walk. const scriptRunsSuite = (name, seen = new Set()) => { if (seen.has(name)) return false; seen.add(name); const body = pkg.scripts?.[name]; if (!body) return false; if (/run-tests\.cjs/.test(body)) return true; return [...body.matchAll(/npm run ([\w:.-]+)/g)].some((m) => scriptRunsSuite(m[1], seen)); }; const runsSuite = (run) => /run-tests\.cjs/.test(run) || [...run.matchAll(/npm run ([\w:.-]+)/g)].some((m) => scriptRunsSuite(m[1])); const suiteJobs = Object.entries(wf.jobs ?? {}) .filter(([, job]) => (job?.steps ?? []).some((s) => typeof s?.run === 'string' && runsSuite(s.run))) .map(([name]) => name) .sort(); // Guards the guard: an empty derivation would make every assertion below // vacuously true, which is the failure mode of the literal list it replaces. assert.ok( suiteJobs.length >= 4, `expected at least 4 suite-running jobs, derived ${JSON.stringify(suiteJobs)}`, ); const windowsMatrix = (job) => JSON.stringify(job?.strategy?.matrix ?? {}).includes('windows'); const problems = []; for (const name of suiteJobs) { const job = wf.jobs[name]; const v = String(job?.env?.MSD_STRICT_LIVE_CONFIG_GUARD ?? ''); // Windows lanes stay report-only until the pre-existing USERPROFILE leak // class is swept (SEVERITY note in scripts/live-config-guard.cjs), so a // job whose matrix includes Windows carries the conditional; an // ubuntu/macOS-only lane must be strict outright. const ok = windowsMatrix(job) // The WHOLE expression, anchored — a prefix match accepted both // `&& '1' || '1'` (Windows silently strict) and a malformed tail. ? /^\$\{\{\s*matrix\.os\s*!=\s*'windows-latest'\s*&&\s*'1'\s*\|\|\s*''\s*\}\}$/.test(v) : v === '1'; if (!ok) problems.push(`jobs.${name}: ${JSON.stringify(v)}`); } assert.deepStrictEqual( problems, [], `every job running run-tests.cjs must wire the guard to strict mode ` + `(Windows matrices carved out). Derived jobs: ${JSON.stringify(suiteJobs)}`, ); }); });