# Proof tests from the 2026-10-14 code review These are the tests the two reviewers wrote to demonstrate their findings. They live under a directory whose name starts with `_`, so `go build ./...`, `go test ./...` and `go vet ./...` ignore them. They are evidence, not part of the suite. When a finding is fixed, turn its proof test into a real regression test in the package it belongs to. | Dir | Reviewer | Style | |---|---|---| | `a/` | A — correctness and runtime | Demonstrations: the tests **pass** and print the evidence with `t.Log` (run with `-v`). | | `b/` | B — security, contracts, ops | Assertions: the tests **fail** while the defect exists (a few `PASS`es only log evidence). | ## Running Copy the files into a scratch copy of the repo, so the real packages stay clean: ```sh rm -rf /tmp/mc_proof && cp -R /Users/dice/Work/migadu_counters /tmp/mc_proof && cd /tmp/mc_proof cp -R review/_proof_tests/a/internal/. internal/ # reviewer A cp -R review/_proof_tests/b/internal/. internal/ # reviewer B cp -R review/_proof_tests/b/cmd/. cmd/ go test -count=1 -v -run 'TestReview' ./internal/... ./cmd/... go test -run '^$' -bench Review -benchmem ./internal/txlog/ # A's CDB parsing benchmarks ``` Requirements and notes: - `a/internal/store/review_test.go` (`TestReview_TimeoutAfterWriteStillCounts`) needs a real Redis on port 16401: `redis-server --port 16401 --save '' --appendonly no`. The test uses `DEBUG SLEEP` to make the reply arrive after the client timeout. It fails to connect if no Redis is running. - `b/bad.cdb` is a three-row fixture with one malformed row (`bad.com x12|A/i=5`). It is used by `b/internal/server/review_b4_test.go`, whose path was updated to `../../review/_proof_tests/b/bad.cdb`. - `a/run/` holds the config and the app log from reviewer A's manual reproduction of "SIGHUP during startup kills the daemon" (merged item #10). The paths in `config.toml` point at the reviewer's former scratch copy, so edit them before reuse. The log stops after `domains db loaded`, which is the evidence. ## Map to the merged report (`../README.md`) | Merged # | Proof | |---|---| | 1 | `a/internal/server/review_test.go` `TestReview_ClientDisconnectLosesCount`, `TestReview_ClientDisconnectNoDelay` | | 2 | `b/internal/server/review_b_test.go` `TestReviewB_InMailFromDropsRecipientCount`, `TestReviewB_OutRecipientDropsSenderCount`; `a/…` `TestReview_MasterLoginAndOddSenders` | | 3 | `a/internal/server/review_test.go` `TestReview_MasterLoginAndOddSenders` (first case) | | 4 | `b/internal/server/review_b2_test.go` `TestReviewB_LostCrossingOnReplyTimeout`; `a/internal/server/review_test.go` `TestReview_PartialExecFailure`; `a/internal/store/review_test.go` (real Redis) | | 5 | `a/internal/txlog/review_bench_test.go` | | 6 | `b/internal/config/review_b_test.go` `TestReviewB_MisconfigStarts`; `b/…/review_b_test.go` `TestReviewB_EmptyTokenOpen` | | 7 | `b/internal/server/review_b_test.go` `TestReviewB_PlusTagSeparateCounters` | | 8 | `b/internal/server/review_b4_test.go`; `a/internal/counting/review_test.go` | | 10 | `a/run/` (manual reproduction) | | 11 | `b/internal/server/review_b_test.go` `TestReviewB_RejectLogHasNoTraceID` | | 13 | `b/internal/server/review_b3_test.go` | | 14 | `b/internal/server/review_b_test.go` `TestReviewB_ErrorLeak` | | 15 | `b/internal/config/review_b_test.go` (case "sentinel without password") | | 16 | `b/cmd/counterctl/review_b_test.go` `TestReviewB_31DayWarningOffByOne` | | 17 | `b/internal/server/review_b_test.go` `TestReviewB_PanicNotInMetrics` | ## Fixed in round 1 (2026-10-14) — regression tests now in the suite | Merged # | Regression test | |---|---| | 1 | `internal/server` `TestClientDisconnectStillCounts`, `TestAcceptedBeforeCounting`, `TestQueueFull`, `TestDrainCountsEverything`; `internal/counting/queue_test.go` | | 2 | `internal/server` `TestIn_OddMailFromStillCountsRecipient`, `TestOut_OddRecipientStillCountsSender`; `internal/api` `TestValidateOut`, `TestValidateIn`, `TestNormalizeEmail` | | 3 | `internal/server` `TestOut_LoginSuffixCountsBaseAddress`; `internal/api` `TestNormalizeAuthUser` | | 4 | `internal/server` `TestPartialExecFailureStillNotifies`, `TestLostReplyStillNotifies`; `internal/counting` `TestCounter_PartialExecFailure`, `TestCounter_LostReplyReReadsMaster`; `internal/store` `TestIncr_PartialFailure`, `TestOutcomeUnknown` | | 5 | `internal/domains` `TestLookup_CachesParsedRecord`, `TestLookup_CacheBounded`, `BenchmarkLookupSmall`/`BenchmarkLookupHuge` | | 7 | `internal/server` `TestIn_PlusTagCountsMailbox`; `internal/counting` `TestPlan_PlusTagCountsMailbox`; `internal/domains` `TestMailbox` (decision 2026-10-15: strip the tag, as rcptd does) | | 8 | `internal/server` `TestMalformedRowCountsOtherSide`; `internal/counting` `TestPlan_MalformedRowIsNotHosted`; `internal/domains` `TestLookup_MalformedRow`; `internal/txlog` `TestTrail_MalformedRow` | | 6 | `internal/config` `TestValidate_Errors` (auth_token / unknown keys), `TestLoad_TokenFromEnvOnly`, `TestLoad_Defaults` (`:5555`); `cmd/migadu_counters` `TestRun_FlagsAndExitCodes` | The proof files stay here as the review record; they no longer compile against the current API (`CountResponse`, `store.Incr`) and are not meant to.