22 KiB
Tasks: Portfolio Triage Review State and Operator Progress
Input: Design documents from /specs/189-portfolio-triage-review-state/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/portfolio-triage-review-state.logical.openapi.yaml, quickstart.md
Tests: Tests are REQUIRED for this feature. Use Pest unit coverage for fingerprinting, state resolution, and badge semantics; Filament feature coverage for tenant-dashboard continuity, tenant-registry review-state rendering, and workspace-overview progress; and RBAC coverage for 404 versus 403 mutation semantics.
Operations: This feature introduces no OperationRun, queue, scheduler, or remote call. Review-state writes stay TenantPilot-only and DB-only, but they must record bounded AuditLog entries through the existing audit infrastructure and execute only after a bounded pre-execution preview plus explicit confirmation.
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 lacking the mutation capability, canonical capability-registry usage, and visible-but-disabled UI where the surface contract requires it.
Operator Surfaces: The affected operator surfaces are workspace overview progress summaries, the tenant registry triage list, and the tenant dashboard arrival continuity block.
Filament UI Action Surfaces: Full-row click remains the registry inspect model, the existing tenant-open shortcut remains the only inline safe shortcut, registry review-state mutations live in overflow, and tenant-dashboard review-state mutations live only inside the continuity block.
Filament UI UX-001: No create, edit, or view-form layouts change. This slice is limited to additive status rendering, filters, overflow actions, and dashboard continuity controls.
Badges: Review-state semantics must use BadgeDomain plus a centralized domain mapper. No page-local status-pill styling or ad hoc label mapping is allowed.
Organization: Tasks are grouped by user story so each story can be implemented and verified independently once the shared triage-review foundation is in place.
Phase 1: Setup (Shared Triage-Review Harness)
Purpose: Prepare reusable fixtures and acceptance scaffolds for mixed-family triage-review scenarios shared across all stories.
- T001 [P] Extend mixed-family and superseded-review fixture helpers in
apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php - T002 [P] Stage focused review-state acceptance scaffolds in
apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php,apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php, andapps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php
Checkpoint: Shared fixture and acceptance seams exist for dashboard, registry, and overview review-state work.
Phase 2: Foundational (Blocking Triage-Review Core)
Purpose: Establish the persisted review-state model, deterministic fingerprinting, batch state resolution, and centralized badge mapping that every story depends on.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T003 [P] Add deterministic fingerprint and concern-family separation coverage in
apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewFingerprintTest.php - T004 [P] Add active-row precedence and current-set summary coverage in
apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php - T005 [P] Add centralized review-state badge mapping coverage in
apps/platform/tests/Unit/Badges/TenantTriageReviewStateBadgesTest.php - T006 Create the
tenant_triage_reviewsschema inapps/platform/database/migrations/*_create_tenant_triage_reviews_table.php - T007 [P] Create the persisted review-state model and factory in
apps/platform/app/Models/TenantTriageReview.phpandapps/platform/database/factories/TenantTriageReviewFactory.php - T008 [P] Implement deterministic concern fingerprint generation in
apps/platform/app/Support/PortfolioTriage/TenantTriageReviewFingerprint.php - T009 Implement batch review-state resolution and current-set progress aggregation in
apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php - T010 Register centralized review-state badge semantics in
apps/platform/app/Support/Badges/BadgeDomain.phpandapps/platform/app/Support/Badges/Domains/TenantTriageReviewStateBadge.php
Checkpoint: One authoritative persisted review-state core exists and can be reused by dashboard, registry, and overview surfaces without N+1 fanout.
Phase 3: User Story 1 - Record That A Concern Was Checked (Priority: P1) 🎯 MVP
Goal: Let authorized operators mark the current dashboard concern as reviewed or follow-up needed so progress survives navigation and time.
Independent Test: Open a tenant from portfolio triage, trigger the continuity-block preview for Mark reviewed or Mark follow-up needed, confirm the TenantPilot only scope, and verify the active triage-review record, bounded audit entry, and dashboard state update all reflect the new manual state.
Tests for User Story 1
- T011 [P] [US1] Extend tenant-dashboard continuity coverage for preview-and-confirmation semantics, valid triage-context gating, generic-session suppression,
Mark reviewed,Mark follow-up needed, and bounded reviewer or timestamp context inapps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php - T012 [P] [US1] Add mutation authorization and audit coverage for non-member
404, member-without-capability403, preview-confirmed successful writes, and no action execution without confirmation inapps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php
Implementation for User Story 1
- T013 [US1] Add the canonical triage-review mutation capability and audit action IDs in
apps/platform/app/Support/Auth/Capabilities.phpandapps/platform/app/Support/Audit/AuditActionId.php - T014 [US1] Implement
markReviewed()andmarkFollowUpNeeded()with superseded-row resolution andAuditRecorderwrites inapps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php - T015 [US1] Bind resolved review state, bounded preview-and-confirmation actions,
TenantPilot onlyscope copy, and generic-session suppression into the dashboard continuity surface inapps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php,apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php, andapps/platform/app/Filament/Pages/TenantDashboard.php - T016 [US1] Enforce visible-but-disabled UI plus server-side mutation gating through
apps/platform/app/Support/Rbac/UiEnforcement.phpandapps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php - T017 [US1] Run focused US1 verification from
specs/189-portfolio-triage-review-state/quickstart.mdagainstapps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.phpandapps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php
Checkpoint: Operators can record review intent from the tenant dashboard, and writes are RBAC-safe, auditable, and workspace-shared.
Phase 4: User Story 2 - Work The Remaining Set From The Registry (Priority: P1)
Goal: Make the tenant registry show and filter review state so operators can keep working the remaining affected set without losing posture truth.
Independent Test: Seed mixed review states, open /admin/tenants, and verify the review-state column, highest-priority concern-family labeling, preview-confirmed overflow actions, and all four review_state filters (not_reviewed, reviewed, follow_up_needed, changed_since_review) all behave correctly while backup posture and recovery evidence remain separately visible.
Tests for User Story 2
- T018 [P] [US2] Add registry column, highest-priority concern-family labeling, and all four
review_statefilters (not_reviewed,reviewed,follow_up_needed,changed_since_review) coverage inapps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php - T019 [P] [US2] Extend posture-truth coexistence, overflow action-surface placement, and preview-and-confirmation action coverage in
apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.phpandapps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php
Implementation for User Story 2
- T020 [US2] Add review-state row rendering, mixed-family labeling, reuse of
TenantResource::portfolioConcernPriority()for highest-priority concern selection, and overflow mutation actions with preview-and-confirmation inapps/platform/app/Filament/Resources/TenantResource.php - T021 [US2] Add all four
review_statefilters, current-slice concern-family handling, and empty-state context inapps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php - T022 [US2] Reuse
TenantTriageReviewStateResolverinsideapps/platform/app/Filament/Resources/TenantResource.phpto keep registry rendering query-bounded and posture truth separate from review state - T023 [US2] Run focused US2 verification from
specs/189-portfolio-triage-review-state/quickstart.mdagainstapps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.phpandapps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php
Checkpoint: The registry becomes a working triage surface for remaining review work without implying that Reviewed means Fixed.
Phase 5: User Story 3 - Re-review Tenants When The Concern Changes (Priority: P1)
Goal: Turn stale manual review records into Changed since review when the current concern changes so old progress does not hide renewed risk.
Independent Test: Record a review, change the stable concern fingerprint while the tenant remains affected, and verify the dashboard and registry both show Changed since review until a new review is recorded.
Tests for User Story 3
- T024 [P] [US3] Extend stale-review precedence and fingerprint-mismatch coverage in
apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php - T025 [P] [US3] Extend dashboard and registry stale-review rendering coverage in
apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.phpandapps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php
Implementation for User Story 3
- T026 [US3] Add
changed_since_reviewprecedence and mismatch handling inapps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php - T027 [US3] Refine stable fingerprint inputs for backup and recovery concern changes in
apps/platform/app/Support/PortfolioTriage/TenantTriageReviewFingerprint.php - T028 [US3] Surface
Changed since reviewlabels and re-review affordances inapps/platform/app/Filament/Resources/TenantResource.php,apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php, andapps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php - T029 [US3] Run focused US3 verification from
specs/189-portfolio-triage-review-state/quickstart.mdagainstapps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewFingerprintTest.php,apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php,apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php, andapps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php
Checkpoint: Previously reviewed tenants become visibly stale when the material concern changes, and re-review becomes the obvious next step.
Phase 6: User Story 4 - See Honest Progress For The Current Affected Set (Priority: P2)
Goal: Show workspace-level progress only for the currently affected visible set so review counts stay honest and clearly separate from posture truth.
Independent Test: Seed currently affected, resolved, and stale-review tenants, open /admin, and verify the overview summaries count only the current visible affected set while still showing weak posture independently from review state.
Tests for User Story 4
- T030 [P] [US4] Add current-set-only progress and calm-tenant exclusion coverage in
apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php - T031 [P] [US4] Extend overview drilldown honesty and visible-tenant scoping coverage in
apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php
Implementation for User Story 4
- T032 [US4] Extend current-set progress derivation with
TenantTriageReviewStateResolverinapps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php - T033 [US4] Render additive reviewed, follow-up-needed, and changed-since-review summaries in
apps/platform/app/Filament/Widgets/Workspace/WorkspaceSummaryStats.phpandapps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php - T034 [US4] Keep overview review-state summaries operator-first and posture-truth-safe in
apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.phpandapps/platform/app/Filament/Pages/WorkspaceOverview.php - T035 [US4] Run focused US4 verification from
specs/189-portfolio-triage-review-state/quickstart.mdagainstapps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.phpandapps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php
Checkpoint: Workspace overview progress stays bounded to the current affected set and never overclaims that reviewed posture is fixed posture.
Phase 7: Polish & Cross-Cutting Concerns
Purpose: Finalize guard coverage, performance protection, 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 the new review-state surfaces in
apps/platform/tests/Feature/Guards/NoAdHocStatusBadgesTest.phpandapps/platform/tests/Feature/Guards/NoDiagnosticWarningBadgesTest.php - T037 [P] Add query-shape regression coverage for registry and overview batch loading in
apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.phpandapps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php - T038 [P] Review
Verb + Objectcopy and TenantPilot-only mutation-scope helper text inapps/platform/app/Filament/Resources/TenantResource.php,apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php, andapps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php - T039 [P] Run formatting with
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentusingspecs/189-portfolio-triage-review-state/quickstart.md - T040 Run the focused verification pack from
specs/189-portfolio-triage-review-state/quickstart.mdagainstapps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewFingerprintTest.php,apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php,apps/platform/tests/Unit/Badges/TenantTriageReviewStateBadgesTest.php,apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php,apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php,apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php,apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php,apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php,apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php,apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php,apps/platform/tests/Feature/Guards/NoAdHocStatusBadgesTest.php, andapps/platform/tests/Feature/Guards/NoDiagnosticWarningBadgesTest.php
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): Starts immediately and prepares shared review-state fixtures plus acceptance scaffolds.
- Foundational (Phase 2): Depends on Setup and blocks all user-story work until the persisted model, fingerprinting, resolver, and badge mapping exist.
- User Story 1 (Phase 3): Starts after Foundational and is the recommended MVP slice because it introduces the first operator write path.
- User Story 2 (Phase 4): Starts after User Story 1 because registry overflow actions reuse the mutation service and capability gating established on the dashboard path.
- User Story 3 (Phase 5): Starts after User Story 1 and User Story 2 because stale-review semantics must reuse the write path and then render truthfully on both dashboard and registry surfaces.
- User Story 4 (Phase 6): Starts after User Story 2 and User Story 3 because workspace progress needs the final registry-facing state family and stale-review semantics in place.
- Polish (Phase 7): Starts after all desired user stories are complete.
User Story Dependencies
- US1: Depends only on the shared triage-review foundation.
- US2: Depends on US1 for the canonical mutation service, capability, and audit seam used by registry overflow actions.
- US3: Depends on US1 for persisted review records and on US2 for final registry rendering.
- US4: Depends on US2 and US3 because honest current-set progress must aggregate the full review-state family across visible tenants.
Within Each User Story
- Write or extend the story tests first and confirm they fail before implementation is considered complete.
- Land service or resolver changes before UI copy and action wiring in the same story.
- Keep each story shippable on its own before moving to the next priority.
Parallel Opportunities
T001andT002can run in parallel during Setup.T003,T004, andT005can run in parallel before the persisted core lands.T007andT008can run in parallel afterT006defines the storage contract.- Within US1,
T011andT012can run in parallel, thenT015andT016can be split afterT013andT014establish the write seam. - Within US2,
T018andT019can run in parallel, thenT020andT021can be split across contributors. - Within US3,
T024andT025can run in parallel, thenT026andT027can be split beforeT028updates the shared UI surfaces. - Within US4,
T030andT031can run in parallel, thenT032,T033, andT034can be sequenced across builder and widget work. - Within Phase 7,
T036,T037, andT038can run in parallel before formatting and final verification.
Parallel Example: User Story 1
# User Story 1 tests in parallel
T011 apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php
T012 apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php
# User Story 1 implementation split after the write seam exists
T015 apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php
T016 apps/platform/app/Support/Rbac/UiEnforcement.php
Parallel Example: User Story 2
# User Story 2 tests in parallel
T018 apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php
T019 apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php
# User Story 2 implementation split
T020 apps/platform/app/Filament/Resources/TenantResource.php
T021 apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
Parallel Example: User Story 3
# User Story 3 tests in parallel
T024 apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php
T025 apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php
# User Story 3 implementation split
T026 apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php
T027 apps/platform/app/Support/PortfolioTriage/TenantTriageReviewFingerprint.php
Parallel Example: User Story 4
# User Story 4 tests in parallel
T030 apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php
T031 apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php
# User Story 4 implementation split
T032 apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php
T033 apps/platform/app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php
Implementation Strategy
MVP First
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3: User Story 1.
- STOP and VALIDATE: Confirm dashboard-originated review-state writes persist correctly, stay RBAC-safe, and do not imply posture is fixed.
Incremental Delivery
- Deliver Setup plus Foundational to lock the persisted truth, fingerprinting, resolver, and badge semantics.
- Deliver User Story 1 so operators can record review intent from the tenant dashboard.
- Deliver User Story 2 so the tenant registry becomes a working queue for remaining review work.
- Deliver User Story 3 so stale reviews become visible and re-review becomes explicit.
- Deliver User Story 4 so workspace overview progress stays honest for the current visible affected set.
- Finish with guard coverage, formatting, and the focused verification pack.
Parallel Team Strategy
- One contributor can take persisted-core tests and storage while another prepares the acceptance scaffolds.
- After Foundational work lands, one contributor can own dashboard mutation wiring while another prepares the registry rendering tests.
- Once User Story 2 is in place, one contributor can refine stale-review derivation while another prepares overview progress coverage.
- Rejoin for Polish so guard suites, copy review, formatting, and the 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]labels map directly to the user stories inspec.md.- The suggested MVP scope is Phase 1 through Phase 3 only.
- 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.