| Previous finding | Disposition at `9cd8e78f` |
|---|---|
| R1-1 — Readiness without established database state | **Resolved.** Unknown pointers block readiness; off and expired pointers require empty mirrors. |
| R1-2 — `off` waits beyond caller timeout | **Resolved.** `TryLock` refuses concurrent publication with 409. |
| R1-3 — Unbounded console pointer reads | **Resolved for pointer reads.** `readPointerCapped` streams and caps the object. |
| R1-4 — Recovery generation deleted after failed synchronization | **Resolved.** Installation-error cleanup protects loaded and retained generations; failed synchronization retains all potentially recoverable generations. |
| R1-5 — Rejected-upload test does not establish zero reads | **Resolved at the reservation boundary.** The panicking-reader test detects reads before slot reservation. |
| R1-6 — Countries overflow ordering | **Resolved.** `_other` survives sorting and is relabelled during rendering. |
| R2-1 — Feed status writes bypass the read cap | **Partly resolved; P2 remains.** `internal/console/geoipfeed.go:174` still calls `Put`, and `internal/release/store.go:408` still reads the entire existing object with `os.ReadFile` before checking the write precondition. An oversized `feed.json` can exhaust memory despite the initial capped read. Apply the stat/streamed-hash checks already used by `PutFrom`, and test this underlying write path. |
| R2-2 — Timed-out checks never persist failures | **Resolved.** Status writes receive a separate bounded context. |
| R2-3 — Unreadable feed status clears an alert | **Resolved for established state.** Read and parse failures preserve the previous feed state. |
| R2-4 — Unusable directory prevents “not loaded” alert | **Resolved.** Control-plane state is retained before directory preparation. |
| R2-5 — Published alert reasons never change while unhealthy | **Resolved for publication.** Reason changes update `Value` and emit an event. |
| R3-1 — Console follower keeps serving an expired database | **Resolved.** Every tick checks the loaded reader independently of `current`; candidates also receive a metadata expiry check. |
| R3-2 — Transient status-read failure erases feed history | **Resolved.** An unsuccessful status read prevents replacement of unknown history. |
| R4-1 — Unbounded bucket operations block startup or publication | **Resolved.** Startup cleanup is asynchronous and bounded; maintenance receives bounded contexts; staging independently bounds its pointer read. |
| R4-2 — Restart falsely clears a persisted GeoIP alert | **Resolved for the reported unreadable-input cases.** Unknown state produces no metric reading, preserving the restored firing rule. The new guard introduces finding 1 below. |
| R4-3 — Email delivery suppresses active reason changes | **Partly resolved; P2 remains.** `internal/console/alertwatch.go:231–242` permanently records delivered reasons as `geoip@N=true`. After `2 → 3 → 0 → 2 → 3`, the second expiry notification is suppressed. Returning to a previously delivered reason within one firing episode is also suppressed. Persist the **last delivered reason per recipient**, preserving retries. Extend the test beyond its current `2 → 3 → 0` sequence. |
| R4-4 — Region guesses carry another generation’s attribution | **Resolved.** `recordingLocator` uses `Swappable.LocateFrom` to capture the lookup and its source under the same reader lock. |

New findings:

1. **P2 — Unknown feed state suppresses an independently established expiry alert.**  
   `internal/edge/geoipmirror.go:554–557`: `AlertCode` returns no reading until both pointer and feed state are known, before checking any affirmative reason. On cold boot with a readable expired pointer and malformed or unreadable `feed.json`, polling confirms expiry and removes the database, but reason 3 never reaches the evaluator—even after its 30-minute sustain. An unrelated feed-status failure therefore hides a confirmed database failure indefinitely. Evaluate established unhealthy conditions before withholding an unknown reading; require sufficient knowledge before reporting recovery. Add a cold-start test combining an expired pointer with unreadable feed status and drive it through the evaluator.

Validation was static. Targeted tests could not start because Go’s work directory was read-only; cross-compilation remains unverified.

Verdict: revise.
