20 KiB
phase, plan, subsystem, tags, requires, provides, affects, actuals, plan_head_before, plan_head_after, app_repo_head_before, app_repo_head_after, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status
| phase | plan | subsystem | tags | requires | provides | affects | actuals | plan_head_before | plan_head_after | app_repo_head_before | app_repo_head_after | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | coverage | duration | completed | status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 14-domain-jobs-and-external-integrations | 06 | testing |
|
|
|
|
|
c12641605c |
17b2ef1961 |
9fc38d9d7fefd9671312e4a148b2f3042acde6eb | cd393e4 |
|
|
|
|
|
|
132min | 2026-10-04 | complete |
Phase 14 Plan 06: Unit tests and the Phase 14 gate Summary
Phase 14 is proven by one fail-closed gate: PHP's own Discogs truth tables replayed row for row, every Phase 14 function and both shared plugins at the 80% floor, every numeric edge pinned one step either side, and 43 anchor-exact mutations, one or more per mitigated threat, each caught by a named test.
Performance
- Duration: 132 min
- Started: 2026-10-03T22:35:35Z
- Completed: 2026-10-04T00:48Z
- Tasks: 4
- Commits: 6 in summercms.go, 9 in fonoteka.go, 2 in sm-golem-plugin and 1 in sm-feedback-plugin (both pushed), plus this summary
- Files: 13 created and 13 modified across the four repositories (plus 11 fuzz seeds)
Accomplishments
- The gate (
scripts/check-phase14.sh).--goruns vet and tests in summercms.go, and with-racein fonoteka.go including sm-user-plugin, sm-golem-plugin and sm-feedback-plugin. It refuses a vendor AI SDK in either module graph (D-02, T-14-SC).--parityreads 175 recorded, 172 ported and passing and 3 pending from the replay's own coverage line and from the manifest. It requires every TestFonotekaNuxtFlows subtest (read from the source, so a new flow cannot be skipped), the broadcast goldens, the sidecar replay, the feedback job sidecar,check_corpus --require-recorded --check-secrets, the fuzz corpus scan and the docs checks.--namedruns about 110 tests by exact name, across 21 packages.--coverageenforces the floors (below).--removalruns 43 mutations.--evidencechecks the security review, the validation map, COVERAGE.md, the REQUIREMENTS wording and the ROADMAP Phase 14 section.--self-testplants a failing, skipped, zero-test, racy and non-JSON run, a fourth pending route, a vendor SDK, each secret shape, each coverage and function-floor refusal, each removal-harness refusal and each evidence gap.
- PHP truth tables.
parity/discogs_truth_tables.phpwas rerun against the isolated PHP instance:php_mapper.jsongained releases without images, with secondary images only, with several formats, with cassette and CD, with unicode artists and a master's main release.- The barcode table gained check-digit cases.
- The price table gained every market currency, rounding ties and empty or odd suggestions.
TestPHPTruthDiscogsreplays all rows and fails if a table shrinks. The price results are compared byte for byte.
- Application tests (fonoteka).
TestPhase14Edgespins the limiter (50/51), the wait budget (15/16 s), Retry-After, the candidate cap (10/11), the 90-day prune cutoff, the 60/20/10 inbound buckets and the 12/13 cover-price throttle.TestPhase14Jobscovers a cancel while a match is paused, a resumed match writing the same rows as an uninterrupted one, already-written rows being skipped, and every worker error branch.TestPhase14HandlersFailClosedcovers gate lookups that fail with a 500 before any vendor call, PHP's no_match, token-rejected and Winter 500 answers, and failures after the fetch.TestPhase14Classesuses a fault-injecting gorm handle.TestPhase14ControllerHelperscovers the controller helpers.TestRouteTablePhase14now asserts which in-handler bucket each route answers 429 from.FuzzWriteEndpointscovers the 11 Phase 14 routes through a scripted vendor, with 11 committed seeds (81 routes in all).
- Threats.
TestPhase14Threatshas one subtest per application threat from T-14-08 to T-14-29. The framework threats map to their module tests, and the feedback threats to the plugin's own tests.14-SECURITY-REVIEW.mdmaps all 39 ids, and the removal run passed 43 of 43. - Shared plugins.
TestGolemAdminSchemasandTestGolemImportCommandwere added to sm-golem-plugin, andTestFeedbackEdgesto sm-feedback-plugin. Both were pushed, and each pointer was bumped in its own commit. - Record. 14-VALIDATION.md is validated. INTG-02 and API-08 are marked Complete. COVERAGE.md is confirmed, and both folded todos are closed.
Coverage (check-phase14.sh --coverage)
| Package | Coverage |
|---|---|
| fetchguard | 84.5% |
| tide | 82.1% |
| sunscreen | 98.5% |
| beachcomber | 84.8% |
| beachcomber/typesense | 95.6% |
| fonoteka classes/discogs | 86.1% |
| fonoteka console | 82.6% |
- The 132 Phase 14 functions of the fonoteka root, classes and controllers/api packages are each at 80% or more. The lowest is 80.0%. Two are exempt.
- sm-golem-plugin packages are between 80.0% (updates) and 100%.
- sm-feedback-plugin packages are between 82.9% (classes) and 100%.
- internal/pgtest is exempt in both plugins.
Task Commits
summercms.go:
- Task 1 (tracer): the gate's self-test, go and parity stages:
88f7683(test) - Task 3: tide sidecar refusals:
fc90ae2(test). Gate named, coverage and removal stages:4c042f7(test). Security review:8154352(docs) - Task 4: evidence stage:
a1fccd3(test). Validation, requirements, coverage, todos:17b2ef1(docs)
fonoteka.go (not pushed):
- Task 2: PHP truth tables:
45052ad. Edges and job lifecycles:b30698f. Route buckets and fuzz:bf177e3. Class, controller and worker coverage:0244392(all test) - Task 3: sm-golem-plugin bump:
49dfef5. sm-feedback-plugin bump:02a4d05(chore). TestPhase14Threats:21b3eb8(test). sm-golem-plugin bump:976b446(chore). T-14-19 strengthened:cd393e4(test)
sm-golem-plugin (pushed, master): 70314b5, 6646d10. sm-feedback-plugin (pushed, master): 3057719.
Tracer gate: after Task 1, <verify> (bash -n, --self-test, --go, --parity) was re-run end to end and passed, so the expansion tasks went ahead.
Deviations from Plan
Auto-fixed issues
1. [Rule 1 - Weak tests found by the removal harness] Two tests did not catch the removal of their protection
- Found during: Task 3, first
--removalrun (5 survivors) - Issue: T-14-19's subtest checked only fields that a dry run stages, so removing the fill-empty skip survived.
TestGolemAdminSchemaschecked only that the key text was absent, whichlagoon.Encrypted's redaction already guarantees. - Fix: T-14-19 now also pins a filled barcode and an empty discogs_id. The golem test refuses any
api_keykey. - Commits:
cd393e4(fonoteka.go),6646d10(sm-golem-plugin), bumped in976b446 - The other three survivors were mutations that were redundant or did not build (the Origin empty-list check, DropIndex's escaping, an import left unused). Their rows now remove a protection that is load-bearing. The details are in the review.
2. [Rule 3 - Blocking] The gate keeps the failed go test log
- Found during: Task 1.
TestCoverFetcherHostLockfailed once under the full-racerun, and the log had been deleted. - Fix:
phase14_gomoves a failed run's JSON log to$TMPDIR/phase14-failed-<pid>.jsonand prints the detector's verdict last. The failure did not recur (see deferred-items.md).
Plan details refined
3. The feedback routes are pinned and fuzzed in sm-feedback-plugin, not in TestRouteTablePhase14/FuzzWriteEndpoints. Activating the feedback plugin from the fonoteka plugin's tests would make the application plugin require the shared plugin module. TestFeedbackConfig, TestFeedbackSubmit and TestFeedbackEdges pin the four routes' throttles, buckets and limits instead. The fonoteka route table pins the eleven Phase 14 routes plus their in-handler buckets.
4. The truth-table files are php_mapper.json (the old php_map_release.json plus php_candidates.json), php_input_parser.json, php_scorer.json and php_price_suggestion.json. php_scorer.json regenerated byte-identical.
5. The removal table covers every mitigated threat (43 rows), not only the high ones. The evidence stage enforces a row for every mitigated threat.
6. Coverage files the plan named but did not need were not created. Their packages already met the floor: fetchguard, sunscreen, typesense, golem services and providers, and feedback classes. The new coverage tests were placed where coverage was low: TestPhase14Classes, TestPhase14ControllerHelpers, TestPhase14HandlersFailClosed (new file phase14_handlers_test.go), TestGolemImportCommand and TestFeedbackEdges.
7. Two function exemptions and one package exemption, each with its reason, are recorded in the gate (see key-decisions).
8. The prune cutoff edge in TestPhase14Edges runs the real command on the wall clock: one row a minute inside the window and one a second past it. The exact-boundary row stays pinned by the console package's TestPruneNotifications, which injects the clock.
Total deviations: 8. Two are auto-fixes and six are refinements. Impact: the only production-adjacent change is test strength. No production code changed.
Issues Encountered
- One
--allrun refused at the coverage stage. A testcontainers Postgres for theupdatespackage did not become ready within 60 s under the gate's parallel load. The rerun passed unchanged. This is recorded in deferred-items.md. - The shell aliases
rmto its interactive form, and one cleanup blocked on its prompt. Later cleanups usecommand rm -f. /tmpis at quota, so the parity root was~/.cache/summercms-parity/p1406and the Go temp dirs were~/.cache/gotest-tmp. The truth-table run wrote nothing into the PHP checkout apart fromphp artisan cache:clear's cache directory, which earlier recordings also touched.git statusthere shows only the user's own files.
Verification
bash scripts/check-phase14.sh --all:phase14 all passed. The stages were self-test, go, parity (175/175 recorded, 172 ported and passing, 0 failing, 3 pending), named, coverage and evidence, and the run took 13 min 55 s.bash scripts/check-phase14.sh --removal: all 43 rowsfails as required, thenphase14 removal passed. Every file was restored byte for byte.- Per-task verifies:
- Task 2's
-racerun of TestPHPTruthDiscogs, TestPhase14Edges, TestPhase14Jobs, TestRouteTablePhase14 and FuzzWriteEndpoints passed with no SKIP or DATA RACE. - Task 3's
-race -coverruns of both plugins passed.
- Task 2's
- Acceptance greps:
EXPECTED_PORTED=172andEXPECTED_PENDING=3each appear once.- The golem and feedback plugin paths are present.
--bogusexits 2 with the usage text.php_mapper.jsonandphp_price_suggestion.jsonexist, and the generator namesPriceSuggestionResolver.- The fuzz corpus went from 70 to 81 files.
T-14-appears 96 times in the review.- There are three
run_(named|removal|coverage)()functions and onerun_evidence(), which--allcalls. - The REQUIREMENTS grep prints 7.
- The validation file has no row with the pending status, and neither todo is left under pending.
- Both plugins are
## master...origin/master.
Known Stubs
None.
Threat Flags
None. This plan adds tests and a gate script only. Its own threats, T-14-37 (gate counts) and T-14-38 (removal harness), are in the review with removal rows RC-40 to RC-42.
Next Phase Readiness
/gsd-verify-work 14can runbash scripts/check-phase14.sh --all, and separately--removal.- The open items from deferred-items.md carry over: the Phase 12 cover-import replay, the one-off TestCoverFetcherHostLock failure and the testcontainers start wait.
- Phase 14.1 (oauth-identities and the token
meroute) will moveEXPECTED_PENDINGfrom 3 toward 0.
Phase: 14-domain-jobs-and-external-integrations Completed: 2026-10-04
Self-Check: PASSED
Every created file exists; commits 88f7683, fc90ae2, 4c042f7, 8154352, a1fccd3 and 17b2ef1 (summercms.go), 45052ad, b30698f, bf177e3, 0244392, 49dfef5, 02a4d05, 21b3eb8, 976b446 and cd393e4 (fonoteka.go), 70314b5 and 6646d10 (sm-golem-plugin, on origin/master) and 3057719 (sm-feedback-plugin, on origin/master) are present.