11 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 | |||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 08-oauth2-1-authorization-server | 01 | auth |
|
|
|
|
|
|
|
|
|
25min | 2026-09-23 |
Phase 08 Plan 01: Fail-Closed RED Infrastructure and Assembled RFC 8414 Metadata Summary
New wristband framework package serves the exact 11-field unwrapped RFC 8414 document from the assembled Go app's raw route group, backed by a stdlib-only fail-closed go test -json RED verifier every later Phase 8 plan will reuse.
Performance
- Duration: ~25 min
- Started: 2026-09-23T17:05:00Z (approx.)
- Completed: 2026-09-23T17:14:26Z
- Tasks: 2 completed (4 commits: RED/GREEN pairs across both repos)
- Files modified: 6 (3 created in summercms.go, 1 created + 2 modified in fonoteka.go)
Accomplishments
wristbandpackage created: app-agnosticOptions/Server/DefaultOptionsplus an exact-byte RFC 8414 metadata writer that never importsfonotekaorgorm.io(verified viago list -deps)GET /.well-known/oauth-authorization-serveris now connector-visible on the real assembled Go app: exact PHP-parity bytes,Content-Type: application/json,Cache-Control: no-cache, private, no envelope, no trailing newline- Route-table inspection proves the metadata route is
Raw, carries zero middleware, and no"oauth"guard is registered anywhere — closing the Phase 6 D-09 reservation per D-10 scripts/check-phase8-red.shimplements the sharedgo/shellfail-closed RED contract (D-04/D-18) that every remaining Phase 8 plan's verify step depends on; manually fuzz-tested against 8 rejection classes (unrelated failing test, compile failure, panic, malformed output, missing sentinel, duplicate sentinel, zero selection, plus both shell-mode wrong-exit and extra-stage-line cases) and the one acceptance case
Task Commits
Each task was committed atomically (TDD RED then GREEN, split per repo where both repos changed):
- Task 1: fail-closed RED verification and metadata contracts —
24d35d8(test, summercms.go): stubServer.Metadata(501), failingTestPhase8RedMetadata, andscripts/check-phase8-red.sh - Task 2a: implement exact metadata writer (GREEN for wristband) —
c578bb5(feat, summercms.go): realMetadatahandler,TestMetadataExactBytes,TestMetadataUsesConfiguredOptions - Task 2b: assembled metadata route test (RED for fonoteka.go) —
58bb628(test, fonoteka.go):TestOAuthMetadataAssembled/RouteIsolation/IssuerTracksAppURL, all failing 404 since the route was unmounted - Task 2c: mount the metadata route (GREEN for fonoteka.go) —
26b2478(feat, fonoteka.go):Plugin.Bootconstructs the server fromapp.url;routes.gomounts the raw GET route
Plan metadata: committed as part of this summary/state-update commit.
Note: both tasks carry tdd="true"; RED/GREEN pairs land as separate commits, and Task 2 splits its RED/GREEN across the two repositories it touches.
Files Created/Modified
wristband/server.go—Options,DefaultOptions,Server,NewServer,Metadatahandler, local exact-JSON writerwristband/server_test.go—TestPhase8RedMetadata(RED anchor),TestMetadataExactBytes,TestMetadataUsesConfiguredOptionsscripts/check-phase8-red.sh— sharedgo/shellfail-closed RED verifier for the rest of Phase 8../fonoteka.go/plugins/golem15/fonoteka/oauth_metadata_test.go— assembled route tests (metadata bytes, route isolation, issuer tracking)../fonoteka.go/plugins/golem15/fonoteka/plugin.go— constructswristband.ServerinBootfromapp.url../fonoteka.go/plugins/golem15/fonoteka/routes.go— mounts the metadata route on the existing raw group
Decisions Made
wristband.Optionsexposes only the four PHP-configurable metadata fields (D-06);response_types_supported,grant_types_supported, andcode_challenge_methods_supportedare hardcoded protocol constants insideMetadata, not Options, since this authorization server only ever supports one fixed set of grants/PKCE method (D-01)Plugin.Bootalways constructs the OAuth server, even with an emptyapp.url(issuer becomes""), rather than failing Boot loudly. A strict fail-loud check was considered (matching the project's general "fail loud, no default" convention) but rejected here because it would break every existing test in the package that boots viabootConfig/testConfigwithoutapp.urlset — dozens of unrelated tests acrossplugins/golem15/fonotekaandparity. This is scoped narrowly to this plan; a later plan may tighten validation once the fullplugins.golem15.fonoteka.oauth.*config surface (D-03) is wired.- D-10 (retiring the Phase 6
"oauth"guard reservation) is recorded here rather than by editing Phase 6 historical docs, per08-PATTERNS.md's explicit guidance to prefer a supersession note in the Phase 8 plan/summary.TestOAuthMetadataRouteIsolationis the failing-when-broken proof: it assertsreg.Middleware("oauth")returns an error. requirements.mark-complete AUTH-05 AUTH-06was run per the state-update protocol, then manually reverted inREQUIREMENTS.md(checkbox and traceability table back to Pending). AUTH-05's own text spans authorize/PKCE/consent/token/DCR/refresh, none of which exist yet — only the metadata slice does. Unlike the HTTP-04/AUTH-01 precedent from Phases 6/7 (where the first touching plan already implemented the full requirement), marking AUTH-05/AUTH-06 Complete after Task 2's metadata-only slice would misrepresent phase progress; a later Phase 8 plan (the one that ships authorize/token/DCR/refresh, or 08-10's closing review) should be the one to flip these.
Deviations from Plan
None — plan executed exactly as written. The RED verifier's fixture self-tests (compile failure, panic, malformed output, missing/duplicate sentinel, zero selection, unrelated failure, shell-mode wrong-exit/extra-stage-line) were exercised manually against throwaway fixtures in /tmp during Task 1 to prove the fail-closed contract described in the plan's acceptance criteria; per the plan's file list (wristband/server.go, wristband/server_test.go, scripts/check-phase8-red.sh only), these fixture self-tests are not committed as a permanent Go test suite here — 08-VALIDATION.md row 08-W0-07 assigns the RED gate's own self-validation to plan 08-09.
Issues Encountered
None.
User Setup Required
None — no external service configuration required.
Next Phase Readiness
wristbandexists as the framework home for the rest of Phase 8's OAuth surface (authorize, token, register, refresh rotation, sweeps) with an established Options/writer convention to extend.scripts/check-phase8-red.shis ready for immediate reuse by plans 08-02 through 08-09, all of which reference it directly in their verify steps.- The corrective OAuth schema/model nullability work flagged in
08-RESEARCH.md("Required Schema Correction") is still outstanding and is Wave 0 for plan 08-02, not touched here. - No blockers.
Self-Check: PASSED
- FOUND: wristband/server.go, wristband/server_test.go, scripts/check-phase8-red.sh, .planning/phases/08-oauth2-1-authorization-server/08-01-SUMMARY.md
- FOUND: ../fonoteka.go/plugins/golem15/fonoteka/oauth_metadata_test.go, plugin.go, routes.go
- FOUND commits:
24d35d8,c578bb5(summercms.go); 58bb628, 26b2478 (fonoteka.go)