# Implementation Plan: Livewire Context Locking and Trusted-State Reduction **Branch**: `152-livewire-context-locking` | **Date**: 2026-03-18 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/152-livewire-context-locking/spec.md` **Input**: Feature specification from `/specs/152-livewire-context-locking/spec.md` ## Summary Harden the repo's most stateful Livewire and Filament surfaces so public component state remains useful for continuity and UX, but never becomes authority for protected actions. The implementation will establish a three-lane trusted-state model, replace or constrain ownership-relevant public state on the first-slice surfaces, reuse existing canonical resolver seams for workspace, tenant, draft, and selector validation, and back the rollout with forged-state regression tests plus a lightweight guard extension. ## Technical Context **Language/Version**: PHP 8.4.15 **Primary Dependencies**: Laravel 12, Filament v5, Livewire v4, PostgreSQL, Laravel Sail, Pest v4 **Storage**: PostgreSQL with existing workspace-, tenant-, onboarding-, and audit-related tables; no new persistent storage planned for the first slice **Testing**: Pest feature tests, Livewire component tests, existing architectural guard tests, optional browser coverage where onboarding refresh semantics are already exercised **Target Platform**: Laravel web application running locally via Sail and deployed via Dokploy **Project Type**: Web application **Performance Goals**: No material regression to first-slice page render paths; protected actions remain DB-only until they intentionally reuse existing operation starts; no extra broad resolver queries per request beyond canonical scope re-resolution **Constraints**: Preserve 404 vs 403 semantics, keep `/admin` and `/system` plane separation intact, do not add new panels/routes/assets, avoid noisy repo-wide refactors in the first slice, and keep onboarding resume UX stable **Scale/Scope**: First slice limited to three representative stateful families: onboarding wizard, one tenant-context page, and one system page, plus shared guard seams for future expansion ### Filament v5 Implementation Notes - **Livewire v4.0+ compliance**: Maintained. This feature hardens Livewire public state and action resolution patterns within the existing Filament v5 + Livewire v4 stack. - **Provider registration location**: No new panel is introduced. Existing panel providers remain registered in `bootstrap/providers.php`. - **Global search rule**: No new globally searchable resource is added or modified. Existing global search rules remain unchanged. - **Destructive actions**: Existing destructive actions in covered surfaces, such as onboarding draft cancellation and runbook execution confirmation, remain explicit and confirmed; this plan changes only how targets are resolved before execution. - **Asset strategy**: No new shared or on-demand assets are planned. Deployment remains unchanged, including `php artisan filament:assets` where already part of the deploy flow. - **Testing plan**: Add focused Pest feature and Livewire coverage for forged-state attempts, stale identifier paths, selector revalidation, and guard regressions on the first-slice surfaces. ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first: PASS. This feature does not alter inventory or snapshot ownership; it hardens UI state trust boundaries. - Read/write separation: PASS. Existing writes remain explicit, confirmation-gated where required, auditable, and test-covered. - Graph contract path: PASS. No new Graph calls or contract-registry changes are introduced. - Deterministic capabilities: PASS. Existing capability registries and authorization helpers remain canonical. - RBAC-UX plane separation: PASS. The first slice explicitly spans `/admin` and `/system` while preserving deny-as-not-found between planes. - Workspace isolation: PASS. Workspace context remains the canonical source for admin-plane scope and must outrank client-submitted state. - Tenant isolation: PASS. Tenant resolution remains route- or resolver-backed and is rechecked before protected actions. - Destructive confirmation standard: PASS. Existing destructive-like actions keep `->requiresConfirmation()` and server-side authorization. - Global search tenant safety: PASS. No global-search behavior changes. - Run observability: PASS. The feature does not introduce new `OperationRun` types; existing operation-backed actions continue to use their established flow after trusted target re-resolution. - Data minimization: PASS WITH WORK. Moving away from public Eloquent model state reduces exposed class and relationship metadata on covered surfaces. - BADGE-001: PASS. No badge taxonomy changes. - UI-NAMING-001: PASS. No new operator-facing vocabulary beyond existing domain labels. - Filament Action Surface Contract: PASS. Existing action surfaces remain intact; only target-resolution internals change. - Filament UX-001: PASS. No new screens or information architecture changes. **Phase 0 Gate Result**: PASS - The feature is bounded to state trust and authorization-safe target resolution. - No new route, panel, Graph, or asset path is introduced. - Existing authorization and audit rules remain in force and are reinforced by the trust-boundary model. ## Project Structure ### Documentation (this feature) ```text specs/152-livewire-context-locking/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ ├── trusted-state-logical.openapi.yaml │ └── trusted-state-guard.schema.json └── tasks.md ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ ├── Concerns/ │ ├── Pages/ │ │ ├── Workspaces/ │ │ └── Monitoring/ │ ├── Resources/ │ └── System/ │ └── Pages/ ├── Services/ │ ├── Onboarding/ │ └── Auth/ ├── Support/ │ ├── Workspaces/ │ ├── OperateHub/ │ └── Rbac/ └── Models/ tests/ ├── Feature/ │ ├── Onboarding/ │ ├── Guards/ │ ├── Rbac/ │ └── System/ └── Unit/ ``` **Structure Decision**: Use the existing Laravel web application structure. The first slice is centered in `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`, `app/Filament/Pages/TenantRequiredPermissions.php`, `app/Filament/System/Pages/Ops/Runbooks.php`, shared resolver seams in `app/Filament/Concerns`, `app/Support/Workspaces`, and focused Pest coverage under `tests/Feature`. ## Phase 0 — Research (complete) - Output: [specs/152-livewire-context-locking/research.md](research.md) - Resolved key decisions: - Use a three-lane trusted-state model: presentation, locked identity, server-derived authority. - Prefer locked scalar IDs and resolver-backed model access over public Eloquent models for ownership-relevant continuity. - Reuse existing canonical seams such as `WorkspaceContext`, `ResolvesPanelTenantContext`, onboarding draft resolvers, and `AllowedTenantUniverse`. - First slice covers onboarding wizard, one tenant-context page, and one system page. - Extend existing forged-state and architectural guard tests instead of inventing a parallel guard system. ## Phase 1 — Design & Contracts (complete) - Output: [data-model.md](./data-model.md) defines trusted-state classes, component policy records, selector proposals, authority sources, and forged-state regression cases. - Output: [contracts/trusted-state-logical.openapi.yaml](./contracts/trusted-state-logical.openapi.yaml) captures the semantic request/response contract for trusted action handling on covered surfaces. - Output: [contracts/trusted-state-guard.schema.json](./contracts/trusted-state-guard.schema.json) defines the policy shape used by guard-oriented validation or documentation. - Output: [quickstart.md](./quickstart.md) captures implementation sequence and focused validation commands. ### Post-design Constitution Re-check - PASS: The design keeps Filament v5 + Livewire v4 and introduces no new panel or route. - PASS: No Graph, queue, or storage expansion is introduced. - PASS: Existing RBAC-UX semantics are preserved and strengthened through per-action re-resolution. - PASS WITH WORK: Some covered components currently store public model objects. The implementation must migrate or neutralize those fields in the first slice without breaking legitimate resume or filter UX. - PASS WITH WORK: Guard coverage must stay high-signal and scoped to the documented first-slice component families. ## Phase 2 — Implementation Planning `tasks.md` should cover: - Classifying first-slice public properties by trusted-state lane. - Replacing or constraining public ownership-relevant model properties on the onboarding wizard. - Normalizing onboarding protected actions so draft, tenant, workspace, and provider records are re-resolved on every action. - Keeping `TenantRequiredPermissions` tenant authority route-derived while preserving mutable filters. - Enforcing `AllowedTenantUniverse` validation for system runbook tenant selectors on every protected action path. - Extending existing forged foreign-tenant and resolver guard tests for onboarding, tenant-context, and system surfaces. - Adding one lightweight guard for forbidden ownership-relevant public authority fields on covered surfaces. ### Contract Implementation Note - The OpenAPI contract is logical rather than transport-prescriptive. It documents the expected server behavior for existing Filament and Livewire handlers. - The guard schema is documentation-first and may be enforced through Pest guards, curated config arrays, or test fixtures rather than a production runtime parser in the first slice. - The preferred implementation approach is to push model access behind resolver-backed methods or computed accessors instead of public model state. ### Deployment Sequencing Note - No migration is expected in the first slice. - No asset publish change is expected. - The rollout should start with onboarding, then tenant-context, then system-page hardening, because the onboarding wizard has the densest authority state and the clearest existing regression tests. ## Complexity Tracking | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | None | Not applicable | Not applicable |