@@ -960,3 +960,107 @@ describe("createOptimizedContextStore unpublished rewrite", () => {
960960 expect ( turnTexts ( ( await store . load ( ) ) . turns ) ) . toEqual ( [ "era-2" ] ) ;
961961 } ) ;
962962} ) ;
963+
964+ describe ( "createOptimizedContextStore prompt dedupe (CL-9026)" , ( ) => {
965+ const PROMPT_FILE = "prompt.jsonl" ;
966+
967+ function toolResultTurn ( body : string ) : ConversationTurn {
968+ return {
969+ role : "user" ,
970+ content : [
971+ {
972+ type : "tool_result" ,
973+ callId : "call-1" ,
974+ content : [ { type : "text" , text : body } ] ,
975+ } ,
976+ ] ,
977+ timestamp : 1 ,
978+ } ;
979+ }
980+
981+ function cloneTurns ( turns : ConversationTurn [ ] ) : ConversationTurn [ ] {
982+ return turns . map (
983+ ( t ) => JSON . parse ( JSON . stringify ( t ) ) as ConversationTurn ,
984+ ) ;
985+ }
986+
987+ test ( "identical writePrompt writes no prompt segment" , async ( ) => {
988+ const dir = tempDir ( ) ;
989+ const store = await createOptimizedContextStore ( dir ) ;
990+ const turns = [ turn ( "a" ) , turn ( "b" ) ] ;
991+ await store . writeTurns ( [ ...turns ] ) ;
992+ await store . writePrompt ( [ ...turns ] ) ;
993+ await store . writePrompt ( cloneTurns ( turns ) ) ;
994+
995+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( false ) ;
996+ expect ( await listSegmentFiles ( dir , PROMPT_FILE ) ) . toEqual ( [ ] ) ;
997+
998+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
999+ await store . commit ( { message : "identical prompt is a no-op" } ) ;
1000+ expect ( await gitLsTree ( dir ) ) . not . toContain ( PROMPT_FILE ) ;
1001+
1002+ // A fresh instance compares against on-disk live turns and also skips.
1003+ const fresh = await createOptimizedContextStore ( dir ) ;
1004+ await fresh . writePrompt ( cloneTurns ( turns ) ) ;
1005+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( false ) ;
1006+ } ) ;
1007+
1008+ test ( "differing writePrompt still writes the prompt snapshot" , async ( ) => {
1009+ const dir = tempDir ( ) ;
1010+ const store = await createOptimizedContextStore ( dir ) ;
1011+ const live = [ turn ( "a" ) , toolResultTurn ( "x" . repeat ( 1000 ) ) ] ;
1012+ await store . writeTurns ( [ ...live ] ) ;
1013+
1014+ const shrunk = [ turn ( "a" ) , toolResultTurn ( "summarized" ) ] ;
1015+ await store . writePrompt ( shrunk ) ;
1016+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( true ) ;
1017+ expect ( fs . readFileSync ( path . join ( dir , PROMPT_FILE ) , "utf-8" ) ) . toBe (
1018+ jsonl ( shrunk ) ,
1019+ ) ;
1020+
1021+ // An appended ephemeral turn also changes the prompt and still writes.
1022+ const ephemeralDir = tempDir ( ) ;
1023+ const ephemeralStore = await createOptimizedContextStore ( ephemeralDir ) ;
1024+ await ephemeralStore . writeTurns ( [ ...live ] ) ;
1025+ const withEphemeral = [ ...cloneTurns ( live ) , turn ( "ephemeral" ) ] ;
1026+ await ephemeralStore . writePrompt ( withEphemeral ) ;
1027+ expect (
1028+ fs . readFileSync ( path . join ( ephemeralDir , PROMPT_FILE ) , "utf-8" ) ,
1029+ ) . toBe ( jsonl ( withEphemeral ) ) ;
1030+ } ) ;
1031+
1032+ test ( "turns-only store loads live turns and commits no prompt file" , async ( ) => {
1033+ const dir = tempDir ( ) ;
1034+ const store = await createOptimizedContextStore ( dir ) ;
1035+ await store . writeTurns ( [ turn ( "a" ) , turn ( "b" ) ] ) ;
1036+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
1037+ const first = await store . commit ( { message : "turns only" } ) ;
1038+
1039+ expect ( turnTexts ( ( await store . load ( ) ) . turns ) ) . toEqual ( [ "a" , "b" ] ) ;
1040+
1041+ const fresh = await createOptimizedContextStore ( dir ) ;
1042+ expect ( turnTexts ( ( await fresh . load ( ) ) . turns ) ) . toEqual ( [ "a" , "b" ] ) ;
1043+ const second = await fresh . commit ( { message : "turns-only no-op" } ) ;
1044+ expect ( second . hash ) . toBe ( first . hash ) ;
1045+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( false ) ;
1046+ expect ( await gitLsTree ( dir ) ) . not . toContain ( PROMPT_FILE ) ;
1047+ } ) ;
1048+
1049+ test ( "identical writePrompt after a differing one removes stale prompt segments" , async ( ) => {
1050+ const dir = tempDir ( ) ;
1051+ const store = await createOptimizedContextStore ( dir ) ;
1052+ const live = [ turn ( "a" ) , turn ( "b" ) ] ;
1053+ await store . writeTurns ( [ ...live ] ) ;
1054+ await store . writePrompt ( [ turn ( "a" ) ] ) ;
1055+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( true ) ;
1056+
1057+ await store . writePrompt ( cloneTurns ( live ) ) ;
1058+ expect ( fs . existsSync ( path . join ( dir , PROMPT_FILE ) ) ) . toBe ( false ) ;
1059+ expect ( await listSegmentFiles ( dir , PROMPT_FILE ) ) . toEqual ( [ ] ) ;
1060+
1061+ await store . writeMetadata ( EMPTY_CHECKPOINT_METADATA ) ;
1062+ await store . commit ( { message : "stale prompt removed" } ) ;
1063+ expect ( await gitLsTree ( dir ) ) . not . toContain ( PROMPT_FILE ) ;
1064+ expect ( turnTexts ( ( await store . load ( ) ) . turns ) ) . toEqual ( [ "a" , "b" ] ) ;
1065+ } ) ;
1066+ } ) ;
0 commit comments