@@ -779,29 +779,59 @@ describe("buildSessionEntry", () => {
779779 expect ( checkpointEntry . lineMap ) . toStrictEqual ( [ ] ) ;
780780 } ) ;
781781
782- it ( "keeps cron-run deleted archives opaque when the live session store entry is gone" , async ( ) => {
783- const archivePath = path . join ( tmpDir , "cron-run.jsonl.deleted.2026-02-16T22-27-33.000Z" ) ;
784- const jsonlLines = [
785- JSON . stringify ( {
786- type : "message" ,
787- message : {
782+ it . each ( [
783+ [
784+ "as the first message" ,
785+ [ ] ,
786+ [
787+ "Assistant: The digest job failed because the API token expired." ,
788+ "User: Please remember: my preferred vendor is Acme Robotics and budget is 5000 USD." ,
789+ "Assistant: Noted. Acme Robotics, budget 5000 USD." ,
790+ ] ,
791+ [ 2 , 3 , 4 ] ,
792+ ] ,
793+ [
794+ "after ordinary messages" ,
795+ [
796+ { role : "user" , content : "Remember before: project codename is Atlas." } ,
797+ { role : "assistant" , content : "Saved project codename Atlas." } ,
798+ ] ,
799+ [
800+ "User: Remember before: project codename is Atlas." ,
801+ "Assistant: Saved project codename Atlas." ,
802+ "Assistant: The digest job failed because the API token expired." ,
803+ "User: Please remember: my preferred vendor is Acme Robotics and budget is 5000 USD." ,
804+ "Assistant: Noted. Acme Robotics, budget 5000 USD." ,
805+ ] ,
806+ [ 1 , 2 , 4 , 5 , 6 ] ,
807+ ] ,
808+ ] ) (
809+ "does not wipe an archive when a user message starts with [cron: %s (#98241)" ,
810+ async ( _position , precedingMessages , expectedContent , expectedLineMap ) => {
811+ const archivePath = path . join ( tmpDir , "ordinary.jsonl.deleted.2026-02-16T22-27-33.000Z" ) ;
812+ const messages = [
813+ ...precedingMessages ,
814+ { role : "user" , content : "[cron:daily-digest] why did my digest job fail last night?" } ,
815+ {
816+ role : "assistant" ,
817+ content : "The digest job failed because the API token expired." ,
818+ } ,
819+ {
788820 role : "user" ,
789- content : "[cron:job-1 Codex Sessions Sync] Run internal sync ." ,
821+ content : "Please remember: my preferred vendor is Acme Robotics and budget is 5000 USD ." ,
790822 } ,
791- } ) ,
792- JSON . stringify ( {
793- type : "message" ,
794- message : { role : "assistant" , content : "Internal cron output that must stay out." } ,
795- } ) ,
796- ] ;
797- fsSync . writeFileSync ( archivePath , jsonlLines . join ( "\n" ) ) ;
823+ { role : "assistant" , content : "Noted. Acme Robotics, budget 5000 USD." } ,
824+ ] ;
825+ const jsonlLines = messages . map ( ( message ) => JSON . stringify ( { type : "message" , message } ) ) ;
826+ fsSync . writeFileSync ( archivePath , jsonlLines . join ( "\n" ) ) ;
798827
799- const entry = requireSessionEntry ( await buildSessionEntry ( archivePath ) ) ;
828+ const entry = requireSessionEntry ( await buildSessionEntry ( archivePath ) ) ;
800829
801- expect ( entry . content ) . toBe ( "" ) ;
802- expect ( entry . lineMap ) . toStrictEqual ( [ ] ) ;
803- expect ( entry . generatedByCronRun ) . toBe ( true ) ;
804- } ) ;
830+ expect ( entry . generatedByCronRun ) . toBeFalsy ( ) ;
831+ expect ( entry . content ) . toBe ( expectedContent . join ( "\n" ) ) ;
832+ expect ( entry . lineMap ) . toStrictEqual ( expectedLineMap ) ;
833+ } ,
834+ ) ;
805835
806836 it ( "keeps cron-run reset archives opaque when session metadata preserves the cron key" , async ( ) => {
807837 const archivePath = path . join ( tmpDir , "cron-run.jsonl.reset.2026-02-16T22-26-33.000Z" ) ;
0 commit comments