Commit graph

992 commits

Author SHA1 Message Date
Arthur Belleville
cfd30eb277
docs(04): UI design contract 2026-05-15 09:05:54 +02:00
Arthur Belleville
cdcb335fec
docs(04): UI design contract for Tasks (Kanban) phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 09:01:17 +02:00
Arthur Belleville
02cf49ac31
docs(04): add validation strategy 2026-05-15 08:52:20 +02:00
Arthur Belleville
1c7b9d632c
docs(04): research phase tasks-kanban domain 2026-05-15 08:51:06 +02:00
Arthur Belleville
338e7e6e92
docs(state): record phase 4 context session 2026-05-15 08:40:41 +02:00
Arthur Belleville
f31951ce1d
docs(04): capture phase context 2026-05-15 08:40:37 +02:00
Arthur Belleville
58c8231af9
docs(03): mark REVIEW.md status fixed after applying CR/WR fixes
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:33 +02:00
Arthur Belleville
79435602c4
fix(03): WR-04 add color field error display to create form template
- TabloCreateErrors: add Color field for server-side hex validation error
- TabloCreateFormFragment: render FieldError for color field and update
  placeholder to hex-only hint (#6366f1) matching the validation constraint

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:27 +02:00
Arthur Belleville
38fe5b3909
fix(03): CR-02 capture user from loadOwnedTablo on update error path
- TabloUpdateHandler: capture user from loadOwnedTablo (was discarded with _)
- Pass captured user to TabloDetailPage on non-HTMX validation error path
  instead of nil, preventing broken layout (no logout button/email shown)
- TabloUpdateHandler: pass tablo.Color to UpdateTablo to preserve color on update (CR-01)
- loadOwnedTablo: pass GetTabloByIDParams{ID, UserID} to DB query (WR-01 call site)
- TabloDeleteHandler: pass DeleteTabloParams{ID, UserID} to DB query (WR-02 call site)
- TabloDeleteHandler: on DB error with HX-Request, render TabloDeleteConfirmFragment
  instead of plain http.Error to avoid broken HTMX DOM state (CR-03)
- renderTabloCreateError: log secondary ListTablosByUser fetch failure (WR-03)
- TablosCreateHandler: validate color with isValidCSSColor (hex only) and surface
  TabloCreateErrors.Color field error to prevent CSS injection (WR-04)
- Add isValidCSSColor helper using ^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$ regex
- Update test call sites for GetTabloByID and DeleteTablo new param types

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:22 +02:00
Arthur Belleville
fc41883b1f
fix(03): CR-01 WR-01 WR-02 add color to UpdateTablo and user_id filters to GetTabloByID/DeleteTablo
- UpdateTablo SQL: add color = \$4 so color is preserved across title/description edits
- GetTabloByID SQL: add AND user_id = \$2 to push ownership enforcement into the DB layer
- DeleteTablo SQL: add AND user_id = \$2 to push authorization into the DB layer
- sqlc bindings regenerated (UpdateTabloParams+Color, GetTabloByIDParams, DeleteTabloParams)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:11 +02:00
Arthur Belleville
7b945652d3
docs(03): add code review report 2026-05-15 08:24:09 +02:00
Arthur Belleville
a420a9c45c
docs(phase-03): complete phase execution — TABLO-01..06 verified 2026-05-15 08:21:38 +02:00
Arthur Belleville
450291a697
docs(03-03): complete Phase 3 — advance state and roadmap
Phase 3 Tablos CRUD fully complete: all 3 plans done, TABLO-01..06
closed, 10/10 TABLO tests green, browser verify passed. Advance active
phase to Phase 4 Tasks (Kanban).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:10:31 +02:00
Arthur Belleville
b5fa3188f4
docs(03-03): mark Task 3 checkpoint approved — plan 03-03 complete
Human verify passed all 13 sub-checks: ownership 404, CSRF forms on
every mutating form, inline edit/discard, inline delete confirm/cancel,
HX-Redirect navigation, and non-JS 303 fallback. Phase 3 fully complete.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 08:09:24 +02:00
Arthur Belleville
a78221ae1c
docs(03-03): plan 03-03 summary and state 2026-05-15 08:03:58 +02:00
Arthur Belleville
ab6937c1aa
feat(03-03): detail/edit/delete handlers + router wiring; all 10 TABLO tests green
- loadOwnedTablo helper: uuid.Parse, GetTabloByID, ownership check (D-04: 404 not 403)
- TabloDetailHandler: GET /tablos/{id} renders detail page
- TabloEditTitleHandler/ShowTitleHandler: GET /tablos/{id}/edit-title|show-title fragments
- TabloEditDescHandler/ShowDescHandler: GET /tablos/{id}/edit-desc|show-desc fragments
- TabloUpdateHandler: POST /tablos/{id} — validates, updates DB, renders matching zone fragment
- TabloDeleteConfirmHandler/CancelHandler: GET /tablos/{id}/delete-confirm|delete-cancel
- TabloDeleteHandler: POST /tablos/{id}/delete — deletes row, HX-Redirect:/ or 303
- router.go: 9 new routes in RequireAuth group, static-before-parametric order preserved
- Fix [Rule 1 - Bug]: test title "Owner's Tablo" caused HTML entity mismatch — changed to "Owners Detail Tablo"
- go test ./internal/web/... -run TestTablo: 10/10 PASS; full suite: all PASS
2026-05-15 08:02:43 +02:00
Arthur Belleville
6f167e2956
feat(03-03): detail page, edit and delete templ fragments + TabloUpdateErrors
- TabloDetailPage: full detail layout with title/desc/delete zones
- TabloTitleDisplay/EditFragment: outerHTML-swappable title zone with _zone=title hidden field
- TabloDescDisplay/EditFragment: outerHTML-swappable desc zone with _zone=desc hidden field
- TabloDeleteButtonFragment: canonical single-source delete zone (TabloCard now delegates here)
- TabloDeleteConfirmFragment: inline confirm with "Delete tablo?", "Yes, delete", "Keep tablo"
- TabloNotFoundPage: 404 page with UI-SPEC copy
- TabloUpdateErrors struct added to tablos_forms.go
- just generate + go build ./... both exit 0
2026-05-15 07:59:10 +02:00
Arthur Belleville
878ab69602
docs(03-02): complete plan 02 — checkpoint approved, SUMMARY + STATE finalized
- Task 3 human-verify checkpoint approved: dashboard, HTMX create, validation, non-JS fallback all confirmed
- SUMMARY updated: all 3 tasks complete, checkpoint outcome documented
- STATE updated: plan 02 marked complete, commit hashes recorded
- index.templ deletion fix noted as final deviation

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 07:56:44 +02:00
Arthur Belleville
c08da7f5bd
fix(03-02): delete retired index.templ to stop templ generating stale imports 2026-05-15 07:51:50 +02:00
Arthur Belleville
c4406cf16c
docs(03-02): plan 02 SUMMARY + STATE update — checkpoint at Task 3
- 03-02-SUMMARY.md: TablosDeps, handler contracts, template contracts,
  4/10 tests green, 6 RED for Plan 03, known stubs documented
- STATE.md: 2 new decisions, plan 02 metrics row added, notes updated
- ROADMAP.md: phase 3 progress updated (2/3 summaries)
2026-05-15 00:22:16 +02:00
Arthur Belleville
5db9215a73
feat(03-02): tablo handlers + router wiring — list/new/create green
- Implement TablosListHandler, TablosNewHandler, TablosCreateHandler in
  handlers_tablos.go replacing the Plan 01 stub
- TablosCreateHandler: reads via r.PostFormValue, validates title (required,
  <=255), inserts with pgtype.Text nullable params, sends HX-Retarget +
  HX-Reswap on HTMX success, 303 redirect on non-HTMX success
- router.go: replace r.Get("/", IndexHandler()) with TablosListHandler;
  add GET /tablos/new and POST /tablos (static before parametric — Pitfall 1)
- handlers.go: remove IndexHandler + unused auth/csrf imports
- index.templ: reduced to bare package declaration (dashboard moved to tablos.templ)
- index_templ.go: deleted (empty templ file generates broken import)
- TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation: PASS
- TestSignup, TestLogin, TestLogout, TestCSRF: still PASS (no regression)
2026-05-15 00:20:25 +02:00
Arthur Belleville
43ddf25364
feat(03-02): tablos templates — dashboard, empty state, card, create form, OOB-clear
- Create backend/templates/tablos.templ with TablosDashboard, TablosEmptyState,
  TabloCard, TabloCreateFormFragment, TabloCardWithOOBFormClear components
- Create backend/templates/tablos_forms.go declaring TabloCreateForm and
  TabloCreateErrors types (mirrors auth_forms.go pattern)
- Update layout.templ footer: "Phase 2 · Authentication" → "Phase 3 · Tablos"
- TabloCardWithOOBFormClear emits OOB div as top-level sibling (Pitfall 5)
- TabloCard guards description/color rendering with pgtype.Text null checks
- All UI-SPEC copywriting copy strings present; templ generate succeeds
2026-05-15 00:17:56 +02:00
Arthur Belleville
2f22d68776
docs(03-01): complete Plan 01 — migration, test scaffold, button CSS
- 03-01-SUMMARY.md: tablos schema foundation, RED test scaffold, button CSS variants
- STATE.md: decisions + metrics for 03-01; phase 3 status updated
- ROADMAP.md: phase 3 plan progress (1/3 complete)
- REQUIREMENTS.md: TABLO-01..06 marked complete
2026-05-15 00:15:36 +02:00
Arthur Belleville
2c1b186fb7
feat(03-01): add ui-button-solid-danger-md and ui-button-soft-neutral-md CSS variants
- Danger variant: #b91c1c bg, #991b1b hover, min-height 44px (WCAG 2.5.5)
- Neutral-soft variant: #f1f5f9 bg, #e2e8f0 hover, #334155 text, min-height 44px
- All pseudo-class selectors top-level (no CSS nesting per Phase 1 convention)
- static/tailwind.css updated via just generate (Pitfall 4: imported CSS passes through)
2026-05-15 00:13:56 +02:00
Arthur Belleville
c8f44b1ad2
test(03-01): add TablosDeps stub and RED integration test scaffold for TABLO-01..06
- handlers_tablos.go: TablosDeps stub type enabling test compilation
- handlers_tablos_test.go: 10 integration tests (RED baseline) for all TABLO-01..06 paths
  - TestTabloList, TestTabloList_Empty, TestTabloCreate, TestTabloCreate_Validation
  - TestTabloDetail_Owner, TestTabloDetail_NonOwner, TestTabloDetail_InvalidID
  - TestTabloUpdate, TestTabloDeleteConfirm, TestTabloDelete
- router.go: NewRouter accepts TablosDeps as second deps parameter
- handlers_auth_test.go, handlers_test.go, csrf_test.go: update NewRouter call sites
- cmd/web/main.go: construct and pass TablosDeps to NewRouter
2026-05-15 00:13:31 +02:00
Arthur Belleville
f1b8d6e629
feat(03-01): add tablos migration and sqlc queries
- 0003_tablos.sql: tablos table with user_id FK + ON DELETE CASCADE + tablos_user_id_idx
- tablos.sql: 5 named queries (ListTablosByUser, GetTabloByID, InsertTablo, UpdateTablo, DeleteTablo)
- UpdateTablo sets updated_at = now() explicitly (Pitfall 7)
- color not editable in UpdateTablo per Phase 3 scope
- sqlc generates Tablo struct with pgtype.Text for description/color (not committed per .gitignore convention)
2026-05-15 00:10:40 +02:00
Arthur Belleville
f53b54637b
docs(03): plan phase 3 — Tablos CRUD (3 plans, 3 waves)
Plans cover TABLO-01..06 via MVP vertical slices: foundation (migration
+ sqlc + test scaffold + button CSS), list+create (dashboard, inline
form, OOB swap), and detail+edit+delete (ownership 404, inline edit
fragments, inline confirm delete). Includes Nyquist VALIDATION.md and
PATTERNS.md with real analog excerpts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:08:08 +02:00
Arthur Belleville
dc7f5ac4e2
docs(03): research phase domain 2026-05-14 23:51:35 +02:00
Arthur Belleville
65cdfbc00f
docs(03): fix UI-SPEC checker blocks — copywriting labels and typography weight
- Replace generic "Save"/"Cancel" with specific labels: "Save changes",
  "Discard changes", "Keep tablo" throughout spec, component inventory,
  interaction contracts, and HTMX reference table
- Remove 500 (medium) weight; form labels now use font-semibold (600),
  consistent with Button convention — 2 declared weights total

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-14 23:42:53 +02:00
Arthur Belleville
c779d2aee1
docs(03): UI design contract for Tablos CRUD phase
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-14 23:39:48 +02:00
Arthur Belleville
ab5b58cd06
docs(state): record phase 3 context session 2026-05-14 23:36:00 +02:00
Arthur Belleville
5fe692aa93
docs(03): capture phase 3 context 2026-05-14 23:35:55 +02:00
Arthur Belleville
df78ed2832
docs(02): phase 2 verification PASSED — AUTH-01..07 complete
All 7 plans executed and verified against the phase boundary.
2026-05-14 23:06:31 +02:00
Arthur Belleville
efb3df51da
docs(02-07): complete gorilla/csrf integration plan (AUTH-06 closed)
- SUMMARY.md: gorilla/csrf middleware, ui.CSRFField, env-driven key, all CSRF tests
- STATE.md: Phase 2 complete (7/7), decisions, commits, metrics recorded
- ROADMAP.md: Phase 2 Authentication marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:01:36 +02:00
Arthur Belleville
389e1bc8b4
feat(02-07): gorilla/csrf integration — mount middleware, wire all forms, env-driven key
- auth.Mount(env, key) wraps csrf.Protect with locked D-14/D-24 options
- auth.LoadKeyFromEnv() reads SESSION_SECRET, hex-decodes, validates 32 bytes; fails fast on error
- ui.CSRFField(token) templ component renders hidden _csrf input
- Layout, LoginPage/Fragment, SignupPage/Fragment, Index all embed @ui.CSRFField(csrfToken)
- Handlers thread csrf.Token(r) into every page/fragment render call
- NewRouter mounts auth.Mount after ResolveSession, before all route groups (D-24)
- main.go calls auth.LoadKeyFromEnv(); logs.Fatalf on missing/invalid SESSION_SECRET
- SESSION_SECRET documented in .env.example with openssl rand -hex 32 instruction
- go.mod: gorilla/csrf v1.7.3 (direct); prior tests updated with getCSRFToken helper
- All Plan 04/05/06 tests updated to acquire and submit valid _csrf tokens
2026-05-14 22:59:06 +02:00
Arthur Belleville
ae2d356f87
test(02-07): add failing CSRF tests (RED gate)
- TestLoadCSRFKey_* in internal/auth for env key loading
- TestCSRF_*MissingToken / TestCSRF_*ValidToken for all three POST routes
- TestForms_ContainCSRFField for hidden _csrf input in rendered HTML
- TestRouter_CSRFMountedAfterResolveSession for middleware order (D-24)
- TestCSRF_HeaderFallback for X-CSRF-Token header support
- Add gorilla/csrf v1.7.3 dependency
2026-05-14 22:45:36 +02:00
Arthur Belleville
00a9388c32
docs(02-06): complete logout + protected routes + layout plan
- Create 02-06-SUMMARY.md with TDD gate compliance, router middleware snapshot
- Update STATE.md: plans 01-06 complete, plan 07 (CSRF) next
- Update ROADMAP.md: Phase 2 at 6/7 plans, 02-06 checked
- Mark AUTH-04 complete in REQUIREMENTS.md (AUTH-05 was already checked)
2026-05-14 22:42:23 +02:00
Arthur Belleville
8b54ff4bec
feat(02-06): implement logout, protect GET /, and update layout with auth state
- Add LogoutHandler: deletes session row (D-06), clears cookie, redirects to /login
- Protect GET / inside RequireAuth group; remove old top-level registration
- Add POST /logout inside same RequireAuth group (D-22: POST-only logout)
- Update Layout signature to accept *auth.User; render logout form + email when authed
- Update Index template to accept *auth.User and show "Signed in as {email}"
- Update SignupPage/LoginPage to pass nil to Layout (auth pages are unauthed)
- Update IndexHandler to pull user from auth.Authed(ctx) and pass to template
- Update TestIndex_RendersHxGet -> TestIndex_UnauthRedirects (GET / now protected)
- AUTH-04 (logout) and AUTH-05 (protected /) are now closed
2026-05-14 22:40:10 +02:00
Arthur Belleville
b5c3fc4d48
test(02-06): add failing tests for logout, protected routes, and layout auth
- TestLogout_Success: POST /logout with valid cookie -> 303, cookie cleared, session deleted
- TestLogout_UnauthRedirectsToLogin: POST /logout without cookie -> 303 from RequireAuth
- TestLogout_HXRedirect: HTMX logout -> 200 + HX-Redirect: /login
- TestLogout_AfterLogoutSubsequentRequestUnauth: stale cookie blocked after logout
- TestProtected_HomeUnauthRedirects: GET / without session -> 303 /login
- TestProtected_HomeUnauthHXRedirect: HTMX GET / without session -> 200 + HX-Redirect
- TestProtected_HomeAuthRendersUserEmail: authed GET / -> 200 with user email
- TestLayout_LogoutFormVisibleWhenAuthed: Layout with user shows logout form
- TestLayout_LogoutFormHiddenWhenUnauthed: Layout with nil user hides logout form
2026-05-14 22:32:33 +02:00
Arthur Belleville
977dafa31d
docs(02-05): complete login + rate limit plan
- SUMMARY.md: login vertical slice, rate limiter design decisions, 12 test results
- STATE.md: advance to 5/7 plans, add decisions, metrics row
- ROADMAP.md: mark 02-05 complete (5/7 plans)
- REQUIREMENTS.md: mark AUTH-07 complete (rate limit delivered)
2026-05-14 22:30:00 +02:00
Arthur Belleville
7d8c498980
feat(02-05): login vertical slice with rate limiting
- auth_login.templ: LoginPage + LoginFormFragment (mirrors signup shape)
- LoginForm + LoginErrors types added to templates/auth_forms.go
- LoginPageHandler + LoginPostHandler in handlers_auth.go
  - Rate-limit check before user lookup (D-16, T-2-14)
  - Single errInvalidCreds constant for D-20 enumeration defense
  - Session rotation via Store.Rotate on success (D-10, T-2-04)
  - HTMX-aware redirect and fragment responses (D-19, D-21)
- AuthDeps extended with Limiter *auth.LimiterStore field
- router.go: GET /login in RedirectIfAuthed group (D-23)
- main.go: LimiterStore created with janitor goroutine (D-16)
- Export NewLimiterStoreWithClock + SetLimiterClock for cross-package tests
- 12 TestLogin_* integration tests all pass with real DB
2026-05-14 22:27:54 +02:00
Arthur Belleville
b5c20c7892
feat(02-05): implement LimiterStore with injectable clock and janitor
- Token-bucket rate limiter keyed per (email+IP) using golang.org/x/time/rate
- rate.Every(12s), burst=5, idleTTL=10min (D-16)
- AllowN(t, 1) with injectable clock for deterministic tests (Pattern 8)
- Janitor goroutine evicts entries idle > 10min via cleanupNow()
- No .Allow() without args (Pitfall 8 avoided)
- Five tests pass with -race: burst, refill, isolation, janitor, concurrent
- golang.org/x/time v0.15.0 added to go.mod
2026-05-14 22:22:24 +02:00
Arthur Belleville
f6a453ff1f
docs(02-04): complete signup vertical slice plan
- Add 02-04-SUMMARY.md: signup form + handler + integration tests
- Update STATE.md: plan 04 complete (4/7 in phase 2), plan 05 next
- Update ROADMAP.md: 02-04 checked off, phase 2 progress 4/7
2026-05-14 22:20:09 +02:00
Arthur Belleville
efdc16babe
feat(02-04): signup handler, router wiring, and integration tests
- Add handlers_auth.go: SignupPageHandler + SignupPostHandler (validate -> hash -> insert -> session -> redirect)
- Add AuthDeps struct; wire argon2id hash, InsertUser, Store.Create, SetSessionCookie
- Update router.go: NewRouter accepts AuthDeps; mount ResolveSession (D-24); wire /signup routes behind RedirectIfAuthed
- Update cmd/web/main.go: build AuthDeps (sqlc.Queries + auth.Store + secure flag) and pass to NewRouter
- Add nil-Store guard to auth.ResolveSession for Phase 1 unit-test compatibility
- Update handlers_test.go: pass AuthDeps{} zero value to NewRouter (Phase 1 routes unaffected)
- Add testdb_test.go: isolated-schema test helper for web package integration tests
- Add handlers_auth_test.go: 8 TestSignup_* integration tests (all pass against real Postgres)
2026-05-14 22:17:50 +02:00
Arthur Belleville
73935ed11c
feat(02-04): signup templates (full page + HTMX fragment) with render tests
- Create auth_form_errors.templ: FieldError and GeneralError primitives
- Create auth_signup.templ: SignupPage (full) and SignupFormFragment (HTMX swap target)
- Define SignupForm and SignupErrors types in templates/auth_forms.go
- Add three smoke tests: renders form, renders errors, does not echo password
2026-05-14 22:14:28 +02:00
Arthur Belleville
38596ac41e
docs(02-03): complete session store + middleware plan
- Create 02-03-SUMMARY.md: SHA-256 token hashing, sliding TTL, HTMX-aware chi middleware
- STATE.md: advance to plan 03 complete, plan 04 (signup) next
- ROADMAP.md: Phase 2 progress 3/7 plans
- REQUIREMENTS.md: mark AUTH-02, AUTH-03, AUTH-05 complete
2026-05-14 22:11:58 +02:00
Arthur Belleville
1d07830954
feat(02-03): ResolveSession + RequireAuth + RedirectIfAuthed middleware
- ResolveSession: reads cookie, SHA-256 lookup, MaybeExtend best-effort, attaches Session+User to ctx
- RequireAuth: 303 /login for plain requests; HX-Redirect: /login for HTMX (D-23, Pattern 5)
- RedirectIfAuthed: bounces authed users to / from login/signup pages
- Authed(ctx): typed context accessor for session + user
- redirect helper centralizes 303 vs HX-Redirect logic (Pitfall 9: no 302)
- 9 tests: 3 real-DB (ResolveSession) + 6 pure ctx/routing (RequireAuth, RedirectIfAuthed)
2026-05-14 22:09:58 +02:00
Arthur Belleville
fd2301decf
feat(02-03): session store + cookie helpers (real-DB TDD)
- Store.Create: 32-byte crypto/rand token, SHA-256 hex as DB id (D-05)
- Store.Lookup: hashes cookie, maps pgx.ErrNoRows to ErrSessionNotFound (D-07)
- Store.Delete: hard-deletes session row (D-06)
- Store.Rotate: deletes old row before creating new one (D-10, T-2-04)
- Store.MaybeExtend: extends only when remaining < 7 days (D-09)
- SetSessionCookie: HttpOnly + Secure (env-gated) + SameSite=Lax (D-12)
- ClearSessionCookie: MaxAge=-1 not 0 (RESEARCH Pattern 3 / D-06)
- 10 tests: 7 real-DB (skip without TEST_DATABASE_URL) + 3 cookie unit tests
2026-05-14 22:08:04 +02:00
Arthur Belleville
648ce143a2
docs(02-02): complete argon2id password TDD plan
- Add 02-02-SUMMARY.md: argon2id Hash+Verify, DefaultParams (OWASP 2024), TestParams, init self-test
- Update STATE.md: plan 02 complete, plan count 7, decision logged
- Update ROADMAP.md: phase 2 now shows 2/7 plans complete
2026-05-14 22:02:25 +02:00
Arthur Belleville
ee36a5c78b
feat(02): GREEN — argon2id Hash + Verify + self-test
- Add Params struct with Memory/Iterations/Parallelism/SaltLength/KeyLength
- DefaultParams: OWASP 2024 baseline (m=64KiB, t=1, p=4, salt=16B, key=32B) — D-08
- TestParams: reduced cost (m=8KiB) so go test stays under 5s — D-26/Pitfall 4
- Hash(): crypto/rand salt per call, argon2.IDKey, PHC format $argon2id$v=19$...
- Verify(): PHC split/parse, ErrInvalidHash on malformed, ErrIncompatibleVersion on v!=19
- subtle.ConstantTimeCompare for timing-attack resistance (T-2-13)
- init() self-test: hash/verify round-trip panics on regression (D-08/T-2-15)
- Add golang.org/x/crypto v0.51.0 as direct dependency
2026-05-14 22:00:55 +02:00