[F034] orchestrator: re-stamp respawn last_check at restore

_pm_made_rule_following_retry bounds its tracing_gap audit lookup with
since = record.get('last_check'). A stale persisted last_check from before
the restart matched pre-restart tracing_gap rows, falsely resetting the
breaker on the very first post-restart spawn — exactly when a fresh strike
count should be evaluating current state.

_partition_respawn_rows now re-stamps last_check to the restore time on
every restorable entry, bounding the lookup to post-restart gaps only.
This commit is contained in:
Renn F
2026-06-28 11:00:00 +02:00
parent fa8e567edd
commit e3011ec145
2 changed files with 32 additions and 2 deletions
@@ -80,6 +80,26 @@ def test_partition_drops_terminal_and_missing_rows() -> None:
}
def test_partition_restamps_last_check_to_now_to_avoid_stale_tracing_gap() -> None:
# F034: a persisted last_check from BEFORE the restart would make the first
# post-restart ``_pm_made_rule_following_retry`` audit lookup
# (``since = record.get("last_check")``) match a PRE-restart tracing_gap
# row, falsely resetting the breaker on the very first post-restart spawn —
# exactly when a fresh strike count should be evaluating current state.
# Restore must re-stamp last_check to the restore time so only post-restart
# tracing gaps can reset the counter.
tid = uuid4()
stale_check = datetime(2026, 6, 20, tzinfo=UTC)
rows = [_row(tid, last_check=stale_check)]
restore_now = datetime(2026, 6, 28, 12, 0, tzinfo=UTC)
restored, stale = AgentOrchestrator._partition_respawn_rows(
rows, {tid: "in_progress"}, now=restore_now
)
assert stale == []
assert restored[("be-pm", str(tid))]["last_check"] == restore_now
assert restored[("be-pm", str(tid))]["last_check"] != stale_check
# --------------------------------------------------------------------------- #
# Startup loader
# --------------------------------------------------------------------------- #