# Tasks: Assignment Hygiene & Stale Work Detection **Input**: Design documents from `/specs/225-assignment-hygiene/` **Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `contracts/assignment-hygiene.logical.openapi.yaml`, `quickstart.md` **Tests**: Required. This feature changes runtime behavior in a new canonical Filament findings page, a shared derived-query service, workspace overview signal rendering, and tenant-safe disclosure behavior, so Pest coverage must be added in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php`, `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php`, and `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php`. **Operations**: No new `OperationRun` is introduced. The feature remains read-only and reuses the existing tenant finding detail repair path plus current audit truth. **RBAC**: The canonical hygiene report and overview signal stay on the admin `/admin` plane, while repair drilldown stays on `/admin/t/{tenant}/findings/{finding}`. The implementation must preserve non-member and out-of-scope workspace `404`, tenant-safe suppression of hidden-tenant rows and counts inside an otherwise available report, in-scope missing-capability `403` on protected drilldown destinations, and the existing findings assign authorization on the tenant detail surface. **UI / Surface Guardrails**: `Findings hygiene report` is a `standard-native-filament` surface and the workspace overview signal is a `global-context-shell` seam. Both must keep one calm drill-in path only, with no inline mutation drift. **Filament UI Action Surfaces**: `FindingsHygieneReport` is a new read-only Filament page with one inspect model only: the finding. There must be no redundant `View` action, no inline repair action, no bulk action group, and no destructive action on the report surface. **Badges**: Existing finding lifecycle and severity semantics remain authoritative. Hygiene reasons remain plain-text reason labels in the report, so BADGE-001 is not extended and no page-local status mapping is introduced. **Organization**: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is `US1 -> US2 -> US3`, because broken-assignment visibility is the smallest MVP repair slice, stale-work detection builds on the same canonical report second, and overview discoverability is safest after the report truth is established. ## Test Governance Checklist - [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior. - [x] New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit. - [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented. - [x] Planned validation commands cover the change without pulling in unrelated lane cost. - [x] The declared surface test profile or `standard-native-filament` relief is explicit. - [x] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR. ## Phase 1: Setup (Report And Test Scaffolding) **Purpose**: Prepare the shared page, service, and focused regression files used across all stories. - [x] T001 [P] Create the findings hygiene page scaffold in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` - [x] T002 [P] Create the findings hygiene Blade shell in `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php` - [x] T003 [P] Create the shared hygiene service scaffold in `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` - [x] T004 [P] Create focused Pest scaffolding in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php`, `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php`, and `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php` **Checkpoint**: The shared page, Blade view, service, and focused test files exist and are ready for implementation work. --- ## Phase 2: Foundational (Blocking Report Route And Shared Classification Seam) **Purpose**: Establish the canonical route treatment, shared visible-tenant scope, and baseline report contract every story depends on. **⚠️ CRITICAL**: No user story work should begin until this phase is complete. - [x] T005 Add `/admin/findings/hygiene` to workspace-scoped tenant-selection bypass and navigation handling in `apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php` - [x] T006 Implement visible-tenant scoping, unique issue counting, and fixed reason filter baseline in `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` - [x] T007 Implement the canonical report table with default-visible tenant, finding summary, owner, assignee, due-state, hygiene reasons, last meaningful workflow activity columns, row drilldown into `FindingResource`, and read-first inspect behavior in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` - [x] T008 Add foundational tenant-safe report access, empty-report behavior for workspace members with zero visible hygiene scope, default-visible finding summary and last-activity coverage, and drilldown coverage in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php` **Checkpoint**: The canonical report route, shared hygiene query seam, and base tenant-safe read path are available for all stories. --- ## Phase 3: User Story 1 - See broken assignments in one repair view (Priority: P1) 🎯 MVP **Goal**: Show cross-tenant assigned findings that are no longer actionable because the current assignee cannot work them anymore. **Independent Test**: Seed assigned findings where the assignee lost tenant entitlement or the user was soft-deleted, open `/admin/findings/hygiene`, and verify one visible row per broken finding with owner context and safe drilldown. ### Tests for User Story 1 - [x] T009 [P] [US1] Add broken-assignment report visibility and hidden-tenant rows, counts, filter values, and empty-state suppression coverage in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php` - [x] T010 [P] [US1] Add broken-assignment classification coverage for entitlement loss and soft-deleted users in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php` ### Implementation for User Story 1 - [x] T011 [US1] Implement `broken assignment` classification from current tenant entitlement and soft-deleted assignee truth in `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` - [x] T012 [US1] Render finding summary, owner, assignee, due-state, last meaningful workflow activity, and plain-text `Broken assignment` reason visibility on the canonical report in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` and `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php` - [x] T013 [US1] Keep the report drill-in aligned to the existing tenant findings repair path in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` **Checkpoint**: User Story 1 is independently functional and operators can see broken assignments in one cross-tenant repair view. --- ## Phase 4: User Story 2 - Detect stalled in-progress work before it becomes hidden backlog (Priority: P1) **Goal**: Surface genuinely stalled `in_progress` work separately from healthy or merely overdue findings. **Independent Test**: Seed fresh and stale `in_progress` findings, open `/admin/findings/hygiene`, and verify that only stale work appears, overdue-but-active findings stay out, and one finding with two reasons remains one row. ### Tests for User Story 2 - [x] T014 [P] [US2] Add stale-work versus overdue-but-active and reopen-driven stale-reset classification coverage in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php` - [x] T015 [P] [US2] Add regression coverage that healthy assigned work and ordinary intake backlog remain excluded from the hygiene report in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php` - [x] T016 [P] [US2] Add fixed reason filter coverage for `All issues`, `Broken assignment`, and `Stale in progress` in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php` - [x] T017 [P] [US2] Add multi-reason single-row, unique-count, and filtered-empty-state `Clear tenant filter` CTA coverage in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php` and `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php` ### Implementation for User Story 2 - [x] T018 [US2] Derive last meaningful workflow activity from `in_progress_at`, `reopened_at`, and existing finding workflow audit events in `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` and `apps/platform/app/Services/Findings/FindingWorkflowService.php` - [x] T019 [US2] Implement `stale in progress` classification and multi-reason aggregation in `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` - [x] T020 [US2] Render finding summary, last meaningful workflow activity, and plain-text `Stale in progress` combined-reason visibility without introducing a new workflow taxonomy in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` and `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php` - [x] T021 [US2] Add the tenant-prefilter empty-state explanation and `Clear tenant filter` CTA in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php` and `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php` **Checkpoint**: User Story 2 is independently functional and stale in-progress work is distinguished from healthy or merely overdue findings. --- ## Phase 5: User Story 3 - Discover hygiene issues from the workspace overview (Priority: P2) **Goal**: Expose the canonical findings hygiene truth from `/admin` so operators can reach the repair surface without scanning multiple pages first. **Independent Test**: Seed visible hygiene issues and a zero-issue visible scope, open `/admin`, verify the attention-state summary, calm-state behavior, and CTA, and follow the signal into `/admin/findings/hygiene` with matching visible-scope truth. ### Tests for User Story 3 - [x] T022 [P] [US3] Add workspace overview signal count, descriptive summary from broken/stale counts, calm-state, visible-scope, and CTA routing coverage in `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php` ### Implementation for User Story 3 - [x] T023 [US3] Add the findings hygiene overview signal with unique issue counts, a short description derived from broken/stale counts, and CTA into the canonical report in `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php` - [x] T024 [US3] Reuse the canonical hygiene service count truth for the overview signal in `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php` and `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php` **Checkpoint**: User Story 3 is independently functional and the workspace overview reliably points operators into the canonical hygiene report. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Finish guardrail alignment, formatting, and focused verification across the full feature. - [x] T025 Review operator-facing vocabulary, UI Action Matrix conformance, and guardrail alignment in `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php`, `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php`, and `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php` - [x] T026 Run formatting for `apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php`, `apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php`, `apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php`, `apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php`, `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php`, `apps/platform/app/Services/Findings/FindingWorkflowService.php`, `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php`, `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php`, and `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php` with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - [x] T027 Run the focused verification workflow from `specs/225-assignment-hygiene/quickstart.md` against `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php`, `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php`, and `apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php` - [x] T028 Record the active feature PR close-out entry and proof commands in `specs/225-assignment-hygiene/plan.md` after implementation validation completes --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: Starts immediately and prepares the shared page, view, service, and focused Pest files. - **Foundational (Phase 2)**: Depends on Setup and blocks all user stories until the canonical report route, shared hygiene query seam, and base tenant-safe report contract exist. - **User Story 1 (Phase 3)**: Depends on Foundational completion and is the recommended MVP cut. - **User Story 2 (Phase 4)**: Depends on Foundational completion and extends the same canonical report with stale-work truth. - **User Story 3 (Phase 5)**: Depends on Foundational completion and reuses the same service truth to expose overview discoverability. - **Polish (Phase 6)**: Depends on all desired user stories being complete. ### User Story Dependencies - **US1**: No dependencies beyond Foundational. - **US2**: No hard dependency on US1 after Foundational, but it reuses the same report and service seams and should preserve the broken-assignment visibility already established there. - **US3**: No hard dependency on US1 or US2 after Foundational, but it must stay aligned with the canonical report truth they establish. ### Within Each User Story - Write the story tests first and confirm they fail before implementation is considered complete. - Keep `FindingAssignmentHygieneService.php` authoritative for classification and counting before duplicating logic in the page or overview builder. - Finish story-level verification before moving to the next priority slice. ### Parallel Opportunities - `T001`, `T002`, `T003`, and `T004` can run in parallel during Setup. - `T009` and `T010` can run in parallel for User Story 1. - `T014`, `T015`, `T016`, and `T017` can run in parallel for User Story 2. - `T022` and `T023` can run in parallel for User Story 3 once the foundational service seam is stable. --- ## Parallel Example: User Story 1 ```bash # User Story 1 tests in parallel T009 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php T010 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php ``` ## Parallel Example: User Story 2 ```bash # User Story 2 tests in parallel T014 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php T015 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php T016 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php T017 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php ``` ## Parallel Example: User Story 3 ```bash # User Story 3 signal work in parallel T022 apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php T023 apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php ``` --- ## Implementation Strategy ### MVP First (User Story 1 Only) 1. Complete Phase 1: Setup. 2. Complete Phase 2: Foundational. 3. Complete Phase 3: User Story 1. 4. Validate the feature against the focused US1 tests before widening the slice. ### Incremental Delivery 1. Ship US1 to close the hidden broken-assignment visibility gap. 2. Add US2 to distinguish stale execution from ordinary overdue follow-up. 3. Add US3 to make the canonical report discoverable from `/admin`. 4. Finish with guardrail review, formatting, and the focused verification pack. ### Parallel Team Strategy 1. One contributor can scaffold the page and view while another prepares the focused Pest suites. 2. After Foundational work lands, one contributor can implement broken-assignment classification while another prepares stale-work tests. 3. Overview-signal work can proceed in parallel with final report polish once the shared hygiene service and canonical report truth are stable. --- ## Notes - `[P]` tasks target different files and can be worked independently once upstream blockers are cleared. - `[US1]`, `[US2]`, and `[US3]` map directly to the feature specification user stories. - The suggested MVP scope is Phase 1 through Phase 3 only. - All implementation tasks above follow the required checklist format with task ID, optional parallel marker, story label where applicable, and exact file paths.