@@ -75,6 +75,23 @@ describe("config clobber snapshots", () => {
7575 }
7676 }
7777
78+ function touchClobberFilesByContentOrderSync ( configPath : string ) : void {
79+ const dir = path . dirname ( configPath ) ;
80+ const prefix = `${ path . basename ( configPath ) } .clobbered.` ;
81+ for ( const entry of fs . readdirSync ( dir ) ) {
82+ if ( ! entry . startsWith ( prefix ) ) {
83+ continue ;
84+ }
85+ const targetPath = path . join ( dir , entry ) ;
86+ const match = / ^ p o l l u t e d - ( \d + ) \n $ / . exec ( fs . readFileSync ( targetPath , "utf-8" ) ) ;
87+ if ( ! match ) {
88+ continue ;
89+ }
90+ const touchedAt = new Date ( `2026-05-03T00:00:${ match [ 1 ] . padStart ( 2 , "0" ) } .000Z` ) ;
91+ fs . utimesSync ( targetPath , touchedAt , touchedAt ) ;
92+ }
93+ }
94+
7895 it ( "keeps concurrent async snapshots under the per-path cap by rotating oldest files" , async ( ) => {
7996 await withCase ( async ( configPath ) => {
8097 const warn = vi . fn ( ) ;
@@ -227,4 +244,42 @@ describe("config clobber snapshots", () => {
227244 expect ( capWarnings ) . toHaveLength ( 1 ) ;
228245 } ) ;
229246 } ) ;
247+
248+ it ( "keeps rotating same-timestamp sync snapshots after the base artifact is reused" , async ( ) => {
249+ await withCase ( async ( configPath ) => {
250+ const warn = vi . fn ( ) ;
251+ const observedAt = "2026-05-03T00:00:00.000Z" ;
252+
253+ for ( let index = 0 ; index < CONFIG_CLOBBER_SNAPSHOT_LIMIT ; index ++ ) {
254+ persistBoundedClobberedConfigSnapshotSync ( {
255+ deps : { fs, logger : { warn } } ,
256+ configPath,
257+ raw : `polluted-${ index } \n` ,
258+ observedAt,
259+ } ) ;
260+ }
261+ touchClobberFilesByContentOrderSync ( configPath ) ;
262+
263+ for (
264+ let index = CONFIG_CLOBBER_SNAPSHOT_LIMIT ;
265+ index < CONFIG_CLOBBER_SNAPSHOT_LIMIT + 3 ;
266+ index ++
267+ ) {
268+ persistBoundedClobberedConfigSnapshotSync ( {
269+ deps : { fs, logger : { warn } } ,
270+ configPath,
271+ raw : `polluted-${ index } \n` ,
272+ observedAt,
273+ } ) ;
274+ }
275+
276+ const clobberFiles = await listClobberFiles ( configPath ) ;
277+ expect ( clobberFiles ) . toHaveLength ( CONFIG_CLOBBER_SNAPSHOT_LIMIT ) ;
278+ const contents = await readClobberFileContents ( configPath ) ;
279+ expect ( contents ) . not . toContain ( "polluted-0\n" ) ;
280+ expect ( contents ) . not . toContain ( "polluted-1\n" ) ;
281+ expect ( contents ) . not . toContain ( "polluted-2\n" ) ;
282+ expect ( contents ) . toContain ( `polluted-${ CONFIG_CLOBBER_SNAPSHOT_LIMIT + 2 } \n` ) ;
283+ } ) ;
284+ } ) ;
230285} ) ;
0 commit comments