The disposition ladder
On confirm the quantity always moves into the holding pen. Nothing is decided at intake, because the person who finds a broken thing is rarely the person who decides what happens to it.
Every unit that stopped being sellable without being sold · four discovery contexts, one register · the 48h matching rule that stops one physical damage becoming two write-offs · the DISPLAY_DAMAGED / QUARANTINE / WRITTEN_OFF ladder · and the Finance gate that makes a write-off a ledger event with an approver attached rather than an edit
Where the damage was found, which is not the same axis as which system told us. v2 welded a stock type, a discovery context and a reporting system into one five-tab strip; i3 keeps them apart because RFID reports damage from all four contexts and ops2 reports from three.
On confirm the quantity always moves into the holding pen. Nothing is decided at intake, because the person who finds a broken thing is rarely the person who decides what happens to it.
A grade is an assessment event, not a typed field. The current grade is a projection of the latest assessment, so re-grading leaves a trail. The grade then constrains which dispositions are legal: a total loss cannot be recovered to stock, and the API refuses it rather than the UI hiding it.
The rule the v2 PRD promised and the shipped i2 schema could not implement: matching on (unit_id OR carton_id) AND 48h against a damages table that has neither column. Here the key is generated and indexed, the matcher runs every 5 minutes, and its hit rate is published so a silent zero is distinguishable from a dead job.
| Reference | State | Context | Src | SKU / identity | Location | Qty | Category | Severity | Disposition | Value AED | Recov. | Age | Evid. | Match |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DMG-2026-0729-014 | confirmed | store | rfid | MIN-VAS-022 · …4021 8F3C | MCC · shelf-A3 | 1 | surface_crack | minor | markdown 30% | 180 | 126 | 5h | +1 | merged 1 |
| DMG-2026-0729-013 | reported | customer_return | csd | MST-CRM-42-BLK | HQ_319 · RETURNS-IN | 1 | stitching_fail | major | not set | 1,520 | 0 | 3h | - | |
| DMG-2026-0729-011 | confirmed | supplier_arrival | iwms | JRY01 · MC-4471 | HQ_319 · QC-bay | 6 | impact_break | major | rts_claim | 9,300 | 0 | 14h | +5 | 1 pending |
| DMG-2026-0729-009 | merged | store | ops2 | MIN-VAS-022 | MCC · shelf-A3 | 0 | surface_crack | minor | into …014 | 0 | 0 | closed | loser · frozen | |
| DMG-2026-0729-008 | reported | supplier_arrival | grn | PP02 · MC-4468 | HQ_319 · RECEIVING | 4 | seal_broken | minor | not set | 1,596 | 0 | 9h | 1 pending | |
| DMG-2026-0729-004 | pending approval | warehouse | ops2 | CDW01 · …9917 B2E1 | HQ_319 · A3-04 | 1 | mechanism_fail | total loss | write_off · tier 1 | 1,400 | 0 | 54h | +2 | - |
| DMG-2026-0728-041 | confirmed | supplier_arrival | iwms | JRY01 · MC-4471 | HQ_319 · QC-bay | 2 | stone_loose | major | rts_claim | 3,100 | 3,100 | 28h | +3 | candidate |
| DMG-2026-0728-037 | triaged | store | ops2 | MST-CRM-42-BLK | MCC · shelf-A3 | 1 | surface_scuff | cosmetic | recover_to_stock | 1,520 | 1,520 | 33h | rejected | |
| DMG-2026-0728-030 | triaged | store | rfid | MST-CRM-42-BLK · …7A18 C044 | MCC · shelf-A3 | 1 | surface_scuff | minor | markdown 25% | 1,520 | 1,140 | 41h | rejected | |
| DMG-2026-0728-021 | pending approval | customer_return | csd | LLW-BAG-047 | HQ_319 · RETURNS-IN | 1 | contamination | total loss | write_off · tier 2 | 2,890 | 0 | 46h | +4 | - |
| DMG-2026-0728-016 | confirmed | warehouse | iwms | FYN01 · MC-4452 | HQ_325 | 8 | packaging_crush | minor | repair | 3,360 | 0 | 36h | +6 | - |
| DMG-2026-0727-022 | resolved | customer_return | ops2 | TNS01 | HQ_319 | 1 | lens_scratch | major | written off | 470 | 0 | closed | rejected | |
| DMG-2026-0726-018 | resolved | customer_return | csd | TNS01 | customer → HQ_319 | 1 | frame_crack | major | rts_claim | 470 | 470 | closed | rejected | |
| DMG-2026-0726-014 | resolved | warehouse | ops2 | MIN-CNL-019 | HQ_319 · A1-11 | 3 | expiry | total loss | written off · tier 0 | 630 | 0 | closed | rejected | |
| DMG-2026-0725-051 | resolved | store | ops2 | MIN-CNL-019 | YAS | 1 | surface_scuff | cosmetic | markdown 20% | 210 | 168 | closed | - | |
| DMG-2026-0725-033 | resolved | supplier_arrival | iwms | LBA01 · MC-4430 | HQ_319 · QC-bay | 5 | stitching_fail | major | rts_claim | 10,250 | 10,250 | closed | +7 | rejected |
| DMG-2026-0724-009 | resolved | store | csd | JAE17 | CCZ | 1 | stone_loose | minor | repair → stock | 420 | 420 | closed | - | |
| DMG-2026-0722-044 | resolved | warehouse | rfid | JAE17 · …3C90 1188 | HQ_319 · A2-07 | 1 | surface_scuff | cosmetic | recover_to_stock | 420 | 420 | closed | - |
Bars are incident counts per source. The line is the rate: damages per 1,000 units handled. A raw count rises with volume and a rate does not, which is why the count peak in w29 is not the worst week.
Normalised by throughput. HQ_319 handles roughly nine times the units MCC does, so a raw count would put it top and mislead. The bar is rate, the number in brackets is the raw count.
Finance owns write-off approval. Nobody else may move stock to WRITTEN_OFF, and that is a database constraint rather than a permission check, because a permission check has a bypass and a constraint does not.
| Tier | Band (landed cost) | Units | Sigs | Who signs | TTL | Open |
|---|---|---|---|---|---|---|
| 0 | < AED 250 | ≤ 2 | 1 | A named auto-approval rule, for a closed reason set: expired, confirmed lost under 2 units, consumable opened. The rule code is the approver identity and every tier-0 approval is sampled monthly by Finance. | 168h | 0 |
| 1 | AED 250 to 2,500 | ≤ 20 | 1 | Finance, and never the requester. | 168h | 4 |
| 2 | AED 2,500 to 25,000 | ≤ 50 | 2 | Finance plus ops_manager or admin. Two humans, two timestamps, two evidence digests. | 168h | 2 |
| 3 | AED 25,000 and above | > 50 | 2 | Finance plus admin, and a mandatory operational incident with a written post-mortem. A loss this size is not a form, it is an event that needs explaining. | 168h | 0 |
| Request | Incident | SKU | Qty | AED | Tier | Basis | Signed | Expires |
|---|---|---|---|---|---|---|---|---|
| WO-2026-0729-006 | DMG-…0728-021 | LLW-BAG-047 | 1 | 2,890 | 2 | value | 1 of 2 · AY 09:14 | 4d |
| WO-2026-0729-005 | DMG-…0729-004 | CDW01 | 1 | 1,400 | 1 | value | 0 of 1 | 2d |
| WO-2026-0728-011 | SHR-…0728-002 | MIN-CHR-001 | 2 | 3,180 | 2 | value | 1 of 2 · FZ 11:02 | 3d |
| WO-2026-0728-009 | DMG-…0727-014 | TNS01 | 4 | 1,880 | 2 | rolling_30d | 0 of 2 | 2d |
| WO-2026-0727-018 | DMG-…0726-031 | PP02 | 6 | 2,394 | 1 | value | 0 of 1 | 1d |
| WO-2026-0727-004 | SHR-…0726-001 | FYN01 | 22 | 9,240 | 2 | units | 1 of 2 · AY 16:40 | 1d |
73 resolved incidents
A damaged unit is present and holds value. A shrunk unit is absent. Netting them into one loss number makes shrinkage invisible, because damage is loud - somebody reports it, there are photos - and shrinkage is silent, because nobody reports an absence.
| Supplier | PO | Incoterm | SKUs recd | SKUs damaged | Rate | Units | Value AED | Claim | Window |
|---|---|---|---|---|---|---|---|---|---|
| CIC Jewellery | PO-2026-118 | DAP | 18 | 5 | 27.8% | 11 | 12,400 | RTS-0022 | open |
| VJ Jewels | PO-2026-114 | FOB | 11 | 3 | 27.3% | 7 | 8,150 | RTS-0020 | open |
| LC Straps | PO-2026-109 | DAP | 24 | 3 | 12.5% | 6 | 2,880 | RTS-0019 | closing 4d |
| Atelier Ceramics | PO-2026-102 | EXW | 31 | 3 | 9.7% | 4 | 1,440 | carrier | expired |
| Nour Leatherworks | PO-2026-097 | DAP | 42 | 2 | 4.8% | 5 | 10,250 | RTS-0017 | credited |
| Emirates Candle Co | PO-2026-093 | DAP | 16 | 1 | 6.3% | 3 | 630 | none | expiry, not defect |
That is a real state and it is not automatically good news. Check that the four intake paths are actually delivering before celebrating: ops2 last pushed 14:22, CSD 13:58, IWMS 12:04, RFID 14:39, GRN 09:10. A silent register and a healthy operation look identical from here.
4 filters are hiding all 23 open incidents.
The damage service timed out after 8 seconds. Nothing was changed. Evidence thumbnails are served from Tigris and may be throttled independently, so the register can be healthy while photos are not.
Your grant on app i3 is manager, which lets you raise, confirm, grade and disposition an incident, and raise a write-off request. It does not carry the finance_signoff feature, so the sign buttons are absent rather than disabled: a control you can press and be refused teaches nothing.
The nightly hash-chain verify is running. Intake still accepts and queues, because refusing a sibling's damage report would lose it. Confirmations, dispositions and write-off postings are held until 21:25 and then drain in order.
The register is complete and correct, and its numbers are not yet authoritative. Damage intake, matching and disposition all run and post; the write-off chain runs in shadow, so requests collect signatures and the posting step is held. Recovery rate and shrinkage rate are marked provisional rather than hidden, because a hidden number reads as a bug and a marked one reads as a schedule.