You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: "p95 HTTP request latency is {{ $value | printf \"%.2f\" }}s over the last 5m (sustained 10m), breaching the 1s SLO."
371
371
runbook: "Check whether slowness is queue/DB/AI-bound: correlate with gittensory_queue_pending and Qdrant/AI latency. A rising p95 with flat error rate usually means a saturated dependency, not a bug."
summary: "gittensory AI review is repeatedly inconclusive"
389
+
description: "{{ $value | printf \"%.0f\" }} AI review(s) came back inconclusive over the last 30m (sustained 10m). Dual-AI review is repeatedly failing to produce a usable verdict."
390
+
runbook: "Check provider health and circuit-breaker state (gittensory_ai_provider_failures_total / gittensory_ai_provider_circuit_open_total) and verify AI_PROVIDER credentials are still valid for every configured reviewer."
391
+
392
+
- alert: GittensoryAiProviderCircuitOpen
393
+
# A provider's circuit breaker opens after AI_PROVIDER_FAILURE_THRESHOLD consecutive failures and
394
+
# short-circuits further attempts for a cooldown window -- ANY circuit-open event in 15m means that
395
+
# provider has been failing repeatedly and calls are being skipped fast rather than retried at full
396
+
# cost. Same absolute-increase style as GittensoryDeadLetterJobsGrowing: any occurrence is worth a look.
summary: "gittensory AI provider {{ $labels.provider }} circuit breaker is open"
403
+
description: "Provider {{ $labels.provider }} has failed repeatedly and its circuit breaker is skipping calls fast during its cooldown (sustained 5m)."
404
+
runbook: "Check that provider's credentials/reachability (CLI auth for claude-code/codex, or the configured API key/base URL for HTTP providers) via gittensory_ai_provider_failures_total{provider=\"...\"} and recent selfhost_ai_provider_failed logs."
warnings.push(`GitHub sync reached local cap of ${limit} item(s) for ${path}; next page cursor is ${nextCursor}.`);
3275
+
// `items.length` (not `limit`) is the actual count: page consumption is atomic, so a whole final page
3276
+
// can overrun the requested `limit` — `limit` is a page-boundary threshold, not a strict maximum.
3277
+
warnings.push(`GitHub sync reached local cap of ${limit} item(s) for ${path} (fetched ${items.length} after completing page ${page}); next page cursor is ${nextCursor}.`);
// Fail loud when the two SLOTS the dual-review plan actually uses (the first two names) are the same
839
+
// provider: routeProviders' `byName` map collapses duplicate provider names to one runtime instance, so
840
+
// "dual review" would silently become "one provider called twice" -- no independent second opinion, and
841
+
// that provider's outage takes down both slots. A THIRD+ duplicate further down the list is fine; only
842
+
// the first two matter because resolveAiReviewerPlan below caps reviewers at names.slice(0, 2).
843
+
if(names[0]===names[1]){
844
+
thrownewError(
845
+
`ai_reviewer_providers_not_distinct: AI_PROVIDER lists "${names[0]}" for both dual-review reviewer slots — configure two distinct providers (e.g. AI_PROVIDER=claude-code,codex) for independent dual review, or a single provider (AI_PROVIDER=codex) for single-reviewer mode.`,
0 commit comments