From e8fceec240859d1e768526f39fbe8f064c2b5b39 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sat, 12 Sep 2026 13:07:53 +0200 Subject: [PATCH] docs: mark M4 done Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Wmy1BpCKi8KeSjaWhYuCPV --- docs/ROADMAP.md | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 3df8b19..39932f9 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -10,14 +10,13 @@ Status legend: โœ… done ยท ๐Ÿšง in progress ยท โฌœ not started ## Current state (one line) -โœ… **M3 done.** Clockula's alarms ring. Next-fire resolution is a pure function -over a repeat mask and a zone, DST-correct in both directions; skip and snooze -each have a persisted watermark; the engine registers only the single next alarm -via `setAlarmClock`, is driven by five thin receivers, and rings through a -foreground service that survives process death and reboot and never degrades to -silence. Schema v2 adds `alarm_states`, and M2's reboot blind spot is closed. -**M4** (the app shell โ€” navigation host, four tabs, the live pill, and the ring -screen's UI) is next. +โœ… **M4 done.** Clockula has a face. Four tabs under an M3 Expressive navigation +bar that becomes a wide rail on a tablet, with the back-stack policy and the +live pill's whole decision written as pure functions rather than as composable +state; the ring screen is real, with a maths or hold challenge that always has a +way out โ€” three wrong answers or sixty seconds, whichever comes first. The tabs +themselves are still empty states: **M5** (the alarms screen โ€” list, editor, +time picker, repeat days, per-alarm overrides) is next. --- @@ -166,7 +165,7 @@ plumbing. no device was attached; an auto-silenced alarm is silently missed, with no missed-alarm notification until someone asks for one. -### โฌœ M4 โ€” App shell +### โœ… M4 โ€” App shell - Navigation host, four tabs, M3 navigation bar, adaptive rail on wide layouts. - The **live pill** (`PLAN.md` ยง9) โ€” shared running-state surface, pause + stop from any tab. @@ -174,6 +173,35 @@ plumbing. dismiss challenge that cannot strand the user. - Motion from the kit's `identity` module; predictive back. + โœ… 480 JVM tests, 154 of them new, and still **no Robolectric** โ€” which had to + be earned rather than kept. Everything that decides something moved out of the + composables: `ShellNavigation` (what a tab tap does to the back stack, and + that back from a tab goes to Alarms while back from Alarms leaves the app), + `LivePillSelector` (which of several running things the pill is about), + `ClockFormat`, and `ChallengeGate`. The adaptive part is + `NavigationSuiteScaffold` taking its own default โ€” the short bar on a phone, + the wide rail on a tablet โ€” rather than a hand-rolled width branch that would + miss the tabletop posture. The pill shows for paused and expired timers too, + not only running ones: pausing from the pill must not make the pill disappear + under the thumb that pressed it. Its value comes from the snapshot, so a timer + that reaches zero flips to "finished" before M6's expiry write lands. The + challenge's escape hatch opens on three wrong answers **or** sixty seconds of + ringing, for every challenge kind, asserted as one parameterised invariant; + snooze is never gated; a completed hold *is* the dismissal, and an + accessibility click completes the hold, because a challenge TalkBack cannot + answer is exactly the stranding the requirement forbids. floret-kit went to + 0.5.0 for one change: `CollapsingScaffold`'s `onBack` is nullable, so a + top-level tab draws no back arrow that would pop nothing. + + Knowingly open: M4 ships no in-app way to *start* a timer or the stopwatch, so + the live pill cannot be demonstrated by hand until M6/M7 โ€” it is proven by its + unit tests and by an instrumentation test that seeds the repository directly, + and no debug button was added to paper over it. The nine new instrumentation + tests compile in the gate but have never run on hardware, as no device was + attached. `POST_NOTIFICATIONS` is asked for once on first launch; explaining a + denial, and the exact-alarm and full-screen-intent grant deep links, moved + wholly to M10's self-check, which is the screen with room to say why. + ### โฌœ M5 โ€” Alarms screen List, create, edit, delete, enable/disable. Time picker, repeat-day selector, label, ringtone picker, vibrate, snooze settings, per-alarm overrides. Next-fire