feat(ops): add fatigue-controlled PagerDuty paging for ops anomalies - #5116
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | c28295a | Commit Preview URL Branch Preview URL |
Jul 11 2026, 03:39 PM |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5116 +/- ##
==========================================
+ Coverage 94.21% 94.22% +0.01%
==========================================
Files 470 471 +1
Lines 39743 39821 +78
Branches 14506 14533 +27
==========================================
+ Hits 37442 37520 +78
Misses 1645 1645
Partials 656 656
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Caution 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥 🛑 Gittensory review result - fixes requiredReview updated: 2026-07-11 15:37:13 UTC
🛑 Suggested Action - Manual Review
Review summary Blockers
Nits — 6 non-blocking
Why this is blocked
CI checks failing
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
…4937) Direct app-level integration mirroring the existing Discord webhook pattern: global + per-repo routing keys, both experimental and default-OFF via GITTENSORY_ENABLE_PAGERDUTY. Hooks the existing ops_anomaly detector rather than every captureError call, and pages at the worst detected anomaly's severity. Two independent alert-fatigue controls beyond PagerDuty's own dedup_key (which coalesces duplicate incidents but not duplicate pages for a still-open one): a global + per-repo minimum severity floor (default error, so routine calibration nudges never page) and a global + per-repo cooldown window between repeat pages for the same condition.
e65c7c2 to
c28295a
Compare
… service (#5121) * feat(selfhost): wire native Docker Compose secrets for the gittensory service Adds a `secrets:` block for the 10 highest-value secrets (GitHub App private key, webhook secret, API/MCP/internal-job tokens, the setup token, the two token-encryption master keys, the Orb enrollment secret, and the PagerDuty routing key), file-mounted at /run/secrets/<name> instead of a plain environment/env_file value visible via `docker inspect`/`docker compose config`. Zero application code changes: reuses the existing generic <NAME>_FILE loader (src/selfhost/load-file-secrets.ts). Purely additive and backward-compatible -- an inline .env value always wins over the file, so migrating is optional and can be done one secret at a time. scripts/selfhost-init-secrets.sh idempotently creates empty placeholder files so a deploy never breaks for an operator who hasn't opted in; wired into both deploy scripts before they touch docker compose. * docs(selfhost): drop the misleading #4937 tag from secrets comments #4937 is the unrelated PagerDuty on-call issue (closed via #5116) -- this feature has no filed issue, so referencing it as "#4937-secrets-hardening" was actively misleading, not just unlinked.


Summary
src/services/notify-pagerduty.ts) as a direct app-level notifier, mirroringnotify-discord.ts's exact per-repo routing precedence:PAGERDUTY_REPO_ROUTING_KEYS(JSON map) over the globalPAGERDUTY_ROUTING_KEYfallback, gated byGITTENSORY_ENABLE_PAGERDUTY.ops_anomalydetector insrc/review/ops-wire.ts(the codebase's own "something needs a human" signal) rather than paging on everycaptureError/captureReviewFailurecall, which would need its own frequency policy first.PAGERDUTY_MIN_SEVERITY/PAGERDUTY_REPO_MIN_SEVERITY, defaulterror, so routine calibration nudges like a gate false-positive spike never page — only active-incident anomalies like a review/failure burst do), and a global + per-repo cooldown window (PAGERDUTY_COOLDOWN_MINUTES/PAGERDUTY_REPO_COOLDOWN_MINUTES, default 60m) between repeat pages for the same ongoing condition. Both are on top of PagerDuty's owndedup_keycoalescing, which prevents duplicate incidents but not duplicate pages for a still-open one.Closes #4937.
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlint(vianpm run test:ci)npm run typechecknpm run test:coveragelocally — both new files (notify-pagerduty.ts, and the changed lines inops-wire.ts) are 100% line + branch covered on the diff.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderate— 0 vulnerabilities.test/unit/notify-pagerduty.test.ts(28 tests) and the newrunOpsAlertsPagerDuty wiring tests intest/unit/ops-wire.test.ts.Ran the full
npm run test:cigate locally (all steps green) plusnpm audit --audit-level=moderate.Safety
apps/gittensory-ui/src/lib/selfhost-env-reference.tsvianpm run selfhost:env-referenceafter addingsrc/services/notify-pagerduty.tsto the generator's scanned source roots (mirroring the existingnotify-discord.tsentry), so the new self-host env vars are documented.Notes