Platform GeoIP for apps (#241): bucket-mirrored database with hot swap on every edge; X-Carlos-Geo-* headers set by the ingress edge and carried across hops and tunnels; analytics countries with attribution; carlos system geoip publish/status/off; auto-update feed (DB-IP Lite default, GeoLite2 or paid MaxMind GeoIP2); geoip box alert; console follower, GET /api/cli/apps/{a}/{app}/geo and carlos geo; untrusted .mmdb verified only in a killable, memory-capped child. Spec rev 13 (Astra-accepted), 13 Astra code-review rounds.
Squashed from geoip-for-apps into main.
README.md+4 −0analytics_cmd.go+3 −0apimode.go+2 −0cmd/console/main.go+123 −3cmd/console/main_test.go+6 −0cmd/console/region_test.go+51 −0docs/site/cli.md+101 −0docs/superpowers/plans/2026-10-06-platform-geoip-FACTS.md+60 −0docs/superpowers/plans/2026-10-06-platform-geoip-plan1.md+4210 −0docs/superpowers/plans/2026-10-07-platform-geoip-plan2.md+242 −0docs/superpowers/plans/CODEX-FINDINGS-GEOIP-PLAN1-R1.md+45 −0docs/superpowers/plans/CODEX-REVIEW-BRIEF-GEOIP-CODE1.md+47 −0docs/superpowers/plans/CODEX-REVIEW-BRIEF-GEOIP-PLAN1.md+39 −0docs/superpowers/specs/2026-10-06-platform-geoip-design.md+1482 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R1.md+45 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R10.md+30 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R11.md+31 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R12.md+28 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R2.md+46 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R3.md+43 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R4.md+24 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R5.md+20 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R6.md+27 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R7.md+41 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R8.md+37 −0docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R9.md+34 −0docs/superpowers/specs/CODEX-REVIEW-BRIEF-GEOIP.md+75 −0geo_cmd.go+100 −0geo_cmd_test.go+35 −0infra/modules/deployment-buckets/main.tf+24 −0internal/analytics/countries_test.go+99 −0internal/analytics/day.go+63 −4internal/analytics/meter.go+9 −1internal/analytics/read.go+6 −0internal/console/alertwatch.go+55 −4internal/console/alertwatch_test.go+33 −0internal/console/analyticsview.go+44 −0internal/console/apianalytics.go+43 −1internal/console/apianalytics_geo_test.go+26 −0internal/console/apianalytics_test.go+43 −0internal/console/apigeo.go+62 −0internal/console/apigeo_test.go+58 −0internal/console/apisystemgeoip.go+389 −0internal/console/apisystemgeoip_test.go+384 −0internal/console/apisystemupdate.go+43 −2internal/console/authcli.go+8 −0internal/console/geoipfeed.go+399 −0internal/console/geoipfeed_test.go+407 −0internal/console/geoipfollower.go+108 −0internal/console/geoipfollower_test.go+147 −0internal/console/geoippublish.go+421 −0internal/console/geoippublish_test.go+597 −0internal/console/geoipverify.go+148 −0internal/console/geoipverify_linux.go+14 −0internal/console/geoipverify_main_test.go+28 −0internal/console/geoipverify_other.go+6 −0internal/console/regionpicker.go+40 −4internal/console/server.go+70 −2internal/console/svcroutes_test.go+14 −2internal/console/templates/app_analytics.html+3 −0internal/console/templates/app_new.html+1 −1internal/edge/analytics.go+9 −1internal/edge/backhaul_e2e_test.go+10 −3internal/edge/edge.go+57 −0internal/edge/geoipheaders.go+59 −0internal/edge/geoipheaders_test.go+427 −0internal/edge/geoipmirror.go+682 −0internal/edge/geoipmirror_test.go+595 −0internal/edge/tunnel_geo_e2e_test.go+172 −0internal/fleetapi/fleetapi.go+5 −0internal/geo/mmdb.go+240 −25internal/geo/mmdb_test.go+155 −0internal/geo/pathological_test.go+97 −0internal/geo/swappable.go+88 −0internal/geo/swappable_test.go+108 −0internal/geo/testdata/README+13 −1internal/geo/testdata/pathological-bigmap.mmdbbinaryinternal/geo/testdata/pathological-dag.mmdbbinaryinternal/geo/testdata/pathological-empty-dag.mmdbbinaryinternal/geo/testdata/pathological-metadata.mmdbbinaryinternal/geoip/answer.go+190 −0internal/geoip/answer_test.go+116 −0internal/geoip/archive.go+71 −0internal/geoip/archive_test.go+130 −0internal/geoip/feed.go+83 −0internal/geoip/pointer.go+140 −0internal/geoip/pointer_test.go+71 −0internal/host/agent.go+46 −0internal/host/agent_geoip_test.go+21 −0internal/host/alertsink.go+21 −0internal/host/alertsink_geoip_test.go+26 −0internal/host/metrics_loop.go+1 −0internal/metrics/alert.go+23 −0internal/metrics/alert_test.go+48 −0internal/release/putfrom_test.go+72 −0internal/release/store.go+143 −0internal/status/snapshot.go+17 −2internal/status/snapshot_test.go+17 −0internal/tunnelclient/mark_test.go+20 −0internal/tunnelclient/tunnelclient.go+27 −1main.go+3 −0system.go+12 −1system_geoip.go+293 −0system_geoip_test.go+145 −0
CI passed — run details
README.mdLoading diff…
analytics_cmd.goLoading diff…
apimode.goLoading diff…
cmd/console/main.goLoading diff…
cmd/console/main_test.goLoading diff…
cmd/console/region_test.goLoading diff…
docs/site/cli.mdLoading diff…
docs/superpowers/plans/2026-10-06-platform-geoip-FACTS.mdLoading diff…
docs/superpowers/plans/2026-10-06-platform-geoip-plan1.mdLoading diff…
docs/superpowers/plans/2026-10-07-platform-geoip-plan2.mdLoading diff…
docs/superpowers/plans/CODEX-FINDINGS-GEOIP-PLAN1-R1.mdLoading diff…
docs/superpowers/plans/CODEX-REVIEW-BRIEF-GEOIP-CODE1.mdLoading diff…
docs/superpowers/plans/CODEX-REVIEW-BRIEF-GEOIP-PLAN1.mdLoading diff…
docs/superpowers/specs/2026-10-06-platform-geoip-design.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R1.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R10.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R11.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R12.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R2.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R3.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R4.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R5.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R6.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R7.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R8.mdLoading diff…
docs/superpowers/specs/CODEX-FINDINGS-GEOIP-R9.mdLoading diff…
docs/superpowers/specs/CODEX-REVIEW-BRIEF-GEOIP.mdLoading diff…
geo_cmd.goLoading diff…
geo_cmd_test.goLoading diff…
infra/modules/deployment-buckets/main.tfLoading diff…
internal/analytics/countries_test.goLoading diff…
internal/analytics/day.goLoading diff…
internal/analytics/meter.goLoading diff…
internal/analytics/read.goLoading diff…
internal/console/alertwatch.goLoading diff…
internal/console/alertwatch_test.goLoading diff…
internal/console/analyticsview.goLoading diff…
internal/console/apianalytics.goLoading diff…
internal/console/apianalytics_geo_test.goLoading diff…
internal/console/apianalytics_test.goLoading diff…
internal/console/apigeo.goLoading diff…
internal/console/apigeo_test.goLoading diff…
internal/console/apisystemgeoip.goLoading diff…
internal/console/apisystemgeoip_test.goLoading diff…
internal/console/apisystemupdate.goLoading diff…
internal/console/authcli.goLoading diff…
internal/console/geoipfeed.goLoading diff…
internal/console/geoipfeed_test.goLoading diff…
internal/console/geoipfollower.goLoading diff…
internal/console/geoipfollower_test.goLoading diff…
internal/console/geoippublish.goLoading diff…
internal/console/geoippublish_test.goLoading diff…
internal/console/geoipverify.goLoading diff…
internal/console/geoipverify_linux.goLoading diff…
internal/console/geoipverify_main_test.goLoading diff…
internal/console/geoipverify_other.goLoading diff…
internal/console/regionpicker.goLoading diff…
internal/console/server.goLoading diff…
internal/console/svcroutes_test.goLoading diff…
internal/console/templates/app_analytics.htmlLoading diff…
internal/console/templates/app_new.htmlLoading diff…
internal/edge/analytics.goLoading diff…
internal/edge/backhaul_e2e_test.goLoading diff…
internal/edge/edge.goLoading diff…
internal/edge/geoipheaders.goLoading diff…
internal/edge/geoipheaders_test.goLoading diff…
internal/edge/geoipmirror.goLoading diff…
internal/edge/geoipmirror_test.goLoading diff…
internal/edge/tunnel_geo_e2e_test.goLoading diff…
internal/fleetapi/fleetapi.goLoading diff…
internal/geo/mmdb.goLoading diff…
internal/geo/mmdb_test.goLoading diff…
internal/geo/pathological_test.goLoading diff…
internal/geo/swappable.goLoading diff…
internal/geo/swappable_test.goLoading diff…
internal/geo/testdata/READMELoading diff…
internal/geo/testdata/pathological-bigmap.mmdbLoading diff…
internal/geo/testdata/pathological-dag.mmdbLoading diff…
internal/geo/testdata/pathological-empty-dag.mmdbLoading diff…
internal/geo/testdata/pathological-metadata.mmdbLoading diff…
internal/geoip/answer.goLoading diff…
internal/geoip/answer_test.goLoading diff…
internal/geoip/archive.goLoading diff…
internal/geoip/archive_test.goLoading diff…
internal/geoip/feed.goLoading diff…
internal/geoip/pointer.goLoading diff…
internal/geoip/pointer_test.goLoading diff…
internal/host/agent.goLoading diff…
internal/host/agent_geoip_test.goLoading diff…
internal/host/alertsink.goLoading diff…
internal/host/alertsink_geoip_test.goLoading diff…
internal/host/metrics_loop.goLoading diff…
internal/metrics/alert.goLoading diff…
internal/metrics/alert_test.goLoading diff…
internal/release/putfrom_test.goLoading diff…
internal/release/store.goLoading diff…
internal/status/snapshot.goLoading diff…
internal/status/snapshot_test.goLoading diff…
internal/tunnelclient/mark_test.goLoading diff…
internal/tunnelclient/tunnelclient.goLoading diff…
main.goLoading diff…
system.goLoading diff…
system_geoip.goLoading diff…
system_geoip_test.goLoading diff…