TenantAtlas/specs/136-admin-canonical-tenant/spec.md
ahmido 45a804970e feat: complete admin canonical tenant rollout (#165)
## Summary
- complete Spec 136 canonical admin tenant rollout across admin-visible and shared Filament surfaces
- add the shared panel-aware tenant resolver helper, persisted filter-state synchronization, and admin navigation segregation for tenant-sensitive resources
- expand regression, guard, and parity coverage for admin-path tenant resolution, stale filters, workspace-wide tenant-default surfaces, and panel split behavior

## Validation
- `vendor/bin/sail artisan test --compact tests/Feature/Guards/AdminTenantResolverGuardTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TableStatePersistenceTest.php`
- `vendor/bin/sail artisan test --compact --filter='CanonicalAdminTenantFilterState|PolicyResource|BackupSchedule|BackupSet|FindingResource|BaselineCompareLanding|RestoreRunResource|InventoryItemResource|PolicyVersionResource|ProviderConnectionResource|TenantDiagnostics|InventoryCoverage|InventoryKpiHeader|AuditLog|EntraGroup'`
- `vendor/bin/sail bin pint --dirty --format agent`

## Notes
- Livewire v4.0+ compliance is preserved with Filament v5.
- Provider registration remains unchanged in `bootstrap/providers.php`.
- `PolicyResource` and `PolicyVersionResource` have admin global search disabled explicitly; `EntraGroupResource` keeps admin-aware scoped search with a View page.
- Destructive and governance-sensitive actions retain existing confirmation and authorization behavior while using canonical tenant parity.
- No new assets were introduced, so deployment asset strategy is unchanged and does not add new `filament:assets` work.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #165
2026-03-13 08:09:20 +00:00

23 KiB

Feature Specification: Admin Panel Canonical Tenant Resolution Full Rollout

Feature Branch: 136-admin-canonical-tenant
Created: 2026-03-11
Status: Draft
Input: User description: "Spec 136 — Admin Panel Canonical Tenant Resolution Full Rollout"

Spec Scope Fields (mandatory)

  • Scope: canonical-view
  • Primary Routes:
    • Workspace-admin tenant-sensitive resources and pages under /admin/...
    • Workspace-admin list, detail, widget, KPI, filter, and deep-link flows that expose tenant-bound semantics under /admin/...
    • Tenant-panel flows under /admin/t/{tenant}/... only where shared code must preserve panel-native tenant behavior while admin flows adopt the canonical admin rule
  • Data Ownership:
    • Workspace-admin shells, navigation, and workspace-owned operational surfaces remain workspace-owned
    • Workspace-admin navigation exposes only workspace-wide surfaces and workspace-owned baseline assets; tenant-sensitive navigation entry points live under /admin/t/{tenant}/...
    • Tenant-sensitive records shown in admin flows remain unchanged in storage and ownership; this feature only standardizes how their active tenant context is resolved, displayed, filtered, and enforced
    • No new business domain is added; the feature completes rollout of one canonical tenant-context rule across the named admin surfaces and their guard coverage
  • RBAC:
    • Workspace membership remains required for workspace-admin access
    • Tenant entitlement remains required before tenant-sensitive data or actions can be shown or executed in admin flows
    • Capability checks continue to gate protected actions on the affected resources and pages
    • Non-members and out-of-scope tenant access remain deny-as-not-found, while entitled users without the required capability remain forbidden on protected actions

For canonical-view specs, the spec MUST define:

  • Default filter behavior when tenant-context is active: Admin flows that remain workspace-wide but show a tenant-default must seed the default tenant filter, filter labels, header context, deep links, and persisted filter state from the same canonical admin tenant. Hard tenant-sensitive admin flows must either use that same tenant consistently everywhere on the surface or show an explicit no-tenant-selected safe state.
  • Explicit entitlement checks preventing cross-tenant leakage: Every in-scope admin query, filter option set, KPI, widget, record lookup, search result, and sensitive action must validate workspace membership and tenant entitlement against the same canonical tenant context before data is shown or acted on. No direct link, persisted filter, or action target may broaden scope beyond that entitled tenant.

User Scenarios & Testing (mandatory)

User Story 1 - Trust the active tenant everywhere (Priority: P1)

As an admin operator, I want the visible tenant context, data results, KPIs, and actions on a tenant-sensitive admin surface to all point to the same tenant so that I do not make decisions or changes against the wrong tenant.

Why this priority: This is the core safety and correctness problem. If a surface can drift between header context, list data, and actions, every downstream workflow becomes unreliable.

Independent Test: Can be fully tested by opening each representative tenant-sensitive admin surface after selecting a tenant and verifying that header context, table data, widgets, drill-down links, and sensitive actions all align to the same tenant.

Acceptance Scenarios:

  1. Given an operator has an active entitled tenant in the workspace-admin shell, When they open a hard tenant-sensitive admin surface, Then the page header, query results, KPIs, widgets, and links all use that same tenant.
  2. Given a tenant-sensitive admin surface includes a sensitive row action, When the operator triggers that action, Then the action operates on the same tenant context that the surface visibly represents.
  3. Given no valid entitled tenant is active for a hard tenant-sensitive admin surface, When the operator opens that surface, Then the surface returns a defined safe no-tenant-selected outcome instead of silently broadening scope.

User Story 2 - Switch tenants without stale filters (Priority: P1)

As an admin operator, I want persisted filters and tenant-default views to update deterministically when I switch tenant context so that I never keep seeing stale data from a previously selected tenant.

Why this priority: Persisted filter drift is one of the known failure modes and can silently produce misleading tables, counts, and follow-on actions.

Independent Test: Can be fully tested by persisting a tenant-related filter for Tenant A, switching to Tenant B, and reloading representative Type A and Type B surfaces to verify that stale filter state is cleared or reseeded consistently.

Acceptance Scenarios:

  1. Given a tenant-related filter is persisted for Tenant A, When the operator switches the canonical admin tenant to Tenant B and reloads the surface, Then the stale filter state is cleared or replaced so the table and header match Tenant B.
  2. Given a workspace-wide admin surface uses a tenant-default filter, When the operator switches tenant, Then the visible default tenant, filter state, and deep links all update to the new canonical admin tenant without changing the base workspace-wide dataset.
  3. Given a persisted tenant-related filter references a tenant the operator no longer has access to, When the surface loads, Then the invalid persisted filter state is not reused.

User Story 3 - Preserve panel-specific tenant rules (Priority: P2)

As a maintainer, I want admin-panel flows and tenant-panel flows to keep their distinct tenant-resolution rules so that fixing the admin drift bug does not break tenant-panel behavior that already depends on panel-native routing.

Why this priority: The rollout touches shared resources and widgets that can be discovered in more than one panel. Separation between panel rules is required to avoid regressions.

Independent Test: Can be fully tested by exercising representative shared surfaces in both the workspace-admin path and the tenant-panel path and verifying that each path uses its intended tenant rule without cross-contamination.

Acceptance Scenarios:

  1. Given a shared surface is opened in the workspace-admin panel, When it resolves tenant context, Then it uses the canonical admin tenant rule.
  2. Given the same or related surface is opened in the tenant panel, When it resolves tenant context, Then it preserves tenant-panel-native behavior.
  3. Given a workspace-only admin surface has no tenant-sensitive semantics, When the page renders, Then no artificial tenant enforcement is applied.

User Story 4 - Catch regressions before merge (Priority: P3)

As a maintainer, I want guard coverage and focused regression tests across all relevant admin tenant-sensitive surfaces so that future changes cannot quietly reintroduce mixed tenant sources.

Why this priority: The defect class is architectural. Without broad enforcement, the same bug can return surface by surface.

Independent Test: Can be fully tested by running the guard suite plus focused regression coverage for representative resources, filters, widgets, and sensitive actions across the rollout set.

Acceptance Scenarios:

  1. Given a new or modified admin tenant-sensitive surface introduces a forbidden tenant resolver in the admin path, When the guard suite runs, Then the change is flagged before release.
  2. Given a formerly mixed resource is exercised through list, detail, widget, and action flows, When the regression suite runs, Then all covered tenant-sensitive paths remain aligned.

Edge Cases

  • A resource or widget may be discoverable in both the workspace-admin panel and the tenant panel and must honor the correct rule in each path.
  • A persisted tenant filter may reference an old tenant after the operator switches tenant context between requests.
  • A workspace-wide surface may correctly remain workspace-wide while still showing a tenant-default header or filter state that must stay synchronized.
  • A hard tenant-sensitive surface may be opened directly from a bookmarked detail link without first loading the list page.
  • A sensitive action may be available from a page that also shows tenant-driven widgets or counts, and all of those elements must align to the same tenant.
  • A workspace-only surface may display tenant context for navigation or orientation only and must not accidentally turn that decorative context into query scope.

Requirements (mandatory)

Constitution alignment (required): This feature does not introduce new Microsoft Graph calls, new queued work, or new scheduled work. It standardizes tenant-context resolution, filter synchronization, and guard coverage for existing workspace-admin and tenant-panel surfaces. Existing destructive behaviors remain destructive and must keep their existing confirmation, authorization, and audit expectations.

Constitution alignment (OPS-UX): This feature does not create or mutate OperationRun lifecycles. If in-scope monitoring or operational surfaces read existing run data, they must remain display-only changes to tenant alignment, filter state, and regression protection.

Constitution alignment (RBAC-UX): This feature affects workspace-admin /admin/... flows and tenant-context /admin/t/{tenant}/... flows where shared files exist. Cross-plane access remains deny-as-not-found. Non-members and non-entitled tenant access remain deny-as-not-found. Entitled users without the required capability remain forbidden on protected mutations. Authorization remains server-side for list queries, filter option sets, record resolution, deep links, search results, and sensitive actions. No raw capability strings or role-name shortcuts may be introduced. Existing destructive actions remain confirmation-gated.

Constitution alignment (OPS-EX-AUTH-001): Not applicable. No authentication handshake behavior is added or changed.

Constitution alignment (BADGE-001): If in-scope pages or widgets show status-like badges or KPI states, their meanings remain centralized. This feature only aligns the tenant context behind those surfaces.

Constitution alignment (UI-NAMING-001): Operator-facing headers, filter labels, safe-state messages, and navigation copy must consistently describe the active tenant using existing product vocabulary. Implementation-first tenant-resolution terms must not become primary operator-facing copy.

Constitution alignment (Filament Action Surfaces): This feature modifies existing Filament Resources, Pages, and Widgets. The Action Surface Contract remains satisfied because the rollout focuses on read, filter, navigation, and safety alignment. No new destructive action is introduced. Existing destructive actions on the affected surfaces remain subject to confirmation and authorization rules.

Constitution alignment (UX-001 — Layout & Information Architecture): In-scope Filament screens keep their established layouts and information architecture, except that /admin navigation is intentionally simplified to workspace-owned surfaces while tenant-sensitive entry points move to /admin/t/{tenant}/.... The required change is consistency of tenant context, explicit safe no-tenant outcomes where applicable, and deterministic tenant-default state on workspace-wide surfaces.

Functional Requirements

  • FR-136-01 Canonical admin resolver: The product must define one canonical tenant source for workspace-admin tenant-sensitive surfaces and require those surfaces to use it for visible context, queries, filters, widgets, actions, and deep links.
  • FR-136-02 No mixed admin sources: A single workspace-admin surface must not combine more than one tenant resolver for header context, query scope, widget scope, default filters, record lookup, or action execution.
  • FR-136-03 Tenant-panel preservation: Tenant-panel flows must preserve their existing panel-native tenant rule and must not be forced into workspace-admin semantics.
  • FR-136-04 Surface classification: Every admin-visible surface touched by this rollout must be explicitly classified as hard tenant-sensitive, workspace-wide with tenant-default, or workspace-only.
  • FR-136-05 Hard tenant-sensitive rule: Every hard tenant-sensitive admin surface must use the same canonical tenant for header context, query results, KPIs, widgets, drill-down links, record lookup, and actions, or show a safe no-tenant-selected state.
  • FR-136-06 Workspace-wide tenant-default rule: Every workspace-wide admin surface with tenant-default behavior must keep its base dataset workspace-wide while ensuring that header context, default filters, persisted filter state, and deep links are synchronized to the canonical admin tenant.
  • FR-136-07 Workspace-only rule: Workspace-only admin surfaces must remain free of hidden tenant scoping in their read and write paths.
  • FR-136-08 Persisted filter synchronization: Admin surfaces with persisted tenant-related filters must revalidate and synchronize persisted state whenever the canonical admin tenant changes.
  • FR-136-09 Invalid filter-state handling: Persisted tenant-related filter state that references a stale, inaccessible, or mismatched tenant must be cleared or replaced before the surface renders tenant-sensitive data.
  • FR-136-10 Query-to-action parity: Sensitive row actions, bulk actions, and page-level actions must never operate on a different tenant than the tenant used to produce the visible list, detail view, or widget context.
  • FR-136-11 Record-resolution parity: Direct record lookup, detail views, and deep links for affected admin surfaces must use the same tenant rule as the corresponding list and widget flows.
  • FR-136-12 Search parity: Search entry points for affected admin tenant-sensitive surfaces must obey the same tenant and entitlement boundaries as their list and detail flows, or be explicitly excluded.
  • FR-136-13 Shared-surface safety: Shared resources, pages, and widgets that can render in more than one panel must apply the correct tenant rule for the current panel without leaking state or semantics across panels.
  • FR-136-14 Rollout coverage: The rollout must cover at minimum PolicyResource, BackupScheduleResource, BackupSetResource, FindingResource, BaselineCompareLanding, RestoreRunResource, InventoryItemResource, PolicyVersionResource, ProviderConnectionResource, TenantDiagnostics, InventoryKpiHeader, AuditLog guard follow-up, and EntraGroupResource filter-state follow-up where tenant-persisted filters apply.
  • FR-136-15 Mixed-resource cleanup: Known mixed-source resources, including backup, finding, governance, restore, and inventory surfaces in the rollout set, must eliminate cross-source drift between list, detail, widget, and action paths.
  • FR-136-16 Guard enforcement: The architectural guard must cover the full target set of relevant workspace-admin tenant-sensitive surfaces and fail when a forbidden admin-path tenant resolver appears.
  • FR-136-17 Direct filter-state tests: The rollout must add direct behavior coverage for tenant-filter synchronization, stale-state detection, and deterministic reseeding or clearing.
  • FR-136-18 Regression scenarios: The rollout must include focused regression coverage for wrong-tenant drift, stale persisted filters, widget-page alignment, and wrong-tenant sensitive-action prevention.
  • FR-136-19 Documentation rule: The developer guidance for future admin surfaces must state that workspace-admin tenant-sensitive flows use the canonical admin rule, tenant-panel flows use the panel-native rule, and persisted tenant filters must be synchronized.
  • FR-136-20 No hidden fallback mutations: A destructive or governance-sensitive admin action must not execute through an implicit tenant fallback when the surface does not visibly and deterministically establish that tenant context.
  • FR-136-21 Workspace navigation split: /admin must not register navigation items for hard tenant-sensitive surfaces. Those entry points must live in the tenant panel, while BaselineProfileResource and BaselineSnapshotResource remain in workspace-admin navigation because they are workspace assets.

Non-Goals

  • Redesigning the tenant panel or changing its routing model
  • Creating a universal context engine for every panel or non-web runtime
  • Refactoring unrelated CLI, queue, or scheduled contexts that are not part of admin-path tenant drift
  • Expanding governance, backup, restore, or inventory product scope beyond tenant-context alignment
  • Reworking workspace-first or tenant-drilldown information architecture beyond what is needed to keep semantics consistent

Assumptions

  • Spec 135 already established the intended canonical admin pattern and this feature is a rollout and enforcement completion rather than a new conceptual design.
  • Some resources and widgets are discovered in more than one panel and therefore require explicit panel-aware behavior rather than one generic rule.
  • Workspace-wide admin surfaces can remain workspace-wide while still using a deterministic tenant-default for filters, header context, and deep links.
  • Existing destructive actions on in-scope resources already have their domain-specific confirmations and authorizations; this feature ensures those actions cannot drift to the wrong tenant.

Dependencies

  • Existing workspace membership and tenant entitlement enforcement in admin and tenant-panel flows
  • Existing canonical admin shell state and remembered tenant behavior used by workspace-admin navigation
  • Existing tenant-sensitive filter persistence behavior on affected resources and pages
  • Existing architectural guard coverage that can be extended to the broader rollout set
  • Existing focused tests around admin resources, filters, widgets, and sensitive actions that can be expanded for regression protection

UI Action Matrix (mandatory when Filament is changed)

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
Type A tenant-sensitive resources (PolicyResource, BackupScheduleResource, BackupSetResource, FindingResource, RestoreRunResource, InventoryItemResource, PolicyVersionResource) Workspace-admin resource lists and details under /admin/... Existing header actions unchanged Table rows, record views, and detail pages remain the inspect affordances Existing inspect or domain actions only Existing grouped bulk actions only Existing empty states plus explicit safe no-tenant state where required Existing view actions only Existing create or edit semantics remain unchanged Existing audit behavior only This rollout aligns tenant context across list, detail, widgets, and actions; it does not add new mutations.
Type A governance pages (BaselineCompareLanding, TenantDiagnostics) Workspace-admin pages under /admin/... Existing non-destructive header actions only KPI cards, comparison summaries, diagnostic panels Existing inspect or drill-down actions only None new Existing empty states plus explicit safe no-tenant state where required Existing page actions only N/A unless already present Existing audit behavior only Page-level queries, widgets, and drill-down links must use one tenant source.
Type B workspace-wide surfaces (ProviderConnectionResource, AuditLog, EntraGroupResource follow-up where tenant defaults apply) Workspace-admin lists under /admin/... Existing header actions unchanged Workspace-wide tables with tenant-default filters remain the inspect affordance Existing inspect actions only Existing grouped bulk actions only Existing empty states remain Existing view actions only Existing create or edit semantics remain unchanged Existing audit behavior only Base dataset remains workspace-wide; tenant-default state, filter persistence, and deep links must remain synchronized.
Embedded widget surfaces (InventoryKpiHeader and related tenant-sensitive KPI or coverage widgets) Workspace-admin widgets embedded in parent pages None new KPI cards and linked drill-downs Linked drill-downs only where already present None N/A N/A N/A No new audit event Widgets must follow the same tenant source as the parent admin surface and must not silently use a different resolver.

Key Entities (include if feature involves data)

  • Canonical Admin Tenant Context: The single tenant context used by workspace-admin tenant-sensitive flows to align what the operator sees with what the system queries and acts on.
  • Tenant-Default Workspace Surface: A workspace-wide admin surface that stays workspace-wide in base scope but still uses the canonical admin tenant to seed defaults, labels, and deep links.
  • Workspace-Only Surface: An admin surface whose semantics are owned by the workspace and must not acquire hidden tenant scoping.
  • Persisted Tenant Filter State: Session-backed filter state whose validity depends on the current canonical admin tenant and the operator's entitlement.
  • Mixed-Source Drift: A defect state where header context, query scope, widget scope, record lookup, or action execution derive tenant meaning from different sources.
  • Sensitive Tenant Action Path: A destructive or governance-relevant action flow whose tenant target must exactly match the tenant visible on the surrounding admin surface.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-136-01 Surface alignment: In focused rollout coverage, 100% of representative hard tenant-sensitive admin surfaces render one consistent tenant context across header, data, widgets, links, and actions for the covered scenarios.
  • SC-136-02 Filter-state determinism: In focused filter-state coverage, 100% of covered tenant switches clear or reseed stale persisted tenant filters before tenant-sensitive data is rendered.
  • SC-136-03 Wrong-tenant action prevention: In focused sensitive-action coverage, 100% of covered destructive or governance-sensitive actions execute only against the same tenant shown on the surrounding surface or are blocked safely.
  • SC-136-04 Workspace-wide preservation: In focused coverage for workspace-wide tenant-default surfaces, 100% of covered scenarios preserve workspace-wide base datasets while keeping tenant-default headers, filters, and links synchronized.
  • SC-136-05 Guard breadth: The architectural guard explicitly covers the full rollout surface set and fails on any newly introduced forbidden admin-path tenant resolver in the covered classes.
  • SC-136-06 Panel regression safety: In focused dual-panel coverage for shared surfaces, 100% of covered tenant-panel scenarios preserve panel-native behavior while covered admin-panel scenarios use the canonical admin rule.
  • SC-136-07 Developer clarity: A maintainer can determine the correct tenant rule for a new admin surface, a tenant-panel surface, and a persisted tenant filter from the feature spec and follow-up guidance without reading implementation code first.