From 3bc8076801aa71e664aed0c4816d69df0da33348 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 1 Sep 2026 16:08:58 +0000 Subject: [PATCH] test(auq): pin the explicit-declaration-only spawned escape sentence SPAWNED_ESCAPE_SENTENCE's tightened wording had no pin: positive pins on the explicit-declaration clause, negative pins on the retired v1.76 loose parentheticals ('e.g. your dispatch prompt says', 'marks this session as spawned'), and a drift guard that both hook directives embed the constant verbatim. Co-Authored-By: Claude Fable 5 --- test/auq-error-fallback-hook.test.ts | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/auq-error-fallback-hook.test.ts b/test/auq-error-fallback-hook.test.ts index 224018ecb..c1ed95fa5 100644 --- a/test/auq-error-fallback-hook.test.ts +++ b/test/auq-error-fallback-hook.test.ts @@ -17,6 +17,7 @@ import { describe, test, expect } from 'bun:test'; import { spawnSync } from 'child_process'; import * as path from 'path'; import { isErrorResponse, directiveFor } from '../hosts/claude/hooks/auq-error-fallback-hook.ts'; +import { SPAWNED_ESCAPE_SENTENCE } from '../hosts/claude/hooks/spawned-directive.ts'; const HOOK = path.resolve(__dirname, '..', 'hosts', 'claude', 'hooks', 'auq-error-fallback-hook.ts'); @@ -107,6 +108,35 @@ describe('directiveFor — per-session-kind instruction', () => { }); }); +describe('SPAWNED_ESCAPE_SENTENCE — explicit-declaration-only trigger (periodic-lane AUQ collapse)', () => { + // The spawned escape must fire ONLY on an explicit dispatch-prompt + // declaration ("you are a spawned subagent"), never on an inference from a + // CI-looking / scripted-looking environment. The loose pre-fix parenthetical + // let the model infer spawned status and silently auto-choose every + // review-phase question (reviewCount=0 across the plan-review periodic E2Es). + test('carries the explicit-declaration wording', () => { + expect(SPAWNED_ESCAPE_SENTENCE).toContain('EXPLICITLY declares you a spawned subagent'); + expect(SPAWNED_ESCAPE_SENTENCE).toContain( + 'explicit statement, never an inference from an automated-looking environment', + ); + }); + + test('the old loose inference wording is gone', () => { + // Pre-fix sentence parenthetical: '(e.g. your dispatch prompt says you + // are a spawned subagent)' — an example, not a requirement, so an + // automated-looking prompt could be read as "saying" it. + expect(SPAWNED_ESCAPE_SENTENCE).not.toContain('e.g. your dispatch prompt says'); + // The v1.76 spawned-rule parenthetical this fix retired everywhere: + // '(or your dispatch prompt marks this session as spawned)'. + expect(SPAWNED_ESCAPE_SENTENCE).not.toContain('marks this session as spawned'); + }); + + test('both prose-directing directives embed the tightened sentence verbatim (no drift)', () => { + expect(directiveFor('interactive')).toContain(SPAWNED_ESCAPE_SENTENCE); + expect(directiveFor('headless')).toContain(SPAWNED_ESCAPE_SENTENCE); + }); +}); + /** Spawn the hook with synthetic stdin + controlled env; parse its JSON stdout. */ function runHook(stdin: object, env: Record): { additionalContext?: string } { const res = spawnSync('bun', [HOOK], {