From 11a543df69cfa40d5b8ca2210384e83c345cf8b8 Mon Sep 17 00:00:00 2001 From: Mengye Ren Date: Sat, 24 Oct 2026 00:41:02 -0400 Subject: [PATCH 1/2] Trajectory: record wall-clock time, not the caller's tick time --- src/outerloop/attempt.py | 5 +---- src/outerloop/tick.py | 4 +--- tests/test_attempt_review.py | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/outerloop/attempt.py b/src/outerloop/attempt.py index 74861eff..88a26152 100644 --- a/src/outerloop/attempt.py +++ b/src/outerloop/attempt.py @@ -3312,7 +3312,6 @@ def _resume_run( "outcome": result.outcome, "head_sha": candidate_sha, }, - at=now, ) submitted_park = bool(stage.get("submitted")) if stage.get("panel_skip"): @@ -4227,7 +4226,6 @@ def refuse( run_dir, "syscall.decision", {"verb": "submit", "outcome": "refused", "reason": redact(text, secrets)}, - at=now, ) append( run_dir, @@ -4643,7 +4641,7 @@ def refuse( # read: visible, plainly not merge-ready draft=draft, ) - record_event(run_dir, "pr.open", {"url": pr_url, "head_sha": result.candidate_sha}, at=now) + record_event(run_dir, "pr.open", {"url": pr_url, "head_sha": result.candidate_sha}) # Arm auto-merge, best-effort, and ONLY when branch protection # requires a human review — the guard keeps bot-never-merges # enforced in code, not in per-repo config. Never arm a draft, @@ -6278,7 +6276,6 @@ def finish_run( "ending", {"state": ending, "reason": note}, refs=file_refs(directory, report), - at=now, ) ref = str(record.stage.get("candidate_ref") or "") if snapshot_attempted and not ref: diff --git a/src/outerloop/tick.py b/src/outerloop/tick.py index 6d0dcdc4..ac317801 100644 --- a/src/outerloop/tick.py +++ b/src/outerloop/tick.py @@ -1191,9 +1191,7 @@ def wake(record: RunRecord, reason: str, tag: str) -> None: if dry_run or _wake(root, record, reason, dispatcher, now, holder): woken.append((record.run_id, tag)) if not dry_run: - record_event( - run_dir(root, record.run_id), "wake", {"reason": reason, "tag": tag}, at=now - ) + record_event(run_dir(root, record.run_id), "wake", {"reason": reason, "tag": tag}) ledger_blocked: set[str] = set() if github is not None and not dry_run: diff --git a/tests/test_attempt_review.py b/tests/test_attempt_review.py index f26c88d0..a3b845ba 100644 --- a/tests/test_attempt_review.py +++ b/tests/test_attempt_review.py @@ -1547,6 +1547,7 @@ def fail(*args, **kwargs): events = read(directory) assert [event["type"] for event in events] == ["ending"] assert events[0]["data"] == {"state": "merged", "reason": "PR merged"} + assert events[0]["ts"] > NOW # wall-clock time, not the caller's tick time assert events[0]["refs"][0]["path"] == "report.md" assert verify(directory, record.run_id) == [] From d9efd5acb3c696778dbc58853d3906a2c5c26315 Mon Sep 17 00:00:00 2001 From: Mengye Ren Date: Sat, 24 Oct 2026 00:45:45 -0400 Subject: [PATCH 2/2] Steward writes its report before finish_run, so the ending event hashes the report that stays --- src/outerloop/steward.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/outerloop/steward.py b/src/outerloop/steward.py index dc918bcf..3c559629 100644 --- a/src/outerloop/steward.py +++ b/src/outerloop/steward.py @@ -518,6 +518,10 @@ def changed_paths() -> list[str]: "resume_session_id": session.session_id or "", } ) + # written before finish_run, which keeps an existing report and + # records its hash in the trajectory's ending event + report_path = run_dir / "report.md" + _best_effort("run report", lambda: report_path.write_text(report), secrets) _best_effort( "final record", lambda: finish_run( @@ -533,8 +537,6 @@ def changed_paths() -> list[str]: ), secrets, ) - report_path = run_dir / "report.md" - _best_effort("run report", lambda: report_path.write_text(report), secrets) if issue_number: _best_effort( "issue report", @@ -696,6 +698,15 @@ def _arm() -> None: } ) report_path = run_dir / "report.md" + # before finish_run, so the ending event hashes the report that stays + wrote = _best_effort( + "error report", + lambda: report_path.write_text( + f"# Steward report — {config.target} / {config.benchmark}\n" + f"Outcome: **{outcome_label}**\nNote: {note}\n" + ), + secrets, + ) _best_effort( "ending record", lambda: finish_run( @@ -711,14 +722,6 @@ def _arm() -> None: ), secrets, ) - wrote = _best_effort( - "error report", - lambda: report_path.write_text( - f"# Steward report — {config.target} / {config.benchmark}\n" - f"Outcome: **{outcome_label}**\nNote: {note}\n" - ), - secrets, - ) if issue_number: if api_outage: release = (