feat(autotheme): fire at the configured sunrise/sunset, not a 15-min poll
All checks were successful
Check / eval (push) Successful in 4m14s

The timer's OnCalendar now bakes the configured times (falling back
like _hhmm_to_min on a hand-edited state), so the switch lands at the
configured minute instead of up to 15 minutes late. The original
poll's robustness case is covered without it: Persistent catches
transitions missed while powered off, systemd fires elapsed calendar
timers on resume, and OnStartupSec settles the theme after login.

Baked times mean a time edit must rebuild: the menu's Sunrise/Sunset
writes now run `auto --force` when enabled (one rebuild re-bakes the
timer and lands on the right theme, same as the enable flow). Day and
night slugs stay live reads — but with no poll to catch them up,
editing the slot currently on screen applies immediately via a plain
`auto`. New eval check `auto-theme-timer` asserts the bake
state-bridges-style: configured times reach OnCalendar, garbage falls
back to 07:00/20:00, disabled installs no unit. Docs + hardware-queue
entry updated to the new semantics.

V2: checks.auto-theme (KVM VM, passed) covers the auto engine the
timer ticks; checks.auto-theme-timer (eval, passed) covers the unit;
OnCalendar strings systemd-analyze-validated; the rebuilt menu script
passes bash -n with the new branches in place. V3 pending: live timer
firing at the exact configured minute on hardware (existing
"Auto-theme pair flip" queue entry, refreshed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 22:31:02 +01:00
parent ac24ac7c34
commit f658b0087e
6 changed files with 136 additions and 43 deletions

View File

@@ -70,11 +70,12 @@ State lives in `settings.autoTheme`:
| `day` / `night` | theme slugs (see `nomarchy-state-sync list`) — the exclusive pairs are made for this: `boreal-dawn`/`boreal`, `executive-ivory`/`executive-slate`, `kiln-clay`/`kiln`, `summer-day`/`summer-night` |
| `sunrise` / `sunset` | switch times, `"HH:MM"` (24-hour) |
A timer re-checks every ~15 minutes: the day theme applies around sunrise, the
night theme around sunset — but it only rebuilds when the active theme
actually needs to change, so most checks do nothing. Enabling rebuilds once
(to install the timer); disabling is instant. Preview the current decision
without switching with `nomarchy-state-sync auto --which`.
A timer fires exactly at the configured sunrise and sunset (plus once shortly
after login, and it catches up on a transition missed while the machine was
off or asleep) — it only rebuilds when the active theme actually needs to
change. The times are baked into the timer, so editing them (or enabling)
rebuilds once; disabling is instant. Preview the current decision without
switching with `nomarchy-state-sync auto --which`.
These values are deliberately kept at normal priority in the modules, so they
stay owned by the theme system. If you *insist* on pinning one in `home.nix`