docs(14-06): Phase 14 validation signed off, requirements complete, API coverage confirmed, folded todos closed
- 14-VALIDATION.md: per-task map 14-01-T1 to 14-06-T4, all green, the measured coverage, validated, Nyquist-compliant, Wave 0 complete, the final --all and --removal results - REQUIREMENTS.md: INTG-02 and API-08 Complete (JOBS-02, JOBS-03, SRCH-02, INTG-01, CLI-05 already were) - COVERAGE.md: every INTEGRATE row's test confirmed by --named - fetchguard-guarded-http-client and redacting-slog-handler moved to done
This commit is contained in:
@@ -2,10 +2,13 @@
|
||||
phase: "14"
|
||||
slug: "domain-jobs-and-external-integrations"
|
||||
# status lifecycle: draft (seeded by plan-phase) → validated (set by validate-phase §6)
|
||||
status: draft
|
||||
nyquist_compliant: false
|
||||
wave_0_complete: false
|
||||
# audit-milestone §5.5 distinguishes NOT-VALIDATED (draft) from PARTIAL (validated + nyquist_compliant: false) (#2117)
|
||||
status: validated
|
||||
nyquist_compliant: true
|
||||
wave_0_complete: true
|
||||
created: "2026-10-03"
|
||||
validated: "2026-10-04"
|
||||
gate: "scripts/check-phase14.sh --all"
|
||||
---
|
||||
|
||||
# Phase 14 — Validation Strategy
|
||||
@@ -19,10 +22,10 @@ created: "2026-10-03"
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | go test (+ testify), testcontainers-go postgres, tide parity replay |
|
||||
| **Config file** | none (Go); gate script `scripts/check-phase14.sh` (Wave 0, modelled on `check-phase13.sh`) |
|
||||
| **Config file** | none (Go); gate script `scripts/check-phase14.sh` (`--self-test --go --parity --named --removal --coverage --evidence --all`, modelled on `check-phase13.sh`) |
|
||||
| **Quick run command** | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/... -count=1 -short` |
|
||||
| **Full suite command** | `go test ./... -count=1 && go -C ../fonoteka.go test ./... -count=1 -race && bash scripts/check-phase14.sh --all` |
|
||||
| **Estimated runtime** | ~180 seconds |
|
||||
| **Full suite command** | `bash scripts/check-phase14.sh --all` (vet and tests in both repos with `-race` in fonoteka.go, the corpus, every named test, the coverage floors and this file), then `bash scripts/check-phase14.sh --removal` on its own |
|
||||
| **Estimated runtime** | about 15 minutes for `--all`, about 25 minutes for `--removal` |
|
||||
|
||||
---
|
||||
|
||||
@@ -30,39 +33,68 @@ created: "2026-10-03"
|
||||
|
||||
- **After every task commit:** the task's named `-run` tests plus `go vet` in the touched repo
|
||||
- **After every plan wave:** `go test ./...` in both repos plus `TestParityCorpus` / `TestFonotekaNuxtFlows`
|
||||
- **Before `/gsd-verify-work`:** `scripts/check-phase14.sh --all` must be green
|
||||
- **Max feedback latency:** 180 seconds
|
||||
- **Before `/gsd-verify-work`:** `scripts/check-phase14.sh --all` must be green: vet and tests in summercms.go and, with `-race`, in fonoteka.go including sm-user-plugin, sm-golem-plugin and sm-feedback-plugin; no vendor AI SDK in either module graph; the parity corpus (175 recorded, 172 ported and passing, the 3 D-09 routes not ported, read from the replay's own coverage line and the manifest), every TestFonotekaNuxtFlows subtest, the broadcast goldens, TestUpstreamSidecarsAreReplayed, TestFeedbackJobSidecarMatchesPlugin, `check_corpus --require-recorded --check-secrets`, the fuzz corpus scan, TestDocsTree and `docs:build --check`; every named test by exact name; the coverage floors; and this file, the security review, COVERAGE.md, REQUIREMENTS.md and the ROADMAP Phase 14 section
|
||||
- **Max feedback latency:** 180 seconds per task's named tests
|
||||
|
||||
---
|
||||
|
||||
## Per-Task Verification Map
|
||||
|
||||
| Req ID | Behavior | Test Type | Automated Command | File Exists | Status |
|
||||
|--------|----------|-----------|-------------------|-------------|--------|
|
||||
| JOBS-02 | CSV match job: 0/1/many, gate off, cancel, superseded, 429 re-dispatch delay, 240 s timeout value | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestCsvMatchJob' -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| JOBS-02 | CSV import job: overwrite/fill/create, write_failed row, canceled, bulk_updated publish once | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestCsvImportJob' -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| JOBS-02 | WR-02: racing commit vs mapping/row-edit/cancel queues at most one import job | Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestCsvWR02' -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| JOBS-03 | Digest: 30-min coalescing, sent count, queue row deleted, en/pl template | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestWishlistDigestJob' -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| SRCH-02 | reindex: zero collection_id-0 before/after, drop legacy index | unit (fake engine) | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestReindexCommand' -count=1` | ❌ W0 | ⬜ pending |
|
||||
| CLI-05 | prune-notifications + schedule entry; reindex; oauth-client | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestPruneNotifications|TestSchedule)' -count=1` | partial | ⬜ pending |
|
||||
| INTG-01 | Discogs limiter threshold, wait budget, retry-after, fake clock | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes/discogs -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| INTG-01 | Discogs routes parity with upstream sidecars | parity | `go -C ../fonoteka.go test ./parity -run '^(TestParityCorpus|TestCheckCorpusPortedCaseStatus)$' -count=1` | partial | ⬜ pending |
|
||||
| INTG-02 | Adapters build PHP payloads; SSRF guard; admin trusted bypass | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/golem/... -count=1` | ❌ W0 | ⬜ pending |
|
||||
| INTG-02 | Recognition retry, truncation, admin vision tier | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^TestRecognize' -count=1` | ❌ W0 | ⬜ pending |
|
||||
| API-08 | Feedback config/submit/options/me-hidden, origin gate, G15Office job via fake | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/feedback/... -count=1 -race` | ❌ W0 | ⬜ pending |
|
||||
| framework | fetchguard client modes; redact handler; tide sidecar replay | unit | `go test ./modules/fetchguard/... ./modules/tide/... -count=1` | ❌ W0 | ⬜ pending |
|
||||
Every row's tests are run by name by `scripts/check-phase14.sh --named` (the evidence stage refuses a row naming a test it does not run); the parity rows also by `--parity`. All rows were green in the 2026-10-04 run of `--all`.
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
| Task ID | Plan | Wave | Requirement | Threat Ref | Behavior | Test Type | Automated Command | File Exists | Status |
|
||||
|---------|------|------|-------------|------------|----------|-----------|-------------------|-------------|--------|
|
||||
| 14-01-T1 | 14-01 | 1 | INTG-02 (framework) | T-14-01, T-14-02 | A guarded JSON POST through fetchguard.Client is answered offline by the asserting tide upstream fake; the transport seam is code-only | unit | `go test ./modules/fetchguard -run '^(TestClientPostJSONThroughUpstreamFake\|TestTransportSeamIsCodeOnly\|TestClientNeverFollowsRedirects)$' -count=1 -v` | ✅ `modules/fetchguard/client_test.go`, `client_internal_test.go` | ✅ green |
|
||||
| 14-01-T2 | 14-01 | 1 | INTG-02 (framework) | T-14-01, T-14-06 | PUT, multipart, bearer and trusted mode; https and host checks before I/O; the body cap | unit | `go test ./modules/fetchguard -run '^(TestClientModes\|TestClientSchemeGuard\|TestClientMultipart\|TestClientBodyCap\|TestClientPutJSONHeaderOrder)$' -count=1 -v` | ✅ `modules/fetchguard/client_test.go` | ✅ green |
|
||||
| 14-01-T3 | 14-01 | 1 | INTG-01 (framework) | T-14-04, T-14-05 | `summer parity:upstream` records masked sidecars on loopback only; the fake asserts the request; refusals of malformed sidecars | unit | `go test ./modules/tide -run '^(TestUpstreamProxyScriptMode\|TestUpstreamProxyRefusesNonLoopback\|TestEnsureParityCA\|TestUpstreamProxyMultipartAndForwardGuard\|TestWriteUpstreamRefusesUnmaskedCredential\|TestUpstreamFakeRejectsMismatchedRequest\|TestUpstreamFakeHashesBase64Bodies\|TestUpstreamSidecarRefusals)$' -count=1 -v` ; `go test ./cmd/summer -run '^(TestParityCommandContract\|TestToolCommandNames)$' -count=1` | ✅ `modules/tide/upstream_test.go`, `upstream_proxy_test.go`, `upstream_coverage_test.go` | ✅ green |
|
||||
| 14-01-T4 | 14-01 | 1 | SRCH-02 (framework) | T-14-03, T-14-07 | sunscreen redacts credentials in every generated main; surf hides panic text; DropIndex and EnsureIndex | unit | `go test ./modules/sunscreen ./modules/surf ./internal/build ./modules/beachcomber/... -run '^(TestRedactHandler\|TestScrub\|TestInstallDefault\|TestRecoverHidesPanicDetails\|TestGenerateMainInstallsRedactingLogger\|TestDropIndex\|TestEngineDropIndex\|TestEngineEnsureIndex)$' -count=1` | ✅ `modules/sunscreen/sunscreen_test.go`, `modules/surf/recover_redaction_test.go`, `modules/beachcomber/typesense/engine_test.go` | ✅ green |
|
||||
| 14-01-T5 | 14-01 | 1 | INTG-02, API-08 | — | REQUIREMENTS, ROADMAP and PROJECT reworded (D-06, D-07, D-13, D-14) | gate | `bash scripts/check-phase14.sh --evidence` (the SDK and sitemap wording refused; the ROADMAP Phase 14 repos and criteria name the routes and both plugin repos) | ✅ `.planning/REQUIREMENTS.md`, `.planning/ROADMAP.md` | ✅ green |
|
||||
| 14-02-T1 | 14-02 | 2 | JOBS-02, INTG-01 | T-14-08, T-14-11 | A CSV row's Discogs pick resolves with PHP's draft, replayed from PHP's recorded exchange; the HMAC bucket | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestCsvRowPickSeam\|TestCsvRowPickResolves)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes/discogs -run '^(TestBucketID\|TestRateLimiterPostgresAcquire)$' -count=1` ; `go -C ../fonoteka.go test ./parity -run '^(TestParityCorpus\|TestUpstreamSidecarsAreReplayed)$' -count=1` | ✅ `csv_smoke_test.go`, `classes/discogs/postgres_test.go` | ✅ green |
|
||||
| 14-02-T2 | 14-02 | 2 | INTG-01 | T-14-09 | Client statuses, limiter budget and Retry-After, the PHP truth tables of the mapper, parser, scorer and price resolver | unit + truth table | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes/discogs -run '^(TestPHPTruthDiscogs\|TestClientGetRelease\|TestDiscogsClientStatuses\|TestRateLimiterBudget\|TestRateLimiterSyncFromHeaders\|TestRegisterRetryAfter\|TestDiscogsDomainVectors\|TestDiscogsRateWindowConcurrent\|TestNumberFormat4)$' -count=1 -race` | ✅ `classes/discogs/discogs_test.go`, `php_truth_test.go`, `testdata/php_*.json` | ✅ green |
|
||||
| 14-02-T3 | 14-02 | 2 | JOBS-02 | T-14-10, T-14-12, T-14-13 | Match and import workers: 0/1/many, pause and re-dispatch, cancel, superseded, write_failed, lost access; WR-02 locks | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestCsvMatchJob\|TestCsvImportJob\|TestCsvWR02)$' -count=1 -race` | ✅ `csv_jobs_test.go`, `csv_wr02_test.go` | ✅ green |
|
||||
| 14-02-T4 | 14-02 | 2 | JOBS-03, SRCH-02, CLI-05 | T-14-14, T-14-15 | The digest mails once per window; prune-notifications on the daily schedule; reindex with its integrity checks and the legacy drop | unit + Postgres | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestWishlistDigestJob\|TestWishlistDigestWorkerRegistered\|TestFonotekaSchedulePrune)$' -count=1` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/console -run '^(TestPruneNotifications\|TestReindexCommand)$' -count=1` | ✅ `wishlist_digest_job_test.go`, `schedule_test.go`, `console/phase14_commands_test.go` | ✅ green |
|
||||
| 14-03-T1 | 14-03 | 3 | INTG-01 | T-14-16, T-14-17 | Album match: scope first, the gate, the shared bucket, PHP's scored candidates | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestDiscogsMatchRoute\|TestDiscogsInboundLimits\|TestRouteTablePhase14)$' -count=1 -race` | ✅ `discogs_routes_test.go`, `routes_table_phase14_test.go` | ✅ green |
|
||||
| 14-03-T2 | 14-03 | 3 | INTG-01 | T-14-18, T-14-19 | Apply-release fill-empty, overwrite, cover_only and PHP's dry run; draft match; wishlist twins | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestApplyReleaseModes)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes/discogs -run '^(TestCoverFetcherHostLock)$' -count=1` | ✅ `discogs_routes_test.go`, `classes/discogs/cover_fetcher_test.go` | ✅ green |
|
||||
| 14-03-T3 | 14-03 | 3 | INTG-01 | T-14-17, T-14-20, T-14-21 | Import box, MCP cover-price (write scope, throttle 12/min), token test | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestDiscogsImportRoute\|TestCoverPriceRoute\|TestDiscogsCredentialTestRoute)$' -count=1 -race` | ✅ `discogs_routes_test.go` | ✅ green |
|
||||
| 14-04-T1 | 14-04 | 4 | INTG-02 | T-14-29 | sm-golem-plugin boots before fonoteka; ai-credential/test answers PHP's bodies | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/golem -run '^(TestGolemPluginBoot)$' -count=1` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestAICredentialTestRoute)$' -count=1` | ✅ `golem/golem_test.go`, `ai_routes_test.go` | ✅ green |
|
||||
| 14-04-T2 | 14-04 | 4 | INTG-02 | T-14-22, T-14-24 | Both adapters' payloads, every AIService call, the SSRF guard, the models admin and importer | unit | `go -C ../fonoteka.go test ./plugins/golem15/golem/... -run '^(TestOpenAIAdapterPayload\|TestAnthropicAdapterPayload\|TestAIServiceFailures\|TestAIServiceStream\|TestDefaultModelQuirk\|TestPromptFactory\|TestSSRFGuard\|TestImportSettings\|TestAdminModelsForm\|TestGolemAdminSchemas\|TestGolemImportCommand)$' -count=1` | ✅ `golem/classes/*/..._test.go`, `golem/golem_admin_test.go` | ✅ green |
|
||||
| 14-04-T3 | 14-04 | 4 | INTG-02 | T-14-22, T-14-23 | The AI tier: admin vision model trusted, user and org guarded, PHP's precedence | unit | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestAdminVisionTier\|TestResolveAIConfigPrecedence)$' -count=1` ; `go -C ../fonoteka.go test ./plugins/golem15/golem/classes/services -run '^(TestAdminModelTrusted)$' -count=1` | ✅ `ai_routes_test.go`, `credentials_smoke_test.go` | ✅ green |
|
||||
| 14-04-T4 | 14-04 | 4 | INTG-02 | T-14-25, T-14-26, T-14-27 | Recognition on both groups: prompt, retry, truncation, caps, image guard, bucket | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestRecognizeRoutes)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes -run '^(TestRecognizeAlbums)$' -count=1` | ✅ `ai_routes_test.go`, `classes/album_recognition_test.go` | ✅ green |
|
||||
| 14-05-T1 | 14-05 | 5 | API-08 | T-14-30 | Widget config behind the constant-time key and the fail-closed Origin list | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/feedback -run '^(TestFeedbackPluginBoot\|TestFeedbackConfig\|TestKeyMatches\|TestURLHost\|TestAllowedOriginHosts\|TestFeedbackOptionsPreflight)$' -count=1` ; `go test ./modules/surf -run '^(TestCORSOptionsMatchesLaravel)$' -count=1` | ✅ `feedback/feedback_test.go`, `modules/surf/cors_coverage_test.go` | ✅ green |
|
||||
| 14-05-T2 | 14-05 | 5 | API-08 | T-14-31, T-14-32, T-14-35 | Submit with PHP's validation and image guard, me/hidden, the user payload key | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/feedback -run '^(TestFeedbackSubmit\|TestMeHidden\|TestFeedbackApiArrayHook)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/feedback/classes -run '^(TestImageGuardCopy)$' -count=1` | ✅ `feedback/feedback_test.go`, `feedback/classes/classes_test.go` | ✅ green |
|
||||
| 14-05-T3 | 14-05 | 5 | API-08 | T-14-33, T-14-34, T-14-36 | G15Office job replays PHP's exchange; settings and submissions admin; embed.js; settings import | unit + parity | `go -C ../fonoteka.go test ./plugins/golem15/feedback/classes -run '^(TestSyncG15Office\|TestTaskText)$' -count=1` ; `go -C ../fonoteka.go test ./plugins/golem15/feedback -run '^(TestFeedbackAdminSchemas\|TestEmbedJSServed\|TestFeedbackImportSettings)$' -count=1` ; `go -C ../fonoteka.go test ./parity -run '^(TestFeedbackJobSidecarMatchesPlugin)$' -count=1` | ✅ `feedback/classes/classes_test.go`, `parity/feedback_seed_test.go` | ✅ green |
|
||||
| 14-06-T1 | 14-06 | 6 | JOBS-02, JOBS-03, SRCH-02, INTG-01, INTG-02, API-08, CLI-05 | T-14-37 | The gate runs both repositories, the corpus at 175/172 and the flows, and fails closed | gate | `bash scripts/check-phase14.sh --self-test && bash scripts/check-phase14.sh --go && bash scripts/check-phase14.sh --parity` ; `go -C ../fonoteka.go test ./parity -run '^(TestParityCorpus\|TestCheckCorpusPortedCaseStatus\|TestFonotekaNuxtFlows\|TestCheckCorpusUpstreamCredential\|TestParityContract\|TestSchemaMatchesPHPSnapshot)$' -count=1` | ✅ `scripts/check-phase14.sh` | ✅ green |
|
||||
| 14-06-T2 | 14-06 | 6 | INTG-01, JOBS-02 | T-14-19 | PHP truth tables row for row; the numeric edges one step either side; the job lifecycles; the route table and the fuzz over the Phase 14 routes | unit + truth table + fuzz seeds | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestPhase14Edges\|TestPhase14Jobs\|TestRouteTablePhase14\|TestRouteTablePhase13\|TestRouteTablePhase12\|FuzzWriteEndpoints\|TestPhase14HandlersFailClosed)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes ./plugins/golem15/fonoteka/controllers/api -run '^(TestPhase14Classes\|TestPhase14ControllerHelpers)$' -count=1` ; `go -C ../fonoteka.go test ./plugins/golem15/fonoteka/classes/discogs -run '^(TestPHPTruthDiscogs)$' -count=1` | ✅ `phase14_edges_test.go`, `phase14_jobs_test.go`, `phase14_handlers_test.go`, `write_endpoints_fuzz_test.go`, `classes/phase14_classes_test.go`, `controllers/api/phase14_controllers_test.go`, `classes/discogs/php_truth_test.go` | ✅ green |
|
||||
| 14-06-T3 | 14-06 | 6 | INTG-02, API-08 | T-14-38, all mitigated | Every mitigated threat fails without its protection; the framework and both plugins at the floor | unit + gate | `go -C ../fonoteka.go test ./plugins/golem15/fonoteka -run '^(TestPhase14Threats)$' -count=1 -race` ; `go -C ../fonoteka.go test ./plugins/golem15/feedback -run '^(TestFeedbackEdges)$' -count=1` ; `bash scripts/check-phase14.sh --named && bash scripts/check-phase14.sh --coverage && bash scripts/check-phase14.sh --removal` | ✅ `phase14_security_test.go`, `feedback/feedback_edges_test.go`, `14-SECURITY-REVIEW.md` | ✅ green |
|
||||
| 14-06-T4 | 14-06 | 6 | JOBS-02, JOBS-03, SRCH-02, INTG-01, INTG-02, API-08, CLI-05 | — | Validation signed off, requirements marked, API coverage checked, folded todos closed, the whole gate green | gate | `bash scripts/check-phase14.sh --evidence && bash scripts/check-phase14.sh --all` | ✅ this file, `COVERAGE.md`, `.planning/REQUIREMENTS.md` | ✅ green |
|
||||
|
||||
*Status: ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
### Coverage (scripts/check-phase14.sh --coverage, 2026-10-04)
|
||||
|
||||
| Package | Statements covered |
|
||||
|---------|--------------------|
|
||||
| summercms.go `modules/fetchguard` | 84.5% |
|
||||
| summercms.go `modules/tide` | 82.1% |
|
||||
| summercms.go `modules/sunscreen` | 98.5% |
|
||||
| summercms.go `modules/beachcomber` | 84.8% |
|
||||
| summercms.go `modules/beachcomber/typesense` | 95.6% |
|
||||
| fonoteka `classes/discogs` | 86.1% |
|
||||
| fonoteka `console` | 82.6% |
|
||||
| fonoteka root, `classes`, `controllers/api`: the 132 Phase 14 functions | each at 80.0% or more (lowest 80.0%: `AlbumReleaseMatchDraft`, both workers' `fail`), two exempt with reasons: `cover_importer.go fetch` 72.7% (its 2xx path needs the live image host) and `validateDiscogsInput` 77.8% (its error branch needs a malformed rule table) |
|
||||
| sm-golem-plugin root, `classes/factories`, `providers`, `security`, `services`, `valueobjects`, `console`, `controllers`, `models`, `updates` | 100.0%, 90.0%, 93.4%, 98.0%, 85.5%, 90.8%, 96.1%, 93.1%, 100.0%, 80.0% |
|
||||
| sm-feedback-plugin root, `classes`, `console`, `controllers`, `controllers/api`, `models`, `updates` | 93.8%, 82.9%, 92.6%, 100.0%, 86.0%, 90.8%, 91.7% |
|
||||
| `internal/pgtest` of both plugins | exempt: a test-only helper whose uncovered lines are container start failures |
|
||||
|
||||
---
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] `fonoteka.go/parity/discogs_truth_tables.php` — truth-table generator (csv_truth_tables.php pattern)
|
||||
- [ ] tide upstream sidecar loader + fake and the replay hook for `*.upstream.yaml`
|
||||
- [ ] Shared fake clock helper for limiter, client and job tests
|
||||
- [ ] Harness to run a conga worker function directly without a live River client
|
||||
- [ ] `scripts/check-phase14.sh` with updated `EXPECTED_PORTED` / `EXPECTED_PENDING`
|
||||
- [x] `fonoteka.go/parity/discogs_truth_tables.php` — truth-table generator (csv_truth_tables.php pattern; 14-02, widened in 14-06 to `php_mapper.json`, `php_input_parser.json`, `php_scorer.json`, `php_price_suggestion.json`)
|
||||
- [x] tide upstream sidecar loader + fake and the replay hook for `*.upstream.yaml` (14-01, 14-02)
|
||||
- [x] Shared fake clock helper for limiter, client and job tests (`classes/discogs/discogstest`, 14-02)
|
||||
- [x] Harness to run a conga worker function directly without a live River client (`deliverCsvMatch`, `deliverCsvImport`, `deliverWishlistDigest` take the job id, 14-02)
|
||||
- [x] `scripts/check-phase14.sh` with `EXPECTED_ROUTES=175`, `EXPECTED_PORTED=172`, `EXPECTED_PENDING=3` (14-06)
|
||||
|
||||
---
|
||||
|
||||
@@ -77,11 +109,13 @@ created: "2026-10-03"
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have `<automated>` 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 < 180s
|
||||
- [ ] `nyquist_compliant: true` set in frontmatter
|
||||
- [x] All tasks have `<automated>` verify or Wave 0 dependencies
|
||||
- [x] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||
- [x] Wave 0 covers all MISSING references
|
||||
- [x] No watch-mode flags
|
||||
- [x] Feedback latency < 180s per task's named tests
|
||||
- [x] Nyquist compliance set in the frontmatter
|
||||
|
||||
**Approval:** pending
|
||||
**Approval:** validated 2026-10-04 (plan 14-06; gate `scripts/check-phase14.sh --all` and `--removal` green)
|
||||
|
||||
**Final gate run:** `bash scripts/check-phase14.sh --all` on 2026-10-04 ended with `phase14 all passed` (self-test, go, parity at "175/175 recorded, 172 ported and passing, 0 failing, 3 pending", named, coverage and evidence; 13 min 55 s). `bash scripts/check-phase14.sh --removal` on its own ended with `phase14 removal passed` (43 of 43 mutations failed their named test; every file restored byte for byte). One earlier `--all` run refused at the coverage stage when the `updates` package's testcontainers Postgres did not start within its 60 s wait under load; the rerun passed unchanged.
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
> Full coverage by default. Opt-outs are explicit, reasoned decisions.
|
||||
>
|
||||
> Scope: Phase 14 is a parity port. The PHP reference (Płytarium's Golem15.Fonoteka, Golem15.Golem and Golem15.Feedback plugins) defines the surface. Every capability the PHP code calls is INTEGRATE. Every capability it never calls is OPT-OUT with the reason "not used by the PHP reference — parity port". The INTEGRATE reason column names the test that proves the capability. Plan 14-06 confirms each named test passes, and `scripts/check-phase14.sh --evidence` refuses a row whose test is missing or failing.
|
||||
>
|
||||
> Confirmed 2026-10-04 (plan 14-06): every test an INTEGRATE row names is run by exact name by `scripts/check-phase14.sh --named` and passed in that run; `--evidence` refuses an INTEGRATE row naming a test outside that stage and an OPT-OUT row without a reason. Live vendor calls stay out of the gate (D-15): each INTEGRATE capability is proven against PHP's recorded exchange or a scripted vendor answer.
|
||||
|
||||
## Discogs API (api.discogs.com, i.discogs.com)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user