Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
257 lines
11 KiB
JavaScript
257 lines
11 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* tests/lint-seam-enforcement.test.cjs
|
|
*
|
|
* Regression net for scripts/lint-seam-enforcement.cjs (#3626). Drives the
|
|
* guard's pure `extractSeamFacts`/`parseEnforcementPointer`/`checkSeamFacts`/
|
|
* `readRegisteredRuleNames` exports directly with synthetic fixtures and
|
|
* injected fakes, so this test never depends on eslint.config.mjs or CONTEXT.md
|
|
* shape churn — plus a final "real repo" integration block.
|
|
*
|
|
* Design: .msd/phase/feat-3626-context-seam-claim-gate/40-design.md
|
|
* Test matrix: .msd/phase/feat-3626-context-seam-claim-gate/50-test-matrix.md
|
|
*/
|
|
|
|
const { test, describe } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const {
|
|
extractSeamFacts,
|
|
parseEnforcementPointer,
|
|
checkSeamFacts,
|
|
readRegisteredRuleNames,
|
|
} = require('../scripts/lint-seam-enforcement.cjs');
|
|
|
|
describe('lint-seam-enforcement: extractSeamFacts', () => {
|
|
test('captures a backtick-wrapped owns/enforced-by pair', () => {
|
|
const text = [
|
|
'Some prose.',
|
|
'`SEAM.foo.owns=bar`',
|
|
'`SEAM.foo.enforced-by=test:tests/x.test.cjs`',
|
|
'More prose.',
|
|
].join('\n');
|
|
|
|
const { owns, enforcedBy } = extractSeamFacts(text);
|
|
assert.equal(owns.get('foo'), 'bar');
|
|
assert.equal(enforcedBy.get('foo'), 'test:tests/x.test.cjs');
|
|
});
|
|
|
|
test('row 13: an unrelated <NAME>.SEAM.<subkey>= line is NOT captured (anchored regex, not <id>.owns|enforced-by)', () => {
|
|
const text = '`WORKTREE.SEAM.files=[msd-core/bin/lib/worktree-safety.cjs]`';
|
|
const { owns, enforcedBy } = extractSeamFacts(text);
|
|
assert.equal(owns.size, 0);
|
|
assert.equal(enforcedBy.size, 0);
|
|
});
|
|
});
|
|
|
|
describe('lint-seam-enforcement: parseEnforcementPointer', () => {
|
|
test('lint-rule: scheme', () => {
|
|
assert.deepEqual(parseEnforcementPointer('lint-rule:no-source-grep'), {
|
|
scheme: 'lint-rule',
|
|
target: 'no-source-grep',
|
|
});
|
|
});
|
|
|
|
test('test: scheme', () => {
|
|
assert.deepEqual(parseEnforcementPointer('test:tests/foo.test.cjs'), {
|
|
scheme: 'test',
|
|
target: 'tests/foo.test.cjs',
|
|
});
|
|
});
|
|
|
|
test('unrecognized scheme falls back to null scheme with the raw value as target', () => {
|
|
assert.deepEqual(parseEnforcementPointer('bogus-scheme:x'), {
|
|
scheme: null,
|
|
target: 'bogus-scheme:x',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('lint-seam-enforcement: checkSeamFacts', () => {
|
|
test('row 1: owns + enforced-by=lint-rule:<name> where the rule is registered and its source exists — no findings', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'lint-rule:no-source-grep']]);
|
|
const deps = {
|
|
ruleIsRegistered: () => true,
|
|
ruleFileExists: () => true,
|
|
testFileExists: () => false,
|
|
};
|
|
assert.deepEqual(checkSeamFacts({ owns, enforcedBy }, deps), []);
|
|
});
|
|
|
|
test('row 2: owns + enforced-by=test:<path> where the file exists — no findings', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'test:tests/foo.test.cjs']]);
|
|
const deps = {
|
|
ruleIsRegistered: () => false,
|
|
ruleFileExists: () => false,
|
|
testFileExists: () => true,
|
|
};
|
|
assert.deepEqual(checkSeamFacts({ owns, enforcedBy }, deps), []);
|
|
});
|
|
|
|
test('row 4: owns with no matching enforced-by — THE FIXTURE THAT PROVES THE GATE CAN FAIL (drift-guard-prove-it-can-fail convention)', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map();
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => true };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /SEAM\.foo/);
|
|
assert.match(findings[0], /no enforcement pointer/);
|
|
});
|
|
|
|
test('row 5: enforced-by=lint-rule:<name> where the name is not registered — dangling lint-rule pointer', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'lint-rule:nope']]);
|
|
const deps = { ruleIsRegistered: () => false, ruleFileExists: () => true, testFileExists: () => true };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /dangling lint-rule pointer/);
|
|
});
|
|
|
|
test('row 6: enforced-by=lint-rule:<name> registered but its source file is missing — registered rule has no source file', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'lint-rule:ghost']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => false, testFileExists: () => true };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /registered rule has no source file/);
|
|
});
|
|
|
|
test('row 7: enforced-by=test:<path> where the path does not exist — dangling test-anchor pointer', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'test:tests/nope.test.cjs']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => false };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /dangling test-anchor pointer/);
|
|
});
|
|
|
|
test('row 8: enforced-by with an unrecognized scheme prefix — unrecognized enforcement-pointer scheme', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'weird:thing']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => true };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /unrecognized enforcement-pointer scheme/);
|
|
});
|
|
|
|
test('row 9: enforced-by with no matching owns (stale/renamed id) — enforcement pointer with no ownership claim', () => {
|
|
const owns = new Map();
|
|
const enforcedBy = new Map([['foo', 'lint-rule:no-source-grep']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => true };
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /enforcement pointer with no ownership claim/);
|
|
});
|
|
|
|
test('row 10 (checkSeamFacts-level zero case): empty owns/enforcedBy maps — no findings', () => {
|
|
// The CLI-level "explicit zero notice" (row 10's full behavior) is emitted
|
|
// via process.stdout.write in main() — CLI/process stdout is not
|
|
// unit-tested in this style elsewhere in the repo (see
|
|
// mutation-test-derivation-drift.test.cjs), so only the checkSeamFacts
|
|
// return value (empty findings on empty input) is asserted here.
|
|
assert.deepEqual(checkSeamFacts({ owns: new Map(), enforcedBy: new Map() }, {
|
|
ruleIsRegistered: () => true,
|
|
ruleFileExists: () => true,
|
|
testFileExists: () => true,
|
|
}), []);
|
|
});
|
|
|
|
test('row 11 (boundary, limit=1): exactly one valid claim — no findings', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'test:tests/foo.test.cjs']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => true };
|
|
assert.deepEqual(checkSeamFacts({ owns, enforcedBy }, deps), []);
|
|
});
|
|
|
|
test('row 11 (boundary, limit=1): exactly one INVALID (dangling) claim — findings array of length exactly 1', () => {
|
|
const owns = new Map([['foo', 'bar']]);
|
|
const enforcedBy = new Map([['foo', 'test:tests/nope.test.cjs']]);
|
|
const deps = { ruleIsRegistered: () => true, ruleFileExists: () => true, testFileExists: () => false };
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
});
|
|
|
|
test('row 12 (independence): two claims, one valid + one dangling — findings name ONLY the dangling id', () => {
|
|
const owns = new Map([
|
|
['good', 'good-thing'],
|
|
['bad', 'bad-thing'],
|
|
]);
|
|
const enforcedBy = new Map([
|
|
['good', 'test:tests/good.test.cjs'],
|
|
['bad', 'test:tests/bad.test.cjs'],
|
|
]);
|
|
const deps = {
|
|
ruleIsRegistered: () => true,
|
|
ruleFileExists: () => true,
|
|
testFileExists: (relPath) => relPath === 'tests/good.test.cjs',
|
|
};
|
|
|
|
const findings = checkSeamFacts({ owns, enforcedBy }, deps);
|
|
assert.equal(findings.length, 1);
|
|
assert.match(findings[0], /SEAM\.bad/);
|
|
assert.doesNotMatch(findings[0], /SEAM\.good/);
|
|
});
|
|
|
|
test('row 14 (hostile, resolves-only scope): a valid lint-rule pointer for an id whose owns prose is unrelated to the rule — still resolves, no content inference', () => {
|
|
const owns = new Map([['totally-unrelated-capability', 'some prose describing an unrelated thing']]);
|
|
const enforcedBy = new Map([['totally-unrelated-capability', 'lint-rule:no-source-grep']]);
|
|
const deps = {
|
|
ruleIsRegistered: (name) => name === 'no-source-grep',
|
|
ruleFileExists: (name) => name === 'no-source-grep',
|
|
testFileExists: () => false,
|
|
};
|
|
assert.deepEqual(checkSeamFacts({ owns, enforcedBy }, deps), []);
|
|
});
|
|
});
|
|
|
|
describe('lint-seam-enforcement: readRegisteredRuleNames', () => {
|
|
test('extracts rule names from a synthetic localPlugin.rules block', () => {
|
|
const text = `
|
|
const localPlugin = {
|
|
rules: {
|
|
'no-source-grep': noSourceGrep,
|
|
'no-private-binary-resolution': noPrivateBinaryResolution,
|
|
},
|
|
};
|
|
`;
|
|
const names = readRegisteredRuleNames(text);
|
|
assert.ok(names instanceof Set);
|
|
assert.ok(names.has('no-source-grep'));
|
|
assert.ok(names.has('no-private-binary-resolution'));
|
|
});
|
|
});
|
|
|
|
describe('lint-seam-enforcement: real repo has zero unresolved SEAM claims', () => {
|
|
test('row 3: extractSeamFacts + checkSeamFacts against the real CONTEXT.md and eslint.config.mjs resolve cleanly', () => {
|
|
// Regression net for every SEAM.*.owns/enforced-by fact CONTEXT.md
|
|
// declares. deepEqual([]) is correct whether CONTEXT.md has zero facts
|
|
// (empty maps produce zero findings trivially) or many (each must
|
|
// resolve cleanly to a registered rule or an existing test file).
|
|
const root = path.join(__dirname, '..');
|
|
const contextText = fs.readFileSync(path.join(root, 'CONTEXT.md'), 'utf8');
|
|
const eslintConfigText = fs.readFileSync(path.join(root, 'eslint.config.mjs'), 'utf8');
|
|
|
|
const registeredRules = readRegisteredRuleNames(eslintConfigText);
|
|
const facts = extractSeamFacts(contextText);
|
|
|
|
const findings = checkSeamFacts(facts, {
|
|
ruleIsRegistered: (name) => registeredRules.has(name),
|
|
ruleFileExists: (name) => fs.existsSync(path.join(root, 'eslint-rules', `${name}.cjs`)),
|
|
testFileExists: (relPath) => fs.existsSync(path.join(root, relPath)),
|
|
});
|
|
|
|
assert.deepEqual(findings, []);
|
|
});
|
|
});
|