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

24 KiB

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.

  • T001 [P] Add reusable visible-set baseline matrix fixture builders in apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php
  • 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.

  • T003 [P] Add centralized matrix state and trust badge coverage in apps/platform/tests/Unit/Badges/BaselineCompareMatrixBadgesTest.php
  • 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
  • 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
  • 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
  • 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

  • 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
  • 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

  • T010 [US1] Implement derived reference, tenant, subject, and cell bundle assembly in apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php
  • T011 [US1] Add the workspace matrix page class, route state, and filter schema in apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
  • 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
  • T013 [US1] Add Open compare matrix header navigation on baseline detail in apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
  • 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
  • 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

  • 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
  • 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

  • T018 [US2] Implement visible-tenant batch compare start reuse in apps/platform/app/Services/Baselines/BaselineCompareService.php
  • 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
  • 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
  • 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

  • T023 [P] [US3] Add subject-focus and drilldown continuity coverage in apps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php
  • 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

  • T025 [US3] Add tenant, subject, finding, and run drilldown state handling in apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
  • T026 [US3] Reuse canonical matrix return-path context in apps/platform/app/Support/Navigation/CanonicalNavigationContext.php and apps/platform/app/Support/Navigation/RelatedNavigationResolver.php
  • 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
  • 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

  • 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
  • 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

  • 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
  • T033 [US4] Render explicit blocked, empty, stale, ambiguous, and low-trust states in apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php
  • 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
  • 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.

  • 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
  • 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
  • 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
  • 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
  • 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

# 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

# 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

# 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

# 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.