# Verixa — User Requirements Specification

# Module 3: Context Gate & Approval Scope

| Field | Value |
|---|---|
| Document ID | VRX-URS-03 |
| Version | 1.0 |
| Status | Final — ready for QA, Validation, Regulatory Affairs, Information Security, 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-03-VAL-008) and validation evidence pack are satisfied. |
| Document Type | User Requirements Specification (URS) |
| GAMP 5 Category | Category 5 — Custom Application |
| Regulatory Classification | Critical infrastructure substrate — operates the runtime context filter and approval-scope check that constrain every regulated read and every regulated decision across the Verixa platform to the actor's authorised scope. |
| Date of Issue | 2026-05-05 |
| Module Owner (Engineering) | Platform / Identity Squad |
| Module Owner (Quality Validation) | CSV / CSA Lead — Context & Scope |
| Module Owner (Compliance) | Quality Assurance, Regulatory Affairs |
| Approving Authority | Founder / Chairman & MD; QA Head; Validation Head; RA Head; Information Security Head |

## Document Approval

| Role | Name | Signature | Date |
|---|---|---|---|
| Author — Platform Architecture | _____________________ | _____________________ | __________ |
| Reviewer — Engineering Lead | _____________________ | _____________________ | __________ |
| Reviewer — QA / Validation Lead | _____________________ | _____________________ | __________ |
| Reviewer — Information Security Lead | _____________________ | _____________________ | __________ |
| Reviewer — Regulatory Affairs Lead | _____________________ | _____________________ | __________ |
| Approving Authority — Founder, Chairman & MD | _____________________ | _____________________ | __________ |

## Version History

| Version | Date | Summary |
|---|---|---|
| 1.0 | 2026-05-05 | First issued user requirements specification for Module 3. |

---

## 0. Document Framing

### 0.1 Purpose of this document

This URS defines the target expected state for Verixa's Context Gate & Approval Scope module (Module 3). It is the binding contract between product, engineering, quality validation, regulatory affairs, information security, and the executive authority for the design, implementation, validation, release, and on-going periodic review of the runtime context filter, the per-module context configuration registry, active-context resolution, the approval-scope check applied at every regulated decision, the context-coverage CI gate, the context-aware front-end (selector, breadcrumbs, gates), and the audit events Module 3 emits. Compliance with this URS is mandatory.

### 0.2 Audience

- Engineering — design, implementation, code review.
- Quality Assurance / Validation — IQ / OQ / PQ test design, traceability matrix, validation reports.
- Regulatory Affairs — regulatory mapping, inspection readiness.
- Information Security — security review, penetration testing, incident response.
- Product Owners — feature definition, UX acceptance.
- Inspectors and Auditors — evidence of system intent and controls.
- Customers — confirmation of platform behaviour during qualification of Verixa as a supplier.

### 0.3 Reading conventions

- Requirements use the keywords MUST, SHOULD, and MAY as defined in IETF RFC 2119 / RFC 8174.
- Atomic requirement identifier form: `URS-03-<Domain>-<Number>`. Domain prefixes: `FE`, `BE`, `WF`, `DATA`, `SEC`, `AUD`, `ESIG`, `AI`, `INT`, `REP`, `VAL`.
- Supporting identifiers: `DEC-03-N` (closed launch decision), `DEP-03-N` (dependency), `BR-03-N` (business rule), `RG-03-N` (regulatory mapping row), `TC-PLAIN-N` (plain-language scenario), `TC-TECH-N` (technical test case), `AC-03-N` (Given/When/Then acceptance criterion), `CIM-N` (change-impact matrix row).
- Where this document does not state a fact in §18.1, the absence MUST be raised as an in-scope decision request to QA / RA / Information Security and resolved before signature; this final version has no decisions left open.

### 0.4 Inherited cross-module standards

The twelve standards defined in URS-01 §0.4 apply unchanged to Module 3: three-layer guard hierarchy, Controlled Approval Modal contract, API path discipline, tenant isolation, audit trail with rollback on audit-write failure, ALCOA+ universal compliance, fail-secure on resolver / context failure, claims-version mismatch handling, no optimistic updates on regulated actions, AI is suggestion-only, Document Quality Gateway interception, encryption discipline.

Module-specific additions:

13. **Context filter universal application.** Every back-end regulated read or write that targets a regulated record MUST pass through the context filter; bare database access bypassing the filter is forbidden outside the documented platform-context exemption list.
14. **Context coverage gate.** Every per-module context configuration entry MUST name columns that exist in the corresponding database table; a Continuous Integration gate MUST fail any pull request that introduces a context configuration referencing a column that does not exist in the migration set.
15. **Active context persistence.** A user's active context (tenant, study, site, product, supplier as applicable) MUST be persisted on the session row and on the bootstrap response so that every request resolves the same context the user last selected.
16. **Approval-scope check at decision time.** Every regulated decision (approve, release, dispose, sign off, close, certify) MUST verify, at the moment of decision, that the union of the actor's Authority Profile scopes intersects the target record's scope on every dimension required by the Authority Profile; failure returns `403 APPROVAL_SCOPE_DENIED` and is audited.
17. **Cross-context request denial.** A request whose URL or payload context does not match the session's resolved context MUST be denied with `403 CROSS_CONTEXT_DENIED`; this is forensic and audited.

### 0.5 Verixa URS suite — module map

This module is **URS-03** in the thirty-five-module suite. Cross-module references use the module number and short title.

| Module | Title |
|---|---|
| URS-01 | Authentication, Session Management & Access Control |
| URS-02 | Role-Based Access Control & Permissions |
| URS-03 | Context Gate & Approval Scope *(this document)* |
| URS-04 | Workflow / Human-in-the-Loop / Electronic Signature / Approval Authority |
| URS-05 | Authority Profile / Approval Delegation / Segregation of Duties |
| URS-06 | Audit Trail & Data Integrity |
| URS-07 | Study Management |
| URS-08 | Tenant Management |
| URS-09 | Sites Management |
| URS-10 | Products Management |
| URS-11 | Supplier Management |
| URS-12 | Document Control & Knowledge Libraries |
| URS-13 | Regulated change governance |
| URS-14 | Complaints |
| URS-15 | Out-of-Specification / Out-of-Trend |
| URS-16 | Deviations |
| URS-17 | Root Cause Analysis |
| URS-18 | Corrective and Preventive Actions |
| URS-19 | Risk Assessment |
| URS-20 | Reviews |
| URS-21 | Findings |
| URS-22 | Inspection Management & Readiness |
| URS-23 | Batch Records & Manufacturing Execution |
| URS-24 | Stability Management |
| URS-25 | Environmental Monitoring |
| URS-26 | Annual Product Quality Review |
| URS-27 | Regulatory Intelligence & Submission Governance |
| URS-28 | Training Management & Qualification |
| URS-29 | Screen Reader / Data Capture & Extraction Governance |
| URS-30 | Notifications, Delivery Channels & Communication Governance |
| URS-31 | Document Quality Gateway |
| URS-32 | MIRA AI Chat / Command Center / Agent Orchestration |
| URS-33 | Good Manufacturing Practice — Manufacturing Operations & Controls |
| URS-34 | Good Distribution Practice — Distribution, Warehouse & Dispatch Controls |
| URS-35 | Infrastructure, Backup, Restore & Operational Resilience |

### 0.6 Glossary

#### Context, scope, and gate concepts

- **Context** — the set of master-data identifiers that bound a user's current view of the platform: tenant identifier always; plus, where applicable, active study, active site, active product, active supplier.
- **Scope** — the set of master-data identifiers across seven dimensions plus tenant-wide that bound where an Authority Profile applies (site, product, study, supplier, module, entity type, workflow type, plus `tenant_wide` and the global super-authority flag).
- **Active context** — the context the user has selected (or that has been resolved by default) for the current session; persisted on the session row.
- **Context filter** — the SQL filter applied by the back end to every regulated read and write so that records out of context are not returned and out-of-context writes are rejected.
- **Module context configuration** — the per-module mapping of regulated tables to their tenant column, study column, site column, product column, supplier column; consumed by the context filter at runtime and by the context-coverage CI gate at build time.
- **Context-coverage CI gate** — a Continuous Integration check that fails any pull request whose module context configuration names a column that does not exist in the corresponding migration's `CREATE TABLE`.
- **Context Gate** — the front-end and back-end gate that prevents a regulated page or API call from operating until the active context required by the page or call is resolved and matches the session.
- **Active-context selector** — the front-end component that lets a user pick (or change) the active study, site, product, or supplier for their current session.
- **Approval-scope check** — the runtime check, performed at the moment of a regulated decision, that the target record's scope intersects the union of the actor's Authority Profile scopes on every dimension the Authority Profile requires.
- **Cross-context request** — a request whose URL parameters or payload reference a context (study, site, product, supplier) that does not match the session's resolved active context; denied with `403 CROSS_CONTEXT_DENIED`.
- **Default context** — the context resolved at login when the user has not yet picked one; the launch default is `tenant_id` only, with no default study, site, product, or supplier.
- **Tenant-wide context** — a special scope-flag indicating that the user's authority applies across the entire tenant; bypasses the dimension-by-dimension intersection check on a `tenant_wide` Authority Profile assignment.
- **Global super-authority** — break-glass authority (`global_quality_oversight` per URS-01 §3.3.3) that bypasses scope checks; tracked separately and SOC-alerted on every use.

#### Engineering and platform

- **`MODULE_CONTEXT_CONFIG`** — the canonical front-end and back-end registry of per-module context columns; declarative configuration with one entry per regulated module.
- **`applyContextFilters`** — the back-end function that, given the active context and the per-module configuration, appends the appropriate `WHERE` clauses to a SQL builder query.
- **`<ContextGate>`** — the front-end component that wraps a route or page; renders a context-selection prompt if the required context is not resolved; renders the page once context is resolved.
- **`/access/me/context`** — the bootstrap endpoint that returns the user's resolved context (active tenant, study, site, product, supplier, where applicable) and the matrix version per URS-02.
- **Context envelope** — the request envelope that carries the resolved context to back-end handlers and is used by the context-filter middleware and the approval-scope check.
- **Tenant Data Access Layer (TDAL)** — the only sanctioned database access wrapper; binds tenant context per URS-02 §0.6 and binds active context for Module 3.
- **Row-Level Security (RLS)** — the database-level filter for tenant isolation; Module 3 layers context filtering on top of RLS.

#### Regulatory and process

- **21 CFR Part 11 §11.10(d)** — limits on system access to authorised individuals; consumed where Module 3 denies cross-context access.
- **21 CFR Part 11 §11.10(g)** — authority checks for system functions; consumed at the approval-scope check.
- **EU GMP Annex 11 §12, §12.1** — logical access controls; consumed by every context filter and approval-scope check.
- **EU GMP Annex 11 §9** — audit trails; consumed by every Module 3 audit event.
- **ALCOA+** — applied to every Module 3 audit event and every regulated decision the approval-scope check gates.

If a reader is uncertain about a term not in this glossary, the term is treated as a defect in this URS and resolved before signature; no unresolved decisions are carried.

---

## 1. Module Purpose

**Plain-language primer (read before §1 if you are a non-domain engineer or a product owner).** A user's permission matrix says "you can update deviations." A user's Authority Profile says "you can approve final-quality records." Neither says **which** deviations or **which** records. **Module 3 is the layer that says "yes, but only the deviations for site = Chennai and product = antibiotic-line, because that is your active scope."** When you click an approve button, Module 3 does two things: it checks that the record you are approving is in your active context (so you cannot accidentally approve another site's record), and it checks that your Authority Profile's scope intersects the record's scope on every dimension that matters (so you cannot approve a record outside the boundary you were authorised for). RBAC alone is not enough. Authority alone is not enough. Context and scope close the loop. The model is shown in Diagram 0.4-A.

#### Diagram 0.4-A — Where Context Gate & Approval Scope sit in the authorisation pipeline

```mermaid
flowchart LR
  A([Authenticated identity]) --> B[URS-01 Auth — token + claims_version]
  B --> C[URS-02 RBAC — base role + permission matrix]
  C --> D[URS-03 Context Gate — active context resolved]
  D --> E[URS-03 Approval Scope — record scope ∩ authority scope]
  E --> F[URS-05 Authority Profile presence check]
  F --> G[URS-04 Controlled Approval Modal + e-signature]
  G --> H[Action committed + audit row + scope snapshot]
  D -- denied --> X1[403 CONTEXT_REQUIRED or 403 CROSS_CONTEXT_DENIED]
  E -- denied --> X2[403 APPROVAL_SCOPE_DENIED]
```

Module 3 is the runtime context filter, the per-module context configuration registry, the active-context resolver, the approval-scope check, the context-coverage CI gate, the context-aware front-end (selector, breadcrumbs, `<ContextGate>` component), and the audit substrate that records context changes and approval-scope decisions. It does not authenticate users (URS-01), it does not gate module entry by base role (URS-02), it does not own the Authority Profile catalogue (URS-05), and it does not perform the electronic-signature ceremony (URS-04). It is the layer that constrains every read, every write, and every regulated decision to the user's authorised scope.

---

## 2. Scope

### 2.1 In scope

- The per-module context configuration registry mapping every regulated table to its tenant column, study column, site column, product column, supplier column.
- The runtime context filter `applyContextFilters` consumed by every regulated SELECT, INSERT, UPDATE, DELETE, and soft-delete on a regulated table.
- The active-context resolver: at session bootstrap, on context-selector change, and on URL-driven context override.
- The active-context selector front-end component (header bar) and the `<ContextGate>` component that wraps regulated routes.
- Context persistence on the session row (`user_sessions.tenant_id`, `study_id`, `site_id`, `product_id`, `supplier_id`).
- Default-context policy at login: `tenant_id` always; no default study, site, product, or supplier (the user picks).
- Approval-scope check executed at every regulated decision: target-record scope ∩ actor authority scopes on every dimension the Authority Profile requires.
- Cross-context denial: any URL parameter or payload reference whose context does not match the session's active context returns `403 CROSS_CONTEXT_DENIED`.
- Context-coverage Continuous Integration gate that fails any pull request whose module configuration names a non-existent column.
- Audit events for context selection, context resolution failure, approval-scope check pass, approval-scope check fail, cross-context attempt, configuration mutation, and tenant-wide / global super-authority bypass.
- Reports and exports of approval-scope decisions, cross-context attempts, and configuration coverage status.
- Dependencies on URS-01 (session and tenant binding), URS-02 (effective permissions), URS-05 (Authority Profile and scope rules), URS-06 (audit substrate), URS-08 (tenant master), URS-09 (sites master), URS-10 (products master), URS-07 (studies master), URS-11 (suppliers master), URS-30 (notifications), URS-35 (backup / restore).

### 2.2 Out of scope

- Authentication, multi-factor authentication, single sign-on, password policy, lockout, IP allowlist (URS-01).
- Permission matrix, role catalogue, access-governance lifecycle (URS-02).
- Authority Profile catalogue, delegations, Segregation-of-Duties rule registry (URS-05).
- Workflow templates, electronic-signature ceremony, human-in-the-loop modal (URS-04 and URS-06).
- Master-data CRUD for tenants, sites, products, studies, suppliers (URS-07/08/09/10/11).
- AI-driven scope recommendation or auto-context-selection (explicitly prohibited at launch).

### 2.3 Closed launch decisions

The table below carries the binding closed decisions on which this URS rests. They are the launch design premises.

| Identifier | Closed launch decision |
|---|---|
| DEC-03-01 | The seven scope dimensions are exactly site, product, study, supplier, module, entity type, workflow type, with `tenant_wide` and `global_super_authority` flags. The list matches URS-05 and URS-01 §3.3.2. Adding a dimension is a Class 1 change. |
| DEC-03-02 | Default context at login is `tenant_id` only. No default study, site, product, or supplier is auto-selected; the user picks. Pages requiring such a context render the `<ContextGate>` selector before the page itself. |
| DEC-03-03 | Active context is persisted on the `user_sessions` row through dedicated columns (`study_id`, `site_id`, `product_id`, `supplier_id`); the bootstrap endpoint returns the resolved context. |
| DEC-03-04 | Context-filter coverage is enforced by a Continuous Integration gate that fails any pull request whose module context configuration names a column that does not exist in the corresponding `CREATE TABLE` migration. |
| DEC-03-05 | The runtime context filter is mandatory for every regulated read and write; bypass is permitted only through the documented platform-context exemption list (`tdal.withPlatformContext`) which is reviewed by Information Security on every change. |
| DEC-03-06 | The approval-scope check executes at the moment of decision; the union of the actor's Authority Profile scopes (assignment-derived plus delegation-derived) is intersected with the target record's scope on every dimension the Authority Profile requires; non-empty intersection is the pass condition. `tenant_wide` Authority Profile assignments bypass dimension-by-dimension intersection (per DEC-03-01) but are still scope-tagged in audit. |
| DEC-03-07 | Cross-context request denial is a forensic event audited as `CROSS_CONTEXT_DENIED`; the denial is rate-limited per user per minute to suppress brute-force enumeration. |
| DEC-03-08 | The active-context selector is the **only authoritative path** to persist a context switch. A deep-link MAY pre-fill a proposed context **only after server validation** (tenant membership + scope eligibility); the deep-link MUST NOT silently persist context. The user MUST confirm the proposed context through the active-context selector or an equivalent in-page confirmation prompt before the session's active context is rebound. On confirmation the system emits `CONTEXT_SWITCHED` with `source = 'deeplink'` so the audit chain reflects how the switch was initiated. If the deep-link's proposed context fails validation it is dropped silently and the user lands on the page with the prior session context unchanged; the attempt is not audited (it is treated as a non-action). |
| DEC-03-09 | Context filtering applies in addition to Row-Level Security tenant isolation (URS-02). The two layers compose: RLS enforces tenant isolation; the context filter enforces the user's intra-tenant scope. |
| DEC-03-10 | Use of the `global_quality_oversight` super-authority bypasses the approval-scope check; every use emits `GLOBAL_SUPER_AUTHORITY_USED`, requires an electronic signature, and triggers a Security Operations Centre alert; auto-expiry is enforced per URS-01. |
| DEC-03-11 | Context-aware breadcrumbs and URL patterns are the canonical UI manifestation of the active context; the format is `/<module>/<resource>/<id>` with optional `?context=<dim>:<id>` overrides honoured only as deep-link conveniences (per DEC-03-08). |
| DEC-03-12 | The approval-scope check writes a `scope_snapshot` row into the URS-06 audit substrate at the moment of every regulated decision; the snapshot captures the actor's authority profiles, scope dimensions, and the target record's scope, so the inspector can reconstruct why the decision was permitted. |
| DEC-03-13 | Context resolution failure (the resolver cannot determine the active context) is fail-secure: the back end returns `503 CONTEXT_RESOLUTION_FAILED`; the front end renders the `<ContextGate>` outage banner; no regulated decision is permitted while the failure persists. |

---

## 3. User Roles and Permissions

### 3.1 Architecture

Module 3 consumes Layer 1 (base role) and Layer 2 (permission matrix) from URS-02 and Layer 2 (Authority Profile) plus Layer 3 (Delegation) from URS-05. It does not introduce new role tiers. Module 3 owns one administrative surface — the per-module context configuration registry — that is platform-administrator-only. End-user surfaces in Module 3 are the active-context selector and the `<ContextGate>` component, both available to every authenticated user.

### 3.2 Role definitions

The five tenant-level base roles defined by URS-02 (admin, quality_lead, reviewer, auditor, viewer) and the two cross-tenant platform identities (platform_admin, super_admin) apply unchanged. Module 3 does not introduce new roles.

### 3.3 Authority Profiles consumed by Module 3

Module 3 consumes Authority Profiles owned by URS-05 for two regulated administrative actions:

| Authority Profile (consumed) | Module 3 action gated |
|---|---|
| `tenant_admin_authority` | Read the per-module context configuration registry for the tenant; export approval-scope reports |
| platform-only (no profile; identity check) | Edit the per-module context configuration registry (`platform_admin` or `super_admin` identity required); add or change a context dimension |
| `global_quality_oversight` | Bypass the approval-scope check (break-glass); requires electronic signature, SOC alert, and auto-expiry per URS-01 |

### 3.4 Segregation-of-Duties rules

| SoD rule (consumed from URS-05) | Module 3 application |
|---|---|
| Self-modification forbidden | A user cannot edit a context configuration entry that grants themselves new context coverage; the back end rejects with `SELF_CONTEXT_MODIFICATION_FORBIDDEN`. |
| Author ≠ approver of context-configuration change | The administrator who edits a context configuration row cannot be the same who signs the approval-scope-report export covering that change window. |

### 3.5 Worked examples

#### Worked example A — Sarah selects an active study and approves a deviation in scope

Sarah holds `final_quality_approver` Authority Profile scoped to site `Chennai`, product `antibiotic-line`. She logs in. Default context resolves to `tenant_id = AcmePharma` only — no active study, site, or product. She opens the deviation list page. The page is gated by `<ContextGate>` on `study`, so the front end renders the active-context selector. Sarah picks study `S-2026-0042`. The session row is updated with `study_id = S-2026-0042`. Sarah opens deviation `DEV-2026-0117`. The page renders because the deviation belongs to study `S-2026-0042`. Sarah clicks "Approve closure". The back end performs the approval-scope check: the deviation's scope is `(site=Chennai, product=antibiotic-line, study=S-2026-0042)`; Sarah's authority scope is `(site=Chennai, product=antibiotic-line)`; the intersection is non-empty on every dimension the `final_quality_approver` profile requires (site and product); pass. The deviation closure proceeds through URS-04's Controlled Approval Modal. The audit substrate records `APPROVAL_SCOPE_CHECK_PASSED` with the scope snapshot and links the electronic signature.

#### Worked example B — Sarah tries to approve an out-of-scope record; system blocks

Sarah opens deviation `DEV-2026-0211`. The deviation belongs to study `S-2026-0042` (in her current context) but to product `vaccine-line` (not in her authority scope). The front end has not disabled the approve button because the user-interface gate `<AuthorityGuard authority="final_quality_approver">` is true (Sarah holds the profile). She clicks Approve. The back end performs the approval-scope check: deviation scope `(site=Chennai, product=vaccine-line, study=S-2026-0042)` ∩ Sarah's authority scope `(site=Chennai, product=antibiotic-line)` is empty on the `product` dimension. The back end returns `403 APPROVAL_SCOPE_DENIED` with a structured detail naming the failing dimension. The user interface displays "You may not approve this record because your authority does not cover product `vaccine-line`." An audit row records `APPROVAL_SCOPE_CHECK_FAILED` with the scope snapshot and the failing dimension.

#### Worked example C — Cross-context URL attempt is denied

A penetration tester logs in as Sarah (in study `S-2026-0042`) and constructs a URL `/deviations/DEV-2027-0900?context=study:S-2027-0901`. The deep-link override is honoured at most for the page's read; the back end re-resolves the context against the session and detects that `S-2027-0901` is not the session's active study and not within Sarah's authority. The request returns `403 CROSS_CONTEXT_DENIED`. An audit row records `CROSS_CONTEXT_DENIED` with the source IP, user agent, attempted context, and session context. Repeated attempts within one minute trigger a Security Operations Centre alert.

#### Worked example D — Platform administrator updates the context configuration registry

A new module URS-26 (APQR) ships with a regulated table `apqr_records` that needs context coverage on tenant, product, and study. The platform administrator opens `/admin/context-config`, adds an entry `{module: 'apqr', tableName: 'apqr_records', tenantColumn: 'tenant_id', studyColumn: 'study_id', productColumn: 'product_id'}`, gives reason "URS-26 launch", and electronically signs. The Continuous Integration gate has already validated the migration and the configuration entry. The configuration registry version increments. Subsequent reads / writes to `apqr_records` are filtered by the active context. An audit row records `CONTEXT_CONFIG_UPDATED`.

#### Worked example E — Resolver outage and fail-secure UX

The active-context resolver cannot read its database for two minutes. The bootstrap endpoint returns `503 CONTEXT_RESOLUTION_FAILED` carrying a correlation identifier. The front end renders the `<ContextGate>` outage banner: "We could not resolve your active context. Approval actions are temporarily disabled. Try again in a moment." Every approve button across the platform is disabled. The Security Operations Centre receives the alert; the on-call engineer brings the resolver back. On the next bootstrap poll the banner clears and the page resumes. The audit substrate records `CONTEXT_RESOLUTION_FAILED` once per failed bootstrap with the correlation identifier.

#### Worked example F — Break-glass `global_quality_oversight` bypasses scope

During a critical inspection a senior QA lead must approve a record outside the normal site / product scope. They hold the `global_quality_oversight` super-authority, granted under §3.3 and auto-expiring within twenty-four hours per URS-01. The approval-scope check sees the super-authority flag, bypasses dimension-by-dimension intersection, but emits `GLOBAL_SUPER_AUTHORITY_USED` to the audit substrate, triggers a Security Operations Centre alert, and the QA Head receives an immediate notification. The record is approved; the inspector pack records the use with reason and electronic signature.

### 3.6 Role-permission matrix (Module 3 administrative surface only)

| Action (within Module 3) | viewer | reviewer | quality_lead | auditor | admin | platform_admin | super_admin | system identity | Authority Profile |
|---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|---|
| Read own active context | ✓ | ✓ | ✓ | ✓ | ✓ | support / break-glass only | support / break-glass only | — | — |
| Switch own active context (study / site / product / supplier) | ✓ | ✓ | ✓ | ✓ | ✓ | support / break-glass only | support / break-glass only | — | — |
| Read approval-scope-decision history (own actions) | ✓ | ✓ | ✓ | ✓ | ✓ | support / break-glass only | support / break-glass only | — | — |
| Read approval-scope-decision history (other users in tenant) | — | — | — | ✓ | ✓ | support / break-glass only | support / break-glass only | — | — |
| Read global context configuration registry (read-only) | — | — | — | ✓ | ✓ | ✓ | ✓ | — | — |
| Edit context configuration registry | — | — | — | — | — | ✓ + sign | ✓ + sign | — | platform-owned; identity check; reason and electronic signature |
| Export approval-scope-decision report | — | — | — | — | ✓ + sign | support / break-glass only | support / break-glass only | — | `tenant_admin_authority` |
| Use `global_quality_oversight` super-authority bypass | — | — | — | — | — | — | — | — | `global_quality_oversight` (auto-expiry, SOC alert, electronic signature) |

There is no `tenant_admin` base role in Module 3 (consistent with URS-02). Regulated actions are gated by base role plus Authority Profile. External identities (URS-01 §3.2.3) cannot edit the configuration registry; they participate only as scope-bound viewers.

#### 3.6.1 Platform-identity tenant actions — controlled support / break-glass posture

Per URS-02 §3.6.1, platform identities (`platform_admin`, `super_admin`) MAY perform tenant-scoped Module 3 actions (read approval-scope reports, switch a tenant's active context for support purposes) **only under a controlled support / break-glass posture**: target tenant identifier, business-justification reason, support-ticket / customer-reference identifier, electronic signature, `PLATFORM_TENANT_ACCESS_USED` audit emit, Security Operations Centre alert. Use outside the envelope returns `PLATFORM_TENANT_ACCESS_DENIED` (403).

---

## 4. End-to-End User Journeys

Each journey names trigger, preconditions, actor, entry screen, step-by-step UI, back-end transaction, validation, audit events, e-signature trigger where applicable, notifications, cross-module effects, and error / recovery paths.

### J-01 — User selects an active study at session start

- Trigger: user navigates to a regulated module that requires a study context.
- Steps: `<ContextGate>` detects no active study; renders the active-context selector listing studies the user is in scope for; user selects a study; the front end calls `POST /access/me/context` with the new study identifier; back end validates the study is in the user's tenant and within at least one of the user's Authority Profile scopes (or any membership-scoped permission); persists `study_id` on the session row; emits `CONTEXT_SELECTED`; returns the resolved context.
- Audit: `CONTEXT_SELECTED`.
- Cross-module: URS-07 study master read; URS-01 session row update; URS-06 audit ingest.
- Error: study not in tenant → `403 CONTEXT_TENANT_MISMATCH`; study not in user's scope → `403 CONTEXT_OUT_OF_SCOPE`.

```mermaid
sequenceDiagram
  autonumber
  participant U as User
  participant FE as Frontend
  participant CG as ContextGate
  participant API as Context API
  participant DB as Database
  participant AUD as Audit Log

  U->>FE: open regulated page (study required)
  FE->>CG: render active-context selector (no active study)
  U->>CG: pick study S-2026-0042
  CG->>API: POST /access/me/context {study_id}
  API->>DB: validate study within tenant + within user scope
  alt invalid
    API-->>CG: 403 CONTEXT_TENANT_MISMATCH / CONTEXT_OUT_OF_SCOPE
  else valid
    API->>DB: update user_sessions.study_id
    API->>AUD: append CONTEXT_SELECTED
    API-->>CG: 200 {resolved context}
    CG-->>FE: dismiss; render page
  end
```

### J-02 — User switches active study mid-session

- Trigger: user clicks the active-context selector in the header bar.
- Steps: front end calls `POST /access/me/context` with the new identifier; back end validates and persists; emits `CONTEXT_SWITCHED`. Front end re-fetches the current page's data with the new context. Pages that cannot operate in the new context (for example a record that does not exist in the new study) navigate the user to the module home.

### J-03 — Approval-scope check passes on a regulated decision

- Trigger: user clicks an approve button on a regulated record.
- Steps: front end POSTs to the regulated action endpoint with a Controlled Approval Modal payload; back end performs the approval-scope check (target record scope ∩ actor authority scope across required dimensions); writes a `scope_snapshot` row; emits `APPROVAL_SCOPE_CHECK_PASSED`; the regulated module's handler proceeds to electronic signature and commit.
- Audit: `APPROVAL_SCOPE_CHECK_PASSED` (with scope snapshot).

```mermaid
sequenceDiagram
  autonumber
  participant U as User
  participant FE as Frontend
  participant CAM as Controlled Approval Modal
  participant API as Module API (e.g. URS-16 deviation)
  participant CTX as Context Resolver
  participant ASC as Approval Scope Check
  participant AUD as Audit Log
  participant DB as Database

  U->>CAM: re-auth + meaning + reason
  CAM->>API: POST /deviations/:id/approve
  API->>CTX: resolve session + record context
  CTX-->>API: context envelope
  API->>ASC: target.scope ∩ actor.authority.scopes
  alt empty intersection
    ASC->>AUD: APPROVAL_SCOPE_CHECK_FAILED + snapshot
    API-->>CAM: 403 APPROVAL_SCOPE_DENIED
  else non-empty
    ASC->>AUD: APPROVAL_SCOPE_CHECK_PASSED + snapshot
    API->>DB: BEGIN TX (URS-04 e-sign + URS-16 closure)
    API->>DB: COMMIT
    API-->>CAM: 200
  end
```

### J-04 — Approval-scope check fails

- Trigger: user clicks approve on an out-of-scope record (front-end gate did not disable button because Authority Profile is held).
- Steps: back end runs the approval-scope check; intersection empty on a required dimension; returns `403 APPROVAL_SCOPE_DENIED`; emits `APPROVAL_SCOPE_CHECK_FAILED` with the snapshot; the user interface displays the failing dimension.
- Audit: `APPROVAL_SCOPE_CHECK_FAILED`.

### J-05 — Cross-context URL attempt

- Trigger: a request whose URL or payload context does not match the session's active context.
- Steps: back end detects the mismatch in the context-filter middleware; returns `403 CROSS_CONTEXT_DENIED`; emits `CROSS_CONTEXT_DENIED`; rate-limit triggers SOC alert if cluster threshold exceeded.

### J-06 — Context resolution failure (resolver outage)

- Trigger: the active-context resolver cannot read its data.
- Steps: bootstrap and per-request resolution return `503 CONTEXT_RESOLUTION_FAILED` with correlation identifier; front end renders outage banner; every regulated approve button is disabled; SOC alert fires; on recovery banner clears.

### J-07 — Platform administrator updates the context configuration registry

- Trigger: a new module ships and needs context coverage.
- Steps: platform administrator opens `/admin/context-config`; adds or updates a row; reason captured; Controlled Approval Modal signs; back end runs the in-line column-existence check (the same check the CI gate enforces); persists the change; increments configuration version; emits `CONTEXT_CONFIG_UPDATED`.
- Error paths: column does not exist → `400 CONTEXT_CONFIG_COLUMN_UNKNOWN`; module key already exists with same table name → `409 CONTEXT_CONFIG_DUPLICATE`.

### J-08 — Continuous Integration gate fails on missing column

- Trigger: a developer pushes a pull request that adds or modifies a `MODULE_CONTEXT_CONFIG` entry.
- Steps: the CI gate parses the configuration; for each entry, queries the migration set for the corresponding `CREATE TABLE` and checks every named column exists; if any column is missing, the gate fails with a precise file / line reference; pull request is blocked.

### J-09 — User opens a page that requires multiple context dimensions

- Trigger: user opens `/batch-records/...` which requires study and site.
- Steps: `<ContextGate>` checks both; if either is missing, renders the multi-dimension selector; user selects the missing dimensions; back end persists; page renders.

### J-10 — User in tenant-wide Authority Profile bypasses dimension intersection

- Trigger: user holds an Authority Profile assignment with `tenant_wide = true` (e.g., `quality_oversight_admin`).
- Steps: approval-scope check sees the `tenant_wide` flag, skips dimension-by-dimension intersection, still records the snapshot. The audit row marks the scope as tenant-wide.

### J-11 — User uses the `global_quality_oversight` break-glass

- Trigger: user holds the time-bounded super-authority and approves an otherwise-out-of-scope record.
- Steps: approval-scope check sees the super-authority flag, bypasses intersection, emits `GLOBAL_SUPER_AUTHORITY_USED`, fires SOC alert, requires electronic signature with extended meaning text, notifies QA Head.

### J-12 — Bulk approval honours per-record scope

- Trigger: user selects 25 records in a list view and clicks "Bulk approve".
- Steps: back end loops per record: each record's approval-scope check is independent; records that fail return per-row diagnostics; the bulk envelope returns 207 multi-status with success / failure per row; each successful row emits its own `APPROVAL_SCOPE_CHECK_PASSED` and electronic signature; each failed row emits `APPROVAL_SCOPE_CHECK_FAILED` with the dimension cause.

### J-13 — Read-only export honours context

- Trigger: user exports a list view.
- Steps: the SQL of the export honours the active context filter; the export manifest records the active context; the resulting file is bounded to records the user could have read interactively.

### J-14 — Auditor reads cross-context-denied forensic log

- Trigger: auditor reviews `/admin/governance/audit?event=CROSS_CONTEXT_DENIED`.
- Steps: read-only view; pagination; integrity-badge per chain segment.

### J-15 — Permission-denied path on context-configuration registry

- Trigger: a tenant administrator (without platform identity) tries to edit the registry.
- Steps: `RoleGuard` blocks the route; if a stray API call escapes, back end returns `403 PLATFORM_IDENTITY_REQUIRED`; an audit row records the denial.

### J-16 — Validation-error path on context-configuration submission

- Trigger: registry edit submitted with a non-existent column name or a non-existent module key.
- Steps: back end returns `400 CONTEXT_CONFIG_COLUMN_UNKNOWN` or `400 CONTEXT_CONFIG_MODULE_UNKNOWN`; inline error in editor.

### J-17 — System-error and retry path

- Trigger: 5xx response from the context API.
- Steps: non-blocking toast with correlation identifier; UI does not auto-retry mutations.

### J-18 — Context-version stale conflict

- Trigger: configuration registry edited concurrently in two browser tabs.
- Steps: second save returns `409 STALE_VERSION`; banner offers refresh + diff preservation.

### J-19 — Periodic access review covers context configuration

- Trigger: per URS-01 §12.10 the access review runs.
- Steps: review explicitly enumerates context-configuration changes in the period; reviewer signs the attestation; URS-30 records the closure event.

### J-20 — Periodic audit-trail review covers Module 3 high-risk events

- Trigger: per URS-01 §12.11.
- Steps: high-risk Module 3 events triaged within one business day: `CROSS_CONTEXT_DENIED` clusters, `CONTEXT_RESOLUTION_FAILED` clusters, `GLOBAL_SUPER_AUTHORITY_USED`, `CONTEXT_CONFIG_UPDATED` outside business hours.

### J-21 — DR drill restores configuration registry and audit chain

- Trigger: URS-35 DR drill.
- Steps: restore preserves configuration version history, audit-event chain, and approval-scope snapshot rows; integrity verifier confirms.

### J-22 — Migration introduces a new dimension (Class 1 change)

- Trigger: launch addition of an eighth dimension is rejected at the configuration layer; the platform team coordinates a Class 1 change with founder electronic signature.
- Steps: schema migration adds the column; configuration registry adds the dimension; resolver updates; CI gate updates; full regression on every consuming module.

### J-23 — Bulk action partial failure with per-row scope reasons

As J-12; the front end groups failed rows with their scope-failure dimensions for triage.

### J-24 — User without any in-scope study in the tenant

- Trigger: user opens a study-scoped page; they hold no Authority Profile and no permission grants in the tenant for any study.
- Steps: `<ContextGate>` detects empty selectable list; renders the empty state "No studies available in this tenant for your account; contact your administrator."

### J-25 — User with delegation receives time-bounded scope

- Trigger: user receives a delegation; their effective scopes for the period include the delegator's scopes.
- Steps: at the next bootstrap the resolver computes the union of assignment scopes plus active-delegation scopes; approval-scope check honours the union for the duration of the delegation.

### J-26 — User resets active context back to tenant-only

- Trigger: user opens the active-context selector and clicks "Reset to tenant only".
- Steps: front end calls `POST /access/me/context` with `{ reset: true }`; back end clears `study_id`, `site_id`, `product_id`, `supplier_id` on the session row; emits `CONTEXT_RESET`; subsequent regulated pages render `<ContextGate>` to require the user to pick again.
- Audit: `CONTEXT_RESET`.

### J-27 — Record-scope resolution failure blocks decision

- Trigger: user clicks Approve on a regulated record whose required-dimension columns are missing or null where the Authority Profile requires them.
- Steps: back end runs the Record Scope Resolver per §6.4.1; a required dimension cannot be derived; resolver returns `500 RECORD_SCOPE_UNRESOLVED`; the regulated decision is blocked; an audit row records the failure with the failing dimension; SOC alert fires per §12.9 because this state is a configuration-or-data-integrity defect, not an operator mistake.

### J-28 — Failed context-switch attempt is audited as `CONTEXT_SWITCH_DENIED`

- Trigger: user attempts to switch to a study outside their authority scope.
- Steps: back end returns `403 CONTEXT_OUT_OF_SCOPE`; emits `CONTEXT_SWITCH_DENIED` with attempted dimension and the failing reason; the user interface shows the inline error. This event is distinct from `CROSS_CONTEXT_DENIED`, which is the request-time URL / payload mismatch event.

---

## 5. Front-End Expected State

### 5.1 Navigation and information architecture

| Route | Purpose | Guards |
|---|---|---|
| `/settings/context` | Read own active context and switch between options | authenticated |
| `/admin/context-config` | Per-module context configuration registry (read for tenant administrators; edit for platform identities) | authenticated, `RoleGuard` admin tier or `RoleGuard platform_admin/super_admin` |
| `/admin/context-config/audit` | Read-only configuration-registry audit-trail viewer | authenticated, `RoleGuard` admin tier or `auditor` |
| `/admin/governance/scope-decisions` | Approval-scope-decision report (read for tenant administrators / auditors) | authenticated, `RoleGuard` admin tier or `auditor` |

The active-context selector is **not** a route; it is a header-bar component visible on every authenticated page.

### 5.2 Screens

#### `/settings/context` — own active context

- Purpose: view and change the caller's active study, site, product, supplier; show effective scopes; surface delegations affecting scope.
- Fields: read-only summary plus selectors for each dimension the caller has options in.
- Loading / Error / Success / Empty / Permission-restricted: standard.
- Audit visibility: writes a `CONTEXT_SWITCHED` row on every change.

#### Active-context selector (header bar — global)

- Purpose: change active context with one click from anywhere.
- Display: pill-shaped indicators per dimension currently active; clicking opens a popover with selectable options; "Reset to tenant only" clears all dimensions back to tenant-only context.
- States: rendered always when authenticated; dim if no options exist on a dimension.
- Audit: writes `CONTEXT_SWITCHED` per change.

#### `<ContextGate>` — page wrapper (component, not a route)

- Purpose: prevent a page from rendering until the required context is resolved.
- Behaviour: declares the dimensions the page requires (e.g., study; or study and site); checks the session's active context; if any required dimension is missing, renders the active-context selector restricted to the missing dimensions; once resolved, renders the wrapped page; on resolver outage renders the outage banner.

#### `/admin/context-config` — per-module context configuration registry

- Purpose: read (tenant admin / auditor) and edit (platform identity) the per-module context configuration.
- Columns: module key, table name, tenant column, study column, site column, product column, supplier column, registry version, last updated by, last updated at.
- Conditional display: tenant administrators see read-only; platform identities see edit-enabled rows; the "Save" button routes through the Controlled Approval Modal.
- States: standard plus stale-version banner if the registry version advanced since the editor opened.

#### `/admin/context-config/audit`

- Read-only configuration-registry audit-trail viewer; integrity badge per chain segment.

#### `/admin/governance/scope-decisions`

- Filters: range, user, module, decision (passed / failed / super-authority used / cross-context denied).
- Columns: timestamp, actor, target record id, module, decision, scope snapshot, electronic-signature identifier where linked.
- Actions: "Export" routes through the Controlled Approval Modal.

### 5.3 Forms and field rules

| Field identifier | Label | Type | Required | Validation | Source | Editability by status | Audit | Regulatory relevance |
|---|---|---|---|---|---|---|---|---|
| `context.tenantId` | Tenant identifier | string | Yes | `.uuid()`; bound to authenticated session | session | always | yes | EU GMP Annex 11 §12 |
| `context.studyId` | Study identifier | string | conditional per page | `.uuid()`; must be in tenant; user must be in scope | user input | context selector / page | yes (`CONTEXT_SELECTED`) | EU GMP Annex 11 §12 |
| `context.siteId` | Site identifier | string | conditional | as above | user input | as above | yes | EU GMP Annex 11 §12 |
| `context.productId` | Product identifier | string | conditional | as above | user input | as above | yes | EU GMP Annex 11 §12 |
| `context.supplierId` | Supplier identifier | string | conditional | as above | user input | as above | yes | EU GMP Annex 11 §12 |
| `contextSwitch.reason` | Reason | string | No (informational) | `.max(2000)` if present | user input | switch | yes | EU GMP Annex 11 §12 |
| `configEntry.module` | Module key | enum | Yes (registry edit) | URS-02 resource taxonomy | catalogue | edit | yes (`CONTEXT_CONFIG_UPDATED`) | 21 CFR Part 11 §11.10(d) |
| `configEntry.tableName` | Database table name | string | Yes | `.regex(/^[a-z][a-z0-9_]*$/)` | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.tenantColumn` | Tenant column | string | Yes | column must exist | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.studyColumn` | Study column | string | conditional | column must exist if provided | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.siteColumn` | Site column | string | conditional | column must exist if provided | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.productColumn` | Product column | string | conditional | as above | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.supplierColumn` | Supplier column | string | conditional | as above | user input | edit | yes | 21 CFR Part 11 §11.10(d) |
| `configEntry.reason` | Reason | string | Yes | `.min(8).max(2000)` | user input | edit | yes | 21 CFR Part 11 §11.10(e) |
| `scopeReport.range` | Range | datetime range | Yes | start ≤ end | user input | export | yes (`SCOPE_REPORT_EXPORTED`) | EU GMP Annex 11 §9 |
| `scopeReport.format` | Format | enum | Yes | `csv | pdf | jsonl` | user input | export | yes | 21 CFR Part 11 §11.10(e) |
| `scopeReport.reason` | Reason | string | Yes | `.min(8).max(2000)` | user input | export | yes | 21 CFR Part 11 §11.10(e) |

### 5.4 UI state machines

#### Active-context lifecycle

```mermaid
stateDiagram-v2
  [*] --> tenantOnly: bootstrap (no active study/site/product/supplier)
  tenantOnly --> resolved: user picks at ContextGate / selector
  resolved --> resolved: user switches dimension
  resolved --> tenantOnly: user resets to tenant only
  resolved --> failed: resolver outage
  failed --> resolved: resolver recovers; bootstrap re-resolves
  resolved --> [*]: logout
  tenantOnly --> [*]: logout
```

#### Context configuration registry row lifecycle

```mermaid
stateDiagram-v2
  [*] --> seeded: initial registry seed at platform release
  seeded --> updated: CONTEXT_CONFIG_UPDATED (electronic signature)
  updated --> updated: CONTEXT_CONFIG_UPDATED
  updated --> retired: CONTEXT_CONFIG_RETIRED (electronic signature; retain history)
  retired --> [*]
```

### 5.5 UX safety controls

- Confirmation modal on context switch when the new context will navigate away from a page with unsaved changes.
- Clear "Active context" indicator on every regulated record list and detail view (so the user knows the boundary of what they see).
- Approve buttons disabled with tooltip when the front end can pre-detect an out-of-scope record (using the cached scope snapshot from bootstrap); back end remains the authoritative gate.
- Outage banner pinned to the top of the page when the resolver is down; non-dismissible until recovery.
- Stale-registry-version banner with diff preservation when a concurrent administrator edits the configuration.
- Bulk-approve summary lists out-of-scope rows separately so the user can triage without losing the in-scope confirmations.
- Self-context-modification block: the user cannot edit a configuration entry that grants themselves new context coverage; rejected with `SELF_CONTEXT_MODIFICATION_FORBIDDEN`.

---

## 6. Back-End Expected State

### 6.1 Domain entities

- `module_context_config` — per-module context configuration registry rows.
- `module_context_config_history` — versioned history of registry mutations.
- `user_sessions` (consumed; primary owner URS-01) — extended with `study_id`, `site_id`, `product_id`, `supplier_id`.
- `approval_scope_snapshots` — per-decision scope snapshots written into URS-06.
- `cross_context_denials` — forensic event rows written into URS-06.
- `audit_log` (consumed; primary owner URS-06) — Module 3 governance event subset.

### 6.1.1 Diagram 6.1-A — Module 3 data model (entity-relationship overview)

```mermaid
erDiagram
  TENANTS ||--o{ MODULE_CONTEXT_CONFIG : owns
  MODULE_CONTEXT_CONFIG ||--o{ MODULE_CONTEXT_CONFIG_HISTORY : versions
  USERS ||--o{ USER_SESSIONS : owns
  USER_SESSIONS ||--o{ APPROVAL_SCOPE_SNAPSHOTS : recorded_at
  USERS ||--o{ APPROVAL_SCOPE_SNAPSHOTS : actor
  USERS ||--o{ CROSS_CONTEXT_DENIALS : actor
  USERS ||--o{ AUDIT_LOG : actor

  MODULE_CONTEXT_CONFIG {
    uuid id PK
    string module_key
    string table_name
    string tenant_column
    string study_column
    string site_column
    string product_column
    string supplier_column
    int registry_version
    uuid updated_by FK
    timestamptz updated_at
  }
  USER_SESSIONS {
    uuid id PK
    uuid user_id FK
    uuid tenant_id FK
    uuid study_id "nullable"
    uuid site_id "nullable"
    uuid product_id "nullable"
    uuid supplier_id "nullable"
    timestamptz last_active_at
  }
  APPROVAL_SCOPE_SNAPSHOTS {
    uuid id PK
    uuid actor_user_id FK
    uuid tenant_id FK
    uuid e_sig_id FK "nullable for failed/pre-signature denials; mandatory for passed regulated decisions, tenant-wide bypasses, and super-authority bypasses where the action proceeds to signature"
    string module_key
    uuid target_record_id
    jsonb actor_authority_scopes
    jsonb target_record_scope
    bool tenant_wide
    bool super_authority_used
    string decision
    timestamptz created_at
  }
  CROSS_CONTEXT_DENIALS {
    uuid id PK
    uuid actor_user_id FK
    uuid tenant_id FK
    string source_ip
    string user_agent
    string attempted_context
    string session_context
    timestamptz created_at
  }
```

### 6.2 Data model requirements

| Entity | Purpose | Key fields | Required | Unique | Tenant isolation | Versioning | Retention | Soft-delete | Audit | E-sig link |
|---|---|---|---|---|---|---|---|---|---|---|
| `module_context_config` | Per-module context configuration | `id`, `module_key`, `table_name`, `tenant_column`, `study_column`, `site_column`, `product_column`, `supplier_column`, `entity_type_default`, `workflow_type_default`, `entity_type_derivation_strategy`, `workflow_type_derivation_strategy`, `registry_version`, `updated_by`, `updated_at` | `id`, `module_key`, `table_name`, `tenant_column`, `registry_version` | unique(`module_key`, `table_name`) | global / platform-context (no tenant column; cross-tenant registry); explicit platform-only access policy | versioned | retain all versions through history | not applicable | yes | yes |
| `module_context_config_history` | Versioned history | `id`, `module_context_config_id`, `registry_version`, `before_state`, `after_state`, `actor_user_id`, `e_sig_id`, `created_at` | all | unique(`module_context_config_id`, `registry_version`) | platform-context | append-only | retain | not applicable | self | yes |
| `user_sessions` (extension) | Active context columns | `study_id`, `site_id`, `product_id`, `supplier_id` (all nullable) added by Module 3 migration | as URS-01 | as URS-01 | RLS on `tenant_id` | none | as URS-01 | as URS-01 | yes (per session lifecycle) | n/a |
| `approval_scope_snapshots` | Per-decision scope snapshot | `id`, `actor_user_id`, `tenant_id`, `e_sig_id` (nullable; see below), `module_key`, `target_record_id`, `actor_authority_scopes jsonb`, `target_record_scope jsonb`, `tenant_wide`, `super_authority_used`, `decision`, `created_at` | all except `e_sig_id` | none | RLS on `tenant_id` | none | append-only | seven years | not applicable | self | yes (when populated) |
| | **`e_sig_id` nullability rule:** `NULL` for `decision = 'failed'` and for any pre-signature denial path (the regulated action did not reach signature because the scope check rejected it). **Mandatory non-null** for `decision = 'passed'`, for `tenant_wide = true` bypasses, and for `super_authority_used = true` bypasses, in every case where the regulated action proceeds to signature. A database CHECK enforces the rule: `(decision = 'failed' AND e_sig_id IS NULL) OR (decision = 'passed' AND e_sig_id IS NOT NULL)`. | | | | | | | | |
| `cross_context_denials` | Forensic denial rows | `id`, `actor_user_id`, `tenant_id`, `source_ip`, `user_agent`, `attempted_context`, `session_context`, `created_at` | all | none | RLS on `tenant_id` | none | append-only | seven years | not applicable | self | not applicable |
| `audit_log` (Module 3 subset) | Governance events | inherited per URS-06 | as URS-06 | as URS-06 | as URS-06 | append-only | seven years | append-only | self | yes where applicable |

### 6.3 API requirements

#### 6.3.1 Active context

| Method | Endpoint | Actor | Request | Response | Permission | Audit | Error codes |
|---|---|---|---|---|---|---|---|
| GET | `/access/me/context` | authenticated | none | `{tenantId, studyId?, siteId?, productId?, supplierId?, effectiveScopes, tenantWide?, contextResolverStatus}` | self | none | `CONTEXT_RESOLUTION_FAILED` (503) |
| POST | `/access/me/context` | authenticated | `{studyId?, siteId?, productId?, supplierId?, reset?}` | `200 ResolvedContext` | self | `CONTEXT_SELECTED` / `CONTEXT_SWITCHED` | `CONTEXT_TENANT_MISMATCH`, `CONTEXT_OUT_OF_SCOPE`, `CONTEXT_NOT_FOUND` |

#### 6.3.2 Per-module configuration registry

| Method | Endpoint | Actor | Request | Response | Permission | Audit | Error codes |
|---|---|---|---|---|---|---|---|
| GET | `/admin/context-config` | administrator / auditor | none | `ModuleContextConfigEntry[]` | `tenant_admin_authority` (read) / platform admin (read+edit) | none | none |
| POST | `/admin/context-config` | platform-administrator | `ModuleContextConfigEntry` (electronic-signed) | `201 ModuleContextConfigEntry` | platform admin | `CONTEXT_CONFIG_CREATED` | `CONTEXT_CONFIG_DUPLICATE`, `CONTEXT_CONFIG_COLUMN_UNKNOWN`, `CONTEXT_CONFIG_MODULE_UNKNOWN` |
| PATCH | `/admin/context-config/:id` | platform-administrator | `ModuleContextConfigEntry` (electronic-signed) | `200` | platform admin | `CONTEXT_CONFIG_UPDATED` | `CONTEXT_CONFIG_COLUMN_UNKNOWN`, `IMMUTABLE_FIELD_REJECTED`, `STALE_VERSION` |
| POST | `/admin/context-config/:id/retire` | platform-administrator | `{reason}` (electronic-signed) | `204` | platform admin | `CONTEXT_CONFIG_RETIRED` | `CONTEXT_CONFIG_NOT_FOUND` |
| GET | `/admin/context-config/audit` | administrator / auditor | filters | hash-chain rows + integrity manifest | `tenant_admin_authority` / `auditor` | none | none |

#### 6.3.3 Approval-scope decisions

| Method | Endpoint | Actor | Request | Response | Permission | Audit |
|---|---|---|---|---|---|---|
| POST | `/access/scope-check` | **server-side hook only — not exposed to clients** | `{moduleKey, targetRecordId, requiredDimensions[]}` | `{allowed, dimensionVerdicts[]}` | self | `APPROVAL_SCOPE_CHECK_PASSED` / `APPROVAL_SCOPE_CHECK_FAILED` / `RECORD_SCOPE_UNRESOLVED` |

The `/access/scope-check` endpoint is internal — it is invoked only by other server-side handlers as part of regulated-decision processing. It MUST NOT be reachable from any client-side path; the route is gated by the request-source check that rejects external callers with HTTP 404 (so the endpoint is not even surfaced as a probing target). This prevents the endpoint from becoming a scope-enumeration probe.
| GET | `/admin/governance/scope-decisions` | administrator / auditor | filters + range | `ApprovalScopeDecision[]` | `tenant_admin_authority` / `auditor` | none |
| POST | `/admin/governance/scope-decisions/export` | administrator | `{range, filters, format}` (electronic-signed) | signed download URL with TTL fifteen minutes | `tenant_admin_authority` | `SCOPE_REPORT_EXPORTED` |

#### 6.3.4 Forensic cross-context denials

| Method | Endpoint | Actor | Request | Response | Permission | Audit |
|---|---|---|---|---|---|---|
| GET | `/admin/governance/cross-context-denials` | administrator / auditor | filters + range | `CrossContextDenial[]` | `tenant_admin_authority` / `auditor` | none |

### 6.4 Workflow engine requirements

| Workflow | Step | Time-to-live or timer | Auto-action | Reminder |
|---|---|---|---|---|
| Context-resolution failure | resolver down | continuous until recovery | persistent banner; SOC alert; every approve disabled | continuous SOC alert |
| Cross-context denial cluster | per user per minute | thresholds: 10 events / user / minute or 100 events / tenant / minute | SOC alert | as URS-02 §12.9 |
| Configuration registry stale version | concurrent edits | immediate | second editor receives `STALE_VERSION` | none |
| Approval-scope snapshot retention | append-only | seven years | move to cold storage after two years per URS-35 | none |
| Periodic access review covering context | per URS-01 §12.10 | quarterly (GxP-critical) / semi-annually | reviewer enumerates context-config changes; signed attestation | T-30 days |
| Periodic audit-trail review covering Module 3 | per URS-01 §12.11 | high-risk events: 1 business day; routine: monthly | reviewer-attached triage decision | as URS-01 §12.11 |

#### 6.4.1 Record Scope Resolver — derivation of all seven dimensions

The approval-scope check intersects the actor's Authority Profile scopes with the **target record's scope**, on every dimension the Authority Profile requires. The seven dimensions are: `site_id`, `product_id`, `study_id`, `supplier_id`, `module_key`, `entity_type`, `workflow_type`. The configuration registry in §6.2 names the master-data columns (`tenant_id`, `study_id`, `site_id`, `product_id`, `supplier_id`); the remaining three dimensions are derived as follows.

| Dimension | Derivation source |
|---|---|
| `tenant_id` | The session's resolved tenant; cross-checked against the target record's `tenant_id` column declared in `module_context_config`. |
| `study_id` | The target record's `study_id` column, where declared by the module's configuration entry; otherwise null and excluded from intersection. |
| `site_id` | As above for `site_id`. |
| `product_id` | As above for `product_id`. |
| `supplier_id` | As above for `supplier_id`. |
| `module_key` | The `module_key` of the configuration entry that owns the target record's table. The resolver looks up the entry by table name and reads `module_key`. |
| `entity_type` | The regulated entity type for the target record. Derivation order: (a) explicit `entity_type` column on the target record where present; (b) per-table mapping in `module_context_config.entity_type` (extension column added by Module 3 migration); (c) module-level default for tables without per-row `entity_type`. The mapping is part of the controlled configuration and edits follow the same Class 1 / Class 3 rules as the rest of `module_context_config`. |
| `workflow_type` | The `workflow_type` of the active workflow template instance executing the regulated state transition (URS-04). The resolver reads this from the workflow runtime envelope. For decisions outside an explicit workflow template (rare; documented per use case), the default is the module-level workflow type declared on the configuration entry. |

If any **required** dimension cannot be resolved, the resolver MUST return `500 RECORD_SCOPE_UNRESOLVED`, MUST emit `RECORD_SCOPE_UNRESOLVED` to the audit subset, and MUST block the regulated decision. "Required" means the dimension is named in the Authority Profile's scope rules for the action being attempted. Optional dimensions that resolve to null are excluded from the intersection (they neither pass nor fail the check on their own).

The resolver runs in a single deterministic pass; no fallback heuristics are permitted. Adding a new derivation source for any dimension is a Class 1 change.

### 6.5 Business rules

- **BR-03-01** — Every regulated read or write that targets a regulated table MUST pass through the context filter; bare database access bypassing the filter is forbidden outside the documented platform-context exemption list.
- **BR-03-02** — The context filter MUST query the per-module configuration at request time and apply `WHERE` clauses for every applicable column on the active context.
- **BR-03-03** — A request whose URL parameters or payload reference a context that does not match the session's active context MUST be denied with `403 CROSS_CONTEXT_DENIED` and audited.
- **BR-03-04** — The approval-scope check MUST execute at the moment of every regulated decision; the check MUST compute the union of the actor's Authority Profile scopes (assignment-derived plus active-delegation-derived) and intersect with the target record's scope on every dimension the Authority Profile requires; non-empty intersection is the pass condition.
- **BR-03-05** — `tenant_wide` Authority Profile assignments MUST bypass dimension-by-dimension intersection but MUST still write a scope snapshot tagged `tenant_wide = true`.
- **BR-03-06** — Use of `global_quality_oversight` MUST bypass intersection, emit `GLOBAL_SUPER_AUTHORITY_USED`, write a scope snapshot tagged `super_authority_used = true`, fire a SOC alert, and require an extended electronic-signature meaning text.
- **BR-03-07** — The default context at login is `tenant_id` only; no default study, site, product, or supplier is auto-resolved.
- **BR-03-08** — The active context MUST be persisted on the session row; the bootstrap response MUST return the persisted context.
- **BR-03-09** — A context switch MUST validate the new identifier is within the user's tenant and within at least one of the user's Authority Profile scopes or membership-scoped permissions.
- **BR-03-10** — The Continuous Integration gate MUST fail any pull request whose `MODULE_CONTEXT_CONFIG` entry references a column that does not exist in the corresponding migration's `CREATE TABLE`.
- **BR-03-11** — Every approval-scope decision (pass, fail, tenant-wide bypass, super-authority bypass) MUST write a `scope_snapshot` row capturing actor authority scopes, target record scope, decision, and `e_sig_id` link where applicable.
- **BR-03-12** — Self-modification block: a user MUST NOT edit a configuration registry entry that grants themselves new context coverage; rejected with `SELF_CONTEXT_MODIFICATION_FORBIDDEN`.
- **BR-03-13** — Audit-write failure rolls back the originating action (consistent with URS-01 BR-01-17).
- **BR-03-14** — Every regulated administrative action in this module is electronically signed via the URS-04 Controlled Approval Modal; metadata is server-derived.
- **BR-03-15** — Cross-context denial events MUST be rate-limited per actor per minute to suppress brute-force enumeration; cluster threshold triggers SOC alert.
- **BR-03-16** — Configuration registry mutations are atomic with the registry-version increment in the same database transaction.

### 6.6 Audit trail requirements

The Module 3 governance event vocabulary listed below is the canonical launch list; every code MUST have at least one writer and one regression test. Adding a code is a Class 3 change per §7.2.

`CONTEXT_SELECTED`, `CONTEXT_SWITCHED` (carries `source ∈ {selector, deeplink}`), `CONTEXT_RESET` (user explicitly clears active context back to tenant-only via the selector "Reset" action), `CONTEXT_SWITCH_DENIED` (forensic; written when a context-switch attempt fails server validation — `CONTEXT_TENANT_MISMATCH`, `CONTEXT_OUT_OF_SCOPE`, or `CONTEXT_NOT_FOUND` — captures actor, attempted dimension, and the failing reason; distinct from `CROSS_CONTEXT_DENIED`, which is a request-time URL/payload mismatch), `CONTEXT_RESOLUTION_FAILED`, `CROSS_CONTEXT_DENIED`, `APPROVAL_SCOPE_CHECK_PASSED`, `APPROVAL_SCOPE_CHECK_FAILED`, `RECORD_SCOPE_UNRESOLVED`, `TENANT_WIDE_SCOPE_BYPASS_USED`, `GLOBAL_SUPER_AUTHORITY_USED`, `CONTEXT_CONFIG_CREATED`, `CONTEXT_CONFIG_UPDATED`, `CONTEXT_CONFIG_RETIRED`, `CONTEXT_CONFIG_COVERAGE_VIOLATION` (CI / startup gate failure forensic), `SELF_CONTEXT_MODIFICATION_FORBIDDEN`, `SCOPE_REPORT_EXPORTED`, `PLATFORM_TENANT_ACCESS_USED` (consumed from URS-02 when platform-identity acts on behalf of tenant), `PLATFORM_TENANT_ACCESS_DENIED`.

Every audit row carries actor, role, server-clock timestamp, action, resource type, resource identifier, before / after state where applicable, reason where applicable, source IP, user agent, session identifier, correlation identifier, electronic-signature identifier where linked, and the hash-chain fields owned by URS-06. Audit-log write failure rolls back the originating action per BR-03-13.

### 6.7 Electronic signature requirements

Every regulated administrative action in this module is electronically signed via the URS-04 Controlled Approval Modal. Module-specific signature meaning examples:

| Action | Signature meaning |
|---|---|
| Edit context configuration entry | "I update the context configuration for module [key], table [name], for tenant set [global]" |
| Retire context configuration entry | "I retire the context configuration for module [key], table [name] for reason [R]" |
| Use `global_quality_oversight` super-authority | "I exercise global quality oversight for record [id] in module [key], because [extended reason]" |
| Export approval-scope-decision report | "I export the approval-scope-decision report [range / filters] for purpose [P]" |

Signature row carries server-derived `ip`, `user_agent`, `signed_at`, `signed_by`. Signature is linked to the action row through the electronic-signature identifier; subsequent change to the signed entity invalidates the signature (URS-04 emits `SIGNATURE_INVALIDATED`).

### 6.8 Record versioning and class-of-change governance

- Versioned: `module_context_config` is counter-versioned per row; full history retained in `module_context_config_history`.
- Append-only: `approval_scope_snapshots`, `cross_context_denials`, audit-log Module 3 subset.
- Soft-delete: not applicable to the configuration registry; retirement is an explicit transition that preserves history.

---

## 7. Cross-Module Wiring and Change-Impact

### 7.1 Cross-module wiring

#### Diagram 7-A — Module 3 substrate consumed by other modules

```mermaid
graph LR
  subgraph M3 [Module 3 — Context Gate & Approval Scope]
    CR[Context Resolver]
    CF[applyContextFilters]
    ASC[Approval Scope Check]
    REG[MODULE_CONTEXT_CONFIG]
    SS[Scope Snapshots]
  end

  M1[URS-01 Auth] --> CR
  M2[URS-02 RBAC] --> CR
  M5[URS-05 Authority] --> ASC
  CR --> M4[URS-04 Workflow / E-Sign]
  CF --> M7[URS-07 Studies]
  CF --> M9[URS-09 Sites]
  CF --> M10[URS-10 Products]
  CF --> M11[URS-11 Suppliers]
  ASC --> M12[URS-12 Documents]
  ASC --> M14[URS-14 Complaints]
  ASC --> M16[URS-16 Deviations]
  ASC --> M18[URS-18 CAPA]
  ASC --> M22[URS-22 Inspections]
  ASC --> M23[URS-23 Batch Records]
  ASC --> M27[URS-27 Reg Submissions]
  SS --> M6[URS-06 Audit Trail]
  REG --> M35[URS-35 Backup / Restore]
```

| Source / target | Direction | Trigger | Data sent / received | Failure handling | Audit |
|---|---|---|---|---|---|
| URS-01 → URS-03 | upstream | bootstrap | tenant identifier, session identifier | URS-01 fails closed if token invalid | none here |
| URS-02 → URS-03 | upstream | bootstrap and per-request | base role and effective permissions | URS-02 fails closed | none here |
| URS-03 → URS-04 | downstream | regulated decision | scope snapshot and `e_sig_id` link | URS-04 fails closed | scope snapshot emitted |
| URS-03 → URS-05 | peer | approval-scope check | actor Authority Profile scopes | URS-05 fails closed | scope snapshot |
| URS-03 → URS-06 | downstream | every Module 3 governance event | hash-chained event row | rollback on audit failure | event |
| URS-03 → URS-07/09/10/11 | upstream | context-selection validation | master-data presence + scope membership | reject if not present | event |
| URS-03 → URS-08 | upstream | tenant active gate | `tenants.status = 'active'` | reject if inactive | event |
| URS-03 → URS-30 | downstream | resolver outage; cross-context cluster | event payload | retry per URS-30 | event |
| URS-03 → URS-35 | peer | configuration registry restore | preserve registry-version history and audit chain | DR drill verifies | event |

### 7.2 Change-Impact Matrix

| # | Module 3 artefact | Class | Affected modules | Specific impact | Required action | Re-validation |
|---|---|---|---|---|---|---|
| CIM-01 | Scope dimensions (the seven plus tenant_wide and super-authority flag) | 1 | URS-05 owns the canonical dimension list; every regulated module that gates by Authority Profile | Adding or removing a dimension breaks every consumer | Coordinate with URS-05; full schema migration; full regression | IQ + OQ + PQ on every consumer |
| CIM-02 | Per-module context configuration shape | 1 | every regulated module | Schema change forces consumer migration | Schema migration with idempotency; align consumers | IQ + OQ + PQ |
| CIM-03 | `applyContextFilters` algorithm | 2 | every regulated read / write path | Behaviour change without contract change | Document; differential test report | OQ + PQ |
| CIM-04 | Approval-scope check algorithm | 2 | every regulated decision path | Decisions today as PASS may become FAIL or vice versa | Document; differential test against frozen historical decision log; QA + RA + Information Security approval | OQ + PQ + Penetration |
| CIM-05 | Active-context selector contract | 1 | every front-end module | Front-end gates fail closed | Update shared types; align front ends | OQ + PQ |
| CIM-06 | Default-context policy (DEC-03-02) | 2 | every regulated module | Auto-selection of a study / site changes user behaviour | Document; UX preview | OQ + PQ |
| CIM-07 | Cross-context-denial rate-limit thresholds | 4 | URS-30 alerts | Operational posture only | Update tenant policy | none |
| CIM-08 | Module 3 audit event vocabulary | 3 (add) / 1 (rename) | URS-06, URS-30, URS-22, URS-35 | Audit replay incomplete | Update writers; align consumers | OQ + PQ |
| CIM-09 | Configuration registry table-shape | 1 | platform-identity admin UI | Admin UI breaks | Update admin UI; align consumers | OQ + PQ |
| CIM-10 | Tenant-wide bypass policy | 2 | every regulated decision path | Tightening or loosening bypass changes posture | Document; executive authority e-signature | OQ + PQ |
| CIM-11 | Super-authority `global_quality_oversight` bypass policy | 2 | as above | as above | executive authority e-signature | OQ + PQ |
| CIM-12 | URL-driven context override (DEC-03-08) | 2 | every regulated module with deep links | Disabling deep-link override breaks bookmarks | UX deprecation window; align documentation | OQ |
| CIM-13 | Scope-snapshot schema | 1 | URS-06, URS-22 | Audit replay format change | Schema migration; align consumers | IQ + OQ |
| CIM-14 | Configuration-coverage CI gate | 2 | every PR that touches a regulated module | Tightening blocks more PRs | Update CI configuration | none beyond CI |
| CIM-15 | `<ContextGate>` component contract | 1 | every front-end module | Component-prop change breaks every consumer | Update shared component; align consumers | OQ |

### 7.3 Change classification and re-validation triggers

| Class | Definition | Examples | Required gates | Default re-validation |
|---|---|---|---|---|
| 1 — Substrate-breaking | Schema, contract, or semantic change that can break consumers | CIM-01, 02, 05, 09, 13, 15 | URS-13 approval by QA, RA, Security, Platform; executive authority e-signature when scope semantics are touched | Full IQ + OQ + PQ |
| 2 — Semantic-shift | Behaviour change without contract change | CIM-03, 04, 06, 10, 11, 12, 14 | URS-13 approval by QA, RA, Security; differential test report archived | OQ + PQ |
| 3 — Additive | Pure addition not changing existing consumer contracts | CIM-08 (add) | URS-13 approval by QA + RA | OQ |
| 4 — Configuration | Tenant-level value change | CIM-07 | Tenant-administrator electronic signature | none |

---

## 8. AI / Automation / Human-in-the-Loop Controls

Module 3 contains no AI. The active-context resolver is deterministic; the approval-scope check is a deterministic set-intersection on master-data identifiers; the configuration registry is rule-based. No large-language model is invoked anywhere on the context or scope path.

EU AI Act (Regulation (EU) 2024/1689) Article 3(1) applicability: not applicable to this module; documented exclusion appears in §14.

The MIRA AI agent (URS-32) does not advise on context selection or approval-scope decisions. The MIRA prompt envelope echoes the active context for downstream regulated-task gating only; it never alters context state.

The human-in-the-loop pattern in this module covers every administrative action (configuration registry edit / retire, approval-scope-decision report export, super-authority bypass). Every such action routes through the Controlled Approval Modal and electronic signature.

---

## 9. Reports, Dashboards, and Exports

| Report | Filters | Columns | Access | Format | Audit | Retention |
|---|---|---|---|---|---|---|
| Approval-scope-decision report | range, tenant, user, module, decision | full row + scope snapshot | administrator / auditor | CSV / PDF / JSONL | yes (export) | seven years |
| Cross-context-denial register | range, tenant, user, source IP | full row | administrator / auditor / Information Security | CSV | yes (export) | seven years |
| Configuration registry version history | range, module, table | actor, before / after, registry version | administrator / auditor | CSV | yes | retain history |
| Configuration coverage report | tenant (none — registry is global) | per-module declared columns vs migration-set columns | administrator / auditor | CSV | yes | release-current |
| Context-resolution-outage register | range | timestamps, durations, correlation identifiers | administrator / Information Security | CSV | yes | one year |
| Tenant-wide bypass register | range, tenant, user | full row including reason | administrator / auditor | CSV | yes | seven years |
| Super-authority bypass register | range, tenant, user | full row including reason and SOC ticket | administrator / auditor | CSV | yes | twenty-five years |

Every export routes through the Controlled Approval Modal. Signed download URLs with fifteen-minute time-to-live. Integrity manifest accompanies every export.

---

## 10. Notifications and Queues

| Trigger | Channel | Recipient | Priority | Retry | Suppression | Audit |
|---|---|---|---|---|---|---|
| Resolver outage | SOC chat | SOC | critical | continuous | one per minute per tenant | yes |
| Cross-context-denial cluster | SOC chat | SOC | high | three | one per five minutes per user / tenant | yes |
| `GLOBAL_SUPER_AUTHORITY_USED` | SOC chat + e-mail | SOC + QA Head + executive authority escalation | critical | five | none | yes |
| Configuration registry edit (digest) | e-mail | tenant administrator queue + platform administrator queue | normal | three | hourly digest | yes |
| Configuration retired | e-mail | tenant administrator queue | normal | three | one per hour per tenant | yes |
| Periodic access review window opens | e-mail | tenant administrator queue | normal | three | one per day per tenant | yes |
| Approval-scope-decision report export | e-mail | exporter | normal | three | none | yes |

Queues:

- **Configuration registry pending review (platform administrator).**
- **Cross-context-denial triage queue (SOC).**
- **Super-authority bypass review queue (QA Head and Founder).**
- **Periodic access-review window (administrator).**

---

## 11. Error Handling and Negative Paths

### 11.1 Error envelope

All error responses follow the envelope: human message, machine-readable code in upper-snake-case, optional structured details, correlation identifier.

### 11.2 Error-code catalogue

| Code | HTTP | Path | UI behaviour |
|---|---|---|---|
| CONTEXT_RESOLUTION_FAILED | 503 | bootstrap / per-request | persistent banner; AuthorityGuard buttons disabled; SOC alert |
| CONTEXT_REQUIRED | 412 | regulated page | render `<ContextGate>` selector |
| CROSS_CONTEXT_DENIED | 403 | any request with mismatching context | toast; rate-limit; SOC alert on cluster |
| CONTEXT_TENANT_MISMATCH | 403 | context-switch validation | inline error |
| CONTEXT_OUT_OF_SCOPE | 403 | context-switch validation | inline error naming the dimension |
| CONTEXT_NOT_FOUND | 404 | context-switch | inline error |
| APPROVAL_SCOPE_DENIED | 403 | regulated decision endpoint | inline error in modal naming the failing dimension |
| CONTEXT_CONFIG_DUPLICATE | 409 | registry POST | inline error |
| CONTEXT_CONFIG_COLUMN_UNKNOWN | 400 | registry POST / PATCH | inline error citing the missing column |
| CONTEXT_CONFIG_MODULE_UNKNOWN | 400 | registry POST | inline error |
| IMMUTABLE_FIELD_REJECTED | 400 | registry PATCH attempting to mutate `module_key` or `table_name` | inline error |
| STALE_VERSION | 409 | registry PATCH with stale version | banner offers refresh + diff preservation |
| SELF_CONTEXT_MODIFICATION_FORBIDDEN | 403 | registry edit that would extend own coverage | inline error |
| PLATFORM_IDENTITY_REQUIRED | 403 | registry edit by non-platform identity | inline error |
| PLATFORM_TENANT_ACCESS_DENIED | 403 | platform identity acting outside support / break-glass envelope | inline error; SOC alert |
| AUDIT_TRAIL_WRITE_FAILED | 500 | any state-changing action | toast; the originating action did NOT commit |
| RECORD_SCOPE_UNRESOLVED | 500 | regulated decision endpoint | toast; the regulated decision is blocked; SOC alert per §12.9 |

### 11.3 Negative-path catalogue

| Scenario | Detection | Response | UI behaviour |
|---|---|---|---|
| Resolver outage | resolver timeout | `503 CONTEXT_RESOLUTION_FAILED` | banner; approve buttons disabled; SOC alert |
| Required context missing for a page | `<ContextGate>` | `412 CONTEXT_REQUIRED` (only on direct API call) or rendered selector (UI path) | selector |
| URL deep-link with mismatched context | back-end middleware | `403 CROSS_CONTEXT_DENIED` | toast; rate-limit |
| User selects a study not in tenant | back-end validation | `403 CONTEXT_TENANT_MISMATCH` | inline error |
| User selects a study not in their scope | back-end validation | `403 CONTEXT_OUT_OF_SCOPE` | inline error |
| Approve clicked on out-of-scope record | back-end approval-scope check | `403 APPROVAL_SCOPE_DENIED` | inline error in modal |
| Concurrent registry edits (stale version) | back end | `409 STALE_VERSION` | banner + diff preservation |
| Registry edit references missing column | back-end validation | `400 CONTEXT_CONFIG_COLUMN_UNKNOWN` | inline error |
| Self-extending coverage attempt | back end | `403 SELF_CONTEXT_MODIFICATION_FORBIDDEN` | inline error |
| Tenant administrator attempts registry edit | back end | `403 PLATFORM_IDENTITY_REQUIRED` | inline error |
| Platform identity acts outside support envelope | back end | `403 PLATFORM_TENANT_ACCESS_DENIED` | inline error; SOC alert |
| Audit-log write failure | audit service | `500 AUDIT_TRAIL_WRITE_FAILED` | toast; rollback |

---

## 12. Security, Privacy, and Tenant Isolation

### 12.1 Authentication dependency

URS-03 is reached only through an authenticated session established by URS-01. The context resolver fails closed if the session lacks tenant binding.

### 12.2 Authorisation pipeline

`authenticate hook → tenant hook → rbac hook → context gate hook → workflow hook → authorityCheckHook`. URS-03 owns the context-gate hook position and contributes the approval-scope check at the workflow layer.

### 12.3 Tenant isolation

Every database operation routes through the Tenant Data Access Layer with tenant context bound to the connection. Every Module 3 tenant-scoped table has Row-Level Security enabled in the same migration as creation. The configuration registry is global / platform-context per DEC-03-09 and §6.2; explicit platform-context access policies apply.

### 12.4 Encryption

At rest: configuration registry rows protected by platform access policy plus KMS at the storage layer. In transit: TLS 1.2 or higher with HTTP Strict Transport Security preload.

### 12.5 Logging hygiene

Logs scrub session identifiers and any field tagged sensitive. Structured logs carry the correlation identifier on every request.

### 12.6 Privacy and data residency

Module 3 processes only master-data identifiers (tenant, study, site, product, supplier, user) and does not store free-form personal data beyond what is inherited from URS-01 audit attribution.

### 12.7 Periodic access review

Per URS-01 §12.10, the access-review window enumerates context-configuration changes and approval-scope-decision exceptions in the period; reviewer signs the attestation; URS-30 records the closure event.

### 12.8 Periodic audit-trail review

Per URS-01 §12.11, high-risk Module 3 events triaged within one business day: `CROSS_CONTEXT_DENIED` clusters, `CONTEXT_RESOLUTION_FAILED` clusters, `GLOBAL_SUPER_AUTHORITY_USED`, `CONTEXT_CONFIG_UPDATED` outside business hours.

### 12.9 Security-operations alert thresholds

| Pattern | Threshold | Severity | Channel |
|---|---|---|---|
| `CROSS_CONTEXT_DENIED` cluster (same user) | ten events per user per minute | critical | SOC chat + on-call e-mail |
| `CROSS_CONTEXT_DENIED` cluster (same tenant) | one hundred events per tenant per minute | critical | SOC chat + on-call e-mail |
| `CONTEXT_RESOLUTION_FAILED` cluster | continuous while outage active | critical | SOC chat |
| `GLOBAL_SUPER_AUTHORITY_USED` | any single event | critical | SOC chat + executive authority escalation |
| `TENANT_WIDE_SCOPE_BYPASS_USED` | any single event | informational (digest hourly) | SOC e-mail digest |
| `CONTEXT_CONFIG_UPDATED` outside business hours | any single event | high | SOC chat |
| `PLATFORM_TENANT_ACCESS_USED` for Module 3 actions | any single event | informational (real-time) | SOC chat |

### 12.10 Self-modification block — scope

Per BR-03-12, a user MUST NOT edit a configuration registry entry that grants themselves new context coverage. The block applies regardless of platform identity (a `platform_admin` editing a configuration that would extend their own coverage is rejected). This is the equivalent of the URS-02 self-modification block at the configuration-registry layer.

### 12.11 Secure export

Every export routes through the Controlled Approval Modal. Signed download URLs with fifteen-minute time-to-live. Integrity manifest accompanies every export.

---

## 13. Data Integrity and ALCOA+ Controls

| Principle | Module 3 control | Requirement | Verification |
|---|---|---|---|
| Attributable | Every Module 3 event carries `actor_user_id` and `tenant_id`; configuration changes attributed to platform identity | URS-03-AUD-001 | Integration test |
| Legible | Audit rows store structured JSON metadata | URS-03-REP-001 | Export test |
| Contemporaneous | All timestamps from server clock | URS-03-AUD-002 | Integration test |
| Original | Append-only scope snapshots, append-only cross-context denials, versioned configuration registry | URS-03-AUD-003 | Validation test |
| Accurate | Validation at every boundary; column-existence checks at registry edit and CI gate | URS-03-DATA-001 | Integration test |
| Complete | Every event in the §6.6 vocabulary has at least one writer | URS-03-AUD-004 | Validation test |
| Consistent | Configuration registry counter-versioned; transactional mutation + audit + version | URS-03-AUD-005 | Concurrency test |
| Enduring | Retention (seven years scope snapshots; twenty-five years super-authority bypass register) | URS-03-DATA-002 | Migration test |
| Available | Read paths administrator-accessible; export self-service | URS-03-REP-002 | End-to-end test |

---

## 14. Regulatory Mapping

| Identifier | Control | Regulation / Guidance | Clause | Applicable | Implementation expectation |
|---|---|---|---|---|---|
| RG-03-001 | Limit access to authorised individuals | 21 CFR Part 11 | §11.10(d) | Yes | Context filter + RLS + cross-context denial |
| RG-03-002 | Authority checks for system functions | 21 CFR Part 11 | §11.10(g) | Yes | Approval-scope check at every regulated decision |
| RG-03-003 | Audit trail of operator actions | 21 CFR Part 11 | §11.10(e) | Yes | Hash-chained Module 3 governance events |
| RG-03-004 | Logical access controls | EU GMP Annex 11 | §12, §12.1 | Yes | Layered RLS + context filter + scope check |
| RG-03-005 | Periodic review of computerised systems | EU GMP Annex 11 | §11 | Yes | Per URS-01 §12.10 |
| RG-03-006 | Validation of computerised systems | EU GMP Annex 11 | §4 | Yes | CSV / CSA pack per §17 |
| RG-03-007 | Documentation and record integrity | EU GMP Chapter 4 | applicable | Yes | Versioning + retention |
| RG-03-008 | Risk-based assurance | FDA Computer Software Assurance for Production and Quality Management System Software, Final Guidance, February 2026 | applicable | Yes | Risk classification per validation pack |
| RG-03-009 | ALCOA+ data integrity | MHRA Data Integrity Guidance (2018) | nine principles | Yes | §13 mapping |
| RG-03-010 | Records retention | EU GMP Annex 11 | §17 | Yes | Seven years scope snapshots; twenty-five years super-authority register |
| RG-03-011 | Identity-management standards | ISO/IEC 27001 | A.5.16, A.8.5 | Yes | Context filter + approval-scope check |
| RG-03-012 | EU AI Act applicability | Regulation (EU) 2024/1689 | Article 3(1) | Not applicable to this module | No AI; documented exclusion |
| RG-03-013 | India regulatory framework | Per applicability | Conditional per tenant operation | Conditional | Tenant-onboarding RA disposition under URS-08 controls |
| RG-03-014 | Notifications integrity | Internal | not applicable | Yes | URS-30 substrate |

### 14.1 Predicate-rule applicability matrix

| Record / signature | Predicate-rule basis | Part 11 applicable? | Retention | Owner | Evidence |
|---|---|---|---|---|---|
| Electronic signature on configuration registry edit | GxP access-control configuration evidence (21 CFR Part 11 §11.10(d), §11.10(g); EU GMP Annex 11 §12) | Yes | seven years | QA / Validation | Electronic-signature row + linked audit row + history |
| Approval-scope snapshot per regulated decision | Authority-of-record evidence (21 CFR Part 11 §11.10(e), §11.10(g)) | Yes | seven years | QA / Information Security | Snapshot row + linked electronic signature |
| Configuration registry version history | Configuration baseline evidence | Yes | retain history | QA | Version-history table |
| Cross-context denial row | Forensic security evidence | Conditional — the audit row is predicate evidence for access-control reviews | seven years | Information Security | Denial register |
| Tenant-wide / super-authority bypass row | Break-glass authority of record evidence | Yes | twenty-five years for super-authority; seven years for tenant-wide | QA / Founder | Bypass register + linked electronic signature |
| Active-context selection event | Operational record | Conditional — the audit row IS predicate evidence; the event itself is operational | seven years | QA | Audit export |

The predicate-rule applicability matrix is a controlled artefact; updating it is a Class 1 change per §7.

---

## 15. URS Requirements Register

### 15.1 Front-end (FE)

- URS-03-FE-001 — `<ContextGate>` MUST wrap every regulated page that requires a study, site, product, or supplier context and MUST render the active-context selector when any required dimension is unresolved. Priority MUST. Risk HIGH. Maps RG-03-004.
- URS-03-FE-002 — Active-context selector MUST be visible on every authenticated page and MUST allow switching across each dimension the caller has options in. Priority MUST. Risk MEDIUM. Maps RG-03-004.
- URS-03-FE-003 — The user interface MUST display the current active context (tenant plus dimensions) clearly on every regulated record list and detail view. Priority MUST. Risk MEDIUM. Maps RG-03-004.
- URS-03-FE-004 — Approve buttons MUST be disabled with tooltip when the front end can pre-detect an out-of-scope record from the cached scope snapshot; back end remains the authoritative gate. Priority MUST. Risk MEDIUM. Maps RG-03-002.
- URS-03-FE-005 — Front end MUST NOT include `ip` / `userAgent` / `timestamp` / `performedBy` in any request body. Priority MUST. Risk HIGH. Maps RG-03-003.
- URS-03-FE-006 — Outage banner MUST be pinned (non-dismissible) when the resolver returns `503 CONTEXT_RESOLUTION_FAILED`; banner clears automatically on next successful bootstrap. Priority MUST. Risk HIGH. Maps RG-03-006.
- URS-03-FE-007 — Configuration registry editor MUST visually disable mutation of `module_key` and `table_name` (immutable per §6.3.2). Priority MUST. Risk MEDIUM. Maps RG-03-004.
- URS-03-FE-008 — Stale-registry-version banner MUST appear when the editor's loaded version is behind the server; pending diffs preserved client-side. Priority MUST. Risk MEDIUM. Maps RG-03-004.
- URS-03-FE-009 — Bulk-action result UI MUST group out-of-scope rows separately so the user can triage without losing in-scope confirmations. Priority MUST. Risk MEDIUM. Maps RG-03-002.
- URS-03-FE-010 — Every route in §5.1 MUST be registered in the application router before release. Priority MUST. Risk LOW. Maps RG-03-004.

### 15.2 Back-end (BE)

- URS-03-BE-001 — `applyContextFilters` MUST be applied to every regulated read or write that targets a regulated table; bare database access bypassing the filter is forbidden outside the documented platform-context exemption list. Priority MUST. Risk CRITICAL. Maps RG-03-001.
- URS-03-BE-002 — The context filter MUST query the per-module configuration at request time and apply `WHERE` clauses for every applicable column on the active context. Priority MUST. Risk HIGH. Maps RG-03-001.
- URS-03-BE-003 — Cross-context request denial MUST return `403 CROSS_CONTEXT_DENIED` and MUST be audited. Priority MUST. Risk HIGH. Maps RG-03-001.
- URS-03-BE-004 — Approval-scope check MUST execute at the moment of every regulated decision and MUST compute the union of the actor's Authority Profile scopes (assignment-derived plus active-delegation-derived) intersected with the target record's scope on every required dimension. Priority MUST. Risk CRITICAL. Maps RG-03-002.
- URS-03-BE-005 — `tenant_wide` Authority Profile assignments MUST bypass dimension intersection but MUST still emit a scope snapshot tagged `tenant_wide = true`. Priority MUST. Risk HIGH. Maps RG-03-002.
- URS-03-BE-006 — Use of `global_quality_oversight` MUST bypass intersection, emit `GLOBAL_SUPER_AUTHORITY_USED`, write a snapshot tagged `super_authority_used = true`, fire SOC alert, and require an extended electronic-signature meaning text. Priority MUST. Risk HIGH. Maps RG-03-002.
- URS-03-BE-007 — Default context at login is `tenant_id` only; no default study / site / product / supplier is auto-selected. Priority MUST. Risk LOW. Maps RG-03-001.
- URS-03-BE-008 — Context-switch endpoint MUST validate the new identifier is within the user's tenant and within at least one of the user's Authority Profile scopes or membership-scoped permissions. Priority MUST. Risk MEDIUM. Maps RG-03-001.
- URS-03-BE-009 — The Continuous Integration gate MUST fail any pull request whose `MODULE_CONTEXT_CONFIG` entry references a column that does not exist in the corresponding migration. Priority MUST. Risk HIGH. Maps RG-03-006.
- URS-03-BE-010 — Every approval-scope decision MUST write a `scope_snapshot` row capturing actor authority scopes, target record scope, and decision. The `e_sig_id` link MUST be populated when the regulated action proceeds to signature (passed decisions, tenant-wide bypasses, super-authority bypasses); the `e_sig_id` link MUST be `NULL` for failed scope checks and other pre-signature denial paths where no signature is produced. A database CHECK constraint enforces: `(decision = 'failed' AND e_sig_id IS NULL) OR (decision = 'passed' AND e_sig_id IS NOT NULL)`. Priority MUST. Risk HIGH. Maps RG-03-003.
- URS-03-BE-011 — Self-modification block: a user MUST NOT edit a configuration entry that grants themselves new context coverage; rejected with `SELF_CONTEXT_MODIFICATION_FORBIDDEN`. Priority MUST. Risk HIGH. Maps RG-03-001.
- URS-03-BE-012 — Configuration registry mutations MUST be atomic with the registry-version increment in the same transaction. Priority MUST. Risk HIGH. Maps RG-03-007.
- URS-03-BE-013 — Every tenant-scoped Module 3 table MUST have Row-Level Security enabled in the same migration that creates it. Global / platform-context registries (`module_context_config`, `module_context_config_history`) MUST instead carry explicit platform-context access policies, version history, audit logging, and no tenant-user write path. Priority MUST. Risk HIGH. Maps RG-03-004.
- URS-03-BE-014 — Cross-context denial events MUST be rate-limited per actor per minute; cluster threshold triggers SOC alert. Priority MUST. Risk MEDIUM. Maps RG-03-001.
- URS-03-BE-015 — `module_key` and `table_name` are immutable after the initial registry row is committed; mutation attempts return `IMMUTABLE_FIELD_REJECTED`. Priority MUST. Risk MEDIUM. Maps RG-03-007.
- URS-03-BE-016 — Audit-log write failure MUST roll back the originating action (BR-03-13). Priority MUST. Risk CRITICAL. Maps RG-03-003.

### 15.3 Workflow (WF)

- URS-03-WF-001 — Active-context lifecycle adheres to §5.4. Priority MUST. Risk MEDIUM.
- URS-03-WF-002 — Configuration registry row lifecycle adheres to §5.4. Priority MUST. Risk MEDIUM.
- URS-03-WF-003 — Periodic access review covers context-configuration changes per URS-01 §12.10. Priority MUST. Risk MEDIUM.

### 15.4 Data (DATA)

- URS-03-DATA-001 — Every entity in §6.1 exists with the columns and constraints in §6.2; uniqueness enforced at the database level. Priority MUST. Risk HIGH.
- URS-03-DATA-002 — `module_context_config` retains all versions through history; restore preserves chain integrity. Priority MUST. Risk HIGH.
- URS-03-DATA-003 — Append-only `approval_scope_snapshots` and `cross_context_denials` queryable for audit / export. Priority MUST. Risk HIGH.

### 15.5 Security (SEC)

- URS-03-SEC-001 — All requests route through Tenant Data Access Layer plus the context filter. Priority MUST. Risk CRITICAL.
- URS-03-SEC-002 — Periodic access review per URS-01 §12.10 covers Module 3 governance events. Priority MUST. Risk HIGH.
- URS-03-SEC-003 — Periodic audit-trail review per URS-01 §12.11 covers Module 3 high-risk events. Priority MUST. Risk HIGH.
- URS-03-SEC-004 — SOC alert routing per §12.9. Priority MUST. Risk HIGH.

### 15.6 Audit (AUD)

- URS-03-AUD-001 — Every state-changing action emits an audit event with all required fields per URS-06 §6.6. Priority MUST. Risk HIGH.
- URS-03-AUD-002 — Server-derived metadata is the only source of truth for audit fields. Priority MUST. Risk HIGH.
- URS-03-AUD-003 — Audit-log write failure rolls back the originating action. Priority MUST. Risk CRITICAL.
- URS-03-AUD-004 — All event codes in §6.6 have at least one writer. Priority MUST. Risk MEDIUM.
- URS-03-AUD-005 — Cross-context denial events written into the forensic register and audit log. Priority MUST. Risk HIGH.

### 15.7 Electronic Signature (ESIG)

- URS-03-ESIG-001 — Every regulated administrative action is electronically signed via URS-04. Priority MUST. Risk HIGH.
- URS-03-ESIG-002 — Signature row carries server-derived `ip`, `user_agent`, `signed_at`, `signed_by`. Priority MUST. Risk HIGH.
- URS-03-ESIG-003 — Super-authority bypass requires extended meaning text capturing the rationale. Priority MUST. Risk HIGH.

### 15.8 AI / HITL (AI)

- URS-03-AI-001 — No AI is invoked in any context-resolution or approval-scope decision path. Priority MUST. Risk HIGH.
- URS-03-AI-002 — When the MIRA agent is invoked from other modules, it MUST receive the active context but MUST NOT mutate context state. Priority MUST. Risk MEDIUM.

### 15.9 Integration (INT)

- URS-03-INT-001 — URS-01 supplies authenticated identity and tenant; Module 3 fails closed on missing tenant. Priority MUST. Risk MEDIUM.
- URS-03-INT-002 — URS-02 supplies effective permissions; Module 3 layers context filter on top. Priority MUST. Risk MEDIUM.
- URS-03-INT-003 — URS-04 receives scope snapshot and electronic-signature linkage at every regulated decision. Priority MUST. Risk HIGH.
- URS-03-INT-004 — URS-05 supplies Authority Profile scopes; Module 3 computes the intersection at decision time. Priority MUST. Risk HIGH.
- URS-03-INT-005 — URS-06 ingests every Module 3 event and preserves hash-chain integrity. Priority MUST. Risk HIGH.
- URS-03-INT-006 — URS-07 / URS-09 / URS-10 / URS-11 supply master-data presence checks; selection of an unknown identifier returns `404 CONTEXT_NOT_FOUND`. Priority MUST. Risk MEDIUM.
- URS-03-INT-007 — URS-08 active-tenant gate rejects operations on inactive tenants. Priority MUST. Risk MEDIUM.
- URS-03-INT-008 — URS-30 delivers all notifications listed in §10. Priority MUST. Risk LOW.
- URS-03-INT-009 — URS-35 preserves audit-chain integrity and registry-version history across restore. Priority MUST. Risk HIGH.

### 15.10 Reports / Exports (REP)

- URS-03-REP-001 — All reports in §9 are implemented with documented filters, columns, formats, and access rules. Priority MUST. Risk MEDIUM.
- URS-03-REP-002 — Every export produces a self-verifying integrity manifest and is electronically signed. Priority MUST. Risk HIGH.
- URS-03-REP-003 — Export download URLs are signed and time-to-live limited (fifteen minutes). Priority MUST. Risk MEDIUM.

### 15.11 Validation Evidence (VAL)

- URS-03-VAL-001 — IQ pack verifies the schema of all migrations creating Module 3 tables; RLS enabled on every tenant-scoped table; configuration registry seed loaded. Priority MUST. Risk HIGH.
- URS-03-VAL-002 — OQ pack tests the active-context resolver, context-switch validation, context filter on every regulated read / write, approval-scope check on every regulated decision, tenant-wide bypass, super-authority bypass, configuration registry CRUD, configuration coverage gate, error-code emission, hash-chain integrity. Priority MUST. Risk HIGH.
- URS-03-VAL-003 — PQ pack runs end-to-end scenarios for each journey J-01..J-25. Priority MUST. Risk HIGH.
- URS-03-VAL-004 — Regression pack exercises every requirement in §15. Priority MUST. Risk MEDIUM.
- URS-03-VAL-005 — Traceability matrix links each requirement identifier in §15 to at least one IQ / OQ / PQ test case. Priority MUST. Risk HIGH.
- URS-03-VAL-006 — Supplier and service-provider qualification pack per §17.1. Priority MUST. Risk HIGH.
- URS-03-VAL-007 — Inspection-ready evidence index per §17.2. Priority MUST. Risk HIGH.
- URS-03-VAL-008 — Migration Evidence Gate. Before Installation Qualification execution, engineering MUST provide the exact migration set proving all §6.2 entities, columns, constraints, indexes, RLS policies, append-only protections, and the configuration-coverage CI gate; Installation Qualification MUST fail if any migration evidence is missing. Priority MUST. Risk CRITICAL. Maps RG-03-006.

---

## 16. Acceptance Criteria and Test Cases

### 16.1 Plain-language behaviour scenarios

#### TC-PLAIN-001 — Sarah picks an active study and approves a record in scope

Sarah logs in. The deviations page renders the active-study selector. She picks study `S-2026-0042`. Deviation `DEV-2026-0117` is in her authority scope; her approve button works through the Controlled Approval Modal. The audit log shows the snapshot of her authority scope and the record's scope side-by-side.

#### TC-PLAIN-002 — Out-of-scope approval is blocked

Sarah opens a deviation she can read but whose product is outside her authority scope. She clicks Approve. The system rejects with a clear message naming the failing dimension; nothing is mutated; the rejection is recorded.

#### TC-PLAIN-003 — Deep-link with another study's identifier is denied

A test harness logs in as Sarah and opens a URL that references a different study from her active session. The system rejects with a clear message; the attempt is recorded; repeated attempts trigger a Security Operations Centre alert.

#### TC-PLAIN-004 — Resolver outage degrades safely

The active-context resolver is offline for two minutes. Every approve button across the platform is disabled with a banner explaining the outage; no regulated decision can be made; on recovery the banner clears.

#### TC-PLAIN-005 — Platform administrator updates the configuration registry

A new module ships. A platform administrator adds the configuration entry, signs the change, and the system from then on filters the new module's records by the active context. Another administrator cannot bypass — only platform identities can edit.

#### TC-PLAIN-006 — Continuous Integration gate catches a missing column

A developer accidentally references a column that does not exist. The Continuous Integration gate blocks the pull request with a precise file / line reference; the column never reaches production.

#### TC-PLAIN-007 — Tenant-wide assignment bypasses dimension check

A QA Director holds an Authority Profile assigned tenant-wide. They approve a record outside any specific site / product. The system permits it, records the bypass with `tenant_wide = true`, and the inspector pack contains the rationale.

#### TC-PLAIN-008 — Super-authority break-glass

A senior QA lead holds the time-bounded super-authority. They approve a record outside their normal scope to unblock an inspection. The system permits the action, alerts the Security Operations Centre, and notifies the QA Head and Founder; the record is approved and the rationale is captured.

#### TC-PLAIN-009 — Bulk approval honours per-record scope

The user selects 25 records and clicks Bulk approve. 18 succeed; 7 fail because the user's scope does not cover them. The user interface lists the 7 failures with their failing dimensions; the user can triage individually.

#### TC-PLAIN-010 — Auditor reads the cross-context-denial register

An auditor opens the cross-context-denial register and filters to a specific user. The system returns the events; integrity badge confirms the chain is intact.

#### TC-PLAIN-011 — Self-context-modification is blocked

A platform administrator attempts to add a configuration entry that would extend their own context coverage. The system rejects with a clear message; nothing is mutated.

#### TC-PLAIN-012 — Default context is tenant-only at login

A user logs in. They have no default study or site selected. They cannot approve anything until they pick one.

#### TC-PLAIN-013 — Deep-link pre-fills a proposed context but the user must confirm

A user clicks a link from an e-mail that includes a study identifier. The back end validates the study against the user's tenant and authority scope. If the validation passes, the active-context selector opens pre-filled with the proposed study and asks for explicit confirmation; on the user's confirmation the session's active context rebinds and the audit row records `CONTEXT_SWITCHED` with `source = 'deeplink'`. If the validation fails (different tenant, out-of-scope study, or unknown identifier), the deep-link is silently dropped and the user lands on the page with the prior session context; nothing is persisted and no audit row is written for the dropped attempt.

### 16.2 Technical test cases

#### TC-TECH-001 — Effective context returns canonical shape

- Type: Integration. Linked: URS-03-BE-001.
- Steps: Authenticate; GET `/access/me/context`. Verify response carries tenant identifier, optional dimension identifiers, effective scopes, tenant-wide and resolver-status fields.

#### TC-TECH-002 — Cross-context denial

- Type: Integration. Linked: URS-03-BE-003.
- Steps: Construct a request whose URL parameter references a study that is not the session's active study. Verify HTTP 403 `CROSS_CONTEXT_DENIED`; one row in the denial register; rate-limit kicks in after ten events per minute per user.

#### TC-TECH-003 — Approval-scope check passes

- Type: Integration. Linked: URS-03-BE-004, URS-03-BE-010.
- Steps: A user with `final_quality_approver` scoped to (site=Chennai, product=antibiotic-line) approves a deviation in (site=Chennai, product=antibiotic-line, study=S-1). Verify HTTP 200; one `APPROVAL_SCOPE_CHECK_PASSED` audit row; one `scope_snapshot` row with both scopes.

#### TC-TECH-004 — Approval-scope check fails

- Type: Integration. Linked: URS-03-BE-004, URS-03-BE-010.
- Steps: Same user attempts a deviation in (site=Chennai, product=vaccine-line, study=S-1). Verify HTTP 403 `APPROVAL_SCOPE_DENIED`; one `APPROVAL_SCOPE_CHECK_FAILED` audit row; snapshot includes the failing dimension `product`.

#### TC-TECH-005 — Tenant-wide bypass

- Type: Integration. Linked: URS-03-BE-005.
- Steps: A user with `tenant_wide = true` Authority Profile assignment approves a record. Verify pass; snapshot tagged `tenant_wide = true`; audit row `TENANT_WIDE_SCOPE_BYPASS_USED`.

#### TC-TECH-006 — Super-authority bypass

- Type: Integration. Linked: URS-03-BE-006.
- Steps: A user holding time-bounded `global_quality_oversight` approves an out-of-scope record. Verify pass; snapshot tagged `super_authority_used = true`; audit row `GLOBAL_SUPER_AUTHORITY_USED`; SOC alert fired; extended meaning text required.

#### TC-TECH-007 — Default context is tenant-only at login

- Type: Integration. Linked: URS-03-BE-007.
- Steps: Authenticate; GET `/access/me/context`. Verify response carries only tenant identifier; study / site / product / supplier are null.

#### TC-TECH-008 — Context-switch validation

- Type: Integration. Linked: URS-03-BE-008.
- Steps: POST a context switch with a study in another tenant. Verify HTTP 403 `CONTEXT_TENANT_MISMATCH`. POST a context switch with a study in the user's tenant but outside their scope. Verify HTTP 403 `CONTEXT_OUT_OF_SCOPE`.

#### TC-TECH-009 — Continuous Integration column-existence gate

- Type: Static analysis. Linked: URS-03-BE-009.
- Steps: Submit a pull request that adds a `MODULE_CONTEXT_CONFIG` entry referencing a column that does not exist in the corresponding migration. Verify the CI gate fails with precise file / line reference.

#### TC-TECH-010 — Self-context-modification block

- Type: Integration. Linked: URS-03-BE-011.
- Steps: As a platform administrator, attempt a configuration edit that extends own coverage. Verify HTTP 403 `SELF_CONTEXT_MODIFICATION_FORBIDDEN`; no mutation; audit row recorded.

#### TC-TECH-011 — Configuration registry atomicity

- Type: Concurrency. Linked: URS-03-BE-012.
- Steps: Fire 20 parallel PATCH requests on different rows. Verify each mutation increments the per-row registry version atomically and writes one audit row.

#### TC-TECH-012 — Resolver outage handling

- Type: Chaos + End-to-end. Linked: URS-03-BE-016, §6.6 `CONTEXT_RESOLUTION_FAILED`.
- Steps: Toggle resolver into failure. Bootstrap returns 503 with correlation identifier. Front end renders banner. Approve buttons disabled. SOC alert fires. On recovery, banner clears.

#### TC-TECH-013 — Audit-write failure rolls back

- Type: Chaos. Linked: URS-03-BE-016, URS-03-AUD-003.
- Steps: Force audit log INSERT to fail mid-transaction during a configuration edit. Verify HTTP 500 `AUDIT_TRAIL_WRITE_FAILED`; no registry row mutated; no electronic signature persisted.

#### TC-TECH-014 — Cross-tenant isolation in scope filter

- Type: Penetration. Linked: URS-03-SEC-001, URS-03-BE-013.
- Steps: As a user in tenant A, attempt to fetch records known to be in tenant B by guessing identifiers. Verify all attempts return 404 with no tenant-B data leaked.

#### TC-TECH-015 — Stale-version conflict on configuration edit

- Type: Integration. Linked: URS-03-BE-012.
- Steps: Open the editor in two sessions; A saves; B saves with stale version. Verify HTTP 409 `STALE_VERSION`; B's diff preserved.

#### TC-TECH-016 — Bulk approval per-record scope

- Type: Integration. Linked: URS-03-BE-004.
- Steps: POST a bulk approval of 25 records, mixed in / out of scope. Verify 207 multi-status with per-row outcome; in-scope rows succeed; out-of-scope rows return per-dimension reason; one snapshot per row.

#### TC-TECH-017 — Periodic access review covers context-config changes

- Type: Integration. Linked: URS-03-WF-003.
- Steps: Configure quarterly review; advance to T-30 days; verify reminder fires (URS-30); reviewer signs the attestation; verify audit row.

#### TC-TECH-018 — Configuration registry mutation transaction

- Type: Integration. Linked: URS-03-BE-012, BR-03-16.
- Steps: PATCH a registry row; force audit failure; verify rollback. Repeat without forced failure; verify atomic increment + audit + version.

#### TC-TECH-019 — Configuration coverage report

- Type: Integration. Linked: URS-03-REP-001.
- Steps: Run the report; verify per-module declared columns vs migration-set columns; report flags any drift.

#### TC-TECH-020 — Performance: approval-scope check

- Type: Load. Linked: URS-03-BE-004.
- Steps: Sustain 500 RPS of regulated decisions for fifteen minutes. Verify approval-scope-check p95 ≤ 50 ms; total p95 (including URS-04) ≤ 250 ms.

#### TC-TECH-021 — Performance: context filter applied

- Type: Load. Linked: URS-03-BE-001.
- Steps: Sustain 1 000 RPS of regulated reads. Verify p95 ≤ 80 ms; error rate < 0.1 %.

#### TC-TECH-022 — Migrations idempotent and create RLS-enabled tenant-scoped tables

- Type: Migration. Linked: URS-03-VAL-001, URS-03-VAL-008.
- Steps: Apply all Module 3 migrations to a clean database; apply them again. Verify schema; RLS enabled on every tenant-scoped table; configuration registry seed loaded; CI gate aligned with seed.

#### TC-TECH-023 — `<ContextGate>` renders selector when context missing

- Type: End-to-end. Linked: URS-03-FE-001.
- Steps: Navigate to a study-scoped page with no active study. Verify `<ContextGate>` renders the selector; once selected, page renders.

#### TC-TECH-024 — Snapshot integrity in audit chain

- Type: Concurrency + Integration. Linked: URS-03-AUD-005.
- Steps: Fire 100 parallel regulated decisions; run the chain integrity verifier on the audit subset. Verify chain unbroken from genesis.

#### TC-TECH-025 — Platform identity controlled support / break-glass posture

- Type: Integration. Linked: §3.6.1.
- Steps: As `platform_admin` without a controlled support envelope, attempt a tenant-scoped Module 3 action. Verify HTTP 403 `PLATFORM_TENANT_ACCESS_DENIED`. With the envelope, verify HTTP 200; `PLATFORM_TENANT_ACCESS_USED` audited; SOC alert fired.

#### TC-TECH-026 — Record Scope Resolver blocks decision on unresolved required dimension

- Type: Integration. Linked: URS-03-BE-004, §6.4.1.
- Steps: Construct a regulated record whose required dimension (e.g., `entity_type`) cannot be derived; submit a regulated decision against it. Verify HTTP 500 `RECORD_SCOPE_UNRESOLVED`; one `RECORD_SCOPE_UNRESOLVED` audit row with the failing dimension; SOC alert fired; the regulated record is not mutated; no electronic signature is persisted.

#### TC-TECH-027 — `CONTEXT_RESET` lifecycle

- Type: Integration. Linked: §6.6, J-26.
- Steps: User has active study context; user clicks "Reset to tenant only" in the selector; verify the session row's dimension columns are cleared; verify one `CONTEXT_RESET` audit row; verify subsequent study-scoped page renders `<ContextGate>`.

#### TC-TECH-028 — `CONTEXT_SWITCH_DENIED` versus `CROSS_CONTEXT_DENIED`

- Type: Integration. Linked: §6.6, J-28, J-05.
- Steps: (a) Attempt a context switch to an out-of-scope study; verify HTTP 403 `CONTEXT_OUT_OF_SCOPE` and one `CONTEXT_SWITCH_DENIED` audit row. (b) Construct a request whose URL parameter references a different study from the session's active study; verify HTTP 403 `CROSS_CONTEXT_DENIED` and one `CROSS_CONTEXT_DENIED` audit row. The two events are distinct and emitted by different code paths.

#### TC-TECH-029 — Deep-link confirmation requirement

- Type: End-to-end. Linked: DEC-03-08, TC-PLAIN-013.
- Steps: User clicks a deep-link with `?context=study:S-2026-0042`. (a) If the study is in scope, verify the active-context selector opens pre-filled and asks for confirmation; on confirmation verify `CONTEXT_SWITCHED` audit row carries `source='deeplink'`. (b) If the study is out of scope, verify the deep-link is silently dropped, no audit row is written, and the page renders with the prior session context.

#### TC-TECH-030 — `e_sig_id` nullability rule

- Type: Integration + Migration. Linked: URS-03-BE-010, §6.2.
- Steps: (a) Trigger a passed approval-scope check; verify the snapshot row has non-null `e_sig_id`. (b) Trigger a failed approval-scope check; verify the snapshot row has `e_sig_id` null. (c) Attempt to insert a snapshot row violating the database CHECK (`decision='passed'` with null `e_sig_id`, or `decision='failed'` with non-null `e_sig_id`); verify the insert is rejected by the database.

#### TC-TECH-031 — `/access/scope-check` is not client-reachable

- Type: Penetration. Linked: §6.3.3.
- Steps: As any authenticated client, attempt to call `POST /access/scope-check`. Verify HTTP 404 (the endpoint is not exposed externally); verify no information about scope or rules is leaked.

### 16.3 Acceptance criteria summary in Given / When / Then form

#### Functional

- AC-03-FUN-01 — Given an authenticated bootstrap, When the resolver succeeds, Then the response carries tenant identifier, optional dimension identifiers, effective scopes, and resolver status `available`.
- AC-03-FUN-02 — Given a request whose URL or payload context does not match the session's active context, When the back end processes the request, Then HTTP 403 `CROSS_CONTEXT_DENIED` and a forensic row is written.
- AC-03-FUN-03 — Given a regulated decision, When committed, Then the back end emits an `APPROVAL_SCOPE_CHECK_PASSED` or `APPROVAL_SCOPE_CHECK_FAILED` audit row with the scope snapshot.

#### UI

- AC-03-UI-01 — Given a page that requires study context with no active study, When the page mounts, Then `<ContextGate>` renders the active-context selector.
- AC-03-UI-02 — Given a stale registry version, When attempting to save, Then a refresh banner appears and pending diffs are preserved.
- AC-03-UI-03 — Given a resolver outage, When any authenticated page renders, Then the outage banner appears and approve buttons are disabled.

#### API

- AC-03-API-01 — Given a context-switch with a study in another tenant, When submitted, Then HTTP 403 `CONTEXT_TENANT_MISMATCH`.
- AC-03-API-02 — Given a configuration edit referencing a missing column, When submitted, Then HTTP 400 `CONTEXT_CONFIG_COLUMN_UNKNOWN`.

#### Workflow

- AC-03-WF-01 — Given the configuration registry, When edited concurrently, Then the second save returns 409 `STALE_VERSION`.

#### Permission / Authority

- AC-03-PERM-01 — Given a tenant administrator, When they attempt registry edit, Then HTTP 403 `PLATFORM_IDENTITY_REQUIRED`.
- AC-03-PERM-02 — Given a `viewer`, When they attempt to read the configuration registry, Then HTTP 403 `PERMISSION_DENIED`.
- AC-03-PERM-03 — Given a regulated decision without an electronic-signature session, When submitted, Then HTTP 422 `ESIG_REQUIRED`.

#### Audit

- AC-03-AUD-01 — Given any state-changing Module 3 action, When the audit transaction is rolled back, Then the action is also rolled back.
- AC-03-AUD-02 — Given 100 parallel regulated decisions, When the chain integrity verifier runs, Then the audit chain is unbroken from genesis.

#### Electronic signature

- AC-03-ESIG-01 — Given a configuration registry edit, When submitted, Then signature row carries server-derived `ip`, `user_agent`, `signed_at`, `signed_by`.
- AC-03-ESIG-02 — Given a `global_quality_oversight` bypass, When submitted, Then the meaning text MUST be present and at least 50 characters.

#### Data integrity

- AC-03-DI-01 — Given a soft-deleted membership, When administrator queries the audit-export endpoint, Then the membership appears in audit history.
- AC-03-DI-02 — Given concurrent registry edits, When committed, Then registry version strictly monotonic per row.

#### Integration

- AC-03-INT-01 — Given a regulated decision, When committed, Then URS-04 emits the electronic-signature row and Module 3 emits the scope snapshot in the same transaction.
- AC-03-INT-02 — Given URS-35 restores a database snapshot, When the integrity verifier runs, Then the audit chain validates including Module 3 events.

#### Report / export

- AC-03-REP-01 — Given an administrator exports the approval-scope-decision report, When the download completes, Then the manifest validates and the export is electronically signed.

#### AI / HITL

- AC-03-AI-01 — Static analysis finds zero references to large-language-model SDKs in Module 3.

#### Negative paths

- AC-03-NEG-01 — Given a deep-link with a study not in the user's scope, When followed, Then HTTP 403 `CONTEXT_OUT_OF_SCOPE`.
- AC-03-NEG-02 — Given a configuration edit on the immutable `module_key`, When submitted, Then HTTP 400 `IMMUTABLE_FIELD_REJECTED`.

#### Performance

- AC-03-PERF-01 — Approval-scope check p95 ≤ 50 ms at 500 RPS sustained.
- AC-03-PERF-02 — Context-filter applied p95 ≤ 80 ms at 1 000 RPS sustained.

#### Security

- AC-03-SEC-01 — Penetration test: cross-tenant token replay returns 404 with no tenant B data.
- AC-03-SEC-02 — Penetration test: bypass attempts of `<ContextGate>` produce `CROSS_CONTEXT_DENIED` audit rows.

#### Migration / backfill

- AC-03-MIG-01 — Module 3 migrations are idempotent.
- AC-03-MIG-02 — Applying all Module 3 migrations seeds the configuration registry with the launch entries and enables Row-Level Security on every tenant-scoped table.

### 16.4 Requirements-to-test traceability

| Requirement | Plain-language | Technical | Given / When / Then |
|---|---|---|---|
| URS-03-FE-001 | TC-PLAIN-001, TC-PLAIN-012 | TC-TECH-023 | AC-03-UI-01 |
| URS-03-FE-002 | TC-PLAIN-001 | TC-TECH-023 | — |
| URS-03-FE-003 | TC-PLAIN-001, TC-PLAIN-012 | (UI test) | — |
| URS-03-FE-004 | TC-PLAIN-002 | (FE pre-detection test) | — |
| URS-03-FE-005 | — | (static analysis) | AC-03-ESIG-01 |
| URS-03-FE-006 | TC-PLAIN-004 | TC-TECH-012 | AC-03-UI-03 |
| URS-03-FE-007 | TC-PLAIN-005 | TC-TECH-015 | — |
| URS-03-FE-008 | TC-PLAIN-005 | TC-TECH-015 | AC-03-UI-02 |
| URS-03-FE-009 | TC-PLAIN-009 | TC-TECH-016 | — |
| URS-03-FE-010 | — | TC-TECH-022 | — |
| URS-03-BE-001 | — | TC-TECH-021 | — |
| URS-03-BE-002 | — | TC-TECH-021 | — |
| URS-03-BE-003 | TC-PLAIN-003 | TC-TECH-002 | AC-03-FUN-02 |
| URS-03-BE-004 | TC-PLAIN-002 | TC-TECH-003, TC-TECH-004, TC-TECH-016 | AC-03-FUN-03 |
| URS-03-BE-005 | TC-PLAIN-007 | TC-TECH-005 | — |
| URS-03-BE-006 | TC-PLAIN-008 | TC-TECH-006 | AC-03-ESIG-02 |
| URS-03-BE-007 | TC-PLAIN-012 | TC-TECH-007 | AC-03-FUN-01 |
| URS-03-BE-008 | — | TC-TECH-008 | AC-03-API-01 |
| URS-03-BE-009 | TC-PLAIN-006 | TC-TECH-009 | AC-03-API-02 |
| URS-03-BE-010 | TC-PLAIN-001 | TC-TECH-003, TC-TECH-024 | AC-03-FUN-03 |
| URS-03-BE-011 | TC-PLAIN-011 | TC-TECH-010 | — |
| URS-03-BE-012 | TC-PLAIN-005 | TC-TECH-011, TC-TECH-018 | AC-03-WF-01 |
| URS-03-BE-013 | — | TC-TECH-014, TC-TECH-022 | AC-03-SEC-01 |
| URS-03-BE-014 | TC-PLAIN-003 | TC-TECH-002 | — |
| URS-03-BE-015 | — | (immutable-field test) | AC-03-NEG-02 |
| URS-03-BE-016 | TC-PLAIN-004 | TC-TECH-013 | AC-03-AUD-01 |
| URS-03-WF-001 | TC-PLAIN-001 | TC-TECH-008 | — |
| URS-03-WF-002 | TC-PLAIN-005 | TC-TECH-018 | — |
| URS-03-WF-003 | TC-PLAIN-009 | TC-TECH-017 | — |
| URS-03-DATA-001 | — | TC-TECH-022 | — |
| URS-03-DATA-002 | TC-PLAIN-005 | TC-TECH-018 | — |
| URS-03-DATA-003 | TC-PLAIN-010 | TC-TECH-024 | — |
| URS-03-SEC-001 | — | TC-TECH-014, TC-TECH-022 | AC-03-SEC-01 |
| URS-03-SEC-002 | TC-PLAIN-009 | TC-TECH-017 | — |
| URS-03-SEC-003 | — | (audit-trail review test) | — |
| URS-03-SEC-004 | TC-PLAIN-008 | TC-TECH-006 | — |
| URS-03-AUD-001 | — | TC-TECH-003, TC-TECH-018 | — |
| URS-03-AUD-002 | — | (server-derived metadata test) | AC-03-ESIG-01 |
| URS-03-AUD-003 | — | TC-TECH-013 | AC-03-AUD-01 |
| URS-03-AUD-004 | — | (writer presence test) | — |
| URS-03-AUD-005 | TC-PLAIN-010 | TC-TECH-024 | AC-03-AUD-02 |
| URS-03-ESIG-001 | — | TC-TECH-018 | AC-03-PERM-03 |
| URS-03-ESIG-002 | — | (signature-row test) | AC-03-ESIG-01 |
| URS-03-ESIG-003 | TC-PLAIN-008 | TC-TECH-006 | AC-03-ESIG-02 |
| URS-03-AI-001 | — | (static analysis) | AC-03-AI-01 |
| URS-03-AI-002 | — | (integration) | — |
| URS-03-INT-001 | — | TC-TECH-001 | — |
| URS-03-INT-002 | — | TC-TECH-001 | — |
| URS-03-INT-003 | TC-PLAIN-001 | TC-TECH-003 | AC-03-INT-01 |
| URS-03-INT-004 | TC-PLAIN-002 | TC-TECH-003, TC-TECH-004 | — |
| URS-03-INT-005 | — | TC-TECH-024 | — |
| URS-03-INT-006 | — | TC-TECH-008 | — |
| URS-03-INT-007 | — | (tenant inactive test) | — |
| URS-03-INT-008 | TC-PLAIN-004, TC-PLAIN-008 | TC-TECH-012 | — |
| URS-03-INT-009 | — | (DR drill) | AC-03-INT-02 |
| URS-03-REP-001 | TC-PLAIN-010 | TC-TECH-019 | AC-03-REP-01 |
| URS-03-REP-002 | TC-PLAIN-010 | TC-TECH-019 | AC-03-REP-01 |
| URS-03-REP-003 | TC-PLAIN-010 | TC-TECH-019 | — |
| URS-03-VAL-001 | — | TC-TECH-022 | — |
| URS-03-VAL-002 | All applicable | All applicable | All applicable |
| URS-03-VAL-003 | All applicable | All applicable | All applicable |
| URS-03-VAL-004 | — | The full TC-TECH suite re-run | — |
| URS-03-VAL-005 | — | This table is the seed of the traceability matrix | — |
| URS-03-VAL-006 | — | (supplier qualification evidence) | — |
| URS-03-VAL-007 | — | (evidence index) | — |
| URS-03-VAL-008 | — | TC-TECH-022 | AC-03-MIG-01, AC-03-MIG-02 |

---

## 17. Validation and CSV/CSA Evidence Expectations

| Item | Required evidence |
|---|---|
| URS traceability | Matrix linking every requirement identifier in §15 to test-case identifiers and to a regulatory-mapping row in §14 |
| Risk assessment | GAMP 5 risk register; risk-based assurance per FDA CSA |
| Configuration specification | Documented launch seed of `MODULE_CONTEXT_CONFIG`; Mode A invariant; default-context policy; super-authority bypass rules |
| Functional specification | Matches §6 of this document |
| Design specification | Matches §6.1–§6.4 |
| Test protocols | IQ (schema, RLS, indexes, registry seed, CI gate parity); OQ per URS-03-VAL-002; PQ per URS-03-VAL-003; regression per URS-03-VAL-004 |
| Test evidence | Pass / fail records per protocol step, traced to requirement identifier |
| Defect log | Defects mapped to URS requirement identifiers; resolved before release |
| Requirements traceability matrix | Per §16.4 |
| Release approval | Electronically signed by Quality Lead, Validation Lead, Information Security Lead, Regulatory Affairs Lead, executive authority |
| Training record | Engineering, QA, validation, operations trained on Module 3 expected state |
| Periodic review | Annual review per EU GMP Annex 11 §11; trigger reviews on every significant change |
| Data migration evidence | Backfill of `user_sessions.study_id`, `site_id`, `product_id`, `supplier_id` columns; backfill of registry seed |

### 17.1 Supplier and service-provider qualification pack

| Category | Required evidence |
|---|---|
| Cloud hosting provider | Inherited from URS-01 §17.1 |
| Backup and restore provider | Backup integrity evidence; restore-drill evidence with audit-chain integrity verification (URS-35); retention of registry-version history |
| Notification provider | Inherited from URS-01 §17.1 |
| Security-operations / SIEM | Alert routing for resolver outages, cross-context clusters, super-authority use, configuration mutations outside business hours |
| Right-to-audit / inspection support | Contractual right-to-audit clause; supplier commitment to support regulator inspections |

### 17.2 Inspection-ready evidence index

| Evidence item | Owner | Location / system of record | Retention | Linked requirement | Inspection use |
|---|---|---|---|---|---|
| Configuration registry version history per module | QA | `module_context_config_history` + audit log | retain history | URS-03-DATA-002 | reconstruct any past configuration baseline |
| Approval-scope snapshots | QA | `approval_scope_snapshots` | seven years | URS-03-AUD-005 | demonstrate authority of record at any past decision |
| Cross-context-denial register | Information Security | `cross_context_denials` | seven years | URS-03-AUD-005 | demonstrate forensic posture |
| Super-authority bypass register | QA / Founder | audit log subset | twenty-five years | URS-03-BE-006 | demonstrate break-glass governance |
| Tenant-wide bypass register | QA | audit log subset | seven years | URS-03-BE-005 | demonstrate tenant-wide governance |
| Resolver outage register | Information Security | audit log subset | one year | URS-03-AUD-005 | demonstrate incident-management posture |
| Validation evidence pack (IQ / OQ / PQ) | Validation | testing system of record | retain per release | URS-03-VAL-001..008 | release approval |
| Release approval (electronically signed) | Founder, QA, RA, Validation, Information Security | document control (URS-12) | retain per release | URS-03-VAL-007 | demonstrate authority chain for release |

---

## 18. Closed Decision and Dependency Register

### 18.1 Closed Launch Decisions Register

Every closed launch decision is locked in §2.3. No Module 3 internal open questions remain.

| Closed decision | Spec reference |
|---|---|
| Scope dimensions fixed at seven plus tenant-wide and super-authority | DEC-03-01, §3.4 |
| Default context is `tenant_id` only at login | DEC-03-02, BR-03-07 |
| Active context persisted on session row | DEC-03-03, §6.2 |
| CI column-existence gate is mandatory | DEC-03-04, BR-03-10 |
| Context filter mandatory for every regulated read / write | DEC-03-05, BR-03-01 |
| Approval-scope check at decision time | DEC-03-06, BR-03-04 |
| Cross-context denial rate-limited and audited | DEC-03-07, BR-03-15 |
| Active-context selector is the only authoritative path | DEC-03-08 |
| Context filter composes with RLS | DEC-03-09 |
| Super-authority bypass with electronic signature, SOC alert, auto-expiry | DEC-03-10, BR-03-06 |
| Context-aware breadcrumbs and URL patterns | DEC-03-11 |
| Scope snapshot per regulated decision | DEC-03-12, BR-03-11 |
| Resolver failure is fail-secure | DEC-03-13, BR-03-13 |

### 18.2 Dependencies

| ID | Dependency | Source | Impact | Blocking? | Mitigation |
|---|---|---|---|---|---|
| DEP-03-01 | URS-01 authentication, sessions, tenant binding | URS-01 | Substrate | Blocking | none |
| DEP-03-02 | URS-02 effective permissions and matrix-version | URS-02 | Substrate | Blocking | none |
| DEP-03-03 | URS-04 Controlled Approval Modal and electronic-signatures table | URS-04 | E-signature substrate | Blocking | none |
| DEP-03-04 | URS-05 Authority Profile catalogue, scope rules, delegations | URS-05 | Authority semantics | Blocking | none |
| DEP-03-05 | URS-06 universal audit substrate and retention | URS-06 | Audit ingest | Blocking | none |
| DEP-03-06 | URS-07 / URS-09 / URS-10 / URS-11 master-data registries | URS-07, URS-09, URS-10, URS-11 | Master-data presence | Blocking | none |
| DEP-03-07 | URS-08 active-tenant gate | URS-08 | Lifecycle | Blocking | none |
| DEP-03-08 | URS-30 notification delivery service | URS-30 | Notifications | Non-blocking | direct e-mail fallback |
| DEP-03-09 | URS-35 backup / restore / hash-chain restore drill | URS-35 | Disaster recovery | Blocking for PQ | DR drill |

---

## 19. Completeness Checklist

| Item | Yes / No | Evidence |
|---|---|---|
| Controlled-document metadata complete? | Yes | front matter |
| Approval block complete? | Yes (signatures pending) | Document Approval section |
| Version history complete? | Yes | Version History |
| Glossary complete? | Yes | §0.6 |
| Scope complete? | Yes | §2 |
| Roles and permissions complete? | Yes | §3 |
| User journeys complete? | Yes | §4 (25 journeys) |
| Front-end complete? | Yes | §5 |
| Backend complete? | Yes | §6 |
| Data model complete? | Yes | §6.2 |
| APIs complete? | Yes | §6.3 |
| Workflow complete? | Yes | §6.4 |
| Business rules complete? | Yes | §6.5 |
| Audit trail complete? | Yes | §6.6, BR-03-13, URS-03-AUD-001..005 |
| Electronic signature complete? | Yes | §6.7, URS-03-ESIG-001..003 |
| AI / Human-in-the-Loop complete or justified not applicable? | Yes (no AI; documented exclusion) | §8 |
| Reports complete? | Yes | §9 |
| Notifications complete? | Yes | §10 |
| Cross-module wiring complete? | Yes | §7 |
| Change-impact matrix complete? | Yes | §7.2 |
| Negative paths complete? | Yes | §11 |
| Security / privacy / tenant isolation complete? | Yes | §12 |
| ALCOA+ complete? | Yes | §13 |
| Regulatory mapping complete? | Yes | §14 |
| Predicate-rule applicability matrix complete? | Yes | §14.1 |
| Requirements register complete? | Yes | §15 |
| Acceptance tests complete? | Yes | §16 |
| Requirements-to-test traceability complete? | Yes | §16.4 |
| Validation evidence complete? | Yes | §17, §17.1, §17.2, URS-03-VAL-001..008 |
| Supplier qualification complete or justified not applicable? | Yes | §17.1 |
| Decisions and dependencies registered (no internal decisions outstanding)? | Yes | §18.1, §18.2 |
| Final quality gate answered? | Yes | §20 |

---

## 20. Final Module Output Quality Gate

This document becomes "Approved Controlled URS — released for engineering implementation and validation planning" only after (a) the Document Approval block is fully signed and (b) the Status field on the cover page is updated accordingly. It becomes "Released for validation execution" only after the required Installation, Operational, and Performance Qualification evidence gates are satisfied. **No Module 3 internal open questions remain.** Remaining items are controlled cross-module dependencies tracked in §18.2 and validation-evidence gates tracked in §15.11 and §17.

- **Specification ready for engineering review?** Yes — every MUST requirement is declarative, atomic, and testable. Front end, back end, data, application programming interface, workflow, audit, electronic signature, security, and integration are covered as a single self-contained contract.
- **Specification ready for quality validation review?** Yes — Installation, Operational, and Performance Qualification scope is specified; the traceability matrix template is in §16.4.
- **Specification ready for compliance review?** Yes — ALCOA+ table, regulatory mapping, and predicate-rule applicability matrix are populated.
- **Specification ready for inspector or client review?** Yes — every regulated assertion traces to a regulatory clause and to a test case; no internal item remains open. URS approval and validation execution are deliberately separated below.
- **Specification ready for Founder approval?** Yes.
- **Blocking gaps?** **None internal.** All Module 3 launch decisions are captured in §2.3 and §18.1. The remaining items are not URS-approval blockers: (a) the cross-module dependencies in §18.2 are owned by their named companion modules and tracked at the program level; (b) the Installation Qualification gate URS-03-VAL-008 (Migration Evidence Gate) and the validation evidence pack in §17 are release-time gates tracked by the validation lead and govern only the transition from "Approved Controlled URS" to "Released for validation execution".
- **Two-step release path (URS approval is separate from validation execution):**
  1. **Approved Controlled URS — released for engineering implementation and validation planning.** Reached upon signature capture in the Document Approval block. Engineering may begin implementation; validation may begin protocol authoring; QA / RA / Security may finalise pack templates.
  2. **Released for validation execution.** Reached only after URS-03-VAL-008 (Migration Evidence Gate) is satisfied and the §17 validation evidence pack is complete. This is a separate gate; URS approval does not depend on it.
  Upon completion of step 2, the document Status updates from "Approved Controlled URS" to "Released for validation execution".

---

## Appendix A — Bootstrap and Active-Context Resolution

```mermaid
flowchart TD
  A([Browser opens app]) --> B[App.tsx mount]
  B --> C[useAuthInit → /auth/me (URS-01)]
  C --> D{200 OK?}
  D -- Yes --> E[Auth store]
  E --> F[useEffectivePermissions → /access/me/permissions (URS-02)]
  F --> G[Permission store]
  G --> H[useContext → /access/me/context (URS-03)]
  H --> I{Resolver OK?}
  I -- Yes --> J[Context store: tenant + optional dimensions + scopes]
  J --> K[App renders authenticated routes]
  K --> L{ContextGate: required dimensions resolved?}
  L -- Yes --> M[Page renders]
  L -- No --> N[Render active-context selector]
  N --> O[POST /access/me/context]
  O --> P[Context store update]
  P --> M
  I -- 503 --> Q[Render outage banner; AuthorityGuard buttons disabled; SOC alert]
```

— End of Module 3 User Requirements Specification —
