@@ -685,6 +685,99 @@ describe("createOptimizedContextStore checkpoint", () => {
685685 expect ( tree ) . not . toContain ( "untracked-junk.txt" ) ;
686686 } ) ;
687687
688+ test ( "a later checkpoint does not re-read an unchanged turn segment" , async ( ) => {
689+ const dir = tempDir ( ) ;
690+ const store = await createOptimizedContextStore ( dir ) ;
691+ const chunk = "s" . repeat ( 100_000 ) ;
692+ const turns : ConversationTurn [ ] = [ ] ;
693+ const middle = segmentFileName ( TURNS_FILE , 1 ) ;
694+ const tail = segmentFileName ( TURNS_FILE , 2 ) ;
695+ do {
696+ turns . push ( turn ( `${ turns . length } -${ chunk } ` ) ) ;
697+ await store . writeTurns ( turns ) ;
698+ } while ( ! fs . existsSync ( path . join ( dir , tail ) ) && turns . length < 20 ) ;
699+ expect ( fs . existsSync ( path . join ( dir , middle ) ) ) . toBe ( true ) ;
700+ expect ( fs . existsSync ( path . join ( dir , tail ) ) ) . toBe ( true ) ;
701+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
702+ await store . commit ( { message : "three segments" } ) ;
703+
704+ turns . push ( turn ( "tail" ) ) ;
705+ await store . writeTurns ( turns ) ;
706+ const reads = await countPathOps ( "readFile" , middle , ( ) =>
707+ store . commit ( { message : "append tail" } ) ,
708+ ) ;
709+ expect ( reads ) . toBe ( 0 ) ;
710+ } ) ;
711+
712+ test ( "a turn commit does not lstat every seeded tool-output blob" , async ( ) => {
713+ const dir = tempDir ( ) ;
714+ const store = await createOptimizedContextStore ( dir ) ;
715+ const blobCount = 24 ;
716+ for ( let index = 0 ; index < blobCount ; index ++ ) {
717+ await store . writeBlob (
718+ `blob-${ index } ` ,
719+ new TextEncoder ( ) . encode ( `body-${ index } ` ) ,
720+ "text/plain" ,
721+ ) ;
722+ }
723+ const turns = [ turn ( "seed" ) ] ;
724+ await store . writeTurns ( turns ) ;
725+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
726+ await store . commit ( { message : "seed blobs" } ) ;
727+
728+ const lstats = await countPathOps (
729+ "lstat" ,
730+ `${ path . sep } tool-output${ path . sep } ` ,
731+ async ( ) => {
732+ turns . push ( turn ( "next" ) ) ;
733+ await store . writeTurns ( turns ) ;
734+ await store . commit ( { message : "next turn" } ) ;
735+ } ,
736+ ) ;
737+ // Vendor commit still stats each blob once while staging it. The
738+ // empty-commit matrix must not stat them again on a turn that already
739+ // changed a managed file.
740+ expect ( lstats ) . toBeLessThan ( blobCount + blobCount / 2 ) ;
741+ } ) ;
742+
743+ test ( "seeded tool-output does not commit a no-op and a fresh store still heals blob bytes" , async ( ) => {
744+ const dir = tempDir ( ) ;
745+ const store = await createOptimizedContextStore ( dir ) ;
746+ await store . writeBlob (
747+ "kept" ,
748+ new TextEncoder ( ) . encode ( "original" ) ,
749+ "text/plain" ,
750+ ) ;
751+ await store . writeTurns ( [ turn ( "seed" ) ] ) ;
752+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
753+ const first = await store . commit ( { message : "seed blob" } ) ;
754+
755+ fs . writeFileSync ( path . join ( dir , "partial.jsonl" ) , '{"reason":"abort"}\n' ) ;
756+ const second = await store . commit ( { message : "empty with blobs" } ) ;
757+ expect ( second . hash ) . toBe ( first . hash ) ;
758+
759+ const blobName = fs
760+ . readdirSync ( path . join ( dir , "tool-output" ) )
761+ . find ( ( name ) => name . startsWith ( "kept" ) ) ;
762+ if ( blobName === undefined ) throw new Error ( "seeded blob missing" ) ;
763+ fs . writeFileSync ( path . join ( dir , "tool-output" , blobName ) , "rewritten" ) ;
764+ fs . writeFileSync ( path . join ( dir , "tool-output" , "stray.txt" ) , "stray" ) ;
765+
766+ const crashed = await createOptimizedContextStore ( dir ) ;
767+ const healed = await crashed . commit ( { message : "heal blobs" } ) ;
768+ expect ( healed . hash ) . not . toBe ( first . hash ) ;
769+ const tree = await gitLsTree ( dir ) ;
770+ expect ( tree ) . toContain ( `tool-output/${ blobName } ` ) ;
771+ expect ( tree ) . toContain ( "tool-output/stray.txt" ) ;
772+ const { blob } = await git . readBlob ( {
773+ fs,
774+ dir,
775+ oid : healed . hash ,
776+ filepath : `tool-output/${ blobName } ` ,
777+ } ) ;
778+ expect ( new TextDecoder ( ) . decode ( blob ) ) . toBe ( "rewritten" ) ;
779+ } ) ;
780+
688781 test ( "commits an on-disk extra turn segment that is not in HEAD without writeTurns" , async ( ) => {
689782 const dir = tempDir ( ) ;
690783 const store = await createOptimizedContextStore ( dir ) ;
@@ -1617,6 +1710,33 @@ function readTurnsFromFile(fullPath: string): ConversationTurn[] {
16171710 . map ( ( line ) => JSON . parse ( line ) as ConversationTurn ) ;
16181711}
16191712
1713+ async function countPathOps (
1714+ op : "readFile" | "lstat" ,
1715+ marker : string ,
1716+ run : ( ) => Promise < unknown > ,
1717+ ) : Promise < number > {
1718+ let hits = 0 ;
1719+ const target = fs . promises as unknown as Record <
1720+ string ,
1721+ ( ...args : unknown [ ] ) => Promise < unknown >
1722+ > ;
1723+ const original = target [ op ] ;
1724+ if ( original === undefined ) {
1725+ throw new Error ( `missing fs.promises.${ op } ` ) ;
1726+ }
1727+ target [ op ] = ( ...args : unknown [ ] ) => {
1728+ const first = args [ 0 ] ;
1729+ if ( typeof first === "string" && first . includes ( marker ) ) hits += 1 ;
1730+ return original . apply ( fs . promises , args ) ;
1731+ } ;
1732+ try {
1733+ await run ( ) ;
1734+ } finally {
1735+ target [ op ] = original ;
1736+ }
1737+ return hits ;
1738+ }
1739+
16201740async function gitLsTree ( dir : string ) : Promise < string [ ] > {
16211741 const proc = Bun . spawn (
16221742 [ "git" , "-C" , dir , "ls-tree" , "-r" , "--name-only" , "HEAD" ] ,
0 commit comments