Preserve live trial results across cleanup timeouts

This commit is contained in:
twentyOne2x 2026-07-16 07:29:06 +02:00
parent b59bee8844
commit 9f7913eaec
2 changed files with 49 additions and 25 deletions

View file

@ -882,30 +882,33 @@ def fetch_remote_report(
) -> dict[str, Any] | None: ) -> dict[str, Any] | None:
report_path = f"/tmp/{report_prefix}-{run_id}.json" report_path = f"/tmp/{report_prefix}-{run_id}.json"
unlink_line = " p.unlink()\n" if unlink else "" unlink_line = " p.unlink()\n" if unlink else ""
proc = subprocess.run( try:
[ proc = subprocess.run(
"ssh", [
"-i", "ssh",
str(SSH_KEY), "-i",
"-o", str(SSH_KEY),
"BatchMode=yes", "-o",
"-o", "BatchMode=yes",
"StrictHostKeyChecking=accept-new", "-o",
VPS, "StrictHostKeyChecking=accept-new",
"sudo -u teleo -H /home/teleo/.hermes/hermes-agent/venv/bin/python -", VPS,
], "sudo -u teleo -H /home/teleo/.hermes/hermes-agent/venv/bin/python -",
input=( ],
"import json\n" input=(
"from pathlib import Path\n" "import json\n"
f"p = Path({report_path!r})\n" "from pathlib import Path\n"
"if p.exists():\n" f"p = Path({report_path!r})\n"
" print(p.read_text(encoding='utf-8'))\n" "if p.exists():\n"
f"{unlink_line}" " print(p.read_text(encoding='utf-8'))\n"
), f"{unlink_line}"
text=True, ),
capture_output=True, text=True,
timeout=60, capture_output=True,
) timeout=180,
)
except subprocess.TimeoutExpired:
return None
if proc.returncode != 0 or not proc.stdout.strip(): if proc.returncode != 0 or not proc.stdout.strip():
return None return None
return json.loads(redact(proc.stdout.strip())) return json.loads(redact(proc.stdout.strip()))
@ -966,7 +969,9 @@ def run_remote(
result["parsed"] = fetched result["parsed"] = fetched
result["parsed_from_report_file"] = True result["parsed_from_report_file"] = True
else: else:
fetch_remote_report(run_id, report_prefix=report_prefix) result["remote_report_cleanup_confirmed"] = (
fetch_remote_report(run_id, report_prefix=report_prefix) is not None
)
return result return result

View file

@ -89,6 +89,25 @@ def test_successful_stdout_is_redacted_before_json_parsing(monkeypatch) -> None:
assert secret not in json.dumps(result) assert secret not in json.dumps(result)
def test_successful_stdout_survives_remote_report_cleanup_timeout(monkeypatch) -> None:
completed = subprocess.CompletedProcess([], 0, stdout=json.dumps({"run_id": "complete"}) + "\n", stderr="")
calls = 0
def fake_run(*args, **kwargs):
nonlocal calls
calls += 1
if calls == 1:
return completed
raise subprocess.TimeoutExpired(args[0], timeout=180)
monkeypatch.setattr(suite.subprocess, "run", fake_run)
result = suite.run_remote(prompts=[])
assert result["parsed"] == {"run_id": "complete"}
assert result["remote_report_cleanup_confirmed"] is False
def test_safety_gate_passes_only_for_complete_no_send_no_write_run() -> None: def test_safety_gate_passes_only_for_complete_no_send_no_write_run() -> None:
report = safe_report() report = safe_report()