fix(simulation): address PR #122 review — determinism, correctness, labeling
- HashMap → BTreeMap throughout econ-sim for deterministic iteration (D-010) - Fix cost_factor: multiplicative gate×zone instead of additive (trade.rs) - Extract derive_seed to shared prng.rs, consolidate FNV-1a implementation - Rename run_shock_test → run_no_explosion_check (not D-179 Test 3) - Deduplicate cross-zone FX rate collection in Test 4 - Replace ORDER BY RANDOM() with deterministic ordering + ChaCha8Rng - Make commodity coverage failure a hard error consistent with D-175 - Fix gap-fill off-by-one (4 corps → 3 when coverage = 0) - Correct test report: EconEvent exists, location_type is body/station All four D-179 stability tests still pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
//! Trade-layer archetype effects (corp-level bid/ask) are deferred to a
|
||||
//! future sprint when the event port (D-180) and IPC bridge are in place.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// EconEvent — D-180 event port stub (#809)
|
||||
@@ -49,8 +49,8 @@ pub enum EventEffect {
|
||||
#[allow(dead_code)]
|
||||
pub enum EventVisibility {
|
||||
Global,
|
||||
Proximate(u32), // hops
|
||||
Disclosed(Vec<String>), // specific node IDs
|
||||
Proximate(u32), // hops
|
||||
Disclosed(Vec<String>), // specific node IDs
|
||||
Hidden,
|
||||
}
|
||||
|
||||
@@ -107,13 +107,27 @@ impl Archetype {
|
||||
/// Falls back to `Producer` (the most neutral, maximises output).
|
||||
pub fn infer_from_specialization(spec: &str) -> Self {
|
||||
let s = spec.to_lowercase();
|
||||
if s.contains("freight") || s.contains("logistics") || s.contains("hauler") || s.contains("cargo") {
|
||||
if s.contains("freight")
|
||||
|| s.contains("logistics")
|
||||
|| s.contains("hauler")
|
||||
|| s.contains("cargo")
|
||||
{
|
||||
Archetype::Distributor
|
||||
} else if s.contains("arbitr") || s.contains("trading company") || s.contains("brokerage") || s.contains("intermediar") {
|
||||
} else if s.contains("arbitr")
|
||||
|| s.contains("trading company")
|
||||
|| s.contains("brokerage")
|
||||
|| s.contains("intermediar")
|
||||
{
|
||||
Archetype::Intermediary
|
||||
} else if s.contains("cooperative") || s.contains("mutu") || s.contains("negociant") {
|
||||
Archetype::Cooperative
|
||||
} else if s.contains("whisky") || s.contains("wine") || s.contains("lager") || s.contains("precision") || s.contains("bespoke") || s.contains("longevity") {
|
||||
} else if s.contains("whisky")
|
||||
|| s.contains("wine")
|
||||
|| s.contains("lager")
|
||||
|| s.contains("precision")
|
||||
|| s.contains("bespoke")
|
||||
|| s.contains("longevity")
|
||||
{
|
||||
Archetype::Specialist
|
||||
} else if s.contains("infrastructure") && (s.contains("gate") || s.contains("span")) {
|
||||
// Gate Corp maintains infrastructure monopoly
|
||||
@@ -193,7 +207,7 @@ pub struct ArchetypeParams {
|
||||
/// `corp_data`: Vec of (corp_id, behavioral_archetype_opt, specialization_opt)
|
||||
pub fn build_archetype_map(
|
||||
corp_data: Vec<(String, Option<String>, Option<String>)>,
|
||||
) -> HashMap<String, Archetype> {
|
||||
) -> BTreeMap<String, Archetype> {
|
||||
corp_data
|
||||
.into_iter()
|
||||
.map(|(corp_id, archetype_str, specialization)| {
|
||||
|
||||
Reference in New Issue
Block a user