docs(08-10): record the checkpoint decision and carry the Playwright UI matrix gap forward

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.
This commit is contained in:
Jakub Zych
2026-09-24 00:56:20 +02:00
parent e562bf6f5b
commit 2d551c09d7
2 changed files with 85 additions and 13 deletions

View File

@@ -1,8 +1,8 @@
--- ---
phase: 08 phase: 08
slug: oauth2-1-authorization-server slug: oauth2-1-authorization-server
status: draft status: complete
nyquist_compliant: true nyquist_compliant: false
wave_0_complete: true wave_0_complete: true
created: 2026-09-23 created: 2026-09-23
updated: 2026-09-24 updated: 2026-09-24
@@ -46,8 +46,8 @@ updated: 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-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-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 | ✅ green (2026-09-24) | | 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 | ✅ green (2026-09-24) |
| 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 | ⬜ pending (08-10 Task 3, not yet executed) | | 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 | ⬜ pending (08-10 Task 3, not yet executed) | | 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* *Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
@@ -55,9 +55,13 @@ updated: 2026-09-24
commands were re-run during the security review and are green; their commands were re-run during the security review and are green; their
`File Exists` columns flip to ✅ now that 08-PHP-TEST-MAP.md, `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-SECURITY-REVIEW.md and this file's own task IDs are finalized.
08-W0-07/08-W0-08 stay `⬜ pending` until 08-10 Task 3 actually executes **08-10 Task 3 update (2026-09-24):** `scripts/check-phase8.sh` ran with no
`scripts/check-phase8.sh` with no flags — that command has not run yet as flags for the first and sole time. 08-W0-07 is green (the real unchanged
of this update. 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.
--- ---
@@ -69,7 +73,7 @@ of this update.
- [x] `../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*oauth*_test.go` — exact raw/JWT endpoint bodies, headers, status codes, consent ownership, and connected-app behavior. - [x] `../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*oauth*_test.go` — exact raw/JWT endpoint bodies, headers, status codes, consent ownership, and connected-app behavior.
- [x] `../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*me*_test.go` — minimal `inv_token`-authenticated MCP bootstrap contract. - [x] `../fonoteka.go/plugins/golem15/fonoteka/controllers/api/*me*_test.go` — minimal `inv_token`-authenticated MCP bootstrap contract.
- [x] `../fonoteka.go/parity/oauth_flow_test.go` and `mcp-lifecycle` fixture — projected existing flows and clean lifecycle/replay coverage. - [x] `../fonoteka.go/parity/oauth_flow_test.go` and `mcp-lifecycle` fixture — projected existing flows and clean lifecycle/replay coverage.
- [x] `scripts/check-phase8.sh` — two-repository vet/test/race, corpus, secret, security-review, and real-MCP gate. Stage bodies complete since 08-09; not yet executed end to end (08-10 Task 3). - [x] `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 except `stage_ui_harness`'s Playwright matrix (carried-forward gap, see deferred-items.md).
- [x] `scripts/check-phase8-ui.mjs` — read-only unchanged-Nuxt state, accessibility, return-path, i18n, and responsive contract gate. - [x] `scripts/check-phase8-ui.mjs` — read-only unchanged-Nuxt state, accessibility, return-path, i18n, and responsive contract gate.
- [x] `scripts/check-phase8-red.sh` — machine-readable `go test -json` verifier requiring exact selected test/package/sentinel and zero unexpected fail actions, plus exact exit-86 stage/sentinel shell protocol. - [x] `scripts/check-phase8-red.sh` — machine-readable `go test -json` verifier requiring exact selected test/package/sentinel and zero unexpected fail actions, plus exact exit-86 stage/sentinel shell protocol.
- [x] `08-SECURITY-REVIEW.md` — map every `T-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). - [x] `08-SECURITY-REVIEW.md` — map every `T-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).
@@ -89,9 +93,21 @@ All phase behaviors are automated. Live Claude, ChatGPT, and Grok connections ar
- [x] Wave 0 covers every currently missing test/gate reference above. - [x] Wave 0 covers every currently missing test/gate reference above.
- [x] No watch-mode flags appear in validation commands. - [x] No watch-mode flags appear in validation commands.
- [x] Task-level feedback is designed for ≤30 seconds; all complete suite/race/parity/UI/real-MCP work appears only in 08-10 Task 3. - [x] Task-level feedback is designed for ≤30 seconds; all complete suite/race/parity/UI/real-MCP work appears only in 08-10 Task 3.
- [x] `nyquist_compliant: true` is set after task IDs are finalized and every mapping is implemented. - [ ] `nyquist_compliant: true` is 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 deliberate
`fatal()`), so this file's own definition of Nyquist compliance is not
fully true. `nyquist_compliant: false` reflects that honestly; the flag
should flip back to `true` only once the follow-up Playwright spec
(deferred-items.md) exists and `--final-gate` runs it for real.
**Approval:** 08-10 Tasks 1-2 complete and green (2026-09-24). Task 3's **Approval:** 08-10 Tasks 1-2 complete and green (2026-09-24). Task 3 ran
`scripts/check-phase8.sh` full-gate execution and the blocking human `scripts/check-phase8.sh`'s full gate exactly once: every stage passed
security checkpoint are still outstanding -- this file's `status:` field except `stage_ui_harness`'s Playwright browser matrix, which is a deliberate,
stays `draft` until that checkpoint is approved. 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.

View File

@@ -66,3 +66,59 @@ gate on two of three full runs, so it was fixed in `summercms.go` commit
`test(fetchguard): widen streaming-cap ceiling to stop flake under parallel `test(fetchguard): widen streaming-cap ceiling to stop flake under parallel
runs`. The ceiling moved from 64 KiB to 1 MiB; the assertion still proves the runs`. The ceiling moved from 64 KiB to 1 MiB; the assertion still proves the
client does not buffer an unbounded body (the handler would reach 8 MiB). client does not buffer an unbounded body (the handler would reach 8 MiB).
## Follow-up: Playwright UI matrix for scripts/check-phase8-ui.mjs --final-gate
**Found during:** 08-10 Task 3, the sole real execution of
`scripts/check-phase8.sh` (2026-09-24).
**What is missing:** `scripts/check-phase8-ui.mjs`'s `--final-gate` mode
(`runFinalGate()`, `scripts/check-phase8-ui.mjs:436-459`) runs
`verify:oauth-return-path` and `verify:oauth-i18n` for real, then reaches a
deliberate `fatal('--final-gate Playwright matrix wiring is 08-10's
responsibility; not implemented in 08-05.')` at line 458. The 32-scenario
`SCENARIOS` catalog (08-UI-SPEC.md's complete state/accessibility/
responsive/i18n matrix) is fully authored and self-tested for completeness
by `--contract-self-test`, but no Playwright spec file consumes it and no
Playwright config exists to run one. Specifically still needed:
- A Playwright config and spec file living outside the `vue-fonoteka-app`
Nuxt checkout (08-UI-SPEC.md's Non-Redesign Rule: this harness must never
write inside the Nuxt checkout or add a registry component there), that
imports/consumes the versioned `SCENARIOS` catalog already in
`check-phase8-ui.mjs` so the spec and the scenario data cannot drift apart.
- `NUXT_DEV_BACKEND_ORIGIN` (or an equivalent env var) wired from the spec's
Playwright config to the ephemeral Go app `scripts/check-phase8.sh` boots
for the gate run, so the real Nuxt dev/preview server the Playwright
browser drives talks to the disposable gate backend instead of a
developer's local backend.
- A real login through the assembled Go backend (not a mocked network
response) for every scenario that is not explicitly declared
network-intercepted in the `SCENARIOS` catalog (see the catalog's own
`no-request` / `redirect-to-login-with-return` scenarios, which assert the
*absence* of a network call and must stay mocked).
- DOM assertions against `app/pages/connect.vue`,
`app/components/fonoteka/ConsentScopePicker.vue`, and
`app/components/fonoteka/ConnectedAppsManager.vue` (the three guarded Nuxt
source files `check-phase8-ui.mjs` hashes at
`scripts/check-phase8-ui.mjs:57-59`), selected via their existing
`data-testid` attributes, matching each scenario's expected state.
**Failing identifier:** `scripts/check-phase8-ui.mjs --final-gate` ->
stage `stage_ui_harness` (`scripts/check-phase8.sh:426-431`) -> fatal message
`--final-gate Playwright matrix wiring is 08-10's responsibility; not
implemented in 08-05.` (`scripts/check-phase8-ui.mjs:458`).
**Disposition:** the user approved closing Phase 8 on 2026-09-24 with this
gap carried forward as a named follow-up ("Approve, carry gap forward" —
08-10 Task 3 checkpoint decision). Every other `scripts/check-phase8.sh`
stage ran green in that same gate execution: docker preflight, Postgres,
app boot, the real unchanged `fonoteka-mcp` lifecycle (discovery, DCR, PKCE
authorize, JWT consent, token, tool call, refresh, replay, revoke), both
repositories' vet/test/race, the 169/169 parity corpus, the secret scan, the
6/6 OAuth return-path checks, the 74-key i18n check, the unchanged-client
diff, and the security review (11/11 threats closed, 0 open). The gate script
must keep failing closed on `stage_ui_harness` until the Playwright spec
above exists -- do not weaken, skip, or stub that stage to close this gap.
Whichever future plan authors the spec should also flip 08-VALIDATION.md's
08-W0-08 row and `nyquist_compliant` back to fully green.