# Verixa — User Requirements Specification

# Module 30: Notifications, Delivery Channels, and Communication Governance

| Field | Value |
|---|---|
| Document ID | VRX-URS-30 |
| Version | 1.0 |
| Status | Final — ready for QA, Validation, Regulatory Affairs, Information Security (Primary Owner — credential governance), Manufacturing Head, Site Quality Lead, Qualified Person Authority, and Founder approval. URS approval is separate from validation execution. This document becomes "Approved Controlled URS — released for engineering implementation and validation planning" only after signature capture in the Document Approval block. It becomes "Released for validation execution" only after the module migration evidence gate (URS-30-VAL-008) and validation evidence pack are satisfied. |
| Document Type | User Requirements Specification (URS) |
| GAMP 5 Category | Category 5 — Custom Application |
| Code Modules | Target implementation binding: expected primary code module `notifications`, expected API mounts `/api/v1/notifications/*` (canonical), expected supporting modules `audit-log`, `auth/rbac`, `electronic_signatures`, `hitl`, `documents` (URS-12 — controlled storage of rendered notification snapshots), expected event-bus emission for `notification_template_created`, `notification_template_released_effective`, `notification_template_superseded`, `notification_channel_created`, `notification_channel_tested`, `notification_channel_secret_rotated`, `notification_send_dispatched`, `notification_send_delivered`, `notification_send_failed`, `notification_send_bounced`, `notification_email_queued`, `notification_email_sent`, `notification_email_terminal_failed`, `notification_digest_compiled`, `notification_digest_dispatched`, `notification_inbox_row_created`, `notification_inbox_acknowledged`, `notification_preference_changed`, `notification_program_locked`, `notification_program_reopened`, expected MIRA context integration through `useMiraRecord('notification_template', id)` and `useMiraRecord('notification_send', id)` mappings, expected URS-12 Document Control linkage for **immutable rendered-content snapshot storage** per DEC-30-08, expected URS-13 Change Control linkage for template effective release + channel-config effective release, expected URS-21 findings emission for chronic delivery failures + missed mandatory notifications, expected URS-18 CAPA emission for chronic delivery failures, expected **inbound consumer integration with every other URS module** as the platform notification dispatcher (URS-13 / URS-14 / URS-15 / URS-16 / URS-17 / URS-18 / URS-19 / URS-20 / URS-21 / URS-22 / URS-23 / URS-24 / URS-25 / URS-26 / URS-27 / URS-28 / URS-29 / URS-31.URS-35 — all emit events that Module 30 consumes for delivery), expected Authority Profile + HITL + e-signature integration for non-bypassable manual send + template release + channel release + program lock + reopen, expected platform_admin / super_admin support / break-glass only paths. Implementation evidence remains subject to repository verification and validation evidence. |
| Architecture Bindings | This module is subject to **ARCH-AI-001 AI Optionality and Manual Continuity**. Verixa internally classifies this AI surface as **limited-risk under internal AI governance**, aligned with the limited-risk transparency approach in **EU AI Act (Regulation 2024/1689) Article 13**. AI-assisted notification surfaces (AI template-content drafting, AI digest summarization, AI recipient-list suggestion, MIRA notification copilot) are advisory only under internal AI governance aligned with EU AI Act Article 13 transparency principles. Every AI surface shall provide a fully functional manual notification, template authoring, and dispatch path; notification template authoring, channel configuration, manual send, automated send, digest compile, and inbox acknowledgment shall be executable when AI services are disabled, degraded, or overridden by the notification program owner. **AI-generated notification content shall be visibly labeled as advisory; no AI service shall be the sole path to release a template, send a notification, dispatch a digest, or acknowledge an inbox item.** This module binds ARCH-AI-001 AC-1, AC-2, AC-3, AC-4, and AC-7. Verixa treats **EU GMP Annex 22 Draft 2025 §7** as an internal forward-looking architectural control (not an enacted predicate rule); under that internal control, generative AI may draft advisory notification template content and digest summaries only with mandatory human acceptance recorded; generative / probabilistic AI is **PROHIBITED from being the sole path to send a notification, release a template to effective state, dispatch a digest, or finalize a delivery decision**. Static deterministic AI may surface template-content suggestions based on similar prior notifications and recipient-list recommendations as advisory help. Jurisdiction-specific legal enforceability of Annex 22 and the EU AI Act remains subject to a future jurisdiction-specific legal assessment. |
| Regulatory Classification | Critical infrastructure substrate — operates the canonical Notifications and Delivery Channels system covering: (a) the notification-template registry with **controlled lifecycle (`draft → under_review → effective → superseded → archived` with version-immutability after `effective` release per DEC-30-03 per DEC-30-03 — the controlled five-state lifecycle replaces any prior two-state Active/Inactive model)**; (b) the notification-channel registry with **secret-store credential governance** (`authentication_token_hash` is integrity-verification only, NOT a usable bearer token; live credentials via tenant-controlled secret store per DEC-30-04); (c) the **mandatory-alert allowlist gate** ensuring critical regulated events (release approvals, OOS classifications, deviation closures, CAPA effectiveness expirations, inspection observations, training overdue, regulatory commitment overdue, batch-record approval, stability OOS, EM excursions) are dispatched on at least one channel **regardless of user preferences** per DEC-30-05 ; (d) the **immutable rendered-content snapshot** stored per send (template version + rendered subject + rendered body) for inspection traceability per DEC-30-08 ; (e) the email-queue lifecycle (`pending → sent | failed → terminal_failed` with retry policy + exponential backoff) per DEC-30-06; (f) the digest lifecycle with **compiled-content evidence** (per-recipient digest items + recipient-level send trace) per DEC-30-07 ; (g) the **inbox-acknowledgment lifecycle** with per-row audit on `markAsRead` / `markAllAsRead` per DEC-30-09; (h) the multi-dimensional context capture (`tenant_id` mandatory, `user_id` for inbox / preference, `event_type` for routing, `severity` for escalation); (i) the canonical API contract `/api/v1/notifications/*` ; (j) the typed schema validation across every route; (k) the controlled frontend route surface; (l) the audit-trail coverage with reason-for-change discipline + per-inbox-row read audit per DEC-30-10 ; (m) the Authority/HITL/e-signature substrate on every regulated final action per DEC-30-04 ; (n) the AI-assisted template-content / digest-summary substrate with **provenance + mandatory human acceptance** per DEC-30-13 (target requirement, ARCH-AI-001 binding); (o) the post-locked record immutability across the notification program; (p) the controlled reopen workflow with executive authority co-sign and Qualified Person co-sign per DEC-30-22; (q) the canonical findings-source emission to URS-21 for chronic delivery failures + missed mandatory notifications per DEC-30-15; (r) the canonical CAPA-source emission to URS-18 for chronic delivery failures per DEC-30-16; (s) the **inbound consumer integration** as the platform-wide notification dispatcher consuming events from every other URS module per DEC-30-23; (t) the MIRA copilot read-only context integration on notification records, and the per-jurisdictional regulatory expectations under FDA 21 CFR Part 11 §11.10(a) (validation), §11.10(e) (audit trails), §11.50 (signature manifestations), §11.70 (signature/record linking) — primary FDA predicate; **EU GMP Annex 11 §4 (Validation), §5 (Data — including notification content integrity), §9 (Audit Trails), §12 (Security including credential governance), §14 (Electronic Records / Signatures), §16 (Incident Management — notification of incidents)** — primary EU predicate; EU GMP Annex 22 Draft 2025 §7 (HITL — internal forward-looking control); EU AI Act (Regulation 2024/1689) Art. 13 (internal forward-looking control); MHRA Data Integrity Guidance (ALCOA+) — applies to delivery records as electronic records; GAMP 5 Cat 5; **FDA Computer Software Assurance (CSA) — September 2025 Final Guidance** (notifications classified as not-high-process-risk advisory infrastructure EXCEPT where mandatory-alert gate applies — those become high-process-risk and are subject to rigorous assurance per DEC-30-05); **ISO/IEC 27001** (information security — credential governance for outbound channels — Slack / Teams / Webhook / SMTP); and India CDSCO Schedule M (Revised) §16 (Records and Reports — applicable to notification delivery records) subject to a future jurisdiction-specific legal assessment for Verixa's exact CDSCO obligations. |
| Date of Issue | 2026-05-07 |
| Module Owner (Engineering) | Quality / Notifications Squad |
| Module Owner (Quality Validation) | CSV / CSA Lead — Notifications |
| Module Owner (Compliance) | Information Security (Primary Owner — channel credential governance), Quality Assurance, Manufacturing, Regulatory Affairs |
| Approving Authority | Founder / Chairman & MD; QA Head; Manufacturing Head; Validation Head; RA Head; **Information Security Head (Primary Owner)**; Qualified Person (QP) Authority; Site Quality Lead |

---

## 0. Document Framing

### 0.1 Purpose of this document

This URS defines the target expected state for Verixa's Notifications, Delivery Channels, and Communication Governance module (Module 30). It is the binding contract between product, engineering, quality validation, regulatory affairs, information security (primary owner — channel credential governance), manufacturing, the Qualified Person authority, distribution, laboratory operations, and the executive authority for the design, implementation, validation, release, and on-going periodic review of the regulated notifications substrate: the notification-template registry with controlled lifecycle and version-immutability per DEC-30-03; the notification-channel registry with secret-store credential governance per DEC-30-04; the mandatory-alert allowlist gate ensuring critical regulated events are dispatched regardless of user preferences per DEC-30-05; the email-queue lifecycle with retry policy per DEC-30-06; the digest lifecycle with compiled-content evidence per DEC-30-07; the immutable rendered-content snapshot per DEC-30-08; the inbox-acknowledgment lifecycle with per-row audit per DEC-30-09; the multi-dimensional context capture; the canonical API contract `/api/v1/notifications/*`; the typed schema validation; the controlled frontend route surface; the audit-trail coverage with reason-for-change discipline per DEC-30-10; the Authority/HITL/e-signature substrate on every regulated final action per DEC-30-04; the AI-assisted template / digest substrate with provenance and mandatory human acceptance per DEC-30-13; the post-locked record immutability; the controlled reopen workflow per DEC-30-22; the canonical findings emission to URS-21 per DEC-30-15; the canonical CAPA emission to URS-18 per DEC-30-16; the **inbound consumer integration** as the platform-wide notification dispatcher per DEC-30-23; the MIRA copilot read-only context integration with **AI advisory only — never the sole path to send a notification, release a template, dispatch a digest, or acknowledge an inbox item** under the internal Annex 22 §7 control; the audit trail coverage with reason-for-change discipline; and the per-jurisdictional regulatory expectations. Compliance with this URS is mandatory.

### 0.2 Audience

Engineering, QA, RA, Manufacturing, Qualified Person Authority, Distribution, Laboratory Operations, Validation, **Information Security** (primary owner for channel credential governance), executive authority, the platform's Implementation team, internal and external auditors, and inspectors from regulatory bodies (FDA, EMA, MHRA, Health Canada, CDSCO, PIC/S, PMDA, WHO). The plain-language primer (§0.4) and worked examples (§3.5) make Module 30 accessible to non-domain engineers, product owners, validation engineers, and quality investigators.

### 0.3 Cross-references

- **URS-01** Authentication, Session & Access Control — identity envelope for every notification mutation
- **URS-02** RBAC & Permissions — the `notifications:*`, `notifications:template:*`, `notifications:channel:*`, `notifications:send:*`, `notifications:digest:*`, `notifications:inbox:*`, `notifications:preferences:*`, `notifications:channel:secret_rotate:*` permission set
- **URS-03** Context Gate & Approval Scope — context-gate enforcement
- **URS-04** Workflow / HITL / E-Signature / Approval Authority — Controlled Approval Modal contract for template release / channel release / manual send / digest dispatch / program lock / reopen
- **URS-05** Authority Profile / Delegation / SoD — Authority Profiles consumed (`notification_template_release_authority`, `notification_channel_release_authority`, `notification_manual_send_authority`, `notification_digest_dispatch_authority`, `qualified_person_authority`, `final_quality_approver`, `executive_authority`, `information_security_authority`)
- **URS-06** Audit Trail / Hash Chain / Tamper-Evident — append-only audit substrate
- **URS-07** Study Management — optional study-scope dimension for study-bound notifications
- **URS-08** Tenant Management Lifecycle — tenant context for notification records
- **URS-09** Site / Facility Management — site-scope inherited via `studies` parent (where applicable)
- **URS-10** Product / SKU / Drug Master Data — optional product context
- **URS-12** Document Control / SOP — **primary linkage**: immutable rendered-content snapshot storage per DEC-30-08
- **URS-13** Change Control — template effective-release linkage; channel-config effective-release linkage
- **URS-14** Complaints — **inbound consumer**: complaint lifecycle events emit notifications
- **URS-15** OOS / OOT — inbound consumer: OOS classifications emit **mandatory** notifications per DEC-30-05
- **URS-16** Deviations — inbound consumer: deviation closures emit notifications
- **URS-17** RCA — inbound consumer
- **URS-18** CAPA — inbound consumer (CAPA effectiveness expirations are mandatory) + primary downstream consumer for chronic delivery-failure CAPA per DEC-30-16
- **URS-19** Risk Assessment — inbound consumer
- **URS-20** Reviews — inbound consumer
- **URS-21** Findings — inbound consumer (overdue findings) + primary downstream consumer for chronic delivery findings + missed mandatory notification findings per DEC-30-15
- **URS-22** Inspection Mgmt — inbound consumer (inspection observations are mandatory)
- **URS-23** Batch Records — inbound consumer (batch-record approval is mandatory; QP release ceremony notifications)
- **URS-24** Stability — inbound consumer (stability OOS is mandatory; shelf-life claim approval notifications)
- **URS-25** Environmental Monitoring — inbound consumer (EM excursions are mandatory)
- **URS-26** APQR — inbound consumer (APQR approval notifications)
- **URS-27** Regulatory Intelligence — inbound consumer (regulatory commitment due-soon and overdue events are mandatory)
- **URS-28** Training — inbound consumer (training assignment due-soon and overdue events; training-gap overdue is mandatory)
- **URS-29** Screen Reader / Data Capture — inbound consumer (capture failures, stale ingestion queue findings)
- **URS-31** DQG — data-quality gate evidence for delivery completeness
- **URS-32** MIRA AI — read-only MIRA copilot context integration; AI advisory drafting only with mandatory human acceptance per DEC-30-13
- **URS-33** GMP Manufacturing — inbound consumer
- **URS-34** GDP Distribution — inbound consumer
- **URS-35** Infrastructure / Backup-Restore — operational continuity; secret-store linkage for outbound channel credentials per DEC-30-04

### 0.4 Plain-language primer

In a regulated pharmaceutical operation, **notifications** are not a cosmetic feature — they are the controlled communication substrate that ensures regulated events reach accountable parties in time to act. Module 30 is the platform-wide notification dispatcher: every other URS module emits events (release approvals, OOS classifications, deviation closures, CAPA effectiveness expirations, inspection observations, training overdue, regulatory commitment overdue, batch-record approval, stability OOS, EM excursions, etc.), and Module 30 dispatches those events through controlled delivery channels (email, in-app inbox + websocket push, Slack, Microsoft Teams, generic webhook) according to user preferences AND the **mandatory-alert allowlist** for events the regulator considers critical. Module 30 is in regulatory scope under: FDA 21 CFR Part 11 §11.10(a) (validation), §11.10(e) (audit trails), §11.50 (signature manifestations) where notifications carry signed actions, §11.70 (signature/record linking); EU GMP Annex 11 §4 (Validation), §5 (Data — including notification content integrity), §9 (Audit Trails), §12 (Security including credential governance), §14 (Electronic Records / Signatures), §16 (Incident Management — notification of incidents); MHRA Data Integrity Guidance (ALCOA+ applies to delivery records as electronic records); FDA Computer Software Assurance (CSA) — September 2025 Final Guidance (notifications carrying mandatory-alert gate are high-process-risk per DEC-30-05).

The most common mistake in regulated notification handling is **storing channel `authentication_token_hash` and using it as a live bearer token** for outbound delivery to Slack / Teams / Webhook. The regulator's tell-tale at inspection is a Teams/Slack outbound POST authenticating with a SHA-256 hash. Module 30 enforces the pathway: `authentication_token_hash` is an **integrity-verification field only**; live credentials for outbound delivery are sourced at send time from the tenant-controlled secret store per DEC-30-04 (parallel to URS-29 DEC-29-07 IMAP credential governance). The second most common mistake is **digests transitioning from `pending` to `queued` without compiled-content evidence**. Module 30 enforces the pathway: digest dispatch persists `notification_digest_items` (per-recipient compiled items) + recipient-level send trace per DEC-30-07.

The third most common mistake is **rendered notification content not preserved with template version**. The regulator asks "what exact subject and body did the user see?", and the only available answer is "we render at send time from the current template" — but the current template may have changed since. Module 30 enforces the pathway: every send persists an **immutable rendered-content snapshot** (template version + rendered subject + rendered body) per DEC-30-08, providing inspection traceability to the exact content delivered. The fourth most common mistake is **inbox read state changes not individually audit logged**. Module 30 enforces the pathway: `markAsRead` and `markAllAsRead` emit per-row audit events per DEC-30-09 (closes the canonical evidence gap).

The fifth (and most consequential for safety) mistake is **mandatory regulated alerts being suppressed by user preferences**. A user opting out of all notifications and then missing an OOS classification or stability failure is an existential business risk. Module 30 enforces the pathway: a **mandatory-alert allowlist** (configurable per tenant; default includes release approvals, OOS classifications, deviation closures, CAPA effectiveness expirations, inspection observations, training overdue, regulatory commitment overdue, batch-record approval, stability OOS, EM excursions) ensures that for events on the allowlist **at least one channel is forced regardless of user preferences** per DEC-30-05. Default forced channel is email; in-app inbox is always populated for mandatory events.

The **AI-assistance** dimension is light-touch but governed. Static deterministic AI may surface template-content suggestions based on similar prior notifications and recipient-list recommendations as advisory help. **Generative AI (LLMs / MIRA copilot) is PROHIBITED from being the sole path to send a notification, release a template, dispatch a digest, or acknowledge an inbox item** under the internal Annex 22 §7 control. MIRA copilot may draft advisory template content and digest summaries via the controlled `notification_ai_assistance` substructure with full provenance + mandatory human acceptance per DEC-30-13.

The **two-step release path** mirrors every other Module: this URS becomes "Approved Controlled URS — released for engineering implementation and validation planning" upon signature capture in the Document Approval block; it becomes "Released for validation execution" only after URS-30-VAL-008 (Migration Evidence Gate) and the §17 validation evidence pack are satisfied.

### 0.5 Conventions

Each requirement has a unique identifier. "MUST" denotes a mandatory requirement; "SHOULD" denotes a strong recommendation; "MAY" denotes an option. The document is self-contained: front end (§5), back end (§6), data model (§6.2), application programming interface (§6.3), workflow (§6.4), business rules (§6.5), audit (§6.6), security (§12), regulatory mapping (§14), test cases (§16), and validation evidence (§17) are all in this single file. Every requirement is mandatory unless explicitly marked SHOULD or MAY.

### 0.6 Glossary

| Term | Definition |
|---|---|
| Notification template | A controlled-template document defining the subject + body template (with placeholders) for a specific `event_type`; lifecycle `draft → under_review → effective → superseded → archived` per DEC-30-03; immutable historical versions. |
| Notification channel | A controlled outbound delivery channel (email / Slack / Teams / Webhook / SMTP / in-app + websocket); credentials via secret store per DEC-30-04. |
| Mandatory-alert allowlist | A tenant-configurable list of `event_type` values that MUST be dispatched on at least one channel regardless of user preferences per DEC-30-05. |
| Rendered content snapshot | The immutable subject + body + template-version captured at send time per DEC-30-08; the system-of-record for "what the user actually saw". |
| Email queue | The persisted email-send queue with lifecycle `pending → sent | failed | bounced → terminal_failed` and retry policy with exponential backoff per DEC-30-06. |
| Digest | A scheduled batched notification per user / event-class; lifecycle `pending → queued → sent | failed` with per-recipient `notification_digest_items` per DEC-30-07. |
| Inbox row | A persisted in-app inbox notification with lifecycle `unread → read → soft_deleted`; per-row audit on read per DEC-30-09. |
| Notification preference | A user-level preference (per `event_type` × per channel) controlling whether the user receives a notification; **does NOT override the mandatory-alert allowlist** per DEC-30-05. |
| Notification send | The orchestration record persisting one send event with template version, recipient list, channel set, audit attribution. |
| Reopen | A governed transition event from `locked → in_progress` requiring `executive_authority` co-sign AND `qualified_person_authority` co-sign + documented reason; appends a new program iteration without mutating prior locked evidence per DEC-30-22. |
| ARCH-AI-001 | Platform architecture binding requiring manual continuity for every AI surface (AC-1, AC-2, AC-3, AC-4, AC-7). |
| Annex 22 | EU GMP Annex 22 (Draft 2025) §7. Verixa treats Annex 22 §7 + EU AI Act high-risk / transparency as internal forward-looking AI governance controls. AI may draft advisory template content / digest summaries with mandatory human acceptance; AI is prohibited from being the sole path to send, release a template, dispatch a digest, or acknowledge an inbox item. Binding predicate-rule obligations remain those listed in §14. |
| MIRA | The platform's read-only AI copilot service; for Module 30 MIRA may propose advisory drafts via `notification_ai_assistance`; no MIRA write paths to system-of-record notification fields without explicit human confirmation; no AI sends notifications. |
| Secret store | Tenant-controlled secret-management substrate (AWS Secrets Manager / HashiCorp Vault / Azure Key Vault / GCP Secret Manager) for outbound channel credentials per DEC-30-04. |

### 0.7 Module-30 architectural picture

```mermaid
flowchart TD
 EVT[Event Bus from URS-13/-14/-15/-16/-17/-18/-19/-20/-21/-22/-23/-24/-25/-26/-27/-28/-29/-31/-33/-34] --> SUB[Event Subscribers]
 SUB --> SVC[Notification Service]
 TPL[/Notification Templates — controlled lifecycle/]
 CH[/Notification Channels — secret store credentials/]
 PRF[/Preferences/]
 MA[/Mandatory-Alert Allowlist/]
 AI[MIRA AI] --> AIA[/Notification AI Assistance — advisory + provenance + acceptance/]
 SVC --> TPL
 SVC --> CH
 SVC --> PRF
 SVC --> MA
 SVC --> RND[Render Subject/Body with template version]
 RND --> SNAP[Immutable Rendered-Content Snapshot — DEC-30-08]
 RND --> EQ[/Email Queue — retry + backoff/]
 RND --> WH[/Slack / Teams / Webhook — credentials from secret store/]
 RND --> WS[Websocket Push]
 RND --> INB[/Inbox Row — per-row read audit/]
 EQ --> TX[SMTP Transport]
 TX --> SENT[sent | failed | bounced]
 SENT -. retry.-> EQ
 WH --> EXT[External Service]
 RND --> AUD[Audit Trail]
 DIG[/Digests/]
 DIG --> COMP[Compile per-recipient items — DEC-30-07]
 COMP --> EQ
 ADM[Admin Manual Send] --> SVC
 M21[URS-21 Findings] <-- chronic delivery failure
 M18[URS-18 CAPA] <-- chronic delivery failure CAPA
 LOCK[Program Lock] --> SVC
 LOCK -. governed reopen + executive + QP co-sign.-> SVC
```

The platform shall implement: a controlled notification-template lifecycle per DEC-30-03; secret-store credential governance for outbound channels per DEC-30-04; mandatory-alert allowlist per DEC-30-05; email-queue retry + backoff per DEC-30-06; digest compile with per-recipient evidence per DEC-30-07; immutable rendered-content snapshot per DEC-30-08; per-row inbox read audit per DEC-30-09; canonical API contract `/api/v1/notifications/*`; typed schema validation; controlled frontend route surface; audit-trail coverage with reason-for-change discipline per DEC-30-10; Authority/HITL/e-signature substrate per DEC-30-04; AI-assisted template / digest substrate with provenance + mandatory human acceptance per DEC-30-13; post-locked record immutability; governed reopen with executive + QP co-sign per DEC-30-22; canonical findings/CAPA emission per DEC-30-15.16; inbound consumer integration with every other URS module per DEC-30-23; MIRA copilot read-only with advisory drafting only; and per-jurisdictional regulatory expectations.

### 0.8 Locked Launch Controls

| Locked control | Authority | Rationale |
|---|---|---|
| Two-step release path: signature → engineering implementation → validation execution | DEC-30-01 / VAL-008 | Mirrors every other Module. |
| "No Module 30 internal decisions outstanding" | §11.6 | Captured in locked decisions DEC-30-01..DEC-30-23 (§3.2). |
| `platform_admin` / `super_admin` support / break-glass only | DEC-30-20 / SoD-30-07 | Operating-tenant notification ownership is the regulated path. |
| Target implementation binding language | Module bindings | URS specifies expected implementation. |
| AI overclaim posture as **internal forward-looking governance** with **GenAI prohibition in send / template-release / digest-dispatch / inbox-acknowledgment** | Architecture Bindings | EU GMP Annex 22 Draft 2025 §7 + EU AI Act Art. 13 treated as internal controls. AI may draft advisory; AI cannot finalize delivery decisions. |
| Enumerated error codes | §6.7 | Stable machine-readable error contract. |
| JSON multi-signature evidence as **derived snapshot** | §6.6 | The `electronic_signatures` substrate is the system of record. |
| India CDSCO §16 row | §14 | India CDSCO Records and Reports captured (subject to a future jurisdiction-specific legal assessment). |
| Version 1.0 posture | Header | First binding version. |
| Canonical API mount `/api/v1/notifications/*` | DEC-30-01 / M30-DR-001 | Frontend hooks aligned to canonical `/api/v1/screen-reader/*` mount; route comments aligned. |
| Notification-template controlled lifecycle + version immutability | DEC-30-03 / M30-DR-003 | `draft → under_review → effective → superseded → archived` (replaces any prior two-state Active/Inactive model); URS-13 CR linkage on effective release. |
| **Channel secret-store credential governance** | DEC-30-04 / M30-DR-004 | `authentication_token_hash` is integrity-verification only; live credentials via secret store. |
| **Mandatory-alert allowlist gate** | DEC-30-05 / M30-DR-005 | Critical regulated events forced on at least one channel regardless of user preferences. |
| Email-queue retry + backoff | DEC-30-06 / M30-DR-005 | `pending → sent | failed | bounced → terminal_failed` with configurable retry policy. |
| Digest compile evidence | DEC-30-07 / M30-DR-007 | `notification_digest_items` + per-recipient send trace; mandates compile-step evidence. |
| **Immutable rendered-content snapshot per send** | DEC-30-08 / M30-DR-006 | Template version + rendered subject + rendered body persisted per send for inspection traceability. |
| **Per-row inbox read audit** | DEC-30-09 / M30-DR-008 | `markAsRead` + `markAllAsRead` emit explicit per-row audit events for inbox read-state. |
| Audit-trail coverage + reason-for-change discipline | DEC-30-10 / M30-DR-009 | Manual send / template release / channel release / digest dispatch / lock / reopen all audited with reason. |
| Authority/HITL/e-sign on every regulated final action | DEC-30-04 / M30-DR-010 | Manual send / template release / channel release / digest dispatch / program lock / reopen gated. |
| Frontend route surface alignment | DEC-30-12 | All notification dashboard CTAs resolve to real pages. |
| AI-assisted template-content / digest substrate with provenance + mandatory human acceptance (target requirement) | DEC-30-13 / ARCH-AI-001 | `notification_ai_assistance` table; advisory only; AI cannot sign template release / send / dispatch. |
| Inbound consumer integration as platform-wide dispatcher (target requirement) | DEC-30-23 | Module 30 consumes events from every other URS module. |
| Bound e-signature persistence on every regulated final action | DEC-30-04 / DEC-30-23 | Manual send / template release / channel release / digest dispatch / program lock / reopen — all carry bound e-signature. |
| Governed reopen pattern (`locked → in_progress`) | DEC-30-22 / SoD-30-06 | Append-only iteration; executive + QP co-sign; does NOT mutate prior locked evidence. |

---

## 1. Scope and Out-of-Scope

### 1.1 In-scope

- The notification-template registry with controlled lifecycle and version immutability.
- The notification-channel registry with secret-store credential governance.
- The mandatory-alert allowlist gate.
- The email-queue lifecycle with retry + backoff.
- The digest lifecycle with compiled-content evidence.
- The immutable rendered-content snapshot per send.
- The inbox-acknowledgment lifecycle with per-row audit.
- The notification-preference registry.
- The Authority/HITL/e-signature substrate on every regulated final action.
- The audit-trail coverage with reason-for-change discipline.
- The MIRA copilot read-only context integration (advisory drafting only).
- The AI-assisted template / digest substrate with provenance + mandatory human acceptance.
- The findings emission to URS-21.
- The CAPA emission to URS-18.
- The change-control linkage to URS-13.
- The URS-12 Document Control integration for rendered-content snapshot storage.
- The inbound consumer integration with every other URS module.
- The governed reopen workflow.
- The per-jurisdictional regulatory expectations.

### 1.2 Out-of-scope

- The CAPA register itself (URS-18).
- The change-control register itself (URS-13).
- The findings register itself (URS-21).
- The document-control register itself (URS-12).
- The MIRA copilot service itself (URS-32).
- The secret-store substrate itself (URS-35 owns secret-store integration; this URS consumes secret-store references).
- SMS / push notification (mobile) channels — out of scope for v1.0; future-state.
- Voice call channels — out of scope.
- Vendor-specific delivery analytics (e.g., SendGrid analytics dashboards) — out of scope; tenant uses platform delivery metrics.

---

## 2. Preconditions, Dependencies, Constraints

### 2.1 Operating preconditions

The following preconditions MUST hold for this URS to apply at validation time. Each bullet is a binding precondition; deviations require a controlled exception per URS-13 Change Control.

- The platform's authentication and session substrate (URS-01), RBAC (URS-02), context gate (URS-03), HITL / e-sign (URS-04), Authority Profile registry (URS-05), audit-trail hash-chain (URS-06), document-control (URS-12), change-control (URS-13), and MIRA AI (URS-32), and infrastructure secret-store (URS-35) are released and operational at validation time.
- Notification program owners, template release authority, channel release authority, manual send authority, Qualified Person, Information Security authority are trained, attributable users with documented authority.
- AI-assisted notification surfaces are advisory only.
- The tenant operating jurisdiction(s) are configured.

### 2.2 Dependencies

- URS-01.URS-29, URS-31.URS-35 platform contracts (every other URS module is an inbound consumer).
- The `electronic_signatures` substrate.
- The `authority` substrate.
- The `hitl` substrate.
- The `audit_trail` substrate.
- The `documents` substrate (URS-12 — rendered content snapshot storage).
- The `secret_store` substrate (URS-35 — outbound channel credential governance per DEC-30-04).
- The `change_control` substrate (URS-13).

### 2.3 Constraints

- The canonical API mount is `/api/v1/notifications/*`. No frontend hook may use `/api/notifications/*` (extra `/api`).
- AI-assisted content is advisory-only; **no AI service shall be the sole path to send a notification, release a template, dispatch a digest, or acknowledge an inbox item**.
- Outbound channel credentials MUST be sourced from secret store; `authentication_token_hash` is integrity-verification only per DEC-30-04.
- Mandatory-alert allowlist events MUST be dispatched on at least one channel regardless of user preferences per DEC-30-05.
- Effective notification-template versions are immutable; revisions create new version rows.
- Rendered-content snapshot per send is immutable per DEC-30-08.
- Inbox `markAsRead` / `markAllAsRead` emit explicit audit events per DEC-30-09.

---

## 3. Closed Launch Decisions

### 3.1 Decision register

| Decision ID | Title | Locked decision |
|---|---|---|
| DEC-30-01 | Two-step release path + canonical API contract | Module 30 follows the same two-step release path; canonical API mount `/api/v1/notifications/*`; all hooks use canonical relative `/notifications/*` paths; route comments aligned . |
| DEC-30-02 | Multi-dimensional context model | `tenant_id` mandatory, `user_id` for inbox / preference, `event_type` mandatory for routing, `severity` (ENUM `info` / `warning` / `critical`) for escalation, `study_id` optional, `product_id` optional, `source_record_type` + `source_record_id` for the originating record. |
| DEC-30-03 | Notification-template controlled lifecycle + version immutability | Template lifecycle is `draft → under_review → effective → superseded → archived` (replaces Active/Inactive two-state); release to `effective` requires `notification_template_release_authority` + HITL + bound e-signature + URS-13 change-request linkage per DEC-30-19; revisions create new version rows with `template_version_snapshot`; superseded versions are immutable; the **at most one `effective` version per `(tenant_id, event_type, language_code)`** invariant is enforced via partial unique index . |
| DEC-30-04 | Channel secret-store credential governance + Authority/HITL/e-sign on channel release | Notification-channel records persist `authentication_token_hash` for **integrity-verification only** (NOT a usable bearer token); live credentials for outbound delivery (Slack / Teams / Webhook bearer tokens, SMTP credentials) are sourced at send time from tenant-controlled secret store via `secret_store_ref` (TEXT — reference to secret-store path, e.g., `aws-secrets-manager:tenant-id/slack-webhook-token`); channel release to `effective` requires `notification_channel_release_authority` + HITL + bound e-signature; channel test action does not replay live credentials in the test response (/ M30-DR-010 — security gap). |
| DEC-30-05 | Mandatory-alert allowlist gate | A tenant-configurable mandatory-alert allowlist (`notification_mandatory_alerts` table) defines `event_type` values that MUST be dispatched on at least one channel regardless of user preferences; default allowlist includes: `regulatory_submission_approved`, `regulatory_commitment_overdue`, `oos_classified`, `deviation_closed`, `capa_effectiveness_due`, `capa_effectiveness_failed`, `inspection_observation_added`, `training_overdue`, `training_gap_overdue`, `batch_record_approved`, `batch_record_rejected`, `stability_oos_recorded`, `em_excursion_created`, `em_excursion_closed`, `complaint_critical_severity`, `change_request_approved`, `risk_assessment_high_severity`, `findings_critical_severity`, `screen_reader_capture_failure`; default forced channel is `email` AND in-app inbox; tenant may add additional events to the allowlist via `notifications_authority` + URS-13 CR; the allowlist itself follows controlled lifecycle . |
| DEC-30-06 | Email-queue lifecycle with retry policy | Email-queue lifecycle is `pending → sent | failed | bounced → terminal_failed` (also `failed → pending` on retry); retry policy uses exponential backoff with configurable `max_retry_count` (default 5) and base delay (default 60s), retry intervals 60s / 5min / 30min / 2hr / 12hr; bounce detected from provider response transitions directly to `bounced` (no retry); `terminal_failed` after retry exhaustion emits `notification_email_terminal_failed` event consumed by URS-21 for repeat-failure pattern detection per DEC-30-15. |
| DEC-30-07 | Digest compile evidence + per-recipient send trace | Digest lifecycle is `pending → compiling → queued → sent | failed`; compile step persists `notification_digest_items` (per-recipient per-event compiled items with rendered preview); dispatch persists per-recipient send trace (linkage to `notification_sends`); compile failure transitions to `failed` with error capture; closes the compile gap . |
| DEC-30-08 | Immutable rendered-content snapshot per send | Every `notification_sends` row persists `template_id`, `template_version_snapshot`, `rendered_subject` (TEXT NOT NULL), `rendered_body` (TEXT NOT NULL), `rendered_at` (TIMESTAMPTZ NOT NULL — server-attributed), `rendered_content_hash` (TEXT NOT NULL — for tamper detection); the rendered content is immutable post-send; the rendered body for high-volume sends MAY be stored in URS-12 Document Control with content hash for cost-efficient long-term retention; this provides inspection traceability to the exact content the user saw . |
| DEC-30-09 | Per-row inbox read audit | `markAsRead(:id)` and `markAllAsRead` actions emit per-row audit events (`notification_inbox_acknowledged` event per affected row) with `acknowledged_by`, `acknowledged_at`; supports optional bound e-signature on inbox acknowledgment for events flagged as `requires_acknowledgment_signature` per DEC-30-09 (e.g., regulatory submission approval acknowledgment); the optional ack-e-signature is captured in `acknowledgment_e_signature_id` . |
| DEC-30-10 | Audit-trail coverage + reason-for-change discipline | Every mutation route emits audit-trail entries; manual send / template release / channel release / digest dispatch / channel test / channel secret rotation / lock / reopen all audited; high-risk status changes (terminal-state transitions, secret rotation) require structured reason-for-change captured in audit `details` JSON . |
| DEC-30-11 | Manual send authority gate | Manual send (admin-triggered notification dispatch via `POST /api/v1/notifications/send`) requires `notification_manual_send_authority` + HITL + bound e-signature; the manual-send actor MUST be SoD-distinct from the recipient list per SoD-30-03; manual send is audited with `actor_id`, `event_type`, `template_id`, `template_version_snapshot`, `recipient_ids`, `channel_set`, `bound_e_signature_id`. |
| DEC-30-12 | Frontend route surface alignment | Frontend routes `/notifications`, `/notifications/templates`, `/notifications/channels`, `/notifications/digests`, `/notifications/inbox`, `/notifications/preferences`, `/notifications/admin/send`, `/notifications/admin/audit` are declared in `App.tsx`; dashboard CTAs resolve to real pages. |
| DEC-30-13 | AI-assisted template-content / digest-summary substrate with provenance + mandatory human acceptance | `notification_ai_assistance` table persists per-record columns including `assistance_type` (ENUM `template_content_draft` / `digest_summary` / `recipient_list_suggestion` / `subject_optimization`), `narrative_text`, `model_id`, `model_version`, `prompt_version`, `confidence`, `proposed_at`, `proposed_by_system`, `accepted_by`, `accepted_at`, `acceptance_e_signature_id`, `accepted_text_immutable`, `rejection_reason`, `status` (ENUM `proposed` / `accepted` / `rejected`); AI-generated content is advisory until accepted; promotion to system-of-record (e.g., into a template draft) requires explicit human confirmation captured in `acceptance_e_signature_id`; **AI cannot send a notification, release a template, dispatch a digest, or acknowledge an inbox item** per ARCH-AI-001 (target requirement, ARCH-AI-001 binding, parallel pattern to URS-26.URS-29). |
| DEC-30-14 | Channel-test isolation | Channel test action sends a controlled test message to a designated test recipient (default the tenant `notifications_authority` user); does not replay live credentials in test response; emits `notification_channel_tested` event with `test_outcome` (ENUM `success` / `failure`) + `error_message` (where applicable). |
| DEC-30-15 | Findings emission to URS-21 | Notification chronic delivery failures (≥ configurable threshold per channel per period — default 5 terminal failures per channel per 24h), missed mandatory notifications (mandatory-alert event without successful dispatch on at least one channel per recipient), and stale digest pending items emit `notification_finding_created` event to URS-21 with `notification_delivery` source type. |
| DEC-30-16 | CAPA emission to URS-18 | Chronic delivery failures (recurring channel-level failures, recurring missed mandatory notifications) escalated to CAPA emit `notification_capa_linked` event consumed by URS-18 (`notification_delivery` source type). |
| DEC-30-17 | URS-12 rendered-content snapshot storage | Rendered content for high-volume notification campaigns MAY be stored as URS-12 documents with content hash for long-term retention per DEC-30-08; in-line storage (in `notification_sends.rendered_body`) is the default for typical volumes. |
| DEC-30-18 | URS-13 change-control linkage | Template + channel + mandatory-alert-allowlist effective release require URS-13 change-request linkage per DEC-30-03 / DEC-30-04 / DEC-30-05. |
| DEC-30-19 | URS-13 change-control linkage for template release | Template `under_review → effective` requires URS-13 change-request linkage via `template_release_change_request_id`. |
| DEC-30-20 | platform_admin / super_admin | `platform_admin` / `super_admin` are support / break-glass only paths. |
| DEC-30-21 | Reason-for-change on material updates | Captured per DEC-30-10. |
| DEC-30-22 | Notification program reopen as governed transition | Program `locked → in_progress` requires `executive_authority` co-sign AND `qualified_person_authority` co-sign + documented reason; appends a new program iteration without mutating prior locked evidence (consistent with M14.M29 reopen pattern). |
| DEC-30-23 | Inbound consumer integration with every other URS module | Module 30 is the platform-wide notification dispatcher consuming events from URS-13 / URS-14 / URS-15 / URS-16 / URS-17 / URS-18 / URS-19 / URS-20 / URS-21 / URS-22 / URS-23 / URS-24 / URS-25 / URS-26 / URS-27 / URS-28 / URS-29 / URS-31 / URS-33 / URS-34 / URS-35; each event-type is mapped to a notification template (`notification_event_type_template_map`) at template-effective-release time per DEC-30-03; default templates included for the canonical event-type set; events without a mapped effective template log a fallback warning + emit `notification_finding_created` to URS-21 for missing-template detection. |

### 3.2 Locked-decision rationale narrative

The decisions above define the binding launch posture for Module 30 v1.0. The most consequential locked controls are: (a) DEC-30-04 mandates tenant-controlled secret store for outbound channel credentials and explicitly demotes `authentication_token_hash` to integrity-verification-only; (b) DEC-30-05 introduces the mandatory-alert allowlist gate — the most consequential safety control in the module — ensuring critical regulated events reach recipients regardless of user preferences; (c) DEC-30-08 mandates immutable rendered subject + body + template version per send for inspection traceability; (d) DEC-30-09 requires per-row audit on `markAsRead` / `markAllAsRead` and optional bound ack-e-signature for designated events; (e) DEC-30-03 introduces a full `draft → under_review → effective → superseded → archived` template lifecycle with version immutability + URS-13 CR linkage; (f) DEC-30-23 establishes Module 30 as the platform-wide notification dispatcher consuming events from every other URS module.

### 3.3 Closed launch decisions: cross-link to items

| Specification item ID | Specification item | Locked decision |
|---|---|---|
| M30-DR-001 | Canonical route + frontend hook | DEC-30-01 |
| M30-DR-003 | Template lifecycle two-state Active/Inactive | DEC-30-03 / DEC-30-19 |
| M30-DR-004 | Channel `authentication_token_hash` reused as live credential | DEC-30-04 |
| M30-DR-005 | Mandatory-alert gate missing | DEC-30-05 |
| M30-DR-006 | Rendered-content snapshot missing | DEC-30-08 |
| M30-DR-007 | Digest compile evidence missing | DEC-30-07 |
| M30-DR-008 | Inbox read-state audit missing | DEC-30-09 |
| M30-DR-009 | Audit + reason-for-change gaps | DEC-30-10 / DEC-30-21 |
| M30-DR-010 | Authority/HITL/e-sign missing on regulated finals | DEC-30-04 / DEC-30-11 |

### 3.4 Locked-decision authority

Each locked decision is approved by the Founder / Chairman & MD on signature capture in the Document Approval block of this URS (§19). Decisions cannot be unlocked except through controlled URS revision under the URS change-control process and re-approval.

### 3.5 Worked examples

**Worked example 1 — OOS classification triggering mandatory notification.**
A laboratory analyst in URS-15 OOS / OOT classifies an OOS as `severity = critical` for batch `BR-PTabs-2026-08-12-001`. URS-15 emits `oos_classified` event. Module 30 receives the event; the event is on the mandatory-alert allowlist per DEC-30-05; selects effective template `TPL-OOS-Classified-v3` (released to effective per DEC-30-03 + URS-13 CC-2026-0021); for each recipient (QA Head, Manufacturing Head, Qualified Person, Site Quality Lead), evaluates user preferences — but per DEC-30-05 the mandatory-alert allowlist forces at least one channel regardless. Email is forced for all recipients; in-app inbox row created for all recipients; websocket push fired. Each send persists immutable rendered content snapshot per DEC-30-08 (`rendered_subject`, `rendered_body`, `rendered_content_hash`, `template_version_snapshot = 3`). Audit-trail entry created per DEC-30-10. URS-30 Notifications event `notification_send_dispatched` emitted.

**Worked example 2 — Slack channel with secret-store credential.**
A tenant configures a Slack notification channel for the `oos-alerts` channel. Per DEC-30-04, the channel persists `secret_store_ref = aws-secrets-manager:tenant-id/slack-oos-alerts-token` (NOT inline credential). The channel release ceremony requires `notification_channel_release_authority` + HITL + bound e-signature + URS-13 CC linkage per DEC-30-04 / DEC-30-18. At send time, the secret-store-resolver fetches the live Slack bearer token from AWS Secrets Manager; the token is used for the outbound POST; the token is never persisted in plain text in `notification_channels`. Rotation: `POST /api/v1/notifications/channels/:id/rotate-secret` rotates the secret-store reference (or triggers secret-store-side rotation); audit emits `notification_channel_secret_rotated` event per DEC-30-10.

**Worked example 3 — Inbox acknowledgment with optional bound e-signature.**
A regulatory submission approval notification (`event_type = regulatory_submission_approved` from URS-27) lands in the QP's inbox. Per DEC-30-09 + tenant configuration, this event is flagged as `requires_acknowledgment_signature = true`. When the QP marks the notification as read, the UI presents the bound e-signature ceremony; the QP signs; `acknowledgment_e_signature_id` persisted; per-row audit event `notification_inbox_acknowledged` emitted with `acknowledged_by`, `acknowledged_at`, `acknowledgment_e_signature_id`. The submission record in URS-27 is updated to reflect QP acknowledgment of approval (linked back via the source event reference).

**Worked example 4 — Email-queue retry exhaustion → URS-21 finding.**
An SMTP transport outage causes 10 email sends to fail. Each transitions `pending → failed → pending → failed.` through 5 retry attempts (60s / 5min / 30min / 2hr / 12hr per DEC-30-06). After retry exhaustion, items transition to `terminal_failed`; `notification_email_terminal_failed` events emitted. The chronic-failure detector (5 terminal failures per channel per 24h per DEC-30-15) detects the pattern; emits `notification_finding_created` to URS-21 with `severity = critical`, `source_type = notification_delivery`. URS-21 standalone finding created. If the pattern persists, URS-18 CAPA opens via `notification_capa_linked` per DEC-30-16.

**Worked example 5 — AI-assisted template draft accepted.**
A notification program owner asks MIRA to suggest a template for a new event type `stability_chamber_temperature_excursion` (URS-25). MIRA proposes an advisory template content draft via `notification_ai_assistance` with `assistance_type = template_content_draft`, model identifier, model version, prompt version, confidence per DEC-30-13. The owner reviews; accepts with bound e-signature; `accepted_text_immutable` written; the owner uses the accepted draft as the basis for a new template draft. The template proceeds through normal `draft → under_review → effective` lifecycle with `notification_template_release_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-03 / DEC-30-19.

**Worked example 6 — Governed reopen of locked notification program.**
On `2027-04-15` an inspection finding (URS-22) reveals that a previously locked notification program may have under-recorded one mandatory-alert delivery. The Manufacturing Head initiates a reopen; per DEC-30-22 + SoD-30-06, both `executive_authority` co-sign AND `qualified_person_authority` co-sign + documented reason are required. On both co-signs the program transitions `locked → in_progress` and a new program iteration is appended; the prior locked evidence (templates, channels, sends, inbox acknowledgments, audit trail) is NOT mutated.

---

## 4. End-to-End User Journeys (28 launch journeys)

| # | Journey | Actor | Pre-condition | Path | Post-condition |
|---|---|---|---|---|---|
| 1 | Author notification template | Template Author | `notifications:template:create` | Create template in `draft` with subject/body templates + placeholders | Template `draft`; audit entry |
| 2 | Submit template for review | Template Author | Template `draft` | Transition `draft → under_review` | Template `under_review` |
| 3 | Release template to effective | `notification_template_release_authority` | Template `under_review`; URS-13 CR | HITL + bound e-sign + URS-13 CR linkage; transition `under_review → effective`; supersede prior effective version per DEC-30-03 | Template `effective`; bound e-signature; `notification_template_released_effective` event |
| 4 | Configure notification channel (Slack) | Information Security Authority | `notifications:channel:create` | Create channel with `secret_store_ref` per DEC-30-04 | Channel `draft`; audit entry |
| 5 | Reject inline credentials in channel payload | System (validation) | Body contains `bearer_token` / `webhook_url_with_token` | Reject with `NTF_CREDENTIALS_IN_PAYLOAD_FORBIDDEN` per DEC-30-04 | Operation rejected |
| 6 | Release channel to effective | `notification_channel_release_authority` | Channel `draft`; URS-13 CR | HITL + bound e-sign + URS-13 CR linkage per DEC-30-04 / DEC-30-18 | Channel `effective`; bound e-signature |
| 7 | Test channel | Notification Admin | Channel `effective` | `POST /channels/:id/test` per DEC-30-14; controlled test recipient; audit emit | Test result returned (no live credentials in response) |
| 8 | Rotate channel secret | Information Security Authority | Secret rotation due | `POST /channels/:id/rotate-secret`; rotation emits `notification_channel_secret_rotated` audit | Secret rotated; audit entry |
| 9 | Configure mandatory-alert allowlist | Notifications Authority | `notifications:mandatory_alerts:configure`; URS-13 CR | Add `event_type` to allowlist; HITL + bound e-sign + URS-13 CR per DEC-30-05 | Allowlist updated; bound e-signature |
| 10 | Send mandatory notification (forced channel) | System (event from URS-15 OOS) | OOS `severity = critical` | Mandatory-alert allowlist check; force email + in-app inbox per DEC-30-05 | Notification dispatched on at least one channel per recipient regardless of preferences |
| 11 | Send non-mandatory notification (preference-respecting) | System (event from URS-14 complaint) | Non-mandatory event | Respect user preferences | Notification dispatched per user preference |
| 12 | Persist immutable rendered-content snapshot | System (auto) | Send dispatched | Persist `rendered_subject`, `rendered_body`, `rendered_content_hash`, `template_version_snapshot` per DEC-30-08 | Immutable snapshot persisted |
| 13 | Email-queue success | System (transport) | Email queued | Transport success; transition `pending → sent`; emit `notification_email_sent` | Email sent; audit |
| 14 | Email-queue failure with retry | System (transport) | Transport failure | Transition `pending → failed → pending` (retry per DEC-30-06 backoff) | Retry scheduled |
| 15 | Email-queue terminal failure | System (transport) | Retry exhausted | Transition `failed → terminal_failed`; emit `notification_email_terminal_failed` per DEC-30-06 | Terminal failure logged |
| 16 | Email bounce | System (transport) | Provider bounce response | Transition `pending → bounced` (no retry) | Bounce logged |
| 17 | Compile digest | System (scheduled) | Digest schedule due | Compile per-recipient `notification_digest_items` per DEC-30-07; transition `pending → compiling → queued` | Digest compiled |
| 18 | Dispatch digest | System | Digest `queued` | Transport per recipient; persist per-recipient send trace per DEC-30-07 | Digest dispatched |
| 19 | Inbox row creation | System (auto) | Send dispatched | Insert inbox row; fire websocket push; create `notification_inbox_row_created` event | Inbox row `unread` |
| 20 | Mark inbox as read | User | Inbox row `unread` | `markAsRead`; per-row audit per DEC-30-09 | Inbox row `read`; audit entry |
| 21 | Mark inbox as read with bound ack-e-signature | User | Inbox row `unread`; event flagged `requires_acknowledgment_signature` | HITL + bound e-sign per DEC-30-09; per-row audit + `acknowledgment_e_signature_id` | Inbox row `read`; bound e-signature persisted |
| 22 | Mark all as read | User | Multiple inbox rows `unread` | `markAllAsRead`; per-row audit for each affected row per DEC-30-09 | All affected rows `read`; per-row audit entries |
| 23 | Manual send by admin | `notification_manual_send_authority` | Authorized event | HITL + bound e-sign per DEC-30-11; `actor_id` SoD-distinct from recipient list per SoD-30-03 | Notification dispatched; bound e-signature |
| 24 | Update notification preferences | User | `notifications:preferences:update` | Update preferences; audit entry; mandatory-alert events still forced | Preferences saved; preference change audited |
| 25 | MIRA proposes AI template draft | System (MIRA) | Authorized user requests | Persist `notification_ai_assistance` advisory per DEC-30-13 | Draft `proposed`; advisory only |
| 26 | Accept AI template draft | Notification Admin | Suggestion `proposed` | HITL + bound e-sign; `accepted_text_immutable` written | Suggestion `accepted` |
| 27 | Reject AI-only send attempt | System (validation) | AI service as acting principal for send | Reject with `NTF_AI_CANNOT_SEND` per DEC-30-13 | Operation rejected |
| 28 | Reopen locked notification program (governed transition) | Manufacturing Head + Executive Authority + Qualified Person | Program `locked` | Executive co-sign AND QP co-sign + reason; transition `locked → in_progress`; append new iteration per DEC-30-22 | Program `in_progress`; new iteration appended; prior locked evidence NOT mutated |

---

## 5. Front-end Requirements

### 5.1 Notifications Dashboard

The dashboard (URS-30-FE-001) renders summary cards (recent sends, queue status, inbox unread count, channel status, recent failures) with filters; uses canonical `/notifications/*` hooks per DEC-30-01.

### 5.2 Inbox

The inbox (URS-30-FE-002) renders user inbox rows with `unread` / `read` states; supports `markAsRead` ceremony with optional bound ack-e-signature for events flagged `requires_acknowledgment_signature` per DEC-30-09.

### 5.3 Preferences Page

The preferences page (URS-30-FE-003) supports user preference management per `event_type` × per channel; **shows mandatory-alert events as read-only "always sent" rows** per DEC-30-05.

### 5.4 Template Console

The template console (URS-30-FE-004) supports template draft authoring with placeholder validation; release flow with HITL + bound e-signature + URS-13 CR linkage per DEC-30-03; supports template preview rendering.

### 5.5 Channel Console

The channel console (URS-30-FE-005) supports channel configuration with **`secret_store_ref` field only** (no bearer-token / password fields in UI per DEC-30-04); release flow with HITL + bound e-sign; channel test with controlled test recipient per DEC-30-14; secret rotation UI.

### 5.6 Mandatory-Alert Allowlist Console

The mandatory-alert allowlist console (URS-30-FE-006) renders the allowlist with controlled add/remove via HITL + bound e-sign + URS-13 CR per DEC-30-05.

### 5.7 Email Queue Console

The email queue console (URS-30-FE-007) renders queue with status, retry history, terminal failures; supports manual retry of `failed` items.

### 5.8 Digest Console

The digest console (URS-30-FE-008) renders digest schedule + compiled items + per-recipient send trace per DEC-30-07.

### 5.9 Manual Send Console

The manual send console (URS-30-FE-009) supports admin-triggered notification dispatch with HITL + bound e-sign + recipient SoD enforcement per DEC-30-11.

### 5.10 AI Assistance Console

The AI assistance console (URS-30-FE-010) renders AI-generated assistance with provenance, accept ceremony with bound e-sign, reject ceremony; advisory-only labeling per DEC-30-13.

### 5.11 Audit Trail Viewer

The audit trail viewer (URS-30-FE-011) renders the per-row read audit, manual send audit, template release audit, channel release audit, secret rotation audit per DEC-30-10.

### 5.12 MIRA Copilot Integration

MIRA copilot (URS-30-FE-012) is read-only context. **AI-generated content is advisory only with mandatory human acceptance per DEC-30-13; no AI sends notifications; no AI releases templates; no AI dispatches digests; no AI acknowledges inbox items.**

### 5.13 Accessibility

WCAG 2.1 AA accessible.

---

## 6. Back-end Requirements

### 6.1 Module structure

`packages/backend/src/modules/notifications/` with `plugin.ts`, `routes.ts` (typed schemas), `service.ts` (controlled template lifecycle; secret-store credential resolution; mandatory-alert allowlist gate; email retry; digest compile; immutable rendered-content snapshot; per-row inbox audit; AI assistance substrate; audit + reason-for-change), `schemas.ts`, `events.ts`, `secret-store-resolver.ts` (per DEC-30-04), `mandatory-alert-engine.ts` (per DEC-30-05), `template-renderer.ts` (per DEC-30-08), `digest-compiler.ts` (per DEC-30-07).

### 6.2 Data model

#### 6.2.1 `notification_templates`

`id`, `tenant_id`, `template_code`, `event_type` (TEXT NOT NULL), `language_code` (TEXT NOT NULL DEFAULT 'en-US'), `version` (INTEGER NOT NULL), `subject_template` (TEXT), `body_template` (TEXT), `placeholders_json` (JSONB), `release_change_request_id` (FK to URS-13 per DEC-30-19), `effective_from`, `effective_to`, `supersedes_template_id` (self-FK nullable), `approved_by`, `approved_at`, `e_signature_id` (FK), `status` (ENUM `draft` / `under_review` / `effective` / `superseded` / `archived` per DEC-30-03), audit columns. Partial unique index: `WHERE status = 'effective'` on `(tenant_id, event_type, language_code)`. RLS enabled.

#### 6.2.2 `notification_channels`

`id`, `tenant_id`, `channel_code`, `channel_type` (ENUM `email` / `slack` / `teams` / `webhook` / `smtp` / `in_app`), `secret_store_ref` (TEXT NOT NULL per DEC-30-04 — except `in_app` which has no external credentials), `endpoint_url`, `authentication_token_hash` (TEXT — integrity-verification only per DEC-30-04), `release_change_request_id` (FK to URS-13), `effective_from`, `effective_to`, `approved_by`, `approved_at`, `e_signature_id` (FK), `last_secret_rotated_at` (TIMESTAMPTZ nullable), `last_secret_rotated_by` (FK nullable), `status` (ENUM `draft` / `under_review` / `effective` / `suspended` / `archived`), audit columns.

#### 6.2.3 `notification_mandatory_alerts`

`id`, `tenant_id`, `event_type` (TEXT NOT NULL), `forced_channel_types` (TEXT[] DEFAULT `{email, in_app}`), `requires_acknowledgment_signature` (BOOLEAN DEFAULT false per DEC-30-09), `release_change_request_id` (FK to URS-13), `effective_from`, `effective_to`, `approved_by`, `approved_at`, `e_signature_id` (FK), audit columns.

#### 6.2.4 `notification_preferences`

`id`, `tenant_id`, `user_id` (FK), `event_type` (TEXT), `channel_type` (TEXT), `enabled` (BOOLEAN), audit columns. UNIQUE `(tenant_id, user_id, event_type, channel_type)`.

#### 6.2.5 `notification_sends`

`id`, `tenant_id`, `event_type` (TEXT NOT NULL), `severity` (ENUM per DEC-30-02), `template_id` (FK), `template_version_snapshot` (INTEGER NOT NULL per DEC-30-08), `actor_id` (FK nullable — for manual sends), `source_record_type` (TEXT nullable), `source_record_id` (UUID nullable), `recipient_user_ids` (UUID[]), `channel_set` (TEXT[]), `rendered_subject` (TEXT NOT NULL per DEC-30-08), `rendered_body` (TEXT NOT NULL per DEC-30-08 — or `rendered_body_document_id` FK to URS-12 for high-volume), `rendered_at` (TIMESTAMPTZ NOT NULL — server-attributed), `rendered_content_hash` (TEXT NOT NULL per DEC-30-08), `is_mandatory_alert` (BOOLEAN), `manual_send_e_signature_id` (FK nullable), audit columns.

#### 6.2.6 `notification_inbox`

`id`, `tenant_id`, `user_id` (FK), `notification_send_id` (FK), `event_type`, `severity`, `subject` (rendered), `body_preview` (rendered), `acknowledged_at` (TIMESTAMPTZ nullable), `acknowledged_by` (FK nullable), `acknowledgment_e_signature_id` (FK nullable per DEC-30-09), `status` (ENUM `unread` / `read` / `soft_deleted`), audit columns.

#### 6.2.7 `notification_email_queue`

`id`, `tenant_id`, `notification_send_id` (FK), `recipient_email`, `subject` (rendered), `body` (rendered), `attempt_count` (INTEGER DEFAULT 0), `max_retry_count` (INTEGER DEFAULT 5 per DEC-30-06), `next_attempt_at` (TIMESTAMPTZ), `last_error_message` (TEXT nullable), `provider_message_id` (TEXT nullable), `bounce_type` (TEXT nullable), `status` (ENUM `pending` / `sent` / `failed` / `bounced` / `terminal_failed`), audit columns.

#### 6.2.8 `notification_digests`

`id`, `tenant_id`, `digest_code`, `recipient_user_id` (FK), `event_classes` (TEXT[]), `compile_started_at`, `compile_completed_at`, `dispatch_at`, `status` (ENUM `pending` / `compiling` / `queued` / `sent` / `failed` per DEC-30-07), audit columns.

#### 6.2.9 `notification_digest_items`

`id`, `tenant_id`, `digest_id` (FK), `notification_send_id` (FK nullable), `event_type`, `event_record_id`, `compiled_preview` (TEXT), audit columns. Per DEC-30-07.

#### 6.2.10 `notification_ai_assistance`

`id`, `tenant_id`, `assistance_type` (ENUM per DEC-30-13), `linked_record_type` (ENUM `template` / `digest` / `manual_send`), `linked_record_id` (UUID), `narrative_text`, `model_id`, `model_version`, `prompt_version`, `confidence`, `proposed_at`, `proposed_by_system`, `accepted_by`, `accepted_at`, `acceptance_e_signature_id`, `accepted_text_immutable`, `rejection_reason`, `status`, audit columns.

#### 6.2.11 `notification_program_locks`

`id`, `tenant_id`, `period_start`, `period_end`, `locked_by`, `locked_at`, `lock_e_signature_id`, `reopened_at`, `reopened_by`, `reopen_executive_co_signer`, `reopen_qp_co_signer`, `reopen_reason`, audit columns.

#### 6.2.12 RLS

All Module 30 tables have RLS enabled.

### 6.3 API contract

| Route | Method | Permission | Status |
|---|---|---|---|
| `/api/v1/notifications/preferences` | GET / PATCH | `notifications:preferences:read` / `notifications:preferences:update` | |
| `/api/v1/notifications/templates` | GET / POST | `notifications:template:read` / `notifications:template:create` | |
| `/api/v1/notifications/templates/:id` | GET / PATCH (draft only) | `notifications:template:read` / `notifications:template:update` | |
| `/api/v1/notifications/templates/:id/release` | POST | `notification_template_release_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-03 / DEC-30-19 | target route |
| `/api/v1/notifications/templates/:id/render-preview` | POST | `notifications:template:render` | |
| `/api/v1/notifications/channels` | GET / POST | `notifications:channel:read` / `notifications:channel:create` (rejects inline credentials per DEC-30-04) | |
| `/api/v1/notifications/channels/:id` | GET / PATCH | `notifications:channel:read` / `notifications:channel:update` | |
| `/api/v1/notifications/channels/:id/release` | POST | `notification_channel_release_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-04 | target route |
| `/api/v1/notifications/channels/:id/test` | POST | `notifications:channel:test` per DEC-30-14 | |
| `/api/v1/notifications/channels/:id/rotate-secret` | POST | `information_security_authority` per DEC-30-04 | target route |
| `/api/v1/notifications/mandatory-alerts` | GET / POST | `notifications:mandatory_alerts:read` / `notifications:mandatory_alerts:configure` (with HITL + bound e-sign + URS-13 CR per DEC-30-05) | target route |
| `/api/v1/notifications/sends` | GET | `notifications:send:read` | |
| `/api/v1/notifications/send` | POST | `notification_manual_send_authority` + HITL + bound e-sign + recipient SoD per DEC-30-11 | |
| `/api/v1/notifications/email-queue` | GET / POST | `notifications:email:queue:read` / `notifications:email:queue:create` | |
| `/api/v1/notifications/email-queue/process` | POST | `notifications:email:queue:process` (system-typically) | |
| `/api/v1/notifications/email-queue/:id/retry` | POST | `notifications:email:queue:retry` | target route |
| `/api/v1/notifications/digests` | GET / POST | `notifications:digest:read` / `notifications:digest:create` | |
| `/api/v1/notifications/digests/:id/process` | POST | `notification_digest_dispatch_authority` per DEC-30-07 | |
| `/api/v1/notifications/inbox` | GET | `notifications:inbox:read` | |
| `/api/v1/notifications/inbox/unread-count` | GET | `notifications:inbox:read` | |
| `/api/v1/notifications/inbox/:id/mark-read` | POST | `notifications:inbox:mark_read` (with optional bound ack-e-sign per DEC-30-09) | (per-row audit) |
| `/api/v1/notifications/inbox/mark-all-read` | POST | `notifications:inbox:mark_read` (per-row audit per DEC-30-09) | |
| `/api/v1/notifications/ai-assistance` | GET / POST | `notifications:ai_assistance:read` / `notifications:ai_assistance:propose` | target route per DEC-30-13 |
| `/api/v1/notifications/ai-assistance/:id/accept` | POST | `notifications:ai_assistance:accept` + HITL + bound e-sign | target route |
| `/api/v1/notifications/ai-assistance/:id/reject` | POST | `notifications:ai_assistance:reject` + reason | target route |
| `/api/v1/notifications/program-locks` | POST | `final_quality_approver` + HITL + bound e-sign | target route |
| `/api/v1/notifications/program-locks/:id/reopen` | POST | `executive_authority` co-sign AND `qualified_person_authority` co-sign + HITL + reason per DEC-30-22 | target route |

### 6.4 Workflow

#### 6.4.1 Template lifecycle

```mermaid
stateDiagram-v2
 [*] --> draft: create
 draft --> under_review: submit for review
 under_review --> effective: release (notification_template_release_authority + HITL + e-sign + URS-13 CR — DEC-30-03)
 effective --> superseded: revise (new version)
 superseded --> archived: archive
```

#### 6.4.2 Send orchestration

```mermaid
sequenceDiagram
 participant E as Event Bus
 participant S as Notification Service
 participant MA as Mandatory-Alert Engine
 participant T as Template (effective version)
 participant R as Renderer
 participant Q as Email Queue
 participant W as Webhook (Slack/Teams)
 participant I as Inbox
 participant A as Audit Trail
 E->>S: publish(event)
 S->>MA: is event in mandatory-alert allowlist?
 MA-->>S: yes — force email + in-app | no — respect preferences
 S->>T: select effective template by (event_type, language)
 T-->>S: template + version_snapshot
 S->>R: render with placeholders
 R-->>S: rendered subject + body + content hash
 loop recipient
 S->>Q: queueEmail (rendered + template_version_snapshot)
 S->>W: send via webhook (credentials from secret store)
 S->>I: insert inbox row (rendered snapshot)
 end
 S->>A: CREATE notification_send (immutable rendered snapshot — DEC-30-08)
```

#### 6.4.3 Email queue lifecycle

```mermaid
stateDiagram-v2
 [*] --> pending
 pending --> sent: transport success
 pending --> failed: transport error
 failed --> pending: retry (attempt_count < max_retry_count) — exponential backoff
 failed --> terminal_failed: retry exhausted (notification_email_terminal_failed event)
 pending --> bounced: provider bounce (no retry)
 sent --> [*]
 terminal_failed --> [*]
 bounced --> [*]
```

#### 6.4.4 Inbox lifecycle

```mermaid
stateDiagram-v2
 [*] --> unread: row created on send
 unread --> read: markAsRead (per-row audit per DEC-30-09; optional bound ack-e-sign for requires_acknowledgment_signature events)
 unread --> read: markAllAsRead (per-row audit for each affected row)
 read --> soft_deleted: retention purge
```

### 6.5 Business rules

- BR-30-01: Template lifecycle is `draft → under_review → effective → superseded → archived` per DEC-30-03.
- BR-30-02: At most one `effective` version per `(tenant_id, event_type, language_code)` enforced via partial unique index per DEC-30-03.
- BR-30-03: Template effective release requires `notification_template_release_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-03 / DEC-30-19.
- BR-30-04: Effective template versions are immutable; revisions create new version rows.
- BR-30-05: Channel `authentication_token_hash` is integrity-verification only; live credentials via secret store per DEC-30-04.
- BR-30-06: Channel release requires `notification_channel_release_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-04.
- BR-30-07: Channel test action does not replay live credentials in the test response per DEC-30-14.
- BR-30-08: Channel secret rotation requires `information_security_authority` per DEC-30-04 and emits `notification_channel_secret_rotated` audit per DEC-30-10.
- BR-30-09: Mandatory-alert allowlist forces at least one channel per recipient regardless of user preferences per DEC-30-05.
- BR-30-10: Mandatory-alert allowlist configuration requires `notifications_authority` + HITL + bound e-sign + URS-13 CR per DEC-30-05.
- BR-30-11: Email-queue lifecycle is `pending → sent | failed | bounced → terminal_failed` with retry per DEC-30-06.
- BR-30-12: `terminal_failed` emits `notification_email_terminal_failed` event consumed by URS-21 chronic-failure detector per DEC-30-15.
- BR-30-13: Digest compile persists per-recipient `notification_digest_items` per DEC-30-07.
- BR-30-14: Every send persists immutable rendered-content snapshot (`rendered_subject`, `rendered_body`, `rendered_content_hash`, `template_version_snapshot`) per DEC-30-08.
- BR-30-15: Inbox `markAsRead` and `markAllAsRead` emit per-row audit events per DEC-30-09.
- BR-30-16: Inbox acknowledgment for events flagged `requires_acknowledgment_signature` requires bound ack-e-signature per DEC-30-09.
- BR-30-17: Manual send requires `notification_manual_send_authority` + HITL + bound e-sign + actor SoD-distinct from recipient list per DEC-30-11 / SoD-30-03.
- BR-30-18: Material updates require structured reason-for-change per DEC-30-21.
- BR-30-19: Bound e-signature persistence on every regulated final action per DEC-30-04 / DEC-30-23.
- BR-30-20: Program reopen `locked → in_progress` requires `executive_authority` co-sign AND `qualified_person_authority` co-sign + reason per DEC-30-22.
- BR-30-21: AI assistance is advisory until human-accepted per DEC-30-13.
- BR-30-22: **AI cannot send notifications, release templates, dispatch digests, or acknowledge inbox items** per ARCH-AI-001 / DEC-30-13.
- BR-30-23: `platform_admin` / `super_admin` are support / break-glass only paths per DEC-30-20.
- BR-30-24: Module 30 consumes inbound events from every other URS module per DEC-30-23.
- BR-30-25: Events without a mapped effective template emit `notification_finding_created` to URS-21 per DEC-30-23 (missing-template detection).

### 6.6 Audit trail

Every Module 30 record mutation persists an audit-trail entry. Material updates persist `reason_for_change` per DEC-30-21. Inbox per-row read audited per DEC-30-09. Channel secret rotation audited per DEC-30-10. Manual send audited with full attribution per DEC-30-11. Regulated final actions persist a bound e-signature via the `electronic_signatures` substrate. Append-only.

### 6.7 Error handling

| Code | HTTP | Meaning |
|---|---|---|
| `NTF_VALIDATION_FAILED` | 400 | Schema validation failure |
| `NTF_UNAUTHORIZED` | 401 | Authentication required |
| `NTF_FORBIDDEN` | 403 | RBAC denied |
| `NTF_NOT_FOUND` | 404 | Resource not found |
| `NTF_DUPLICATE_KEY` | 409 | Uniqueness violation |
| `NTF_INVALID_TRANSITION` | 422 | Lifecycle transition not permitted |
| `NTF_TERMINAL_STATE_PATCH_FORBIDDEN` | 422 | Direct PATCH attempted on terminal status |
| `NTF_CREDENTIALS_IN_PAYLOAD_FORBIDDEN` | 422 | Inline credentials in channel payload per DEC-30-04 |
| `NTF_SECRET_STORE_REF_REQUIRED` | 422 | Channel missing `secret_store_ref` per DEC-30-04 |
| `NTF_SECRET_STORE_RESOLUTION_FAILED` | 502 | Secret store resolution failed at send time |
| `NTF_MANDATORY_ALERT_DELIVERY_FAILED` | 422 | Mandatory-alert event failed dispatch on all channels per DEC-30-05 |
| `NTF_TEMPLATE_NOT_EFFECTIVE` | 422 | Send attempted with no effective template for `event_type` |
| `NTF_TEMPLATE_RELEASE_CHANGE_REQUEST_REQUIRED` | 422 | Template release without URS-13 CR |
| `NTF_RENDERED_CONTENT_HASH_MISMATCH` | 422 | Rendered content hash mismatch detected (tampering) |
| `NTF_AUTHORITY_REQUIRED` | 422 | Authority Profile missing |
| `NTF_HITL_DECISION_REQUIRED` | 422 | HITL decision capture missing |
| `NTF_E_SIGNATURE_REQUIRED` | 422 | Bound e-signature persistence missing |
| `NTF_REASON_FOR_CHANGE_REQUIRED` | 422 | Material update without reason-for-change |
| `NTF_MANUAL_SEND_RECIPIENT_SOD_VIOLATION` | 422 | Manual send actor in recipient list per SoD-30-03 |
| `NTF_AI_CANNOT_SEND` | 422 | AI service attempted to send notification per ARCH-AI-001 |
| `NTF_AI_CANNOT_RELEASE_TEMPLATE` | 422 | AI service attempted to release template per ARCH-AI-001 |
| `NTF_AI_CANNOT_DISPATCH_DIGEST` | 422 | AI service attempted to dispatch digest per ARCH-AI-001 |
| `NTF_AI_CANNOT_ACKNOWLEDGE_INBOX` | 422 | AI service attempted to acknowledge inbox per ARCH-AI-001 |
| `NTF_AI_ASSISTANCE_NOT_ACCEPTED` | 422 | Attempt to promote AI assistance without human acceptance per DEC-30-13 |
| `NTF_REOPEN_AUTHORITY_REQUIRED` | 422 | Reopen attempted without executive AND QP co-sign per DEC-30-22 |
| `NTF_INTERNAL` | 500 | Sanitized server error |

### 6.8 Configuration rules

- Email retry policy (`max_retry_count` default 5, base delay default 60s) configurable per tenant per DEC-30-06.
- Mandatory-alert allowlist default set configurable per tenant via controlled change request per DEC-30-05.
- Chronic delivery failure threshold (default 5 terminal failures per channel per 24h) configurable per DEC-30-15.
- Rendered-content storage mode (in-line vs URS-12 document storage) configurable per template per DEC-30-08.
- Secret-store provider configured per tenant per DEC-30-04.

---

## 7. Non-functional Requirements

- NFR-30-01: List pagination (default 50, max 200).
- NFR-30-02: Inbox unread-count p95 < 200ms.
- NFR-30-03: Inbox list p95 < 500ms.
- NFR-30-04: Send orchestration end-to-end p95 < 2s (event arrival → all-channel dispatch initiated).
- NFR-30-05: Email-queue throughput: 1000 emails / minute per tenant.
- NFR-30-06: Audit-trail append p99 < 200ms (per-row inbox read audit critical path).
- NFR-30-07: Concurrent recipients per send: 1000.
- NFR-30-08: Storage scalability: 100M sends per tenant; 1B inbox rows per tenant.
- NFR-30-09: Backup / restore RPO ≤ 15 min; RTO ≤ 4 hours per URS-35.
- NFR-30-10: Bound e-signature persistence transaction p95 < 1.5s.
- NFR-30-11: Secret-store resolution p95 < 200ms.
- NFR-30-12: Mandatory-alert delivery SLA: at least one channel succeeds within 5 minutes of event arrival OR `NTF_MANDATORY_ALERT_DELIVERY_FAILED` raised + URS-21 finding emitted.

---

## 8. Localization

English (en-US, en-GB), Hindi (hi-IN), Marathi (mr-IN), Japanese (ja-JP) at launch. Templates support `language_code` per recipient preference; default `en-US`.

---

## 9. Migration

### 9.1 Migration scope

Greenfield at launch.

### 9.2 Schema migration

Migration baseline aligned with target migrations columns: extend `notification_templates.status` enum to `draft / under_review / effective / superseded / archived` per DEC-30-03; add partial unique index `WHERE status = 'effective'` on `(tenant_id, event_type, language_code)`; add `release_change_request_id` FK to URS-13 on `notification_templates` and `notification_channels` and `notification_mandatory_alerts`; add `secret_store_ref` NOT NULL on `notification_channels` (`in_app` channels exempt); deprecate `authentication_token_hash` as live credential (retain as integrity-verification only) per DEC-30-04; add `notification_mandatory_alerts` table per DEC-30-05; add `rendered_subject`, `rendered_body`, `rendered_content_hash`, `template_version_snapshot`, `rendered_at`, `rendered_body_document_id` (FK to URS-12) on `notification_sends` per DEC-30-08; add `notification_digest_items` table per DEC-30-07; add `acknowledgment_e_signature_id` on `notification_inbox` per DEC-30-09; add `notification_ai_assistance` table per DEC-30-13; add `notification_program_locks` table per DEC-30-22; add per-row audit trigger on `notification_inbox` for `markAsRead` per DEC-30-09; add `last_secret_rotated_*` on `notification_channels` per DEC-30-04.

### 9.3 Migration evidence gate (URS-30-VAL-008)

(a) all migrations applied; (b) RLS verified; (c) typed schema validation verified; (d) template controlled lifecycle + URS-13 CR linkage verified; (e) channel secret-store credential governance verified (inline-credential rejection tested); (f) mandatory-alert allowlist gate verified (forced channel regardless of preference tested); (g) email-queue retry + backoff verified; (h) digest compile evidence verified; (i) immutable rendered-content snapshot verified (tamper-detection test); (j) per-row inbox read audit verified; (k) optional bound ack-e-sign verified for `requires_acknowledgment_signature` events; (l) manual send authority + recipient SoD verified; (m) AI assistance substrate + AI-only-send rejection verified; (n) cross-module event consumption verified (URS-13/-14/-15/-16/-17/-18/-19/-20/-21/-22/-23/-24/-25/-26/-27/-28/-29 events received and dispatched); (o) findings + CAPA emission verified; (p) governed reopen verified; (q) §17 validation evidence pack signed.

---

## 10. Decommissioning

Module 30 records subject to platform record-retention policy: notification sends + inbox rows retained per regulatory record-retention rules; rendered-content snapshots retained for inspection traceability per DEC-30-08; on tenant decommissioning, records exported per URS-35.

---

## 11. Decisions, Dependencies, Risks, and Error Handling
### 11.1 Closed decision posture

**No Module 30 internal decisions outstanding.** Launch decisions are captured in the locked decisions above.

### 11.2 External dependencies

- URS-12 Document Control must support rendered-content snapshot storage with content hash per DEC-30-08.
- URS-13 change-control register must support template + channel + mandatory-alert release linkage per DEC-30-03 / DEC-30-04 / DEC-30-05.
- URS-18 CAPA register must accept `notification_delivery` source type per DEC-30-16.
- URS-21 findings register must accept `notification_delivery` source type per DEC-30-15.
- URS-32 MIRA AI must support read-only `useMiraRecord(.)` mappings; AI advisory drafting only.
- URS-35 infrastructure must support secret-store integration per DEC-30-04.
- All inbound consumer modules (URS-13.URS-29, URS-31, URS-33.URS-35) must emit events per DEC-30-23.

### 11.3 Risks

- Risk-30-01: Secret-store provider availability (AWS / Vault / Azure / GCP outages). Mitigation: NFR-30-11 latency budget; configurable timeout; read-only fallback (in-app inbox + websocket continue without external channels).
- Risk-30-02: Mandatory-alert delivery failure on all channels. Mitigation: NFR-30-12 SLA + automatic URS-21 finding + URS-18 CAPA.
- Risk-30-03: Inbox per-row audit volume at scale. Mitigation: NFR-30-06 latency budget + audit partitioning.
- Risk-30-04: Rendered-body storage volume. Mitigation: URS-12 document storage option per DEC-30-17 for high-volume campaigns.
- Risk-30-05: AI-assistance acceptance rate may be high if reviewers rubber-stamp. Mitigation: acceptance-rate audit; periodic review.
- Risk-30-06: Reopen workflow gravity may delay urgent investigations. Mitigation: documented reopen SLA.

### 11.4 Out-of-scope risks tracked elsewhere

- SMS / push channels (future-state).
- Voice channels (future-state).
- Vendor-specific delivery analytics dashboards (future-state).

### 11.5 Risk owner

Module-30 risk register owned by Quality / Notifications Squad with quarterly review by **Information Security Head (Primary Owner)** + QA Head + Validation Head + Qualified Person Authority.

### 11.6 Decision discipline

No Module 30 internal decisions outstanding.

### 11.7 Error Handling and Negative Paths

This section defines the controlled error envelope, the enumerated machine-code catalogue, and the negative-path response contract required for this module. The error envelope is the standard platform envelope (human message, machine code in upper-snake-case, optional structured details, correlation identifier). Errors are returned with the appropriate HTTP status; the UI surfaces inline errors at the field of cause where applicable, otherwise a controlled error toast or modal. Every error path is logged to the URS-06 audit substrate when the originating action is regulated; errors that occur before authentication are logged without `userId`. Audit-trail write failure on a state-changing action MUST cause the originating action to NOT commit (atomic write per URS-04 BR-04-15). The enumerated machine codes for this module's negative paths are defined alongside the corresponding lifecycle gates, segregation-of-duties controls, and authority-resolution outcomes throughout §6 (Back-end Requirements) and §13 (Segregation of Duties); engineering MUST surface every enumerated machine code through the standard envelope and MUST NOT swallow errors silently. Cross-module error propagation follows the §20 Cross-Module Event Contract.


---

## 12. Security

- SEC-30-01: Tenant isolation enforced at RLS on every Module 30 table.
- SEC-30-02: RBAC enforced on every route via `requirePermission(.)`.
- SEC-30-03: Authority resolution enforced on regulated final actions before HITL + e-signature.
- SEC-30-04: HITL decision capture enforced before bound e-signature persistence.
- SEC-30-05: Bound e-signature persistence via `electronic_signatures` substrate.
- SEC-30-06: PII redaction in logs (notification subject + body may contain PII; redaction enforced for log output).
- SEC-30-07: Audit-trail integrity via URS-06 hash chain.
- SEC-30-08: AI-request provenance via `ai_requests` linked to `notification_ai_assistance`; **AI cannot send / release / dispatch / acknowledge** per ARCH-AI-001; AI may draft advisory only.
- SEC-30-09: `platform_admin` / `super_admin` break-glass actions logged per DEC-30-20.
- SEC-30-10: **Outbound channel credentials via tenant-controlled secret store per DEC-30-04 — `authentication_token_hash` is integrity-verification only; live credentials never persisted in `notification_channels`**.
- SEC-30-11: Channel test action does not replay live credentials in test response per DEC-30-14.
- SEC-30-12: Rendered-content hash for tamper detection per DEC-30-08.
- SEC-30-13: Per-row inbox read audit per DEC-30-09 (regulatory acknowledgment evidence).
- SEC-30-14: Manual send actor SoD-distinct from recipient list per SoD-30-03.

---

## 13. Segregation of Duties

| SoD ID | Constraint |
|---|---|
| SoD-30-01 | The template releaser MUST NOT be the template author when tenant policy requires content-author/releaser separation. |
| SoD-30-02 | The channel releaser MUST be `information_security_authority` (default policy). |
| SoD-30-03 | The manual-send actor MUST NOT be in the recipient list (DB-level constraint). |
| SoD-30-04 | The channel-secret-rotation actor MUST be `information_security_authority` per DEC-30-04. |
| SoD-30-05 | The mandatory-alert allowlist configuration actor MUST be `notifications_authority` (or higher). |
| SoD-30-06 | The reopen co-signers (executive AND Qualified Person per DEC-30-22) MUST NOT be the original lock signer. |
| SoD-30-07 | The `platform_admin` / `super_admin` support / break-glass action MUST NOT be a regulated production action; logged and reviewed per DEC-30-20. |

---

## 14. Regulatory Mapping

| Predicate rule | Section | Module 30 binding |
|---|---|---|
| **FDA 21 CFR Part 11 §11.10(a)** | Validation | URS-30-VAL-008 |
| **FDA 21 CFR Part 11 §11.10(e)** | Audit trails | Per-row inbox audit + send audit + channel secret rotation audit |
| **FDA 21 CFR Part 11 §11.50** | Signature manifestations | Bound ack-e-signature manifestations per DEC-30-09 |
| **FDA 21 CFR Part 11 §11.70** | Signature/record linking | Bound e-signature linked via `electronic_signatures` substrate |
| **EU GMP Annex 11 §4** | Validation | URS-30-VAL-008 |
| **EU GMP Annex 11 §5** | Data — including notification content integrity | Immutable rendered-content snapshot per DEC-30-08 |
| **EU GMP Annex 11 §9** | Audit Trails | Audit-trail substrate including per-row inbox read |
| **EU GMP Annex 11 §12** | Security including credential governance | Secret-store credential governance per DEC-30-04 |
| **EU GMP Annex 11 §14** | Electronic Records / Signatures | Bound e-signature on every regulated final action |
| **EU GMP Annex 11 §16** | Incident Management — notification of incidents | Mandatory-alert allowlist per DEC-30-05 (incident-class events forced) |
| EU GMP Annex 22 Draft 2025 | §7 — HITL / GenAI advisory only | Internal forward-looking control |
| EU AI Act (Regulation 2024/1689) | Art. 13 transparency | Internal forward-looking control |
| **MHRA Data Integrity Guidance** | ALCOA+ — applies to delivery records as electronic records | Module 30 delivery records ALCOA+-compliant |
| GAMP 5 Cat 5 | Custom-application validation lifecycle | URS-30 validation evidence pack per URS-30-VAL-008 |
| **FDA Computer Software Assurance (CSA) — September 2025 Final Guidance** | Notifications carrying mandatory-alert gate are high-process-risk | URS-30 risk-based validation aligned with CSA |
| **ISO/IEC 27001** | Information security — credential governance for outbound channels | Secret-store credential governance per DEC-30-04 |
| **India CDSCO Schedule M (Revised) §16** | Records and Reports — applicable to notification delivery records | India operations subject to a future jurisdiction-specific legal assessment |

---

## 15. Code Modules

| Code module | Path | Status |
|---|---|---|
| `notifications` plugin | `packages/backend/src/modules/notifications/plugin.ts` | (canonical mount) |
| `notifications` routes | `packages/backend/src/modules/notifications/routes.ts` | (typed schemas; route additions per §6.3; inline credentials rejected) |
| `notifications` service | `packages/backend/src/modules/notifications/service.ts` | (controlled template lifecycle; secret-store credential resolution; mandatory-alert allowlist gate; email retry; digest compile; immutable rendered-content snapshot; per-row inbox audit; AI assistance; audit + reason-for-change) |
| `notifications` schemas | `packages/backend/src/modules/notifications/schemas.ts` | (inline credentials removed) |
| `notifications` events | `packages/backend/src/modules/notifications/events.ts` | target route (extended) |
| `notifications` secret-store-resolver | `packages/backend/src/modules/notifications/secret-store-resolver.ts` | target route per DEC-30-04 |
| `notifications` mandatory-alert-engine | `packages/backend/src/modules/notifications/mandatory-alert-engine.ts` | target route per DEC-30-05 |
| `notifications` template-renderer | `packages/backend/src/modules/notifications/template-renderer.ts` | (rendered-content snapshot per DEC-30-08) |
| `notifications` digest-compiler | `packages/backend/src/modules/notifications/digest-compiler.ts` | per DEC-30-07 |
| Migration | `packages/backend/src/db/migrations/.` | (per §9.2) |
| Shared types | `packages/shared/src/types/notifications.ts` | |
| Shared schemas | `packages/shared/src/schemas/notifications.schema.ts` | |
| Frontend hooks | `packages/frontend/src/api/hooks/useNotifications.ts` | |
| Frontend dashboard | `packages/frontend/src/pages/NotificationsDashboard.tsx` | target route per DEC-30-12 |
| Frontend inbox | `packages/frontend/src/pages/NotificationsInbox.tsx` | target route per DEC-30-09 |
| Frontend preferences | `packages/frontend/src/pages/NotificationPreferences.tsx` | (mandatory events as read-only "always sent" rows) |
| Frontend templates | `packages/frontend/src/pages/NotificationTemplates.tsx` | |
| Frontend channels | `packages/frontend/src/pages/NotificationChannels.tsx` | target route per DEC-30-04 |
| Frontend mandatory-alerts | `packages/frontend/src/pages/NotificationMandatoryAlerts.tsx` | target route per DEC-30-05 |
| Frontend email queue | `packages/frontend/src/pages/NotificationEmailQueue.tsx` | target route per DEC-30-06 |
| Frontend digests | `packages/frontend/src/pages/NotificationDigests.tsx` | target route per DEC-30-07 |
| Frontend manual send | `packages/frontend/src/pages/NotificationManualSend.tsx` | target route per DEC-30-11 |
| Frontend AI assistance | `packages/frontend/src/pages/NotificationAIAssistance.tsx` | target route per DEC-30-13 |
| Frontend audit viewer | `packages/frontend/src/pages/NotificationAuditViewer.tsx` | target route per DEC-30-10 |
| App routing | `packages/frontend/src/App.tsx` | (per DEC-30-12) |

---

## 16. Test Cases

### 16.1 Unit tests

- TC-30-U-001: Template uniqueness `(tenant_id, event_type, language_code, version)` rejects duplicate.
- TC-30-U-002: At most one effective template per `(tenant_id, event_type, language_code)` enforced.
- TC-30-U-003: Template effective release without URS-13 CR rejects with `NTF_TEMPLATE_RELEASE_CHANGE_REQUEST_REQUIRED`.
- TC-30-U-004: Effective template edit rejects with `NTF_INVALID_TRANSITION`.
- TC-30-U-005: Channel inline credentials rejected with `NTF_CREDENTIALS_IN_PAYLOAD_FORBIDDEN`.
- TC-30-U-006: Channel without `secret_store_ref` rejected with `NTF_SECRET_STORE_REF_REQUIRED`.
- TC-30-U-007: Secret-store resolution failure handled gracefully.
- TC-30-U-008: Channel test does not replay live credentials in response.
- TC-30-U-009: Channel secret rotation by non-`information_security_authority` rejected.
- TC-30-U-010: Mandatory-alert event forced on email + in-app regardless of preferences.
- TC-30-U-011: Mandatory-alert delivery failure on all channels emits `NTF_MANDATORY_ALERT_DELIVERY_FAILED` + URS-21 finding.
- TC-30-U-012: Email queue retry with exponential backoff verified.
- TC-30-U-013: Email queue terminal failure emits `notification_email_terminal_failed` event.
- TC-30-U-014: Digest compile persists `notification_digest_items` per DEC-30-07.
- TC-30-U-015: Send persists immutable rendered-content snapshot per DEC-30-08.
- TC-30-U-016: Rendered-content hash mismatch detected per DEC-30-08.
- TC-30-U-017: `markAsRead` emits per-row audit event per DEC-30-09.
- TC-30-U-018: `markAllAsRead` emits per-row audit for each affected row per DEC-30-09.
- TC-30-U-019: Inbox acknowledgment for `requires_acknowledgment_signature` event requires bound ack-e-sign.
- TC-30-U-020: Manual send by actor in recipient list rejects with `NTF_MANUAL_SEND_RECIPIENT_SOD_VIOLATION`.
- TC-30-U-021: Manual send without `notification_manual_send_authority` rejects.
- TC-30-U-022: AI service attempting send / release / dispatch / acknowledge rejected with appropriate error.
- TC-30-U-023: AI assistance promotion without acceptance rejects with `NTF_AI_ASSISTANCE_NOT_ACCEPTED`.
- TC-30-U-024: Reopen without executive AND QP co-sign rejects.

### 16.2 Integration tests

- TC-30-I-001: OOS classification triggering mandatory notification per Worked Example 1.
- TC-30-I-002: Slack channel with secret-store credential per Worked Example 2.
- TC-30-I-003: Inbox acknowledgment with bound ack-e-sign per Worked Example 3.
- TC-30-I-004: Email-queue retry exhaustion → URS-21 finding per Worked Example 4.
- TC-30-I-005: AI-assisted template draft accepted per Worked Example 5.
- TC-30-I-006: Governed reopen of locked program per Worked Example 6.
- TC-30-I-007: Inbound consumer integration with URS-13 / URS-14 / URS-15 / URS-16 / URS-17 / URS-18 / URS-19 / URS-20 / URS-21 / URS-22 / URS-23 / URS-24 / URS-25 / URS-26 / URS-27 / URS-28 / URS-29 events.
- TC-30-I-008: Event without mapped effective template emits missing-template finding to URS-21.
- TC-30-I-009: Cross-module event emission for chronic-failure CAPA to URS-18.
- TC-30-I-010: Secret-store integration with AWS Secrets Manager mock.
- TC-30-I-011: Cross-tenant `platform_admin` break-glass logged.
- TC-30-I-012: MIRA copilot read-only context; advisory drafting only.
- TC-30-I-013: Mandatory-alert allowlist add/remove with HITL + bound e-sign + URS-13 CR.
- TC-30-I-014: Channel test action with success and failure outcomes.
- TC-30-I-015: Email bounce handled (no retry).

### 16.3 End-to-end tests

- TC-30-E-001: OOS notification flow per Worked Example 1.
- TC-30-E-002: Slack channel rotation per Worked Example 2.
- TC-30-E-003: QP acknowledgment per Worked Example 3.
- TC-30-E-004: SMTP outage → terminal failure → URS-21 finding per Worked Example 4.
- TC-30-E-005: AI template draft per Worked Example 5.
- TC-30-E-006: Reopen scenario per Worked Example 6.
- TC-30-E-007: 1000 concurrent recipients per send — NFR-30-07.
- TC-30-E-008: India CDSCO Schedule M §16 records scenario.

### 16.4 Performance tests

- TC-30-P-001: Inbox unread-count p95 latency (NFR-30-02).
- TC-30-P-002: Inbox list p95 latency (NFR-30-03).
- TC-30-P-003: Send orchestration p95 latency (NFR-30-04).
- TC-30-P-004: Email-queue throughput (NFR-30-05).
- TC-30-P-005: Audit-trail append p99 latency including per-row inbox audit (NFR-30-06).
- TC-30-P-006: Bound e-signature p95 latency (NFR-30-10).
- TC-30-P-007: Secret-store resolution p95 latency (NFR-30-11).
- TC-30-P-008: Mandatory-alert delivery SLA (NFR-30-12).

### 16.5 Security tests

- TC-30-S-001: Cross-tenant access rejected by RLS.
- TC-30-S-002: Missing RBAC rejected.
- TC-30-S-003: Missing Authority Profile rejected.
- TC-30-S-004: Missing HITL rejected.
- TC-30-S-005: Missing bound e-signature rejected.
- TC-30-S-006: SQL injection rejected.
- TC-30-S-007: Audit-trail UPDATE / DELETE rejected.
- TC-30-S-008: AI service attempting send / release / dispatch / acknowledge rejected.
- TC-30-S-009: PII redaction in logs verified.
- TC-30-S-010: Inline credentials in channel payload rejected.
- TC-30-S-011: `authentication_token_hash` not used as live bearer token verified.
- TC-30-S-012: Rendered-content hash tampering detected.
- TC-30-S-013: Manual send actor in recipient list rejected.

---

## 17. Validation Evidence

### 17.1 URS-30-VAL-001: Requirements traceability matrix

Complete RTM mapping every URS-30 requirement (DEC-30-01.DEC-30-23, BR-30-01.BR-30-25, NFR-30-01.NFR-30-12, SoD-30-01.SoD-30-07, SEC-30-01.SEC-30-14) to test cases (TC-30-U-001.TC-30-U-024, TC-30-I-001.TC-30-I-015, TC-30-E-001.TC-30-E-008, TC-30-P-001.TC-30-P-008, TC-30-S-001.TC-30-S-013) and code modules (§15).

### 17.2 URS-30-VAL-002: Design qualification (DQ)

Architecture, data model, API contract, workflow, business rules, audit trail, security, integration; signed by Validation Head, QA Head, RA Head, Manufacturing Head, **Information Security Head (Primary Owner)**, Qualified Person Authority.

### 17.3 URS-30-VAL-003: Installation qualification (IQ)

Migration application + RLS verification + route mount verification + frontend hook resolution + secret-store integration verification.

### 17.4 URS-30-VAL-004: Operational qualification (OQ)

Happy-path execution of every test case with evidence captures.

### 17.5 URS-30-VAL-005: Performance qualification (PQ)

NFR-30-01.NFR-30-12 verification including mandatory-alert delivery SLA.

### 17.6 URS-30-VAL-006: AI/ML governance evidence

Per ARCH-AI-001: (a) MIRA read-only context integration; (b) AI advisory drafting only with mandatory human acceptance via `notification_ai_assistance`; (c) **AI cannot send notifications, release templates, dispatch digests, or acknowledge inbox items** verification; (d) Annex 22 §7 + EU AI Act Art. 13 internal forward-looking control compliance evidence.

### 17.7 URS-30-VAL-007: Regulatory mapping evidence

FDA 21 CFR Part 11 §§11.10(a), 11.10(e), 11.50, 11.70; **EU GMP Annex 11 §§4, 5, 9, 12, 14, 16**; Annex 22 Draft 2025 §7; EU AI Act Art. 13; MHRA Data Integrity Guidance (ALCOA+); GAMP 5 Cat 5; **FDA CSA September 2025 Final Guidance**; **ISO/IEC 27001**; India CDSCO Schedule M §16.

### 17.8 URS-30-VAL-008: Migration evidence gate

Per §9.3.

### 17.9 URS-30-VAL-009: Signature manifest

QA Head, RA Head, Validation Head, Manufacturing Head, **Information Security Head (Primary Owner)**, Qualified Person Authority, Site Quality Lead, Founder / Chairman & MD per §19.

### 17.10 URS-30-VAL-010: Post-launch periodic-review pack

(a) Notification metrics (sends per tenant, channel success/failure rates, mandatory-alert delivery SLA compliance, inbox acknowledgment rate); (b) AI-assistance acceptance rate; (c) audit-trail integrity; (d) reopen-event audit; (e) cross-tenant break-glass audit; (f) cross-module event consumption metrics; (g) secret-store reliability; (h) chronic-failure detection metrics; periodic review at quarterly cadence by Information Security Head + QA Head + Validation Head + Qualified Person Authority.

---

## 18. Document Change History

| Version | Date | Author | Change Summary |
|---|---|---|---|
| 1.0 | 2026-05-07 | Founder Doctrine — Verixa URS Cell | First issued user requirements specification for Module 30. |

---

## 19. Document Approval

| Role | Name | Signature | Date |
|---|---|---|---|
| Founder / Chairman & MD | Vimal | __________ | __________ |
| QA Head | __________ | __________ | __________ |
| RA Head | __________ | __________ | __________ |
| Validation Head | __________ | __________ | __________ |
| Manufacturing Head | __________ | __________ | __________ |
| Information Security Head (Primary Owner) | __________ | __________ | __________ |
| Qualified Person Authority | __________ | __________ | __________ |
| Site Quality Lead | __________ | __________ | __________ |

---

## 20. Cross-Module Event Contract

### 20.1 Outbound events (emitted by Module 30)

| Event | Consumer | Payload key fields |
|---|---|---|
| `notification_template_created` | URS-21 | `template_id`, `event_type` |
| `notification_template_released_effective` | URS-13 | `template_id`, `change_request_id`, `released_by`, `e_signature_id` |
| `notification_channel_created` | URS-21 | `channel_id`, `channel_type` |
| `notification_channel_tested` | URS-21 | `channel_id`, `test_outcome` |
| `notification_channel_secret_rotated` | URS-21 | `channel_id`, `rotated_by` |
| `notification_send_dispatched` | URS-21 | `send_id`, `event_type`, `recipient_count` |
| `notification_send_failed` | URS-21 | `send_id`, `error_message` |
| `notification_send_bounced` | URS-21 | `send_id`, `bounce_type` |
| `notification_email_queued` | — | `queue_id`, `recipient_email` |
| `notification_email_sent` | — | `queue_id`, `provider_message_id` |
| `notification_email_terminal_failed` | URS-21 (chronic-failure detector) | `queue_id`, `recipient_email`, `attempt_count` |
| `notification_digest_compiled` | — | `digest_id`, `item_count` |
| `notification_digest_dispatched` | URS-21 | `digest_id`, `recipient_user_id` |
| `notification_inbox_row_created` | — | `inbox_id`, `user_id` |
| `notification_inbox_acknowledged` | URS-21 (per-row audit) | `inbox_id`, `acknowledged_by`, `acknowledgment_e_signature_id` (where applicable) |
| `notification_finding_created` | **URS-21 (Findings — primary consumer)** | `finding_id` (URS-21), `severity`, `finding_type` |
| `notification_capa_linked` | **URS-18 (CAPA — primary consumer)** | `capa_id`, `linked_by`, `source_type = notification_delivery` |
| `notification_program_locked` | URS-21 | `program_lock_id`, `locked_by`, `lock_e_signature_id` |
| `notification_program_reopened` | URS-21 (governed-reopen audit) | `program_lock_id`, `reopened_by`, `executive_co_signer`, `qp_co_signer`, `reopen_reason` |

### 20.2 Inbound events (consumed by Module 30 per DEC-30-23)

Module 30 consumes events from every other URS module as the platform-wide notification dispatcher. The canonical consumed event set includes:

| Source Module | Event | Default mandatory-alert? | Default template_code |
|---|---|---|---|
| URS-13 Change Control | `change_request_approved` | Yes | `TPL-CC-Approved` |
| URS-14 Complaints | `complaint_severity_critical` | Yes | `TPL-CMP-Critical` |
| URS-15 OOS / OOT | `oos_classified` | Yes | `TPL-OOS-Classified` |
| URS-16 Deviations | `deviation_closed` | Yes | `TPL-DEV-Closed` |
| URS-17 RCA | `rca_completed` | No | `TPL-RCA-Completed` |
| URS-18 CAPA | `capa_effectiveness_due` | Yes | `TPL-CAPA-EffDue` |
| URS-18 CAPA | `capa_effectiveness_failed` | Yes | `TPL-CAPA-EffFailed` |
| URS-19 Risk | `risk_high_severity` | Yes | `TPL-RISK-HighSev` |
| URS-20 Reviews | `review_completed` | No | `TPL-REV-Completed` |
| URS-21 Findings | `finding_critical_severity` | Yes | `TPL-FND-Critical` |
| URS-22 Inspection | `inspection_observation_added` | Yes | `TPL-INSP-Observation` |
| URS-23 Batch Records | `batch_record_approved` | Yes | `TPL-BR-Approved` |
| URS-23 Batch Records | `batch_record_rejected` | Yes | `TPL-BR-Rejected` |
| URS-24 Stability | `stability_oos_recorded` | Yes | `TPL-STB-OOS` |
| URS-24 Stability | `shelf_life_claim_approved` | No | `TPL-STB-Claim` |
| URS-25 EM | `em_excursion_created` | Yes | `TPL-EM-Excursion` |
| URS-25 EM | `em_excursion_closed` | Yes | `TPL-EM-Closed` |
| URS-26 APQR | `apqr_report_approved` | No | `TPL-APQR-Approved` |
| URS-27 Regulatory | `regulatory_submission_approved` | Yes (with ack-sig) | `TPL-REG-SubApproved` |
| URS-27 Regulatory | `regulatory_commitment_overdue` | Yes | `TPL-REG-CmtOverdue` |
| URS-28 Training | `training_overdue` | Yes | `TPL-TRN-Overdue` |
| URS-28 Training | `training_gap_overdue` | Yes | `TPL-TRN-GapOverdue` |
| URS-29 Screen Reader | `sr_capture_failure` | Yes | `TPL-SR-CaptureFail` |
| URS-31 DQG | `dqg_failure` | Yes | `TPL-DQG-Failure` |
| URS-33 GMP | `gmp_event` | Per event type | varies |
| URS-34 GDP | `gdp_event` | Per event type | varies |
| URS-35 Infrastructure | `infra_outage` | Yes | `TPL-INFRA-Outage` |

The mandatory-alert allowlist is tenant-configurable per DEC-30-05.

---

## 21. References

- ARCH-AI-001 — AI Optionality and Manual Continuity (binding architecture)
- VRX-SPEC-URS-030-Notifications-Delivery-Channels-and-Communication-Governance.md (Module specification)
- URS-01.URS-29, URS-31.URS-35 (cross-module contracts)
- **FDA 21 CFR Part 11** §§11.10(a), 11.10(e), 11.50, 11.70
- **EU GMP Annex 11** §§4, 5, 9, 12, 14, 16
- EU GMP Annex 22 (Draft 2025) §7 — internal forward-looking control
- EU AI Act (Regulation 2024/1689) Art. 13 — internal forward-looking control
- **MHRA Data Integrity Guidance (2018)** — ALCOA+
- GAMP 5 Cat 5
- **FDA Computer Software Assurance (CSA) — September 2025 Final Guidance**
- **ISO/IEC 27001** — information security
- India CDSCO Schedule M (Revised) §16

---

**END OF VRX-URS-30 — NOTIFICATIONS, DELIVERY CHANNELS, AND COMMUNICATION GOVERNANCE — VERSION 1.0**
