Keep setup before missing files
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
3cbd1bb06a2eee323b318aa4ccc414a8c47acd87- Parents
-
89ffea4 - Tree
b776be4
3cbd1bb
3cbd1bb06a2eee323b318aa4ccc414a8c47acd8789ffea4
b776be4| Status | File | + | - |
|---|---|---|---|
| M |
src/loader/runtime/workflow.py
|
1 | 1 |
| M |
tests/test_repair.py
|
5 | 5 |
| M |
tests/test_workflow.py
|
37 | 0 |
src/loader/runtime/workflow.pymodified@@ -1515,7 +1515,7 @@ def _todo_is_subsumed_by_concrete_missing_artifact( | ||
| 1515 | 1515 | target, expect_directory = missing_artifact |
| 1516 | 1516 | if _contains_any(text, _BROAD_SETUP_HINTS): |
| 1517 | 1517 | if not expect_directory: |
| 1518 | - return True | |
| 1518 | + return target.parent.exists() | |
| 1519 | 1519 | return target.is_dir() |
| 1520 | 1520 | return False |
| 1521 | 1521 | |
tests/test_repair.pymodified@@ -308,22 +308,22 @@ def test_empty_response_retry_mentions_write_can_create_missing_parent_directori | ||
| 308 | 308 | assert decision.should_continue is True |
| 309 | 309 | assert decision.retry_message is not None |
| 310 | 310 | assert ( |
| 311 | - "Resume with this exact next step: continue `Write main index.html for nginx guide` " | |
| 312 | - "by creating `index.html`." | |
| 311 | + "Resume with this exact next step: create `index.html`." | |
| 313 | 312 | in decision.retry_message |
| 314 | 313 | ) |
| 315 | 314 | assert ( |
| 316 | - f"Prefer one `write(content=...)` call for `{index_path}` before more research." | |
| 315 | + f"Prefer one `write` call for `{index_path}` before any more reference reads." | |
| 317 | 316 | in decision.retry_message |
| 318 | 317 | ) |
| 319 | 318 | assert ( |
| 320 | - f'Emit this tool shape now: `write(file_path="{index_path.resolve(strict=False)}", content="...")`.' | |
| 319 | + "The `write` tool can create that file's parent directories automatically, so do the write in one step instead of stopping for a separate mkdir." | |
| 321 | 320 | in decision.retry_message |
| 322 | 321 | ) |
| 323 | 322 | assert ( |
| 324 | - "Do not restart discovery unless one specific missing fact blocks that file write." | |
| 323 | + f'Emit this tool shape now: `write(file_path="{index_path.resolve(strict=False)}", content="...")`.' | |
| 325 | 324 | in decision.retry_message |
| 326 | 325 | ) |
| 326 | + assert "Do not restart discovery unless one specific missing fact blocks this step." in decision.retry_message | |
| 327 | 327 | |
| 328 | 328 | |
| 329 | 329 | def test_empty_response_retry_recovers_blocked_empty_file_path_to_concrete_target( |
tests/test_workflow.pymodified@@ -20,6 +20,7 @@ from loader.runtime.workflow import ( | ||
| 20 | 20 | extract_verification_commands_from_markdown, |
| 21 | 21 | infer_pending_todo_output_target, |
| 22 | 22 | merge_refreshed_todos_with_existing_scope, |
| 23 | + preferred_pending_todo_item, | |
| 23 | 24 | preserve_task_grounded_acceptance_criteria, |
| 24 | 25 | reconcile_aggregate_completion_steps, |
| 25 | 26 | sync_todos_to_definition_of_done, |
@@ -1018,6 +1019,42 @@ def test_infer_pending_todo_output_target_maps_broad_setup_to_planned_directory( | ||
| 1018 | 1019 | assert target == chapters.resolve(strict=False) |
| 1019 | 1020 | |
| 1020 | 1021 | |
| 1022 | +def test_preferred_pending_todo_item_keeps_setup_step_when_missing_file_parent_absent( | |
| 1023 | + tmp_path: Path, | |
| 1024 | +) -> None: | |
| 1025 | + dod = create_definition_of_done("Create a multi-file nginx guide.") | |
| 1026 | + nginx_root = tmp_path / "Loader" / "guides" / "nginx" | |
| 1027 | + chapters = nginx_root / "chapters" | |
| 1028 | + index_path = nginx_root / "index.html" | |
| 1029 | + implementation_plan = tmp_path / "implementation.md" | |
| 1030 | + implementation_plan.write_text( | |
| 1031 | + "\n".join( | |
| 1032 | + [ | |
| 1033 | + "# Implementation Plan", | |
| 1034 | + "", | |
| 1035 | + "## File Changes", | |
| 1036 | + f"- `{chapters}/`", | |
| 1037 | + f"- `{index_path}`", | |
| 1038 | + "", | |
| 1039 | + ] | |
| 1040 | + ) | |
| 1041 | + ) | |
| 1042 | + dod.implementation_plan = str(implementation_plan) | |
| 1043 | + dod.pending_items = [ | |
| 1044 | + "Create the nginx directory structure", | |
| 1045 | + "Create the main index.html file for nginx guide", | |
| 1046 | + "Complete the requested work", | |
| 1047 | + ] | |
| 1048 | + | |
| 1049 | + preferred = preferred_pending_todo_item( | |
| 1050 | + dod, | |
| 1051 | + project_root=tmp_path, | |
| 1052 | + missing_artifact=(index_path.resolve(strict=False), False), | |
| 1053 | + ) | |
| 1054 | + | |
| 1055 | + assert preferred == "Create the nginx directory structure" | |
| 1056 | + | |
| 1057 | + | |
| 1021 | 1058 | def test_advance_todos_from_tool_call_does_not_complete_content_study_from_root_index_read() -> None: |
| 1022 | 1059 | dod = create_definition_of_done("Create a multi-file nginx guide.") |
| 1023 | 1060 | sync_todos_to_definition_of_done( |