chore: archive v1.1 phase directories to milestones/v1.1-phases/
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a2890d1542
commit
c7955a46b9
@@ -0,0 +1,92 @@
|
||||
---
|
||||
phase: 11
|
||||
slug: per-event-reminders
|
||||
status: draft
|
||||
nyquist_compliant: false
|
||||
wave_0_complete: false
|
||||
created: 2026-06-13
|
||||
---
|
||||
|
||||
# Phase 11 — Validation Strategy
|
||||
|
||||
> Per-phase validation contract for feedback sampling during execution.
|
||||
> Source: `11-RESEARCH.md` § Validation Architecture.
|
||||
|
||||
---
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | Vitest (vite-native, same config as frontend) |
|
||||
| **Config file** | `apps/api/vitest.config.ts` |
|
||||
| **Quick run command** | `pnpm --filter @familysync/api exec vitest run tests/broker/vevent.test.ts tests/broker/reminderScheduler.test.ts` |
|
||||
| **Full suite command** | `pnpm --filter @familysync/api exec vitest run` |
|
||||
| **Estimated runtime** | ~10–30 seconds (quick); full suite longer |
|
||||
|
||||
---
|
||||
|
||||
## Sampling Rate
|
||||
|
||||
- **After every task commit:** Run quick command (`vevent.test.ts` + `reminderScheduler.test.ts`)
|
||||
- **After every plan wave:** Run full API suite
|
||||
- **Before `/gsd-verify-work`:** Full API suite green + Playwright smoke (allDay toggle swaps presets; edit-mode picker loads correct value)
|
||||
- **Max feedback latency:** ~30 seconds
|
||||
|
||||
---
|
||||
|
||||
## Per-Task Verification Map
|
||||
|
||||
> Per-task rows are populated during planning once plan/task IDs exist. The
|
||||
> requirement → behavior → test-command coverage below is sourced from
|
||||
> `11-RESEARCH.md` § "Phase Requirements → Test Map" and must each be claimed
|
||||
> by at least one task's `<automated>` verify.
|
||||
|
||||
| Requirement | Behavior | Test Type | Automated Command | File Exists |
|
||||
|-------------|----------|-----------|-------------------|-------------|
|
||||
| CAL-13 | Timed VALARM emits DURATION trigger `-PTNmM` (no `VALUE=TEXT`) | unit | `vitest run tests/broker/vevent.test.ts` | ✅ extend |
|
||||
| CAL-13 | All-day VALARM emits absolute DATE-TIME trigger | unit | `vitest run tests/broker/vevent.test.ts` | ✅ extend |
|
||||
| CAL-13 | allDay toggle swaps preset list; resets to None on toggle | browser | `playwright-cli` | ❌ W0 |
|
||||
| CAL-14 | No picker change on edit → rawVevent VALARM preserved in PUT | unit | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extend |
|
||||
| CAL-14 | Off-list single relative VALARM → `offlist` classification | unit | `vitest run tests/broker/vevent.test.ts` | ✅ extend |
|
||||
| CAL-14 | Absolute trigger → `custom` classification | unit | `vitest run tests/broker/vevent.test.ts` | ✅ extend |
|
||||
| CAL-14 | Two VALARMs → `custom` classification | unit | `vitest run tests/broker/vevent.test.ts` | ✅ extend |
|
||||
| NOTIF-04 | Scheduler fires at T-leadMinutes (e.g. T-30 for 30-min lead) | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend |
|
||||
| NOTIF-04 | Humanized body: 30→"30 min", 60→"1 hour", 1440→"1 day", 10080→"7 days" | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend |
|
||||
| NOTIF-05 | `null` reminderLeadMinutes → no push | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend |
|
||||
| NOTIF-05 | `0` lead + `allDay=false` → no push | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend |
|
||||
| NOTIF-06 | All-day `0` lead fires 9 AM local (UTC computation correct) | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ❌ W0 |
|
||||
| NOTIF-06 | Rescheduled event (new dtstart) re-fires — `uid:dtstartMs` dedup | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend |
|
||||
| NOTIF-06 | Same event fires exactly once across 3 ticks — `uid:dtstartMs` dedup | unit | `vitest run tests/broker/reminderScheduler.test.ts` | ✅ extend (current test is uid-only) |
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
---
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] `tests/broker/vevent.test.ts` — extend: VALARM serialization (DURATION trigger type, all-day absolute DATE-TIME, preserve round-trip, classifier I/O none/preset/offlist/custom)
|
||||
- [ ] `tests/broker/reminderScheduler.test.ts` — extend: variable-lead fire, all-day 9 AM UTC, `uid:dtstartMs` dedup re-fire on reschedule + once-across-ticks, NULL-vs-0 semantics, humanized body
|
||||
- [ ] `computeAlertInstantUtc` — unit tests at DST boundaries (spring-forward and fall-back dates)
|
||||
- [ ] Playwright smoke — EventForm create mode allDay-toggle preset swap; edit mode loads correct picker value
|
||||
|
||||
---
|
||||
|
||||
## Manual-Only Verifications
|
||||
|
||||
| Behavior | Requirement | Why Manual | Test Instructions |
|
||||
|----------|-------------|------------|-------------------|
|
||||
| All-day VALARM trigger honored by Fastmail / Apple Calendar | CAL-13 (best-effort interop) | Requires live Fastmail + Apple Calendar accounts; not driveable headlessly | Create an all-day event with a "1 day before" reminder in FamilySync; open in Apple Calendar / Fastmail web and confirm an alarm shows (exact fire time is best-effort — scheduler is push ground truth) |
|
||||
|
||||
---
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
|
||||
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||
- [ ] Wave 0 covers all MISSING references
|
||||
- [ ] No watch-mode flags
|
||||
- [ ] Feedback latency < 30s
|
||||
- [ ] `nyquist_compliant: true` set in frontmatter
|
||||
|
||||
**Approval:** pending
|
||||
Reference in New Issue
Block a user