Some checks failed
Main Confidence / confidence (push) Failing after 1m20s
## 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
68 lines
5.6 KiB
Markdown
68 lines
5.6 KiB
Markdown
# Research: Assignment Hygiene & Stale Work Detection
|
|
|
|
## Decision 1: Add a dedicated hygiene report instead of stretching `My Findings` or intake
|
|
|
|
**Decision**: Create a new canonical admin-plane page at `/admin/findings/hygiene` rather than adding one more fixed view to `My Findings` or the intake queue.
|
|
|
|
**Rationale**: `My Findings` already answers the personal execution question and intake already answers the shared unassigned-backlog question. Hygiene is a third operator question: which assigned or in-progress findings are no longer in a healthy workflow path across visible tenants. Mixing that into either existing surface would blur their current decision role.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Add a `Needs repair` filter to `My Findings`. Rejected because broken assignments often no longer belong to the current operator, so the personal queue would still miss the cross-tenant repair problem.
|
|
- Add another fixed mode to intake. Rejected because intake is explicitly about pre-assignment backlog, not unhealthy assigned work.
|
|
|
|
## Decision 2: Reuse the existing workspace overview signal pattern
|
|
|
|
**Decision**: Extend `WorkspaceOverviewBuilder` with one findings hygiene signal rather than creating a new dashboard widget family.
|
|
|
|
**Rationale**: The repository already exposes `my_findings_signal` from `WorkspaceOverviewBuilder`, and `/admin` is already the accepted discoverability surface for workspace-wide findings follow-up. A second signal in the same builder keeps counts, phrasing, and drill-in behavior in one place.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Build a dedicated Livewire widget. Rejected because the current overview already has a signal builder pattern and this feature does not need a new widget framework.
|
|
- Make the report discoverable only through navigation. Rejected because the spec explicitly wants a small overview signal that exposes hidden workflow decay before operators start browsing deeper pages.
|
|
|
|
## Decision 3: Use one narrow `FindingAssignmentHygieneService`
|
|
|
|
**Decision**: Add one focused service that owns hygiene classification, filtering, and unique-count aggregation for both the report and the overview signal.
|
|
|
|
**Rationale**: This feature has two real concrete consumers of the same derived truth: the canonical report and the overview signal. Duplicating issue classification in both places would drift quickly. A narrow service is the smallest justified shared seam and does not require a generic workflow-health framework.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Duplicate the queries in the report page and `WorkspaceOverviewBuilder`. Rejected because tenant-visible scope, multi-reason counting, and stale-work anchoring would diverge under maintenance.
|
|
- Introduce a broader workflow-health engine. Rejected because findings are the only real consumer today.
|
|
|
|
## Decision 4: Keep broken-assignment truth bounded to current entitlement and existing user lifecycle
|
|
|
|
**Decision**: In v1, classify `broken assignment` from two existing truths only: the assignee no longer has current tenant entitlement, or the assignee user record is soft-deleted. Do not introduce absence, capacity, or shift scheduling models.
|
|
|
|
**Rationale**: The repository already enforces tenant membership as the true work boundary, and `User` already uses `SoftDeletes`. Those are real current truths. Anything broader would require new product modeling and would violate the spec's narrow scope.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Add an explicit operator-availability state or calendar. Rejected because it introduces a new workflow domain and new persistence unrelated to the current slice.
|
|
- Treat every owner-only finding as broken. Rejected because owner-only accountability is already a valid state under Spec 219 and belongs outside this hygiene slice unless assignment is actually broken.
|
|
|
|
## Decision 5: Derive stale work from workflow activity, not observation freshness
|
|
|
|
**Decision**: Derive `stale in progress` from workflow activity anchors such as `in_progress_at`, `reopened_at`, and the latest existing finding workflow audit event (`finding.assigned`, `finding.in_progress`, `finding.reopened`) rather than from `last_seen_at` or generic `updated_at`.
|
|
|
|
**Rationale**: Observation pipelines update `last_seen_at` and may touch the record during recurring detection, which would falsely calm truly stale operator work. The stale question here is whether workflow moved, not whether the problem was re-observed by the system.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Use `last_seen_at`. Rejected because recurring detection would reset the stale window even when no operator work happened.
|
|
- Use `updated_at`. Rejected because model updates are broader than workflow activity and would make stale classification depend on incidental writes.
|
|
- Add a new `last_workflow_activity_at` column. Rejected because the spec explicitly prefers derivation over new persistence.
|
|
|
|
## Decision 6: Keep repair on the existing finding detail surface
|
|
|
|
**Decision**: The hygiene report remains read-first and uses row click to drill into the existing tenant finding detail route for repair.
|
|
|
|
**Rationale**: The current findings workflow already has audited assignment and lifecycle actions on the detail surface. Recreating those actions on the hygiene report would create a second mutation surface and complicate action hierarchy, RBAC, and audit semantics.
|
|
|
|
**Alternatives considered**:
|
|
|
|
- Add inline reassignment actions to the report. Rejected because the report would stop being a pure repair-identification surface and would duplicate the existing finding workflow UI.
|
|
- Add a bulk repair action. Rejected because the spec explicitly keeps automation and redistribution out of scope for v1. |