# Feature Specification: Canonical Operation Viewer Context Decoupling

**Feature Branch**: `144-canonical-operation-viewer-context-decoupling`  
**Created**: 2026-03-14  
**Status**: Draft  
**Input**: User description: "Canonical operation-run viewing currently fails or becomes misleading when remembered tenant context does not match the operation run's referenced tenant, especially for onboarding and non-active tenant scenarios."

## Spec Scope Fields *(mandatory)*

- **Scope**: canonical-view
- **Primary Routes**:
  - `/admin/operations`
  - `/admin/operations/{run}`
  - `/admin/tenants/{tenant}`
  - Any in-product deep link that resolves to `/admin/operations/{run}`
- **Data Ownership**:
  - Operation runs remain canonical workspace-owned records.
  - Operation runs may reference a tenant, but they are not subordinate to remembered tenant context.
  - Tenant lifecycle may affect presentation and follow-up affordances, but not the existence of a canonical run.
  - This feature introduces no new tables and does not change the workspace-first ownership model.
- **RBAC**:
  - Authorization planes involved: tenant/admin `/admin` canonical workspace routes and tenant entitlement checks for referenced tenants.
  - Workspace non-members or users lacking entitlement to a referenced tenant must receive deny-as-not-found behavior.
  - Workspace members who are in scope but lack the required capability to inspect operation history must receive forbidden behavior.
  - Authorization must be determined from the run, workspace relationship, actor, and referenced tenant entitlement, never from remembered tenant context equality.
  - This spec is a focused implementation slice of Spec 143's canonical workspace-level record viewer rules.

For canonical-view specs, the spec MUST define:

- **Default filter behavior when tenant-context is active**: `/admin/operations` may prefilter to the currently selected tenant as a convenience, but the filter is optional state and clearing or changing it must not affect whether `/admin/operations/{run}` is legitimate.
- **Explicit entitlement checks preventing cross-tenant leakage**: The canonical run viewer must verify the run belongs to the active workspace, verify tenant entitlement directly against the run's referenced tenant when one exists, and withhold tenant-linked details from any actor who is not entitled to that tenant. Remembered tenant context, including the currently selected header tenant, must never substitute for these checks.

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Open A Canonical Run Reliably (Priority: P1)

As a workspace operator, I need `/admin/operations/{run}` to open whenever the run exists and I am authorized, even if my remembered tenant context points at another tenant, so that operation history behaves like a trustworthy monitoring surface.

**Why this priority**: This is the core trust failure. If valid runs appear missing because of unrelated header state, incident investigation and operator confidence both break.

**Independent Test**: Can be fully tested by opening an authorized run while the header points to a different tenant and confirming the run renders, authorization is enforced correctly, and the page shows an informational mismatch state instead of failing.

**Acceptance Scenarios**:

1. **Given** an authorized user opens a valid run linked to tenant A while tenant B is selected in the header, **When** the canonical viewer loads, **Then** the run renders successfully and the mismatch is treated as informational context rather than record invalidity.
2. **Given** an authorized user opens a valid run with no tenant reference, **When** the canonical viewer loads, **Then** the viewer renders as a workspace-level run without requiring any selected tenant context.
3. **Given** a run does not exist, **When** a user opens `/admin/operations/{run}`, **Then** the system returns the normal not-found outcome.

---

### User Story 2 - Trust Deep Links From Other Surfaces (Priority: P1)

As a workspace operator, I need run links from tenant pages, notifications, verification surfaces, and future alerts to resolve to the same authoritative viewer regardless of current header state, so that any View run link is dependable.

**Why this priority**: Canonical links lose their value if they only work when generated and opened under matching remembered context.

**Independent Test**: Can be fully tested by opening canonical run links generated from a tenant detail page, a notification-style entry point, and a workspace verification or monitoring surface while switching or clearing header context between requests.

**Acceptance Scenarios**:

1. **Given** a tenant detail surface links to a canonical run, **When** the operator opens that link with a different tenant selected, **Then** the canonical viewer still opens the same run.
2. **Given** a notification or monitoring widget links to a canonical run, **When** the operator opens that link without any selected tenant, **Then** the canonical viewer still resolves from the run and authorization rules alone.
3. **Given** a valid run references an onboarding, archived, or other tenant state already excluded by existing selector rules, **When** an authorized operator opens a canonical link to that run, **Then** the viewer remains accessible and does not require that tenant to be selectable in the standard tenant switcher.

---

### User Story 3 - Understand Context And Lifecycle Without Being Blocked (Priority: P2)

As a workspace operator, I need the viewer to explain tenant-context mismatch and tenant lifecycle state clearly, so that I understand why some follow-up actions may differ without confusing that state with access failure.

**Why this priority**: Operators should not have to infer from a 404 whether the problem is entitlement, lifecycle, or just mismatched context.

**Independent Test**: Can be fully tested by opening canonical runs for active, onboarding, archived, selector-excluded, and tenantless runs while varying remembered tenant context and verifying the viewer uses non-blocking explanatory messaging plus lifecycle-safe follow-up affordances.

**Acceptance Scenarios**:

1. **Given** the selected tenant differs from the run's tenant, **When** the run viewer loads, **Then** the page shows a non-blocking message explaining the mismatch.
2. **Given** the run's tenant is onboarding, archived, or otherwise excluded from the tenant selector by existing availability rules, **When** the canonical viewer loads for an authorized operator, **Then** the page shows lifecycle-aware context, keeps the run viewable, and does not over-promise tenant follow-up actions.
3. **Given** the operator is authorized for the workspace but not entitled to the run's referenced tenant, **When** the operator opens the canonical run route, **Then** the system returns deny-as-not-found rather than a misleading mismatch message.

### Edge Cases

- A remembered tenant may be stale, archived, cleared, or otherwise ineligible for current tenant selection; that state must not invalidate an unrelated canonical run.
- A canonical run may reference a tenant that is onboarding, archived, or otherwise excluded from the normal tenant selector by existing availability rules; the run remains valid if entitlement allows it.
- A canonical run may have no tenant reference at all and still must remain viewable as a workspace record.
- A deep link may open the run viewer before the current browser session has selected any tenant context.
- Follow-up links from the run viewer back into tenant surfaces may be unavailable because of tenant lifecycle rules even when the run itself is valid.

## Requirements *(mandatory)*

**Constitution alignment (required):** This feature introduces no new Microsoft Graph calls, no new write workflow, and no new scheduled or queued work. It hardens the semantics of an existing canonical monitoring record so that route legitimacy, authorization, and tenant-reference handling stay explicit, testable, and audit-safe.

**Constitution alignment (OPS-UX):** This feature reuses existing `OperationRun` records but does not create a new run type and does not change run lifecycle ownership. The existing three-surface feedback contract remains unchanged. `OperationRun.status` and `OperationRun.outcome` remain service-owned, `summary_counts` rules remain unchanged, and this feature adds regression coverage around canonical run visibility rather than around run transitions or notifications.

**Constitution alignment (RBAC-UX):** This feature changes authorization behavior within the admin plane. Non-members or users lacking workspace or tenant entitlement remain deny-as-not-found. Members who are in scope but lack the required capability to inspect operation history remain forbidden. Authorization must be enforced server-side from workspace membership, tenant entitlement on the run's referenced tenant, and capability policy checks. No raw capability strings or role-name checks may be introduced. Global search and direct record access must remain tenant-safe and non-member-safe. No destructive action is introduced by this spec.

**Constitution alignment (OPS-EX-AUTH-001):** Not applicable. Monitoring and operation viewing continue to avoid auth-handshake exceptions and do not rely on synchronous auth-path behavior.

**Constitution alignment (BADGE-001):** This feature may change lifecycle or context presentation inside the viewer, so lifecycle and run-status badges must continue to come from centralized badge semantics rather than page-local mappings.

**Constitution alignment (UI-NAMING-001):** The target object is the operation run. Primary operator verbs remain `View run`, `Back to Operations`, and existing follow-up labels already used by related navigation. The new messaging must use domain language such as `current tenant context`, `run tenant`, and `canonical workspace view`, and must avoid implying that mismatched context makes the run invalid.

**Constitution alignment (Filament Action Surfaces):** This feature modifies existing Filament operations screens. The Action Surface Contract remains satisfied because the action inventory is not materially expanded; the change is to route legitimacy, messaging, and authorization semantics. The matrix below documents the in-scope surfaces.

**Constitution alignment (UX-001 — Layout & Information Architecture):** The operations index remains a table-driven monitoring page and the canonical run page remains a view/detail surface. This feature preserves the current layouts while adding explicit, non-blocking context messaging and lifecycle-aware framing. No create or edit layout is introduced in this scope.

### Functional Requirements

- **FR-144-001**: The system MUST classify `/admin/operations/{run}` as a canonical workspace-level record viewer whose primary subject is the operation run.
- **FR-144-002**: The system MUST determine canonical run-view legitimacy from the run's existence, workspace relationship, actor authorization, and referenced tenant entitlement when a tenant is present.
- **FR-144-003**: The system MUST NOT require the remembered tenant context, including the currently selected header tenant, to match the run's tenant in order to render the canonical run viewer.
- **FR-144-004**: If a run exists and the actor is authorized, the system MUST render the canonical run viewer even when the selected tenant differs from the run's tenant.
- **FR-144-005**: If a run exists and references no tenant, the system MUST render the canonical viewer as a workspace-level run without requiring tenant context.
- **FR-144-006**: If a run exists and references an onboarding, archived, or otherwise selector-excluded tenant under existing availability rules, the system MUST keep the run viewable for authorized actors and MUST NOT require that tenant to be selectable as active context.
- **FR-144-007**: If the actor lacks workspace membership or lacks entitlement to the run's referenced tenant, the system MUST return deny-as-not-found and MUST NOT reveal tenant-linked details.
- **FR-144-008**: If the actor is in scope but lacks the required capability to inspect operation history, the system MUST return forbidden rather than masking the failure as a context mismatch.
- **FR-144-009**: The viewer MUST distinguish between not-found, authorization failure, and tenant-context mismatch, and tenant-context mismatch MUST never masquerade as not-found.
- **FR-144-010**: The viewer MUST display the run's referenced tenant clearly when one exists and MUST frame tenantless runs clearly as workspace-level runs.
- **FR-144-011**: When the currently selected header tenant differs from the run's tenant, the viewer MUST display a non-blocking informational message explaining the mismatch.
- **FR-144-012**: When no tenant context is selected, the viewer MAY display workspace-view framing, but it MUST NOT require tenant selection to proceed.
- **FR-144-013**: Tenant lifecycle state for the run's referenced tenant MUST influence informational messaging and follow-up affordances, but MUST NOT determine whether the canonical run page exists.
- **FR-144-014**: All in-product deep links to operation runs within this scope MUST resolve to the canonical operation viewer route and MUST remain viewable because the run is viewable, not because the generating page shared the same remembered tenant context.
- **FR-144-015**: Return navigation, back links, and tenant-prefilter behavior on `/admin/operations` MUST be treated as convenience behavior only and MUST NOT reintroduce selected-tenant-as-validity-gate logic.
- **FR-144-016**: The canonical run viewer MUST NOT silently switch the user's remembered tenant context to match the run's tenant as an implicit side effect of viewing the page.
- **FR-144-017**: Any follow-up links or actions from the canonical run viewer into tenant surfaces MUST remain lifecycle-safe and authorization-safe, so a valid run can coexist with unavailable or reduced tenant follow-up actions.
- **FR-144-018**: New code in scope MUST NOT use selected-tenant equality as an authorization shortcut, route precondition, or record-resolution gate for canonical run viewing.
- **FR-144-019**: Regression coverage for this feature MUST include matched tenant context, mismatched tenant context, no selected tenant, onboarding tenant run, archived or selector-excluded tenant run, and tenantless run scenarios, plus at least one positive and one negative authorization case and one lifecycle-safe follow-up-action case.
- **FR-144-020**: This feature's solution pattern MUST remain reusable for future canonical workspace-level record viewers without changing operation-run ownership or introducing a new page category.

## UI Action Matrix *(mandatory when Filament is changed)*

If this feature adds/modifies any Filament Resource / RelationManager / Page, fill out the matrix below.

For each surface, list the exact action labels, whether they are destructive (confirmation? typed confirmation?),
RBAC gating (capability + enforcement helper), and whether the mutation writes an audit log.

| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Operations index | `/admin/operations` | Existing scope indicator plus `Back to {tenant}` or origin return when context provides it, and `Show all tenants` when tenant context is active | Canonical run links from row inspection | `View run` | Existing grouped bulk actions unchanged in this spec | Existing empty state unchanged in this spec | Not applicable | Not applicable | No new audit event | This feature preserves the existing action inventory and only clarifies that tenant prefilter state is convenience behavior, not canonical-record validity. |
| Canonical operation run viewer | `/admin/operations/{run}` | Existing scope indicator, `Back to Operations` or origin return, `Show all operations` when tenant context is active, `Refresh`, existing `Open` related links, and existing `Resume capture` when already valid | Route-record detail page | None | None | Not applicable | Same as header actions listed for this viewer | Not applicable | No new audit event in this spec | Action Surface Contract remains satisfied. `Resume capture` keeps its existing confirmation and authorization rules; this feature changes page legitimacy and informational context, not mutation semantics. |

### Key Entities *(include if feature involves data)*

- **Operation Run**: A canonical workspace-owned monitoring record that may optionally reference a tenant and remains authoritative on its own route.
- **Referenced Tenant**: The tenant linked from an operation run, whose entitlement and lifecycle influence viewer details and follow-up affordances but not the existence of the run itself.
- **Remembered Tenant Context**: Operator preference state used for convenience filtering and navigation, but not as an authorization source or route-legitimacy requirement.
- **Canonical Run Deep Link**: Any in-product link that opens `/admin/operations/{run}` from a tenant page, notification, monitoring surface, or future alerting surface.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-144-001**: In focused regression coverage, 100% of authorized operation-run links open successfully for matched tenant context, mismatched tenant context, and no selected tenant context scenarios.
- **SC-144-002**: In focused regression coverage, 0 authorized canonical run views fail with false not-found behavior solely because remembered tenant context differs from the run's tenant.
- **SC-144-003**: In focused regression coverage, 100% of non-member or non-entitled access attempts resolve as deny-as-not-found, and 100% of in-scope capability denials resolve as forbidden.
- **SC-144-004**: In focused regression coverage, 100% of authorized runs linked to onboarding, archived, or other selector-excluded tenants under existing availability rules remain viewable through the canonical route.
- **SC-144-005**: In focused regression coverage, 100% of tenantless runs remain viewable through the canonical route without requiring tenant selection.
- **SC-144-006**: In focused UX validation, every covered tenant-context mismatch case shows explicit non-blocking context messaging instead of an ambiguous failure state.
- **SC-144-007**: All in-scope `View run` entry points continue to resolve to the canonical run viewer route and do not require page-local tenant-coupled URLs.

## Assumptions

- This spec refines and implements the canonical-viewer semantics established by Spec 143 rather than redefining the broader tenant lifecycle model.
- The existing canonical operation viewer route remains `/admin/operations/{run}`.
- Existing run links already target the canonical route family and this feature hardens their trust contract rather than introducing a new link family.
- Existing capability registry and policy structure already define the capability needed to inspect operation history.
- Lifecycle-safe follow-up actions for tenant surfaces may be refined by later specs, but this feature must not let missing follow-up actions invalidate the run viewer itself.

## Risks

- Hidden tenant-context coupling may remain in route resolution, page mount logic, or shared shell helpers if the change only addresses the most visible failure path.
- Over-correcting into tenant blindness could weaken legitimate tenant entitlement checks for tenant-linked runs.
- Follow-up links from the canonical viewer may still confuse operators if they continue to assume active tenant context rather than lifecycle-safe tenant access.
- Future canonical viewers may repeat the same anti-pattern if this feature is treated as an operations-only exception instead of a reusable rule.

## Follow-Up Dependencies

- Spec 145 — Tenant Action Taxonomy and Lifecycle-Safe Visibility
- Spec 146 — Central Tenant Status Presentation
- Spec 147 — Tenant Selector and Remembered Context Enforcement
- Spec 148 — Central Tenant Operability Policy

## Final Direction

The operation-run viewer must behave like a true canonical workspace-level record page. The run is authoritative, the workspace relationship matters, authorization matters, and the referenced tenant matters, but remembered tenant context does not determine page legitimacy. This is the required trust model for enterprise monitoring and the correct pattern for future canonical record viewers.
