# Feature Specification: RBAC Troubleshooting & Tenant UI Bugfix Pack v1

**Feature Branch**: `067-rbac-troubleshooting`  
**Created**: 2026-01-31  
**Status**: Draft  
**Input**: RBAC troubleshooting + tenant admin UI bugfix pack focused on the tenant-plane admin experience (`/admin`).

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Permission-safe tenant UI interactions (Priority: P1)

A tenant member with read-only permissions can browse tenant pages and menus without being sent to error pages for normal UI clicks.

**Why this priority**: Eliminates confusing UX and reduces support load; also prevents “permission leak” regressions in high-risk actions.

**Independent Test**: As a read-only member, verify restricted actions are visible-but-disabled with an explanatory tooltip and cannot be executed.

**Acceptance Scenarios**:

1. **Given** a user is a member of a tenant but lacks tenant management capability, **When** they view tenant lists and pages, **Then** management actions (e.g. Edit, Deactivate) are disabled and show an explanatory tooltip.
2. **Given** a user is a member but lacks tenant management capability, **When** they attempt to execute a blocked mutation (direct request / forced execution), **Then** the server denies it.

---

### User Story 2 - Archived tenant remains viewable for entitled members (Priority: P1)

A tenant member who is entitled to view a tenant can still access the tenant view even if the tenant is archived, and the UI clearly indicates status.

**Why this priority**: Prevents accidental “false 404” for legitimate members; enables safe lifecycle operations like restore.

**Independent Test**: Mark a tenant archived, ensure a viewing member can load it and sees an “Archived” banner; ensure non-members still receive 404.

**Acceptance Scenarios**:

1. **Given** a tenant is archived and a user is a member with tenant view capability, **When** they navigate to the tenant view, **Then** the page loads and shows an “Archived” status banner.
2. **Given** a tenant is archived and a user is not a member, **When** they navigate to the tenant scope URL, **Then** they receive a 404 (deny-as-not-found).

---

### User Story 3 - Diagnose & repair tenant membership invariants (Priority: P2)

An authorized tenant owner/manager can identify and fix membership integrity issues (missing owner, duplicates) via a dedicated troubleshooting screen.

**Why this priority**: Provides a recovery path for real-world “sharp edges” without requiring direct database intervention.

**Independent Test**: Seed broken states (0 owners, duplicate memberships), confirm diagnostics flag them and repair actions resolve them.

**Acceptance Scenarios**:

1. **Given** a tenant has no owners, **When** an authorized user opens diagnostics, **Then** the issue is surfaced and a repair action can promote a member to owner.
2. **Given** a tenant has duplicate memberships for the same user, **When** an authorized user runs “merge duplicates”, **Then** duplicates are removed and exactly one membership remains.

### Edge Cases

- A tenant member without management capability attempts to execute a blocked action via a forged request.
- A non-member attempts to access a tenant-scoped page (must be deny-as-not-found).
- Tenant is archived: view allowed for entitled members; lifecycle actions are status-appropriate.
- Tenant has 0 owners; tenant has 1 owner and an action would demote/remove the last owner.
- Membership duplicates exist and are resolved; ensure resulting owner count remains valid.
- A tenant has an external GUID identifier; ensure no internal lookups treat that GUID as the internal tenant primary key.

## Requirements *(mandatory)*

**Constitution alignment (required):** If this feature introduces any Microsoft Graph calls, any write/change behavior,
or any long-running/queued/scheduled work, the spec MUST describe contract registry updates, safety gates
(preview/confirmation/audit), tenant isolation, run observability (operation run record: type/identity/visibility), and tests.
If security-relevant DB-only actions intentionally skip an operation run record, the spec MUST describe audit log entries.

**Constitution alignment (RBAC-UX):** If this feature introduces or changes authorization behavior, the spec MUST:
- state which authorization plane(s) are involved (tenant `/admin/t/{tenant}` vs platform `/system`),
- ensure any cross-plane access is deny-as-not-found (404),
- explicitly define 404 vs 403 semantics:
  - non-member / not entitled to tenant scope → 404 (deny-as-not-found)
  - member but missing capability → 403
- describe how authorization is enforced server-side (Gates/Policies) for every mutation/operation-start/credential change,
- reference the canonical capability registry (no raw capability strings; no role-string checks in feature code),
- ensure global search is tenant-scoped and non-member-safe (no hints; inaccessible results treated as 404 semantics),
- ensure destructive-like actions require an explicit confirmation step,
- include at least one positive and one negative authorization test, and note any RBAC regression tests added/updated.

**Constitution alignment (OPS-EX-AUTH-001):** OIDC/SAML login handshakes may perform synchronous outbound HTTP (e.g., token exchange)
on `/auth/*` endpoints without an operation run record. This MUST NOT be used for Monitoring/Operations pages.

**Constitution alignment (BADGE-001):** If this feature changes status-like badges (status/outcome/severity/risk/availability/boolean),
the spec MUST describe how badge semantics stay centralized (no ad-hoc mappings) and which tests cover any new/changed values.

### Functional Requirements

- **FR-001 (Restore action icon)**: The tenant list row menu MUST display a consistent icon for the Restore action.
- **FR-002 (Readonly edit UX)**: For a tenant member lacking tenant management capability, the UI MUST present Edit as disabled with an explanatory tooltip and MUST avoid normal-click navigation leading to an error page.
- **FR-003 (Readonly cannot deactivate)**: Deactivate MUST be treated as a protected mutation and MUST NOT be executable by a tenant member lacking tenant management capability.
- **FR-004 (Archived tenant access)**: An entitled tenant member (tenant view capability) MUST be able to open archived tenants. A non-member MUST receive a 404 for tenant scope URLs.
- **FR-005 (Owner invariant)**: The system MUST prevent removing/demoting the last remaining tenant owner and MUST surface “missing owner” situations in diagnostics.
- **FR-006 (Membership integrity)**: The system MUST prevent duplicate memberships per (tenant, user). Diagnostics MUST identify duplicates and provide a safe repair flow for authorized users.
- **FR-007 (GUID vs internal ID)**: The system MUST treat external tenant identifiers (GUIDs) as external-only identifiers and MUST NOT use them where an internal tenant primary key is required.
- **FR-008 (Diagnostics access + safety)**: Diagnostics MUST not expose cross-tenant data to non-members. Repair actions MUST be permission-gated and MUST record an auditable trail.

#### Authorization & Error Semantics (explicit)

- Tenant-scope URLs: non-member / not entitled MUST be deny-as-not-found (404).
- Member but missing capability: server-side MUST deny execution (403).
- UI behavior: member-without-capability SHOULD see actions visible-but-disabled with tooltip to prevent normal-click 403 pages.

#### Out of Scope

- No new “Workspace” model in this spec.
- No platform-plane (`/system`) expansion.
- No outbound integration calls are introduced as part of diagnostics/repairs.

#### Assumptions

- “Archived” is treated as an archived/lifecycle state that remains viewable to entitled members.
- Deactivate (archive) uses the existing tenant lifecycle capability `Capabilities::TENANT_DELETE`.

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

- **Tenant**: The internal customer/workspace entity users are members of; has an internal primary key and an external identifier.
- **Tenant Membership**: Links a user to a tenant with one or more capability grants or derived entitlements.
- **Capability / Entitlement**: A named permission used to determine visibility/execution of actions within a tenant scope.
- **Diagnostics Finding**: A detected issue such as “missing owner”, “duplicate membership”, or “identifier misuse risk”.
- **Repair Action**: A controlled, permission-gated remediation step that fixes a finding and records an audit entry.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: Read-only members can navigate all tenant UI flows covered by automated tests without encountering an error page during normal click paths.
- **SC-002**: Protected tenant mutations (e.g., deactivate) have 0 successful executions by users lacking the required capability across automated tests.
- **SC-003**: Archived tenant access works as defined: entitled members can view; non-members get 404, verified by automated tests.
- **SC-004**: Membership integrity can be restored via UI-only repair actions for seeded broken states, verified by automated tests.
