Skip to content

fix(mcp): scan the whole window for backup problems, not the newest rows (audit M9) - #439

Merged
passcod merged 1 commit into
mainfrom
claude/pr-370-fix-m9-mcp-backup-problems
Aug 1, 2026
Merged

fix(mcp): scan the whole window for backup problems, not the newest rows (audit M9)#439
passcod merged 1 commit into
mainfrom
claude/pr-370-fix-m9-mcp-backup-problems

Conversation

@passcod

@passcod passcod commented Aug 1, 2026

Copy link
Copy Markdown
Member

Fixes M9 (medium) from the audit in #370.

The bug

find_backup_problems advertises "failed runs in the last 24h", but only inspected the 20 newest runs per group (5 for maintenance), applying the time and outcome tests in Rust afterwards. The row cap therefore decided which runs got looked at, and the effective window shrank in proportion to how often a group backs up.

A group reporting ~120 runs/day with a failure 8h ago followed by more than 20 successes reports no failed_run at all — the failure is squarely inside the advertised window. The busier the group, the smaller its window, which is the opposite of what an operator would assume. Same shape for stuck_maintenance behind its cap of 5.

The fix

Both scans use the existing filtered queries — BackupRunFilters { outcome: Failure, since: now - 24h } and MaintenanceOutcomeFilter::Running — so selection happens in SQL. The per-group cap survives as a noise bound (PROBLEM_LIMIT), but it now bounds real problems rather than deciding which ones are visible.

Tests

backup_problems_finds_a_failure_behind_many_later_successes (private-server, through the real /api/mcp endpoint) — a ready group with a failure 8h ago and 30 later successes, all inside the window. Confirmed to fail against the unfixed scan, which reports problems: [].

Last of four in the audit's "filter-after-LIMIT in the MCP layer" pattern (M7, M8, M9, L14).


Generated by Claude Code

`find_backup_problems` advertises "failed runs in the last 24h", but only
inspected the 20 newest runs per group (5 for maintenance) and applied the
time and outcome tests in Rust afterwards. The row cap therefore decided
which runs got looked at, and the effective window shrank in proportion to
how often a group backs up.

A group reporting ~120 runs a day with a failure 8h ago followed by more than
20 successes reports no `failed_run` at all, even though the failure sits
squarely inside the advertised window. The busier the group, the smaller its
window — the opposite of what an operator would assume. Same shape for
`stuck_maintenance`.

Both scans now select on outcome and time in SQL. The per-group cap stays as
a noise bound, but it now bounds real problems rather than deciding which
ones are visible.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SGfH1cdFKPnKpM7ytRThft
@passcod
passcod marked this pull request as ready for review August 1, 2026 22:14
@passcod
passcod added this pull request to the merge queue Aug 1, 2026
Merged via the queue into main with commit aa39b5e Aug 1, 2026
7 checks passed
@passcod
passcod deleted the claude/pr-370-fix-m9-mcp-backup-problems branch August 1, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants