docs(06-10): complete exact InvScope denial bodies plan

This commit is contained in:
Jakub Zych
2026-09-21 00:26:51 +02:00
parent c9909ce412
commit 943be2353d

View File

@@ -0,0 +1,126 @@
---
phase: 06-http-routing-auth-groups-and-rate-limiting
plan: 10
subsystem: auth
tags: [inv-scope, wire-json, php-parity, regression-tests]
requires:
- phase: 06-http-routing-auth-groups-and-rate-limiting
provides: bouncer user/credential context, InvScope middleware, and shared wire.WriteJSON response conventions
provides:
- Byte-exact no-newline InvScope 401 and 403 denial responses
- Raw-byte regression assertions for missing-user, missing-scope, and wrong-credential denial paths
affects: [phase-06-verification, personal-token-routes, php-parity]
tech-stack:
added: []
patterns:
- Security denial middleware delegates JSON serialization to the shared PHP-compatible wire writer
- Wire-contract tests compare recorder bytes before decoding response shape
key-files:
created: []
modified:
- fonoteka.go/plugins/golem15/fonoteka/middleware/token_scope.go
- fonoteka.go/plugins/golem15/fonoteka/middleware/token_scope_test.go
key-decisions:
- "Use wire.WriteJSON for both InvScope denial branches so authentication and scope errors share the established PHP-compatible no-newline serialization path"
- "Assert exact response bytes before secondary JSON shape checks; denial tests must never normalize whitespace"
patterns-established:
- "TokenScope parity: status, Content-Type, and raw body bytes are one indivisible HTTP contract"
requirements-completed: [HTTP-05, HTTP-06]
duration: 3h 15m
completed: 2026-09-20
---
# Phase 6 Plan 10: Exact InvScope Denial Bodies Summary
**Personal-token scope denials now use `wire.WriteJSON`, producing PHP-byte-identical 401/403 bodies with raw-byte tests that fail on any newline or carriage return**
## Performance
- **Duration:** 3h 15m elapsed (including sandbox approval wait)
- **Started:** 2026-09-20T19:10:39Z
- **Completed:** 2026-09-20T22:26:07Z
- **Tasks:** 1 TDD task
- **Files modified:** 2
## Accomplishments
- Replaced InvScope's local `json.Encoder` response helper with the framework's PHP-compatible `wire.WriteJSON` for both denial branches.
- Added exact raw-body assertions for the 401 missing-user and 403 missing-scope cases, including explicit final-`}` and no-CR/LF checks.
- Kept JSON decoding as a secondary envelope check and preserved the valid-scope next-handler and wrong-credential fail-closed behavior.
## Task Commits
Each TDD stage was committed atomically in the `fonoteka.go` repository:
1. **RED: Assert exact InvScope denial bytes** - `bf3f8a0` (test)
2. **GREEN: Emit exact InvScope denial bodies** - `d43cc76` (fix)
**Plan metadata:** (this commit)
_No refactor commit was needed; the production change is the minimal shared-writer delegation._
## Files Created/Modified
- `fonoteka.go/plugins/golem15/fonoteka/middleware/token_scope.go` - delegates 401/403 serialization to `wire.WriteJSON` and removes the local encoder helper.
- `fonoteka.go/plugins/golem15/fonoteka/middleware/token_scope_test.go` - compares exact recorder bodies, asserts JSON content type, forbids CR/LF bytes, and retains decoded shape checks.
## Decisions Made
- Both denial branches use the existing framework writer rather than duplicating newline trimming in app middleware.
- Exact bytes are asserted before JSON decoding so semantically valid but wire-incompatible whitespace cannot pass.
## Deviations from Plan
None - plan executed exactly as written.
## Issues Encountered
- The first sandboxed Go verification could not write to the shared Go build cache; rerunning the same bounded command with approved cache access passed. This was an execution-environment constraint, not a code defect.
## User Setup Required
None - no external service configuration required.
## TDD Gate Compliance
- RED: `bf3f8a0` demonstrated all three denial bodies carried the unwanted trailing newline.
- GREEN: `d43cc76` switched both branches to `wire.WriteJSON`; the exact tests passed under `-race`.
- REFACTOR: omitted because the minimal implementation already removed the redundant helper.
## Verification
- `go test ./plugins/golem15/fonoteka/middleware -run 'TestInvScope' -count=1 -race -short` - pass
- `go vet ./plugins/golem15/fonoteka/middleware` - pass
- `go test ./plugins/golem15/fonoteka/... -count=1 -short` - pass
- Acceptance greps - two `wire.WriteJSON` calls present; no `json.NewEncoder`, local `writeJSON`, `TrimSpace`, or normalized denial-body comparison.
## Known Stubs
None.
## Threat Flags
None. The change narrows an existing authentication response serialization path and introduces no new endpoint, trust boundary, file access, or schema surface.
## Next Phase Readiness
- The fourth authoritative Phase 6 verification gap is closed; Plan 06-11 can perform final coverage and phase closeout.
- No blockers.
## Self-Check: PASSED
- FOUND: both modified middleware files.
- FOUND: `bf3f8a0` and `d43cc76` in the `fonoteka.go` history.
- PASS: exact InvScope tests, middleware vet, and full Fonoteka plugin suite.
- PASS: no generated or untracked files in `fonoteka.go`; the pre-existing main-repo `go.work.sum` remains untouched.
---
*Phase: 06-http-routing-auth-groups-and-rate-limiting*
*Completed: 2026-09-20*