8.7 KiB
8.7 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created
| phase | slug | status | nyquist_compliant | wave_0_complete | created |
|---|---|---|---|---|---|
| 6 | http-routing-auth-groups-and-rate-limiting | planned | true | false | 2026-09-19 |
Phase 6 — Validation Strategy
Per-phase validation contract for feedback sampling during execution.
Test Infrastructure
| Property | Value |
|---|---|
| Framework | Go stdlib testing + testify (assert/require); net/http/httptest for router, limiter, CORS and fetch-helper tests; testcontainers-go Postgres only where the inv_token guard and parity harness need real rows |
| Config file | none — plain func TestX(t *testing.T); parity TestMain in ../fonoteka.go/parity is reused |
| Quick run command | go vet ./... && go test ./... -short (run in the repo the task writes to) |
| Full suite command | go test ./... -race in summercms.go and in ../fonoteka.go |
| Estimated runtime | ~20 s quick, ~120-180 s full |
Sampling Rate
- After every task commit: Run
go vet ./... && go test ./... -short - After every plan wave: Run
go test ./...in both repos - Before
/gsd:verify-work: Full suite green in both repos with-race, parity harness green on genres under both auth groups, swag +openapi-typescriptgate green - Max feedback latency: 120 seconds
Per-Task Verification Map
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| 06-01-T1 | 06-01 | 1 | HTTP-05 | T-06-01 | Router verbs + parameterized middleware factories; guard registry primitives unit-tested in isolation | unit | go test ./surf/... ./bouncer/... ./pact/... -short (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-01-T2 | 06-01 | 1 | HTTP-05 | T-06-04, T-06-05 | Real inv_token guard + inv.scope exact 401/403 bodies; jwt guard behaviorally unchanged | unit + testcontainers | go test ./plugins/golem15/fonoteka/... ./plugins/golem15/user/... -short (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-01-T3 | 06-01 | 1 | HTTP-03 | T-06-02 | Same handler serves JWT and personal-token genres; parity-green on both | integration + parity | go test ./plugins/golem15/fonoteka/... -run TestGenresSharedHandler -short && go test ./parity/... -run TestParityCorpus (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-02-T1 | 06-02 | 2 | HTTP-04 | T-06-06 | Fixed-window Store/FixedWindowLimiter (distinct from the pre-existing surf.Limiter interface seam) matching Laravel wire contract; trusted-proxy ClientIP | unit | go test ./surf/... -run 'TestFixedWindowLimiter|TestClientIP' -short (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-02-T2 | 06-02 | 2 | HTTP-04 | T-06-07 | Five named buckets registered; token group throttled; PublicShareHeaders 429 rewrite | unit + integration | go test ./plugins/golem15/fonoteka/... -run TestPublicShareHeaders -short (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-02-T3 | 06-02 | 2 | HTTP-04 | T-06-09 | All six declared route groups boot cleanly; APP_DEBUG=false pinned for future fixture recordings | integration | go test ./plugins/golem15/fonoteka/... -run TestAllRouteGroupsBoot -short (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-03-T1 | 06-03 | 3 | HTTP-06 | T-06-10, T-06-11 | Raw group refuses house-envelope middleware (declared only via the pact.HasHouseMiddleware plugin capability) at registration; bare 500 on raw panic; route table + route:list | unit | go test ./surf/... -run 'TestRawGroup|TestRouteTable|TestHouseMiddleware' -short (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-03-T2 | 06-03 | 3 | HTTP-06, HTTP-08 | — | wire response helpers (JSON writer, +00:00 time, tri-state bool, never-nil slice); swag→openapi-typescript pipeline | unit + build-gate | go test ./wire/... -short && bash scripts/check-openapi.sh (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-03-T3 | 06-03 | 3 | HTTP-09 | T-06-12, T-06-13 | Path-scoped CORS matches config/cors.php; body limits enforced with operator-confirmed production numbers; oauth group raw | integration + human-verify | go test ./surf/... -run 'TestCORS|TestBodyLimit' -short (summercms.go); blocking checkpoint for production body-size numbers |
✅ created by plan | ⬜ pending |
| 06-04-T1 | 06-04 | 1 | HTTP-07 | T-06-14 | Private/reserved/CGNAT/metadata IP table matches ManualCoverUrlFetcher.php exactly | unit | go test ./fetchguard/... -run TestIsReservedOrPrivate -v (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-04-T2 | 06-04 | 1 | HTTP-07 | T-06-14, T-06-15, T-06-16, T-06-17, T-06-18 | Dial-time SSRF guard, https-only, no redirects, streaming byte cap, typed failure reasons | unit (httptest) | go test ./fetchguard/... -short -race (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-05-T1 | 06-05 | 4 | HTTP-03..09 | all (coverage sweep) | Framework-side coverage gaps closed (bouncer/surf/wire/fetchguard) | unit | go test ./... -race -short (summercms.go) |
✅ created by plan | ⬜ pending |
| 06-05-T2 | 06-05 | 4 | HTTP-03..09 | T-06-02, T-06-10 (full completion) | App-side coverage gaps; full route-table mutual-exclusivity over every route, not just genres | unit + parity | go test ./... -race -short && go test ./parity/... -run TestParityCorpus (fonoteka.go) |
✅ created by plan | ⬜ pending |
| 06-05-T3 | 06-05 | 4 | HTTP-03..09 | T-06-19, T-06-20 | Every T-06-xx threat mapped to a passing test or restated acceptance | doc + grep-gate | grep -c "^| T-06-" 06-SECURITY-REVIEW.md |
✅ created by plan | ⬜ pending |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
surf/limiter_test.go— fixed-window Store semantics, named-bucket resolution, inline throttle keys, stacking — scaffolded and filled by Plan 06-02 Task 1 (no pre-existing file; the plan creates it, satisfying the Nyquist "create the scaffold" rule since there is no separate Wave 0 in this phase's plan set)bouncer/registry_test.go— guard register / duplicate-fail / resolve-by-name — scaffolded and filled by Plan 06-01 Task 1- Fetch-helper package
fetch_test.go/ip_test.go— httptest servers for each typed failure reason — scaffolded and filled by Plan 06-04 Tasks 1-2 surf/routetable_test.go— raw-group middleware refusal at registration, route table contents — scaffolded and filled by Plan 06-03 Task 1- Existing infra reused:
surfrouter tests,../fonoteka.go/parityTestMain andseedHooks(token insertion for theinv_tokenguard, extended by Plan 06-01 Task 3) - No new test framework
No standalone Wave 0 plan is used in this phase's plan set — each implementation plan (06-01 through 06-04) creates and fills its own test files in the same wave as the production code, and every task in every plan carries a concrete <automated> verify command (confirmed via verify.plan-structure on all 5 plans: hasVerify: true on every task). Plan 06-05 (wave 4) is the dedicated coverage-closing plan required by this project's lean-mode "unit tests are always the last plan" rule.
Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|---|---|---|---|
Production client_max_body_size / post_max_size / upload_max_filesize values |
HTTP-09 | The production nginx vhost and php.ini are operator-managed and not in any repo (06-RESEARCH.md A2) | Plan 06-03 Task 3 is a checkpoint:human-verify (autonomous: false): operator reads the values from the production host; they are recorded in fonoteka.go/config/http.yaml replacing the INTERIM defaults, and the existing body-limit tests (which assert against config-loaded values) are re-run to confirm no regression |
Validation Sign-Off
- All tasks have
<automated>verify or Wave 0 dependencies — confirmed viagsd-sdk query verify.plan-structureon all 5 PLAN.md files (hasVerify: trueon every task, including the onecheckpoint:human-verifytask, which also carries an<automated>block for its automatable portion) - Sampling continuity: no 3 consecutive tasks without automated verify — every task across all 5 plans has one
- Wave 0 covers all MISSING references — no file listed as
❌ W0in the original requirement→test map remains missing; every referenced test file is created by an explicit plan task - No watch-mode flags — all commands are one-shot
go test/go vet/bashinvocations - Feedback latency < 120s — quick-run commands are package-scoped
-shortruns nyquist_compliant: trueset in frontmatter
Approval: planned — ready for /gsd:execute-phase 06