Skip to content

Declare geography and sea-crossing classifiaction in data #41

Description

@Hackatro

Problem

topology.py decides sea crossings from a hardcoded dict LOCATION_CONTINENT (6 countries). derive_sea_edges calls a stage "sea" when its endpoints sit on different continents.

Four flaws:

  1. Silent skip. Guard if c_src and c_dst: — an unknown location yields no
    crossing, no error, no lane. A PDL with location: China loses its sea leg silently.
  2. Joins on free text, not entity id. location: Brasilien instead of Brazil
    misses — silently, per (1).
  3. Sidecar entities are invisible to the classifier (they carry no location:).
  4. Continent-difference is a leaky proxy. UK→Netherlands (sea, same continent)
    reads as land; Panama→Colombia (land, two continents) reads as sea.

Geography is also split across three places: this dict, inline lat/lng on sidecar
entities, and the frontend gazetteer.

Solution

A top-level geo: block in the roster sidecar, keyed by entity id — the single home
for geography:

geo:
  brazil_farms:   { continent: South America, lat: -15.8, lng: -47.9, illustrative: true }
  rotterdam_port: { continent: Europe,        lat:  51.9, lng:   4.1, illustrative: true }

Plus a per-stage override for the cases the proxy gets wrong — a dedicated top-level
crossings: block, normalized (undirected) pair key, binary mode:

crossings:
  - stage: [uk_port, rotterdam_port]   # [a,b] == [b,a]
    mode: sea
  - stage: [panama_hub, colombia_hub]
    mode: land

Resolution order: explicit stage mode → both endpoints' geo.continent → raise.

Scope

  • Add geo: to load_roster_sidecar, validated like _entity_placement
    (type / range / finiteness / boolean flag).
  • Make geo: the single home for geography: move inline lat/lng/illustrative
    off the sidecar entities into it, delete the inline path; _entity_placement
    reads from geo:.
  • Rewrite derive_sea_edges to resolve continents from geo: over the merged
    entity list, by id.
  • Add the crossings: override (shape decided above).
  • Fail loudly — an unresolvable crossing raises, naming entity and stage.
    Never a silent skip.
  • Delete LOCATION_CONTINENT.
  • Verify whether replacement_crossings in build_flow_adjacency can be simplified
    once classification reads the merged list. Don't remove on assumption.

Acceptance

  • No geographic literal in topology.py; geography declared in exactly one place.
  • An unresolvable crossing raises (entity + stage named); never yields a missing lane.
  • Shipped and alternate PDLs: unchanged topology, unchanged values.

Notes

  • Sidecar is an additive bridge; fields must survive going upstream to the partner
    schema. continent: South America and mode: sea can; is_sea_side: true cannot.

Rejected

  • Overloading sidecar edges: with a mode field — a PDL stage isn't an edge.
  • A node flag on geo: (is_sea_side:) — repeats the node→edge inference mistake.
  • Deriving continent from coordinates via a geo library — the coords are illustrative.

Out of scope

Frontend gazetteer migration (settled in #33) · #37 cardinality work.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementFor everything that improves an already existing feature.simulation logicFor everything related to the internal simulation logic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions