# Architecture — Forge PM Work Order Simulation

> **FICTIONAL / SYNTHETIC DEPLOYMENT MODEL.** No real customer data is used.

## How it fits together

```
src/enterprise-synth.mjs   ──>  100,000 labeled synthetic work orders (seeded)
                                 │
                                 ▼
../work-order-agents (the real, verified ecosystem, imported unchanged)
  bootstrap.startStack({})
     ├─ openDatabase()        real PostgreSQL engine (PGlite, in-process)
     └─ startDispatchServer() real gRPC/HTTP2 dispatch service (loopback)
  createPipeline()  ──>  for each order:
     classify ─> route ─> validate ─> action
                                 │
                                 ▼
verify.mjs   ──>  streams metrics, persistence checks, idempotency,
                  ROI (src/roi.mjs), and writes verification-report.* + evidence/
                                 │
                                 ▼
build-deliverables.mjs  ──>  report/impact-study.md + certification-report.md
publish.mjs             ──>  ../../published/forge-pm-work-order-sim/ (public page)
```

## Design principles

1. **Reuse, don't re-implement.** The simulation imports the *already-verified*
   agent ecosystem (`../work-order-agents/src`) unmodified. This study adds scale,
   an enterprise dataset, and an ROI model around it — it does not change agent
   behaviour. The runtime dependencies (`@electric-sql/pglite`, `@grpc/grpc-js`,
   `@grpc/proto-loader`) resolve from that package.

2. **Determinism is a proof requirement.** A single seed (`20260625`) drives the
   entire 100,000-order corpus. The corpus carries a content fingerprint, so any
   engineer who runs the generator gets byte-identical inputs and therefore the
   same metrics.

3. **Ground-truth answer key.** Every synthetic order is labeled with its true
   trade, priority, region, and the expected validation outcome and disposition, so
   accuracy, recall, precision, and the false-auto-action rate are measured against
   a known answer — not asserted.

4. **Live infrastructure, synthetic input.** Persistence and dispatch are real
   (real SQL transactions over PGlite; real gRPC over HTTP/2). Only the *inbound
   volume* is synthetic. Swapping in real orders would change inputs, not wiring.

5. **Transparent economics.** The ROI model shows its arithmetic on every line and
   reads its only measured input — the auto-action rate — from the simulation.

## The synthetic order "kinds"

| Kind | Models | Expected disposition |
| --- | --- | --- |
| `clean` | clear single-trade request, valid | AUTO_DISPATCH |
| `emergency` | clean but P1 (safety) | AUTO_DISPATCH (escalated) |
| `ambiguous` | two trades, weak signal | HUMAN_EXCEPTION |
| `highCost` | estimate over the auto-approval cap | HUMAN_EXCEPTION |
| `duplicate` | resubmission of an earlier order | HUMAN_EXCEPTION |
| `missingLoc` | no resolvable unit/zone (blocking) | REJECTED |
| `missingField` | description too short to action (blocking) | REJECTED |

## Module map

- `src/enterprise-synth.mjs` — portfolio model (19 fictional properties, 42,000
  units across 4 states), trade vocabulary, vendor pools, SLA requirements, and the
  seeded generator + dataset-row + fingerprint helpers.
- `src/roi.mjs` — `computeRoi(assumptions, sim)` returns the full manual-vs-agent
  model with formulas; `usd()` formats currency.
- `verify.mjs` — the simulation runner + 25 MUST_PASS checks + report writers.
- `build-deliverables.mjs` — renders the executive + certification reports from
  `verification-report.json`.
- `publish.mjs` — builds the public case-study page from the verified report.
