# 21 — Gap Analysis (Both Directions)

Answer to the owner's question "ايه اللي ناقص" in two directions:

- **Direction A** — what Moon ERP lacks today to host the Manufacturing spec (verified against
  `md/10` Production-now, `md/11` Inventory/Purchases, `md/12` Accounting/Core, `md/13` Sales/HRM/QMS/CMMS/FE).
- **Direction B** — what the SPEC itself fails to specify (expert critique of
  `files/manufacturing_spec/markdown` 00–06, verified against `md/00..06` digests).

Severity: **CRITICAL** (blocks a correct go-live), **IMPORTANT** (blocks completeness / causes rework),
**NICE-TO-HAVE** (quality/maturity). Sizing: **S** ≤ ~3 dev-days, **M** ≤ ~3 dev-weeks, **L** > 3 dev-weeks.
⚠️ **This is the GAP-level legend.** The roadmap (23) uses a different PHASE-level legend (S ≈ ≤1 wk,
M ≈ 2–4 wks, L ≈ 4–8 wks) — do NOT map gap sizes onto phase sizes when budgeting.

**Candidates checked and EXCLUDED (already covered, NOT gaps):**

| Candidate | Verdict |
|---|---|
| UoM conversion engine | EXISTS — Core `unit_groups`/`units` (`conversion_factor` 15,6) + per-product `product_units` with `is_purchase`/`is_sale`; BOM/issue/receipt rows already carry `unit_id` (md/11 §1). The remaining issue is a SPEC gap (B1): the spec never states conversion/rounding policy. |
| Cost centers / dimension on journal lines | EXISTS — `cost_centers` (hierarchical) + `journal_entry_lines.cost_center_id`, report-aware in `GeneralLedgerService`, plus `CostAllocationService` for Direct allocation (md/12 §4). Only the `type` column (A18) and Step-Down/Reciprocal (A22) are missing. |
| Document numbering / tenancy / branch scoping / permissions registry / attachments / audit | All inherited rails (`SequenceService`, `BaseModel`/TenantAware, `DataScope`, `PermissionDependencyRegistry`, `Attachment`) — proven by LIS. |
| ATP/CTP as a spec gap | NOT a spec gap — spec 02 fully defines CTP (capacity-based) and ATP (3 modes). The gap is Moon-side only (A14: Sales has no field to receive the promised date). |
| Quality layer | Spec defers it; Moon **QMS already supplies it** — `qms_inspection_plans`/`qms_inspections` carry `production_order_id` waiting; NCR/CAPA link only via `inspection_id` (no direct `production_order_id`). Residual gaps are A10-adjacent (operation pinning) and B22 (sampling plans). |

---

## Direction A — What Moon ERP lacks for this spec

### CRITICAL

**A1. Zero GL posting from production (the biggest single gap)**
- **What:** `Modules/Production` contains no `CreateJournalEntry` call; Inventory services also post nothing. The entire WIP rail — DR WIP/CR RM on issue, DR WIP/CR Labor-Applied + MOH-Applied on confirmation, DR FG + variance/CR WIP on receipt, settlement on close — does not exist (md/12 §10.1).
- **Why:** Spec rule 6 (00 §0.4): *every actual event posts a GL entry, real-time, not batch*. Without it production is financially invisible: no WIP balance, no COGM, no variances, books wrong at any month-end with open orders.
- **Remedy:** Manufacturing Actions per event (`PostMaterialIssue`, `PostConfirmation`, `PostGoodsReceipt`, `CloseProductionOrder` — canonical name per mapping/D-17) calling `Modules\Accounting\Actions\CreateJournalEntry` with `source_type='production_order'`, distinct `entry_type` per event, `cost_center_id` per line — pattern copied 1:1 from `PostLabInvoice` (md/12 §9). Rails need NO Accounting schema change.
- **Size: L**

**A2. Production does not move stock**
- **What:** `consume()` / `record-output()` only mutate quantity columns inside production tables; `source_warehouse_id`/`target_warehouse_id` are dead columns; no `InventoryIssue`/`InventoryReceipt` created (md/10).
- **Why:** Inventory balances and cost layers are never affected by manufacturing — stock-on-hand is wrong the moment the first order runs.
- **Remedy:** Material Issue → draft `InventoryIssue` (`reference_type='production_order'`) + `app(ApproveIssue::class)->execute()`; FG receipt → `InventoryReceipt` + `ApproveReceipt` at rolled-up WIP cost — the exact GRN pattern in `PurchaseGrnController::approve` (md/11 §7).
- **Size: M**

**A3. No planning layer at all (MPS / MRP / CRP)**
- **What:** Greenfield: no `mfg_mps_*`, no `Item_MRP_Settings`, no MRP run, no CRP loads, no pegging table, no exception messages (md/10, spec 02).
- **Why:** Spec build-order steps 2–5; without MRP there is no automatic procurement, no promised dates, no capacity check — the module degrades to manual order entry.
- **Remedy:** Build per spec 02 on existing inputs: demand ← `sales_orders`, supply ← `StockBalance`/`PurchaseOrder`/`ProductionOrder`, recursion ← BOM. Output planned POs via A11 and planned production orders in `Planned` status.
- **Size: L**

**A4. Batch/lot is not first-class in Inventory**
- **What:** Only Serial is fully modelled (`product_serials`). `batch_number`/`expiry_date` are free-text strings on receipt/issue/GRN items; stock balances and cost layers are keyed `(product, variant, warehouse)` only — no batch master, no batch balances, no genealogy, no FEFO (md/11 §1).
- **Why:** Manufacturing traceability (which RM lots entered which FG lot), expiry-driven issue, and recall capability are impossible; toll/consignment and graded outputs make this worse.
- **Remedy:** Add a `batches` master + batch-keyed balance (or batch dimension on `inventory_cost_layers`), batch-aware `StockService`, and a genealogy link table written at Material Issue ↔ Goods Receipt.
- **Size: L**

**A5. Stock reservation logic absent**
- **What:** `inventory_stock_balances.reserved_quantity` and the `available_quantity` accessor exist, but **nothing writes them**; `ApproveIssue` checks gross qty not available (md/11 §3).
- **Why:** Spec hard rule (06 §6.1): reserve at order Release, consume at Material Issue. Without it, two orders can promise the same stock.
- **Remedy:** Add `StockService::reserve()/release()` (transactional) + call from order Release/Issue/Cancel. The column hook is ready — logic only.
- **Size: S**

**A6. Item master has no manufacturing fields**
- **What:** `ProductType` = Product|Service only; no RM/WIP/FG class, no `procurement_type` (Make/Buy), no `material_ownership` (Own/Customer), `cost_method` is a free nullable string ignored by `StockService`, no decomposed standard cost (md/11 §1, md/12 §8).
- **Why:** Nearly every spec branch (MRP make-vs-buy, toll, costing method per item, MPS by production_type) keys off these fields.
- **Remedy:** Manufacturing-side item-settings extension table (`mfg_item_mrp_settings` — canonical name per mapping row 10, AccBpExt pattern) carrying `procurement_type`, `material_ownership`, `production_type`, `costing_method` enum, MRP params, + `mfg_standard_costs` (std material/labor/overhead/total).
- **Size: M**

**A7. No standard costing or variance engine**
- **What:** StockService supports FIFO + WAC (company-level) only; no Standard valuation, no 7-variance computation (MPV, MUV, LRV, LEV, VOSV, VOEV, FOVV), no tolerance bands, no owner routing (md/11 §3, md/12 §10.8).
- **Why:** Spec 04 calls variance analysis the most valuable output of the whole module; FG receipt at standard + variance posting is the core costing contract.
- **Remedy:** Variance engine as Actions triggered on order Close + monthly period job hooked before `CloseFiscalPeriod`; accounts seeded via `AutoAccountService`; settings keys `production.*_account_id` (the module's single settings namespace, matching the `production.*` permission prefix and `'production'` sequence key — D-01) via `SettingDefinition` seeder.
- **Size: L**

**A8. No work-center calendar / shift-capacity model**
- **What:** `production_centers` has `capacity_per_hour` but no calendar, shifts, holidays, or capacity-by-period; HRM `shifts` exist for attendance only, not machine capacity (md/10, md/13 §2).
- **Why:** CRP, CTP, `effective_capacity`, `find_earliest_slot` and `issue_level=PerShift` all require a working calendar — without it every capacity number is fiction.
- **Remedy:** `mfg_work_calendars` + `mfg_calendar_shifts` (canonical names per mapping row 12; working days, shift hours, exceptions) referenced by work center; derive `effective_capacity = daily_capacity × multiplier × efficiency% × utilization%` per period.
- **Size: M**

**A9. BOM versioning, Routing entity and Frozen Snapshot missing**
- **What:** `BomStatus` enum declared but unused (state = `is_active` bool); `version` is free text with no effective dates; routing operations hang off BOM (no versioned `Routing_Header`); released orders copy from BOM at creation but there is no Release-time frozen snapshot, and the order state machine differs (Draft/Confirmed/... vs Planned/Released/InProcess/Completed/Closed) (md/10).
- **Why:** Spec cross-cutting rule 1: master-data edits must never alter released orders — audit and cost integrity depend on it.
- **Remedy:** Add `mfg_routing_headers/_operations` (versioned, effective-dated, lot-size ranges, cavity/cycle/queue/move times); BOM versions with status state machine; snapshot copy on `Planned→Released`; align `ProductionOrderStatus` to the spec machine (additive states).
- **Size: M–L**

**A10. Tool/Mold entity + cycle counters missing (and CMMS has no meter-reading table)**
- **What:** No Tool entity anywhere in Production; CMMS `cmms_pm_schedules.meter_field/meter_threshold` support shot-count PM but there is **no `cmms_asset_meters` time-series** to accumulate cycles, and no Work_Center/Tool ↔ `cmms_assets` cross-link (md/13 §4).
- **Why:** In molding factories the tool, not the machine, is the constraint; usage-based depreciation (`purchase_cost / life_cycles / cavity_count`) and mold-availability scheduling depend on cycle counters.
- **Remedy:** `mfg_tools` (cavity_count, life_cycles, cycles_used, status machine Available→Mounted→Maintenance→Retired) with FK to `cmms_assets.id`; add `cmms_asset_meters` readings table fed by Confirmation cycle counts; depreciation JE via CreateJournalEntry.
- **Size: M**

**A23. Overhead `cost_driver` has no storage home**
- **What:** Spec 04 §4.2 makes `cost_driver ∈ {LaborHours, MachineHours, DirectMaterialCost, UnitsProduced}` the overhead-rate denominator; Moon stores `production_centers.overhead_rate` but NOTHING stores which driver applies — the confirmation OH posting (`cost_driver × overhead_rate`) is uncomputable as specified.
- **Remedy:** `cost_driver` enum column on `production_centers` (per work center — mapping row 6), resolved by `PostConfirmation`. Scheduled with the Phase 2 work-center extension.
- **Size: S**

**A24. Work-center capacity/rate columns absent (and previously unscheduled)**
- **What:** `production_centers` lacks the ~14 columns the mapping's Work_Center EXTEND requires (`capacity_unit`, `daily_capacity`, `capacity_multiplier`, `efficiency_percent`, `utilization_percent`, `setup/labor/machine_cost_rate`, `labor_calc`, `cost_driver`, `calendar_id`, `bottleneck_flag`…). Phase 2 costing posts from WC rates and Phase 4 CRP computes effective capacity from them.
- **Remedy:** Schedule the EXTEND explicitly: rate/capacity/driver columns in roadmap Phase 2, `calendar_id` in Phase 4 (Phase 1 adds only `cost_center_id`).
- **Size: M**

### IMPORTANT

**A11. No programmatic PurchaseRequest creation for MRP** — PR creation lives only in `PurchaseRequestController::store`; extract `Purchases\Actions\CreatePurchaseRequest` so MRP raises requisitions in-process, flowing to PO via the existing `convertFromRequest`. **(S)**

**A12. `ApprovalModule` enum lacks Production** — only Sales/Purchases (md/12 §7); production-order / BOM-change approvals cannot route. Add `Production` case + label + translation key. **(S)**

**A13. No stored labor rate in HRM** — employees carry `basic_salary` only; hourly rate is derived at payroll runtime (`PayrollService:48-49`); no piece_rate anywhere (md/13 §2). Decide rate source: `Work_Center.labor_cost_rate` (spec-native, recommended v1) + optional employee override; PieceRate quantities flow back to payroll. **(S)**

**A14. Sales cannot receive the promised date** — no ATP/CTP field on `sales_orders`; `expected_delivery_date` is manual (md/13 §1). Add `promised_date` (+source flag) written back by a Manufacturing Action; Pegging/Delivery_Schedule live Manufacturing-side. **(S)**

**A15. No consignment/toll ownership bucket in Inventory** — spec hard rule: customer-owned material is held, never valued, never procured. v1 = dedicated consignment warehouses flagged `warehouses.is_consignment` (never valued, never purchasable — mapping row 17, ratified D-15); full `ownership` dimension on balances/movements deferred. **(M)**

**A16. Production module has no events, Actions, or tests** — empty `EventServiceProvider`, no Actions/Services dirs, zero tests, empty seeder (md/10). Violates the house recipe (domain events + listeners, Actions for cross-module calls). Build the event spine (`OrderReleased`, `MaterialIssued`, `OperationCompleted`, `GoodsReceived`, `OrderClosed`) + listeners + Pest coverage. **(M)**

**A17. No shop-floor terminal UI or realtime channel** — no `manufacturing` FE route group; no touch terminal; no broadcast mechanism for the Ready-queue push. Clone `features/pos/pos-layout` as the terminal template; supervisor dashboard; websockets/Core notifications for auto-advance. **(M)**

**A18. Cost-center `type` + work-center→cost-center link missing** — `cost_centers` has no Production/Service/Auxiliary type column; `production_centers` has `account_id` but no `cost_center_id` FK (md/12 §10.2/§10.10). Add both. **(S)**

**A25. FOVV budgeted-volume input missing (budget money EXISTS)** — backend audit: Accounting **already has** a budgeting rail — `budgets` (per fiscal year) + `budget_lines` (`account_id`, `cost_center_id`, annual + monthly `m1..m12` amounts) — md/12 missed it. So FOVV's budgeted fixed-OH spend per cost center is a REUSE; what is genuinely missing is **budgeted production VOLUME** (units). Remedy: `production_centers.budgeted_monthly_volume` v1 (+ entry screen); no approved budget for the period ⇒ FOVV auto-descoped to 6 declared variances (D-22). **(S)**

**A26. Usage-based depreciation method missing in Accounting (register EXISTS)** — backend audit: the fixed-asset register exists (`fixed_assets`, `FixedAsset` + `AssetCategory` + `DepreciationEntry` models, `FixedAssetService`, Sell/Dispose Actions), so `mfg_tools.fixed_asset_id` has a real FK target. Missing: `DepreciationMethod` has only StraightLine/DecliningBalance/Accelerated — the spec's usage-driven (units-of-production) variant for molds needs a new enum case + meter-driven `DepreciationEntry` generation. Phase 2 prerequisite. **(M)**

**A27. Inventory reference-type enums lack a production case** — `ReceiptReferenceType` {Purchase, Return, Adjustment, Opening, Other} and `IssueReferenceType` {Sale, Consumption, Damage, Adjustment, Other} are backed enums (verified); `reference_type='production_order'` requires adding a `ProductionOrder` case to BOTH — a required Inventory touch alongside `MovementType` (A19). **(S)**

### NICE-TO-HAVE

**A19. Production movement types** — `MovementType` lacks production_issue/production_receipt/scrap/rework; v1 can overload issue/receipt with `reference_type='production_order'`. **(S)**
**A20. Bin/location model below warehouse** — shop-floor staging/WIP locations map onto `warehouses` rows for v1; true bins later. **(M)**
**A21. Barcode printing for lots/travel cards** — `product_units` barcodes + `print.service.ts` exist; add order travel-card / lot-label templates. **(S)**
**A22. Step-Down / Reciprocal allocation** — `CostAllocationService` implements Direct only; acceptable v1. **(M)**

---

## Direction B — What the SPEC itself is missing (expert critique)

### CRITICAL

**B1. UoM conversion policy never stated**
- Every entity carries a `uom` but the spec never defines conversion application points (BOM explosion kg→pcs, issue, costing) or rounding policy — it silently assumes the host. Moon's engine covers the mechanics; the BUILD must still decide policy (base-unit normalization at explosion time, banker's rounding, conversion at issue vs at BOM). **Remedy:** write a one-page UoM policy addendum binding `units`/`product_units` to each touchpoint. **(S)**

**B2. Lot/batch traceability absent as a rule**
- No genealogy requirement anywhere (which RM lots → which FG lot), no FEFO/lot-selection on issue — despite grades, toll ownership and expiry implying it. **Remedy:** add a traceability cross-cutting rule + genealogy table to the data model (pairs with A4). **(M)**

**B3. Subcontracted (outsourced) operations not modelled**
- Routing ops always reference an internal work center. TollManufacturing covers customer-material INBOUND only; sending OUR WIP out for one operation (plating, printing…) has no operation type, no subcontract PO link, no in-transit WIP bucket, no service-cost element. Very common in real factories. **Remedy:** `operation_type=Subcontract` + vendor + linked PurchaseOrder + WIP-at-vendor location + service cost into WIP. **(M)**

**B4. Planning/shop calendar entity undefined**
- `calendar_id` is referenced on Work_Center; CRP, CTP, `issue_level=PerShift` and confirmation.shift all need it, but the calendar/shift model is never specified (deferred with APS). **Remedy:** specify the calendar entity now (pairs with A8) — it cannot wait for APS. **(M)**

### IMPORTANT

**B5. Rework/repair flow undefined** — `order_type=Rework`, `routing_type=Repair` and `rework_quantity` are named, but no flow: how rework qty spawns/links an order, its costing, re-entry into routing, normal-vs-abnormal spoilage. **(M)**
**B6. Co-product vs by-product distinction + allocation method config** — only graded joint products with NRV allocation; no by-product NRV-credit treatment, no allocation-method enum (market value / physical units / fixed ratio), and BOM has no output-structure for secondary products. **(M)**
**B7. Reversal semantics unspecified** — Issue/Confirmation/GR all carry Reversed status but no algorithm (restock, negative WIP, GL reversal, preconditions). **(S)**
**B8. Backflush shortage handling undefined** — block confirmation vs allow negative vs partial backflush is never stated; Moon has per-warehouse `allow_negative_stock` to key off. **(S)**
**B9. Over/under-production tolerance & partial close** — "confirmed ≈ ordered" with no tolerance %, no auto-close threshold, no rule for WIP carrying between partial receipts. **(S)**
**B10. Pegging allocation policy** — table defined, but no priority/proportional rule on shortage and no re-pegging rule when MRP regenerates. **(S)**
**B11. Multi-plant/warehouse netting ambiguous** — `plant_id` on MPS but MRP nets a single `on_hand`; no warehouse dimension, no transfer-order sourcing — must be reconciled with Moon's branch+warehouse model. **(M)**
**B12. No demand-forecast source** — MPS consumes `forecast_qty` but nobody produces it; Moon has no forecasting module. v1: manual forecast entry/import screen; later statistical. **(M)**
**B13. ECO change management named but absent** — master data "changes only via ECO" yet no ECO entity/workflow is specified (future phase). Interim: BOM/Routing versioning + `ApprovalModule::Production` approvals as the lightweight substitute. **(M)**
**B14. Return-to-stock of unused issued material** — no return-from-shop-floor document (excess issue back to warehouse, WIP credit). Standard in every MES. **(S)**
**B15. SFC: downtime, pause/resume, andon, OEE all undefined** — operation enum has no Paused/Down state; no stoppage taxonomy; OEE referenced with no formula. CMMS work orders cover maintenance downtime; production micro-stops need a minimal downtime log + Paused state. **(M)**
**B16. Variance disposition & standard-cost revision** — whether variances are expensed or prorated into inventory at close is unstated; no procedure for re-standardization and on-hand revaluation. Decide policy (v1: expense to P&L) and a `RevalueAtNewStandard` action. **(S)**
**B17. Cost-center ownership ambiguous** — spec lists Cost_Center as a Mfg entity; in Moon, Accounting owns `cost_centers` (exists, report-aware). Decision: Accounting is system-of-record; Manufacturing only links to it (A18). **(S)**
**B18. Toll conversion-fee invoicing / e-invoicing untouched** — toll GR posts "DR Customer / CR Toll-service revenue" but no invoice document is specified; in Moon this must be a Sales service invoice flowing through the EInvoicing module (ZATCA/ETA compliance) — a regulatory touchpoint the spec ignores. **(S)**

### NICE-TO-HAVE

**B19. Multi-currency costing** — material price currency basis undefined; Moon's `CreateJournalEntry` handles FX, but standard costs should be declared base-currency-only. **(S)**
**B20. WIP physical count** — no period-end WIP inventory/count procedure. **(M)**
**B21. Serialized finished goods** — GR lines carry batch only; Moon's `product_serials` could serialize FG; spec silent. **(S)**
**B22. Quality sampling plans (AQL)** — spec defers quality wholly; QMS has criteria but no sampling/AQL tables; acceptable later. **(S)**
**B23. Arabic/RTL & bilingual fields** — spec has zero localization requirements; Moon convention (`name_ar`, English-first translate keys, RTL FE) must be imposed on all 26 entities. **(S)**
**B24. Reporting/BI pack** — only a variance Pareto is mentioned; no WIP aging, order cost sheet, capacity load, scrap analysis, OEE reports. Define a v1 report list. **(M)**
**B25. Phantom BOM semantics & substitute_items structure** — both enum/field named, semantics unspecified (pass-through explosion; substitute priority/ratio/validity). **(S)**

---

## Combined risk table

| # | Gap | Direction | Severity | Remedy (short) | Size |
|---|---|---|---|---|---|
| A1 | No GL posting from production | A | CRITICAL | Posting Actions over `CreateJournalEntry` (LIS pattern) | L |
| A2 | Production moves no stock | A | CRITICAL | `ApproveIssue`/`ApproveReceipt` integration (GRN pattern) | M |
| A3 | No MPS/MRP/CRP layer | A | CRITICAL | Build planning per spec 02 on existing demand/supply rails | L |
| A4 | Batch/lot not first-class | A | CRITICAL | Batch master + batch balances + genealogy + FEFO | L |
| A5 | Reservations: column, no logic | A | CRITICAL | `StockService::reserve()/release()` at Release/Issue | S |
| A6 | Item master mfg fields missing | A | CRITICAL | `mfg_item_mrp_settings` + `mfg_standard_costs` extension tables | M |
| A7 | No standard costing / 7-variance engine | A | CRITICAL | Variance Actions on Close + monthly job before period close | L |
| A8 | No WC calendar/shift capacity | A | CRITICAL | `mfg_work_calendars` + shifts; effective-capacity derivation | M |
| A9 | BOM versioning/Routing/Frozen snapshot | A | CRITICAL | Versioned routing entity + Release-time snapshot + status machine | M–L |
| A10 | Tool/Mold + cycle meters | A | CRITICAL | `mfg_tools` ↔ `cmms_assets` + `cmms_asset_meters` | M |
| A11 | No `CreatePurchaseRequest` Action | A | IMPORTANT | Extract Action; MRP → PR → PO | S |
| A12 | `ApprovalModule` lacks Production | A | IMPORTANT | Extend enum + label | S |
| A13 | No stored labor/piece rate | A | IMPORTANT | Rate on Work Center (+employee override) | S |
| A14 | Sales promised-date field missing | A | IMPORTANT | Add field + write-back Action | S |
| A15 | No consignment ownership bucket | A | IMPORTANT | Consignment warehouses (`is_consignment`) v1; ownership dimension deferred (D-15) | M |
| A16 | No events/Actions/tests in Production | A | IMPORTANT | Event spine + listeners + Pest coverage | M |
| A17 | No shop-floor terminal / realtime | A | IMPORTANT | POS-layout clone + broadcast channel | M |
| A18 | CC type + WC→CC link | A | IMPORTANT | Add `type` column + FK | S |
| A19 | Production movement types | A | NICE | Overload issue/receipt v1; enum later | S |
| A20 | No bin model | A | NICE | Warehouses-as-locations v1 | M |
| A21 | Lot/travel-card barcode printing | A | NICE | Print templates | S |
| A22 | Step-Down/Reciprocal allocation | A | NICE | Direct-only v1 | M |
| A23 | `cost_driver` has no storage home | A | CRITICAL | `production_centers.cost_driver` enum column (Phase 2) | S |
| A24 | WC capacity/rate columns unscheduled | A | CRITICAL | Schedule EXTEND: rates/capacity/driver Phase 2, calendar Phase 4 | M |
| A25 | FOVV budgeted-volume input | A | IMPORTANT | REUSE `budget_lines` (exists) + `budgeted_monthly_volume` column; else 6 variances (D-22) | S |
| A26 | Usage depreciation method (FA register exists) | A | IMPORTANT | `DepreciationMethod::UnitsOfProduction` + meter-driven entries | M |
| A27 | Inventory reference-type enums | A | IMPORTANT | `ProductionOrder` case on Receipt/Issue ReferenceType | S |
| B1 | UoM conversion policy unstated | B | CRITICAL | Policy addendum bound to Moon UoM engine | S |
| B2 | Lot traceability not a rule | B | CRITICAL | Genealogy rule + table (with A4) | M |
| B3 | Subcontracted operations missing | B | CRITICAL | `operation_type=Subcontract` + PO link + WIP-at-vendor | M |
| B4 | Shop calendar undefined | B | CRITICAL | Specify calendar entity now (with A8) | M |
| B5 | Rework flow undefined | B | IMPORTANT | Rework-order flow + costing addendum | M |
| B6 | Co/by-product + allocation method | B | IMPORTANT | Output structure + allocation enum | M |
| B7 | Reversal semantics | B | IMPORTANT | Define reversal algorithms per document | S |
| B8 | Backflush shortage handling | B | IMPORTANT | Policy keyed to `allow_negative_stock` | S |
| B9 | Over/under tolerance & partial close | B | IMPORTANT | Tolerance % config + auto-close rule | S |
| B10 | Pegging allocation policy | B | IMPORTANT | Priority rule + re-pegging on replan | S |
| B11 | Multi-plant netting ambiguity | B | IMPORTANT | Per-warehouse netting decision vs branches | M |
| B12 | No forecast source | B | IMPORTANT | Manual forecast entry/import v1 | M |
| B13 | ECO absent | B | IMPORTANT | Versioning + approvals as interim ECO | M |
| B14 | Return-to-stock missing | B | IMPORTANT | Production-return document (issue reversal) | S |
| B15 | Downtime/pause/OEE undefined | B | IMPORTANT | Paused state + downtime log; OEE later | M |
| B16 | Variance disposition / std revision | B | IMPORTANT | Expense-to-P&L policy + revaluation action | S |
| B17 | Cost-center ownership ambiguous | B | IMPORTANT | Decide: Accounting owns; Mfg links | S |
| B18 | Toll fee invoicing / e-invoicing | B | IMPORTANT | Sales service invoice via EInvoicing | S |
| B19 | Multi-currency costing | B | NICE | Base-currency standard costs | S |
| B20 | WIP physical count | B | NICE | Period-end WIP count procedure | M |
| B21 | Serialized FG | B | NICE | Optional FG serialization via `product_serials` | S |
| B22 | Sampling plans (AQL) | B | NICE | QMS extension later | S |
| B23 | Arabic/RTL/bilingual | B | NICE | Impose Moon `name_ar` convention on all entities | S |
| B24 | Reporting/BI pack | B | NICE | Define v1 report list (WIP aging, cost sheet, load, scrap) | M |
| B25 | Phantom BOM / substitutes semantics | B | NICE | Specify explosion + substitute structure | S |

**Headline:** 27 Moon-side gaps (12 critical) + 25 spec-side gaps (4 critical). The financial/stock
rails all exist and are proven (CreateJournalEntry, cost centers, budgets, fixed assets, UoM,
StockService, sequences, permissions) — the critical Moon work is the production-to-rails wiring
(GL, stock, reservations, planning, batch). The spec's worst blind spots are operational reality at
the edges: subcontracting, rework, returns, reversals, calendars, and traceability — every one must
be resolved as a written addendum BEFORE the build order starts, or it resurfaces as rework in
Execution/Costing. **Owner + timebox for those addenda is now scheduled: the roadmap's Phase 0
spec-addenda track (product architect + factory SME, one-week timebox, hard gate before Phase 1
exit).**
