From 91d0c43090b14a8089fc70bd5897e130090b7cd9 Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 17 Oct 2026 19:23:44 +0000 Subject: [PATCH] test(qa-functional): keep the captured webhook-report cat attempts as denied negative controls (Q3) Paid run 39006896632 (qa-functional-webhook-report) attempted `cat package.json probe.ts .gitignore` and `cat src/*.ts test/*.ts`; the PreToolUse hook denied both. This is a model miss, not a detector defect, so both commands are pinned as denied by the registered hook and outside qaCommandAllowed. No detector change. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- test/qa-functional-observer.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/qa-functional-observer.test.ts b/test/qa-functional-observer.test.ts index 19d07f71d..cbc56273d 100644 --- a/test/qa-functional-observer.test.ts +++ b/test/qa-functional-observer.test.ts @@ -53,6 +53,24 @@ describe('QA command-observation boundary', () => { } }); + test('captured 39006896632 webhook-report cat attempts stay denied (Q3 negative controls)', () => { + // qa-functional-webhook-report, paid run 39006896632: the hook denied two shell reads the prompt routes to Read/Glob/Grep. + const fixture = createQAFunctionalFixture('webhook'); + try { + const registration = JSON.parse(fs.readFileSync(path.join(fixture.config, 'settings.json'), 'utf8')).hooks.PreToolUse; + for (const command of ['cat package.json probe.ts .gitignore', 'cat src/*.ts test/*.ts']) { + expect(qaCommandAllowed(command, fixture.root), command).toBe(false); + const result = spawnSync('bash', ['-c', registration[0].hooks[0].command], { + cwd: fixture.root, input: JSON.stringify({ hook_event_name: 'PreToolUse', cwd: fixture.root, tool_name: 'Bash', tool_input: { command } }), + encoding: 'utf8', timeout: 5000, + }); + expect(result.status, result.stderr).toBe(0); + expect(JSON.parse(result.stdout).hookSpecificOutput).toEqual({ hookEventName: 'PreToolUse', permissionDecision: 'deny', + permissionDecisionReason: 'Only foreground commands from the owned functional fixture interface are authorized.' }); + } + } finally { fixture.cleanup(); } + }); + test('admits native fixture commands and rejects unobserved shell effects', () => { for (const command of ['date -u +%Y-%m-%dT%H:%M:%SZ', 'bun run probe -- apply credit 7junk', 'bun run probe -- apply UPPER 7', 'bun run probe -- apply 9bad 7', 'bun run probe -- apply', 'bun run probe -- apply credit', 'bun run probe -- apply credit 7 extra', 'bun run probe -- partial', 'bun test test/regression.test.ts', 'git status --short']) expect(qaCommandAllowed(command)).toBe(true); for (const command of ['bun bin/gstack-qa-evidence', 'bun /abs/runtime/bin/gstack-qa-deadline', 'bun bin/gstack-qa-evidence --help']) expect(qaCommandAllowed(command), command).toBe(true);