Skip to content

feat(observability): per-repo sweep-liveness watchdog with Sentry/Prometheus alerting and automatic targeted re-enqueue self-heal #3808

Description

@JSONbored

Context

Found during the 2026-07-06 incident audit (parent: #1667). During today's incident, the scheduled re-gate sweep silently stopped producing audit events for JSONbored/gittensory and JSONbored/metagraphed specifically for over an hour — while it kept succeeding for every other registered repo — and nothing in the system noticed. The operator had to manually query raw Postgres for ~2 hours to discover this, then manually INSERT rows directly into _selfhost_jobs to force recovery, bypassing every normal enqueue path.

Confirmed by exhaustive search: agent.sweep.regate/agent.sweep.fanout audit events (src/queue/processors.ts) are never read back by any dashboard, alert, or ops route anywhere in the repo. The existing anomaly-alerting module (src/review/alerts.ts, detectAnomalies) covers manual-rate spikes, DLQ counts, calibration drift, and disputed closes — nothing about the sweep/fan-out trigger itself going quiet. src/selfhost/sentry.ts's SENTRY_MONITOR_NAMES is a fixed 5-name list with no per-repo dimension — the regate sweep runs as ordinary logic inside the single scheduled-loop monitor, which only reports "error" if the whole 2-minute tick function throws. A sweep that silently produces zero candidates/dispatches for one specific repo does not throw — it just does nothing — so the scheduled-loop check-in reports "ok" every tick regardless of per-repo health.

Requirements

  • Add a periodic watchdog (piggybacking the existing ~2-min cron tick or its own schedule) that, for every repo eligible for the sweep (the same set fanOutAgentRegateSweepJobs already computes), checks whether that repo has produced any agent.sweep.regate/agent.sweep.fanout audit event within a configurable threshold (e.g. 3x expected cadence, default ~30-60 min).
  • When a repo is found stale beyond the threshold and has open, non-draft PRs eligible for regate, emit a structured Sentry-forwarded error naming the repo and how long it's been silent.
  • On the same detection, directly enqueue a fresh, targeted agent-regate-sweep job scoped to that specific repo — this is the actual self-heal action replacing the manual _selfhost_jobs INSERT the operator had to perform today.
  • Wrap each repo's check in its own try/catch so a DB blip checking one repo doesn't stop the watchdog checking others.
  • Add a gauge (e.g. gittensory_regate_sweep_seconds_since_last{repo}) and a Prometheus alert rule + Grafana panel so a stalled repo is visible proactively, not only via a Sentry page.
  • Distinguish "sweep ran, found 0 stale candidates" (healthy) from "sweep did not run this tick" (the actual failure) so a quiet repo with no work isn't falsely flagged.

Deliverables

  • New watchdog function (e.g. checkAgentRegateSweepLiveness or a new src/review/sweep-watchdog.ts), wired into the existing scheduled cron in src/index.ts.
  • New DB read helper for the most recent agent.sweep.* audit row per repo.
  • src/selfhost/metrics.ts: new gauge metric.
  • prometheus/rules/alerts.yml: new alert rule.
  • grafana/dashboards/gittensory.json: new panel.
  • Unit tests: (a) a repo stale beyond threshold triggers the Sentry log + targeted re-enqueue; (b) a repo with a recent audit event (including a legitimate "denied"/"queued" one) does not false-alarm; (c) a repo with genuinely zero open PRs is not flagged as broken.

Expected outcome

A repo whose scheduled sweep silently stops is detected within one watchdog cycle, gets both a Sentry-visible alert and an automatic targeted re-enqueue of its sweep — closing the exact gap that required manual database surgery today. This also directly covers the discovery of orphaned PRs like #3782/#3793 (zero audit_events, zero DB row) that a stalled sweep would otherwise never find.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions