File size: 2,982 Bytes
ed1d39f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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