@@ -21,6 +21,7 @@ import {
2121 LEGACY_COMPACT_SPACER_TEXT ,
2222 compactorNoOpFloor ,
2323} from "../session/compactor.js" ;
24+ import { buildSummaryPrompt } from "../session/summarizer.js" ;
2425
2526const capabilities = {
2627 infer : ( options ?: unknown ) => ( {
@@ -903,6 +904,20 @@ describe("handoff arming (/handoff)", () => {
903904 ) . toBeNull ( ) ;
904905 } ) ;
905906
907+ test ( "cancelManual restores extraInstructions from a prior successful fold" , ( ) => {
908+ const governor = createCompactionGovernor ( undefined ) ;
909+ governor . syncFromTurns ( tenTurns ) ;
910+ expect ( governor . requestHandoff ( "keep the UI audit" ) ) . toBe ( "armed" ) ;
911+ governor . interceptIdleContinuation (
912+ pivot ( "keep the UI audit" ) ,
913+ capabilities ,
914+ ) ;
915+ expect ( governor . extraInstructions ) . toBe ( "keep the UI audit" ) ;
916+ expect ( governor . requestHandoff ( "failed pivot: drop this" ) ) . toBe ( "armed" ) ;
917+ governor . cancelManual ( ) ;
918+ expect ( governor . extraInstructions ) . toBe ( "keep the UI audit" ) ;
919+ } ) ;
920+
906921 test ( "cancelManual clears sticky extraInstructions from a failed pivot" , ( ) => {
907922 const governor = createCompactionGovernor ( undefined ) ;
908923 governor . syncFromTurns ( tenTurns ) ;
@@ -911,6 +926,55 @@ describe("handoff arming (/handoff)", () => {
911926 expect ( governor . extraInstructions ) . toBeUndefined ( ) ;
912927 } ) ;
913928
929+ test ( "failed-pivot instructions are not in a later threshold summary prompt" , ( ) => {
930+ const governor = createCompactionGovernor ( undefined ) ;
931+ governor . syncFromTurns ( tenTurns ) ;
932+ expect ( governor . requestHandoff ( "now do the UI audit" ) ) . toBe ( "armed" ) ;
933+ governor . cancelManual ( ) ;
934+ governor . noteInferenceDone ( inferenceDone ( overThreshold ) , tenTurns ) ;
935+ expect (
936+ governor . interceptActions ( toolDone ( ) , inferAction , capabilities ) ,
937+ ) . not . toBeNull ( ) ;
938+ const prompt = buildSummaryPrompt (
939+ tenTurns ,
940+ governor . extraInstructions !== undefined
941+ ? { extraInstructions : governor . extraInstructions }
942+ : undefined ,
943+ ) ;
944+ expect ( prompt ) . not . toContain ( "now do the UI audit" ) ;
945+ expect ( prompt ) . not . toContain ( "Operator compact instructions" ) ;
946+ } ) ;
947+
948+ test ( "cancelManual does not invent pending" , ( ) => {
949+ const governor = createCompactionGovernor ( undefined ) ;
950+ governor . syncFromTurns ( tenTurns ) ;
951+ expect ( governor . requestHandoff ( "now do the UI audit" ) ) . toBe ( "armed" ) ;
952+ governor . cancelManual ( ) ;
953+ expect (
954+ governor . interceptActions ( toolDone ( ) , inferAction , capabilities ) ,
955+ ) . toBeNull ( ) ;
956+ } ) ;
957+
958+ test ( "cancelManual restores idlePending so an idle threshold fold still fires" , ( ) => {
959+ const governor = createCompactionGovernor ( undefined ) ;
960+ governor . noteInferenceDone ( inferenceDone ( overThreshold ) , tenTurns ) ;
961+ expect (
962+ governor . noteIdleTurn ( inferenceDone ( overThreshold ) , [
963+ { type : "reply" , content : "done" } ,
964+ ] ) ,
965+ ) . toBe ( true ) ;
966+ expect ( governor . requestHandoff ( "now do the UI audit" ) ) . toBe ( "armed" ) ;
967+ governor . cancelManual ( ) ;
968+ const actions = governor . interceptIdleContinuation (
969+ emptyMessage ( ) ,
970+ capabilities ,
971+ ) ;
972+ expect ( actions ) . not . toBeNull ( ) ;
973+ expect ( actions ?. find ( ( a ) => a . type === "compact" ) ) . toMatchObject ( {
974+ reason : "context-threshold" ,
975+ } ) ;
976+ } ) ;
977+
914978 test ( "threshold pending survives cancelManual so a tool pause still folds" , ( ) => {
915979 const governor = createCompactionGovernor ( undefined ) ;
916980 governor . noteInferenceDone ( inferenceDone ( overThreshold ) , tenTurns ) ;
0 commit comments