Transfers

Inter-location movement under our own custody · 14 states · every dispatch writes a balanced pair through TRANSIT · 946u in flight right now, worth AED 267.2K, and every one of them is on a named transfer

RT-20260724-HQ319-AJM-2 crossed its 10-day lost horizon at 04:00 today. 46 units worth AED 19.3K were converted from IN_TRANSIT_INTERNAL to LOST_IN_TRANSIT at TRANSIT and drift case D-2026-0729-131 now owns them. Two more transfers are past the 96h critical bucket holding AED 12.3K. Nothing was written off and nothing vanished. Open D-2026-0729-131 →
Transfers is a Phase 4 surface and GATE 3 has held 4 of 7 days. The page is complete and the ledger contract is wired, but posting is disabled until the inbound gate closes. Read-only until 01-08-2026.
SpineBranchesTerminal
rail counts sum to the filtered population · AC-07.9

Lane matrix

Origin rows x destination columns · transfers dispatched in the last 30 days · 192 total · a red outline means the lane produced a variance

30d
HQ_319HQ_325MCCYASCCZAJMBAS
HQ_319 . 4 38 27 19 11 9
HQ_325 6 . 14 9 7 3 2
MCC 2 1 . 6 8 2 1
YAS 1 0 5 . 2 1 0
CCZ 1 0 4 1 . 2 0
AJM 1 0 1 0 1 . 0
BAS 2 0 0 1 0 0 .
hot lane light produced a variance HQ_319 to MCC is 20% of all transfer volume
This replaces v2's hand-drawn UAE map. The map hard-coded seven node positions and six bezier lanes, and it displayed JIMI, DFC and ABD, none of which is an i3 location code.

In-transit age

The 11 open transfers by time since dispatch, segmented by carrier · thresholds are per-lane policy, drawn here at the HQ_319 defaults

2 past 96h
Past the 96h critical bucket 0 1 2 3 0-12h · Aramex · RT-20260729-HQ319-MCC-1 · 128u · AED 48,320 0-12h · DHL · RT-20260729-HQ319-YAS-1 · 212u · AED 71,480 0-12h · manual AWB · RT-20260729-HQ319-CCZ-2 · 84u · AED 21,700 12-24h · Porterex · RT-20260728-HQ319-CCZ-1 · 164u · AED 39,760 · past ETA 1-2d · Aramex · RT-20260728-HQ319-AJM-1 · 96u · AED 22,140 1-2d · self delivery · RT-20260728-MCC-CCZ-1 · 27u of 88 still out · AED 3,950 1-2d · Quiqup · RT-20260727-HQ319-YAS-3 · 72u of 190 still out · AED 11,840 2-4d · SMSA · RT-20260727-HQ319-BAS-1 · 140u · AED 34,900 · stale warning 2-4d · DHL · RT-20260726-HQ325-YAS-1 · 2u residue · AED 820 · short receive 4-10d · Porterex · RT-20260725-HQ319-BAS-2 · 20u residue · AED 9,860 · carton lost Over 10d · Aramex · RT-20260723-HQ319-CCZ-3 · 1u residue · AED 2,410 · 146h old warn 48h crit 96h lost horizon 240h
0-12h12-24h1-2d2-4d4-10dover 10d
Aramex DHL SMSA Porterex Quiqup Self or manual

Dispatch to receipt

Median hours from the OUT pair to the last receive pair, per day · the green band is the 24h lane SLA · this is the number that decides whether stale alerting is signal or noise

30d
Lane SLA band · 18h to 24h target 0h 24h 48h 72h Median dispatch to receipt hours, 30 Jun to 29 Jul 2026 18 Jul · median 55h · four Porterex lanes stalled at the Al Quoz hub over the long weekend 17 Jul · median 50h 13 Jul · median 42h 29 Jul · median 20h · inside the 24h SLA 55h backlog
30 Jun05 Jul11 Jul17 Jul23 Jul29 Jul
The 48h warn threshold is set above the observed p50 plus the worst weekly excursion. A threshold below the real distribution turns the stale queue into wallpaper.

Receipt outcome

Every unit received in 90 days by five-bucket outcome · 41,880 units · each bucket posts a different pair, and one of them posts nothing at all

96.1% intact
Intact 40,246u · 96.1% · TRANSIT out, destination STOCK in Damaged 586u · 1.4% · TRANSIT out, destination QUARANTINE in, raises a damage incident Short 503u · 1.2% · posts nothing, residue stays at TRANSIT, opens a drift case Over 251u · 0.6% · surplus posts nothing, opens a drift case, a transfer cannot create units Wrong SKU 294u · 0.7% · destination QUARANTINE in, spawns a reverse transfer 41.9K units 90d
  • Intact to STOCK40,246 · 96.1%
  • Damaged to QUARANTINE586 · 1.4%
  • Short, residue at TRANSIT503 · 1.2%
  • Over, drift only251 · 0.6%
  • Wrong SKU, reverse294 · 0.7%
v2 rendered these five buckets with no ledger behind them and a note that "totals must equal shipped qty". In i3 the totals do not have to equal anything: short is allowed to be short, and the difference stays visible at TRANSIT.

Age by state

Open count, average age and oldest, for all fourteen states · cached 60s

as of 14:41 GST
Draft3avg 0.4d · max 1d
Requested6avg 0.9d · max 7d
Approved4avg 0.3d · max 1d
Picked2avg 0.2d · max 0d
Packed3avg 0.3d · max 1d
Dispatched4avg 0.2d · max 0d
In transit5avg 2.1d · max 4d
Received2avg 1.1d · max 2d
Reconciled187avg 3.4d cycle
Partial recv2avg 1.8d · max 2d
Short recv3avg 4.4d · max 6d
Lost1converted 04:00
Cancelled5all pre-dispatch
Rejected22 reverses open

SKU mix on transfers

Top 5 SKUs by dispatched units, 23 to 29 Jul · 2,164 units across 46 SKUs · composites never appear here because a composite holds no balance anywhere (L2)

7d
MSR31-07 512 MST-CRM-42-BLK 438 MST-OUD-90-AMB 361 MIN-2159 288 MSR31-04 224 41 others 341

Transfer queue

25 open and recently closed transfers, sorted by risk · in flight is dispatched - received - damaged - rejected, a stored generated column, not a subtraction the page performs

4 variance6 past ETA946u in flight
Reference Lane State Kind Lines Disp Recd In flight Value AED At risk AED Carrier / AWB Age Gate Flags
RT-20260724-HQ319-AJM-2 HQ_319→AJM Lost replenishment 2 46 0 46 19,340 19,340 ARX 8840112Aramex 5d 06h 46/46 D-2026-0729-131 horizon 240h
RT-20260723-HQ319-CCZ-3 HQ_319→CCZ Short recv replenishment 4 132 131 1 39,900 2,410 ARX 8839221Aramex 6d 02h 132/132 D-2026-0726-118
RT-20260725-HQ319-BAS-2 HQ_319→BAS Short recv replenishment 3 120 98 20 28,400 9,860 PTX 220301Porterex 4d 03h 120/120 D-2026-0725-104 2 dmg carton lost
RT-20260727-HQ319-BAS-1 HQ_319→BAS In transit replenishment 4 140 0 140 34,900 34,900 SMS 1208941SMSA 2d 04h 140/140 past ETA
RT-20260727-HQ319-YAS-3 HQ_319→YAS Partial recv replenishment 6 190 118 72 31,240 11,840 QQP 55142Quiqup 2d 06h 190/190 2 receipts
RT-20260726-HQ325-YAS-1 HQ_325→YAS Short recv replenishment 5 176 174 2 44,600 820 DHL 4540188DHL 3d 01h n/a D-2026-0727-121
RT-20260728-HQ319-CCZ-1 HQ_319→CCZ In transit replenishment 5 164 0 164 39,760 39,760 PTX 220418Porterex 1d 06h 164/164 past ETA
RT-20260728-HQ319-AJM-1 HQ_319→AJM In transit replenishment 3 96 0 96 22,140 22,140 ARX 8841903Aramex 1d 09h 96/96 past ETA
RT-20260728-MCC-CCZ-1 MCC→CCZ Partial recv rebalance 4 88 61 27 12,880 3,950 SELF-0728-02Self 1d 02h n/a store to store
RT-20260729-HQ319-YAS-1 HQ_319→YAS Dispatched replenishment 6 212 0 212 71,480 71,480 DHL 4548827193DHL 0d 05h 210/212 2 EPC unmatched
RT-20260729-HQ319-MCC-1 HQ_319→MCC Dispatched replenishment 4 128 0 128 48,320 48,320 ARX 8842197Aramex 0d 03h 128/128 on time
RT-20260729-HQ319-CCZ-2 HQ_319→CCZ Dispatched replenishment 3 84 0 84 21,700 21,700 MAN-0729-0004manual 0d 01h 84/84 carrier down manual AWB
RT-20260729-HQ325-CCZ-3 HQ_325→CCZ Dispatched replenishment 2 58 0 58 14,220 14,220 DHL 4548827204DHL 0d 02h n/a on time
RT-20260728-HQ319-BAS-3 HQ_319→BAS Rejected replenishment 2 60 0 0 14,900 0 SMS 1208774SMSA 1d 04h 60/60 wrong SKU to QUARANTINE
RT-20260729-BAS-HQ319-1 BAS→HQ_319 Approved reverse 2 0 0 0 14,900 0 awaiting pickup 0d 02h n/a reverses BAS-3
RT-20260728-HQ319-MCC-2 HQ_319→MCC Received replenishment 5 152 152 0 44,120 0 SELF-0728-01Self 1d 01h 152/152 residue 0
RT-20260727-HQ325-CCZ-1 HQ_325→CCZ Received replenishment 3 74 74 0 15,600 0 DHL 4540291DHL 2d 00h n/a residue 0
RT-20260729-HQ325-MCC-2 HQ_325→MCC Packed replenishment 3 0 0 0 18,900 0 awaiting pickup 0d 02h pending 3 cartons sealed
RT-20260729-HQ319-MCC-3 HQ_319→MCC Approved replenishment 7 0 0 0 61,900 0 awaiting pickup 0d 04h pending from TRQ-20260729-MCC-1
RT-20260729-HQ319-YAS-2 HQ_319→YAS Picked replenishment 4 0 0 0 27,300 0 not assigned 0d 01h pending 98 of 104 picked
RT-20260729-CCZ-MCC-1 CCZ→MCC Requested rebalance 3 0 0 0 9,260 0 none 0d 06h n/a store to store
RT-20260722-MCC-AJM-1 MCC→AJM Requested fulfillment_inferred 1 0 0 0 1,180 0 none 7d 00h n/a inferred from #MIN10482
RT-20260729-YAS-MCC-1 YAS→MCC Draft rebalance 2 0 0 0 4,180 0 none 0d 00h n/a editable
RT-20260726-HQ319-MCC-4 HQ_319→MCC Reconciled replenishment 6 198 198 0 58,900 0 ARX 8841004Aramex closed 27 Jul 198/198 24 pairs balanced
RT-20260724-HQ325-HQ319-1 HQ_325→HQ_319 Reconciled consolidation 9 406 406 0 88,410 0 SELF-0724-01Self closed 25 Jul 406/406 36 pairs balanced
Showing 25 of 229 · sorted by risk · in flight totals 946u and AED 267,180, which is the entire IN_TRANSIT_INTERNAL balance at TRANSIT Keyboard j k move · x select · Enter open · r receive · c create

Store request queue

What each store has asked HQ for, with the replenishment suggestion that produced it · approving a line places an unposted hold at the source, it does not post a ledger row (R-07.5)

4 urgent11 lines · 6 requests
RequestStoreSKU On hand Available Cover (blank = no velocity) HQ_319 avail Suggested Requested RulePriorityAgeDecide
TRQ-20260729-MCC-1MCCMSR31-07421.46124848zero coverurgent4h
TRQ-20260729-MCC-1MCCMST-CRM-42-BLK11113.13883636below minurgent4h
TRQ-20260729-MCC-1MCCMST-OUD-90-AMB762.82412430below minnormal4h
TRQ-20260729-YAS-1YASMIN-2159000.01843240stockouturgent7h
TRQ-20260729-YAS-1YASMSR31-0418186.22971212lane balancenormal7h
TRQ-20260728-CCZ-1CCZMST-CRM-42-BLK331.13883030zero coverurgent1d 3h
TRQ-20260728-CCZ-1CCZMIN-4402-GLD22.63.6manualnormal1d 3h
TRQ-20260728-AJM-1AJMMSR31-07664.46121818below minnormal1d 6h
TRQ-20260728-AJM-1AJMMST-OUD-90-AMB98.241.12manuallow1d 6h
TRQ-20260727-BAS-1BASMIN-2159110.61842424zero coverurgent2d 1h
TRQ-20260727-BAS-1BASMSR31-04442.22971616below minnormal2d 1h
Two lines show a blank cover figure. Per L9 that is a real answer, not 999: MIN-4402-GLD at CCZ and MST-OUD-90-AMB at AJM have no computable velocity in the window, so they sort last and no suggestion is offered. A suggestion is never fabricated from a missing denominator.

Ledger pairs

Every row this module writes, shown in the two halves it was written as · RT-20260728-MCC-CCZ-1, a partial receive in progress

all pairs sum to zero
dispatchline 1 · MSR31-07 · 40upair 7f2a-9c1bsum 0 ok
outMCCSTOCK-40bal 172counterpart TRANSITtransfer:RT-20260728-MCC-CCZ-1:1:dispatch:out
inTRANSITIN_TRANSIT_INTERNAL+40bal 40counterpart MCCtransfer:RT-20260728-MCC-CCZ-1:1:dispatch:in
receive 1line 1 · MSR31-07 · 28u intactpair b104-33eesum 0 ok
outTRANSITIN_TRANSIT_INTERNAL-28bal 12counterpart CCZtransfer:RT-20260728-MCC-CCZ-1:1:receive:1:out
inCCZSTOCK+28bal 61counterpart TRANSITtransfer:RT-20260728-MCC-CCZ-1:1:receive:1:in
receive 1 · damagedline 3 · MST-OUD-90-AMB · 2upair c8d0-4471sum 0 ok
outTRANSITIN_TRANSIT_INTERNAL-2bal 6counterpart CCZtransfer:RT-20260728-MCC-CCZ-1:3:receive:1:out
inCCZQUARANTINE+2bal 2counterpart TRANSITtransfer:RT-20260728-MCC-CCZ-1:3:receive:1:in
not yet posted27u still at TRANSIT across lines 1, 2 and 4 · second receipt expected todayresidue 27
This is the whole point of the module. Under the v2 and i2 contract the destination would already have been credited with all 88 units on the strength of a courier callback, and the 27 unseen units would be indistinguishable from stock on a shelf at CCZ. Here they are one number, at one virtual location, attached to one transfer, and an hourly job asserts that number against the balance cache.
4 pairs shown of 24 for this transfer · every pair carries a movement_pair_id and both halves were written in one transaction Full hash-chained trail →

The in-transit invariant

For any transfer, the units that left the source are, at every instant, in exactly one of three places: counted at the destination, sitting at TRANSIT, or named on a drift case. There is no fourth option and there is no moment where the number is nowhere.

-- AC-07.1a  runs hourly, must return zero rows
WITH legs AS (
  SELECT p.transfer_id, t.state,
    SUM(p.quantity_delta) FILTER (WHERE p.location_id = t.from_location_id) AS out_at_source,
    SUM(p.quantity_delta) FILTER (WHERE p.location_id = t.to_location_id)   AS in_at_dest,
    SUM(p.quantity_delta) FILTER (WHERE p.location_id = transit_id())    AS at_transit
  FROM transfer_postings p JOIN transfers t ON t.id = p.transfer_id
  GROUP BY 1, 2, t.from_location_id, t.to_location_id)
SELECT * FROM legs
WHERE COALESCE(out_at_source,0) + COALESCE(in_at_dest,0) + COALESCE(at_transit,0) <> 0
   OR (state = 'reconciled' AND COALESCE(at_transit,0) <> 0);

Two more checks run every 15 minutes: every movement_pair_id has exactly two legs summing to zero, and no ledger row with a transfer_ source type is missing from the pair registry. A violation raises P1 inside the hour it happens. INV1 accumulated 1,205 cross-location orders because a single ledger row was allowed to change a location and nothing ever asked whether it balanced.

Open drift queue → Sweep history → Alert rules →

Why in flight lives at TRANSIT

Rejected
At the source. The source would then show stock it does not have on a shelf.
Rejected
At the destination. This is what INV1 does today, and it is why an MCC shelf count can never reconcile against MCC's balance while a truck is on the road.
Chosen
At TRANSIT, stock type IN_TRANSIT_INTERNAL, with counterpart_location_id on every row so the destination is never lost.
Also here
LOST_IN_TRANSIT, so loss is a stock-type conversion at one location, not a teleport.
Not here
IN_TRANSIT_CUSTOMER. Using it for internal replenishment, as v2 and the i2 PRD both do, inflates the customer-risk measure by the entire replenishment programme.
Module 04 owns the TRANSIT location. Module 02 owns the stock-type flags. This module owns what passes through and how long it is allowed to stay.

No transfers yet.

The moment stock moves between two locations, i3 writes a balanced pair through TRANSIT: one row out of the source, one row in at TRANSIT, then the mirror pair when the destination counts what arrived. Nothing here means nothing has moved.

Set up lanes Import from CSV
State: reconciled Origin: BAS Carrier: Quiqup

No transfers match.

BAS has never shipped on Quiqup. Drop the carrier filter to see the two reverse transfers BAS has raised, or widen the state filter to include the open reverse.

The transfer service did not respond. Posting actions are disabled. The last known in-flight figure was 946u at 14:22 GST and is now 19 minutes old, so it is not shown as a KPI.

Could not load transfers.

A stale number here would be worse than no number, because the whole page is a claim about where stock is right now. Nothing is rendered from cache.

Error id trf-9a11c4 · 29-07-2026 14:41:07 GST
Service health
Signed in as viewer. Everything on this page is visible. Approve, dispatch, receive, reject and declare-lost are absent from the page rather than greyed out, and their endpoints return 403 regardless of what is rendered (AC-07.10).

Read-only view.

Approval needs role >= manager plus the transfers.approve feature flag plus the location in your rota-effective set. Personas are derived at login, never granted (L11).

Who can do whatRequest access

Transfer posting is paused for the ledger rebuild.

The balance cache is being verified against balance_after for every key. Reads are live, dispatch and receive are queued and will drain in order with their idempotency keys intact. Estimated finish 15:10 GST.

Job statusNotify me

Transfers is complete but its gate has not held.

i3 is phase-gated by design. Transfers is Phase 4 and cannot post until GATE 3 has held for seven consecutive days: every GRN receipt posting inside 5 minutes and PO expected versus received reconciling. It has held four. This is not an outage and it is not a bug.

Gate status boardGATE 3 detailWhat a gate is

Connected to

Transfer detail → Locations and lanes → HQ_319 detail → Cartons and bins → Live SKU grid → SKU detail → Stock health → Drift → Drift case → RFID gates → Unit events → Mobile scanner → Shipments → ops2 events → IWMS events → GRN and QC → Damages → Return to supplier → Stock count → Approvals → Alert rules → Audit log → Reports →