fix(hkv): remove post-session — it is a runner hook, not a settings event
Verified 2026-06-20 against hooks.md + the 2.1.169 changelog: the `post-session` hook in that changelog is a SELF-HOSTED-RUNNER workspace-lifecycle hook (runs after the session, before the workspace is deleted), NOT a settings.json hook event. It is absent from hooks.md's 30-event list (all PascalCase), so config-audit was wrongly treating a bogus `post-session` settings hook as valid — it now flags it. Restructured the event test suite accordingly and added a negative test. Resolved U1/U2 in the v5.5 plan (U1 refuted → removed; U2 `outputStyles` plugin.json key confirmed → PLH unchanged). Suite stays 954, self-audit A/A. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ter3E2JSi1Khgmuf2kady8
This commit is contained in:
parent
55633028e5
commit
5ac6c87053
3 changed files with 50 additions and 13 deletions
|
|
@ -101,13 +101,13 @@ describe('HKV scanner — verbose hook output (v5 M5)', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('HKV scanner — CC 2.1.152/2.1.169 hook events (Batch 1 false-positive fix)', () => {
|
||||
describe('HKV scanner — CC 2.1.152 MessageDisplay event (Batch 1 false-positive fix)', () => {
|
||||
// The pre-write path-guard blocks committing settings.json/hooks.json, so
|
||||
// this suite materializes a hermetic temp fixture at runtime.
|
||||
let tmpRoot;
|
||||
let result;
|
||||
|
||||
const NEW_EVENTS = ['MessageDisplay', 'post-session'];
|
||||
const VALID_NEW = ['MessageDisplay'];
|
||||
|
||||
beforeEach(async () => {
|
||||
resetCounter();
|
||||
|
|
@ -118,6 +118,50 @@ describe('HKV scanner — CC 2.1.152/2.1.169 hook events (Batch 1 false-positive
|
|||
// 'echo …' commands skip the script-existence check (extractScriptPath
|
||||
// only resolves bash/node/sh), isolating the event-name validation.
|
||||
MessageDisplay: [{ hooks: [{ type: 'command', command: 'echo display' }] }],
|
||||
},
|
||||
};
|
||||
await writeFile(
|
||||
join(tmpRoot, '.claude', 'settings.json'),
|
||||
JSON.stringify(settings, null, 2) + '\n',
|
||||
'utf8',
|
||||
);
|
||||
const discovery = await discoverConfigFiles(tmpRoot);
|
||||
result = await scan(tmpRoot, discovery);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (tmpRoot) await rm(tmpRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
for (const event of VALID_NEW) {
|
||||
it(`does NOT flag "${event}" as an unknown hook event`, () => {
|
||||
const unknown = result.findings.find(f =>
|
||||
f.title === 'Unknown hook event' && f.evidence === event);
|
||||
assert.equal(unknown, undefined, `${event} should be in VALID_EVENTS`);
|
||||
});
|
||||
}
|
||||
|
||||
it('produces zero findings for a valid MessageDisplay config', () => {
|
||||
assert.equal(result.findings.length, 0,
|
||||
`expected clean scan; got: ${result.findings.map(f => `${f.title}:${f.evidence || ''}`).join(' | ')}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('HKV scanner — post-session is NOT a settings.json hook event (Verifiseringsplikt)', () => {
|
||||
// Verified 2026-06-20 against hooks.md + the 2.1.169 changelog: the
|
||||
// `post-session` hook in that changelog is a SELF-HOSTED-RUNNER
|
||||
// workspace-lifecycle hook, NOT a settings.json hook event. It is absent
|
||||
// from hooks.md's (all-PascalCase) event list, so a settings.json hook
|
||||
// keyed on it never fires and MUST be flagged.
|
||||
let tmpRoot;
|
||||
let result;
|
||||
|
||||
beforeEach(async () => {
|
||||
resetCounter();
|
||||
tmpRoot = await mkdtemp(join(tmpdir(), 'ca-hkv-postsession-'));
|
||||
await mkdir(join(tmpRoot, '.claude'), { recursive: true });
|
||||
const settings = {
|
||||
hooks: {
|
||||
'post-session': [{ hooks: [{ type: 'command', command: 'echo bye' }] }],
|
||||
},
|
||||
};
|
||||
|
|
@ -134,17 +178,10 @@ describe('HKV scanner — CC 2.1.152/2.1.169 hook events (Batch 1 false-positive
|
|||
if (tmpRoot) await rm(tmpRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
for (const event of NEW_EVENTS) {
|
||||
it(`does NOT flag "${event}" as an unknown hook event`, () => {
|
||||
const unknown = result.findings.find(f =>
|
||||
f.title === 'Unknown hook event' && f.evidence === event);
|
||||
assert.equal(unknown, undefined, `${event} should be in VALID_EVENTS`);
|
||||
});
|
||||
}
|
||||
|
||||
it('produces zero findings for a valid MessageDisplay + post-session config', () => {
|
||||
assert.equal(result.findings.length, 0,
|
||||
`expected clean scan; got: ${result.findings.map(f => `${f.title}:${f.evidence || ''}`).join(' | ')}`);
|
||||
it('flags "post-session" as an unknown hook event', () => {
|
||||
const f = result.findings.find(x =>
|
||||
x.title === 'Unknown hook event' && x.evidence === 'post-session');
|
||||
assert.ok(f, 'post-session must be flagged as an unknown settings.json hook event');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue