Files
clockula/CHANGELOG.md
T
makiolajandClaude Opus 5 a522d68098 docs: the alarm engine, and the blind spot it closes
ARCHITECTURE gains a section 11 on the engine itself — the state machine, the
two AlarmManager slots, the DST table, and the chain that keeps a denied
permission from turning into a silent morning. Section 5's known blind spot is
amended rather than deleted: the boot id exists now, and the stopwatch repair
moved from M7 to here.

Section 9's "no permissions are declared yet, deliberately" is finally untrue,
so it is replaced with the real set and why each one is there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 16:05:31 +02:00

4.0 KiB

Changelog

All notable changes to Clockula are documented here.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. Tag sections feed the release notes — see docs/RELEASING.md.

[Unreleased]

Added

  • Project skeleton: Gradle build, version catalog, Hilt, Compose and the Material 3 Expressive theme over floret-kit's identity module, seeded #6B7A5C — the third 120° hue rotation of Calendula's slate, completing the family's palette.
  • floret-kit as a git submodule wired in as a Gradle composite build.
  • Crash capture and the report surface via floret-kit's core-crash; per-app language support via core-locale.
  • Launcher and notification icons: a line-art clock face carrying the family's Calendula bloom badge.
  • Full release pipeline, Codeberg-canonical from the first commit — CI, translations, release (F-Droid repo + Codeberg release + Google Play) and Renovate, with the F-Droid reproducibility rules intact.
  • The locked specification: docs/PLAN.md and docs/ROADMAP.md.
  • Preferences over floret-kit's new core-prefs: SettingsPrefs holds the appearance slice (theme mode, dynamic colour) in a DataStore of Clockula's own, under the family's key names. The theme now follows the stored preference — light/dark override and dynamic colour persist across launches instead of always following the system — and an unrelated preference write no longer re-emits it.
  • floret-kit's core-di supplies the @IoDispatcher the preference store runs on, so Clockula no longer declares its own dispatcher qualifier.
  • Clockula's own storage, headless: a Room database with alarms, timers, world_clocks and stopwatch_laps, its schema exported and committed at every version so each migration is reviewable and testable.
  • Plain-Kotlin alarms, timers, world clocks and stopwatch runs behind four repository interfaces exposing Flows — nothing above the data layer knows Room exists, and a test fails the build if anyone reaches through. A corrupt row degrades on read (a clamped time, an unknown ringtone, a rotted zone id) rather than crashing the list it appears in.
  • Alarm and timer settings are inherited, not copied: a per-alarm ringtone, snooze, vibrate, volume ramp or dismiss challenge is an override, so changing an app default later reaches every alarm the user never customised.
  • The clock defaults and the stopwatch's running state now live in DataStore alongside the appearance preferences, clamped on read as well as on write, so a hand-edited or restored file cannot produce a setting the user could never have chosen.
  • The wall-clock / elapsed-realtime split, made explicit: alarm records follow the system clock, while running timers and the stopwatch are anchored to time since boot. Changing the device's time — forwards or backwards — cannot warp either, and a timer that survives a reboot falls back to its wall-clock estimate and says so instead of vanishing.
  • Alarms that ring. A repeat schedule that is re-resolved against the device's zone every time anything moves, so the clock going forwards, backwards or through a daylight-saving transition cannot lose one: a 02:30 alarm on a spring-forward night rings at 03:30 rather than vanishing, and on a fall-back night rings once rather than twice.
  • Skip-next-occurrence that skips exactly one occurrence, snooze with a per-alarm interval and limit, and a snooze that is still kept after a reboot.
  • An alarm that keeps ringing through a reboot or a process kill — the ring is rebuilt from storage, not from memory — and one that still rings when the full-screen-intent or notification permission is denied. The chain of fallbacks ends in vibration, never in silence.
  • The post-reboot repair: a running timer no longer counts down from an anchor the reboot killed, and the stopwatch no longer invents a segment it never ran.