Files
familysync/.planning/milestones/v1.1-phases/09-faster-write-back/09-VALIDATION.md
T
2026-06-18 22:21:38 -04:00

85 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 9
slug: faster-write-back
status: draft
nyquist_compliant: false
wave_0_complete: false
created: 2026-06-12
---
# Phase 9 — Validation Strategy
> Per-phase validation contract for feedback sampling during execution.
---
## Test Infrastructure
| Property | Value |
|----------|-------|
| **Framework** | Vitest (existing) |
| **Config file** | `apps/api/vitest.config.ts` |
| **Quick run command** | `cd apps/api && npx vitest run tests/broker/outboxWorker.test.ts` |
| **Full suite command** | `cd apps/api && npm test` (→ `vitest run`) |
| **Estimated runtime** | ~520 seconds (existing broker suite + new signal cases; no live Fastmail) |
---
## Sampling Rate
- **After every task commit:** Run quick command (`vitest run tests/broker/outboxWorker.test.ts`)
- **After every plan wave:** Run full suite (`npm test`) + `npm run typecheck` (`tsc --noEmit` — esbuild/Vitest does not catch type errors; see [[vitest-passes-tsc-fails]])
- **Before `/gsd-verify-work`:** Full suite + typecheck must be green
- **Max feedback latency:** ~20 seconds
---
## Per-Task Verification Map
> Task IDs are assigned by the planner; rows below map each Success Criterion + CAL-15 to its
> concrete automated assertion (Nyquist coverage). The signal-path tests need no fake timers —
> a `setImmediate`/microtask flush is sufficient to observe the synchronous emit → drain wiring
> (per RESEARCH.md). The 15s `setInterval` fallback is exercised with Vitest fake timers as today.
| Item | Wave | Requirement | Threat Ref | Expected Behavior | Test Type | Automated Command | File Exists | Status |
|------|------|-------------|------------|-------------------|-----------|-------------------|-------------|--------|
| SC-1 signal → prompt drain | 1 | CAL-15 | — | Enqueuing a pending row publishes the trigger and `runOutboxDrain` runs without waiting for the 15s interval (CalDAV dispatch stubbed) | unit/integration | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extends existing | ⬜ pending |
| SC-2 fire-and-forget 202 | 1 | CAL-15 | — | Publishing the signal is non-blocking; route enqueue path makes no inline CalDAV call (signal is fire-and-forget) | unit | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extends existing | ⬜ pending |
| SC-3 create-before-delete under move | 1 | CAL-15 | — | Edit-as-move publishes once after the transaction commits; CREATE row precedes DELETE; no signal fires between the two inserts | unit | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extends existing | ⬜ pending |
| SC-4 exactly-once overlap | 1 | CAL-15 | — | Concurrent `scheduleOutboxDrain` calls + 15s fallback overlap produce no duplicate CalDAV PUT for the same uid (`isDraining` guard + `pending AND next_attempt_at <= NOW()` selection unchanged) | unit | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extends existing | ⬜ pending |
| SC-5 / D-05 trailing re-drain | 1 | CAL-15 | — | A signal arriving during an in-flight drain sets `drainRequested` and triggers exactly one follow-up drain after the current one finishes; the 15s `setInterval` fallback still runs and recovers missed rows | unit | `vitest run tests/broker/outboxWorker.test.ts` | ✅ extends existing | ⬜ pending |
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
---
## Wave 0 Requirements
- Existing infrastructure covers all phase requirements. `apps/api/tests/broker/outboxWorker.test.ts`
already provides the DB / write / sync mock scaffold (`isDraining`, drain, edit-as-move ordering).
New cases are added to that file (or a sibling `tests/broker/outboxTrigger.test.ts`); no new
framework, config, or fixtures are installed.
---
## Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|----------|-------------|------------|-------------------|
| — | — | — | — |
*All phase behaviors have automated verification. No operator-stopwatch checkpoint (D-10): the dev-bypass user (id 1) has no CalDAV credential/calendars, so a live event-create 422s in the dev stack ([[dev-data-user1-no-calendars]]); the automated wiring test is the durable, CI-guarded evidence.*
---
## 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 (`vitest run`, not `vitest`)
- [ ] Feedback latency < 20s
- [ ] `nyquist_compliant: true` set in frontmatter
**Approval:** pending