TenantAtlas/specs/302-tenant-owned-surface-route-audit/plan.md
ahmido d072b0107b feat(specs/302): tenant owned surface route audit (#357)
Implements platform feature branch `302-tenant-owned-surface-route-audit`.

Target branch: `platform-dev`.

Follow-up integration path after merge:

`platform-dev` → `dev`.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #357
2026-05-14 21:14:59 +00:00

12 KiB

Implementation Plan: Tenant-Owned Surface Route Audit

Branch: 302-tenant-owned-surface-route-audit | Date: 2026-05-14 | Spec: spec.md Input: Feature specification from /specs/302-tenant-owned-surface-route-audit/spec.md

Summary

Produce a repo-verified audit matrix for tenant-owned admin surfaces after the Inventory navigation cutover. The implementation is docs/spec-artifact only: create surface-route-audit.md, classify each audited surface against existing route/navigation/context/global-search/RBAC contracts, cite current tests or gaps, and recommend a bounded follow-up repair order. No application runtime code changes are in scope.

Technical Context

Language/Version: PHP 8.4.15 for inspected application code; Markdown for delivered audit artifact Primary Dependencies: Laravel 12.52.0, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1 Storage: PostgreSQL in the application; N/A for this docs-only audit slice Testing: Existing Pest feature tests; no new tests required by this spec Validation Lanes: confidence for focused existing Filament tests; git diff --check for artifact hygiene Target Platform: Laravel Sail local development; Dokploy deployment unaffected Project Type: Laravel/Filament application with Spec Kit artifacts under specs/ Performance Goals: N/A; no runtime behavior changes Constraints: No application code changes; no route enablement; no navigation changes; no global-search enablement; no migrations; no assets Scale/Scope: Tenant-owned admin surface inventory, starting from TenantOwnedModelFamilies and admin Filament resources/pages/tests

UI / Surface Guardrail Plan

  • Guardrail scope: no operator-facing surface change; audit/prep artifact only
  • Native vs custom classification summary: N/A for runtime; existing surfaces are inspected, not changed
  • Shared-family relevance: navigation, route generation, global search, authorization, relation entry points
  • State layers in scope: route context, shell/navigation posture, global-search scope, RBAC posture as audited facts only
  • Audience modes in scope: internal product owner / implementer / reviewer
  • Decision/diagnostic/raw hierarchy plan: default-visible matrix fields first; source-file and test evidence second
  • Raw/support gating plan: N/A; no product data or raw tenant payloads included
  • One-primary-action / duplicate-truth control: one recommended next action per surface row
  • Handling modes by drift class or surface: document-in-feature for contained findings; follow-up-spec for runtime repair; reject-or-split for broad migration bundles
  • Repository-signal treatment: review-mandatory for stale navigation/search/RBAC signals; report-only for unrelated code quality findings
  • Special surface test profiles: standard-native-filament for referenced existing surfaces
  • Required tests or manual smoke: existing focused Pest tests only; no browser smoke because no UI changes
  • Exception path and spread control: no runtime exception; document-only classification labels stay inside the audit artifact
  • Active feature PR close-out entry: Guardrail

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes, audit touches shared route/navigation/search/RBAC concepts
  • Systems touched:
    • apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php
    • apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php
    • apps/platform/app/Support/Navigation/NavigationScope.php
    • apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php
    • apps/platform/app/Support/OperateHub/OperateHubShell.php
    • apps/platform/routes/web.php
    • apps/platform/app/Filament/Resources/
    • apps/platform/app/Filament/Pages/
    • apps/platform/tests/Feature/Filament/
  • Shared abstractions reused: N/A at runtime; the audit measures each surface against the existing helpers above
  • New abstraction introduced? why?: none
  • Why the existing abstraction was sufficient or insufficient: the audit records sufficiency per surface; it must not introduce replacement machinery
  • Bounded deviation / spread control: document-only migration-state labels; no executable classification layer

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: no
  • Central contract reused: N/A
  • Delegated UX behaviors: N/A
  • Surface-owned behavior kept local: existing run links may be mentioned as evidence but are not changed
  • Queued DB-notification policy: N/A
  • Terminal notification path: N/A
  • Exception path: none

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: no runtime boundary change
  • Provider-owned seams: Entra Groups and provider-specific diagnostics may appear as audited surface names only
  • Platform-core seams: workspace/environment route context, navigation scope, tenant-owned global-search scope, RBAC semantics
  • Neutral platform terms / contracts preserved: workspace, managed environment, tenant-owned surface, route posture, navigation posture, repair blocker
  • Retained provider-specific semantics and why: provider-specific surface names remain contextual to the audited resource/page
  • Bounded extraction or follow-up path: follow-up-spec if the audit finds provider-specific semantics leaking into platform-core route or search contracts

Constitution Check

GATE: Must pass before implementation. Re-check after audit artifact is produced.

  • Inventory-first: audit only; no Inventory, snapshot, backup, or provider truth changes.
  • Read/write separation: read-only repo audit; no write/change function.
  • Graph contract path: no Microsoft Graph calls or contract changes.
  • Deterministic capabilities: audit records existing capability posture; no resolver changes.
  • RBAC-UX: audit must record non-member 404 versus member-missing-capability 403 expectations and server-side proof separately from UI visibility.
  • Workspace isolation: audit must distinguish workspace-home cleanliness from environment-bound visibility.
  • Tenant isolation: audit must identify tenant-owned surfaces that need workspace plus managed-environment entitlement.
  • Run observability: no OperationRun creation or lifecycle change.
  • Test governance: existing focused tests are evidence; missing proof is documented as a gap, not hidden by new broad tests.
  • Proportionality: one audit artifact is narrower than a route/navigation framework or broad migration.
  • No premature abstraction: no new registry, resolver, strategy, or framework.
  • Persisted truth: no runtime persistence; the audit is repair evidence only.
  • Behavioral state: migration-state labels are document-only and must not become product state.
  • Shared pattern first: the audit measures current usage of existing shared helpers before recommending any new work.
  • Provider boundary: provider-specific surfaces remain named only where current repo truth requires them.
  • Filament-native UI: no UI is changed; future repairs must preserve Filament v5 and Livewire v4 conventions.
  • Filament v5 / Livewire v4 compliance: the plan does not introduce Livewire v3 references or legacy Filament APIs.
  • Provider registration location: no provider registration changes; Laravel provider registration remains in apps/platform/bootstrap/providers.php.
  • Global search rule: the audit must record every globally searchable resource's Edit/View-page eligibility or disabled posture.
  • Destructive actions: none are added or changed; any surface with destructive actions is inspected only for follow-up risk.
  • Asset strategy: no assets are registered; deploy-time filament:assets requirements are unchanged.

Test Governance Check

  • Test purpose / classification by changed surface: N/A for runtime; confidence evidence from existing Feature tests
  • Affected validation lanes: confidence and diff-check only
  • Why this lane mix is the narrowest sufficient proof: the deliverable is an audit artifact; existing feature tests and source references prove current posture
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Filament/AdminTenantSurfaceParityTest.php tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php
    • git diff --check
  • Fixture / helper / factory / seed / context cost risks: none
  • Expensive defaults or shared helper growth introduced?: no
  • Heavy-family additions, promotions, or visibility changes: none
  • Surface-class relief / special coverage rule: standard-native-filament relief; no new browser proof
  • Closing validation and reviewer handoff: reviewers should verify the matrix evidence, runtime no-change boundary, and follow-up split
  • Budget / baseline / trend follow-up: none
  • Review-stop questions: Did any task edit app code? Does every row cite repo evidence? Are runtime bugs documented as follow-ups?
  • Escalation path: document-in-feature for audit findings; follow-up-spec for runtime repair
  • Active feature PR close-out entry: Guardrail
  • Why no dedicated follow-up spec is needed: this spec is the audit; surface-specific repairs become separate specs only after the matrix identifies them

Project Structure

Documentation (this feature)

specs/302-tenant-owned-surface-route-audit/
├── checklists/
│   └── requirements.md
├── plan.md
├── spec.md
├── surface-route-audit.md   # Created during implementation, not preparation
└── tasks.md

Source Code (repository root)

apps/platform/app/Filament/
├── Concerns/
├── Pages/
└── Resources/

apps/platform/app/Support/
├── Navigation/
├── OperateHub/
└── WorkspaceIsolation/

apps/platform/routes/web.php
apps/platform/tests/Feature/Filament/

Structure Decision: The implementation edits only the spec package. Application files and tests are inspected as evidence and remain unchanged.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
Document-only classification labels The audit needs consistent row states to compare surfaces Freeform prose would make repair ordering harder to review

Implementation Phases

Phase 1 - Preparation and Scope Lock

Confirm Spec 301 is completed context, verify no 302 package existed before this branch, and keep the implementation boundary to the spec package.

Phase 2 - Surface Inventory

Build the initial surface set from TenantOwnedModelFamilies::firstSlice(), residual inventory, scope exceptions, Filament resources/pages, route files, and focused tests.

Phase 3 - Posture Classification

For each surface, classify route posture, navigation posture, context source, global-search posture, RBAC posture, evidence, blocker, migration state, and recommended next action.

Phase 4 - Repair Order

Convert findings into a bounded repair order. Keep Entra Groups cutover, navigation contract split, tenant-panel dead-code retirement, and any surface-specific repairs as separate recommendations.

Phase 5 - Validation and Close-Out

Run the existing focused tests when available, run git diff --check, verify no application files changed, and record any failures as audit findings or blockers.

Rollout Considerations

  • No environment variables.
  • No database migrations.
  • No queues or scheduled workers.
  • No storage or volume changes.
  • No Dokploy runtime impact.
  • No filament:assets change.
  • Staging/production validation is N/A unless a later repair spec changes runtime behavior.

Risk Controls

  • Stop if implementation requires runtime code changes; promote a separate repair spec instead.
  • Do not treat document classification labels as product states.
  • Do not revive /admin/t/{tenant} or /admin/tenants/{tenant} routes.
  • Do not change tests that encode current behavior; document stale tests as findings.
  • Keep all follow-up recommendations scoped as bounded candidates.