--- phase: "12" slug: "p-ytarium-api-collections-and-albums" # status lifecycle: draft (seeded by plan-phase) → validated (set by validate-phase §6) # audit-milestone §5.5 distinguishes NOT-VALIDATED (draft) from PARTIAL (validated + nyquist_compliant: false) (#2117) status: draft nyquist_compliant: false wave_0_complete: false created: "2026-10-02" --- # Phase 12 — Validation Strategy > Per-phase validation contract for feedback sampling during execution. --- ## Test Infrastructure | Property | Value | |----------|-------| | **Framework** | Go `testing` (+ testify assert/require, Go fuzzing), testcontainers Postgres | | **Config file** | none (`parity/parity_test.go` TestMain starts Postgres) | | **Quick run command** | `cd fonoteka.go && go test ./plugins/golem15/fonoteka/... -short -count=1` | | **Full suite command** | `cd fonoteka.go && go vet ./... && go test ./... -count=1`, plus `cd summercms.go && go vet ./... && go test ./... -count=1` for framework changes | | **Parity command** | `cd fonoteka.go && go test ./parity -run 'TestParityCorpus|TestBroadcastGoldens|TestNuxtFlow' -count=1` | | **Estimated runtime** | ~180 seconds (full suite, both repos, with containers) | --- ## Sampling Rate - **After every task commit:** quick run command plus `go vet` in the touched repo - **After every plan wave:** full suite in both repos plus the parity command - **Before `/gsd-verify-work`:** full suite green in both repos; parity corpus with the new routes flipped to `ported` and passing; `check_corpus.go --require-recorded --check-secrets` green; `go test ./cmd/summer -run TestDocsTree` green - **Max feedback latency:** 60 seconds (quick run) --- ## Per-Task Verification Map Seeded from RESEARCH.md by requirement; task IDs are filled in once PLAN.md files exist. | Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status | |---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------| | TBD | 01 | 1 | framework | — | beachcomber `found`/weights, tide multipart + URL mask, Laravel-semantics validator + catalogs, attach URL export | unit | `cd summercms.go && go test ./modules/... -count=1` | ❌ W0 | ⬜ pending | | TBD | 02 | 2 | API-01 | T-12-01, T-12-03, T-12-04, T-12-05 | Collections, switch, me/context, realtime/channels, share replays; token pin and narrowing | parity + integration | `go test ./parity -run TestParityCorpus/.*collection` | ❌ W0 | ⬜ pending | | TBD | 03 | 3 | API-01 | T-12-06, T-12-07 | Invite mail enqueued in tx, absent on rollback; token encrypted in job args, never logged | integration + parity flow | `go test ./parity -run TestNuxtFlow/nuxt-collections` | ❌ W0 | ⬜ pending | | TBD | 04 | 4 | API-02 | T-12-02, T-12-09, T-12-10, T-12-11 | Album CRUD, rating, photos, bulk, stats/value/missing/sync, search, lookups; upload guard; SSRF guard | parity + integration | `go test ./parity -run 'TestParityCorpus/.*albums|TestBroadcastGoldens'` | ❌ W0 | ⬜ pending | | TBD | 05 | 5 | API-01, API-02 | T-12-01..T-12-11 | D-18 leak test (5 cases + total), request-DTO fuzz, route-table single-scope test | security + fuzz + unit | `go test ./plugins/golem15/fonoteka/... -run 'TestSearchLeak|TestRouteTable|FuzzWriteEndpoints' -count=1` | ❌ W0 | ⬜ pending | *Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky* --- ## Wave 0 Requirements - [ ] Re-record the HttpException cases under `APP_DEBUG=false` (accept 410, switch 404, household/members 404, invitations 404, token 404) — D-21 - [ ] tide request `body_file` (multipart) + `url`/`thumb_url` disk-name normalizer + publication date masking (framework) - [ ] Seed hooks or flows for a second user and an outsider (reuse `id:outsider` from Phase 11) - [ ] Fake `beachcomber` engine with scripted ids and `found` for D-18/D-19 --- ## Manual-Only Verifications | Behavior | Requirement | Why Manual | Test Instructions | |----------|-------------|------------|-------------------| | Recording new PHP fixtures against the isolated PHP instance | API-01, API-02 | Needs the running PHP reference instance and capture tooling | Follow the Phase 2 `tide` capture rules (private 0600 vars, no live tokens in git), then run `check_corpus.go --require-recorded --check-secrets` | --- ## Validation Sign-Off - [ ] All tasks have `` verify or Wave 0 dependencies - [ ] Sampling continuity: no 3 consecutive tasks without automated verify - [ ] Wave 0 covers all MISSING references - [ ] No watch-mode flags - [ ] Feedback latency < 60s - [ ] `nyquist_compliant: true` set in frontmatter **Approval:** pending