| 1 | """Tests for intent-aware clarify strategy.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | from loader.runtime.clarify_strategy import ( |
| 6 | ClarifyPressureKind, |
| 7 | ClarifySlot, |
| 8 | ClarifySnapshot, |
| 9 | ClarifyStage, |
| 10 | assess_clarify_snapshot, |
| 11 | build_clarify_question, |
| 12 | ) |
| 13 | |
| 14 | |
| 15 | def test_assess_clarify_snapshot_prioritizes_touchpoints_for_broad_answer() -> None: |
| 16 | assessment = assess_clarify_snapshot( |
| 17 | task="Improve Loader so it feels more like claw-code.", |
| 18 | answer="Make it nicer.", |
| 19 | snapshot=ClarifySnapshot( |
| 20 | task_statement="Improve Loader so it feels more like claw-code.", |
| 21 | explicit_sections=[], |
| 22 | ), |
| 23 | ) |
| 24 | |
| 25 | assert assessment.unresolved_slots |
| 26 | assert assessment.focus_slot == ClarifySlot.LIKELY_TOUCHPOINTS |
| 27 | assert "Out-of-scope boundaries are still underspecified." in assessment.unresolved_questions |
| 28 | |
| 29 | |
| 30 | def test_build_clarify_question_targets_requested_slot() -> None: |
| 31 | question = build_clarify_question( |
| 32 | "Tighten the runtime behavior.", |
| 33 | ClarifySlot.NON_GOALS, |
| 34 | ) |
| 35 | |
| 36 | assert "out of scope" in question.lower() |
| 37 | |
| 38 | |
| 39 | def test_assess_clarify_snapshot_requests_tradeoff_pressure_pass_on_later_round() -> None: |
| 40 | assessment = assess_clarify_snapshot( |
| 41 | task="Improve Loader runtime behavior.", |
| 42 | answer="Focus on src/loader/runtime/conversation.py.", |
| 43 | snapshot=ClarifySnapshot( |
| 44 | task_statement="Improve Loader runtime behavior.", |
| 45 | explicit_sections=["desired_outcome", "likely_touchpoints"], |
| 46 | desired_outcome=["Make the runtime flow more disciplined."], |
| 47 | likely_touchpoints=["src/loader/runtime/conversation.py"], |
| 48 | ), |
| 49 | round_index=2, |
| 50 | ) |
| 51 | |
| 52 | assert assessment.stage == ClarifyStage.READINESS |
| 53 | assert assessment.pressure_kind == ClarifyPressureKind.TRADEOFF |
| 54 | assert assessment.pressure_pass_complete is False |
| 55 | assert "non_goals" in assessment.missing_readiness_gates |
| 56 | assert "decision_boundaries" in assessment.missing_readiness_gates |
| 57 | |
| 58 | |
| 59 | def test_assess_clarify_snapshot_marks_pressure_pass_complete_for_boundary_answer() -> None: |
| 60 | assessment = assess_clarify_snapshot( |
| 61 | task="Improve Loader runtime behavior.", |
| 62 | answer="Keep the CLI unchanged and do not broaden the UX without confirming first.", |
| 63 | snapshot=ClarifySnapshot( |
| 64 | task_statement="Improve Loader runtime behavior.", |
| 65 | explicit_sections=["desired_outcome", "non_goals", "decision_boundaries"], |
| 66 | desired_outcome=["Make the runtime flow more disciplined."], |
| 67 | non_goals=["Keep the CLI unchanged."], |
| 68 | decision_boundaries=["Confirm before broad UX changes."], |
| 69 | ), |
| 70 | round_index=2, |
| 71 | ) |
| 72 | |
| 73 | assert assessment.pressure_pass_complete is True |
| 74 | assert "pressure_pass" not in assessment.missing_readiness_gates |
| 75 | |
| 76 | |
| 77 | def test_build_clarify_question_can_render_pressure_pass_question() -> None: |
| 78 | question = build_clarify_question( |
| 79 | "Tighten the runtime behavior.", |
| 80 | ClarifySlot.NON_GOALS, |
| 81 | ClarifyPressureKind.TRADEOFF, |
| 82 | ) |
| 83 | |
| 84 | assert "unchanged" in question.lower() or "avoid" in question.lower() |