9.2 KiB
9.2 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 08-oauth2-1-authorization-server | 01 | execute | 1 |
|
true |
|
|
Purpose: Obtain end-to-end feedback in the first wave while keeping the protocol writer app-agnostic and making every later RED phase diagnostic.
Output: wristband metadata contract, mounted raw route, assembled exact-byte tests, and the shared RED verifier.
Phase Goal
As a connector implementer, I want to discover the assembled Go authorization server, so that I can obtain its exact OAuth endpoints and capabilities before registering.
<execution_context> @/home/jin/.codex/get-shit-done/workflows/execute-plan.md @/home/jin/.codex/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/08-oauth2-1-authorization-server/08-CONTEXT.md @.planning/phases/08-oauth2-1-authorization-server/08-RESEARCH.md @.planning/phases/08-oauth2-1-authorization-server/08-PATTERNS.md @.planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md Task 1: Create fail-closed RED verification and metadata contracts wristband/server.go, wristband/server_test.go, scripts/check-phase8-red.sh .planning/phases/08-oauth2-1-authorization-server/08-CONTEXT.md .planning/phases/08-oauth2-1-authorization-server/08-PATTERNS.md /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/api/OAuthMetadataController.php /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthMetadataTest.php wire/response.go scripts/check-phase3.sh - Metadata is the exact unwrapped 11-field document with recorded order, `application/json`, no trailing newline, and the PHP cache header. - The selected RED test fails with `PHASE8_RED:metadata` only because metadata behavior is absent. - Any other failed test/package/action, compilation/setup failure, panic, malformed JSON event stream, or zero selected tests makes the verifier fail. D-06 and D-18: define only the exported metadata options/server handler needed by this slice, with compiling stubs and an exact `TestPhase8RedMetadata` assertion. Implement `scripts/check-phase8-red.sh` with two explicit modes. In `go` mode accept `sentinel`, exact package import path, exact test name, `--`, and a required `go test -json` command; parse every JSON event, require the selected test to emit the exact sentinel and fail, require its package to fail, require at least one selected test run, and reject every other `Action:"fail"` test/package, non-JSON output, compile/build/setup/syntax failure, panic, timeout, and no-test/zero-selection result. Package-level fail is allowed only for the named package after the named test failure. In `shell` mode accept `sentinel`, exact stage, and a command; require exit 86 and exactly one line `PHASE8_STAGE:<stage>:FAIL:<sentinel>`, reject every other FAIL/ERROR/PANIC stage and missing/extra sentinel. D-01: use only the standard library. Commit RED separately. scripts/check-phase8-red.sh go PHASE8_RED:metadata git.golem15.com/golem15/summercms/wristband TestPhase8RedMetadata -- go test -json ./wristband -run '^TestPhase8RedMetadata$' -count=1 - The verifier accepts one JSON stream containing only `TestPhase8RedMetadata` plus its package failure and exact sentinel. - Fixture self-tests reject an unrelated failing test, another failing package/action, compile/setup failure, panic, malformed/non-JSON output, missing sentinel, duplicate sentinel, and zero selected tests. - Metadata RED asserts the exact 11-field byte order, `Content-Type: application/json`, cache header, status 200, and no trailing newline. The metadata RED test compiles and the shared verifier is fail-closed against every unrelated or non-behavior failure class. Task 2: Implement and mount exact metadata on the assembled app wristband/server.go, wristband/server_test.go, ../fonoteka.go/plugins/golem15/fonoteka/plugin.go, ../fonoteka.go/plugins/golem15/fonoteka/routes.go, ../fonoteka.go/plugins/golem15/fonoteka/oauth_metadata_test.go wristband/server_test.go surf/router.go ../fonoteka.go/plugins/golem15/fonoteka/plugin.go ../fonoteka.go/plugins/golem15/fonoteka/routes.go /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/routes.php /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/api/OAuthMetadataController.php ../fonoteka.go/parity/fixtures/mcp/mcp-oauth.yaml - Direct handler and assembled route return the same exact metadata bytes and headers. - The route has no house/JWT/personal-token middleware and no `oauth` guard registration. - Issuer is `app.url` with one trailing slash trim; endpoint/resource/service-documentation/scope/auth-method values match PHP defaults. D-01, D-03, D-05, and D-06: implement the local no-newline exact JSON metadata writer and configurable values without response hooks or app imports. Construct the metadata-capable server during app boot from `app.url` and locked PHP defaults, retain it on Plugin, and mount only `GET /.well-known/oauth-authorization-server` in the existing raw group. D-09/D-10/D-12: attach no middleware, register no oauth guard, and do not add protected-resource metadata or Bearer challenges. Add an assembled test that boots the real plugin/router and compares status, headers, and exact bytes to the PHP contract. go test ./wristband -run '^TestMetadata' -count=1 && (cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestOAuthMetadataAssembled$' -count=1) - Direct and assembled GET return status 200, exact PHP metadata bytes in field order, `Content-Type: application/json`, the expected cache header, and no envelope/newline. - Route inspection shows only the raw GET path and rejects `jwt.auth`, `inv_token`, `inv.scope`, body-limit, house tags, and an `oauth` guard. - Changing `app.url` changes issuer/endpoints after exactly one trailing-slash trim; framework import checks find no fonoteka or GORM reference. A connector can fetch the exact metadata contract from the assembled production router in Wave 1.<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| Connector → assembled raw route | Untrusted discovery traffic reaches the exact wristband writer. |
STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|---|---|---|---|---|
| T-08-SURFACE | Elevation | raw metadata route | mitigate | Assembled route inspection proves no guard/house middleware. |
| T-08-REQUEST-LEAK | Information Disclosure | metadata/config | mitigate | Only public configured metadata fields are serialized. |
| T-08-SC | Tampering | dependencies | mitigate | No package install; stdlib-only import audit. |
| </threat_model> |
<success_criteria>
- Exact metadata is connector-visible through the assembled app.
- RED verification cannot pass on compile/setup/panic/no-test errors or any unrelated test/package/stage failure. </success_criteria>