@@ -352,6 +352,121 @@ describe("prometheus-md-only", () => {
352352 } )
353353 } )
354354
355+ describe ( "boulder state priority over message files (fixes #927)" , ( ) => {
356+ const BOULDER_DIR = join ( tmpdir ( ) , `boulder-test-${ randomUUID ( ) } ` )
357+ const BOULDER_FILE = join ( BOULDER_DIR , ".sisyphus" , "boulder.json" )
358+
359+ beforeEach ( ( ) => {
360+ mkdirSync ( join ( BOULDER_DIR , ".sisyphus" ) , { recursive : true } )
361+ } )
362+
363+ afterEach ( ( ) => {
364+ rmSync ( BOULDER_DIR , { recursive : true , force : true } )
365+ } )
366+
367+ //#given session was started with prometheus (first message), but /start-work set boulder agent to atlas
368+ //#when user types "continue" after interruption (memory cleared, falls back to message files)
369+ //#then should use boulder state agent (atlas), not message file agent (prometheus)
370+ test ( "should prioritize boulder agent over message file agent" , async ( ) => {
371+ // given - prometheus in message files (from /plan)
372+ setupMessageStorage ( TEST_SESSION_ID , "prometheus" )
373+
374+ // given - atlas in boulder state (from /start-work)
375+ writeFileSync ( BOULDER_FILE , JSON . stringify ( {
376+ active_plan : "/test/plan.md" ,
377+ started_at : new Date ( ) . toISOString ( ) ,
378+ session_ids : [ TEST_SESSION_ID ] ,
379+ plan_name : "test-plan" ,
380+ agent : "atlas"
381+ } ) )
382+
383+ const hook = createPrometheusMdOnlyHook ( {
384+ client : { } ,
385+ directory : BOULDER_DIR ,
386+ } as never )
387+
388+ const input = {
389+ tool : "Write" ,
390+ sessionID : TEST_SESSION_ID ,
391+ callID : "call-1" ,
392+ }
393+ const output = {
394+ args : { filePath : "/path/to/code.ts" } ,
395+ }
396+
397+ // when / then - should NOT block because boulder says atlas, not prometheus
398+ await expect (
399+ hook [ "tool.execute.before" ] ( input , output )
400+ ) . resolves . toBeUndefined ( )
401+ } )
402+
403+ test ( "should use prometheus from boulder state when set" , async ( ) => {
404+ // given - atlas in message files (from some other agent)
405+ setupMessageStorage ( TEST_SESSION_ID , "atlas" )
406+
407+ // given - prometheus in boulder state (edge case, but should honor it)
408+ writeFileSync ( BOULDER_FILE , JSON . stringify ( {
409+ active_plan : "/test/plan.md" ,
410+ started_at : new Date ( ) . toISOString ( ) ,
411+ session_ids : [ TEST_SESSION_ID ] ,
412+ plan_name : "test-plan" ,
413+ agent : "prometheus"
414+ } ) )
415+
416+ const hook = createPrometheusMdOnlyHook ( {
417+ client : { } ,
418+ directory : BOULDER_DIR ,
419+ } as never )
420+
421+ const input = {
422+ tool : "Write" ,
423+ sessionID : TEST_SESSION_ID ,
424+ callID : "call-1" ,
425+ }
426+ const output = {
427+ args : { filePath : "/path/to/code.ts" } ,
428+ }
429+
430+ // when / then - should block because boulder says prometheus
431+ await expect (
432+ hook [ "tool.execute.before" ] ( input , output )
433+ ) . rejects . toThrow ( "can only write/edit .md files" )
434+ } )
435+
436+ test ( "should fall back to message files when session not in boulder" , async ( ) => {
437+ // given - prometheus in message files
438+ setupMessageStorage ( TEST_SESSION_ID , "prometheus" )
439+
440+ // given - boulder state exists but for different session
441+ writeFileSync ( BOULDER_FILE , JSON . stringify ( {
442+ active_plan : "/test/plan.md" ,
443+ started_at : new Date ( ) . toISOString ( ) ,
444+ session_ids : [ "other-session-id" ] ,
445+ plan_name : "test-plan" ,
446+ agent : "atlas"
447+ } ) )
448+
449+ const hook = createPrometheusMdOnlyHook ( {
450+ client : { } ,
451+ directory : BOULDER_DIR ,
452+ } as never )
453+
454+ const input = {
455+ tool : "Write" ,
456+ sessionID : TEST_SESSION_ID ,
457+ callID : "call-1" ,
458+ }
459+ const output = {
460+ args : { filePath : "/path/to/code.ts" } ,
461+ }
462+
463+ // when / then - should block because falls back to message files (prometheus)
464+ await expect (
465+ hook [ "tool.execute.before" ] ( input , output )
466+ ) . rejects . toThrow ( "can only write/edit .md files" )
467+ } )
468+ } )
469+
355470 describe ( "without message storage" , ( ) => {
356471 test ( "should handle missing session gracefully (no agent found)" , async ( ) => {
357472 // given
0 commit comments