# Tasks: Spec 334 - Nested Filament / Livewire Context Contract Hardening - Input: `specs/334-nested-filament-context-contract-hardening/spec.md`, `specs/334-nested-filament-context-contract-hardening/plan.md` - Prerequisites: `spec.md`, `plan.md` **Tests**: Required. This is runtime-hardening for nested operator surfaces with authorization/scope impact. ## Test Governance Checklist - [x] Lane assignment is explicit and is the narrowest sufficient proof for the changed behavior. - [x] New tests stay in the smallest honest family (Feature/Livewire + one architecture guard; browser smoke only for the two user-visible regressions). - [x] New helpers/factories/seeds/context defaults stay cheap by default. - [x] Planned validation commands cover the change without pulling in unrelated lane cost. - [x] Any deviation resolves as `document-in-feature`, `follow-up-spec`, or `reject-or-split`. ## Phase 1: Preparation And Repo Truth **Purpose**: Confirm repo truth and capture the current failure paths before touching runtime code. - [x] T001 Re-read `spec.md`, `plan.md`, and this `tasks.md`. - [x] T002 Confirm working tree intent and record baseline commit (`git status`, `git log -1`). - [x] T003 Verify confirmed scope file paths exist and inspect current context usage: - `apps/platform/app/Livewire/BackupSetPolicyPickerTable.php` - `apps/platform/app/Filament/Resources/RestoreRunResource.php` - `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php` - `apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php` - `apps/platform/app/Filament/Widgets/ManagedEnvironment/ManagedEnvironmentTriageArrivalContinuity.php` - `apps/platform/app/Support/OperateHub/OperateHubShell.php` - `apps/platform/app/Support/Workspaces/WorkspaceContext.php` - [x] T004 Capture the current Add Policies modal failure path (tenantless modal → checkbox column hidden) and record the exact call chain and where tenant/context is read. - Captured via regression: `apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php` and browser smoke `apps/platform/tests/Browser/Spec334NestedFilamentContextContractSmokeTest.php`. - [x] T005 Capture the current Restore Run Create wizard failure path (Livewire update request without route params → tenant resolver throws) and record the exact call chain and closure(s) involved. - Captured via regression: `apps/platform/tests/Feature/Filament/RestoreRunResourceLivewireTenantContextTest.php` (real Livewire update payload) + browser smoke `apps/platform/tests/Browser/Spec334NestedFilamentContextContractSmokeTest.php`. - [x] T006 Decide whether any shared helper is justified (≥2 confirmed consumers). If not, keep fixes local to each surface + the existing shared seam. - No new helper introduced (ABSTR-001). Shared seam hardening applied in `apps/platform/app/Support/OperateHub/OperateHubShell.php`. ## Phase 2: Guardrails And Regression Tests (before refactor) **Purpose**: Lock “fail-closed and scoped” behavior and block unsafe tenant switching patterns before implementation refactors. - [x] T007 Add an architecture guard test: `apps/platform/tests/Architecture/FilamentTenantContextContractTest.php`. - Detect and fail on unsafe `Filament::setTenant($model->...)` patterns in nested surfaces without explicit allowlist. - Keep an explicit allowlist limited to infrastructure-only context selection locations. - [x] T008 Add a regression test covering Add Policies picker behavior when ambient tenant is null (authorized user still sees row selection and can select). - [x] T009 Add a regression test covering Restore Run Create wizard Livewire update lifecycle (no crash when route params are missing; options are scoped). - [x] T010 Add a regression test for BackupSchedule operation runs relation manager scope (owner record scopes query; ambient tenant missing/wrong does not broaden). - [x] T011 Add a regression test for the triage widget context (record context preferred; ambient tenant is fallback; missing context fails closed). ## Phase 3: Implement Nested Context Contract (confirmed surfaces only) **Purpose**: Apply the contract to the confirmed high-risk surfaces without a broad tenancy rewrite. - [x] T012 Harden `apps/platform/app/Livewire/BackupSetPolicyPickerTable.php`: - Resolve context from validated BackupSet ownership (workspace + managed environment). - Scope table query by resolved environment. - Re-resolve and re-authorize at mutation time (bulk action). - Never silently override mismatched ambient tenant. - [x] T013 Harden `apps/platform/app/Filament/Resources/RestoreRunResource.php`: - Ensure option closures used during Livewire updates can resolve validated environment context without route params. - Livewire update context recovery is implemented in the shared seam: `apps/platform/app/Support/OperateHub/OperateHubShell.php` (validated referer path candidate for `/livewire-*/update` requests). - Referer is treated as a candidate only; access is still validated via workspace + membership + operability checks. - [x] T014 Harden `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php` only if the seam is shared and the fix is not restore-specific. - No change required (the shared seam hardening in `OperateHubShell` unblocks the failing lifecycle). - [x] T015 Harden `apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php`: - Prefer owner schedule record as primary context (`$this->getOwnerRecord()`). - Remove dependencies on ambient tenant where owner context exists. - [x] T016 Harden `apps/platform/app/Filament/Widgets/ManagedEnvironment/ManagedEnvironmentTriageArrivalContinuity.php`: - Prefer widget record context. - Use one resolver consistently for visibility and mutation checks. - Fail closed when context is missing. ## Phase 4: Browser Smoke (required because the original bugs were user-visible) - [x] T017 Backup Set Add Policies smoke: - Open Backup Set detail → Add Policies. - Verify policies are visible and row selection checkbox column is visible. - Select one or more rows; verify “Add selected” path works. - [x] T018 Restore Run Create wizard smoke: - Open Restore Runs → Create. - Trigger Livewire interactions (wizard next/previous, selections). - Verify no “no tenant context selected” crash. ## Phase 5: Validation - [x] T019 Run narrow tests first (confidence lane): - `cd apps/platform && ./vendor/bin/sail artisan test tests/Architecture --filter='FilamentTenantContextContract' --compact` - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament --filter='BackupSetPolicyPicker|RestoreRun|BackupScheduleOperationRuns|Triage' --compact` - [ ] T020 Run broader related suites only if needed (keep lane cost honest): - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament --compact` - [x] T021 Run `cd apps/platform && ./vendor/bin/sail pint --dirty` and `git diff --check`. - [x] T022 Report full-suite status honestly if not run. - Full suite not executed; this spec was validated via targeted Feature/Architecture tests + a dedicated browser smoke file.