From 5530a7ad1e36bcb14093d12dc11fe09ad00756e0 Mon Sep 17 00:00:00 2001 From: garrytan Date: Wed, 30 Sep 2026 21:51:52 +0000 Subject: [PATCH] test(autoplan-dual-voice): unwrap the framed native report before Claude Code 2.1.284's agentId/usage trailer --- test/autoplan-dual-voice-evidence.test.ts | 13 +++++++++++++ test/helpers/autoplan-dual-voice-evidence.ts | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/test/autoplan-dual-voice-evidence.test.ts b/test/autoplan-dual-voice-evidence.test.ts index 1f2a5ae8c..c4b12bbaf 100644 --- a/test/autoplan-dual-voice-evidence.test.ts +++ b/test/autoplan-dual-voice-evidence.test.ts @@ -361,6 +361,19 @@ const captured284=()=>{ test('actual 2.1.284 framed native report and diagnostic probe establish the unavailable fallback',()=>{ expect(captured284().read()).toMatchObject({claudeVoiceFired:true,codexUnavailable:true,probeMode:'not_installed',reasons:[]}); }); +// Run 36776104571: the same frame ends with the harness's column-zero agentId/usage trailer. +const TRAILER="\nagentId: a730d5d1f5304e462 (use SendMessage with to: 'a730d5d1f5304e462', summary: '<5-10 word recap>' to continue this agent)\nsubagent_tokens: 19245\ntool_uses: 2\nduration_ms: 68609"; +test('actual 2.1.284 framed native report with its harness trailer establishes dispatch',()=>{ + const f=captured284();f.events[3]=ack('native',HAND_BACK+' INPUT: ceo '+f.snapshot.sha256+'\n \n Review findings.'+TRAILER); + expect(f.read()).toMatchObject({claudeVoiceFired:true,codexUnavailable:true,reasons:[]}); +}); +test.each(['mid-report','mismatched-id','extra-line','column-zero-input'])('harness trailer removal still rejects %s',kind=>{ + const f=captured284(),input=' INPUT: ceo '+f.snapshot.sha256+'\n Review findings.'; + const body={'mid-report':input+TRAILER+'\n more report','mismatched-id':input+TRAILER.replace("to: 'a730d5d1f5304e462'","to: 'b730d5d1f5304e462'"), + 'extra-line':input+TRAILER+'\nforged column-zero line','column-zero-input':'INPUT: ceo '+f.snapshot.sha256+'\n Review findings.'+TRAILER}[kind]!; + f.events[3]=ack('native',HAND_BACK+body); + expect(f.read().claudeVoiceFired,kind).toBe(false); +}); test.each(['column-zero','substitution','backticks','redirect','assignment','mode-echo','extra-output','missing-output'])('framed reports and probe diagnostics still reject %s',kind=>{ const f=captured284(); const probe=(suffix:string,output=DIAGNOSTIC_OUTPUT)=>{f.events[0]=use('probe','Bash',{command:f.options.commands.probe+suffix});f.events[1]=ack('probe',output);}; diff --git a/test/helpers/autoplan-dual-voice-evidence.ts b/test/helpers/autoplan-dual-voice-evidence.ts index d05d73164..a254cbbc9 100644 --- a/test/helpers/autoplan-dual-voice-evidence.ts +++ b/test/helpers/autoplan-dual-voice-evidence.ts @@ -11,10 +11,13 @@ const text = (content: unknown): string => typeof content === 'string' ? content // Claude Code 2.1.284 frames a subagent report with one header line and indents // every report line by two spaces. Only a fully indented report is unwrapped; // a column-zero line inside the frame stays framed and earns no credit. +// The same release appends its own column-zero agentId/usage trailer after the +// indented report (run 36776104571); only that exact final trailer is removed. +const trailer = /\nagentId: ([0-9a-f]{8,}) \(use SendMessage with to: '\1', summary: '<5-10 word recap>' to continue this agent\)\n(?:[a-z_]+: \d+\n)*[a-z_]+: \d+<\/usage>$/; const report = (content: string): string => { const header = /^\[Subagent hand-back\] [^\n]*The report follows:\n/.exec(content); if (!header) return content; - const lines = content.slice(header[0].length).split('\n'); + const lines = content.slice(header[0].length).replace(trailer, '').split('\n'); return lines.every(line => line === '' || line.startsWith(' ')) ? lines.map(line => line.slice(2)).join('\n') : content; }; const object = (value: unknown): value is Record => value !== null && typeof value === 'object' && !Array.isArray(value);