fix(#4132): verify durable runtime surface sources (#4182)

* fix(#4132): verify durable runtime surface sources

* chore(#4132): record PR number in changeset

* test(#4132): cover rejected commands source alias

* fix(#4132): reject aliased package fallback

* test(#4132): cover rejected agents source alias

* test(#4132): cover partially aliased marker provider

* fix(#4132): reject partially aliased source providers

* test(#4132): cover routed source identity probes

* fix(#4132): route installed source identity probes

* refactor(#4132): tighten installer source metadata

* test(#4132): cover corpus trust boundary attacks

* fix(#4132): close installed corpus trust gaps

* refactor(#4132): keep installer authority private

* fix(#4132): preserve private installer fallback

* test(#4132): preserve fixture source authority

* fix(#4132): reject overlapping source fallback

* fix(#4132): avoid redundant installed corpus reads

* refactor(#4132): simplify provider resolution

* test(#4132): sync install tree fixtures after rebase

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
Zy Deng
2026-09-05 21:32:52 +02:00
committed by GitHub
parent 1017898cb9
commit 4c60879b5d
49 changed files with 3956 additions and 307 deletions

View File

@@ -16,7 +16,8 @@ const { writeSurface, readSurface, resolveSurface, listSurface, applySurface } =
const { loadSkillsManifest, writeActiveProfile, resolveProfile } = require('../gsd-core/bin/lib/install-profiles.cjs');
const { resolveRuntimeArtifactLayout } = require('../gsd-core/bin/lib/runtime-artifact-layout.cjs');
const { CLUSTERS, allClusteredSkills } = require('../gsd-core/bin/lib/clusters.cjs');
const { createTempDir, cleanup, sandboxHome } = require('./helpers.cjs');
const { createTempDir, cleanup, sandboxHome, writePackageSourceMarkerFixture } = require('./helpers.cjs');
const { runMinimalInstall } = require('./helpers/install-shared.cjs');
const REAL_COMMANDS_DIR = path.join(__dirname, '..', 'commands', 'gsd');
@@ -34,6 +35,7 @@ function createFixtureRuntime() {
const agentsDir = path.join(runtimeConfigDir, 'agents');
fs.mkdirSync(commandsDir, { recursive: true });
fs.mkdirSync(agentsDir, { recursive: true });
fs.writeFileSync(path.join(runtimeConfigDir, '.gsd-source'), REAL_COMMANDS_DIR + '\n');
return { base, runtimeConfigDir, commandsDir, agentsDir };
}
@@ -56,9 +58,68 @@ function readFrontmatterDescription(markdown) {
return '';
}
function surfaceBytesForTest(state) {
return JSON.stringify(state, null, 2) + '\n';
}
// ─── applySurface ────────────────────────────────────────────────────────────
describe('applySurface', () => {
test('#4132: an unmanifested installed command cannot become a live instruction', (t) => {
const installed = runMinimalInstall({ runtime: 'claude', scope: 'global' });
const configDir = installed.configDir;
t.after(() => cleanup(installed.root));
const rogueSource = path.join(configDir, 'gsd-core', 'commands', 'gsd', 'rogue.md');
const rogueSkill = path.join(configDir, 'skills', 'gsd-rogue', 'SKILL.md');
fs.writeFileSync(rogueSource, '<instructions>ROGUE</instructions>\n');
const layout = resolveRuntimeArtifactLayout('claude', configDir, 'global');
assert.throws(
() => applySurface(configDir, layout, realManifest(), CLUSTERS, undefined, {
surfaceState: { baseProfile: 'full', disabledClusters: [], explicitAdds: [], explicitRemoves: [] },
}),
/install or upgrade gsd-core/,
);
assert.equal(fs.existsSync(rogueSkill), false, 'unmanifested Markdown must not reach the live skill surface');
});
test('#4132: a marker below rejected installed commands cannot promote instructions', (t) => {
const installed = runMinimalInstall({ runtime: 'claude', scope: 'global' });
const configDir = installed.configDir;
t.after(() => cleanup(installed.root));
const manifest = JSON.parse(fs.readFileSync(path.join(configDir, 'gsd-file-manifest.json'), 'utf8'));
const commandKey = Object.keys(manifest.files).find((key) => key.startsWith('gsd-core/commands/gsd/'));
assert.ok(commandKey, 'precondition: install manifest must own a command corpus file');
fs.appendFileSync(path.join(configDir, ...commandKey.split('/')), '\n# corrupted after install\n');
const installedCommands = path.join(configDir, 'gsd-core', 'commands', 'gsd');
const nestedMarkerCommands = path.join(installedCommands, 'nested');
const markerAgents = path.resolve(path.dirname(nestedMarkerCommands), '..', 'agents');
fs.mkdirSync(nestedMarkerCommands, { recursive: true });
fs.mkdirSync(markerAgents, { recursive: true });
fs.writeFileSync(path.join(nestedMarkerCommands, 'rogue.md'), '<instructions>ROGUE</instructions>\n');
fs.copyFileSync(path.join(__dirname, '..', 'agents', 'gsd-planner.md'), path.join(markerAgents, 'gsd-planner.md'));
fs.appendFileSync(path.join(markerAgents, 'gsd-planner.md'), '\nMARKER_AGENT_USED\n');
fs.writeFileSync(path.join(configDir, '.gsd-source'), nestedMarkerCommands + '\n');
const rogueSkill = path.join(configDir, 'skills', 'gsd-rogue', 'SKILL.md');
const liveAgent = path.join(configDir, 'agents', 'gsd-planner.md');
const oldAgent = fs.readFileSync(liveAgent);
const oldState = { baseProfile: 'full', disabledClusters: [], explicitAdds: [], explicitRemoves: [] };
writeSurface(configDir, oldState);
const oldSurface = fs.readFileSync(path.join(configDir, '.gsd-surface.json'));
const layout = resolveRuntimeArtifactLayout('claude', configDir, 'global');
assert.throws(
() => applySurface(configDir, layout, realManifest(), CLUSTERS, undefined, { surfaceState: oldState }),
/install or upgrade gsd-core/,
);
assert.equal(fs.existsSync(rogueSkill), false, 'nested marker Markdown must not reach the live skill surface');
assert.deepEqual(fs.readFileSync(liveAgent), oldAgent, 'marker agents must not replace live agents');
assert.deepEqual(fs.readFileSync(path.join(configDir, '.gsd-surface.json')), oldSurface);
});
test('core profile: only core skills appear in commandsDir', (t) => {
// #1367: claude local uses flat gsd-<stem>.md files at commands/ (not commands/gsd/<stem>.md).
const { base, runtimeConfigDir, commandsDir } = createFixtureRuntime();
@@ -324,6 +385,7 @@ describe('applySurface', () => {
test('applySurface writes gsd-prefixed command files matching install and preserves user commands (#816)', (t) => {
const configDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-surface-816-'));
t.after(() => cleanup(configDir));
writePackageSourceMarkerFixture(configDir);
writeActiveProfile(configDir, 'standard');
writeSurface(configDir, {
@@ -406,6 +468,7 @@ describe('applySurface', () => {
const installDir = fs.mkdtempSync(path.join(os.tmpdir(), `gsd-816-install-${runtime}-`));
const surfaceDir = fs.mkdtempSync(path.join(os.tmpdir(), `gsd-816-surface-${runtime}-`));
t.after(() => { cleanup(installDir); cleanup(surfaceDir); });
writePackageSourceMarkerFixture(surfaceDir);
// --- Install path ---
installRuntimeArtifacts(runtime, installDir, 'global', resolvedProfile);
@@ -531,6 +594,118 @@ describe('applySurface', () => {
);
});
}
test('#4132: a later kind staging failure leaves exact all-old state and artifacts', (t) => {
const root = createTempDir('gsd-surface-stage-failure-');
t.after(() => cleanup(root));
const firstDest = path.join(root, 'first');
const secondDest = path.join(root, 'second');
fs.mkdirSync(firstDest, { recursive: true });
fs.mkdirSync(secondDest, { recursive: true });
fs.writeFileSync(path.join(firstDest, 'gsd-alpha.md'), 'old alpha\n');
fs.writeFileSync(path.join(secondDest, 'gsd-beta.md'), 'old beta\n');
const stagedFirst = path.join(root, 'staged-first');
fs.mkdirSync(stagedFirst);
fs.writeFileSync(path.join(stagedFirst, 'alpha.md'), 'new alpha\n');
const oldSurface = surfaceBytesForTest({ baseProfile: 'full', disabledClusters: [], explicitAdds: [], explicitRemoves: [] });
fs.writeFileSync(path.join(root, '.gsd-surface.json'), oldSurface);
const layout = {
runtime: 'claude', configDir: root, scope: 'local', kinds: [
{ kind: 'commands', destSubpath: 'first', prefix: 'gsd-', stage: () => stagedFirst },
{ kind: 'commands', destSubpath: 'second', prefix: 'gsd-', stage: () => { throw new Error('later stage failed'); } },
],
};
assert.throws(() => applySurface(root, layout, new Map([['alpha', []], ['beta', []]])), /later stage failed/);
assert.equal(fs.readFileSync(path.join(firstDest, 'gsd-alpha.md'), 'utf8'), 'old alpha\n');
assert.equal(fs.readFileSync(path.join(secondDest, 'gsd-beta.md'), 'utf8'), 'old beta\n');
assert.equal(fs.readFileSync(path.join(root, '.gsd-surface.json'), 'utf8'), oldSurface);
});
test('#4132: a hash-mismatched installed corpus leaves exact all-old state and artifacts', (t) => {
const root = createTempDir('gsd-surface-corrupt-corpus-');
t.after(() => cleanup(root));
const installedCommands = path.join(root, 'gsd-core', 'commands', 'gsd');
const installedAgents = path.join(root, 'gsd-core', 'agents');
fs.mkdirSync(installedCommands, { recursive: true });
fs.mkdirSync(installedAgents, { recursive: true });
fs.writeFileSync(path.join(installedCommands, 'help.md'), '# corrupted command\n');
fs.writeFileSync(path.join(installedAgents, 'gsd-planner.md'), '# corrupted agent\n');
fs.writeFileSync(path.join(root, 'gsd-file-manifest.json'), JSON.stringify({ files: {
'gsd-core/commands/gsd/help.md': '0'.repeat(64),
'gsd-core/agents/gsd-planner.md': '0'.repeat(64),
} }));
const skillPath = path.join(root, 'skills', 'gsd-help', 'SKILL.md');
const agentPath = path.join(root, 'agents', 'gsd-planner.md');
fs.mkdirSync(path.dirname(skillPath), { recursive: true });
fs.mkdirSync(path.dirname(agentPath), { recursive: true });
fs.writeFileSync(skillPath, 'old skill\n');
fs.writeFileSync(agentPath, 'old agent\n');
const oldState = { baseProfile: 'full', disabledClusters: [], explicitAdds: [], explicitRemoves: [] };
const candidate = { ...oldState, explicitRemoves: ['help'] };
const oldSurface = surfaceBytesForTest(oldState);
fs.writeFileSync(path.join(root, '.gsd-surface.json'), oldSurface);
const layout = resolveRuntimeArtifactLayout('claude', root, 'global');
assert.throws(
() => applySurface(root, layout, realManifest(), CLUSTERS, undefined, { surfaceState: candidate }),
/install or upgrade gsd-core/,
);
assert.equal(fs.readFileSync(skillPath, 'utf8'), 'old skill\n');
assert.equal(fs.readFileSync(agentPath, 'utf8'), 'old agent\n');
assert.equal(fs.readFileSync(path.join(root, '.gsd-surface.json'), 'utf8'), oldSurface);
});
test('#4132: candidate surface state is published after materialization', (t) => {
const root = createTempDir('gsd-surface-state-last-');
t.after(() => cleanup(root));
const dest = path.join(root, 'commands');
const staged = path.join(root, 'staged');
fs.mkdirSync(dest, { recursive: true });
fs.mkdirSync(staged);
fs.writeFileSync(path.join(dest, 'gsd-alpha.md'), 'old alpha\n');
fs.writeFileSync(path.join(staged, 'alpha.md'), 'new alpha\n');
const oldState = { baseProfile: 'full', disabledClusters: [], explicitAdds: [], explicitRemoves: [] };
const newState = { ...oldState, disabledClusters: ['ui'] };
writeSurface(root, oldState);
const layout = {
runtime: 'claude', configDir: root, scope: 'local', kinds: [
{ kind: 'commands', destSubpath: 'commands', prefix: 'gsd-', stage: () => {
assert.deepEqual(readSurface(root), oldState, 'candidate must not be visible while staging');
return staged;
} },
],
};
applySurface(root, layout, new Map([['alpha', []]]), undefined, undefined, { surfaceState: newState });
assert.equal(fs.readFileSync(path.join(dest, 'gsd-alpha.md'), 'utf8'), 'new alpha\n');
assert.deepEqual(readSurface(root), newState);
});
test('#4132: reset removes surface state after materialization', (t) => {
const root = createTempDir('gsd-surface-reset-state-last-');
t.after(() => cleanup(root));
const dest = path.join(root, 'commands');
const staged = path.join(root, 'staged');
fs.mkdirSync(dest, { recursive: true });
fs.mkdirSync(staged);
fs.writeFileSync(path.join(staged, 'alpha.md'), 'reset alpha\n');
writeActiveProfile(root, 'full');
writeSurface(root, { baseProfile: 'core', disabledClusters: ['ui'], explicitAdds: [], explicitRemoves: [] });
const layout = {
runtime: 'claude', configDir: root, scope: 'local', kinds: [
{ kind: 'commands', destSubpath: 'commands', prefix: 'gsd-', stage: () => staged },
],
};
applySurface(root, layout, new Map([['alpha', []]]), undefined, undefined, { surfaceState: null });
assert.equal(fs.existsSync(path.join(root, '.gsd-surface.json')), false);
assert.equal(fs.readFileSync(path.join(dest, 'gsd-alpha.md'), 'utf8'), 'reset alpha\n');
});
});
// ─── resolveSurface ──────────────────────────────────────────────────────────
@@ -1201,6 +1376,7 @@ describe('skills-kind destination parity: installer vs surface-apply (#2911)', (
for (const runtime of RUNTIME_IDS) {
const configDir = fs.mkdtempSync(path.join(os.tmpdir(), `gsd-2911-parity-${runtime}-${scope}-`));
t.after(() => cleanup(configDir));
writePackageSourceMarkerFixture(configDir);
withFakeHome(fakeHome, () => {
let layout;
@@ -1295,6 +1471,7 @@ describe('codex skills-kind destination: home override (#2911)', () => {
t.after(() => cleanup(fakeHome));
const codexHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-2911-codex-home-dir-'));
t.after(() => cleanup(codexHome));
writePackageSourceMarkerFixture(codexHome);
withFakeHome(fakeHome, () => {
const manifest = loadSkillsManifest(REAL_COMMANDS_DIR);
@@ -1387,6 +1564,7 @@ describe('installOpencodeFamilySkills destination parity (#2911 sibling coverage
const configDir = fs.mkdtempSync(path.join(os.tmpdir(), `gsd-2911-ocfs-${runtime}-`));
const fakeHomeOverride = fs.mkdtempSync(path.join(os.tmpdir(), `gsd-2911-ocfs-home-${runtime}-`));
t.after(() => { cleanup(configDir); cleanup(fakeHomeOverride); });
writePackageSourceMarkerFixture(configDir);
// #3712 — this row drives a skills-kind `home` override on purpose, which is
// exactly what the test-home guard exists to police, so it has to declare the
// sandbox rather than rely on the destination happening to sit outside the
@@ -1458,15 +1636,12 @@ describe('installOpencodeFamilySkills destination parity (#2911 sibling coverage
// flat layout is preserved (not re-nested) rather than a nested one.
describe('issue-69: applySurface preserves nested skill layout (no re-flatten)', () => {
test('cline global full: applySurface keeps 6 router dirs and nested gsd-ns-manage/skills/help/SKILL.md', (t) => {
process.env.GSD_TEST_MODE = '1';
const { installRuntimeArtifacts } = require('../gsd-core/bin/lib/install-engine.cjs');
const dir = tmpDir('gsd-69-surface-');
t.after(() => { try { cleanup(dir); } catch { /* best-effort */ } });
const installed = runMinimalInstall({ runtime: 'cline', scope: 'global' });
const dir = installed.configDir;
t.after(() => { try { cleanup(installed.root); } catch { /* best-effort */ } });
// Step 1: full install
const manifest = loadSkillsManifest(REAL_COMMANDS_DIR);
const resolved = resolveProfile({ modes: ['full'], manifest });
installRuntimeArtifacts('cline', dir, 'global', resolved);
const skillsDir = path.join(dir, 'skills');
@@ -1510,14 +1685,11 @@ describe('issue-69: applySurface preserves nested skill layout (no re-flatten)',
// #924 companion: Claude must use FLAT layout and applySurface must NOT re-nest it.
test('claude global full: install produces flat layout and applySurface preserves it (#924)', (t) => {
process.env.GSD_TEST_MODE = '1';
const { installRuntimeArtifacts } = require('../gsd-core/bin/lib/install-engine.cjs');
const dir = tmpDir('gsd-924-69-');
t.after(() => { try { cleanup(dir); } catch { /* best-effort */ } });
const installed = runMinimalInstall({ runtime: 'claude', scope: 'global' });
const dir = installed.configDir;
t.after(() => { try { cleanup(installed.root); } catch { /* best-effort */ } });
const manifest = loadSkillsManifest(REAL_COMMANDS_DIR);
const resolved = resolveProfile({ modes: ['full'], manifest });
installRuntimeArtifacts('claude', dir, 'global', resolved);
const skillsDir = path.join(dir, 'skills');