@@ -318,13 +318,18 @@ describe("mergeUsage", () => {
318318 ] ,
319319 projects : [ ] ,
320320 } ) ;
321- // At the same read time, prefer the scan with stronger T3 attribution.
321+ // Read later, but it only sees the session from outside, or (an older
322+ // server) cannot split by thread at all.
322323 const outside = environment ( "outside" , {
323324 ...summary ( [ bucket ( { thread : 0 } ) ] , [ source ] ) ,
325+ readAt : "2026-08-07T00:01:00.000Z" ,
324326 threads : [ { key : "session:claude:s" , located : true } ] ,
325327 projects : [ ] ,
326328 } ) ;
327- const older = environment ( "older" , summary ( [ bucket ( ) ] , [ source ] , USAGE_MERGE_COMPATIBLE_SINCE ) ) ;
329+ const older = environment ( "older" , {
330+ ...summary ( [ bucket ( ) ] , [ source ] , USAGE_MERGE_COMPATIBLE_SINCE ) ,
331+ readAt : "2026-08-07T00:02:00.000Z" ,
332+ } ) ;
328333
329334 for ( const ordered of [
330335 [ ran , outside , older ] ,
@@ -336,40 +341,41 @@ describe("mergeUsage", () => {
336341 }
337342 } ) ;
338343
339- it ( "uses the newest complete scan even when it has less T3 attribution" , ( ) => {
344+ it ( "keeps one complete scan per directory, even when a newer one differs" , ( ) => {
345+ // Aliases or a later read can make the same records look like other cells.
340346 const source = { provider : "claude" as const , hostId : "mac" , homePath : "/home/theo/.claude" } ;
341- const older = environment ( "older " , {
347+ const ran = environment ( "ran " , {
342348 ...summary ( [ bucket ( { thread : 0 } ) ] , [ source ] ) ,
343349 threads : [ { key : "t3:ship" , threadId : ThreadId . make ( "ship" ) , located : true } ] ,
344350 projects : [ ] ,
345351 } ) ;
346- const newer = environment ( "newer " , {
347- ...summary ( [ bucket ( { thread : 0 , costUsd : 15 , records : 6 } ) ] , [ source ] ) ,
352+ const later = environment ( "later " , {
353+ ...summary ( [ bucket ( { thread : 0 , model : "fable-alias" , costUsd : 15 } ) ] , [ source ] ) ,
348354 readAt : "2026-08-07T00:05:00.000Z" ,
349355 threads : [ { key : "session:claude:s" , located : true } ] ,
350356 projects : [ ] ,
351357 } ) ;
352- const merged = mergeUsage ( [ newer , older ] , USAGE_CONTRACT_VERSION ) ;
353- expect ( merged . costUsd ) . toBe ( 15 ) ;
354- expect ( merged . records ) . toBe ( 6 ) ;
355- expect ( merged . contributions . map ( ( entry ) => entry . environmentId ) ) . toEqual ( [ "newer" ] ) ;
358+ const merged = mergeUsage ( [ later , ran ] , USAGE_CONTRACT_VERSION ) ;
359+ expect ( merged . costUsd ) . toBe ( 10 ) ;
360+ expect ( merged . contributions . map ( ( entry ) => entry . environmentId ) ) . toEqual ( [ "ran" ] ) ;
356361 } ) ;
357362
358- it ( "does not let a scan kept from a failed refresh hold a directory " , ( ) => {
363+ it ( "does not let a better attributed scan drop records a newer scan counted " , ( ) => {
359364 const source = { provider : "claude" as const , hostId : "mac" , homePath : "/home/theo/.claude" } ;
360365 const stale = environment ( "stale" , {
361366 ...summary ( [ bucket ( { thread : 0 } ) ] , [ source ] ) ,
362367 threads : [ { key : "t3:ship" , threadId : ThreadId . make ( "ship" ) , located : true } ] ,
363368 projects : [ ] ,
364369 } ) ;
365370 const fresh = environment ( "fresh" , {
366- ...summary ( [ bucket ( { thread : 0 , costUsd : 50 } ) ] , [ source ] ) ,
367- readAt : "2026-08-07T03:00 :00.000Z" ,
371+ ...summary ( [ bucket ( { thread : 0 , costUsd : 50 , records : 6 } ) ] , [ source ] ) ,
372+ readAt : "2026-08-07T00:05 :00.000Z" ,
368373 threads : [ { key : "session:claude:s" , located : true } ] ,
369374 projects : [ ] ,
370375 } ) ;
371376 const merged = mergeUsage ( [ stale , fresh ] , USAGE_CONTRACT_VERSION ) ;
372377 expect ( merged . costUsd ) . toBe ( 50 ) ;
378+ expect ( merged . records ) . toBe ( 6 ) ;
373379 expect ( merged . contributions . map ( ( entry ) => entry . environmentId ) ) . toEqual ( [ "fresh" ] ) ;
374380 } ) ;
375381
@@ -390,6 +396,7 @@ describe("mergeUsage", () => {
390396 [ bucket ( { records : 9 } ) , bucket ( { model : "y" , thread : 0 , costUsd : 1 , records : 1 } ) ] ,
391397 [ source ] ,
392398 ) ,
399+ readAt : "2026-08-07T00:01:00.000Z" ,
393400 threads,
394401 projects : [ ] ,
395402 } ) ;
0 commit comments