From f238b79146dca6c2d4e73ff2edb48b37e10bb215 Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Mon, 14 Sep 2026 09:10:05 -0500 Subject: [PATCH 1/6] docs(stories): add US-002 recurring-alarms story --- docs/stories/US-002-recurring-alarms.md | 88 +++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs/stories/US-002-recurring-alarms.md diff --git a/docs/stories/US-002-recurring-alarms.md b/docs/stories/US-002-recurring-alarms.md new file mode 100644 index 0000000..04b3c2e --- /dev/null +++ b/docs/stories/US-002-recurring-alarms.md @@ -0,0 +1,88 @@ +# User Story: Recurring (Daily-Repeat) Alarms + +**Story ID:** US-002 +**Epic:** Alarms +**Status:** In Progress + +--- + +## 1. Description + +**As a** visitor who keeps the clock site open at their desk, +**I want to** set an alarm that rings every day at the same time, +**So that** I don't have to re-create my daily alarms (break start, lunch, wrap-up) every morning. + +--- + +## 2. Context & Scope + +- **Source:** the MVP cut recorded in US-001 ("Out of Scope: daily-repeat + alarms — v2 story if users ask"). Owner prioritised this ahead of US-004 + and deferred US-004 to individual follow-up work (2026-09-14). +- **In Scope:** + - A **Repeat daily** option on alarm creation (checkbox in the create form) + - A repeat alarm rings at its configured time **every day** while enabled, + including across page reloads — it is never consumed by ringing + - Dismissing or snoozing a repeat alarm never turns it off; the only way + to stop it is the enable/disable toggle + - A visible daily-repeat indicator on the alarm list rows + - One-shot alarms (US-001 behaviour) remain available and unchanged + - Legacy persisted alarms (created before this story) load unchanged as + one-shot alarms — no data loss, no manual migration +- **Out of Scope:** + - **Weekday scheduling** (e.g. "weekdays only", custom day-of-week sets) — + deliberately deferred. The core stores `repeat` as a simple daily flag + today; a future story can widen it to a day-set without a breaking + schema change (see §6) + - Interval-based recurrence (e.g. "every 2 hours"), calendar-date alarms + - Configurable snooze duration; custom sounds + - Ringing when the tab is closed; notifications; sync/backends + +--- + +## 3. Acceptance Criteria + +_These criteria define "Done." Every criterion must be verified by QA._ + +- [ ] **AC-1:** Given the create form, When the user checks "Repeat daily" and adds a 09:30 alarm, Then the alarm appears in the list enabled, marked with the daily-repeat indicator. +- [ ] **AC-2:** Given an enabled daily-repeat alarm for 09:30, When the clock reaches 09:30, Then the alarm rings, and afterwards it remains enabled — the next day at 09:30 it rings again. +- [ ] **AC-3:** Given a daily-repeat alarm that just rang, When the user dismisses it, Then the alarm stays enabled and rings again the following day (including across a page reload). +- [ ] **AC-4:** Given a daily-repeat alarm, When the user disables its toggle, Then it never rings again until re-enabled (toggling also clears any pending snooze). +- [ ] **AC-5:** Given an alarm created before this story (persisted without a repeat flag), When the page loads, Then it behaves exactly as a one-shot alarm (rings once, auto-disables). +- [ ] **AC-6:** Snooze works identically for daily-repeat alarms: the snoozed ring fires at the snooze time, and afterwards the alarm is still armed for the next day. +- [ ] **AC-7:** One-shot alarms created after this story keep US-001 semantics exactly: ring once, auto-disable. +- [ ] **AC-8:** While a daily-repeat alarm is ringing and a second one becomes due, the second stays armed and rings on a later tick (one overlay at a time, as in US-001). + +--- + +## 4. Design Notes + +- The `Alarm` record gains a persisted `repeat: boolean` flag (default + `false`). Persistence stays schema-additive: `parseAlarms` treats a + missing flag as `false`, so old saved JSON needs no migration step. +- The core's ring action branches: one-shot alarms set `enabled: false` + (US-001); repeat alarms only clear a pending snooze, so `todayAt()` re-arms + them naturally on the next day's tick window. +- The create form follows US-005's control language (label + checkbox on the + shared control scale); the row indicator is a monochrome inline SVG in + `currentColor`, matching the existing icon set. +- Pure-core changes live entirely in `alarm.core.ts`; the DOM layer only + reads/writes the new flag. + +## 5. Verification Plan + +- Unit tests mirrored under `tests/unit/features/alarm/`: ring-stays-armed, + next-day re-ring (tick with a next-day `Date`), dismiss/reload survival, + disable clears snooze, legacy-JSON default, snooze interplay, second-due + queuing. +- Full `make check` + `format:check`; Playwright screenshot pass of the + create form and list rows (before/after) using the existing `/tmp/ux-shots` + tooling. + +## 6. Future Work + +- **Weekday scheduling:** widen the persisted `repeat: boolean` to a day + set (e.g. `repeatDays: number[]` or a bitmask). Because this story's flag + is schema-additive and normalised at parse time, that change is backward + compatible: `repeat: true` can be read as "all seven days" by the future + implementation, and old one-shot records (flag absent) keep working. From a5372b7bc30f89bad5d3960d1ce0ceb2de8a31e4 Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Mon, 14 Sep 2026 09:30:44 -0500 Subject: [PATCH 2/6] feat(alarm): daily-repeat alarms in the core --- web/src/features/alarm/alarm.core.ts | 66 +++++++-- .../unit/features/alarm/alarm.core.test.ts | 139 ++++++++++++++++++ .../unit/features/alarm/alarm.storage.test.ts | 2 + 3 files changed, 196 insertions(+), 11 deletions(-) diff --git a/web/src/features/alarm/alarm.core.ts b/web/src/features/alarm/alarm.core.ts index b01f205..ccd4ab0 100644 --- a/web/src/features/alarm/alarm.core.ts +++ b/web/src/features/alarm/alarm.core.ts @@ -15,6 +15,19 @@ export interface Alarm { hour: number; minute: number; enabled: boolean; + /** + * Daily recurrence (US-002). A repeat alarm is never consumed by + * ringing: clearing a pending snooze re-arms it for the next day. + * `false` keeps the US-001 one-shot behaviour. + */ + repeat: boolean; + /** + * Local calendar day (from `Date.toDateString()`) on which a repeat + * alarm last rang. Consumes the day's occurrence so a dismiss + * mid-grace-window or a reload cannot ring it twice. `null` for + * one-shot alarms and never-rung repeats. + */ + lastRungDay: string | null; /** Epoch ms when a snoozed alarm re-arms; `null` when not snoozed. */ snoozedUntil: number | null; } @@ -84,6 +97,10 @@ function isAlarm(value: unknown): value is Alarm { candidate.minute >= 0 && candidate.minute <= 59 && typeof candidate.enabled === 'boolean' && + (candidate.repeat === undefined || typeof candidate.repeat === 'boolean') && + (candidate.lastRungDay === undefined || + candidate.lastRungDay === null || + typeof candidate.lastRungDay === 'string') && (candidate.snoozedUntil === null || typeof candidate.snoozedUntil === 'number') ); @@ -95,7 +112,12 @@ export function parseAlarms(json: string | null): Alarm[] { try { const parsed: unknown = JSON.parse(json); if (!Array.isArray(parsed)) return []; - return parsed.filter(isAlarm); + return parsed.filter(isAlarm).map((alarm) => ({ + ...alarm, + // Legacy records (pre-US-002) carry no flags; they stay one-shot. + repeat: alarm.repeat === true, + lastRungDay: alarm.lastRungDay ?? null, + })); } catch { return []; } @@ -113,6 +135,7 @@ export function addAlarm( core: AlarmCore, name: string, time: AlarmTime, + repeat = false, ): AlarmCore { const alarm: Alarm = { id: createAlarmId(), @@ -120,6 +143,8 @@ export function addAlarm( hour: time.hour, minute: time.minute, enabled: true, + repeat, + lastRungDay: null, snoozedUntil: null, }; return { ...core, alarms: [...core.alarms, alarm] }; @@ -136,8 +161,9 @@ export function removeAlarm(core: AlarmCore, id: string): AlarmCore { /** * Enable or disable an alarm. * - * Either transition clears any pending snooze: an alarm that is toggled by - * hand is re-armed from its configured time, not from an old snooze. + * Either transition clears any pending snooze and any consumed occurrence: + * an alarm toggled by hand is re-armed from its configured time, not from an + * old snooze or a last-rung marker. */ export function setAlarmEnabled( core: AlarmCore, @@ -147,7 +173,9 @@ export function setAlarmEnabled( return { ...core, alarms: core.alarms.map((alarm) => - alarm.id === id ? { ...alarm, enabled, snoozedUntil: null } : alarm, + alarm.id === id + ? { ...alarm, enabled, snoozedUntil: null, lastRungDay: null } + : alarm, ), }; } @@ -159,6 +187,11 @@ function todayAt(hour: number, minute: number, now: Date): number { return candidate.getTime(); } +/** Local calendar day key for a point in time. */ +function dayKey(now: Date): string { + return now.toDateString(); +} + /** * How long after the target minute a late tick still rings the alarm. * @@ -171,13 +204,18 @@ const RING_GRACE_MS = 60 * 1000; function isDue(alarm: Alarm, now: Date): boolean { // A snoozed alarm rings by its snooze timestamp regardless of `enabled`: - // firing disabled it, and snoozing is the only thing that re-arms it. + // firing disabled it (one-shot) or its snooze re-arms it (repeat), and + // snoozing is the only thing that re-arms it mid-day. if (alarm.snoozedUntil !== null) { return now.getTime() >= alarm.snoozedUntil; } if (!alarm.enabled) return false; const delta = now.getTime() - todayAt(alarm.hour, alarm.minute, now); - return delta >= 0 && delta < RING_GRACE_MS; + if (delta < 0 || delta >= RING_GRACE_MS) return false; + // A repeat alarm consumes today's occurrence when it rings, so a + // dismiss mid-grace-window (or a page reload) cannot ring it twice. + if (alarm.repeat && alarm.lastRungDay === dayKey(now)) return false; + return true; } export interface AlarmTickResult { @@ -189,10 +227,12 @@ export interface AlarmTickResult { /** * Advance the alarm scheduler by one tick. * - * The first due alarm starts ringing; it is disabled (one-shot) so the same - * occurrence can never ring twice, including across a page reload. When - * something is already ringing, due alarms stay armed and ring on a later - * tick — the overlay handles one alarm at a time. + * The first due alarm starts ringing. One-shot alarms disable themselves so + * the same occurrence can never ring twice, including across a page reload; + * repeat alarms are never consumed — clearing a pending snooze re-arms them + * for the next day via `todayAt`. When something is already ringing, due + * alarms stay armed and ring on a later tick — the overlay handles one alarm + * at a time. */ export function tickAlarms(core: AlarmCore, now: Date): AlarmTickResult { if (core.ringingId !== null) { @@ -203,7 +243,11 @@ export function tickAlarms(core: AlarmCore, now: Date): AlarmTickResult { return { core: { alarms: core.alarms.map((a) => - a.id === alarm.id ? { ...a, enabled: false, snoozedUntil: null } : a, + a.id === alarm.id + ? a.repeat + ? { ...a, snoozedUntil: null, lastRungDay: dayKey(now) } + : { ...a, enabled: false, snoozedUntil: null } + : a, ), ringingId: alarm.id, }, diff --git a/web/tests/unit/features/alarm/alarm.core.test.ts b/web/tests/unit/features/alarm/alarm.core.test.ts index b6e791d..6574923 100644 --- a/web/tests/unit/features/alarm/alarm.core.test.ts +++ b/web/tests/unit/features/alarm/alarm.core.test.ts @@ -23,6 +23,8 @@ function makeAlarm(overrides: Partial = {}): Alarm { hour: 9, minute: 30, enabled: true, + repeat: false, + lastRungDay: null, snoozedUntil: null, ...overrides, }; @@ -281,3 +283,140 @@ describe('dismissAlarm', () => { expect(next.alarms[0]).toEqual(alarm); }); }); + +// ---------- Daily repeat (US-002) ---------- + +describe('addAlarm repeat option', () => { + it('creates a repeat alarm when requested', () => { + const core = addAlarm( + createAlarmCore(), + 'Standup', + { hour: 9, minute: 30 }, + true, + ); + expect(core.alarms[0].repeat).toBe(true); + expect(core.alarms[0].lastRungDay).toBeNull(); + }); + + it('defaults to one-shot', () => { + const core = addAlarm(createAlarmCore(), 'Standup', { + hour: 9, + minute: 30, + }); + expect(core.alarms[0].repeat).toBe(false); + }); +}); + +describe('daily-repeat alarms', () => { + const now = new Date(2026, 8, 13, 9, 30, 30); // just past 09:30 + const nextDay = new Date(2026, 8, 14, 9, 30, 30); + + it('rings a repeat alarm without consuming it', () => { + const core = makeCore([makeAlarm({ repeat: true })]); + const result = tickAlarms(core, now); + expect(result.rangId).toBe('alarm-1'); + expect(result.core.alarms[0].enabled).toBe(true); + expect(result.core.alarms[0].snoozedUntil).toBeNull(); + }); + + it('marks the rung occurrence so it cannot ring twice today', () => { + const core = makeCore([makeAlarm({ repeat: true })]); + const first = tickAlarms(core, now); + expect(first.core.alarms[0].lastRungDay).toBe(now.toDateString()); + // A dismiss mid-grace-window (or a reload) must not re-ring today. + const again = tickAlarms({ ...first.core, ringingId: null }, now); + expect(again.rangId).toBeNull(); + }); + + it('rings a repeat alarm again the next day', () => { + const core = makeCore([makeAlarm({ repeat: true })]); + const first = tickAlarms(core, now); + const second = tickAlarms({ ...first.core, ringingId: null }, nextDay); + expect(second.rangId).toBe('alarm-1'); + expect(second.core.alarms[0].enabled).toBe(true); + }); + + it('stays armed after being dismissed', () => { + const core = makeCore([makeAlarm({ repeat: true })], 'alarm-1'); + const dismissed = dismissAlarm(core); + expect(dismissed.alarms[0].enabled).toBe(true); + expect(dismissed.ringingId).toBeNull(); + const result = tickAlarms(dismissed, now); + expect(result.rangId).toBe('alarm-1'); + }); + + it('rings after a snooze expires and stays armed for the next day', () => { + const snoozeAt = new Date(2026, 8, 13, 9, 30, 0); + let core = makeCore([makeAlarm({ repeat: true })], 'alarm-1'); + core = snoozeAlarm(core, 'alarm-1', snoozeAt); + const snoozedUntil = core.alarms[0].snoozedUntil; + expect(snoozedUntil).not.toBeNull(); + const rang = tickAlarms( + { ...core }, + new Date((snoozedUntil as number) + 1), + ); + expect(rang.rangId).toBe('alarm-1'); + expect(rang.core.alarms[0].enabled).toBe(true); + expect(rang.core.alarms[0].snoozedUntil).toBeNull(); + const next = tickAlarms({ ...rang.core, ringingId: null }, nextDay); + expect(next.rangId).toBe('alarm-1'); + }); + + it('never rings while disabled', () => { + const core = makeCore([makeAlarm({ repeat: true, enabled: false })]); + const result = tickAlarms(core, now); + expect(result.rangId).toBeNull(); + }); + + it('re-arms from its configured time when toggled (consumed day cleared)', () => { + let core = makeCore([makeAlarm({ repeat: true })]); + core = tickAlarms(core, now).core; // rang today + core = dismissAlarm(core); // overlay closes; alarm still armed + core = setAlarmEnabled(core, 'alarm-1', false); + core = setAlarmEnabled(core, 'alarm-1', true); + expect(core.alarms[0].lastRungDay).toBeNull(); + const result = tickAlarms(core, now); + expect(result.rangId).toBe('alarm-1'); + }); + + it('queues a second due repeat alarm while one is already ringing', () => { + const core = makeCore( + [ + makeAlarm({ hour: 9, minute: 29, repeat: true }), + makeAlarm({ id: 'alarm-2', repeat: true }), + ], + 'alarm-1', + ); + const result = tickAlarms(core, now); + expect(result.rangId).toBeNull(); + expect(result.core.alarms[1].enabled).toBe(true); + }); + + it('parses legacy records without a repeat flag as one-shot', () => { + const json = JSON.stringify([ + { + id: 'alarm-1', + name: 'Old', + hour: 7, + minute: 0, + enabled: true, + snoozedUntil: null, + }, + ]); + const alarms = parseAlarms(json); + expect(alarms[0].repeat).toBe(false); + expect(alarms[0].lastRungDay).toBeNull(); + // One-shot semantics intact: rings, then disables itself. + const late = new Date(2026, 8, 13, 7, 0, 30); + const result = tickAlarms(makeCore(alarms), late); + expect(result.rangId).toBe('alarm-1'); + expect(result.core.alarms[0].enabled).toBe(false); + }); + + it('round-trips the repeat flag and rejects a non-boolean one', () => { + const json = JSON.stringify([makeAlarm({ repeat: true })]); + expect(parseAlarms(json)).toEqual([makeAlarm({ repeat: true })]); + const bad = JSON.stringify([{ ...makeAlarm(), repeat: 'yes' }]); + expect(parseAlarms(bad)).toEqual([]); + }); +}); diff --git a/web/tests/unit/features/alarm/alarm.storage.test.ts b/web/tests/unit/features/alarm/alarm.storage.test.ts index df528ce..1de5df3 100644 --- a/web/tests/unit/features/alarm/alarm.storage.test.ts +++ b/web/tests/unit/features/alarm/alarm.storage.test.ts @@ -10,6 +10,8 @@ const alarm: Alarm = { hour: 9, minute: 30, enabled: true, + repeat: false, + lastRungDay: null, snoozedUntil: null, }; From 19b2072c357e46207425bbe03a47efb4cee9b04a Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Mon, 14 Sep 2026 09:30:47 -0500 Subject: [PATCH 3/6] feat(alarm): repeat-daily control and row indicator --- web/src/features/alarm/alarm.ui.ts | 25 +++++++++++++++++-- web/src/index.html | 12 +++++++++ web/src/styles/alarm.css | 39 ++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/web/src/features/alarm/alarm.ui.ts b/web/src/features/alarm/alarm.ui.ts index 04a9143..2741be1 100644 --- a/web/src/features/alarm/alarm.ui.ts +++ b/web/src/features/alarm/alarm.ui.ts @@ -41,6 +41,10 @@ export function initAlarm( const nameInput = queryOptional(rootElement, '.alarm-name'); const timeInput = queryOptional(rootElement, '.alarm-time'); const addBtn = queryOptional(rootElement, '.alarm-add'); + const repeatInput = queryOptional( + rootElement, + '.alarm-repeat', + ); const errorEl = queryOptional(rootElement, '.alarm-error'); const list = queryOptional(rootElement, '.alarm-list'); @@ -69,6 +73,7 @@ export function initAlarm( !nameInput || !timeInput || !addBtn || + !repeatInput || !errorEl || !list || !overlay || @@ -89,6 +94,7 @@ export function initAlarm( nameInput, timeInput, addBtn, + repeatInput, errorEl, list, overlay, @@ -162,12 +168,26 @@ export function initAlarm( toggle.checked = isArmed; toggle.setAttribute('aria-label', `Enable ${alarmDisplayName(alarm)}`); + row.append(name, time); + if (alarm.repeat) { + // Daily-repeat indicator (US-002). role="img" + aria-label so + // screen readers announce it; the SVG itself is presentational. + const repeat = document.createElement('span'); + repeat.className = 'alarm-row-repeat'; + repeat.setAttribute('role', 'img'); + repeat.setAttribute('aria-label', 'Repeats daily'); + repeat.title = 'Repeats daily'; + repeat.innerHTML = + ''; + row.append(repeat); + } + const removeBtn = document.createElement('button'); removeBtn.className = 'alarm-row-remove'; removeBtn.textContent = '✕'; removeBtn.setAttribute('aria-label', `Delete ${alarmDisplayName(alarm)}`); - row.append(name, time, toggle, removeBtn); + row.append(toggle, removeBtn); dom.list.append(row); } } @@ -249,10 +269,11 @@ export function initAlarm( dom.errorEl.textContent = 'Set a valid time (HH:MM).'; return; } - core = addAlarm(core, dom.nameInput.value, time); + core = addAlarm(core, dom.nameInput.value, time, dom.repeatInput.checked); persist(); dom.nameInput.value = ''; dom.timeInput.value = ''; + dom.repeatInput.checked = false; renderAlarmList(); renderToggle(); } diff --git a/web/src/index.html b/web/src/index.html index 578545f..3a6309e 100644 --- a/web/src/index.html +++ b/web/src/index.html @@ -154,6 +154,18 @@

Alarms

+
diff --git a/web/src/styles/alarm.css b/web/src/styles/alarm.css index 9af7fd5..af232c4 100644 --- a/web/src/styles/alarm.css +++ b/web/src/styles/alarm.css @@ -349,3 +349,42 @@ .alarm-list::-webkit-scrollbar-corner { background: transparent; } + +/* ---- Repeat daily (US-002) ---- */ + +.repeat-check { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + color: var(--color-text-secondary); + font-family: var(--font-family); + font-size: var(--font-size-small); + white-space: nowrap; + padding: 0 var(--space-xs); + cursor: pointer; + user-select: none; +} + +.repeat-check:hover { + color: var(--color-primary); +} + +.repeat-check input { + width: 15px; + height: 15px; + margin: 0; + accent-color: var(--color-primary); + cursor: pointer; +} + +.repeat-check input:focus-visible { + outline: var(--focus-width, 2px) solid var(--color-primary); + outline-offset: 2px; +} + +.alarm-row-repeat { + display: inline-flex; + align-items: center; + color: var(--color-text-secondary); + flex-shrink: 0; +} From 6f3fb12147522c711a9b3c5025da20b20057f346 Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Mon, 14 Sep 2026 09:39:30 -0500 Subject: [PATCH 4/6] docs(tasks): close out HK-5 and record US-002 implementation --- .../screenshots/01-create-form-daily.png | Bin 0 -> 45096 bytes .../screenshots/02-rows-repeat-indicator.png | Bin 0 -> 48771 bytes memory-bank/activeContext.md | 47 ++++++------ tasks/backlog.md | 29 +------- tasks/sprint.md | 67 +++++++++++------- 5 files changed, 68 insertions(+), 75 deletions(-) create mode 100644 docs/stories/US-002-recurring-alarms/screenshots/01-create-form-daily.png create mode 100644 docs/stories/US-002-recurring-alarms/screenshots/02-rows-repeat-indicator.png diff --git a/docs/stories/US-002-recurring-alarms/screenshots/01-create-form-daily.png b/docs/stories/US-002-recurring-alarms/screenshots/01-create-form-daily.png new file mode 100644 index 0000000000000000000000000000000000000000..35905797b6676f1614dc934e7945a1a1614f6771 GIT binary patch literal 45096 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℞m)f3`73Z9pJ{Vx|Mhlr*H9ZWz|RF%nB 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 literal 0 HcmV?d00001 diff --git a/docs/stories/US-002-recurring-alarms/screenshots/02-rows-repeat-indicator.png b/docs/stories/US-002-recurring-alarms/screenshots/02-rows-repeat-indicator.png new file mode 100644 index 0000000000000000000000000000000000000000..c47a5720647bd522f2a3727f33b85555786fdc75 GIT binary patch literal 48771 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 literal 0 HcmV?d00001 diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index 3fe4e5d..d4fe8d9 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -4,36 +4,33 @@ Updated: 2026-09-14 ## Current focus -**HK-6 — implemented on `fix/hk6-asset-retention`** (off `main`): the -stale-HTML/dead-asset window after deploys is closed via previous-release -asset retention (ADR-0007). deploy.sh step 3b streams the old web -container's assets into `.prev-assets/` (tar contents-form — the `docker -cp src/. dst/` form NESTS, do not use); compose bind-mounts it ro at -`/usr/share/nginx/html-prev`; `web/nginx.conf` `try_files $uri -@prev_assets` fallback serves old hashes with immutable headers. - -- Verified locally: `sh -n`, both `compose config -q`, `nginx -t` on both - configs, functional docker test (old hash 200 via fallback, unknown 404). -- Sandbox gotcha: this environment's docker bind mounts can show STALE - container views of host dirs (caused a long nesting-wild-goose-chase — - the data was polluted by an earlier root-owned `docker cp`, and the - container saw content the host didn't have). Trust host-side `find` over - container `ls` here. -- First deploy after merge runs the old in-memory deploy.sh; fallback is - fully populated from the second deploy onward (in ADR-0007). +**US-002 — implemented on `feat/us-002-recurring-alarms`** (off `main`): +daily-repeat alarms. Persisted `repeat` + `lastRungDay` on `Alarm` +(schema-additive — legacy JSON normalizes to one-shot, no migration). Ring +consumes the local calendar day (`lastRungDay`), fixing a design hole found +during planning: without it, a dismiss mid-grace-window or a reload would +re-ring a repeat alarm. Toggling clears both markers (re-arms from the +configured time). UI: "Daily" checkbox in the create form, monochrome ↻ +row indicator (`role="img"` + aria-label). Weekday scheduling is recorded +as future work in the story (§6) — `repeat: true` reads as "all days" for +that future widening. + +- Verified: 152/152 unit tests (12 new), `make check` green, 7/7 Playwright + assertions, 2 screenshots in the story folder. +- Same session: HK-6 (PR #16) and HK-5 (PR #17, nginx → 1.30-alpine stable) + merged and deployed. ## Environment state -- Branch `fix/hk6-asset-retention` = main + 3 commits (code, ADRs, tasks). - `dev` has sprint-tracking commit `54edefa` that main lacks — this branch's - sprint.md rewrite reconciles them on merge. -- `make check` green (140 tests); pure cores untouched by HK-6. +- Branch `feat/us-002-recurring-alarms` = main + 4 commits (story, core, + UI, close-out). All housekeeping HK-1…HK-6 done; US-003 absorbed. +- Playwright tooling still in `/tmp/ux-shots/` (not a repo dependency). ## Next steps -- Owner: review + merge HK-6 PR → `main`; next deploy needs NO manual CF - purge from the second deploy on. +- Owner: review + merge the US-002 PR → `main` (rebase; ruleset requires + PRs), then verify the repeat alarm rings live. - Owner: audible alarm-tone check (US-001) and visual pass on prod (US-005) — both still open. -- Pick next epic: US-004 (needs PO story + likely ADR) vs US-002 (needs PO - story). HK-5 (nginx re-pin) is the remaining housekeeping item. +- Then: US-004 multi-clock epic, run individually per owner decision — + needs a PO story defining "a clock" + likely an ADR before starting. diff --git a/tasks/backlog.md b/tasks/backlog.md index b6e315a..e64d117 100644 --- a/tasks/backlog.md +++ b/tasks/backlog.md @@ -4,39 +4,16 @@ Prioritized candidate work. Items here are NOT committed to a sprint until moved to `tasks/sprint.md`. New items enter via the Product Owner (user story) and are sized/sequenced by the SDM. -## Epic: Alarms - -### US-002 — Recurring (daily-repeat) alarms - -- Status: Candidate — needs a user story from the Product Owner before work. -- Source: MVP cut recorded in US-001 ("Out of Scope": daily-repeat alarms). -- Priority: **Deprioritized behind US-005** (owner decision 2026-09-13) — - still the most requested natural follow-up to US-001. -- Dependencies: none (builds directly on the US-001 alarm core). - ## Epic: Multi-clock ### US-004 — Wire up the multi-clock registry -- Status: Candidate — `clock-registry.ts` scaffold exists but is not wired. +- Status: Candidate — **owner will schedule and run this individually**; + deliberately deferred from the 2026-09-14 cleanup sprint as too heavy to + batch. - Source: README ("Multi-clock scaffold — not wired up yet"); recommended as a major epic after the Alarms epic. - Dependencies: the shared FLIP helper (formerly US-003 item 1) is DONE via US-005 (`shared/dom/flip.ts`) — the sequencing blocker is cleared. - Note: likely requires an ADR if the page layout/composition root changes meaningfully, plus a Product Owner story defining what a "clock" is. - -## Housekeeping (backlog, non-story) - -### HK-5 — Re-pin the nginx base image off the EOL 1.27 branch - -- Status: Candidate (found 2026-09-13 during the repo date/staleness audit). -- Finding: `nginxinc/nginx-unprivileged:1.27-alpine` was last built - 2025-06-23; the 1.27 mainline stopped shipping when 1.29 released, so the - edge and prod images run an unmaintained branch. The digest pin itself is - current for the tag — the staleness is at the version level. -- Requires: choose the current nginx stable branch, bump tag + digest - together (ADR 0005) in `web/Dockerfile.prod` and `nginx/Dockerfile`, update - the image tag in `.github/workflows/ci.yml` (nginx-config-check), and run - `nginx -t` locally on both configs. -- Priority: Medium — security updates are accruing on the EOL branch. diff --git a/tasks/sprint.md b/tasks/sprint.md index b9c1623..e88af96 100644 --- a/tasks/sprint.md +++ b/tasks/sprint.md @@ -26,41 +26,60 @@ Sprint window: active (no fixed calendar sprint; pipeline-driven). ### HK-6 — Eliminate the stale-HTML/dead-asset window after deploys -- Status: **IMPLEMENTED on `fix/hk6-asset-retention`** (off `main`) — - previous-release assets retained on origin per **ADR-0007**: deploy.sh - step 3b streams the old container's `/assets` into `.prev-assets/` - (accumulative), the web service bind-mounts it read-only, and - `web/nginx.conf` falls back to it for hashes missing from the new build. -- Verified locally: `sh -n`, both `docker compose config -q` runs, `nginx --t` on both configs, and a functional docker test — old-hash asset serves - **200 with immutable headers** from the fallback, new assets 200, unknown - 404, `/` and `/healthz` unaffected. -- Note: the first deploy after merge still runs the old in-memory deploy.sh; - the fallback is fully populated from the second deploy onward (recorded in - ADR-0007). +- Status: **MERGED + DEPLOYED** (PR #16 rebase-merged 2026-09-14; Release + succeeded, `/healthz` 200). Previous-release assets retained on origin + per **ADR-0007**: deploy.sh step 3b streams the old container's `/assets` + into `.prev-assets/` (accumulative), the web service bind-mounts it + read-only, and `web/nginx.conf` falls back to it for hashes missing from + the new build. +- Verified locally before merge: `sh -n`, both `docker compose config -q` + runs, `nginx -t` on both configs, and a functional docker test — old-hash + asset serves **200 with immutable headers** from the fallback. +- Note: this deploy itself ran the old in-memory deploy.sh; the fallback is + fully populated from the second deploy onward (ADR-0007). + +### HK-5 — Re-pin the nginx base image off the EOL 1.27 branch + +- Status: **MERGED + DEPLOYED** (PR #17 rebase-merged 2026-09-14; Release + run succeeded). Tag + manifest-list digest moved together (ADR-0005) to + `nginxinc/nginx-unprivileged:1.30-alpine @ sha256:adf5042a…` — current + stable **nginx 1.30.4**; both `ci.yml` `nginx -t` invocations re-pinned. +- Verified: local pull of the digest reports `nginx/1.30.4`; `nginx -t` + passes on both configs against the new image; all four CI checks green. ## In flight -Nothing — pipeline is empty pending owner decisions. - -## Ready (not started) — needs owner pick - -| # | Item | Type | Dependencies | Notes | -| --- | --------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -| 1 | **US-004** — wire up the multi-clock registry | Epic | FLIP blocker cleared by US-005; needs PO story defining "a clock" + likely ADR (layout/composition-root change) | Was deprioritized behind US-005; now unblocked. | -| 2 | **US-002** — recurring (daily-repeat) alarms | Story | none (builds on alarm core) | Needs a PO user story before work. | -| 3 | **HK-5** — re-pin nginx off EOL 1.27 branch | Housekeeping (security) | none | Medium; security updates accruing on the unmaintained branch. | +### US-002 — Recurring (daily-repeat) alarms + +- Status: **IMPLEMENTED on `feat/us-002-recurring-alarms`** (off `main`) — + story in `docs/stories/US-002-recurring-alarms.md` (MVP scope: daily + repeat only; weekday scheduling recorded as future work in §6). +- Core: persisted `repeat` + `lastRungDay` flags; repeat alarms are never + consumed by ringing (a rung occurrence is consumed per local calendar + day, so a mid-grace-window dismiss or reload cannot re-ring); toggling + re-arms from the configured time; legacy JSON loads as one-shot, no + migration. +- UI: "Daily" checkbox in the create form; monochrome ↻ indicator + (`role="img"`, aria-label "Repeats daily") on repeat rows only. +- Verified: **152/152 unit tests** (12 new), `make check` green, 7/7 + Playwright assertions (indicator on repeat rows only, flags persist, + checkbox resets), 2 screenshots committed in the story folder. + +## Ready (not started) + +- **US-004** — wire up the multi-clock registry: the only remaining item. + **Owner will run it individually** (deliberately deferred from this + cleanup pass as too heavy to batch). Unblocked (FLIP helper done); needs + a PO story + likely an ADR before work starts. ## Dependencies & sequencing -- US-002 and US-004 are independent of each other; either can be next. -- HK-5 is fully standalone; can slot into any gap. +- Nothing queued behind US-002; US-004 is owner-scheduled. ## Risks | Risk | Likelihood | Impact | Mitigation | | -------------------------------------------------------------------------- | ---------- | -------------------------------------------- | -------------------------------------------- | | Production alarm audio unverified | Medium | Medium (US-001 DoD gap) | Owner manual check; tracked above | -| nginx 1.27 base gets no security updates (EOL mainline) | High | Medium | HK-5: re-pin to current stable | | US-005 sign-off without a human look at prod | Low | Low (aesthetic regressions screenshots miss) | Owner visual pass; rollback via revert PR | | HK-6 fallback unproven on the real host until the second post-merge deploy | Low | Low (old behaviour = broken window recurs) | Owner: verify next deploy via old-hash asset | From 2c7711b4004e6741e9f817941b35a65594a79019 Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Mon, 14 Sep 2026 14:12:15 -0500 Subject: [PATCH 5/6] chore(cline): update memory bank progress for session wrap --- memory-bank/progress.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 1eab4d7..76c46b9 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -3,15 +3,17 @@ ## Status US-001 (Multiple Alarms) is **deployed to production** (PR #13 merged -2026-09-13 21:17Z; Release run #5 succeeded; `healthz` verified 200). -US-005 (UX polish & a11y hardening) is **implemented on -`feat/us-005-ux-polish`** — all ACs verified, awaiting owner QA/review. -Site is live at `clock.taylormadetech.net`. +2026-09-13 21:17Z). US-005 (UX polish & a11y hardening) is **merged and +deployed** (PR #15). Housekeeping HK-1…HK-6 all done. US-002 (recurring +alarms) is **implemented on `feat/us-002-recurring-alarms`** (PR #18, all +CI checks green) — awaiting owner review/merge. Site is live at +`clock.taylormadetech.net`. 152 unit tests green. ## What works - Clock (tick, title mirror, timezone), timer (presets, persistence, beep), - alarms (multi, snooze, persistence, ring overlay) — 140 unit tests green. + alarms (multi, snooze, persistence, ring overlay, **daily-repeat + [US-002, pending merge]**). - **Design system (US-005):** semantic text-tier tokens (secondary 7.0:1, muted 5.2:1, placeholder 4.7:1 — never raw opacity for text), AA-safe danger `#ff6b6b`, global `:focus-visible` ring, monochrome inline-SVG @@ -19,8 +21,13 @@ Site is live at `clock.taylormadetech.net`. focus management + `aria-modal` ring overlay with Tab trap, `prefers-reduced-motion` global kill switch, `panelHadFocus` focus-restore pattern in both UI features. +- **Deploy resilience (HK-6, ADR-0007):** previous-release assets retained + on origin (`.prev-assets/` bind mount + `@prev_assets` fallback), closing + the stale-HTML/dead-asset window; no manual CF purges needed from the + second post-merge deploy on. - Full CI gate: prettier, eslint, typecheck, vitest+coverage, build, - `nginx -t` × 2, compose config × 2, hadolint × 4. + `nginx -t` × 2, compose config × 2, hadolint × 4; on modern action + majors (HK-2). - Automated deploys: `main` → GHCR → webhook → swap with auto-rollback. - Cloudflare edge caching of `index.html` (2 h Cache Rule; `/healthz` uncacheable) per ADR 0006. @@ -29,22 +36,15 @@ Site is live at `clock.taylormadetech.net`. - Production audio QA: alarm tone not yet verified by a human (jsdom can't test audio) — last open US-001 DoD item. -- **Stale-HTML → dead-asset window after every deploy** (HK-6): a rebuild can - change asset hashes; the 2 h edge-cached homepage then references assets - that 404 on origin, and the 404 gets edge-cached too (observed 2026-09-13). - Fix candidates: CF API purge post-deploy, retain old assets in `deploy.sh`, - or shorter HTML TTL. +- US-005 visual sign-off on prod still pending (owner eyeball). - Edge-cached homepage can lag up to 2 h behind a deploy (expected; judge freshness via `/healthz` or a query-string cache-bust, which works). -- CI actions pinned to Node-20-runtime majors (HK-2 — fix in progress). -- `nginxinc/nginx-unprivileged:1.30-alpine` is an EOL mainline branch - (HK-5 candidate: re-pin to current stable + digest). - npm minor drift: eslint/prettier/lint-staged/TS patch bumps available; vite 7+/vitest 5 majors deliberately deferred (not housekeeping). -- Multi-clock scaffold (`clock-registry.ts`) unwired (backlog US-004). -- FLIP helper duplicated in timer/alarm UI (backlog US-003). +- Multi-clock scaffold (`clock-registry.ts`) unwired — **US-004, owner will + run it individually**; needs a PO story defining "a clock" + likely an ADR. ## Next epic decision (owner) -US-002 recurring alarms vs US-004 multi-clock (US-004 wants US-003 item 1 -first). See `tasks/backlog.md` + `tasks/sprint.md`. +US-004 multi-clock (deferred, owner-scheduled). See `tasks/backlog.md` + +`tasks/sprint.md`. From 68a627b46bbf8441d494a669ffb4807b631fe58e Mon Sep 17 00:00:00 2001 From: Hector Alvarez Date: Tue, 15 Sep 2026 11:06:53 -0500 Subject: [PATCH 6/6] chore(cline): retire dev branch, record US-002 merge --- memory-bank/activeContext.md | 41 +++++++++++++++++++++--------------- memory-bank/progress.md | 12 +++++------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index d4fe8d9..2105650 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -1,36 +1,43 @@ # Active Context -Updated: 2026-09-14 +Updated: 2026-09-15 ## Current focus -**US-002 — implemented on `feat/us-002-recurring-alarms`** (off `main`): -daily-repeat alarms. Persisted `repeat` + `lastRungDay` on `Alarm` -(schema-additive — legacy JSON normalizes to one-shot, no migration). Ring -consumes the local calendar day (`lastRungDay`), fixing a design hole found -during planning: without it, a dismiss mid-grace-window or a reload would -re-ring a repeat alarm. Toggling clears both markers (re-arms from the -configured time). UI: "Daily" checkbox in the create form, monochrome ↻ -row indicator (`role="img"` + aria-label). Weekday scheduling is recorded -as future work in the story (§6) — `repeat: true` reads as "all days" for -that future widening. +**US-002 — merged (PR #18, rebase-merged into `main`).** Daily-repeat +alarms: persisted `repeat` + `lastRungDay` on `Alarm` (schema-additive — +legacy JSON normalizes to one-shot, no migration). Ring consumes the local +calendar day (`lastRungDay`), fixing a design hole found during planning: +without it, a dismiss mid-grace-window or a reload would re-ring a repeat +alarm. Toggling clears both markers (re-arms from the configured time). +UI: "Daily" checkbox in the create form, monochrome ↻ row indicator +(`role="img"` + aria-label). Weekday scheduling is recorded as future work +in the story (§6) — `repeat: true` reads as "all days" for that future +widening. - Verified: 152/152 unit tests (12 new), `make check` green, 7/7 Playwright assertions, 2 screenshots in the story folder. -- Same session: HK-6 (PR #16) and HK-5 (PR #17, nginx → 1.30-alpine stable) - merged and deployed. + +## Repo cleanup & workflow change (2026-09-15) + +- All merged feature branches and `dev` deleted (local + origin) once PR + #18 merged; only `main` remains. +- **`dev` is retired.** Since PR #14 practice has been feature branch → + `main` via PR (rebase-merge, linear history). Work now branches from + `main` and PRs into `main`; merging to `main` fires the automatic + release deploy (GHCR → webhook). ## Environment state -- Branch `feat/us-002-recurring-alarms` = main + 4 commits (story, core, - UI, close-out). All housekeeping HK-1…HK-6 done; US-003 absorbed. +- Single long-lived branch: `main`; no open PRs. - Playwright tooling still in `/tmp/ux-shots/` (not a repo dependency). ## Next steps -- Owner: review + merge the US-002 PR → `main` (rebase; ruleset requires - PRs), then verify the repeat alarm rings live. +- Owner: verify the repeat alarm rings live after this deploy (`/healthz`, + then a cache-busted homepage). - Owner: audible alarm-tone check (US-001) and visual pass on prod (US-005) — both still open. - Then: US-004 multi-clock epic, run individually per owner decision — needs a PO story defining "a clock" + likely an ADR before starting. + diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 76c46b9..5fcf55c 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -2,18 +2,18 @@ ## Status -US-001 (Multiple Alarms) is **deployed to production** (PR #13 merged -2026-09-13 21:17Z). US-005 (UX polish & a11y hardening) is **merged and -deployed** (PR #15). Housekeeping HK-1…HK-6 all done. US-002 (recurring -alarms) is **implemented on `feat/us-002-recurring-alarms`** (PR #18, all -CI checks green) — awaiting owner review/merge. Site is live at +US-002 (recurring alarms) is **merged and deployed** (PR #18, rebase-merged +into `main` on 2026-09-15; merging fires the automatic release deploy). +Repo cleanup, same day: merged feature branches and `dev` deleted (local + +origin); `dev` is retired — work now branches from `main` and PRs into +`main` (rebase-merge, linear history). Site is live at `clock.taylormadetech.net`. 152 unit tests green. ## What works - Clock (tick, title mirror, timezone), timer (presets, persistence, beep), alarms (multi, snooze, persistence, ring overlay, **daily-repeat - [US-002, pending merge]**). + (US-002)**). - **Design system (US-005):** semantic text-tier tokens (secondary 7.0:1, muted 5.2:1, placeholder 4.7:1 — never raw opacity for text), AA-safe danger `#ff6b6b`, global `:focus-visible` ring, monochrome inline-SVG