# Verixa Pilot — Phase 1 / 2 / 3 Build Map (ULTRA-DETAILED)

**Date:** 2026-06-01 · **Repo:** `Verixaai/Verixa @ dev-vimal-audit-2 / 3bd2fe47` · **Evidence:** deep code audit (`Verixa_Deep_Code_Audit_Status_dev-vimal-audit-2.md`) · **Scope lock:** CC-PILOT-2026-001.
**Discipline:** Verixa **verifies**; partner **validates**. No "validated/Part 11-ready" claim without executed evidence + QA disposition. `file:line` accurate at `3bd2fe47` — re-confirm at build.
**Effort key:** S = ≤2 dev-days · M = 3–5 · L = 1–2 wks · XL = >2 wks (rough, pre-estimate; Engineering to confirm).
**Status key:** 🟢 strong · ✅ exists · 🟡 partial · 🔴 absent.

---

## PHASE 1 — DEMO (URS-39A) · *win the meeting* · Jun–Aug

Goal: a credible, governed demo of the 6 workflows + MIRA on synthetic data. Mostly configuration of existing mechanisms + 3 small builds + 1 fix.

| # | Item | Exists today (file:line) | Eng action — BUILD / CONNECT / TEST | Acceptance / test | Why (regulatory/functional) | Eff | Client win |
|---|---|---|---|---|---|---|---|
| 1.1 | Demo environment flag | ✅ `environment_class` enum `'demo'\|'sandbox'\|'production'\|'regulated_pilot'` — `licensing/middleware/resolve-tenant-env.ts:43-44`; `core/regulated-pilot-mode.ts:10-12` | **CONNECT** — provision a tenant with `environment_class='demo'`; set env vars | Tenant resolves as demo; `regulated_pilot_mode` false | Demo must be **non-GxP / not a system of record** (Annex 11 §1 intended use) | S | Lets you demo with zero compliance claims |
| 1.2 | "Not a record" GxP-write guard (QMS routes) | 🟢 `DEC-36-07` — `licensing/services/license-gate.service.ts:232-238` + `:390-396`; `isGxpModule` URS-07..35 `:51-58`; global hook `app.ts:404`; catalog `core/regulated-pilot-catalog.ts` | **TEST** — attempt a write on each of the 6 workflows in demo; expect `SANDBOX_ENVIRONMENT_GXP_WRITE_BLOCKED` | All 6 workflow write routes return the block code in demo; reads allowed | Demo records must never become GxP records (21 CFR 11.10) | S | "This is governed" credibility to a QA buyer |
| 1.3 | **AI/handover write hole (FIX)** | 🔴 `/api/v1/ai`,`/mira`,`/handover-bridge` NOT in catalog → hook fail-opens (`regulated-license-scope.hook.ts:22,25`); handover writes records via internal calls `handover-bridge.service.ts:288,291,405,435 (createDeviationRecord),469 (createCapaRecord)` | **BUILD/FIX** — in demo: force `checkHitlRequired=true` always + disable MIRA write-back; OR add `environment_class` check in `createDomainRecord` (`:405`) to block on demo/sandbox | In demo, no MIRA/handover path creates a `deviations`/`capas` row (negative test) | Closes the one path that defeats the demo record-of-record guard (Annex 22 — AI must not create records outside governance) | M | Removes the only demo-safety risk; protects the trust story |
| 1.4 | Global demo banner/watermark | 🟡 export watermark only — `dashboard/export.service.ts:31-99`, config `schema.ts:1547-1550`; no global UI banner found | **BUILD** — app-wide banner/watermark shown when `environment_class='demo'` (frontend) | Banner visible on every screen + on exports in demo | Visible "DEMO — not validated" so demo ≠ production (good-faith / no-misrepresentation) | S | Honesty signal that builds trust, not erodes it |
| 1.5 | Curated synthetic dataset | 🟡 seed infra — `package.json` `seed`,`seed:e2e`→`db/seeds/002_seed_test_data.ts`, `db/seeds/` dir | **BUILD** — curated demo seed: the 6 workflows' scenarios + MIRA examples + **seeded batch master-data rows** + OOS records for reference (system-attributed, audit-trailed) | Idempotent seed script; data clearly synthetic; attributed to a seed account (QS-2) | Realistic demo without real/PHI data; also supplies `batch_id` lookups (CC-PILOT-2026-001 seeded-batch approach) | M | A demo on the buyer's actual pain (deviation→CAPA, inspection prep) |
| 1.6 | One-click demo reset | 🟡 tenant purge/retention — `jobs/tenant-deletion-executor.job.ts`, `jobs/data-retention.job.ts`, `purgeable_at` col | **BUILD** — demo-tenant reset that truncates demo data + re-seeds | Reset returns demo to clean seeded state in one action | Re-runnable sales demos | S | Clean, repeatable demos across prospects |
| 1.7 | Deviation / RCA / CAPA workflows | ✅ built — `deviations/service.ts` (gates `:587-654`), `rca/service.ts`, `capas/service.ts` | **CONNECT + seed** — exercise create→investigate→close on synthetic data | End-to-end demo runs on the 3 flows | The core QMS story | S | Shows workflow depth |
| 1.8 | Document Control (4 creation methods) | ✅ persist `documents/service.ts:608,621`; lifecycle `lifecycle.ts:20-25`; upload `document-library/routes.ts:80-152`; AI-gen via MIRA | **CONNECT + seed** — demo blank/template/upload/AI-gen → review → effective | All 4 methods reach `effective` in demo | Authoring → review → effective (GDocP) | S | Foundational QMS credibility |
| 1.9 | MIRA AI generation (governed) | ✅ advisory, RAG-cited, Annex-22-constrained — `ai/` + `oos-ai.service.ts:92-154` (strips classification/RC/disposition); provenance fields | **DEMO the provenance** — model + prompt hash + sources + edit delta + outcome label | Demo shows AI draft → human accept/override → provenance preserved | The differentiator done right (EU AI Act Art. 50 transparency; Annex 22 advisory) | S | **"AI you can take into an inspection"** — the wedge incumbents can't match |
| 1.10 | Inspection-readiness scorecard | 🟡 scoring/gap built `inspection-readiness/service.ts:801-947`; export absent | **CONNECT** — show the read-only scorecard on synthetic data | Scorecard renders with seeded readiness | Shows the readiness story (no export needed for demo) | S | Hits the buyer's most-hated chore (inspection prep) |
| 1.11 | OOS as reference/display in deviation | ✅ OOS lifecycle built — `oos-oot/routes.ts` (phase1/phase2/retest/`:166 disposition`); **but no `batch_id` in OOS module** | **CONNECT + BUILD-small** — display related OOS doc inside deviation; add the OOS→batch lookup/linkage (team open point) | Deviation surfaces the related OOS; OOS traces to its batch | Realistic investigation; demonstrates workflows cross modules | M | Demonstrates depth without building OOS workflow |

**Phase-1 net-new build:** 1.3 AI-path fix (M) · 1.4 banner (S) · 1.5 curated seed (M) · 1.6 reset (S) · 1.11 OOS→batch link (M). Everything else = connect/configure/test.

---

## PHASE 2 — VERIFIED BUILD (URS-39B) · *win the validation* · → Sep 01

Goal: close the integrity + completion gaps so the partner can validate. The audit gaps **are** the build list. Priority top-to-bottom.

| # | WP | Item | Exists today (file:line) | Eng action — BUILD / CONNECT / TEST (specifics) | Acceptance / test | Why (regulatory) | Eff | Client win |
|---|---|---|---|---|---|---|---|---|
| 2.1 | WP-4 | E-sig substrate verify on terminal decisions | 🔴 verifier `hitl/esig.service.ts:650`; only caller `infrastructure-governance.ts:84`. Store-only: `change-control/service.ts:964` (approve) + `:1526` (close, no esig param); `rca/service.ts:773-778`; `capas/service.ts:417-421`; `findings/service.ts:602-616` (`disposition_signature_id` declared `:67,103,142`, never written). Reference pattern to copy: `oos-oot/service.ts:710-732` | **CONNECT** — route CAPA close, finding disposition, RCA approve/reject, change-control approve+close through `validateEsignatureForRecord`; write bound `electronic_signatures` row; normalize failures to `ESIG_VERIFICATION_FAILED` | Forged/absent/cross-tenant esig → rejected, no state change, audit written; valid esig → bound row; regression on oos-oot/DQG | 21 CFR Part 11 §11.70 (sig–record binding) + §11.100; Annex 11 §14 | M | **#1 thing a pharma QA buyer checks** — Part 11 defensibility |
| 2.2 | WP-13b | Fail-closed AI audit | 🔴 `ai/ai-gateway.service.ts:100 llmAudit?`; `:228 if(this.llmAudit)`; `ai_requests` always logged `:210-225`; constructed WITHOUT audit at `gdp/plugin.ts:92`,`document-library/plugin.ts:32`,`hardening/plugin.ts:155` | **BUILD** — in regulated mode, require `llmAudit`; fail gateway construction/request if absent; write `llm_audit_log` (hash-chained) BEFORE inference returns | No inference runs without an `llm_audit_log` row in regulated mode (negative test on the 3 plugins) | EU GMP Annex 22 + EU AI Act Art. 12 (logging) | M | The AI-governance evidence pack that closes the deal |
| 2.3 | WP-12 | Inspection-readiness export package | 🔴 absent — no archiver/manifest/`createHash`/export route in `inspection/`,`inspection-readiness/`; scoring exists `inspection-readiness/service.ts:679-947`; unrelated pack at `ai-evidence/evidence-pack.service.ts` | **BUILD** — terminal export: evidence selection → completeness/gap → reviewer disposition (e-sig) → sealed **manifest + content hash** export (PDF/JSON); add export route | Export produces a hash-sealed, watermarked, e-signed pack; tamper-evident; reproducible | 21 CFR 11.10(b)(e) (accurate copies, audit), Annex 11 §8/§9 | L | The differentiator that removes weeks of inspection prep |
| 2.4 | WP-7 | Critical-deviation exec co-sign + SoD fix | 🟡 single approver `deviations/service.ts:683-702`, `minApprovers:1` `:689`; SoD enforces **reporter≠closer** `:615-618` (not investigator≠closer); reopen absent `workflow.ts:20-31` | **BUILD** — for `severity='critical'`, require exec co-sign (2nd authority, substrate-verified per 2.1); change SoD to investigator(`assigned_to`)≠closer | Critical close blocked without exec co-sign; investigator cannot close own deviation; existing gates regress-pass | EU GMP critical-deviation governance; SoD (Annex 11 §12, data integrity) | M | Real GxP rigor a QA head respects |
| 2.5 | WP-2 | Linkage consumers | 🟡 ~95 events emitted, ~10 consumed; `document_effective` orphaned `documents/service.ts:1061`; `oos_confirmed` no event `oos-oot/service.ts:753`; generic spawn not CAPA `config/workflow-auto-spawn.subscriber.ts:41-55` | **CONNECT** — add consumers: deviation/OOS-confirmed→CAPA, finding→CAPA, `document_effective`→training; emit `oos_confirmed` + `finding_capa_linked`; coverage test failing if an in-scope GxP event has no consumer | Each in-scope linkage fires end-to-end; coverage test green | Closed-loop QMS (ICH Q10 CAPA linkage); traceability | M | The end-to-end automation story |
| 2.6 | WP-9/10 | Closure/disposition e-sig + finding→CAPA link | 🟡 CAPA close store-only `capas/service.ts:417-421`; finding disposition authority-only `findings/service.ts:602-616`; finding→CAPA reverse-only `capas/service.ts:217-221`; no `finding_capa_links` table; conditional engine gate `workflow-builder.service.ts:1047-1090` no-ops `workflow-engine-binding.ts:297,358,383` | **BUILD/CONNECT** — substrate-verify CAPA closure + finding disposition (reuse 2.1); write `disposition_signature_id`; add `finding_capa_links` + `finding_capa_linked` event | CAPA/finding terminal e-sig verified + bound; finding→CAPA link queryable both directions | Part 11 binding + traceability (ICH Q10) | M | Closed-loop CAPA an auditor can follow |
| 2.7 | WP-6 | Hash-persist + distribution/read-ack | 🟡 content hash computed but transient `documents/service.ts:582,770-771` (not on `document_versions`); upload files carry `content_hash` `mig 068:26`; **no distribution-audience table, no read-ack** | **BUILD or DEFER (decide)** — persist `content_hash` on `document_versions`; build distribution audience + read-acknowledgment OR formally defer to Phase-2.x with a note | Effective version has a persisted, verifiable hash; distribution/ack decision recorded | ALCOA+ (Original/Accurate); controlled distribution (GDocP) | M (hash S; distribution L) | Document-control completeness |
| 2.8 | WP-11 | Training on document-effective | 🔴 `document_effective` orphaned; `training/service.ts:231 assignTraining` manual; notifications only react to `training_assigned` `notifications/event-subscriber.ts:141` | **CONNECT** (consumer `document_effective`→assignTraining) **OR** accept manual for pilot (WP-11 note) | Effective SOP auto-assigns training, OR a documented manual SOP step | Training-on-effective is a GxP expectation (Annex 11 §2) | S–M | Closed-loop training story |
| 2.9 | WP-1 | Tenant/scope isolation | 🟢 TDAL `core/tdal.ts:116-145,120-121` (215 files); RLS 132 migrations; `dedicated_db` mode | **TEST** — regression: cross-tenant read/write denied; single-tenant lock holds | No cross-tenant leakage in OQ | 21 CFR 11.10(d), Annex 11 §12 | S | Trust foundation under everything |
| 2.10 | WP-5 | Audit trail / hash-chain | 🟢 `core/audit-trail.ts:205-243` SHA-256 chain; append-only `migrations/260:38-40`; startup gate `audit-storage-gate.ts:58-130` | **TEST** — regression: tamper attempt rejected; `verifyRange` passes | Audit chain verifies; UPDATE/DELETE on audit denied | 21 CFR 11.10(e), Annex 11 §9 | S | "Your data is inspection-grade" |
| 2.11 | — | AI/handover gate in production | 🔴 same bypass as demo (`handover-bridge.service.ts:290` direct-create) | **BUILD** — gate handover writes through HITL + license/governance; ensure `ai_requests`+`llm_audit_log` on every AI-originated record | AI-originated record always has HITL + audit provenance | Annex 22 HITL (Art. 14 AI Act human oversight) | M | Consistent AI governance prod + demo |
| 2.12 | §7C | Validation pack execution | 🔴 not executed (pack drafted) | **TEST** — execute IQ/OQ/PQ on the hardened build; capture evidence; QA disposition | VSR drafted; Head of QA disposition recorded | Verification evidence for the partner (CSA/GAMP 5) | L | The validation-enablement pack (G-7) that lets the partner validate → **reference logo** |

**Phase-2 critical path:** 2.1 → 2.2 → 2.3 are the three that make-or-break the validation. 2.9/2.10 already strong (protect via regression).

---

## PHASE 3 — EXPANSION · *win expansion revenue* · post-go-live

Goal: extend to GMP-critical modules on the proven foundation — full validated modules, not thin slices.

| # | Item | Exists today (file:line) | Eng action — BUILD / VALIDATE | Acceptance / test | Why (regulatory) | Eff | Client win |
|---|---|---|---|---|---|---|---|
| 3.1 | Full URS-23 batch disposition (create→MBR→IPC→release→QP cert) | 🟡 `batch/service.ts:86 createMBR`, `:623 createBatchRecord` exist; e-sig gap `:256-297` (auto-mint); not validated | **BUILD + VALIDATE** full lifecycle; fix batch e-sig via 2.1 pattern; own URS-23 + RA + protocols | Full batch lifecycle validated; QP cert (Annex 16) path tested | GMP batch release = highest-stakes GMP decision; Annex 16 | XL | Completes the GMP story; expansion revenue |
| 3.2 | MBR-driven batch creation UI | 🔴 (out of pilot; seeded in P1/P2) | **BUILD** native create UI | Native batch creation replaces seed | Removes pilot seeded-data workaround | L | Native GMP authoring |
| 3.3 | Batch-hold trigger (DEC-16-27) | 🔴 de-scoped; deviation `batch_id` plain FK `deviations/service.ts:46,371-386`, no event | **BUILD** — deviation→batch hold cascade (emit `BATCH_HOLD_TRIGGERED`, URS-23 subscriber flips `lifecycle_state`) | Critical batch-affecting deviation holds the batch; bidirectional link | Realizes "a deviation holds the batch" control | M | The workflow-crosses-modules vision, fully wired |
| 3.4 | Full OOS operate-and-dispose validation (+ OOT) | ✅ OOS lifecycle built (`oos-oot/routes.ts` phase1/2/retest/disposition); OOT absent | **VALIDATE** OOS as in-scope; **BUILD** OOT alert/trend | OOS disposition validated; OOT trending live | OOS classification GMP-critical; FDA OOS Guidance | L | Deepens GMP coverage |
| 3.5 | Equipment / EM / stability / APQR | ⛔ later | **BUILD** (future) | per-module | Broader GxP | XL | Future TAM expansion |

**Phase-3 guardrails:** EU AI Act high-risk + Annex 22 **prohibit GenAI in batch/OOS critical decisions** — MIRA stays advisory-only, human-signed. Each module: own URS + risk assessment + validation. Verixa verifies; partner validates.

---

## Team questions — answered (What / Why / How / When)

Direct answers to the engineering team's open questions, cross-referenced to the build-map rows above.

| # | Team question | **What** (answer) | **Why** | **How** | **When** | Map ref |
|---|---|---|---|---|---|---|
| Q1 | Is the seeded-batch approach acceptable? (vs reference-correction) | **Yes — approved.** Seed minimal batch master-data; reference-correction is fallback only. | MBR-driven creation is out of pilot scope and not worth building for Sep-01; seeding makes `batch_id` lookup + deviation initiation work **without building the batch module**. | Controlled, repeatable seed inserts minimal rows (batch_number, product, site, status); deviation references via nullable `batch_id` FK (`deviations/service.ts:46`) — reference-only, no MBR lifecycle. | Phase 1 (demo seed) + Phase 2 (verification data); native creation → Phase 3. | 1.5, 3.1, 3.2 |
| Q2 | How does minimal batch master data land in URS-23 for the demo? | A **documented seed script**, not manual DB inserts. | Reproducibility (idempotent, QS-13) + attribution (QS-2) so demo/verification data is controlled and re-seedable. | Extend `db/seeds/002_seed_test_data.ts`; call `createBatchRecord` (`batch/service.ts:623`) or insert minimal rows; `created_by`=seed account; synthetic-flagged; aligned to validation-pack schema mapping. | Agree the script with engineering **before the demo** (Phase 1); formalize Phase 2. | 1.5 |
| Q3 | OOS → batch traceback — lookup/linkage approach? | Add a **batch reference on the OOS record** (preferred), or trace OOS→deviation→batch. | Confirmed gap: **no `batch_id` anywhere in `oos-oot`** today, so "find the batch behind this OOS" has no link — needed to surface the right docs. | **Option A (recommended):** nullable `batch_id` FK on `oos_investigations` — clean direct trace. **Option B:** join via the deviation's `batch_id` — no schema change, indirect. | Phase 1 (small build; needed for deviation-displays-OOS). Pick option with engineering first. | 1.11 |
| Q4 | Findings scope — patterns B/D in, A/C Phase-2? | **Confirmed.** B (from deviation investigation) + D (standalone) **IN**; A (internal audit) + C (regulatory/483) **Phase-2**. Not one of the 6, but available where others reach in. | B/D are the pilot's initiation paths; A/C depend on audit/inspection modules out of pilot. Lifecycle built but with WP-10 gaps. | Use existing Finding lifecycle for B/D; Phase 2 substrate-verify disposition (`findings/service.ts:602-616`) + add `finding_capa_links` + event. | B/D Phase 1–2; WP-10 hardening Phase 2; A/C Phase 3. | 2.6 |
| Q5 | OOS lifecycle in Phase 1 — reference or full validation? | **Reference/display IN Phase 1**; full OOS operate-and-dispose validation → **Phase 3** (decide together). | OOS code is built + well-governed (AI Annex-22-constrained), so display/reference is low-risk; validating the standalone disposition workflow expands the GMP-critical surface — defer unless wanted. | Deviation reads the related OOS via the Q3 link; no OOS disposition validation committed for pilot. (Doc fix: relax the "OOS not reachable" line in URS-39B/VRX-PILOT-001.) | Reference/display Phase 1; full OOS validation Phase 3. | 1.11, 3.4 |

**Two items to close with engineering at the walkthrough:** the seed script (Q2) and the OOS→batch link option (Q3) — both small, both needed before the demo.

---

## Client-win thread
- **Phase 1 wins the meeting** — a credible, governed, differentiated demo (AI-with-provenance + inspection-readiness) on synthetic data. Restraint reads as credibility to a QA buyer.
- **Phase 2 wins the validation** — closing the Part 11 e-sig gap (2.1), fail-closed AI audit (2.2), and inspection export (2.3) are the three things that let a pharma partner validate intended use and become a reference logo by Sep-01.
- **Phase 3 wins expansion** — batch/OOS as full validated modules: the land-and-expand that grows one partner into account revenue.

## Honest notes
- "Exists today" = code at `3bd2fe47`. **Built ≠ validated** — the 🟡/✅ Phase-2 items exist but carry the e-sig/linkage gaps in their own rows; fine for demo/reference, must be hardened for controlled GxP use.
- Effort = rough T-shirt sizing, **Engineering to confirm** with the walkthrough + estimate.
- Two open Engineering yes/no's feed this map: distribution/read-ack scope (2.7) and training automation vs manual (2.8).
- Batch master data for the pilot lands via a **controlled synthetic seed** (reference-only), not native creation (CC-PILOT-2026-001).
