Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.4 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created
| phase | slug | status | nyquist_compliant | wave_0_complete | created |
|---|---|---|---|---|---|
| 9 | faster-write-back | draft | false | false | 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 | ~5–20 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 15ssetIntervalfallback 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.tsalready provides the DB / write / sync mock scaffold (isDraining, drain, edit-as-move ordering). New cases are added to that file (or a siblingtests/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, notvitest) - Feedback latency < 20s
nyquist_compliant: trueset in frontmatter
Approval: pending