xtablo-source/.planning/phases/02-authentication/02-VALIDATION.md

6.2 KiB
Raw Blame History

phase slug status nyquist_compliant wave_0_complete created
2 authentication draft false false 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 ~1530 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 <automated> 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
01-T1 01 1 AUTH-01,AUTH-02 T-2-08b Schema, sqlc gen, test harness integration cd backend && go build ./... && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/db/... -count=1 pending
02-T1 02 2 AUTH-01 T-2-01 argon2id PHC Hash/Verify, malformed-PHC + version-mismatch rejection (RED→GREEN→REFACTOR) unit (tdd) cd backend && go test ./internal/auth -run "TestPassword_" -count=1 pending
03-T1 03 2 AUTH-02,AUTH-03,AUTH-05 T-2-04,T-2-05,T-2-06 Session create/lookup/rotate/extend; cookie attrs; ResolveSession/RequireAuth/RedirectIfAuthed integration cd backend && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/auth -run "TestSession_|TestCookie_|TestResolveSession|TestRequireAuth|TestRedirectIfAuthed" -count=1 pending
04-T1 04 3 AUTH-01,AUTH-03,AUTH-05 T-2-01,T-2-03 Signup E2E: validate → argon2 → InsertUser → Store.Create → 303; RedirectIfAuthed wraps GET /signup integration cd backend && templ generate && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/web -run "TestSignup_" -count=1 pending
05-T1 05 4 AUTH-02,AUTH-03,AUTH-05,AUTH-07 T-2-02,T-2-03 Login E2E: rate-check → Verify → Rotate → cookie → 303; generic error string; rate limiter burst+per-key+janitor with injectable clock integration cd backend && templ generate && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/web ./internal/auth -run "TestLogin_|TestRateLimit_" -count=1 pending
06-T1 06 5 AUTH-04,AUTH-05 T-2-07,T-2-10 Logout deletes row + clears cookie; / now protected; Layout shows logout button only when authed integration cd backend && templ generate && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/web ./templates -run "TestLogout_|TestProtected_|TestLayout_" -count=1 pending
07-T1 07 6 AUTH-06 T-2-08,T-2-08a,T-2-08b,T-2-08c,T-2-08d gorilla/csrf mounted after ResolveSession; @ui.CSRFField in every form; SESSION_SECRET from env; 403 on missing token, 200/303 on valid integration cd backend && templ generate && TEST_DATABASE_URL=$DATABASE_URL go test ./internal/web ./internal/auth ./cmd/web -run "TestCSRF_|TestForms_ContainCSRFField|TestRouter_CSRFMountedAfterResolveSession|TestLoadCSRFKey" -count=1 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 <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