scripts/check-phase8.sh's final gate ran once with every stage green except stage_ui_harness's Playwright browser matrix, a deliberate fatal() never authored by 08-05. The user approved closing Phase 8 with this gap carried forward; 08-VALIDATION.md flips 08-W0-07 green, marks 08-W0-08 partially verified, and sets nyquist_compliant: false honestly. deferred-items.md records what the follow-up spec needs to do.
11 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created, updated
| phase | slug | status | nyquist_compliant | wave_0_complete | created | updated |
|---|---|---|---|---|---|---|
| 08 | oauth2-1-authorization-server | complete | false | true | 2026-09-23 | 2026-09-24 |
Phase 08 — Validation Strategy
Per-phase validation contract for feedback sampling during execution.
Test Infrastructure
| Property | Value |
|---|---|
| Framework | Go 1.27 testing; existing testcontainers-backed Postgres harness; Node.js 22 plus the unchanged fonoteka-mcp only for end-to-end gates |
| Config file | Existing go.work, repository package tests, ../fonoteka.go/plugins/golem15/fonoteka/classes/TestMain, and planned scripts/check-phase8.sh |
| Quick run command | go test ./wristband -count=1 |
| App-focused command | `cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'TestOAuth |
| Full suite command | scripts/check-phase8.sh — Plan 08-10 Task 3 only |
| Estimated runtime | Every task command is focused and designed for ≤30 seconds; the sole final two-repository parity/race/UI/real-MCP gate may take several minutes |
Sampling Rate
- After every task commit: Run the narrowest affected package test;
go test ./wristband -count=1is the default framework check. - After every task: Run only the named package/test, shell syntax, source assertion, or contract self-test shown in that task; focused Postgres tests select one behavior family.
- Final blocking checkpoint only (08-10 Task 3):
scripts/check-phase8.shruns both repositories' vet/test/race, full parity/corpus, full UI, secret scan, security review, and unchanged real-MCP lifecycle exactly once. - Max feedback latency: Task-level commands are designed for ≤30 seconds. Complete repository suites, race, full parity/corpus, browser UI, Docker services, and real MCP are forbidden before the final checkpoint.
Per-Task Verification Map
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| 08-W0-01 | 08-01, 08-03, 08-04, 08-06, 08-10 | 1, 3, 4, 6, 9 | AUTH-05 | T-08-PKCE / T-08-CODE-REPLAY | Mounted metadata plus deterministic authorize, PKCE S256, code exchange, refresh, and ordered redirects have focused tests | unit/route | `go test ./wristband -run 'Test(Metadata | Authorize | Token |
| 08-W0-02 | 08-02, 08-04, 08-06, 08-10 | 2, 4, 6, 9 | AUTH-05, AUTH-07 | T-08-DCR-FLOOD / T-08-CODE-REPLAY / T-08-REFRESH-REPLAY | Nullability, persistent DCR, row locks, single-use codes, committed lineage kill, sweeps, and indexes work on real Postgres | integration | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/classes/auth -run '^TestOAuth' -count=1 |
✅ W0 | ✅ green (2026-09-24) |
| 08-W0-03 | 08-01-05, 08-10 | 1-5, 9 | AUTH-06 | T-08-DCR-FLOOD / T-08-SURFACE | Metadata/DCR/authorize/token raw routing, parsers, rate limits, 64 KiB bound, exact bare bodies, and headers remain isolated | route/integration | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestOAuth' -count=1 |
✅ W0 | ✅ green (2026-09-24) |
| 08-W0-04 | 08-05, 08-06, 08-10 | 5-6, 9 | AUTH-07 | T-08-SCOPE-CEILING / T-08-CROSS-USER | Consent, active-collection binding, connected-app ownership, list, and revoke semantics match PHP | Postgres integration | cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/controllers/... -run 'TestOAuth' -count=1 |
✅ W0 | ✅ green (2026-09-24; ownership/scope-ceiling coverage lives in the root plugins/golem15/fonoteka package's TestOAuthConsent*/TestOAuthRevocation*, exercised by 08-W0-03's command) |
| 08-W0-05 | 08-09, 08-10 | 8-9 | AUTH-05, AUTH-06, AUTH-07 | T-08-REQUEST-LEAK / T-08-SURFACE | Nine manifest routes plus mcp-lifecycle replay exactly and every one of 103 PHP OAuth/security methods maps to a named Go test |
parity/corpus | Focused TestOAuthFlows/map audits during tasks; full corpus only in scripts/check-phase8.sh at 08-10 Task 3 |
✅ W0 | ✅ green (2026-09-24; parity/oauth_audit_test.go:TestPHPTestMap confirms all 103 rows; full corpus gate is Task 3) |
| 08-W0-06 | 08-08, 08-09 | 7-8 | AUTH-07 | T-08-SURFACE | Exact authenticated /api/v1/fonoteka/me lets the unchanged MCP process initialize without expanding the profile API surface |
integration/e2e | `cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'TestMe | TestTokenSurface' -count=1` | ✅ W0 |
| 08-W0-07 | 08-09, 08-10 | 8-9 | AUTH-05, AUTH-07 | All T-08 threats | 08-09 self-validates the gate contract; 08-10 final checkpoint alone runs real SDK discovery, DCR, PKCE, JWT consent, token, tool, refresh/replay, revoke, and post-revoke failure unchanged | e2e | scripts/check-phase8.sh only at 08-10 Task 3 |
✅ W0 | ✅ green (2026-09-24; 08-10 Task 3's sole real execution of scripts/check-phase8.sh -- docker preflight, Postgres, app boot, real unchanged fonoteka-mcp discovery/DCR/PKCE authorize/JWT consent/token/tool-call/refresh/replay/revoke/post-revoke-failure, both repos' vet/test/race, 169/169 parity corpus, secret scan, security-review gate, and unchanged-client diff all ran green; see checkpoint transcript and 08-10-SUMMARY.md) |
| 08-W0-08 | 08-05, 08-09, 08-10 | 5, 8-9 | AUTH-05, AUTH-07 | T-08-CROSS-USER / T-08-SURFACE | 08-05 self-validates scenario coverage; 08-10 final checkpoint alone executes invalid-handle, return-path, consent/apps, accessibility, mobile, and en/pl browser checks without Nuxt changes | browser/contract | Full scripts/check-phase8-ui.mjs plus Nuxt verifiers only inside final scripts/check-phase8.sh |
✅ W0 | ⚠️ partially verified (2026-09-24; verify:oauth-return-path (6/6) and verify:oauth-i18n (74 keys) ran for real and are green, but check-phase8-ui.mjs --final-gate's real Playwright browser matrix (32 UI-SPEC scenarios) is a deliberate fatal() at scripts/check-phase8-ui.mjs:458, never authored by 08-05. User approved closing Phase 8 with this gap carried forward -- see deferred-items.md's "Follow-up: Playwright UI matrix" entry. stage_ui_harness must keep failing closed until the spec exists.) |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
08-10 Task 2 update (2026-09-24): 08-W0-01 through 08-W0-06's automated
commands were re-run during the security review and are green; their
File Exists columns flip to ✅ now that 08-PHP-TEST-MAP.md,
08-SECURITY-REVIEW.md and this file's own task IDs are finalized.
08-10 Task 3 update (2026-09-24): scripts/check-phase8.sh ran with no
flags for the first and sole time. 08-W0-07 is green (the real unchanged
fonoteka-mcp lifecycle, both repos' vet/test/race, parity corpus, secret
scan, security-review gate, and unchanged-client diff all passed). 08-W0-08
is partially verified: the return-path and i18n checks are real and green,
but the Playwright browser matrix was never authored by 08-05 and remains a
deliberate fatal(); see the row above and deferred-items.md.
Wave 0 Requirements
wristband/*_test.go— metadata, authorize, token, DCR, PKCE, refresh/replay, deterministic clock/random, ordered RFC3986 encoding, and 64 KiB body-bound tests.../fonoteka.go/plugins/golem15/fonoteka/updates/*oauth*_test.go— additive nullability/index correction with safe up/down behavior.../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_store_test.go— real-Postgres transaction, row-lock, concurrent single-use, sweep, and lineage tests.../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*oauth*_test.go— exact raw/JWT endpoint bodies, headers, status codes, consent ownership, and connected-app behavior.../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*me*_test.go— minimalinv_token-authenticated MCP bootstrap contract.../fonoteka.go/parity/oauth_flow_test.goandmcp-lifecyclefixture — projected existing flows and clean lifecycle/replay coverage.scripts/check-phase8.sh— two-repository vet/test/race, corpus, secret, security-review, and real-MCP gate. Stage bodies complete since 08-09; executed end to end by 08-10 Task 3 (2026-09-24) -- every stage green exceptstage_ui_harness's Playwright matrix (carried-forward gap, see deferred-items.md).scripts/check-phase8-ui.mjs— read-only unchanged-Nuxt state, accessibility, return-path, i18n, and responsive contract gate.scripts/check-phase8-red.sh— machine-readablego test -jsonverifier requiring exact selected test/package/sentinel and zero unexpected fail actions, plus exact exit-86 stage/sentinel shell protocol.08-SECURITY-REVIEW.md— map everyT-08-*threat to a failing-when-broken test and close all high-severity threats.status: verified,threats_open: 0, 11/11 closed (2026-09-24).
Manual-Only Verifications
All phase behaviors are automated. Live Claude, ChatGPT, and Grok connections are explicitly deferred to cutover UAT; they are not Phase 8 acceptance checks.
Validation Sign-Off
- All final plan tasks have an automated command or an explicit Wave 0 dependency.
- Sampling continuity: no three consecutive implementation tasks lack automated verification.
- Wave 0 covers every currently missing test/gate reference above.
- No watch-mode flags appear in validation commands.
- Task-level feedback is designed for ≤30 seconds; all complete suite/race/parity/UI/real-MCP work appears only in 08-10 Task 3.
nyquist_compliant: trueis set after task IDs are finalized and every mapping is implemented. Not set. 08-W0-08's Playwright browser matrix (32 UI-SPEC scenarios) is not implemented (check-phase8-ui.mjs:458's deliberatefatal()), so this file's own definition of Nyquist compliance is not fully true.nyquist_compliant: falsereflects that honestly; the flag should flip back totrueonly once the follow-up Playwright spec (deferred-items.md) exists and--final-gateruns it for real.
Approval: 08-10 Tasks 1-2 complete and green (2026-09-24). Task 3 ran
scripts/check-phase8.sh's full gate exactly once: every stage passed
except stage_ui_harness's Playwright browser matrix, which is a deliberate,
never-authored fatal() inherited from 08-05's own scope boundary (not a
regression introduced by this plan). Presented with that evidence, the user
approved Phase 8 closure on 2026-09-24 with the Playwright gap explicitly
carried forward as a named follow-up ("Approve, carry gap forward" --
08-10 Task 3 checkpoint decision; see deferred-items.md and 08-10-SUMMARY.md).
This file's status: field is complete; nyquist_compliant stays false
until the follow-up closes.