# Implementation Plan: Spec 136 Admin Panel Canonical Tenant Resolution Full Rollout

**Branch**: `136-admin-canonical-tenant` | **Date**: 2026-03-11 | **Spec**: `specs/136-admin-canonical-tenant/spec.md`
**Spec (absolute)**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/136-admin-canonical-tenant/spec.md`
**Input**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/136-admin-canonical-tenant/spec.md`

## Summary

Complete the rollout of the canonical admin tenant rule established in Spec 135 across all remaining admin-visible and admin-reachable shared tenant-sensitive surfaces.

Workspace-admin flows under `/admin/...` will use `OperateHubShell::activeEntitledTenant(Request $request): ?Tenant` as the single tenant source for header context, queries, filters, widgets, links, and sensitive actions. Workspace-admin navigation will stay workspace-only except for baseline assets, so tenant-sensitive entry points move to the tenant panel under `/admin/t/{tenant}/...`. Admin surfaces with persisted tenant-related filters will standardize on `CanonicalAdminTenantFilterState`. Tenant-panel flows under `/admin/t/{tenant}/...` will keep panel-native `Filament::getTenant()` semantics. Global-search parity will be preserved through the existing admin-aware scoping pattern in `ScopesGlobalSearchToTenant` or explicit disablement where parity cannot be guaranteed cheaply.

Implementation is organized into three rollout waves:
1. high-risk tenant-sensitive resources with sensitive actions or strong drift risk,
2. governance, restore, and inventory alignment surfaces,
3. workspace-wide tenant-default pages, diagnostics, widget alignment, and full guard expansion.

## Technical Context

**Language/Version**: PHP 8.4 on Laravel 12  
**Primary Dependencies**: Filament v5, Livewire v4, Pest v4, Laravel Sail  
**Storage**: PostgreSQL application database and session-backed Filament table state  
**Testing**: Pest feature and unit tests via `vendor/bin/sail artisan test --compact`  
**Target Platform**: Web application with Filament admin and tenant panels  
**Project Type**: Laravel monolith with Filament resources, pages, widgets, policies, support-layer helpers, and Pest guard tests  
**Performance Goals**: Keep monitoring and admin renders DB-only, keep tenant resolution deterministic per request, and avoid broader-than-visible scopes or stale session-driven tenant drift  
**Constraints**:
- No dependency changes.
- No new Graph calls, queued workflows, or scheduled workflows.
- No panel-provider or routing redesign; provider registration remains in `bootstrap/providers.php` and panel routing remains intact.
- No universal resolver abstraction that erases the distinction between workspace-admin and tenant-panel semantics.
- Existing destructive and governance-sensitive actions must keep their current confirmation, authorization, and audit behavior while gaining tenant-target parity.
- No new assets are introduced; deployment remains unchanged and does not add `filament:assets` work for this feature.
**Scale/Scope**: Rollout across the canonical admin shell helper, session filter synchronization helper, admin-aware global-search behavior, 10+ affected resources/pages/widgets, the admin panel provider registration map, one architectural guard suite, and focused regression coverage for tenant switching, stale filters, search parity, and sensitive actions

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- **Inventory-first / snapshots**: PASS — the feature changes request-time resolution and session-backed filter state only; inventory, backup, and snapshot storage remain unchanged.
- **Read/write separation**: PASS — no new write workflow is introduced. Existing destructive and governance-sensitive actions remain existing actions and are only hardened to keep visible tenant and execution tenant aligned.
- **Graph contract path**: PASS — no Graph calls or contract-registry changes are required.
- **Deterministic capabilities**: PASS — no capability registry changes; existing Gates, policies, and capability helpers remain authoritative.
- **RBAC-UX planes**: PASS — `/admin/...` and `/admin/t/{tenant}/...` stay explicitly separate. Admin canonical tenant logic applies only in the admin path, tenant-panel-native logic applies only in tenant routes.
- **Workspace isolation**: PASS — workspace-admin routes remain workspace-scoped and tenant-safe, with deny-as-not-found preserved for non-members or out-of-scope access.
- **Tenant isolation**: PASS — Type A and Type B rollout surfaces will keep tenant entitlement checks aligned across query, widgets, links, detail access, and actions.
- **Global search safety**: PASS — any rollout resource that remains globally searchable must either use admin-safe scoped search with a View page present or disable global search where parity cannot be guaranteed.
- **Run observability**: PASS — no new `OperationRun` types or lifecycle behavior. Monitoring remains DB-only at render time.
- **Ops-UX lifecycle / summary counts / notifications**: PASS — unchanged.
- **BADGE-001**: PASS — badge meanings remain centralized; only the tenant context feeding those views is normalized.
- **UI-NAMING-001**: PASS — existing operator-facing phrases such as tenant labels, safe-state messages, and filter labels remain domain-first and implementation-neutral.
- **Filament Action Surface Contract**: PASS WITH EXEMPTION — affected resources and pages mostly keep their current action surfaces. The rollout verifies tenant-target parity for existing actions instead of changing action inventory.
- **Filament UX-001**: PASS WITH EXEMPTION — no layout redesign is needed; the feature only tightens tenant semantics and explicit safe-state behavior.
- **Livewire v4.0+ compliance**: PASS — all affected Filament screens remain on the supported Filament v5 / Livewire v4 stack.
- **Provider registration location**: PASS — no provider changes are required; Laravel 12 provider registration remains in `bootstrap/providers.php`.
- **Global-search hard rule**: PASS — `PolicyResource`, `PolicyVersionResource`, and `EntraGroupResource` already have View pages where search parity matters; rollout design requires those resources to retain View-page-backed parity or disable admin-path global search.
- **Destructive action safety**: PASS — `BackupScheduleResource`, `BackupSetResource`, `RestoreRunResource`, `FindingResource`, and `PolicyVersionResource` retain existing destructive or governance-sensitive actions; rollout scope is to preserve confirmation + authorization while guaranteeing the action tenant matches the visible tenant.
- **Asset strategy**: PASS — no new panel assets, no `FilamentAsset::register()`, and no deployment change beyond existing processes.

## Phase 0 — Research Summary

Research findings are recorded in `specs/136-admin-canonical-tenant/research.md`.

Key decisions:
- Treat admin panel provider registration plus direct admin page registration as the source of truth for which surfaces are truly admin-visible, while still reviewing shared resources whose code can run in both panels.
- Keep `OperateHubShell::activeEntitledTenant()` as the only canonical admin tenant resolver instead of inventing a second abstraction.
- Standardize persisted tenant-filter synchronization through `CanonicalAdminTenantFilterState` wherever `persistFiltersInSession()` and tenant-related filters coexist.
- Reuse the existing `ScopesGlobalSearchToTenant` admin-aware search pattern for searchable rollout resources, and disable admin-path search if parity is not cheap or safe.
- Treat `AlertDeliveryResource` and `AuditLog` as reference patterns for workspace-wide datasets with canonical tenant-default behavior.
- Expand `AdminTenantResolverGuardTest` from a narrow allowlist to the full rollout surface set with explicit, documented exceptions for tenant-panel-native files.

## Phase 1 — Design & Contracts

### Data Model

Design details are recorded in `specs/136-admin-canonical-tenant/data-model.md`.

Key design points:
- No schema changes are required.
- The feature models request-time surface classification, tenant-resolution state, persisted filter state, sensitive action parity, and guard coverage as behavioral entities.
- Shared resources are treated as panel-aware execution surfaces rather than purely admin or purely tenant objects.
- Persisted filter state is never trusted without synchronization against the current canonical admin tenant.

### Contracts

Internal behavior contracts are recorded in `specs/136-admin-canonical-tenant/contracts/admin-tenant-resolution-rollout.yaml`.

Contract scope:
- workspace-admin canonical tenant rule versus tenant-panel-native rule
- Type A, Type B, and Type C surface classifications
- rollout expectations for the named resources, pages, and widgets
- search parity rules and no-context behavior
- guard coverage and exception inventory expectations

### Quickstart

Implementation and verification steps are recorded in `specs/136-admin-canonical-tenant/quickstart.md`.

### Post-Design Constitution Re-check

- **Inventory-first / snapshots**: PASS — unchanged.
- **Read/write separation**: PASS — the design only normalizes read, filter, link, and action-target semantics.
- **Graph contract path**: PASS — still no Graph activity.
- **RBAC-UX**: PASS — design keeps 404 for non-members or out-of-scope tenant access and 403 only after scope membership is established for capability-gated mutations.
- **Workspace isolation**: PASS — admin routes remain workspace-scoped even when tenant is a shell concept rather than a route parameter.
- **Tenant isolation**: PASS — list, detail, widget, search, and action paths are designed to use one tenant rule per surface.
- **Global search safety**: PASS — the design explicitly requires admin-safe search parity for searchable resources or explicit disablement.
- **Run observability / Ops-UX lifecycle**: PASS — unchanged.
- **BADGE-001 / UI-NAMING-001**: PASS — centralized badge rendering and product wording remain intact.
- **Filament Action Surface Contract**: PASS WITH EXEMPTION — no new destructive actions, no new action-surface inventory.
- **Livewire v4.0+ compliance**: PASS — unchanged Filament v5 / Livewire v4 stack.
- **Provider registration location**: PASS — no panel or provider changes; `bootstrap/providers.php` remains correct.
- **Asset strategy**: PASS — still no asset registration or deployment delta.

## Project Structure

### Documentation (this feature)

```text
specs/136-admin-canonical-tenant/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   └── admin-tenant-resolution-rollout.yaml
└── tasks.md
```

### Source Code (repository root)

```text
app/
├── Providers/Filament/
│   └── AdminPanelProvider.php
├── Support/
│   ├── OperateHub/
│   │   └── OperateHubShell.php
│   └── Filament/
│       ├── CanonicalAdminTenantFilterState.php
│       └── ScopesGlobalSearchToTenant.php
├── Filament/
│   ├── Pages/
│   │   ├── Monitoring/
│   │   │   └── AuditLog.php
│   │   ├── BaselineCompareLanding.php
│   │   ├── InventoryCoverage.php
│   │   └── TenantDiagnostics.php
│   ├── Resources/
│   │   ├── PolicyResource.php
│   │   ├── BackupScheduleResource.php
│   │   ├── BackupSetResource.php
│   │   ├── FindingResource.php
│   │   ├── RestoreRunResource.php
│   │   ├── InventoryItemResource.php
│   │   ├── PolicyVersionResource.php
│   │   ├── ProviderConnectionResource.php
│   │   ├── EntraGroupResource.php
│   │   └── AlertDeliveryResource.php
│   └── Widgets/
│       ├── Inventory/
│       │   └── InventoryKpiHeader.php
│       └── Operations/
├── Models/
└── Policies/

tests/
├── Feature/
│   ├── Guards/
│   ├── Filament/
│   ├── Monitoring/
│   └── Spec085/
└── Unit/
```

**Structure Decision**: Keep implementation inside the existing Laravel / Filament monolith. Reuse `OperateHubShell`, `CanonicalAdminTenantFilterState`, and the existing admin-aware search trait instead of adding new infrastructure. Harden affected resources, pages, and widgets in place, then extend the current Pest guard and feature coverage.

## Phase 2 — Implementation Planning

Implementation should be delivered in the following slices so `/speckit.tasks` can break work cleanly.

1. **Freeze the final surface inventory and classifications**
  - Use `AdminPanelProvider`, direct admin page registration, and shared resource reachability to finalize the rollout manifest.
  - Classify each target as Type A hard tenant-sensitive, Type B workspace-wide with tenant-default, or Type C workspace-only.
  - Keep tenant-only resources in the rollout only where shared code, admin deep links, cross-resource URLs, or dual-panel discovery can still create admin-path drift.

2. **Standardize support-layer resolver usage**
  - Keep `OperateHubShell::activeEntitledTenant(Request)` as the only public canonical admin tenant resolver.
  - Avoid introducing a second public resolver abstraction unless it is a thin, internal delegation wrapper for readability only.
  - Audit direct admin-path usages of `Tenant::current()` and `Filament::getTenant()` across the rollout set.

3. **Roll out persisted filter-state hardening**
  - Apply `CanonicalAdminTenantFilterState::sync()` to every affected admin surface that combines `persistFiltersInSession()` with tenant-related filters or tenant-default behavior.
  - Standardize stale-session behavior so old tenant state is cleared or reseeded before the surface renders.
  - Reuse `AlertDeliveryResource` and `AuditLog` as known-good reference patterns.

4. **Wave 1: high-risk tenant-sensitive resources**
  - Harden `PolicyResource`, `BackupScheduleResource`, `BackupSetResource`, and `FindingResource` so query, detail, filters, links, and sensitive actions align to the same tenant.
  - Verify destructive or governance-sensitive actions retain confirmation and server-side authorization while gaining tenant-target parity.

5. **Wave 2: governance, restore, and inventory alignment**
  - Harden `BaselineCompareLanding`, `RestoreRunResource`, `InventoryItemResource`, and `PolicyVersionResource`.
  - Treat `InventoryCoverage` and `InventoryKpiHeader` as one unit so page and widget cannot diverge.
  - Review `RestoreRunResource` and other shared tenant resources as panel-aware code paths even where admin navigation is intentionally absent.

6. **Wave 3: workspace-wide tenant-default, diagnostics, and search parity**
  - Harden `ProviderConnectionResource`, `TenantDiagnostics`, `AuditLog`, and `EntraGroupResource` follow-up behavior.
  - Keep workspace-wide datasets workspace-wide while synchronizing tenant-default labels, filters, deep links, and persisted state.
  - Preserve or explicitly disable admin-path global search where parity is not safe.

7. **Expand the guardrail and developer guidance**
  - Extend `AdminTenantResolverGuardTest` to the full rollout surface set.
  - Maintain a narrow, explicit exception inventory for tenant-panel-native files and other approved panel-native surfaces.
  - Update short developer guidance so future admin surfaces reuse the canonical rule and synchronized filter-state pattern.

8. **Finish with regression coverage and manual tenant-switch verification**
  - Add direct tests for `CanonicalAdminTenantFilterState`.
  - Add focused feature tests for wrong-tenant drift, stale filters, shared-surface panel behavior, search parity, and wrong-tenant sensitive-action prevention.
  - Record a manual tenant-switch check per rollout wave for representative Type A and Type B surfaces.

## Testing Strategy

- Extend `tests/Feature/Guards/AdminTenantResolverGuardTest.php` to cover the full rollout manifest and exceptions.
- Add direct unit or feature coverage for `CanonicalAdminTenantFilterState` behavior on tenant change, stale state, and invalid persisted state.
- Add focused feature coverage for:
  - `PolicyResource`, `BackupScheduleResource`, `BackupSetResource`, and `FindingResource` tenant parity across list/detail/action paths,
  - `BaselineCompareLanding`, `InventoryCoverage`, and `InventoryKpiHeader` page-widget alignment,
  - `RestoreRunResource`, `InventoryItemResource`, and `PolicyVersionResource` shared resource parity across panel modes,
  - `ProviderConnectionResource`, `AuditLog`, and `EntraGroupResource` workspace-wide tenant-default behavior and search or deep-link safety,
  - representative 404 vs 403 authorization semantics for admin-path tenant-sensitive access.
- Reuse existing Pest helpers, factories, and workspace or tenant session setup; avoid bespoke harnesses.
- Run the minimum affected suite with Sail during implementation, then finish with `vendor/bin/sail bin pint --dirty --format agent`.

## Complexity Tracking

No constitution violations or complexity exemptions are required for this plan.
