Skip to content

ci: calm-rotation CI failure screen (repo + PR number, gentle LED, snooze retired) - #20

Merged
sumitake merged 10 commits into
mainfrom
claude/ci-failure-screen-alerts-acb7d5
Aug 9, 2026
Merged

ci: calm-rotation CI failure screen (repo + PR number, gentle LED, snooze retired)#20
sumitake merged 10 commits into
mainfrom
claude/ci-failure-screen-alerts-acb7d5

Conversation

@sumitake

@sumitake sumitake commented Aug 9, 2026

Copy link
Copy Markdown
Owner

What & why

The CI failure screen was a priority-60 takeover that camped the panel (evicting the calendar) and only ever showed the workflow name. This reworks it on two axes:

  1. Helpful info — the failure/stuck frame now shows the repo + PR number: CI FAIL owner/repo #42 · workflow (falls back to the branch for push/fork runs with no PR). evaluate_runs stopped discarding the run dict; the ref reuses the existing _pr_or_branch helper.
  2. Part of the rotating flow — failure/stuck (and the quiet-green "CI ok") drop from PRIORITY_ALERT (60) to the overlay tier (PRIORITY_OVERLAY, 21) and join the existing dwell/silence rotation, so they alternate calmly with the upcoming calendar event, the running badge, and the quota gauges — and now rotate even when no job is running (previously the rotation only ran during an active run). One frame per failing run.

A gentle red LED stays lit while a workflow is failing (decoupled from which frame is on screen, with an explicit off on the failing→clear transition), mirroring calendar_countdown's proven LED lifecycle — so losing the screen takeover doesn't mean losing noticeability. This also fixes a latent gap where the CI red LED never reliably turned off after a failure resolved.

The start-button snooze subsystem is retired (no longer needed for a calm rotating frame): compute_alert_fingerprint, update_snooze, the snooze_state plumbing, the per-poll get_busy() call, and snooze_minutes config are all removed.

PRIORITY_ALERT (60) remains defined in busybar.display as the ladder's alert slot; it's simply no longer drawn to by ci_status. No calendar_countdown behavior changes — its tiers still outrank the overlay rotation, so an imminent event still wins.

Design & plan

  • Spec: docs/superpowers/specs/2026-08-08-ci-failure-rotation-frame-design.md
  • Plan: docs/superpowers/plans/2026-08-08-ci-failure-rotation-frame.md

Testing

  • Full suite green: 374 passed.
  • New/updated coverage: PR-vs-branch ref rendering; failure frame joining the rotation with no active run; dwell/silence for a failure frame; green folded into the rotation; the LED on→off lifecycle (red across a non-failure frame while a failure coexists; explicit #00000000 off via both the piggybacked and standalone LED_OFF_ELEMENTS paths); unified shape-clear gate across the new frame seams; cross-repo sequence ordering; snooze tests removed.

On-device verification (fw 1.1.1 — please confirm after deploy)

Not automatable in CI (spec §9):

  • A failure frame alternates with the calendar and running badge with visible dwell gaps (no permanent camp).
  • The red LED stays lit across a non-failure frame while a failure coexists, and turns off within one dwell after the failure clears.
  • An imminent calendar event still outranks the failure frame.
  • With poll_seconds = 120 and a lone failure + no running job, the frame redraws sparsely (~every 120s) — the persistent LED, not the frame cadence, is what carries "don't miss it."

Out-of-scope follow-up (noted, not in this PR)

integrations/calendar_countdown/README.md (~L150/167) still describes a persistent CI failure alert burying the calendar — dated phrasing now that CI failure rides the overlay rotation (the core claim, that the calendar climbs above it, still holds). The spec scoped calendar docs as a non-goal; happy to follow up separately.

🤖 Generated with Claude Code

sumitake and others added 10 commits August 8, 2026 22:55
RepoState.failing/.stuck moved to FailingRun objects, which silently
made compute_alert_fingerprint include the PR/branch ref. GitHub's REST
API can leave pull_requests empty for a poll or two before populating
it, so the ref can flip ("" -> "#42") for the same ongoing failure,
which would flip the fingerprint and cause update_snooze to treat it
as a new alert (clearing an active/pending snooze, re-firing the LED).

Key the fingerprint on (repo, workflow, category) only, restoring the
original documented semantics and ref-invariance.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…snooze from run_once

Task 4 of the ci_status overlay-rotation refactor. run_once now drives its
draw path entirely from build_overlay_sequence, so failing/stuck runs
rotate into view (and keep rotating) even with no CI run currently active,
instead of only alerting via a separate PRIORITY_ALERT path gated on the
running-badge machinery. The failure-driven LED is centralized through
resolve_ci_led_value/LED_OFF_COLOR/LED_OFF_ELEMENTS, tracked via the new
overlay_state["led_was_on"] key. The snooze subsystem is retired from the
loop (snooze_state parameter removed from run_once and main()); the
now-dead logic.py helpers and their tests are left in place for Task 5.
…ze_minutes default

Review findings: README's "Overlay dwell/rotation." paragraph still enumerated
only the running badge/quota frames, contradicting the already-updated ladder
table; config.py's DEFAULTS still carried a dead snooze_minutes default and
comment pointing at the deleted "Snoozing alerts" README section.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sumitake
sumitake merged commit bb32126 into main Aug 9, 2026
4 checks passed
@sumitake
sumitake deleted the claude/ci-failure-screen-alerts-acb7d5 branch August 9, 2026 07:28

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 565d426734

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +258 to 259
if overlay_gap_elapsed(last_dwell_end, now) < OVERLAY_DWELL_SECONDS:
return "overlay dwell gap; staying silent (letting the ambient app reclaim the screen)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply LED transitions before returning for the dwell gap

When a failure first appears or the last failure clears during an overlay silence gap—for example, when running_poll_seconds is configured below the 20-second dwell-plus-gap cycle—this early return sends no LED update. Consequently, a new failure does not light the LED and a resolved failure leaves it red until a later eligible draw, despite the documented per-poll LED lifecycle. Handle the on/off transition independently before returning for the panel dwell gap.

Useful? React with 👍 / 👎.

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