carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1| Previous finding | Disposition at `a10120de` |
2|---|---|
3| R1-1 — Readiness without established database state | **Resolved.** Unknown pointers block readiness; off and expired pointers require empty mirrors (`internal/console/apisystemgeoip.go:140,345,366`). |
4| R1-2 — `off` waits beyond caller timeout | **Resolved.** `Off` uses `TryLock`; concurrent publication returns 409 (`internal/console/geoippublish.go:343`). |
5| R1-3 — Unbounded console pointer reads | **Resolved.** Pointer reads remain streamed and capped, retaining the ETag (`internal/console/geoippublish.go:163`). |
6| R1-4 — Recovery generation deleted after failed synchronization | **Partly resolved; P2 remains.** A → B → C now retains every potentially recoverable generation. However, republishing retained A while directory synchronization still fails can reach `internal/edge/geoipmirror.go:429–432`: a failure writing `current` unconditionally deletes A. A crash can then restore durable `current=A` without its database. Protect retained generations on installation-error paths too, and test A → B → A with both directory-sync sites failing and the final `current` write failing. |
7| R1-5 — Rejected-upload test does not establish zero reads | **Resolved at the reservation boundary.** The panicking-reader test detects reads before slot reservation (`internal/console/geoippublish_test.go:375`). |
8| R1-6 — Countries overflow ordering | **Resolved.** `_other` survives sorting and is relabelled during rendering (`internal/console/analyticsview.go:415,425`). |
9| R2-1 — Feed status writes bypass the read cap | **Resolved.** The writer uses the ETag from the initial capped read (`internal/console/geoipfeed.go:146,161`). |
10| R2-2 — Timed-out checks never persist failures | **Resolved.** Status persistence has a separate bounded context detached from the expired check (`internal/console/geoipfeed.go:131`). |
11| R2-3 — Unreadable feed status clears an alert | **Resolved in the mirror.** Read and parse failures preserve the previous state; confirmed deletion clears it (`internal/edge/geoipmirror.go:497`). |
12| R2-4 — Unusable directory prevents “not loaded” alert | **Resolved.** Control-plane state is retained before directory preparation (`internal/edge/geoipmirror.go:245,315`). |
13| R2-5 — Published alert reasons never change while unhealthy | **Resolved.** A changed reason updates `Value` and emits an event for publication without restarting sustain (`internal/metrics/alert.go:269`). |
14
15New findings:
16
171. **P2 — The console follower can keep serving an expired database.**
18 `internal/console/geoipfollower.go:48–61`: expiry is checked against the newly read `current`, not the reader already loaded. Load GeoLite2 A, then make `current` unreadable—or have it select an unopenable replacement B. Once A passes its 30-day limit, every tick still returns while retaining A, so `/geo` and region guesses continue using expired data. Check the loaded reader’s own source/build on every tick, independently of local-state errors, and validate a candidate’s own metadata before swapping. Add expiry tests covering both failure paths.
19
202. **P2 — A transient status-read failure erases the feed’s failure history.**
21 `internal/console/geoipfeed.go:146–168`: a read error becomes an empty status and empty ETag. If the subsequent create-only write conflicts, `writeStatus` deletes the existing object and replaces it. With seven failures already recorded, one transient read failure followed by another failed download therefore replaces the count with one. The mirror reads a valid non-failing status and clears the alert despite no successful check. Distinguish confirmed absence from read failure; retry a capped read before updating, or preserve the existing object when its history is unknown. Test a failed status read followed by successful writes against an existing failing status.
22
23Validation was static. Targeted tests could not start because Go’s work directory was read-only; cross-compilation remains unverified.
24
25Verdict: revise.
26