tenseleyflow/loader / 0310078

Browse files

Advance child write fallbacks

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
03100782cf11357467fb458b282bf27b8286e452
Parents
62a6597
Tree
0628168

2 changed files

StatusFile+-
M src/loader/runtime/repair.py 8 1
M tests/test_repair.py 70 0
src/loader/runtime/repair.pymodified
@@ -1319,6 +1319,9 @@ class ResponseRepairer:
13191319
             target,
13201320
             outline_label=outline_label,
13211321
             allow_initial_concrete_output=initial_concrete_output,
1322
+            has_confirmed_substantive_output_file_progress=(
1323
+                has_confirmed_substantive_output_file_progress
1324
+            ),
13221325
             retry_number=retry_number,
13231326
         )
13241327
         if html_payload_line:
@@ -1589,9 +1592,13 @@ class ResponseRepairer:
15891592
         *,
15901593
         outline_label: str | None,
15911594
         allow_initial_concrete_output: bool,
1595
+        has_confirmed_substantive_output_file_progress: bool,
15921596
         retry_number: int,
15931597
     ) -> str | None:
1594
-        if retry_number < 5:
1598
+        minimum_retry_number = 5
1599
+        if not self._is_index_html_target(target):
1600
+            minimum_retry_number = 3
1601
+        if retry_number < minimum_retry_number:
15951602
             return None
15961603
         if target.suffix.lower() not in {".html", ".htm"}:
15971604
             return None
tests/test_repair.pymodified
@@ -1038,6 +1038,15 @@ def test_empty_response_retry_adds_root_html_starter_shape_for_first_index_write
10381038
     chapters.mkdir()
10391039
     index_path = guide_root / "index.html"
10401040
     chapter_one = chapters / "01-introduction.html"
1041
+    index_path.write_text(
1042
+        "\n".join(
1043
+            [
1044
+                '<a href="chapters/01-introduction.html">Chapter 1: Introduction to Nginx</a>',
1045
+                '<a href="chapters/02-installation.html">Chapter 2: Installation and Setup</a>',
1046
+                "",
1047
+            ]
1048
+        )
1049
+    )
10411050
 
10421051
     implementation_plan = temp_dir / "implementation.md"
10431052
     implementation_plan.write_text(
@@ -1600,6 +1609,67 @@ def test_repeated_first_substantive_retry_includes_minimal_payload_shape(
16001609
     assert "../index.html" in decision.retry_message
16011610
 
16021611
 
1612
+def test_empty_response_retry_surfaces_minimal_child_html_payload_earlier_after_progress(
1613
+    temp_dir: Path,
1614
+) -> None:
1615
+    context = build_context(
1616
+        temp_dir=temp_dir,
1617
+        use_react=False,
1618
+    )
1619
+    repairer = ResponseRepairer(context)
1620
+
1621
+    guide_root = temp_dir / "guides" / "nginx"
1622
+    chapters = guide_root / "chapters"
1623
+    guide_root.mkdir(parents=True)
1624
+    chapters.mkdir()
1625
+    index_path = guide_root / "index.html"
1626
+    chapter_one = chapters / "01-introduction.html"
1627
+    index_path.write_text(
1628
+        "\n".join(
1629
+            [
1630
+                '<a href="chapters/01-introduction.html">Chapter 1: Introduction to Nginx</a>',
1631
+                '<a href="chapters/02-installation.html">Chapter 2: Installation and Setup</a>',
1632
+                "",
1633
+            ]
1634
+        )
1635
+    )
1636
+
1637
+    implementation_plan = temp_dir / "implementation.md"
1638
+    implementation_plan.write_text(
1639
+        "\n".join(
1640
+            [
1641
+                "# Implementation Plan",
1642
+                "",
1643
+                "## File Changes",
1644
+                f"- `{guide_root}/`",
1645
+                f"- `{index_path}`",
1646
+                f"- `{chapters}/`",
1647
+                f"- `{chapter_one}`",
1648
+                "",
1649
+            ]
1650
+        )
1651
+    )
1652
+
1653
+    dod = create_definition_of_done("Create a multi-file nginx guide.")
1654
+    dod.implementation_plan = str(implementation_plan)
1655
+    dod.touched_files.append(str(index_path))
1656
+    dod.completed_items.append("Develop the main index.html file with proper structure")
1657
+    dod.pending_items.append("Create first chapter file (01-introduction.html)")
1658
+
1659
+    decision = repairer.handle_empty_response(
1660
+        task="Create a multi-file nginx guide.",
1661
+        original_task=None,
1662
+        empty_retry_count=3,
1663
+        max_empty_retries=6,
1664
+        dod=dod,
1665
+    )
1666
+
1667
+    assert decision.should_continue is True
1668
+    assert decision.retry_message is not None
1669
+    assert "If blanking continues, use this minimal starter payload shape" in decision.retry_message
1670
+    assert "<title>Chapter 1: Introduction to Nginx</title>" in decision.retry_message
1671
+
1672
+
16031673
 def test_first_substantive_retry_activates_on_first_empty_turn(
16041674
     temp_dir: Path,
16051675
 ) -> None: