@@ -102,8 +102,8 @@ describe("compaction governor", () => {
102102 expect ( actions ?. some ( ( a ) => a . type === "infer" ) ) . toBe ( false ) ;
103103 expect ( continuations ) . toBe ( 1 ) ;
104104
105- expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( true ) ;
106- expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( false ) ;
105+ expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( "infer" ) ;
106+ expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBeNull ( ) ;
107107 } ) ;
108108
109109 test ( "stays inert below the threshold or with few turns" , ( ) => {
@@ -133,7 +133,7 @@ describe("compaction governor", () => {
133133 test ( "recovers from context overflow a bounded number of times" , ( ) => {
134134 const governor = createCompactionGovernor ( ( ) => { } ) ;
135135 expect ( governor . interceptOverflow ( overflowError ( ) , capabilities ) ) . not . toBeNull ( ) ;
136- expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( true ) ;
136+ expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( "infer" ) ;
137137 expect ( governor . interceptOverflow ( overflowError ( ) , capabilities ) ) . not . toBeNull ( ) ;
138138 expect ( governor . interceptOverflow ( overflowError ( ) , capabilities ) ) . toBeNull ( ) ;
139139
@@ -161,6 +161,38 @@ describe("compaction governor", () => {
161161 expect ( governor . interceptIdleContinuation ( emptyMessage ( ) , capabilities ) ) . toBeNull ( ) ;
162162 } ) ;
163163
164+ // Idle compact with an empty continuation previously left postCompactInfer
165+ // unset, so resumeAfterCompact never fired and notePostCompact never ran —
166+ // the Ctx meter stayed on pre-compact lastTurnUsage until the next user turn.
167+ test ( "idle empty compact syncs the meter after shrink without a following user turn" , ( ) => {
168+ let continuations = 0 ;
169+ const governor = createCompactionGovernor ( ( ) => continuations ++ ) ;
170+ const large = turnsOfLength ( 10 , 200 ) ;
171+ governor . noteInferenceDone ( inferenceDone ( overThreshold ) , large ) ;
172+ expect ( governor . usingEstimate ) . toBe ( false ) ;
173+ const before = governor . estimatedTokens ;
174+
175+ governor . noteIdleTurn ( inferenceDone ( overThreshold ) , [ { type : "reply" , content : "done" } ] ) ;
176+ expect ( continuations ) . toBe ( 1 ) ;
177+
178+ const actions = governor . interceptIdleContinuation ( emptyMessage ( ) , capabilities ) ;
179+ expect ( actions ) . toEqual ( [
180+ { type : "compact" , compactor : "pruning-compactor" , reason : "context-threshold" } ,
181+ ] as ReactorAction [ ] ) ;
182+ // A second continuation re-enters decide after the compact cycle so the
183+ // governor can adopt the shrunk turns — without starting a new inference.
184+ expect ( continuations ) . toBe ( 2 ) ;
185+
186+ const shrunk = turnsOfLength ( 3 , 20 ) ;
187+ // resumeAfterCompact must arm the meter-only path (not infer) for empty idle.
188+ expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( "meter" ) ;
189+ governor . notePostCompact ( shrunk ) ;
190+
191+ expect ( governor . usingEstimate ) . toBe ( true ) ;
192+ expect ( governor . estimatedTokens ) . toBeLessThan ( before ) ;
193+ expect ( governor . estimatedTokens ) . toBe ( governor . syncFromTurns ( shrunk ) ) ;
194+ } ) ;
195+
164196 test ( "an operator message that races the idle continuation still compacts, then re-infers" , ( ) => {
165197 let continuations = 0 ;
166198 const governor = createCompactionGovernor ( ( ) => continuations ++ ) ;
@@ -176,7 +208,7 @@ describe("compaction governor", () => {
176208 // A second continuation is requested so the operator message gets answered
177209 // after the compact cycle.
178210 expect ( continuations ) . toBe ( 2 ) ;
179- expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( true ) ;
211+ expect ( governor . resumeAfterCompact ( emptyMessage ( ) ) ) . toBe ( "infer" ) ;
180212 } ) ;
181213
182214 test ( "idle turns with follow-up work or under threshold never arm idle compaction" , ( ) => {
0 commit comments