# 36 — Plan Amendments: Consolidated Changes to Mapping (20), Contracts (22) and Roadmap (23)

> **Status: amendment sheet — the single consolidated delta** that the pharma toll-manufacturing
> client interview (`md/30` requirements, `md/31` coverage audit, `md/32` ERP evidence, `md/33`
> pharma domain) imposes on the three published decision docs: `md/20-mapping.md`,
> `md/22-contracts.md`, `md/23-roadmap.md`. Everything here is **additive**, with exactly TWO
> explicitly ratified exceptions (each carries its own decision row — nothing is changed silently):
> **LA-1 / D-33** (the customer-advance cash-in posts via the `ReceiptVoucher` rail, an amendment
> to `md/22` §5.4) and **D-32** (Trial orders may snapshot a Draft BOM, an amendment to `md/20`
> row 2). All other published verdicts (D-01..D-22), the 5 JE families, the production-order state
> machine and the dependency law stand untouched.
> The client is a **real prospective customer** — re-phasing below treats his flow as launch scope.
>
> **Entity & naming model (consolidated, ends the 34/35/36 fork):** this sheet ratifies
> **`md/34`'s canonical Cycle-1 pair** (`mfg_cost_estimates` + `mfg_cost_estimate_versions` —
> the provisional `mfg_quotations`/`mfg_quotation_costings` names from `md/30` are retired) and
> **`md/35`'s case umbrella** (`mfg_order_cases` — the Cycle-2 commercial machine lives on the
> case, **never** as pre-states grafted onto `production_orders.status`). Event names, permission
> namespaces, sequence keys and FKs below all follow `md/34`/`md/35`.

---

## 1. Mapping amendments (delta to `md/20`)

Format: البند | جديد / تعديل على | الجدول | الملاحظة.
New-table tally moves **24 → 30 `mfg_*` tables** (+6: cost_estimates, cost_estimate_versions,
trial_batches, customer_advances, order_stage_gates, order_cases).

| # | البند (item) | جديد / تعديل على | الجدول (table) | الملاحظة (note) |
|---|---|---|---|---|
| M-01 | Exploratory-costing estimate header / RFQ intake (ملف التسعير الاستكشافي) | **NEW** | `mfg_cost_estimates` | Cycle-1 lineage head (T-8). `customer_id`, prospect product (`lifecycle=Prospect`, D-26), spec attachments, `draft_bom_id`, `current_version_id`, `sales_quotation_id` (**REUSE** `Modules\Sales\SalesQuotation` as the customer-facing commercial doc — verified EXISTS with full Draft→Sent→Accepted→Converted lifecycle + conversion, `md/32` §1; D-29), `sales_order_id` on Won. **Lean mfg-side status `{Draft, Estimated, Quoted, Won, Lost}`** — the commercial funnel states (Sent/Accepted/Rejected/Expired/Converted) live ONLY on `SalesQuotation`, never duplicated mfg-side (avoids a dual-state-machine sync problem). Seq `SequenceService('production','cost_estimate')`. Canonical per `md/34`; retires `mfg_quotations`. |
| M-02 | Exploratory cost estimate versions (التكلفة الاستكشافية) | **NEW** | `mfg_cost_estimate_versions` | **Versioned, immutable** estimate rows (recompute = new version): `material_cost`, `labor_cost`, `overhead_cost`, `total_unit_cost`, `markup_percent`, `quoted_unit_price`, `valid_until`, `price_basis`. Runs the `RollUpStandardCost` core in **simulation-only mode** against a Draft/Engineering BOM. **No GL, no stock.** Canonical per `md/34`; retires `mfg_quotation_costings`. |
| M-03 | Production case umbrella (ملف أمر العميل) | **NEW** | `mfg_order_cases` | **The Cycle-2 entity decision (per `md/35` §0, ratified here):** one case per customer engagement, `sales_order_id` demand anchor, `cost_estimate_id` Cycle-1 lineage, 14-stage commercial machine `{SalesOrder, TrialRequested, TrialInProduction, TrialApproved, BomFinalized, PlanningChecked, DepositGate, MaterialsReserved, InProduction, QcRelease, InFgWarehouse, Delivered, Closed, Cancelled}`, `trial_cost_policy`, deposit fields, `consignment_warehouse_id`, `active_bom_id`, `planning_verdict`. Rationale: 1 case ↔ N production orders (trial loops + main); 7 of 14 stages exist before any production order; deposit is case-level. **The ratified order state machine is NOT widened — no pre-states on `production_orders.status`.** |
| M-04 | Trial batch (الباتش التجريبي) | **NEW** | `mfg_trial_batches` | `case_id`, `cost_estimate_id`, `production_order_id` (the Trial order), `trial_quantity`, `actual_unit_cost` (true-up source for the final quote), `result ∈ {Pending, Passed, Failed}`, `evaluated_at`, `sample_delivery_doc_id` + `sample_delivered_at` (U-3 hand-over). Failed blocks formal-order conversion (`md/30` R-07). **Kept as a separate entity deliberately, against `md/32` §4's leaner order-flag recommendation:** one case spans N re-trial orders, each needing its own customer verdict/sign-off/sample-delivery record that the production order (cost carrier) should not absorb; the approval engine records the sign-off, the trial row anchors it. |
| M-05 | Trial order type | **EXTEND** | `production_orders` | Mapping row 13 enum widens: `order_type ∈ {Standard, Rework, Repair, **Trial**}` (D-24 ratified as enum value, not flag). Trial orders ride the FULL Release→Issue→Confirm→Receive→Close + JE rail unchanged; reported separately; **excluded from standard-cost baselining**. **D-32 carve-out (explicit amendment to `md/20` row 2):** ONLY `order_type=Trial` orders may snapshot an `Engineering/Draft` BOM, guarded by setting `production.trial_allow_draft_bom`; Standard orders never — without this ratified exception the trial-before-BOM-finalization flow is unimplementable. |
| M-06 | Sales-order / case link on the order | **EXTEND** | `production_orders` | Add `sales_order_id` + `case_id` columns (verified absent — fillable has neither, `md/32` §4; per `md/35` §0.1). Direct demand anchor for MTO; complements (does not replace) `mfg_peggings`. No deposit columns and **no commercial states** on orders. |
| M-07 | Customer advance / deposit (الدفعة المقدمة) | **NEW** | `mfg_customer_advances` | **Keyed to `case_id`** (one advance covers the whole engagement — trial + main; per `md/35`, ends the three-way anchor fork): `case_id`, `amount`, `percent`, `basis ∈ {OwnMaterialCost, OrderValue}`, `status ∈ {Due, Received, Waived}`, `receipt_voucher_id`, `journal_entry_id` (the voucher's JE), `applied_invoice_id`. The data backing the Release gate (R-11). `Waived` requires `production.case.deposit_waive` and is audited. |
| M-08 | Customer-advances liability account | **EXTEND** | Accounting COA + settings | New detail account **Customer Advances (دفعات عملاء تحت الحساب)** as child of `2104 Unearned Revenue` (seeded via `AutoAccountService`); setting key `production.customer_advance_account_id`. NOT `SalesPayment` (invoice-bound, hard-wired DR Cash/CR AR — wrong tool, `md/32` §2). |
| M-09 | Deposit cash receipt | **REUSE + LA-1 law amendment (D-33)** | `receipt_vouchers` | `ReceiptVoucher` + `ApproveReceiptVoucher` are account-agnostic (line account drives the CR — verified `buildJournalLines`). Wire **`reference_type='mfg_order_case'`** + line account = Customer Advances. **LA-1 (explicit amendment to `md/22` §5.4):** the advance's DR Cash / CR Customer-Advances JE is **the voucher engine's own JE** — a single posting; Production does NOT additionally call `CreateJournalEntry` for it (the earlier double-listing is retired). `CreateJournalEntry` remains the exclusive rail for every other production posting, including the settlement JE. **Zero schema change in Accounting.** |
| M-10 | Stage gates (بوابات المراحل) | **NEW** | `mfg_order_stage_gates` | Audit + transition table behind the per-stage screens (R-17), **keyed to `case_id`** (per `md/35`): `case_id`, `from_stage`, `to_stage`, `actor_user_id`, `gate_snapshot` json, `at`. The stage pipeline IS the `mfg_order_cases` machine (M-03); screens call the same Actions as the API — never bypass either state machine. **Split rule vs the Core approval engine (RM-2):** `mfg_order_stage_gates` is the *transition audit log* (every move, automated or human); Core `ApprovalWorkflow`/`ApprovalLog` (M-14) carries *human sign-off gates* (BOM finalize, trial decision, advance waive, QC release) whose approval is a transition *precondition* — never a duplicate audit trail. |
| M-11 | Consignment ownership (مخازن الأمانة) | **EXTEND** (pull-forward) | `warehouses` | `is_consignment` (D-15, already ratified) **+ `owner_partner_id`** (`md/32` §3: zero ownership concept exists today). Held, never valued, never purchasable. **Moves Phase 6 → Phase 1/2** (C-07/D-27 — toll client is the launch customer). |
| M-12 | Customer free-issue intake & return (استلام/إرجاع خامة العميل) | **EXTEND** (documents) | Inventory receipt/issue docs | **U-2 closure — the intake document:** customer free-issue material enters the consignment warehouse via a real **Inventory receipt document** approved by `ApproveReceipt` running a **no-valuation/no-GL branch** for `is_consignment` warehouses (tracking-only quantities; lots recorded for genealogy, md/33 P3), referenced to the case. Return of UNUSED customer material at case close = the mirror **Inventory issue document** (tracking-only) + a case-close reconciliation (received − issued-to-orders − consignment scrap = returned). No stock balance is ever touched outside the Approve* document rails (`md/22` §1). Production calls these forward via `ReceiveCustomerMaterial` / `ReturnCustomerMaterial` (§2.2 #23/#24). |
| M-13 | Reservation activation | **EXTEND** (logic) | `inventory_stock_balances` | `StockService::reserve()/release()` stays a **Phase 1** item exactly as published (A5). Amendments: (a) the **advance gate precedes Release** — and reservation remains a *side-effect of* `ReleaseProductionOrder` exactly as ratified (`md/20` row 13; the case stage `MaterialsReserved` is *entered by* Release, never before it); (b) new branch: customer-supplied components reserve against the consignment bucket (R-12). |
| M-14 | Lineage chain | **EXTEND** | `mfg_peggings` | Add `cost_estimate_id` + `case_id` to the peg chain so the lineage view reconstructs RFQ → draft BOM → quote → trial → order → MO → docs (R-18). |
| M-15 | Approval gating | **EXTEND** | Core enums | `ApprovalModule::Production` (already Phase 0) **plus** new `ApprovalDocumentType` cases: `bom`, `production_order`, `trial_batch`, `customer_advance` — reuse the Core ApprovalWorkflow engine for human sign-offs (`md/32` §5), under the M-10 split rule. |
| M-16 | GR quality default (pharma) | **EXTEND** | settings | New per-company setting `production.gr_default_quality_status`; pharma companies flip **Released → OnHold** + quarantine warehouse (warehouse-as-state, same pattern as `is_consignment`). D-21 stays the generic default; this is the compliant override (`md/33` P2). |
| M-17 | Batch number stamp | **EXTEND** | `production_orders` | `batch_no` stamped at Release via new sequence key `SequenceService('production','batch')`, propagated to every child document — the cheap Phase 1 slice of the pharma BMR (`md/33` P1). |
| M-18 | Prospect product | **EXTEND** | Core `products` | `lifecycle=Prospect` state (D-26) so a Draft BOM for a not-yet-onboarded customer product keeps its `product_id` FK; promotes cleanly on Won. |
| M-19 | R&D actor / permission namespaces | **EXTEND** | Core permissions | **One taxonomy (ends the three-namespace fork):** Cycle-1 slices under `production.estimates.*` per `md/34` §5 (incl. `production.estimates.rnd.draft_bom`); Cycle-2 slices under `production.case.*` per `md/35` §5 (waive = **`production.case.deposit_waive`**). The Phase-0 seeder is written from those two files verbatim. R&D ownership routing per C-04. |

---

## 2. Contracts amendments (delta to `md/22`)

All additions obey the two prime rules and §5 law (as amended by **LA-1** only): **Actions forward,
events backward, no module ever reads an `mfg_*` table.** Sales receives prices by **push**
(Action); Accounting receives a voucher and never knows `mfg_customer_advances` exists; QMS
inspections are created forward and Manufacturing reads `qms_inspections.result` read-only
(already permitted).

### 2.1 New domain events (extends §2)

**One vocabulary (ends the three-vocabulary fork):** Cycle-1 events are `md/34` §3's five —
`CostEstimateRequested`, `DraftBomReady`, `EstimateQuoted`, `EstimateWon`, `EstimateLost`.
Cycle-2 events are `md/35` §2's twelve `Case*` events — `ProductionCaseOpened`,
`CaseTrialRequested`, `TrialOrderCreated`, `CaseTrialDecided`, `CaseBomFinalized`,
`CasePlanningChecked`, `CaseDepositSatisfied`, `CaseMaterialsReserved`, `CaseQcReleased`,
`CaseDelivered`, `CaseClosed`, `CaseCancelled` — plus `CaseConsignmentReceived` /
`CaseConsignmentReturned` (M-12). Key wiring:

| Event | Emitter (Action) | Consumers (Manufacturing-side listeners → forward Action) | Payload (key fields) |
|---|---|---|---|
| `EstimateQuoted` | `QuoteCostEstimate` (after the simulation-only roll-up version is approved) | `PushQuotePricing` → **NET-NEW** `Modules\Sales\Actions\UpsertQuotationPricing` (writes price + `valid_until` into the `SalesQuotation` — Sales never reads `mfg_cost_estimate_versions`) | `estimate_id, version_id, sales_quotation_id, quoted_unit_price, currency, valid_until` |
| `CaseTrialDecided` | `RecordTrialDecision` (records customer verdict; **gate: trial sample hand-over document exists**, U-3) | Lineage gate (Passed ⇒ conversion eligible; Failed ⇒ block + optional re-trial loop); trial cost-policy posting per D-23; notification to Sales/R&D roles | `case_id, trial_batch_id, production_order_id, result, actual_unit_cost, evaluated_at` |
| `CaseDepositSatisfied` | `AllocateCaseAdvance` / `WaiveCaseDeposit` (after `ApproveReceiptVoucher` posts DR Cash / CR Customer Advances — LA-1) | Release-gate re-evaluation (Σ approved vouchers `reference_type='mfg_order_case'` ≥ required); **NOW raise the on-behalf purchase requests** (`Purchases\CreatePurchaseRequest`, billable-to-customer tag) — PRs are NEVER raised before this event (U-6/C-5 rule); notify Planning | `case_id, sales_order_id, deposit_required, deposit_received, receipt_voucher_id, journal_entry_id` |
| `CaseConsignmentReceived` / `CaseConsignmentReturned` | `ReceiveCustomerMaterial` / `ReturnCustomerMaterial` (M-12 documents) | Consignment balance/reconciliation view; genealogy lot capture; case-close reconciliation gate | `case_id, warehouse_id, document_id, lines[{product_id, lot_no, quantity}]` |
| `CaseQcReleased` | `ReleaseCaseQc` (reads `qms_inspections.result` read-only) | Quarantine→FG move via the **ratified document rails only**: a paired tracking transfer (ApproveIssue out of quarantine + ApproveReceipt into FG — registered below as contract addition #25; no ad-hoc "transfer rail"); pegged delivery release; advance settlement reminder | `case_id, gr_id, order_id, lines[{product_id, quality_status}], resolved_at` |

(The generic per-move audit row is written by each transition Action itself into
`mfg_order_stage_gates` — there is no separate `StageAdvanced` event; the per-stage `Case*` events
above ARE the stage-advanced notifications.)

### 2.2 New / changed forward Action entry points (extends §3)

| # | Action | Module | Status | Used for |
|---|---|---|---|---|
| 16 | `Modules\Accounting\Actions\ApproveReceiptVoucher` | Accounting | **EXISTS** (verified — account-agnostic posting, `md/32` §2) | Deposit receipt: DR Cash/Bank / CR Customer Advances; caller sets the line account + `reference_type='mfg_order_case'`. **The voucher's JE IS the advance posting (LA-1/D-33) — no second JE.** |
| 17 | `Modules\Accounting\Actions\CreateJournalEntry` | Accounting | **EXISTS** | The **settlement JE** at invoicing: `entry_type='production_advance_settlement'` (DR Customer Advances / CR AR), plus the D-23 trial-policy entry_types (`production_trial_absorb/_defer/_apply/_writeoff`) and `production_toll_material_cogs` (#22). |
| 18 | `Modules\Sales\Actions\UpsertQuotationPricing` | Sales | **NET-NEW** (thin) | Push estimate price/validity into `SalesQuotation`; keeps the no-`mfg_*`-reads law |
| 19 | `Modules\Sales\Actions\ConvertQuotationToOrder` | Sales | **NET-NEW** (extraction of `SalesOrderController::convertFromQuotation` L368 — same recipe as `CreatePurchaseRequest`) | Programmatic Accepted→Order conversion from `MarkEstimateWon` / the case workflow; stamps lineage. `md/34` §6 step 1 binds to THIS Action (never the controller). |
| 20 | `Modules\Sales\Actions\CreateServiceInvoice` | Sales | **NET-NEW** (extraction, same recipe) | **U-4 closure — the compliant invoice creation rail:** Production triggers the final case invoice forward: toll conversion-fee line + **material pass-through line(s)** (#22) + optional trial-billing line (D-23 Bill). Flows to EInvoicing (B18). No controller call, no direct Sales table writes. |
| 21 | `Modules\QMS\Actions\CreateInspection` | QMS | already #8 | **Changed timing**: also called at GR for the pharma final-release inspection; gate config (`production.gr_default_quality_status`) lands Phase 1 instead of waiting for full Phase 6 gates |
| 22 | *(journal map — see §2.3)* Material pass-through billing | Accounting (via #17/#20) | **NEW design (U-1 closure)** | RM the factory buys **on the customer's behalf** is FACTORY property until invoiced (normal own stock, reserved/pegged to the case; its purchase POs carry the billable-to-customer tag). At FG receipt on the toll branch the material portion of WIP relieves to toll-material COGS; the final invoice (#20) carries a **material pass-through line at cost (+ contractual handling %)** beside the conversion fee — so the advance (sized as % of own-procured material cost, D-25) settles against an invoice that **contains the material it funded**: the cash math closes. Title to the material content passes to the customer at delivery/invoice. |
| 23 | `Modules\Production\Actions\ReceiveCustomerMaterial` → Inventory receipt doc | Production → Inventory | **NEW** (M-12) | Customer free-issue intake into the consignment warehouse — tracking-only `ApproveReceipt` branch; lots captured |
| 24 | `Modules\Production\Actions\ReturnCustomerMaterial` → Inventory issue doc | Production → Inventory | **NEW** (M-12) | Return of unused customer material at case close — tracking-only `ApproveIssue` branch + reconciliation |
| 25 | Quarantine→FG release transfer | Inventory documents | **EXTEND** (contract addition) | QC release (CaseQcReleased) moves stock ONLY via a paired tracking ApproveIssue/ApproveReceipt transfer document — registered here so no un-ratified "transfer rail" exists |
| 26 | Trial-sample hand-over delivery | Production doc → tracking issue | **NEW** (U-3 closure) | Trial output is received into the **trial/evaluation bucket** (warehouse-as-state, non-sellable — `md/31` C-05 made concrete); the hand-over to the customer is a **sample delivery document** (tracking-only issue out of the evaluation bucket, referenced to `mfg_trial_batches.sample_delivery_doc_id`); `RecordTrialDecision` is gated on its existence |
| — | `ReleaseProductionOrder` precondition | Production (internal) | **EXTEND** | Hard gate: block Planned→Released until `Σ(approved case advances) ≥ required` OR status `Waived` (permission-guarded). Sits BEFORE snapshot + reserve. **The same gate governs on-behalf purchasing: `CreatePurchaseRequest` for billable-to-customer material fires only on `CaseDepositSatisfied`** (U-6). Not a cross-module call — the gate reads Manufacturing's own tables. |

### 2.3 Journal map additions (extends §4)

| Event | entry_type | DR | CR | Amount |
|---|---|---|---|---|
| Customer advance received | `production_customer_advance` | Cash/Bank | Customer Advances (liability, child of 2104) | received amount — **posted once, by the voucher engine (`ApproveReceiptVoucher`), LA-1/D-33; tagged with this entry_type via the voucher reference** |
| Advance settled at final invoicing | `production_advance_settlement` | Customer Advances | Accounts Receivable | min(advance balance, invoice total) — single canonical name (the earlier `production_advance_application` alias is retired) |
| Advance refund on cancel (OQ-6/D-35) | `production_advance_refund` | Customer Advances | Cash/Bank | residual after incurred cost |
| Trial run (during execution) | — | *the normal 5 JE families unchanged* | | |
| Trial close — cost ownership (D-23, per `md/35` §1.1/§3) | `production_trial_absorb` / `production_trial_defer` / `production_trial_apply` / `production_trial_writeoff` | R&D Expense / Deferred Trial Cost / Order cost / R&D Expense | WIP / WIP / Deferred / Deferred | trial WIP residual per policy `{Bill, Absorb, CreditOnWin}` (Bill = a normal Sales invoice line via #20, no special entry_type). These four entry_types and the two accounts (Deferred Trial Cost, R&D Expense) ARE new and ratified here — the earlier "no new JE family" wording was wrong and is retired. |
| Toll FG receipt — on-behalf material relief (U-1) | `production_toll_material_cogs` | Toll material COGS (recharged) | WIP | material portion of WIP for factory-bought-on-behalf components |
| Final toll invoice (via #20) | (Sales invoice → EInvoicing) | AR | Toll-service revenue + **Material pass-through revenue** (+ trial line if Bill) | conversion fee + on-behalf material at cost (+ handling %) |
| Customer-supplied (free-issue) | — | **no JE ever** — tracking-only consignment movements (intake M-12, issue, return, scrap D-30); lots in genealogy | | |

---

## 3. Roadmap re-phasing (delta to `md/23`)

The client is a **real prospective launch customer** — toll/MTO with the commercial funnel in
front. Revised phase order, sizing (PHASE-level legend unchanged) and rationale per move:

| Phase | Was | Becomes | Size | Rationale |
|---|---|---|---|---|
| **0 — Hardening** | S | S (scope +) | S | **ADD:** ratify the authoritative decision register **D-23..D-36 + OQ-9** (§4) inside the spec-addenda track (same one-week timebox, same hard gate); R&D role + the two permission namespaces (`production.estimates.*` / `production.case.*`, M-19); `ApprovalDocumentType` production cases (M-15); `Product.lifecycle=Prospect` (M-18). No new build — decisions + perms only. |
| **1 — Master Data v2 + Real Execution** | L | L (top edge) | L | **ADD:** `order_type=Trial` enum value + D-32 draft-BOM carve-out guard (M-05); `sales_order_id`/`case_id` on `production_orders` (M-06); **consignment pulled from Phase 6** — `warehouses.is_consignment` + `owner_partner_id` + per-line `ownership` + tracking-only issue branch **+ the free-issue intake/return documents (M-12)** (C-07/D-27: a toll factory cannot run a single real order without them); pharma GR default flip `OnHold` + quarantine warehouse (M-16); `batch_no` stamp at Release (M-17). **Risk control:** Phase 1 was already aggressive-L; the published 1a/1b fallback split stays, and the consignment slice is the first candidate to slip into 1b — never back to Phase 6. |
| **2 — Routing, Confirmations, Conversion Costing** | L | L (scope +) | L | **ADD (the deposit gate moves UP — it had no scheduled home at all):** `mfg_order_cases` + the case machine core (M-03) + `mfg_customer_advances` keyed to the case + Customer-Advances account/setting (M-07/M-08) + `ReceiptVoucher` wiring under **LA-1** (M-09) + the `ReleaseProductionOrder` advance precondition + **PR-raising moved behind the gate** (§2.2 last row) + `CaseDepositSatisfied` event; consignment-bucket **reservation branch** completing M-13 (core `reserve()/release()` itself stays Phase 1, unchanged); `mfg_order_stage_gates` (case-keyed) + **pipeline-board MVP** (D-28). Deposit gate needs the Phase 1 Release rail — earliest correct slot. |
| **2.5 — Customer Front (NEW phase)** | — (was "1.5" in `md/30`/`md/31` proposals) | **NEW** | **M** | `mfg_cost_estimates` + `mfg_cost_estimate_versions` + `SimulateCostEstimate` (simulation-only — **pulls the `RollUpStandardCost` CORE forward from Phase 3**, estimate mode only, no standards, no variances, no GL); `mfg_trial_batches` + the trial flow over the Phase-1 Trial rail incl. the **evaluation bucket + sample hand-over delivery** (#26); `UpsertQuotationPricing` + `ConvertQuotationToOrder` + `CreateServiceInvoice` Sales tie-ins; **the gate-critical case workbenches ship HERE, not Phase 5** (D-28 amended): trial-bench, trial-review, bom-bench, planning-bench, deposit-desk, reserve-desk + the Cycle-1 screens (`md/34` §4) — Phase 5 only polishes and completes the set. **Why after Phase 2, not before:** exploratory costing prices labor/OH from work-center rates + `cost_driver`, which land in Phase 2 — quoting before that means material-only estimates. Sits cleanly before Planning (needs no MRP). |
| **3 — Costing Engine** | M | M (slightly lighter) | M | Unchanged scope: standards, 7 variances, settlement. The roll-up core arrives already built (Phase 2.5) — Phase 3 productionizes it (standards versioning, variance engine, period jobs). **ADD:** Trial orders excluded from standard-cost baselining until trial `Passed` (M-05); trial-policy JEs (D-23) wired. |
| **4 — Planning (MRP/CRP/MPS-lite)** | L | L | L | Mostly unchanged. **ADD:** MRP POs for own-procured material on a customer case get a **billable-to-customer tag** (C-06b — purchase on the customer's behalf) and **are raised only after `CaseDepositSatisfied`** (U-6 rule; the Phase-2 case-local planning obeys the same gate); readiness screen joins the stage pipeline as the Planning workbench. Toll branch (never raise PO for customer material) was already in scope. |
| **5 — Shop Floor Control** | M | M | M | Unchanged engine. **ADD:** completes/polishes the per-stage back-office workbenches begun in Phase 2.5 (C-08 complete) + production-monitor per-operation views. Operator terminals unchanged. **OQ-9 dependency:** if the client's "واجهات لكل مرحلة إنتاجية" means per-MANUFACTURING-stage screens (mixing/granulation/compression/packaging), the answer lands here as per-operation workbenches over routing operations — see OQ-9. |
| **6 — Deep hooks** | L | **M–L (shrinks)** | M–L | Toll/consignment core **moved out** (to Phases 1–2). Remains: batch/lot first-class + genealogy + FEFO (A4/D-14 — **flagged pull-forward candidate for the pharma go-live release**, `md/33` P3), full QMS gates (the Phase-1 default-flip becomes a real inspection-resolved gate), HRM piecework, BMR assembly/print (P1), retained samples (P5), yield-reconciliation gate (P8). |

**Explicitly unchanged:** D-01..D-22 all stand; module identity (EXTEND `Modules/Production`,
`mfg_*` prefix); **the production-order state machine and its Phase-1 migration (truly untouched —
the commercial stages live on `mfg_order_cases`)**; the 5 JE families + month-end absorption; the
dependency law (§5) **except the single ratified amendment LA-1/D-33**; MRP/CRP/variance engine
designs; SFC terminal design; Phase-0 hard gate discipline. Revised sequence:
**0 → 1 → 2 → 2.5 → 3 → 4 → 5 → 6** (0:S · 1:L · 2:L · 2.5:M · 3:M · 4:L · 5:M · 6:M–L).

---

## 4. THE authoritative decision register (D-23..D-36 + OQ-9)

> **Single numbering (ends the three-scheme collision):** this table is THE D-register. `md/30` §6
> and `md/31` §4 now point here; `md/31`'s former "D-23 pre-sales scope" is **D-31** below;
> `md/30`'s OQ-x → D-x mapping is given per row. Requirement numbering: R-01..R-21 = `md/30`'s
> scheme everywhere; `md/31`'s derived list is renumbered IR-1..IR-9.

| # | Decision / Risk | Options | Recommendation |
|---|---|---|---|
| **D-23** | **Trial cost policy** — who pays the trial batch (and re-trials on failure)? (OQ-1/OQ-3) | Bill at cost+markup vs absorb vs defer-and-credit-on-win | Configurable per case: **`trial_cost_policy ∈ {Bill, Absorb, CreditOnWin}`** (per `md/35` §1.1 — the earlier two-valued `{Customer, Absorbed}` table is superseded); posting per §2.3 (Absorb ⇒ `production_trial_absorb` reclass; CreditOnWin ⇒ defer/apply/writeoff family); failed-trial cost inherits the same policy; N failed trials ⇒ case auto-flagged for review |
| **D-24** | Trial modeling | `order_type=Trial` enum vs `is_trial` flag vs separate module | **`order_type=Trial` ratified** (M-05) — first-class reporting, zero new rail (supersedes the `is_trial` lean in `md/31`) |
| **D-25** | **Deposit / advance percentage** (OQ-2) | Fixed % vs per-customer vs per-order vs material-cost-based | Setting `production.default_advance_percent` + per-case override; **v1 basis = % of own-procured material cost** (matches "factory buys on the customer's behalf" — and the invoice now carries the matching material pass-through line, U-1); hard block at Release AND on PR-raising; `Waived` only via `production.case.deposit_waive`, audited |
| **D-26** | Draft BOM for prospect product | nullable `product_id` vs `Product.lifecycle=Prospect` | **`lifecycle=Prospect`** — keeps BOM FK integrity, promotes on Won |
| **D-27** | Toll/consignment timing | Phase 6 vs pull forward | **Pull forward to Phase 1/2 — ratified** (D-07 trigger fired: toll client is the launch customer) |
| **D-28** | Stage-screen scope (OQ-7 granularity folded in) | Full workbenches early vs pipeline-board MVP first | **Board MVP in Phase 2; gate-critical workbenches in Phase 2.5; completion/polish Phase 5.** Per-stage permission slices (`production.case.*`); supervisor spans all (OQ-7 default) |
| **D-29** | Quote / deposit document ownership | New `mfg_*` docs vs reuse Sales + Accounting | **Reuse verified:** `SalesQuotation` (commercial doc) + `ReceiptVoucher` (cash); `mfg_*` tables carry only the mfg-side estimate/case/costing/gate data |
| **D-30** | **Customer-material scrap ownership** (OQ-4) | Own scrap expense vs return vs bill-back | **Never an own-scrap JE** (customer property, bailment): tracking-only consignment scrap movement; reconcile/return/bill per contract; surfaced in the consignment movement report and the M-12 case-close reconciliation |
| **D-31** | **Pre-sales costing funnel scope** (was `md/31`'s "D-23") | Build the full RFQ→DraftBOM→estimate→quote funnel (C-01..C-03) vs minimal spreadsheet | **Build it** (`md/34` design) — it is this client's entry point; without it Cycle-1 is unserved |
| **D-32** | **Trial Draft-BOM snapshot carve-out** (amends `md/20` row 2) | Forbid (trial deadlocks before BOM finalization) vs ratified narrow exception | **Ratify the exception:** ONLY `order_type=Trial` orders may snapshot an `Engineering/Draft` BOM, behind setting `production.trial_allow_draft_bom`; Standard orders never. Explicit amendment — `md/20` row 2's guard text gains this one carve-out |
| **D-33** | **Advance posting rail — law amendment LA-1** (amends `md/22` §5.4) | Bare `CreateJournalEntry` vs `ReceiptVoucher` rail | **Voucher rail ratified:** the advance cash-in posts via `ApproveReceiptVoucher` (account-agnostic, verified `md/32` §2) and the voucher's own JE is the single advance posting (`entry_type='production_customer_advance'` stamped via the voucher reference); no parallel `CreateJournalEntry` call (no double posting). Every other production posting remains `CreateJournalEntry`-only |
| **D-34** | Quote validity policy (OQ-5) | Free vs enforced expiry | `production.quote_validity_days` (v1 = 30); expired quote blocks Won/conversion until re-costed |
| **D-35** | Advance refund / forfeiture on cancellation (OQ-6) | Forfeit vs refund vs net | Per-contract; default = applied to incurred cost, balance refundable (`production_advance_refund`) |
| **D-36** | Trial-vs-order quantity & true-up (OQ-8) | Fixed ratio vs independent | Trial qty independent; full-order cost re-estimated from `mfg_trial_batches.actual_unit_cost` before conversion (mandatory true-up) |
| **OQ-9** | **What does «واجهات لكل مرحلة إنتاجية» mean?** — commercial CASE stages (the 14-stage board + workbenches, the reading designed in `md/35` §4) or per-MANUFACTURING-stage screens (mixing/granulation/compression/packaging — pharma-plausible)? | ask the client | Both are servable: case workbenches land Phases 2–2.5; if the manufacturing-stage reading is confirmed, per-operation workbenches over routing operations land with Phase 5 SFC (operators already get per-WC terminals) and an early read-only per-operation monitor can ship in Phase 2.5. **Must be answered at the Phase-0 gate.** |
| R-a | **Phase-1 slip risk** grows with the consignment pull-forward | — | Keep the published 1a/1b split as the pre-agreed fallback; consignment slice slips into 1b only |
| R-b | **Estimate-vs-actual divergence** on quotes (priced off Draft BOM + estimated prices) | — | Mandatory true-up from `mfg_trial_batches.actual_unit_cost` before conversion (D-36); `valid_until` enforcement (D-34) |
| R-c | **Advance liability accounting** (advance ≠ revenue, ≠ AR settlement) | — | Accountant sign-off on the Customer-Advances child account + the settlement JE + the material pass-through lines (U-1) before Phase 2 exit; refund per D-35 |
| R-d | **Gate-bypass pressure** (commercial urgency vs the deposit hard block) | — | `Waived` exists precisely for this — permission-guarded, audited, reported; no silent bypass path in code (and the PR gate obeys the same waiver) |

---

**Bottom line:** +6 `mfg_*` tables (24→30: estimates, estimate versions, order cases, trial
batches, customer advances, stage gates — `md/34`/`md/35` naming, no parallel `mfg_quotations`),
the `md/34` estimate events + `md/35` case events as the single vocabulary, +3 thin Sales Actions
(`UpsertQuotationPricing`, `ConvertQuotationToOrder`, `CreateServiceInvoice`), the four
previously-missing documents designed (free-issue intake/return, trial-sample hand-over,
quarantine-release transfer, material pass-through billing), one new phase (2.5 Customer Front,
M), Phase 6 shrinks as toll moves into Phases 1–2, two explicit ratified amendments (D-32
draft-BOM carve-out, D-33/LA-1 voucher rail) and the authoritative register D-23..D-36 + OQ-9
joins the Phase-0 ratification gate. Nothing else published is undone — the client's funnel bolts
onto the front of the existing rails.
