You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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.
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.csvandscenario.pycurrently carry seven invented population columns. None of them appear in the PDL. All collapse:brazil_farmsargentina_farmsus_farmsprocessorsfeed_manufacturersfeed_traderseu_farmersConsequences, accepted:
size_sigma_*becomes inert at n=1. Do not delete the code path until confirmed dead.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_rostergroups entity ids by archetype, but does so inconsistently:brazil_farms,argentina_farms,us_farms→ archetypeproducer→ three separate roster entriespoultry_farms,pig_farms,dairy_farms→ archetypeconsumer→ one pooled entry,eu_farmers, carrying all three entity idsThe 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_millsand ship tofood_retail;poultry_farmsandpig_farmsadditionally carry a feedback edge back tofeed_millsthatdairy_farmsdoes not, and dependency criticality ishigh/high/mediumrespectively.Knock-on effects this pulls in:
eu_farmersseries becomes three —_PROPS_BY_ROLE,data_collector.py,result_table_name, the Postgres tick tables.eu_farmersnode currently carriesentityIds: [poultry_farms, pig_farms, dairy_farms]; three nodes replace it. The frontend's pooled-node marker split inresolveScenebecomes dead code. Marker count is unchanged at 16.feed_traders->eu_farmersbecomes 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.poultry_farms/pig_farms/dairy_farmsentries, 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
n_{eid}column remains in either scenarios CSV or inscenario.pypoultry_farms,pig_farmsanddairy_farmsare three roster entries with three recorded seriespython -m provider_simenv.export_bundlesucceeds; the four sea-route edge ids from refactor(web): derive map topology from the PDL instead of hardcoded … #36 still appear inbundle.jsonpytestgreen with re-baselined fixturesSplit out
share_santos_port). The only open question is whether the wholesaler keepswholesaler_storage_capacity,fixed_costs_wholesalerandmargin_wholesaleror 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
count:field without partner agreementfood_retail/consumers— PDL entities excluded from the roster as downstream of the modelled chainus_gulf_ports/ Argentina origin-port asymmetry.us_gulf_portsis 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.