TenantAtlas/specs/190-baseline-compare-matrix/tasks.md
ahmido 65e10a2020 Spec 190: tighten baseline compare matrix scanability (#222)
## Summary
- tighten the baseline compare matrix working surface with active filter scope summaries and clearer visible-set disclosure
- improve matrix scanability with a sticky subject column, calmer attention-first cell styling, and Filament form-based filter controls
- replace the misleading perpetual refresh loading state with a passive auto-refresh note and add focused regression coverage

## Testing
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareMatrixPageTest.php`

## Notes
- this PR only contains the Spec 190 implementation changes on `190-baseline-compare-matrix`
- follow-up spec drafting for high-density operator mode was intentionally left out of this PR

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #222
2026-04-11 12:32:10 +00:00

269 lines
24 KiB
Markdown

# Tasks: Workspace Baseline Compare Matrix V1
**Input**: Design documents from `/specs/190-baseline-compare-matrix/`
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `contracts/baseline-compare-matrix.logical.openapi.yaml`, `quickstart.md`
**Tests**: Tests are REQUIRED for this feature. Use Pest unit coverage for centralized matrix badge semantics, Pest feature coverage for matrix aggregation, page rendering, compare-all fan-out, and RBAC semantics, plus one browser smoke test for the rendered matrix surface and one core interaction.
**Operations**: This feature must reuse existing tenant-owned `baseline_compare` `OperationRun` semantics only. Tasks must preserve the Ops-UX 3-surface feedback contract, avoid any workspace umbrella run or shadow batch truth, keep `OperationRun.status` and `OperationRun.outcome` service-owned, keep reused `summary_counts` canonical via `OperationSummaryKeys` and numeric-only, prevent ad hoc queued, running, or completion database notifications, and keep compare-all feedback limited to canonical queued feedback plus existing Monitoring drilldowns.
**RBAC**: Existing workspace membership and tenant visibility remain authoritative. Tasks must preserve deny-as-not-found `404` behavior for non-members, `403` behavior for in-scope members missing `WORKSPACE_BASELINES_VIEW`, `WORKSPACE_BASELINES_MANAGE`, `TENANT_VIEW`, or `TENANT_FINDINGS_VIEW`, visible-disabled compare actions plus helper text for in-scope members missing capability where the surface contract requires it, and visible-set-only aggregation so hidden tenants never leak through counts, summaries, or drilldowns.
**Operator Surfaces**: The affected operator surfaces are baseline profile detail, the new workspace baseline compare matrix page, tenant compare landing, finding follow-up surfaces, and Monitoring run drilldowns.
**Filament UI Action Surfaces**: Baseline profile detail keeps its existing inspect model and gains `Open compare matrix` plus confirmation-gated `Compare assigned tenants` header actions. The matrix page exposes explicit tenant, subject, cell, and run drilldowns only, forbids row click, adds no destructive actions, and uses one narrow matrix-grid exception for the two-dimensional body.
**Filament UI UX-001**: The new page must keep Filament-native sections, summaries, legends, filters, and empty states. The grid body is the only approved UX-001 exception because a one-axis table cannot represent subject-by-tenant truth.
**Badges**: Matrix state, freshness, and trust surfaces must use centralized badge semantics through `BadgeDomain`, `BadgeCatalog`, and `BadgeRenderer`. No page-local status color or ad hoc legend mapping is allowed.
**Organization**: Tasks are grouped by user story so each story can be implemented and verified independently once the shared matrix foundation is in place.
## Phase 1: Setup (Shared Matrix Harness)
**Purpose**: Prepare reusable fixtures and acceptance scaffolds for multi-tenant baseline matrix scenarios shared across all stories.
- [X] T001 [P] Add reusable visible-set baseline matrix fixture builders in `apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php`
- [X] T002 [P] Stage matrix acceptance scaffolds in `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php`, `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php`, `apps/platform/tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php`, and `apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php`
**Checkpoint**: Shared matrix fixtures and empty acceptance seams exist for builder, page, compare-all, RBAC, and browser smoke coverage.
---
## Phase 2: Foundational (Blocking Matrix Core)
**Purpose**: Establish centralized badge semantics, action-surface guards, and reusable query seams that every user story depends on.
**⚠️ CRITICAL**: No user story work should begin until this phase is complete.
- [X] T003 [P] Add centralized matrix state and trust badge coverage in `apps/platform/tests/Unit/Badges/BaselineCompareMatrixBadgesTest.php`
- [X] T004 [P] Add matrix header-action, visible-disabled compare-action helper-text, and grid-surface guard coverage in `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`
- [X] T005 [P] Register matrix state and trust badge semantics in `apps/platform/app/Support/Badges/BadgeDomain.php` and `apps/platform/app/Support/Badges/Domains/BaselineCompareMatrixStateBadge.php`
- [X] T006 [P] Add visible-assignment and latest-compare query helpers for query-bounded matrix loading in `apps/platform/app/Models/BaselineTenantAssignment.php`, `apps/platform/app/Models/OperationRun.php`, and `apps/platform/app/Models/Finding.php`
- [X] T007 Reuse reference snapshot, freshness, and explanation seams for matrix aggregation in `apps/platform/app/Support/Baselines/BaselineSnapshotTruthResolver.php`, `apps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php`, `apps/platform/app/Support/Baselines/BaselineCompareEvidenceGapDetails.php`, and `apps/platform/app/Support/Baselines/BaselineCompareExplanationRegistry.php`
**Checkpoint**: Central badge semantics and data-access seams are ready, so page, compare-all, drilldown, and degraded-state work can build on one authoritative matrix foundation.
---
## Phase 3: User Story 1 - Scan Visible Drift Across Assigned Tenants (Priority: P1) 🎯 MVP
**Goal**: Let workspace operators open one baseline-scoped matrix and understand visible tenant drift, subject breadth, freshness, and trust from a single page.
**Independent Test**: Open the matrix for a baseline profile with mixed compare outcomes and verify that reference truth, visible tenant columns, subject rows, summaries, filters, and cell states are truthful without opening tenant pages first.
### Tests for User Story 1
- [X] T008 [P] [US1] Add matrix aggregation coverage for visible-set-only counts, subject-axis derivation, and cell precedence in `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php`
- [X] T009 [P] [US1] Add matrix page coverage for reference truth, summaries, filters, and grid rendering in `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`
### Implementation for User Story 1
- [X] T010 [US1] Implement derived reference, tenant, subject, and cell bundle assembly in `apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php`
- [X] T011 [US1] Add the workspace matrix page class, route state, and filter schema in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php`
- [X] T012 [US1] Render reference sections, visible-set summaries, legends, and the subject-by-tenant grid in `apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php`
- [X] T013 [US1] Add `Open compare matrix` header navigation on baseline detail in `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`
- [X] T014 [US1] Register the matrix page entry seam on the baseline resource in `apps/platform/app/Filament/Resources/BaselineProfileResource.php` and `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`
- [X] T015 [US1] Run focused US1 verification from `specs/190-baseline-compare-matrix/quickstart.md` against `apps/platform/tests/Unit/Badges/BaselineCompareMatrixBadgesTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php`, and `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`
**Checkpoint**: Operators can scan one baseline-scoped visible-set matrix and identify the most divergent tenants and subjects without leaving the workspace surface.
---
## Phase 4: User Story 2 - Refresh Compare Truth For The Visible Assigned Set (Priority: P1)
**Goal**: Let authorized operators trigger compare across all visible assigned tenants from the baseline detail or matrix surface without inventing a workspace umbrella run.
**Independent Test**: Start `Compare assigned tenants` from the baseline detail or matrix page and verify that eligible visible tenants reuse normal compare execution, blocked tenants stay explicit, and no second batch truth is created.
### Tests for User Story 2
- [X] T016 [P] [US2] Add compare-all fan-out and Ops-UX regression coverage for queued, already-queued, blocked, no-umbrella-run, service-owned run transitions, canonical `summary_counts`, and no ad hoc non-terminal database notifications in `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php`
- [X] T017 [P] [US2] Extend compare-start surface, confirmation, and visible-disabled helper-text coverage for `Compare assigned tenants` in `apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php` and `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`
### Implementation for User Story 2
- [X] T018 [US2] Implement visible-tenant batch compare start reuse in `apps/platform/app/Services/Baselines/BaselineCompareService.php`
- [X] T019 [US2] Add confirmation-gated `Compare assigned tenants` execution, honest launch summaries, and visible-disabled helper text on the matrix page in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php` and `apps/platform/app/Support/Rbac/UiEnforcement.php`
- [X] T020 [US2] Add confirmation-gated `Compare assigned tenants` execution with capability-gated disabled state on baseline detail in `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php` and `apps/platform/app/Support/Rbac/UiEnforcement.php`
- [ ] T021 [US2] Reuse canonical queued feedback, initiator-only run links, service-owned run transitions, canonical `summary_counts`, and no ad hoc notification or status writes for compare-all outcomes in `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`, `apps/platform/app/Support/OpsUx/OpsUxBrowserEvents.php`, `apps/platform/app/Support/OperationRunLinks.php`, and `apps/platform/app/Services/OperationRunService.php`
- [X] T022 [US2] Run focused US2 verification from `specs/190-baseline-compare-matrix/quickstart.md` against `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php` and `apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php`
**Checkpoint**: Authorized operators can refresh compare truth for the visible assigned set from one action while Monitoring and tenant compare runs remain the only execution truth.
---
## Phase 5: User Story 3 - Drill From The Matrix Into Existing Follow-Up Surfaces (Priority: P2)
**Goal**: Let operators move from matrix cells, tenant summaries, and subject focus into existing compare, finding, and run detail surfaces without reconstructing context.
**Independent Test**: Open a differing, missing, or ambiguous matrix cell and confirm the product lands on the existing tenant compare or finding path with a bounded return path back to the matrix.
### Tests for User Story 3
- [X] T023 [P] [US3] Add subject-focus and drilldown continuity coverage in `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`
- [X] T024 [P] [US3] Add matrix-to-tenant and matrix-to-finding authorization coverage for `404` versus `403` semantics in `apps/platform/tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php`
### Implementation for User Story 3
- [X] T025 [US3] Add tenant, subject, finding, and run drilldown state handling in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php`
- [X] T026 [US3] Reuse canonical matrix return-path context in `apps/platform/app/Support/Navigation/CanonicalNavigationContext.php` and `apps/platform/app/Support/Navigation/RelatedNavigationResolver.php`
- [X] T027 [US3] Accept matrix source context on tenant compare and finding follow-up surfaces in `apps/platform/app/Filament/Pages/BaselineCompareLanding.php` and `apps/platform/app/Filament/Resources/FindingResource.php`
- [ ] T028 [US3] Expose bounded back-link and source-hint rendering for matrix arrivals in `apps/platform/app/Filament/Pages/BaselineCompareLanding.php` and `apps/platform/app/Filament/Resources/OperationRunResource.php`
- [X] T029 [US3] Run focused US3 verification from `specs/190-baseline-compare-matrix/quickstart.md` against `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php` and `apps/platform/tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php`
**Checkpoint**: The matrix becomes a decision surface instead of a dead-end report because operators can drill directly into existing follow-up workflows and return cleanly.
---
## Phase 6: User Story 4 - Stay Honest In Degraded Or Low-Trust Conditions (Priority: P2)
**Goal**: Keep blocked, stale, ambiguous, not-compared, and low-trust states visibly distinct so the matrix never reads calmer than the underlying truth.
**Independent Test**: Open the matrix for a baseline profile with no usable snapshot, no visible tenants, stale results, ambiguous matches, and uncovered policy types, and verify that none of those states render as healthy matches.
### Tests for User Story 4
- [X] T030 [P] [US4] Add degraded-state page coverage for no usable snapshot, no assigned tenants, no visible tenants, and no compare results in `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`
- [X] T031 [P] [US4] Add ambiguity, stale-result, uncovered-policy-type, policy-type filter honesty, and query-shape guard coverage in `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php` and `apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php`
### Implementation for User Story 4
- [X] T032 [US4] Reuse stale-result and evidence-gap semantics inside `apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php`, `apps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php`, and `apps/platform/app/Support/Baselines/BaselineCompareEvidenceGapDetails.php`
- [X] T033 [US4] Render explicit blocked, empty, stale, ambiguous, and low-trust states in `apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php`
- [X] T034 [US4] Add policy-type, state-group, severity, tenant-sort, subject-sort, and subject-focus state handling in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php`
- [X] T035 [US4] Run focused US4 verification from `specs/190-baseline-compare-matrix/quickstart.md` against `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php` and `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`
**Checkpoint**: The matrix stays honest when data is stale, missing, ambiguous, or invisible, so operators do not mistake degraded truth for clean posture.
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: Finalize guard coverage, browser confidence, copy review, formatting, and the focused verification pack across all stories.
- [X] T036 [P] Add no-ad-hoc-badge and no-diagnostic-warning guard coverage for matrix state surfaces in `apps/platform/tests/Feature/Guards/NoAdHocStatusBadgesTest.php` and `apps/platform/tests/Feature/Guards/NoDiagnosticWarningBadgesTest.php`
- [X] T037 [P] Add browser smoke coverage for matrix render, one filter interaction, and one drilldown or compare affordance in `apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php`
- [X] T038 [P] Review `Verb + Object`, `visible-set only`, and `simulation only` copy in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php`, `apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php`, and `apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php`
- [X] T041 [P] Tighten matrix scanability with active-filter scope summaries, visible-set scope disclosure, non-blocking refresh feedback, sticky subject-column treatment, and focused UI regression coverage in `apps/platform/app/Filament/Pages/BaselineCompareMatrix.php`, `apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php`, `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`, and `apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php`
- [X] T039 [P] Run formatting with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` using `specs/190-baseline-compare-matrix/quickstart.md`
- [ ] T040 Run the focused verification pack from `specs/190-baseline-compare-matrix/quickstart.md` against `apps/platform/tests/Unit/Badges/BaselineCompareMatrixBadgesTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareStatsTest.php`, `apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php`, `apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php`, `apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php`, `apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php`, `apps/platform/tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php`, `apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php`, `apps/platform/tests/Feature/Guards/NoAdHocStatusBadgesTest.php`, `apps/platform/tests/Feature/Guards/NoDiagnosticWarningBadgesTest.php`, and `apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: Starts immediately and prepares shared fixtures plus empty acceptance seams.
- **Foundational (Phase 2)**: Depends on Setup and blocks all user-story work until centralized badge semantics, action-surface guards, and query seams exist.
- **User Story 1 (Phase 3)**: Starts after Foundational and is the recommended engineering MVP because it delivers the first truthful read-only matrix.
- **User Story 2 (Phase 4)**: Starts after User Story 1 because compare-all actions reuse the matrix page and baseline-detail seams established in the MVP.
- **User Story 3 (Phase 5)**: Starts after User Story 1 because drilldown continuity depends on matrix page state and cell metadata.
- **User Story 4 (Phase 6)**: Starts after User Story 1 and can proceed in parallel with User Story 2 or User Story 3 once the core matrix bundle and page exist.
- **Polish (Phase 7)**: Starts after all desired user stories are complete.
### User Story Dependencies
- **US1**: Depends only on the shared matrix foundation.
- **US2**: Depends on US1 for the matrix page, baseline-detail entry seams, and derived visible-set truth.
- **US3**: Depends on US1 for matrix page state and cell metadata used by drilldowns.
- **US4**: Depends on US1 for the matrix builder and page, then hardens degraded-state and filter honesty across the same surface.
### Within Each User Story
- Write or extend the story tests first and confirm they fail before implementation is considered complete.
- Land shared service, builder, or navigation changes before view and copy wiring in the same story.
- Keep each story shippable on its own before moving to the next priority.
### Parallel Opportunities
- `T001` and `T002` can run in parallel during Setup.
- `T003` and `T004` can run in parallel before the shared badge and action-surface seams land.
- `T005` and `T006` can run in parallel once the corresponding tests exist.
- Within US1, `T008` and `T009` can run in parallel, then `T011` and `T012` can split after `T010` defines the matrix bundle.
- Within US2, `T016` and `T017` can run in parallel, then `T019` and `T020` can split after `T018` lands the batch compare seam.
- Within US3, `T023` and `T024` can run in parallel, then `T026`, `T027`, and `T028` can split after `T025` defines the page drilldown state.
- Within US4, `T030` and `T031` can run in parallel, then `T033` and `T034` can split after `T032` lands the degraded-state semantics.
- Within Phase 7, `T036`, `T037`, and `T038` can run in parallel before formatting and the final verification pack.
---
## Parallel Example: User Story 1
```bash
# User Story 1 tests in parallel
T008 apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php
T009 apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php
# User Story 1 implementation split after the matrix bundle exists
T011 apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
T012 apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php
```
## Parallel Example: User Story 2
```bash
# User Story 2 tests in parallel
T016 apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php
T017 apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php
# User Story 2 implementation split after the batch start seam lands
T019 apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
T020 apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
```
## Parallel Example: User Story 3
```bash
# User Story 3 tests in parallel
T023 apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php
T024 apps/platform/tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php
# User Story 3 implementation split after drilldown state exists
T026 apps/platform/app/Support/Navigation/CanonicalNavigationContext.php
T027 apps/platform/app/Filament/Pages/BaselineCompareLanding.php
```
## Parallel Example: User Story 4
```bash
# User Story 4 tests in parallel
T030 apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php
T031 apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php
# User Story 4 implementation split after degraded-state semantics land
T033 apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php
T034 apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
```
---
## Implementation Strategy
### MVP First
1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational.
3. Complete Phase 3: User Story 1.
4. **STOP and VALIDATE**: Confirm the read-only matrix answers the visible-set portfolio question honestly before adding refresh or drilldown behavior.
### Incremental Delivery
1. Deliver Setup plus Foundational to lock shared matrix fixtures, centralized badge semantics, action-surface guards, and query seams.
2. Deliver User Story 1 so operators can scan one truthful cross-tenant baseline matrix.
3. Deliver User Story 2 so operators can refresh visible-set compare truth from the same workflow.
4. Deliver User Story 3 so the matrix becomes a decision surface with bounded follow-up continuity.
5. Deliver User Story 4 so degraded and low-trust conditions remain explicit under the final filter set.
6. Finish with browser confidence, copy review, formatting, and the focused verification pack.
### Parallel Team Strategy
1. One contributor can prepare fixture scaffolds and browser seams while another adds badge and action-surface guards.
2. After the foundation lands, one contributor can own the matrix builder while another wires the page shell and Blade view.
3. Once the matrix page exists, one contributor can take compare-all fan-out while another handles drilldown continuity.
4. Degraded-state hardening can proceed in parallel with drilldown work once the base matrix bundle and page filters are stable.
5. Rejoin for Polish so guard suites, browser smoke coverage, copy review, formatting, and the final verification pack land together.
---
## Notes
- `[P]` tasks target different files or safe concurrent work after prerequisite seams are in place.
- `[US1]`, `[US2]`, `[US3]`, and `[US4]` map directly to the user stories in `spec.md`.
- The recommended engineering MVP scope is Phase 1 through Phase 3. The product-complete P1 scope is Phase 1 through Phase 4.
- This task plan stays compliant with Filament v5 on Livewire v4, makes no panel-provider changes in `bootstrap/providers.php`, introduces no new globally searchable resource, adds no destructive action, and requires no asset-strategy change beyond the existing deployment process.