Repository navigation
test(ingestor): pin the loser's re-parented observation headers in the merged route_mask (#324) - #328
Conversation
…e merged route_mask (#324) recomputeMergedRouteMask ORs five evidence terms. The fifth, the header bits of the loser's observations after the UPDATE OR IGNORE move re-parents them onto the survivor, had no test: mutant N2 (recompute above the move, so the scan sees only the survivor's own rows) survived the full cmd/ingestor suite. Add the RZ1 shape from the issue: survivor computed FLOOD with one FLOOD observation; loser route_mask NULL, route_type FLOOD, one surviving DIRECT observation. That header is the only DIRECT evidence, so the merged mask must be DIRECT|FLOOD (6). Under N2 it is FLOOD (2). Test-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rapport — CS-pve-agent2 PR#328 #324 — head 4912821Status: Done. The test pins the fifth Evidence: [T] = run locally on this head, [A] = analysis / code reading, [K] = CI check on this head. Requirements
Always-checks
Local runs (head)
CI per job (head
|
| Job | Result | Evidence |
|---|---|---|
| Go Build & Test | pass | [K] |
| Playwright E2E Tests | pass | [K] |
| Build & Publish Docker Image | pass | [K] |
| Release Artifacts | skipped (PR) | [K] |
| Deploy Staging | skipped (PR) | [K] |
| Publish Badges & Summary | skipped (PR) | [K] |
No reruns; the known-unstable #271 did not fail.
Leftovers
gofmt -lflagshash_migrate_route_mask_287_test.goon master too. gofmt would rewrite''in an existing doc comment (the fill-column test,COALESCE(scope_name, '')) to a typographic quote. The added lines are gofmt-clean; the pre-existing line was left alone to keep the diff test-only and minimal. [T]cmd/servergo test ./...was not run locally because nothing in it changed; CI "Go Build & Test" covers it. [A] [K]scripts/check-xss-sinks.shhas a bash shebang and fails undersh(Syntax error: "(" unexpected); run it withbashor directly. [T]
Review — CS-Macmini PR#328 — head 4912821Dom: APPROVE med nits Independent, read-only review. Evidence: [T] = run locally by me on the merged tree ( Findings
No blocking finding. No behaviour change: the diff is one test file. Answers to the review points1. The RZ1-shaped test is red under mutant N2 and green on master — run myself.
2. The loser's observation header is the only evidence for the bit.
3. Test-only. Always-checks
Tests I ran (merged tree, base
|
| Suite | Result |
|---|---|
cmd/ingestor go test -count=1 -timeout 40m ./... |
ok (112 s) [T] |
cmd/server go test -count=1 -timeout 40m ./... |
ok (53 s) [T] |
New test -count=30 |
ok — not flaky [T] |
go test -race -count=5 -run TestContentHashMigration_MergeRecomputes |
ok [T] |
sh test-all.sh |
225 passed, 0 failed (225 files) [T] |
node test-frontend-helpers.js |
709 passed, 0 failed [T] |
node test-e2e-playwright.js against a local Go server on a fresh fixture copy prepared as in CI (freshen, grouped/Kpa-clawbot#1791 seed SQL, corescope-migrate, seeds 2073 / 199 / 245; instrumented public dir; server stopped by port) |
132/135 passed, 3 skipped — same numbers the author reports [T] |
node test-node-liveness-e2e.js |
35 checks passed [T] |
Two E2E detours, neither attributable to this PR and neither one of the known-unstable #256 / #267:
- First run failed on "Version info lives on Perf dashboard". Root cause is N3 above plus my own harness: I review from a
git archiveexport, soresolveCommit'sgit rev-parsefallback finds no repository and/api/healthreportscommit: "unknown". Replicating CI's.git-commitfile fixed it, and the test then passed every time. - Second run failed on "Node side panel Details link navigates" (
[data-loaded="true"]15 s timeout) after the preceding nodes-page test had passed. It passed on the next run with no change — a local flake.
Mutants I ran myself
| ID | Mutation | New test | Verdict |
|---|---|---|---|
| N2 (the issue's) | hoist recomputeMergedRouteMask above the UPDATE OR IGNORE observations move |
FAIL, mask 2 |
killed — and it is the only test in the whole suite that catches it |
| MA | observation scan reads transmission_id = loser instead of winner |
FAIL, mask 2 |
killed |
| MB | drop the UPDATE OR IGNORE re-parent entirely (loser's observations deleted) |
FAIL, mask 2 |
killed |
| MC | routeMaskBitFromHeader's bit contributes nothing (mask |= 0 * …) |
FAIL, mask 2 |
killed |
| MD | read only the winner's route_type (the old MX1) |
PASS | expected survival — the shape makes both route_types FLOOD, and ..._MergeRecomputesBitFromLoserRouteType_287 kills it instead. Confirms the new test is narrowly targeted rather than overlapping its siblings. |
CI per job (head 4912821b, run 37480948213, attempt 1, no reruns) [K]
| Job | Result |
|---|---|
| Go Build & Test | success |
| Playwright E2E Tests | success |
| Build & Publish Docker Image | success |
| Release Artifacts | skipped (PR) |
| Deploy Staging | skipped (PR) |
| Publish Badges & Summary | skipped (PR) |
Head was 4912821b5db3a4b04dafa79cbd6ddb9fbeabd257 at both the start and the end of this review; the PR is still a draft and reports mergeable.
Not verified
- Behaviour on a real large database. The merge path is exercised only through the test harness's in-memory-sized SQLite fixtures; no staging or production access was used, and none was needed for a test-only change.
- The remaining E2E files from the CI list. The PR changes no frontend and no server code, so nothing in that list is affected; I ran the main Playwright suite and the node-liveness suite as a sanity check and relied on CI [K] for the rest.
- Go modules other than
cmd/ingestorandcmd/server(this is a multi-module repo). Unchanged by the diff; covered by the CI Go job [K]. - The Docker image job locally — CI only [K].
- Whether N1's "Master" wording predates hash migration: merging a transmission with a NULL route_mask turns it into 0, so route flags are lost permanently #287 in intent rather than by copy. I only confirmed the arithmetic claim is true for the pre-hash migration: merging a transmission with a NULL route_mask turns it into 0, so route flags are lost permanently #287 code and that the sibling comments share the phrasing.
Relates to #324
Follow-up to #295 (#287): pins the fifth evidence term of
recomputeMergedRouteMask, the header bits of the loser's observations afterUPDATE OR IGNORE observationsre-parents them onto the survivor.Plan
Change
cmd/ingestor/hash_migrate_route_mask_287_test.go: newTestContentHashMigration_MergeRecomputesBitFromLoserReparentedObservation_324.route_maskroute_type["aa"]["bb"](survives the move)The test asserts:
6);Mutant N2
N2 moves
recomputeMergedRouteMaskabove theUPDATE OR IGNORE observationsmove, so the scan sees only the survivor's own rows.cmd/ingestorsuitede6e83b4)6okmerged route_mask = {2 true}, want DIRECT|FLOOD = 0110Checks
cmd/serveruntouched (stays read-only); no newmap[string]interface{}.bash scripts/check-xss-sinks.sh --diff origin/masteris clean.deploy.yml, 1 inrelease-fast-path.yml.Performance
Test-only; no hot path touched.
🤖 Generated with Claude Code