TenantAtlas/specs/225-assignment-hygiene/tasks.md
ahmido 12fb5ebb30
Some checks failed
Main Confidence / confidence (push) Failing after 1m20s
feat: add findings hygiene report and control catalog layering (#264)
## Summary
- add the workspace-scoped findings hygiene report, overview signal, and supporting classification service for broken assignments and stale in-progress work
- add Spec 225 artifacts and focused findings hygiene test coverage alongside the new Filament page and workspace overview wiring
- align product roadmap and spec candidates around the layered canonical control catalog, CIS library, and readiness model
- extend SpecKit constitution and templates with the XCUT-001 shared-pattern reuse guidance

## Notes
- validation commands and implementation close-out notes are documented in `specs/225-assignment-hygiene/plan.md` and `specs/225-assignment-hygiene/quickstart.md`
- this PR targets `dev` from `225-assignment-hygiene`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #264
2026-04-22 12:26:18 +00:00

217 lines
17 KiB
Markdown

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