--- phase: 07-user-plugin-and-authentication verified: 2026-09-23T08:52:00Z status: passed score: 4/4 must-haves verified overrides_applied: 0 --- # Phase 7: User plugin and authentication Verification Report **Phase Goal:** The user plugin is ported with registration, login, JWT issue/refresh, organizations, personal API tokens and the must-change-password lock. **Verified:** 2026-09-23T08:52:00Z **Status:** passed ## Goal Achievement ### Observable Truths | # | Truth | Status | Evidence | |---|-------|--------|----------| | 1 | A user can register, log in, log out, reset a password, verify email, and receive a JWT the Nuxt app can use unchanged | ✓ VERIFIED | 15 `/_user/api/v1` routes and both nuxt-auth flows are `ported`. `TestParityCorpus` is recorded 169 / ported 22 / pending 147 / failing 0. UAT tests 1–4 and 12 passed. | | 2 | Organization fields arrive through a fire-and-collect event, and the user module does not import fonoteka | ✓ VERIFIED | UAT test 6: login/register include organisation fields; `go list -deps` on the user module does not import `plugins/golem15/fonoteka`. | | 3 | Personal tokens mint, list, and revoke inside the read/write/ai ceiling, and a read token is rejected on a write route | ✓ VERIFIED | UAT test 7; `TestTokenApi` and `TestInvScope`. | | 4 | The password lock returns 423 except locale and change-password, and locale still resolves while locked | ✓ VERIFIED | UAT tests 8–9; `TestMustChangePasswordLock`. | **Score:** 4/4 truths verified ### Required Artifacts | Artifact | Expected | Status | Details | |----------|----------|--------|---------| | `bouncer` JWT mint/refresh/blacklist | Session tokens | ✓ EXISTS + SUBSTANTIVE | Logout blacklists; fetch after logout is 401 | | `plugins/golem15/user` session and account handlers | Register through reset, activation, avatar | ✓ EXISTS + SUBSTANTIVE | Assembled avatar POST is 200 after 07-08 | | `plugins/golem15/fonoteka` tokens and locale | AUTH-03 and the lock exemption | ✓ EXISTS + SUBSTANTIVE | Ported token and locale routes replay green | | `parity` user-api fixtures | Byte-identical replay | ✓ REPLAYED | 15 user-api routes `ported`; both nuxt flows green | | serve + Handler bucket publish | Avatar boot path | ✓ EXISTS + SUBSTANTIVE | `TestPublishUploads*`, `TestAvatarAssembled` | **Artifacts:** 5/5 verified ### Key Link Verification | From | To | Via | Status | Details | |------|----|----|--------|---------| | fonoteka `getApiArray` listener | user payload | fire-and-collect | ✓ WIRED | UAT test 6 | | `InvScope` | token routes | Phase 6 middleware | ✓ WIRED | `TestInvScope` 403 for missing write | | user API handlers | Nuxt contract | parity replay | ✓ WIRED | `TestUserAPINuxtFlows` | | `attach.OpenBucket` | serve / Handler | `Publish` before Assemble | ✓ WIRED | `44900f0` / `bc1adf2` | **Wiring:** 4/4 connections verified ## Requirements Coverage | Requirement | Status | Blocking Issue | |-------------|--------|----------------| | AUTH-01 | ✓ SATISFIED | 07-07 flipped the 15 user-api routes and both nuxt flows to ported | | AUTH-02 | ✓ SATISFIED | Organisation fields via event; user does not import fonoteka | | AUTH-03 | ✓ SATISFIED | Mint, list, revoke, and scope ceiling | | AUTH-04 | ✓ SATISFIED | 423 lock with locale exemption | | I18N-02 | ✓ SATISFIED | preferred_locale then Accept-Language then app.locale, including while locked | **Coverage:** 5/5 requirements satisfied. ## Anti-Patterns Found None that block. Handler does not close the published `*blob.Bucket` (info in 07-REVIEW.md); CLI serve does. ## Human Verification Required None — UAT was curl-verified on the assembled Handler. The avatar 500 is closed by 07-08 (`TestAvatarAssembled`). ## Gaps Summary ### Critical Gaps (Block Progress) None. ### Non-Critical Gaps (Can Defer) - `app.Handler` does not close the uploads bucket (CLI serve does). Fine for `mem://` tests. - Static `/storage/uploads` is not mounted on Assemble; `avatar_url` is a path, not a served GET. Out of this phase's success criteria. ## Recommended Fix Plans None. ## Verification Metadata **Verification approach:** Goal-backward from ROADMAP Phase 7 success criteria after 07-08 gap closure **Must-haves source:** ROADMAP.md Phase 7 success criteria + 07-08 PLAN must_haves **Automated checks:** `go vet ./... && go test ./... -race` green in `summercms.go` and `fonoteka.go` plus nested plugin packages. `TestAvatarAssembled` green. Schema drift `drift_detected: false`. **Human checks required:** 0 **Regression gate:** prior-phase suites are in the same `go test ./... -race` run and passed --- *Verified: 2026-09-23T08:52:00Z* *Verifier: inline goal check after 07-08*