**Core value:** A user can sign in and run the Tablos workflow — organize work, attach files, discuss, and plan scheduled events — without a JS framework or managed chat provider.
- 2026-05-15: Phase 9 UAT complete. Five browser checkpoints passed after fixing the selected-etape create gap; backend verification passed with `TEST_DATABASE_URL='postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable' go test ./... -count=1`.
- **SignupForm/SignupErrors in templates package** (not handlers or separate forms pkg) — avoids import cycle between templates and internal/web
- **setupTestDB duplicated into web package test file** — Go prohibits importing _test.go files across packages; duplication chosen over non-test shared infra
- **nil-Store guard in auth.ResolveSession** — enables Phase 1 unit tests to pass AuthDeps{} zero value without panic
- **index_templ.go deleted manually after emptying index.templ** — templ generates broken import when .templ has no components (03-02)
- **Non-HTMX validation error re-fetches tablos and renders full dashboard** — no form state threading; simpler than threading form through full page (03-02)
- **_zone hidden field (title|desc) in edit fragments** — unified POST /tablos/{id} handler reads _zone to select which display fragment to return; misuse only affects response body, not DB state (03-03)
- **loadOwnedTablo helper for all parametric handlers** — uuid.Parse + GetTabloByID + ownership check factored into single function; 404 on any failure, 403 never used (D-04) (03-03)
- **TabloDeleteButtonFragment canonical delete-zone** — TabloCard delegates to it; single source of truth for zone HTML across card and detail-page contexts (03-03)
- **task_status ENUM order matches visual column order** (todo, in_progress, in_review, done) — ENUM ordinal sorting aligns with kanban column display order per Pitfall 6 (04-01)
- **Down migration drops TABLE before TYPE** — tasks table dropped before task_status type per Pitfall 3; type cannot be dropped while still referenced (04-01)
- **TasksDeps stub in test file** — declared in handlers_tasks_test.go; moved to handlers_tasks.go in Plan 02 to avoid file dependency before handlers exist (04-01)
- **TaskColumns/TaskColumnLabels in templates package** — moved from web package to templates to avoid web↔templates import cycle; handlers reference via templates.TaskColumns (04-02)
- **TabloDetailPage accepts tasks []sqlc.Task** — kanban board embedded below tablo header; TabloDetailHandler fetches tasks via ListTasksByTablo before rendering (04-02)
- **Dual reorder payload** — TaskReorderHandler supports array form (task_id[]/task_col[]) and single-value form (task_id/status/position) for test scaffold + Sortable.js compatibility (04-03)
- **GetTaskByID before UpdateTask in reorder** — preserves title+description (T-04-08), validates task-to-tablo ownership at fetch time (T-04-10) (04-03)
- **fileQuerier interface in OrphanCleanupWorker** — enables mock injection for pure unit tests without real DB; pool field retained for production (06-01)
- **river deps as // indirect until Plan 02** — cmd/worker wiring in Plan 02 will promote river to direct dependency; expected Go module behavior (06-01)
- **signal.NotifyContext after rivermigrate and S3 init** — startup I/O uses context.Background(); signal context created after all I/O succeeds; prevents river.Client.Start receiving a pre-cancelled context (RESEARCH Pitfall 2) (06-02)
- **pool.Close() explicit after StopAndCancel, not via defer** — StopAndCancel fully returns before pool is closed; matches PATTERNS.md pool close ordering (06-02)
- **Social-only users use NULL password_hash** — email/password login rejects them through the generic invalid-credentials path while provider sign-in owns the session path (08-01)
- **Verified provider identity links by provider subject first, then verified email** — prevents duplicate local users while keeping provider subject as the strongest identity key (08-02)
- **Apple callback uses GET/query response mode for the first working version** — keeps the callback inside existing CSRF middleware boundaries; Apple dashboard configuration must match (08-03)
- **Provider buttons degrade to disabled controls when config is missing** — auth pages remain deployable without provider credentials (08-04)
- **Account providers page is read-only in Phase 8** — linked identity visibility shipped before unlink/add-password account management (08-05)
- **Apple sign-in disabled after UAT scope change** — Apple controls are hidden, Apple auth routes are not mounted, and provider docs only cover Google for now (08-UAT)