## Summary
- add the shared trusted-state model and resolver helpers for first-slice Livewire and Filament surfaces
- harden managed tenant onboarding, tenant required permissions, and system runbooks against forged or stale public state
- add focused Pest guard and regression coverage plus the complete spec 152 artifact set
## Validation
- `vendor/bin/sail artisan test --compact`
- manual smoke validated on `/admin/onboarding/{onboardingDraft}`
- manual smoke validated on `/admin/tenants/{tenant}/required-permissions`
- manual smoke validated on `/system/ops/runbooks`
## Notes
- Livewire v4.0+ / Filament v5 stack unchanged
- no new panels, routes, assets, or global-search changes
- provider registration remains in `bootstrap/providers.php`
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #182
159 lines
10 KiB
Markdown
159 lines
10 KiB
Markdown
# 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 |
|