@@ -614,6 +614,96 @@ def test_no_keyword_no_forecast(self):
614614 assert "Permissions:" not in result .stdout
615615
616616
617+ class TestClarificationBudgetHudFile :
618+ """Regression tests for #1433: CODINGBUDDY_HUD_STATE_FILE must be honored
619+ when persisting standalone clarification question budget."""
620+
621+ def _run_hook (self , prompt , home_dir , hud_state_file ):
622+ import os as _os
623+
624+ hook_path = Path (__file__ ).parent / "user-prompt-submit.py"
625+ input_data = json .dumps ({"prompt" : prompt })
626+ env = _os .environ .copy ()
627+ env ["HOME" ] = str (home_dir )
628+ env ["CLAUDE_PROJECT_DIR" ] = str (home_dir )
629+ env ["CODINGBUDDY_HUD_STATE_FILE" ] = str (hud_state_file )
630+ env .pop ("CODINGBUDDY_RULES_DIR" , None )
631+ return subprocess .run (
632+ [sys .executable , str (hook_path )],
633+ input = input_data ,
634+ capture_output = True ,
635+ text = True ,
636+ env = env ,
637+ cwd = str (home_dir ),
638+ )
639+
640+ def _init_hud (self , hud_file ):
641+ _lib_dir = Path (__file__ ).parent / "lib"
642+ if str (_lib_dir ) not in sys .path :
643+ sys .path .insert (0 , str (_lib_dir ))
644+ from hud_state import init_hud_state
645+ init_hud_state ("test-session" , "5.0.0" , state_file = str (hud_file ))
646+
647+ def _read_hud (self , hud_file ):
648+ return json .loads (Path (hud_file ).read_text ())
649+
650+ def test_custom_hud_file_budget_decrements (self ):
651+ """Ambiguous prompt twice with custom HUD file: budget goes 3→2→1."""
652+ import tempfile
653+
654+ with tempfile .TemporaryDirectory () as tmpdir :
655+ Path (tmpdir , ".claude" ).mkdir ()
656+ hud_file = Path (tmpdir ) / "custom-hud.json"
657+ self ._init_hud (hud_file )
658+
659+ # First run: budget 3 → 2
660+ r1 = self ._run_hook ("PLAN: improve auth flow" , tmpdir , hud_file )
661+ assert r1 .returncode == 0
662+ assert "CLARIFICATION REQUIRED" in r1 .stdout
663+ state1 = self ._read_hud (hud_file )
664+ assert state1 ["questionBudget" ] == 2
665+
666+ # Second run: budget 2 → 1
667+ r2 = self ._run_hook ("PLAN: improve auth flow" , tmpdir , hud_file )
668+ assert r2 .returncode == 0
669+ state2 = self ._read_hud (hud_file )
670+ assert state2 ["questionBudget" ] == 1
671+
672+ def test_default_path_still_works (self ):
673+ """Without CODINGBUDDY_HUD_STATE_FILE, default path behavior unchanged."""
674+ import tempfile
675+ import os as _os
676+
677+ with tempfile .TemporaryDirectory () as tmpdir :
678+ Path (tmpdir , ".claude" ).mkdir ()
679+ # Use default path under custom HOME
680+ codingbuddy_dir = Path (tmpdir ) / ".codingbuddy"
681+ codingbuddy_dir .mkdir ()
682+ hud_file = codingbuddy_dir / "hud-state.json"
683+ self ._init_hud (hud_file )
684+
685+ hook_path = Path (__file__ ).parent / "user-prompt-submit.py"
686+ input_data = json .dumps ({"prompt" : "PLAN: fix something" })
687+ env = _os .environ .copy ()
688+ env ["HOME" ] = str (tmpdir )
689+ env ["CLAUDE_PROJECT_DIR" ] = str (tmpdir )
690+ env .pop ("CODINGBUDDY_HUD_STATE_FILE" , None )
691+ env .pop ("CODINGBUDDY_RULES_DIR" , None )
692+
693+ result = subprocess .run (
694+ [sys .executable , str (hook_path )],
695+ input = input_data ,
696+ capture_output = True ,
697+ text = True ,
698+ env = env ,
699+ cwd = str (tmpdir ),
700+ )
701+ assert result .returncode == 0
702+ assert "CLARIFICATION REQUIRED" in result .stdout
703+ state = self ._read_hud (hud_file )
704+ assert state ["questionBudget" ] == 2
705+
706+
617707if __name__ == "__main__" :
618708 import pytest
619709 pytest .main ([__file__ , "-v" ])
0 commit comments