diff --git a/.planning/phases/02-authentication/02-VALIDATION.md b/.planning/phases/02-authentication/02-VALIDATION.md new file mode 100644 index 0000000..0b91d74 --- /dev/null +++ b/.planning/phases/02-authentication/02-VALIDATION.md @@ -0,0 +1,83 @@ +--- +phase: 2 +slug: authentication +status: draft +nyquist_compliant: false +wave_0_complete: false +created: 2026-05-14 +--- + +# Phase 2 — Validation Strategy + +> Per-phase validation contract for feedback sampling during execution. + +--- + +## Test Infrastructure + +| Property | Value | +|----------|-------| +| **Framework** | Go `testing` + `go test` (stdlib) | +| **Config file** | `backend/go.mod` (no separate config) | +| **Quick run command** | `cd backend && go test ./internal/auth/...` | +| **Full suite command** | `cd backend && go test ./...` | +| **Estimated runtime** | ~15–30 seconds (argon2 tests use reduced params) | + +DB-touching tests require `TEST_DATABASE_URL` pointing at the compose-managed Postgres (see Phase 1 pattern in `backend/internal/db/pool_test.go`). Each test runs in a transaction that rolls back, OR uses a per-test schema name to avoid cross-contamination. + +--- + +## Sampling Rate + +- **After every task commit:** Run `go test ./internal/auth/...` +- **After every plan wave:** Run `go test ./...` +- **Before `/gsd-verify-work`:** Full suite must be green +- **Max feedback latency:** 30 seconds + +--- + +## Per-Task Verification Map + +Filled by planner as PLAN.md tasks are emitted. Each task with `type: execute` must have an `` verify command OR an explicit Wave 0 dependency. Tasks creating templ/HTML output may need a small Go test that renders the component and asserts the resulting HTML contains expected markers. + +| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status | +|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------| +| (to be filled by planner) | | | | | | | | | ⬜ pending | + +*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky* + +--- + +## Wave 0 Requirements + +- [ ] `backend/internal/auth/password_test.go` — argon2 hash/verify round-trip with reduced test params +- [ ] `backend/internal/auth/session_test.go` — token generate + SHA-256 lookup, expiry semantics +- [ ] `backend/internal/auth/ratelimit_test.go` — per-key bucket allow/deny with injectable clock +- [ ] `backend/internal/auth/middleware_test.go` — ResolveSession context plumbing, RequireAuth 303 / HX-Redirect +- [ ] Reuse `backend/internal/db/pool_test.go` Postgres harness for users/sessions integration tests + +*Existing Go test infrastructure (Phase 1) covers framework setup — no new tooling install needed.* + +--- + +## Manual-Only Verifications + +| Behavior | Requirement | Why Manual | Test Instructions | +|----------|-------------|------------|-------------------| +| Cookie is `HttpOnly` and `Secure` in non-dev environments | AUTH-03 | Browser DevTools required to inspect cookie attributes from a live response | Run `ENV=staging` server, hit `/login`, submit valid creds, open DevTools → Application → Cookies; confirm `HttpOnly=true`, `Secure=true`, `SameSite=Lax` | +| `/login` page visual layout matches Phase 1 design system | AUTH-01 / D-69 | Visual assertion | Open `http://localhost:8080/login`, confirm Button/Card/Badge styling from `internal/web/ui` is applied; confirm `/signup` mirrors | +| HTMX inline form-error swap on bad credentials | AUTH-02 | Requires browser to evaluate `HX-Request` round-trip | Submit `/login` with bad password via HTMX form; only the form fragment swaps with "Invalid email or password" — no full page reload | +| Rate-limit error fragment shows after 6th failed login | AUTH-06 | Requires browser to observe 429 + swap | Submit 6 wrong-password attempts in <60s from same IP; 6th returns 429 with "Too many attempts" inline fragment | + +--- + +## Validation Sign-Off + +- [ ] All tasks have `` 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