@@ -685,6 +685,155 @@ 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 ( "an external append to a tracked segment is in the next commit" , async ( ) => {
713+ const dir = tempDir ( ) ;
714+ const store = await createOptimizedContextStore ( dir ) ;
715+ const chunk = "s" . repeat ( 100_000 ) ;
716+ const turns : ConversationTurn [ ] = [ ] ;
717+ const closed = segmentFileName ( TURNS_FILE , 1 ) ;
718+ const tail = segmentFileName ( TURNS_FILE , 2 ) ;
719+ do {
720+ turns . push ( turn ( `${ turns . length } -${ chunk } ` ) ) ;
721+ await store . writeTurns ( turns ) ;
722+ } while ( ! fs . existsSync ( path . join ( dir , tail ) ) && turns . length < 20 ) ;
723+ expect ( fs . existsSync ( path . join ( dir , closed ) ) ) . toBe ( true ) ;
724+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
725+ const first = await store . commit ( { message : "three segments" } ) ;
726+
727+ const marker = "external-drift-bytes" ;
728+ fs . appendFileSync ( path . join ( dir , closed ) , `${ marker } \n` ) ;
729+ let secondHash = "" ;
730+ const unchangedReads = await countPathOps ( "readFile" , tail , async ( ) => {
731+ const second = await store . commit ( { message : "publish drifted segment" } ) ;
732+ secondHash = second . hash ;
733+ } ) ;
734+ expect ( unchangedReads ) . toBe ( 0 ) ;
735+ expect ( secondHash ) . not . toBe ( first . hash ) ;
736+ const { blob } = await git . readBlob ( {
737+ fs,
738+ dir,
739+ oid : secondHash ,
740+ filepath : closed ,
741+ } ) ;
742+ expect ( new TextDecoder ( ) . decode ( blob ) ) . toContain ( marker ) ;
743+ } ) ;
744+
745+ test ( "a turn commit does not lstat every seeded tool-output blob" , async ( ) => {
746+ const dir = tempDir ( ) ;
747+ const store = await createOptimizedContextStore ( dir ) ;
748+ const blobCount = 24 ;
749+ for ( let index = 0 ; index < blobCount ; index ++ ) {
750+ await store . writeBlob (
751+ `blob-${ index } ` ,
752+ new TextEncoder ( ) . encode ( `body-${ index } ` ) ,
753+ "text/plain" ,
754+ ) ;
755+ }
756+ const turns = [ turn ( "seed" ) ] ;
757+ await store . writeTurns ( turns ) ;
758+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
759+ await store . commit ( { message : "seed blobs" } ) ;
760+
761+ const lstats = await countPathOps (
762+ "lstat" ,
763+ `${ path . sep } tool-output${ path . sep } ` ,
764+ async ( ) => {
765+ turns . push ( turn ( "next" ) ) ;
766+ await store . writeTurns ( turns ) ;
767+ await store . commit ( { message : "next turn" } ) ;
768+ } ,
769+ ) ;
770+ // Vendor commit still stats each blob once while staging it. The
771+ // empty-commit matrix must not stat them again on a turn that already
772+ // changed a managed file.
773+ expect ( lstats ) . toBeLessThan ( blobCount + blobCount / 2 ) ;
774+ } ) ;
775+
776+ test ( "a no-op commit does not lstat every tool-output blob" , async ( ) => {
777+ const dir = tempDir ( ) ;
778+ const store = await createOptimizedContextStore ( dir ) ;
779+ const blobCount = 24 ;
780+ for ( let index = 0 ; index < blobCount ; index ++ ) {
781+ await store . writeBlob (
782+ `blob-${ index } ` ,
783+ new TextEncoder ( ) . encode ( `body-${ index } ` ) ,
784+ "text/plain" ,
785+ ) ;
786+ }
787+ await store . writeTurns ( [ turn ( "seed" ) ] ) ;
788+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
789+ await store . commit ( { message : "seed blobs" } ) ;
790+
791+ const lstats = await countPathOps (
792+ "lstat" ,
793+ `${ path . sep } tool-output${ path . sep } ` ,
794+ ( ) => store . commit ( { message : "no writes" } ) ,
795+ ) ;
796+ expect ( lstats ) . toBe ( 0 ) ;
797+ } ) ;
798+
799+ test ( "seeded tool-output does not commit a no-op and a fresh store still heals blob bytes" , async ( ) => {
800+ const dir = tempDir ( ) ;
801+ const store = await createOptimizedContextStore ( dir ) ;
802+ await store . writeBlob (
803+ "kept" ,
804+ new TextEncoder ( ) . encode ( "original" ) ,
805+ "text/plain" ,
806+ ) ;
807+ await store . writeTurns ( [ turn ( "seed" ) ] ) ;
808+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
809+ const first = await store . commit ( { message : "seed blob" } ) ;
810+
811+ fs . writeFileSync ( path . join ( dir , "partial.jsonl" ) , '{"reason":"abort"}\n' ) ;
812+ const second = await store . commit ( { message : "empty with blobs" } ) ;
813+ expect ( second . hash ) . toBe ( first . hash ) ;
814+
815+ const blobName = fs
816+ . readdirSync ( path . join ( dir , "tool-output" ) )
817+ . find ( ( name ) => name . startsWith ( "kept" ) ) ;
818+ if ( blobName === undefined ) throw new Error ( "seeded blob missing" ) ;
819+ fs . writeFileSync ( path . join ( dir , "tool-output" , blobName ) , "rewritten" ) ;
820+ fs . writeFileSync ( path . join ( dir , "tool-output" , "stray.txt" ) , "stray" ) ;
821+
822+ const crashed = await createOptimizedContextStore ( dir ) ;
823+ const healed = await crashed . commit ( { message : "heal blobs" } ) ;
824+ expect ( healed . hash ) . not . toBe ( first . hash ) ;
825+ const tree = await gitLsTree ( dir ) ;
826+ expect ( tree ) . toContain ( `tool-output/${ blobName } ` ) ;
827+ expect ( tree ) . toContain ( "tool-output/stray.txt" ) ;
828+ const { blob } = await git . readBlob ( {
829+ fs,
830+ dir,
831+ oid : healed . hash ,
832+ filepath : `tool-output/${ blobName } ` ,
833+ } ) ;
834+ expect ( new TextDecoder ( ) . decode ( blob ) ) . toBe ( "rewritten" ) ;
835+ } ) ;
836+
688837 test ( "commits an on-disk extra turn segment that is not in HEAD without writeTurns" , async ( ) => {
689838 const dir = tempDir ( ) ;
690839 const store = await createOptimizedContextStore ( dir ) ;
@@ -1617,6 +1766,33 @@ function readTurnsFromFile(fullPath: string): ConversationTurn[] {
16171766 . map ( ( line ) => JSON . parse ( line ) as ConversationTurn ) ;
16181767}
16191768
1769+ async function countPathOps (
1770+ op : "readFile" | "lstat" ,
1771+ marker : string ,
1772+ run : ( ) => Promise < unknown > ,
1773+ ) : Promise < number > {
1774+ let hits = 0 ;
1775+ const target = fs . promises as unknown as Record <
1776+ string ,
1777+ ( ...args : unknown [ ] ) => Promise < unknown >
1778+ > ;
1779+ const original = target [ op ] ;
1780+ if ( original === undefined ) {
1781+ throw new Error ( `missing fs.promises.${ op } ` ) ;
1782+ }
1783+ target [ op ] = ( ...args : unknown [ ] ) => {
1784+ const first = args [ 0 ] ;
1785+ if ( typeof first === "string" && first . includes ( marker ) ) hits += 1 ;
1786+ return original . apply ( fs . promises , args ) ;
1787+ } ;
1788+ try {
1789+ await run ( ) ;
1790+ } finally {
1791+ target [ op ] = original ;
1792+ }
1793+ return hits ;
1794+ }
1795+
16201796async function gitLsTree ( dir : string ) : Promise < string [ ] > {
16211797 const proc = Bun . spawn (
16221798 [ "git" , "-C" , dir , "ls-tree" , "-r" , "--name-only" , "HEAD" ] ,
0 commit comments