Skip to content

fix(control-plane): dashboard success rate defaults to 100% and actually covers 24h - #792

Merged
AbirAbbas merged 2 commits into
mainfrom
fix/dashboard-success-rate-24h
Jul 17, 2026
Merged

fix(control-plane): dashboard success rate defaults to 100% and actually covers 24h#792
AbirAbbas merged 2 commits into
mainfrom
fix/dashboard-success-rate-24h

Conversation

@AbirAbbas

Copy link
Copy Markdown
Contributor

Summary

The dashboard "Success rate" stat (desktop app tile labeled last 24 hours, web dashboard success stat) had three compounding bugs:

  • Idle looked like an outage. With no executions, /api/ui/v1/dashboard/summary returned success_rate: 0, so an idle system showed a red 0% as if everything had failed. Nothing failing should read healthy: it now returns 100.
  • "Last 24 hours" was actually calendar-today UTC. The rate was computed from executions started since midnight UTC — at 01:00 UTC that's a one-hour sample. It now covers a rolling [now-24h, now] window (derived from the already-fetched today+yesterday query results, no extra storage round-trip).
  • In-flight runs counted as failures. Running/waiting executions sat in the denominator. The denominator is now terminal executions only, so kicking off a workflow no longer drags the rate down before it finishes.

While fixing the consumer side, the web dashboard turned out to double-scale the value (successRate * 100 on an already-0–100 percentage) — its test fixtures mirrored the same wrong 0–1 scale, so tests passed while a real server response would have rendered 9100%. Fixture scales are aligned with the actual API contract.

The desktop app needs no change: its "last 24 hours" label is now truthful and it renders the server value as-is.

Validation contract

  • Zero executions in the window → success_rate is 100 (idle reads healthy, not failed)
  • Only terminal executions count: a running/waiting execution affects neither numerator nor denominator
  • The window is rolling 24h: an execution started 23h ago (yesterday, UTC) counts; one started 24.5h ago does not
  • executions.today / executions.yesterday remain calendar-day counts (unchanged)
  • Web dashboard renders 91 from the API as "91%", not "9100%"

Each new test maps to one of the items above (TestExecutionsSummarySuccessRateRolling24h, the calculateSuccessRate edge cases, the idle-summary endpoint test, and the corrected web fixtures).

Test plan

  • go test ./... — 49 packages pass; the one failure (internal/server: TestStartAndStopCoverAdditionalBranches) reproduces identically on clean origin/main in the same environment (WSL-specific, green in CI)
  • golangci-lint run — no findings in touched files
  • Web UI: npm ci && npm run build and npm run test:coverage — 683/683 tests pass

🤖 Generated with Claude Code

AbirAbbas and others added 2 commits July 17, 2026 12:38
The summary endpoint computed success_rate from calendar-today (UTC)
executions only, returned 0 when nothing had run, and counted in-flight
executions as failures. An idle system therefore showed a red 0% under a
label claiming "last 24 hours".

Compute the rate over executions started in the rolling last-24h window,
count only terminal executions in the denominator, and report 100 when
none have finished - no completed runs means nothing has failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The summary endpoint returns success_rate as a 0-100 percentage, but the
dashboard multiplied it by 100 again before display. The test fixtures
mirrored the same wrong 0-1 scale, so the tautology passed while a real
server response would have rendered 9100%. Align the fixtures with the
actual API contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@AbirAbbas
AbirAbbas requested a review from a team as a code owner July 17, 2026 16:39
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 86.90% 87.40% ↓ -0.50 pp 🟡
sdk-go 92.50% 92.00% ↑ +0.50 pp 🟢
sdk-python 93.82% 93.73% ↑ +0.09 pp 🟢
sdk-typescript 90.44% 90.42% ↑ +0.02 pp 🟢
web-ui 84.75% 84.79% ↓ -0.04 pp 🟡
aggregate 85.54% 85.75% ↓ -0.21 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 19 100.00%
sdk-go 0 ➖ no changes
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

@AbirAbbas
AbirAbbas merged commit 623084e into main Jul 17, 2026
29 checks passed
@AbirAbbas
AbirAbbas deleted the fix/dashboard-success-rate-24h branch July 17, 2026 17:08
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.

1 participant