Alerts¶
Alerts are what the platform tells you without being asked. They are generated automatically (you do not create them) and they appear on the dashboard, over the API, and on any webhook endpoint subscribed to alert.created.
When they are generated¶
Every sync evaluates the rules for the organization it just synced, so an alert follows collection immediately. A sweeper also runs every six hours (at :30) to catch organizations that are not syncing, because a dormant organization still has to trip the inactivity rule.
An alert is filed once and stays. The same condition does not file a second alert while the first is unacknowledged, so a repository quiet for a year produces a single inactivity alert.
The rules¶
| Alert | Fires when | Severity |
|---|---|---|
| Inactivity | No activity for 30 days (90 for critical) | warning / critical |
| Low health score | Health score below 50 (below 30 for critical) | warning / critical |
| Health score drop | Score fell 15+ points against a week-old baseline | warning / critical |
| Activity drop | This week's activity fell 50%+ against last week's | warning / critical |
| High PR backlog | 10+ open pull requests (25+ for critical) | warning / critical |
| High issue backlog | 20+ open issues (50+ for critical) | warning / critical |
Two distinctions:
- Inactivity is absolute silence; activity drop is relative. A repository that went from 40 commits a week to 5 trips the drop rule while remaining active. The drop rule ignores repositories that were already quiet (fewer than 5 events in the prior week), so it does not fire on noise.
- Health drop compares against a week-old baseline. Scores are recomputed on every sync, so comparing consecutive values would measure minutes of drift.
Thresholds¶
The thresholds above are the defaults in AlertConfig, and they are currently not user-configurable: there is no settings page for them. Changing them means changing the defaults, or shipping a rule evaluator of your own (see Extension points).
Planned
Per-account thresholds, and per-rule enable/disable. The rules already take their configuration as an argument, so this is a settings surface over an existing mechanism.
Rules are plugins¶
The six rules ship in-tree, and they are RuleEvaluator plugins loaded through the same registry a third-party package uses. A rule of your own needs no change to Ospobox: "alert when a dependency we ship gains a critical advisory", say, or "alert when the only maintainer stops committing". See Extension points.
Research
Policy-as-code verdicts (hold, quarantine, patch, roll back) carrying their reasoning, evaluated against evidence. Alerts stay the currency the webhook bus carries, so anything subscribing today keeps working.
Alert types the API can return¶
inactivity, low_health_score, health_score_drop, activity_drop, high_pr_backlog, high_issue_backlog. Two further values exist in the schema, sync_failure and new_release, with no rule producing them yet.
What you can do with an alert¶
On the dashboard (Alerts in the sidebar), each alert can be:
- Marked read: clears it from the unread count, leaves it in the list
- Acknowledged: says you have dealt with it. The same condition can then file a fresh alert if it recurs
- Deleted: removes it entirely
You can filter by severity and by unread status. There is no snooze and no bulk action beyond "mark all as read".
Over the API¶
import httpx
client = httpx.Client(
base_url="http://localhost:8000/api",
headers={"Authorization": f"Bearer {token}"},
)
# Unread alerts, most recent first
alerts = client.get("/alerts/", params={"is_read": False}).json()
# Filter by severity
critical = client.get("/alerts/", params={"severity": "critical"}).json()
# Acknowledge one
client.patch(f"/alerts/{alert_id}/acknowledge")
# Mark everything read
client.patch("/alerts/read-all")
GET /api/alerts/ also reports unread and total counts, which feed the dashboard badge.
Getting alerts out¶
Webhooks are the supported route. An endpoint subscribed to alert.created receives every alert as it is filed, HMAC-signed, with retries; see Webhooks. Anything downstream hangs off that: a chat notification, an issue in your tracker, a deployment hold.
Email carries alerts inside the daily and weekly digests when SMTP is configured. Per-alert email and per-alert-type delivery preferences are unbuilt. The NotificationPreference model has fields for both, and nothing reads them yet.
Planned
Chat destinations (Slack, Discord, Teams, Matrix, Telegram and the rest) through one dispatcher subscribing to the webhook bus. Per account, with a send-test, and filterable by severity. See the roadmap.
What to expect on a new install¶
The first alert pass over an existing account is noisy. Health scores start empty, so every quiet repository files one low-health alert the first time the rules run. Acknowledge the batch; the dedup keeps it to one per repository, and later passes are quiet.
Archived repositories are skipped entirely. An archive flag states that the project is finished, which is a fact about the repository and never a health finding.