@@ -340,6 +340,58 @@ describe("workflowsMaxMtime", () => {
340340 "0 when there are no workflow artifacts"
341341 ) ;
342342 } ) ;
343+
344+ // Regression guard for the maintenance sweep (server/index.js step 3) and
345+ // startWorkflowPoll: both skip a session whose workflow artifacts are
346+ // unchanged and re-ingest only once the fingerprint advances. Before the
347+ // gate, the 5-min sweep full-re-parsed every workflow journal and every
348+ // inner agent-*.jsonl for every active session every cycle; on a large
349+ // corpus each sweep outran the interval, sweeps overlapped, and the event
350+ // loop pegged (dashboard stopped responding). This asserts the exact
351+ // skip/re-ingest decision that gate relies on. Isolated root — no shared
352+ // fixture state so later suites are unaffected.
353+ it ( "gates skip vs re-ingest: stable fingerprint when unchanged, higher after a new artifact" , ( ) => {
354+ const root = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "wf-gate-" ) ) ;
355+ try {
356+ const sid = "sess-gate" ;
357+ const tp = path . join ( root , `${ sid } .jsonl` ) ;
358+ fs . writeFileSync ( tp , "" ) ;
359+ const wdir = path . join ( root , sid , "workflows" ) ;
360+ writeJson ( path . join ( wdir , "wf_a.json" ) , {
361+ runId : "wf_a" ,
362+ status : "completed" ,
363+ startTime : 1700000000000 ,
364+ workflowProgress : [ ] ,
365+ } ) ;
366+
367+ const seen = new Map ( ) ; // mirrors sweepWorkflowSeen / lastSeen
368+
369+ const m1 = workflowsMaxMtime ( tp ) ;
370+ assert . ok ( m1 > 0 , "fingerprint > 0 with a journal" ) ;
371+ assert . equal ( m1 === 0 || seen . get ( sid ) === m1 , false , "first sight ingests" ) ;
372+ seen . set ( sid , m1 ) ;
373+
374+ const m2 = workflowsMaxMtime ( tp ) ;
375+ assert . equal ( m2 , m1 , "fingerprint stable when nothing changes" ) ;
376+ assert . equal ( m2 === 0 || seen . get ( sid ) === m2 , true , "unchanged session is skipped" ) ;
377+
378+ const later = path . join ( wdir , "wf_b.json" ) ;
379+ writeJson ( later , {
380+ runId : "wf_b" ,
381+ status : "completed" ,
382+ startTime : 1700000001000 ,
383+ workflowProgress : [ ] ,
384+ } ) ;
385+ const bump = m1 / 1000 + 5 ; // seconds, safely newer than m1
386+ fs . utimesSync ( later , bump , bump ) ;
387+
388+ const m3 = workflowsMaxMtime ( tp ) ;
389+ assert . ok ( m3 > m1 , "fingerprint advances when a new artifact appears" ) ;
390+ assert . equal ( m3 === 0 || seen . get ( sid ) === m3 , false , "changed session is re-ingested" ) ;
391+ } finally {
392+ fs . rmSync ( root , { recursive : true , force : true } ) ;
393+ }
394+ } ) ;
343395} ) ;
344396
345397describe ( "live running workflow (no terminal journal)" , ( ) => {
0 commit comments