Skip to content

PDL-literal agent counts (n=1) and wholesaler passthrough #37

Description

@Hackatro

Context

The simulation should follow the PDL completely instead of inventing population sizes the PDL does not contain.

Gate satisfied: #33 merged as #39 (2026-08-31), #38 merged as #40 (2026-09-09).

Scope revised 2026-09-11 against the merged state of main. Wholesaler behaviour has been removed from this issue — see "Split out" below.

Decision 1 — count = PDL entities, default 1

One PDL entity → one agent, unless the PDL lists more of the same agent. No count field → 1.

SimulatorScenarios.csv and scenario.py currently carry seven invented population columns. None of them appear in the PDL. All collapse:

Roster list Today After
brazil_farms 10 1
argentina_farms 5 1
us_farms 8 1
processors 3 1
feed_manufacturers 3 1
feed_traders 3 1
eu_farmers 10 agents in one pooled list see Decision 2
wholesalers 1 per region unchanged

Consequences, accepted:

  • Total volume drops (Brazil ~10x). Cascades re-baseline; report volume/price deltas rather than byte-for-byte identity.
  • size_sigma_* becomes inert at n=1. Do not delete the code path until confirmed dead.
  • Do not add a sidecar count: as a permanent substitute. If partners later need N agents, the count belongs in the PDL.

Decision 2 — one agent per consumer entity

build_roster groups entity ids by archetype, but does so inconsistently:

  • brazil_farms, argentina_farms, us_farms → archetype producer → three separate roster entries
  • poultry_farms, pig_farms, dairy_farms → archetype consumer → one pooled entry, eu_farmers, carrying all three entity ids

The pooling is invented structure. These are three PDL entities and become three agents, one each, making consumers consistent with the rule producers already follow.

PDL positions differ only slightly, which is not the justification but is worth recording: all three take input from feed_mills and ship to food_retail; poultry_farms and pig_farms additionally carry a feedback edge back to feed_mills that dairy_farms does not, and dependency criticality is high/high/medium respectively.

Knock-on effects this pulls in:

  • Output schema. One recorded eu_farmers series becomes three — _PROPS_BY_ROLE, data_collector.py, result_table_name, the Postgres tick tables.
  • Bundle contract. The exported eu_farmers node currently carries entityIds: [poultry_farms, pig_farms, dairy_farms]; three nodes replace it. The frontend's pooled-node marker split in resolveScene becomes dead code. Marker count is unchanged at 16.
  • Edges. feed_traders->eu_farmers becomes three edges. No conflict with the authored sea routes in refactor(web): derive map topology from the PDL instead of hardcoded … #36, which key only on the four ocean crossings.
  • The frontend gazetteer already holds separate poultry_farms / pig_farms / dairy_farms entries, so placement needs no change.

Keep Decision 1 and Decision 2 as separate commits so a reviewer can tell a volume change from a schema change.

Acceptance

  • No n_{eid} column remains in either scenarios CSV or in scenario.py
  • The shipped PDL yields one agent per modelled entity
  • poultry_farms, pig_farms and dairy_farms are three roster entries with three recorded series
  • python -m provider_simenv.export_bundle succeeds; the four sea-route edge ids from refactor(web): derive map topology from the PDL instead of hardcoded … #36 still appear in bundle.json
  • pytest green with re-baselined fixtures
  • Volume and price deltas reported in the PR description, not asserted byte-for-byte

Split out

  • Wholesaler passthrough economics — own issue. Cardinality is already 1 per region and Make transport roles and routing fully PDL-derived #38 already landed the routing (one outbound lane for ARG/US, Santos + Paranaguá split for Brazil via share_santos_port). The only open question is whether the wholesaler keeps wholesaler_storage_capacity, fixed_costs_wholesaler and margin_wholesaler or becomes a pure passthrough. The 2026-08-24 vault clarification argues for retaining them as legitimate domain parameters. Not decided here, and nothing in this issue touches them.

Out of scope

  • Collapse BRA/ARG/USA producers into one PDL-derived producer archetype #33 producer-identity collapse, sidecar, fertilizer-from-deps, output-schema rename
  • Adding a new PDL count: field without partner agreement
  • food_retail / consumers — PDL entities excluded from the roster as downstream of the modelled chain
  • The us_gulf_ports / Argentina origin-port asymmetry. us_gulf_ports is a PDL entity excluded as a "sea-edge origin, not a handler node"; Argentina has no origin port in the PDL at all. A question for the partners, not a change here.

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