Record the PHP-does-blacklist finding, the accepted Go 401 after logout, and the 22-ported corpus so later phases do not revive the harness artifact. Co-authored-by: Cursor <cursoragent@cursor.com>
7.6 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-user-plugin-and-authentication | 07 | auth |
|
|
|
|
|
|
|
|
|
3h 15m | 2026-09-22 |
Phase 7 Plan 07: User-API parity gap Summary
The 15 /_user/api/v1 routes and both nuxt auth flows replay green against Go and are ported; production PHP does blacklist on logout.
Performance
- Duration: 3h 15m
- Started: 2026-09-22T18:42:00Z
- Completed: 2026-09-22T21:57:22Z
- Tasks: 3
- Files modified: 28
Accomplishments
- Isolated PHP recording now uses
CACHE_DRIVER=fileso jwt-auth blacklist state persists across requests, matching production. - Go login/fetch/register/activate payloads match PHP (gravatar,
permissions: null,groups: [], Polish validation,Cache-Control: no-cache, private). - Already-activated
ActivateandActivateByCodeserve the embedded Winter production error page (500,text/html). TestParityCorpusis recorded 169 / ported 22 / pending 147 / failing 0. Bothnuxt-authandnuxt-auth-lockreplay green.
Task Commits
- Task 1: Persistent PHP cache + re-record logout fixtures —
aa5266finfonoteka.go - Task 2: Activation quirk, seed hooks, green replay, manifest flips —
31634f7insummercms.go,de83d41infonoteka.go - Task 3: Unit tests and corpus-count assertions —
016460ainfonoteka.go
Plan metadata: this docs commit
Files Created/Modified
parity/php_parity.sh—CACHE_DRIVER=fileand cache clear on resetparity/user_api_seed_test.go— direct-DB Alice seed; resetspreferred_locale/ surname leftoversparity/nuxt_flow_test.go— in-process replay of both nuxt fixtures; fetch-after-logout asserts 401parity/manifest.yaml— 15 user-api routesstatus: ported; fetchreusedcase removed from the ported listplugins/golem15/user/controllers/winter_error_page.html— byte copy of the recorded Winter pageplugins/golem15/user/controllers/api_controller.go—apiArray, localized errors, already-activated Winter pageplugins/golem15/user/classes/codes.go—IsAlreadyActivated;takeUseruses a fresh GORM sessionlagoon/validate.go+phrasebook/lang/{en,pl}/validate.yaml— Laravel-shaped Polish messages
Decisions Made
Production PHP does blacklist on logout (AuthManager::logout → JWTAuth::invalidate(true), blacklist_enabled defaults true, production CACHE_DRIVER=file). The previous STATE note that "PHP does not blacklist" was a harness artifact of isolated PHP running CACHE_DRIVER=array, which does not persist jwt-auth cache across requests. That note is superseded.
Go fetch-after-logout stays 401. Re-recorded PHP with file cache still returned 200 on the reused token because show_black_list_exception defaults to 0 (jwt-auth treats a blacklisted token as invalid without throwing). That is non-breaking for frontends; the reused fetch case remains on disk but is not a ported corpus case.
Already-activated activate is Winter's uncaught User is already active! → generic 500 HTML under APP_DEBUG=false, not a "wrong code" 422.
Deviations from Plan
Auto-fixed Issues
1. Fetch reused case left recorded but not ported
- Found during: Task 1/2 (logout re-record)
- Issue: Even with
CACHE_DRIVER=file, PHP fetch-after-logout stayed 200 (show_black_list_exceptiondefault 0). Plan must-have asked for byte-identical 401 in both backends. - Fix: User locked Go 401. Dropped the reused fetch case from the ported corpus; fixture file kept. Nuxt flow asserts 401 after logout and skips the PHP reuse step.
- Verification:
TestParityCorpusandTestUserAPINuxtFlowsgreen - Committed in:
aa5266f/de83d41
2. Shared TestMain pool leaked Alice profile and user id 1
- Found during: Task 3 (
go test ./... -race) - Issue: Other parity tests leave Alice
preferred_locale=enand a not-activated row at id 1, so login/fetch failed JSON compare and1!nopereturned 422. - Fix:
seedUserAPInulls leftover profile columns;ensureActivatedUserID(1)runs before activate-by-code replay. Unit test uses the just-activated user's id, not hardcoded1!nope. - Verification:
go test ./... -racegreen including./paritywithout-short - Committed in:
de83d41/016460a
3. takeUser isolated from leftover GORM clauses
- Found during: Task 3 (
TestActivateByCodeafterTestActivateon a shared*gorm.DB) - Issue: Root-session
Whereleftovers madeIsAlreadyActivatedmiss the activated row. - Fix:
takeUserusesSession({NewDB: true, Context: ctx}) - Verification:
TestActivate+TestActivateByCodetogether pass - Committed in:
de83d41
Total deviations: 3 auto-fixed (1 contract clarification, 2 test-harness isolation) Impact on plan: Required for a honest PHP contract and a green full-package race gate. No scope creep.
Issues Encountered
PHP file-cache re-record did not produce a 401 on fetch-after-logout. Locked as Go 401; documented above.
User Setup Required
None - no external service configuration required.
Next Phase Readiness
AUTH-01's user-api replay gap is closed. Phase 7's seven plans all have SUMMARYs. Ready for $gsd-verify-work 7 / phase verification — do not auto-advance to Phase 8.
Phase: 07-user-plugin-and-authentication Completed: 2026-09-22