MEIO V4 Network Rescue and Repair Implementation Plan¶
Status: Implemented (release 1, Aug 2026). This page defines the build sequence, compatibility guarantees, route-classification policy, and validation gates for the MEIO V4 network model. Implementation notes: route roles are stored ONLY on
master.route.network_role(tenant-wide, locked decision — no scenario JSON override); source protection is operationalized as "buffer above the source's own committed requirement (ASL floor, else own demand-over-LT baseline)"; repair-covered demand accrues over the repair cycle via a horizon blend; one-hop rescue only.Target outcome: V3 remains the standard single-path MEIO optimizer. V4 adds explicit multilateral rescue, hierarchical replenishment, and timed repair supply without replacing V3. The existing MEIO zone pass remains available and can wrap either V3 or V4.
Primary constraints:
- The existing single-path V3 model keeps working.
- The existing UI remains substantially unchanged; V4 is controlled primarily by scenario configuration and diagnostics.
- Edge classification must be explicit: initial default is rescue = intra-zone balancing, standard replenishment = inter-zone balancing + repair + procurement/transform replenishment, with route-level override available.
1. Executive Build Decision¶
Do not replace V3. Add V4 as a separate network calculation mode inside the existing MEIO scenario execution surface.
Existing MEIO scenario
|
+-- network_mode = "v3" (default)
| +-- existing hierarchy propagation
| +-- optional existing zone pass
|
+-- network_mode = "v4"
+-- corrected directed topology
+-- explicit lateral rescue
+-- timed repair supply
+-- optional existing zone pass
The same scenario should be able to run in both modes so planners can compare V3 and V4 outputs directly. The first V4 release should be one-hop lateral rescue only.
2. Working Definitions and Decisions¶
2.1 Confirmed product requirements¶
| Requirement | Decision |
|---|---|
| Keep previous model | V3 remains the default and remains byte-compatible when V4 is disabled. |
| Keep previous UI | Existing MEIO pages, results tables, budgets, groups, and scenario editors stay unchanged except for a small network-mode control and optional diagnostics. |
| Add multilateral rescue | V4 is activated by scenario configuration such as network_mode="v4" or enable_multilateral_rescue=true. The exact final key must be one canonical key, not several duplicate toggles. |
| Define transshipment vs standard route | Route classification is an explicit policy with defaults and route-level override. |
| Zone capability | The existing enable_zone_pass remains independent and can wrap V3 or V4. It must not double count V4 rescue benefits. |
| Repair-capable sites | Repair supply is a timed transformation process, not immediate demand reduction. |
2.2 Initial route-classification policy¶
The user-provided initial interpretation is:
This is the recommended default classifier, with one important hardening rule: route type alone is not enough. Classification must use route type, zone membership, direction, eligibility, and optional overrides.
| Route evidence | Default V4 class | Reason |
|---|---|---|
BALANCING, source and destination in same collaborative zone |
LATERAL_RESCUE |
Fast mutual support inside the agreed local pool. |
BALANCING, source and destination in different zones, or either side outside the zone map |
FORWARD_REPLENISHMENT or EMERGENCY_REPLENISHMENT |
Cross-zone balancing is slower and policy-heavy; do not silently treat it as rescue. |
ZONE_BALANCING |
FORWARD_REPLENISHMENT |
Existing semantics define it as inter-zone balancing, not steady-state rescue. |
TRANSFER |
FORWARD_REPLENISHMENT |
Standard directed replenishment unless explicitly marked rescue. |
BUY |
EXTERNAL_REPLENISHMENT |
Procurement from an external source. |
MAKE |
PRODUCTION_REPLENISHMENT |
Transform replenishment. |
RETURN |
RETURN_FLOW |
Bad-stock movement; never direct service stock. |
REPAIR |
REPAIR_PROCESS |
Delayed transformation, yield and capacity constrained. Pool semantics (Aug 2026): facility shared pool — RETURN routes from ANY site replenish it, REPAIR routes distribute good output to (possibly other) demand sites, split by push_quota. Fully traced in MEIO V4 Worked Numbers. |
USE |
USE_CONSUMPTION |
Consumption/degradation flow; not a rescue edge. |
Route with explicit rescue_role |
Explicit role wins | Business owner can correct the default without code changes. |
Recommended precedence:
1. Explicit route override field
2. Scenario route-role map
3. Zone-aware defaults from route type + zone membership
4. Standard replenishment fallback for all forward/procurement/repair paths
There must be no hidden fifth fallback that guesses from site names or geography.
2.3 Route-role override¶
Add a small explicit role marker rather than changing route planning types.
Candidate persistence options:
- Preferred long term: a nullable
rescue_roleornetwork_rolecolumn onmaster.route, constrained to known values. - Scenario-only alternative: a
route_role_overridesJSONB map under the MEIO scenarioparam_overrides. - Hybrid recommended: base default in
master.route, scenario override inparam_overridesfor experiments.
Suggested values:
rescue -- eligible for fast lateral backup
standard -- ordinary replenishment
emergency -- optional premium expedite path
disabled -- present in route table but ignored by V4
Ambiguous configurations must fail validation loudly. For example, a route marked rescue but crossing zones must be rejected or explicitly allowed by allow_cross_zone_rescue=true.
3. Compatibility and Toggle Model¶
3.1 Canonical scenario switch¶
One canonical key should select the network model:
For compatibility during implementation, the loader may recognize a temporary alias:
But one writer must own the canonical value before release. Do not leave two permanent competing toggles.
3.2 Byte-compatibility guarantee¶
When meio_network_mode is absent or "v3":
- no V4 edge CTEs should be used;
- no V4 Rust fields should affect the calculation;
- no V4 fixed-point or scenario logic should run;
- golden fixture output must remain byte-identical.
When meio_network_mode="v4":
- the V4 topology loader runs;
- the V4 Rust batch fields are attached;
- old fields remain present for backward compatibility but must not drive V4 calculations;
- diagnostics record the selected mode, topology version, route-role policy, and edge counts.
3.3 Zone-pass composition¶
The existing zone pass remains controlled by:
Composition matrix:
| network mode | zone pass | Behaviour |
|---|---|---|
| V3 | off | Existing MEIO behaviour. |
| V3 | on | Existing virtual-zone aggregation and pass-2 budget cap. |
| V4 | off | Multilateral network sizing without zone envelopes. |
| V4 | on | Zone pass defines pooled envelopes; V4 rescue consumes remaining free stock through explicit lanes. |
The zone pass is not a rescue implementation. It is a planning envelope. V4 rescue must use stock that remains free after zone constraints and source protection.
4. Planned Architecture¶
4.1 Layered design¶
flowchart TB
P[Scenario config and route-role policy] --> L[Python topology loader]
L --> V3[V3 single-path batch]
L --> V4[V4 network batch]
V4 --> E[Typed directed edges]
E --> R[Rescue engine]
E --> H[Hierarchy engine]
E --> RP[Timed repair processes]
R --> O[Global service objective]
H --> O
RP --> O
O --> G[Existing group targets and budgets]
4.2 Data sources¶
| Data | Source | V4 use |
|---|---|---|
| Routes | master.route |
Base directed edges, timing, costs, route type, coverage. |
| Route roles | route column or scenario overrides | Rescue/standard/emergency classification. |
| Zones | config_zone_parameter |
Intra-zone vs inter-zone classification and zone-pass membership. |
| Capacity | master.capacity, master.route_resource |
Lane and repair throughput constraints. |
| Demand | existing MEIO demand loaders | Direct and indirect demand remain distinct. |
| On hand | existing MEIO loaders | Starting good stock. |
| Return/repair routes | master.route |
Return flow and repair transformation. |
| WIP | route wip_qty initially; detailed WIP later |
Horizon-aware repair output credit. |
| Empirical distributions | existing V3 empirical bootstrap | Demand-over-LT and lead-time uncertainty. |
4.3 Rust wire extension¶
V4 should not overload repl_site_ids. Add explicit records:
struct NetworkEdge {
source_item_id: i64,
source_site_id: i64,
destination_item_id: i64,
destination_site_id: i64,
edge_kind: EdgeKind,
route_id: i64,
mean_lead_time_weeks: f64,
lead_time_stddev_weeks: f64,
capacity_per_week: f64,
coverage_weight: f64,
route_reliability: f64,
priority: i32,
}
struct RepairProcessEdge {
input_item_id: i64,
input_site_id: i64,
facility_site_id: i64,
output_item_id: i64,
output_site_id: i64,
return_lead_time_weeks: f64,
shop_lead_time_weeks: f64,
output_lead_time_weeks: f64,
repair_yield: f64,
capacity_per_week: f64,
current_wip_qty: f64,
}
Keep old JSON fields so old clients and older .pyd consumers fail in a controlled way if versions are mismatched. The extension rebuild is mandatory for any Rust change.
5. V4 Algorithm¶
5.1 Release 1 scope¶
V4 release 1 should implement:
- one-hop rescue only;
- intra-zone balancing rescue by default;
- inter-zone balancing and repair/procurement as standard supply;
- source free-stock calculation;
- quantity-aware rescue useful quantity;
- lane capacity;
- deterministic allocation policy;
- timed repair output as a supply branch;
- existing target groups, budgets, and site caps;
- diagnostics and conservation invariants.
Explicitly excluded from release 1:
- multi-hop rescue;
- automatic reverse edges;
- unrestricted complete-graph rescue;
- repair output pooling across multiple facilities without explicit facility identities;
- correlation/copula calibration;
- common-cause disruption scenarios;
- replacing the existing zone pass.
5.2 Network state¶
For each candidate evaluation, maintain a deterministic network state:
SKU state:
committed_buffer
current_fill_rate
current_wait_time
direct demand
indirect demand
protected_stock
Edge state:
route capacity remaining
route reliability
edge lead time
edge role
Repair state:
expected bad input
WIP by expected completion horizon
repair capacity remaining
expected good output
The state is recalculated from canonical ordering. No HashMap-order float accumulation.
5.3 Source free stock¶
For source SKU j at planning time t:
protected_stock_j =
max(
own_cycle_need_j,
firm_reservations_j,
configured_source_reserve_j
)
free_stock_j = max(
0,
committed_or_on_hand_good_stock_j - protected_stock_j - already_allocated_outbound_j
)
The initial analytic approximation can estimate this from the source's demand-over-LT distribution and configured source-protection quantile. The long-term simulator must track actual units.
5.4 Rescue useful quantity¶
For destination i, source j, shortage quantity q, and service horizon h:
lane_qty_ji = min(q, free_stock_j, lane_capacity_ji)
lane_arrives_ji = P(arrival_time_ji <= h)
route_reliability_ji = configured reliability
allocation_qty_ji = allocation_policy(j, claimants, lane_qty_ji)
useful_qty_ji =
E[lane_qty_ji * lane_arrives_ji * route_reliability_ji]
The service credit is the expected quantity served before the deadline, not the peer fill rate.
5.5 Arrival competition¶
A shortage can receive supply from:
- own stock;
- lateral rescue;
- standard replenishment;
- repair output;
- emergency replenishment.
V4 evaluates the earliest feasible branch by time and quantity:
service_quantity_i(t) =
own_stock_service_i(t)
+ lateral_service_i(t)
+ standard_service_i(t)
+ repair_service_i(t)
+ emergency_service_i(t)
Conservation rules ensure every unit is counted once. The global objective uses total served quantity and service timing, not the sum of independent fill-rate improvements.
5.6 Repair supply¶
A repair-capable site is not a backup location by itself. It becomes useful only when the full process is modelled:
bad item at demand site
-> return transport
-> repair facility queue
-> repair process
-> yield outcome
-> repaired output
-> output distribution
-> good stock at eligible site
Release 1 can use expected weekly completion curves derived from return lead time, shop lead time, WIP quantity, yield, and weekly repair capacity. It must not credit all WIP as immediate stock.
5.7 Objective and marginal value¶
Use a conserved global objective:
where J values served demand, shortage penalties, holding cost, transfer cost, repair cost, and target-group constraints.
The existing TargetDictionary remains the constraint layer. It should not be extended to independently reward every downstream/peer fill-rate change. V4 records candidate-caused service deltas once in the global objective.
6. UI Plan¶
6.1 What stays unchanged¶
- Existing scenario list and editor structure.
- Existing target-group and budget panels.
- Existing result tables and charts.
- Existing zone configuration surface.
- Existing per-segment MEIO parameter sets.
6.2 Minimal UI additions¶
Add one small network-mode control to the MEIO scenario editor, probably under Advanced:
Add one optional compact diagnostics card, hidden unless the mode is V4:
- number of rescue edges;
- number of standard edges;
- number of repair processes;
- lane-capacity-limited edges;
- repair-capacity-limited processes;
- non-converged or rejected edges;
- topology-policy version.
No new result-table columns are required for the first release. Optional diagnostics can be exposed in existing detail drawers or API payloads later.
6.3 API compatibility¶
Existing MEIO results endpoints remain unchanged. Additions should be separate fields or a separate diagnostics endpoint so older UI consumers do not break.
Recommended new payload:
{
"network_mode": "v4",
"topology_policy_version": 1,
"edge_counts": {
"rescue": 12,
"standard": 34,
"repair_process": 3
},
"capacity_limited_edges": 2,
"repair_capacity_limited_processes": 1,
"rescue_served_qty_estimate": 128.5
}
7. Implementation Phases¶
Phase 0: Baseline contract and hierarchy direction¶
Goal: make the existing V3 hierarchy contract explicit and correct before adding V4.
Actions:
- Fix the transfer-dependency orientation in
meio_runner.pyso the loader and Rust recursion agree. - Add a two-node warehouse-to-store regression test.
- Add a reverse-direction negative test: downstream stock does not affect upstream wait unless an explicit reverse/lateral edge exists.
- Run golden fixture in V3 mode and document expected changes.
Exit gate:
- V3 disabled/new mode default is byte-compatible except for the intentionally fixed propagation defect.
- No V4 topology or rescue code runs in V3 mode.
Phase 1: Topology and route-role classifier¶
Goal: build a validated network edge table without changing optimization results yet.
Actions:
- Add route-role metadata and scenario override support.
- Build a Python
network_topologyloader that emits typed directed edges. - Implement zone-aware defaults:
- intra-zone
BALANCING-> rescue; - inter-zone balancing and
ZONE_BALANCING-> standard; TRANSFER,BUY,MAKE-> standard;RETURN/REPAIR-> repair flow edges.- Add topology validation errors for duplicate edges, missing SKU endpoints, invalid roles, and ambiguous cross-zone rescue.
- Persist a diagnostics payload even when V4 is disabled.
Exit gate:
- Topology dump matches expected route counts on synthetic fixtures.
- V3 output remains unchanged.
Phase 2: V4 Rust wire and one-hop rescue¶
Goal: implement the first V4 calculation.
Actions:
- Extend
SkuRecordbatch payload withnetwork_edgesandrepair_processes. - Add deterministic network state structures using ordered maps.
- Implement free-stock, lane-capacity, and useful-quantity calculations.
- Implement one-hop rescue candidate credit in the global objective.
- Keep existing group/budget/site-cap constraints.
- Add unit tests for zero free stock, partial rescue, lane capacity, and source conservation.
Exit gate:
- One-hop synthetic fixtures match hand calculations.
- V3 mode remains byte-identical.
- No multi-hop recursive credit exists.
Phase 3: Timed repair supply¶
Goal: make repair lead time part of the MEIO service model.
Actions:
- Model return, queue, shop, yield, and output distribution stages.
- Convert route-level
RETURN/REPAIRdata into repair process edges. - Use WIP by expected completion horizon instead of immediate
wip_qty * yieldcredit. - Enforce weekly repair capacity.
- Add repair-output allocation policy when one facility feeds multiple sites.
- Prevent double counting between existing net repair logic and V4 repair arrivals.
Exit gate:
- Increasing repair lead time changes service timing and stock decisions.
- Repair capacity limits total output across claimant sites.
- Existing V3 repair behaviour remains unchanged when V4 is off.
Phase 4: Zone integration and double-count prevention¶
Goal: allow zone pass with V3 or V4.
Actions:
- Keep
enable_zone_passindependent frommeio_network_mode. - Define zone pass as envelope/prior, not as an additional rescue benefit.
- Reserve zone constraints before calculating V4 free stock.
- Add tests that run V3+zone, V4, and V4+zone.
- Report zone and rescue contributions separately.
Exit gate:
- V4+zone service gain is less than or equal to independently summed gains when overlap exists.
- No zone row and rescue row claims the same units.
Phase 5: Scenario validation and calibration¶
Goal: prove the analytic V4 approximation against a time-ordered scenario simulator.
Actions:
- Build a common-random-number simulator for demand, lead times, lateral availability, and repair completion.
- Process network events chronologically.
- Compare V4 analytic service estimates to simulation on canonical fixtures.
- Calibrate conservative bounds where analytic assumptions are optimistic.
- Add correlation and common-cause disruption scenarios.
Exit gate:
- V4 is never worse than simulation by more than the configured tolerance on service and stock outcomes.
- Deterministic replay passes with fixed seed.
Phase 6: Multi-hop and policy expansion (later)¶
Goal: extend only after one-hop accounting is stable.
Actions:
- Add time-expanded multi-hop paths.
- Consume time and capacity at every hop.
- Support configurable allocation policies beyond priority-then-proportional.
- Consider correlation-aware rescue availability and disruption scenarios.
- Add route-cost-aware rescue selection if business requires it.
Exit gate:
- Multi-hop cycles cannot double count.
- All paths respect horizon and capacity.
8. Validation Plan¶
8.1 Golden fixtures¶
Use the existing golden harness:
python files/scripts/golden_fixture.py snapshot --db thebicycle --pipeline-id 4 --archive 2026-06-15 --out <baseline>
python files/scripts/golden_fixture.py reset-capacity --db thebicycle --pipeline-id 4 --scenario-id 1
python files/scripts/golden_fixture.py run --db thebicycle --schema scenario --pipeline-id 4 --steps indirect-demand,netting,meio,supply,allocation --env MEIO_MC_SEED=42
python files/scripts/golden_fixture.py snapshot --db thebicycle --pipeline-id 4 --archive 2026-06-15 --out <after>
python files/scripts/golden_fixture.py diff <baseline> <after>
Required checks:
- V3 default run: byte-identical except Phase 0's documented propagation fix.
- V4 enabled run: changed rows trace to declared V4 diagnostics.
- Zone pass on/off matrices behave independently.
8.2 Unit tests¶
Add Rust and Python tests for:
| Area | Test |
|---|---|
| Hierarchy | Warehouse affects store; store does not affect warehouse without a reverse edge. |
| Role classification | Intra-zone balancing becomes rescue; inter-zone balancing remains standard. |
| Override | Explicit route role wins over defaults. |
| Free stock | High fill rate with zero free stock gives zero rescue. |
| Capacity | Claimants cannot exceed source stock or lane capacity. |
| Partial rescue | Useful quantity is credited, not binary all-or-nothing rescue. |
| Repair | Longer repair lead time delays service; yield applies once; capacity constrains output. |
| Zone | Zone envelope and rescue do not double count. |
| Cycles | L1-L2-L3 cannot recursively credit one unit. |
| Determinism | Repeated runs produce byte-identical outputs. |
8.3 Synthetic end-to-end fixtures¶
Create these fixtures before production rollout:
- V3 hierarchy only.
- V4 two-store mutual backup.
- V4 intra-zone balancing rescue.
- V4 inter-zone balancing standard replenishment.
- V4 central repair facility serving two stores.
- V4 repair capacity bottleneck.
- V4 zone pass plus rescue.
- V4 cross-zone rescue explicitly enabled and explicitly disabled.
- V4 common-cause lane outage.
- V4 BOM component rescue feeding an assembly.
9. Deliverables by File Area¶
| Area | Planned changes |
|---|---|
files/meio_runner.py |
Network-mode parsing, topology loader, edge attachment, repair process loading, diagnostics, V3/V4 dispatch. |
files/meio_zone_pass.py |
Zone/V4 composition guards and separate contribution accounting. |
files/MEIO_v3/src/sku.rs |
New wire records for edges and repair processes. |
files/MEIO_v3/src/config.rs |
Canonical V4 config and diagnostics settings. |
files/MEIO_v3/src/marginal.rs |
V4 global objective evaluation and one-hop service accounting. |
files/MEIO_v3/src/optimizer.rs |
Recompute affected network state after commits; no silent stale rescue credits. |
files/MEIO_v3/src/target.rs |
Constraint integration without double-counted service benefit. |
files/api/main.py or scenario routes |
Scenario network-mode payload validation and optional diagnostics endpoint. |
files/frontend/src/components/MeioScenarios.jsx |
Minimal network-mode control and diagnostics display. |
files/tests/ |
Python unit and integration tests. |
| Rust tests | One-hop, capacity, repair, conservation, determinism. |
| Docs | User configuration and algorithm reference updates. |
10. Rollback and Safety Controls¶
10.1 Feature flags¶
meio_network_mode="v3"is the rollback switch.- V4 is off by default.
- Zone pass remains off unless explicitly enabled.
- Cross-zone rescue is off unless explicitly enabled.
10.2 Fail-loud validation¶
The runner must abort V4 with a clear error when:
- a rescue edge has an unknown source or destination SKU;
- a route role is invalid;
- a rescue route crosses zones without
allow_cross_zone_rescue=true; - duplicate route-role overrides conflict;
- a repair process lacks facility identity or yield;
- capacity is negative;
- rescue state fails to converge in a later iterative release;
- a V4-required field is missing from the Rust payload.
10.3 Extension compatibility¶
Any Rust wire change requires rebuilding and copying the extension to both load paths described in AGENTS.md. The Python layer should verify the extension exposes the V4 entry points and abort clearly if a stale .pyd is loaded.
11. Open Decisions to Confirm Before Coding¶
These decisions should be locked before implementation starts:
- Canonical mode key: use
meio_network_mode="v3|v4"as the single switch. - Route-role storage: choose route column, scenario JSON override, or hybrid. Recommendation: hybrid.
- Intra-zone definition: use
config_zone_parametermembership as the only zone source. - Cross-zone rescue: default disabled; explicit scenario opt-in only.
- Allocation policy: initial
priority_then_proportional, with criticality first and proportional split for equal priority. - Source protection: initial protected-stock quantile configuration, default 0.95.
- Repair netting: V4 must disable legacy immediate repair netting for SKUs in scope, to prevent double counting.
- Zone interaction: zone pass is a cap/envelope; V4 rescue consumes free stock after that envelope.
- Diagnostics surface: scenario editor diagnostics card only in V4 mode.
- Release 1 scope: no multi-hop rescue.
12. Immediate Next Actions¶
- Confirm the ten open decisions above.
- Implement Phase 0 only: hierarchy orientation and regression fixtures.
- Produce a golden-fixture comparison for V3 default.
- Add the route-role classifier and emit a topology diagnostics dump without changing calculations.
- Review one real tenant network (gps_1 or thebicycle) and list which routes the classifier marks as rescue, standard, and repair.
- Only then start the V4 Rust wire and one-hop rescue implementation.
This sequence keeps V3 stable, avoids a broad UI rewrite, makes transshipment classification explicit, and introduces V4 as a controlled calculation layer that can later coexist with the zone pass.