| from pathlib import Path | |
| from src.progress import progress_from_events | |
| def test_worker_uses_structured_repair_contract_and_artifacts(): | |
| worker = Path("src/worker_payload.py").read_text(encoding="utf-8") | |
| assert "STRUCTURED REPAIR MODE" in worker | |
| assert "classify_repair_failure" in worker | |
| assert "REPAIR_BRIEF.md" in worker | |
| assert "REPAIR_PLAN.md" in worker | |
| assert "REPAIR_SUMMARY.md" in worker | |
| assert "sanity_check_repair_workspace" in worker | |
| assert "Do not rebuild from scratch" in worker | |
| assert "Never fake outputs" in worker | |
| def test_worker_emits_repair_specific_events_and_revalidation_failure(): | |
| worker = Path("src/worker_payload.py").read_text(encoding="utf-8") | |
| for step in [ | |
| "repair_diagnosis", | |
| "repair_plan", | |
| "repair_patch", | |
| "repair_upload", | |
| "repair_validation", | |
| "failure", | |
| ]: | |
| assert f'"{step}"' in worker | |
| assert "Repair attempted, but validation still failed" in worker | |
| assert "Run failed after structured repair attempt" in worker | |
| def test_progress_timeline_has_repair_and_failure_steps(): | |
| js = Path("web/static/progress.js").read_text(encoding="utf-8") | |
| py = Path("src/progress.py").read_text(encoding="utf-8") | |
| for step in ["repair_diagnosis", "repair_plan", "repair_patch", "repair_upload", "repair_validation"]: | |
| assert step in js | |
| assert step in py | |
| assert "visibleCompactTimelineGroups" in js | |
| assert "step_status[\"failure\"] = \"failed\"" in py | |
| def test_failed_after_repair_has_red_failure_point(): | |
| progress = progress_from_events( | |
| [ | |
| {"ts": "2026-06-05T08:50:00+00:00", "step": "bootstrap", "status": "success"}, | |
| {"ts": "2026-06-05T08:51:00+00:00", "step": "upload_files", "status": "success"}, | |
| {"ts": "2026-06-05T08:52:00+00:00", "step": "api_validation", "status": "failed", "message": "runtime error"}, | |
| {"ts": "2026-06-05T08:53:00+00:00", "step": "repair_diagnosis", "status": "success"}, | |
| {"ts": "2026-06-05T08:54:00+00:00", "step": "repair_patch", "status": "success"}, | |
| {"ts": "2026-06-05T08:55:00+00:00", "step": "repair_validation", "status": "failed"}, | |
| {"ts": "2026-06-05T08:55:10+00:00", "step": "failure", "status": "failed"}, | |
| ], | |
| state={"status": "failed"}, | |
| ) | |
| assert progress["status"] == "failed" | |
| by_step = {item["step"]: item["status"] for item in progress["timeline"]} | |
| assert by_step["failure"] == "failed" | |
| assert any(status == "failed" for status in by_step.values()) | |
| def test_repair_documents_are_exposed_in_run_documents_dock(): | |
| bucket = Path("src/bucket.py").read_text(encoding="utf-8") | |
| runs = Path("web/static/runs.js").read_text(encoding="utf-8") | |
| assert '"id": "repair"' in bucket | |
| assert "REPAIR_SUMMARY.md" in bucket | |
| assert "Brief, plan and summary" in bucket | |
| assert "id:'repair'" in runs | |
| assert "tree/runs/${runId}/repair" in runs | |