fix(mcp): get_anomaly shows a quick Steward restart, not only a gap over 90 s (#5862)
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m27s
CI / integration (push) Successful in 1m33s
CI / publish (push) Successful in 1m15s

A redeploy's new process ticks at once, so its once-a-minute samples never
broke for 90 s and get_anomaly showed none of the day's restarts. The first
self-monitor tick in a process now records restart_gap_secs (time since the
last process's last sample), and steward_gaps shows each one as a restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 16:11:27 -04:00
co-authored by Claude Opus 5.5
parent 22da64a284
commit 4ded8ecee4
8 changed files with 68 additions and 11 deletions
+22
View File
@@ -144,3 +144,25 @@ def test_unwatched_counts_only_a_real_gap():
assert sm.unwatched_secs(None, now) == 0.0 # first ever tick
assert sm.unwatched_secs(now - timedelta(seconds=61), now) == 0.0 # an ordinary minute
assert sm.unwatched_secs(now - timedelta(minutes=7), now) == 420.0 # a deploy or outage
def test_a_fresh_process_marks_its_restart_once(monkeypatch):
"""#5862: the first tick records how long since the last process's last
sample, however short; later ticks and a first-ever start don't."""
from datetime import datetime, timedelta, timezone
recorded = _patch_recorder(monkeypatch)
monkeypatch.setattr(sm, "_started", False)
monkeypatch.setattr(_FakeSession, "last", datetime.now(timezone.utc) - timedelta(seconds=40))
asyncio.run(sm.record_self_metrics(_FakeApp()))
asyncio.run(sm.record_self_metrics(_FakeApp()))
gaps = [v for (_s, _r, m, v) in recorded if m == "restart_gap_secs"]
assert len(gaps) == 1 and 39 <= gaps[0] <= 60
assert dict((m, v) for (_s, _r, m, v) in recorded)["unwatched_secs"] == 0.0
recorded.clear()
monkeypatch.setattr(sm, "_started", False)
monkeypatch.setattr(_FakeSession, "last", None)
asyncio.run(sm.record_self_metrics(_FakeApp()))
assert "restart_gap_secs" not in {m for (_s, _r, m, _v) in recorded}