@@ -1527,7 +1527,7 @@ describe("SessionService", () => {
15271527 expect ( mockSessionStoreSetters . appendEvents ) . not . toHaveBeenCalled ( ) ;
15281528 } ) ;
15291529
1530- it ( "processes a pending cloud log gap after active reconciliation finishes " , async ( ) => {
1530+ it ( "queues a pending cloud log gap when stale fetches can't fill it, without appending " , async ( ) => {
15311531 const service = getSessionService ( ) ;
15321532 let sessionState = createMockSession ( {
15331533 taskRunId : "run-123" ,
@@ -1628,38 +1628,18 @@ describe("SessionService", () => {
16281628 } ) ;
16291629 resolveFirstLocalLogs ( "" ) ;
16301630
1631+ // The pending request must drain after the in-flight one resolves —
1632+ // verify the second readLocalLogs call eventually happens.
16311633 await vi . waitFor ( ( ) => {
1632- expect ( mockSessionStoreSetters . appendEvents ) . toHaveBeenCalledTimes ( 2 ) ;
1633- } ) ;
1634- expect ( mockSessionStoreSetters . appendEvents ) . toHaveBeenNthCalledWith (
1635- 1 ,
1636- "run-123" ,
1637- [
1638- expect . objectContaining ( {
1639- message : expect . objectContaining ( {
1640- params : { entry : firstEntry } ,
1641- } ) ,
1642- } ) ,
1643- ] ,
1644- 6 ,
1645- ) ;
1646- expect ( mockSessionStoreSetters . appendEvents ) . toHaveBeenNthCalledWith (
1647- 2 ,
1648- "run-123" ,
1649- [
1650- expect . objectContaining ( {
1651- message : expect . objectContaining ( {
1652- params : { entry : secondEntry } ,
1653- } ) ,
1654- } ) ,
1655- expect . objectContaining ( {
1656- message : expect . objectContaining ( {
1657- params : { entry : thirdEntry } ,
1658- } ) ,
1659- } ) ,
1660- ] ,
1661- 8 ,
1662- ) ;
1634+ expect ( mockTrpcLogs . readLocalLogs . query ) . toHaveBeenCalledTimes ( 2 ) ;
1635+ } ) ;
1636+ // Stale fetches can't fill the gap; we must NOT append the snapshot's
1637+ // tail slice (positions [expectedCount-N, expectedCount]) on top of an
1638+ // events array that's still at processedLineCount=5 — that path used
1639+ // to corrupt the array with duplicates/gaps and ratchet
1640+ // processedLineCount past entries we don't actually have, leading to
1641+ // unbounded growth on long-running cloud runs.
1642+ expect ( mockSessionStoreSetters . appendEvents ) . not . toHaveBeenCalled ( ) ;
16631643 } ) ;
16641644 it ( "flips status to connected on _posthog/run_started" , async ( ) => {
16651645 const service = getSessionService ( ) ;
0 commit comments