Skip to content

fix: close two roadmap items — snapshot retry and reduce motion - #7

Merged
snaka merged 2 commits into
mainfrom
fix/roadmap-small-items
Sep 12, 2026
Merged

snaka merged 2 commits into
mainfrom
fix/roadmap-small-items

Conversation

@snaka

@snaka snaka commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Closes the two smallest deferred items in ROADMAP.md.

A failed live snapshot now retries

refreshFromSnapshot() swallowed a failed session.snapshot and returned,
leaving the menu bar on the previous state until the next event or the 300 s
resync. SnapshotRetry (new, in KelpieCore) hands out a bounded run of
delays — 250 ms, 500 ms, 1 s — and then gives up, so the resync stays the
backstop rather than being competed with.

The budget is a local in refreshFromSnapshot, not a stored property: the
event-driven refresh and the resync loop can be in flight at once, and a shared
budget would let them spend each other's attempts. It also means teardown has
nothing extra to reset.

Giving up deliberately does not call coalescer.didRefresh(). Leaving the
window open is what makes the next event refresh immediately instead of
debouncing on top of a UI that is already stale.

Reduce Motion is picked up when it changes

refreshUI() already read accessibilityDisplayShouldReduceMotion fresh on
every render; what was missing was any wake when the setting itself changed.
With agents working and no state change due, turning Reduce Motion on left the
spinner running until the next snapshot. Subscribing to
accessibilityDisplayOptionsDidChangeNotification supplies that wake — the
reading side is unchanged.

Verification

  • swift test — 132 tests, all passing, including four new SnapshotRetry tests written before the type existed
  • xcodebuild Debug build of the app target — succeeds, no warnings

The Reduce Motion observer has no automated coverage (AppCoordinator has
none) and has not been exercised at runtime: confirming it means toggling the
system setting against a running build.

🤖 Generated with Claude Code

snaka and others added 2 commits September 12, 2026 15:53
A `session.snapshot` request that failed after an event was swallowed, so
the menu bar kept showing the previous state until the next event or the
300 s resync — whichever came first. Observed once, transiently, while
herdr was mid-replay.

`SnapshotRetry` hands out a short, bounded run of delays (250 ms, 500 ms,
1 s) and then gives up, leaving the resync as the backstop. The budget is
a local in `refreshFromSnapshot`, so the event-driven refresh and the
resync loop cannot spend each other's attempts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`refreshUI()` already reads `accessibilityDisplayShouldReduceMotion`
fresh on every render, but nothing woke the menu bar when the setting
itself changed. With agents working and no state change due, turning
Reduce Motion on left the spinner running until the next snapshot —
up to the 300 s resync away.

Subscribing to `accessibilityDisplayOptionsDidChangeNotification` is
the missing wake; the reading side needed no change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@snaka
snaka merged commit fec86a6 into main Sep 12, 2026
2 checks passed
@snaka
snaka deleted the fix/roadmap-small-items branch September 12, 2026 07:11
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