TenantAtlas/specs/254-remove-acknowledged-compat/spec.md
ahmido b511b08371
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m0s
feat: remove findings acknowledged compatibility and unify canonical operation types (#296)
This PR removes the legacy "acknowledged" status compatibility for findings and unifies the canonical operation types (e.g., transitioning from baseline_capture to baseline.capture). It includes updated tests, models, and services to reflect these changes.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #296
2026-04-29 07:34:39 +00:00

284 lines
36 KiB
Markdown

# Feature Specification: Remove Legacy Acknowledged Finding Status Compatibility
**Feature Branch**: `254-remove-acknowledged-compat`
**Created**: 2026-04-29
**Status**: Draft
**Input**: User description: "Prepare the next repo-based cleanup slice that removes legacy acknowledged finding-status compatibility and collapses findings workflow semantics onto canonical triaged or open handling without changing customer-facing workflow scope or reintroducing repair tooling."
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
- **Problem**: TenantPilot still carries two parallel findings workflow languages. The product treats `triaged` as the canonical operator meaning, but productive code, shared queries, status filters, badges, role mappings, and workflow tests still preserve `acknowledged` compatibility as if it were an active workflow truth.
- **Today's failure**: Operators and maintainers can still encounter `acknowledged` as a current finding status through shared helpers, filter options, badge labels, capability aliases, and findings-derived summary logic. That weakens workflow clarity, keeps RBAC language inconsistent, and makes shared counts and previews harder to trust.
- **User-visible improvement**: Tenant and workspace operators see one canonical findings workflow language. Status badges, filters, summary counts, helper text, and workflow actions consistently speak in `new`, `triaged`, `in_progress`, `reopened`, `resolved`, `closed`, and `risk_accepted` terms only.
- **Smallest enterprise-capable version**: Remove acknowledged compatibility end to end from productive findings status constants and helpers, shared query helpers, shared filter and badge catalogs, capability registry and role mappings, workflow-facing tests, and findings-derived summary surfaces while leaving the rest of the findings lifecycle unchanged.
- **Explicit non-goals**: No backfill-runtime-surface removal in this slice, no broader findings lifecycle redesign, no new states, no migration shim, no historical data migration, no verification-acknowledgement cleanup, no onboarding-verification terminology rewrite, and no new customer-facing workflow surface.
- **Permanent complexity imported**: Net negative. The slice removes a legacy status branch, a capability alias, catalog special-casing, and acknowledged-specific workflow expectations. The only enduring obligation is focused regression coverage that proves one canonical status path remains across findings workflows and findings-derived summaries.
- **Why now**: This candidate remains explicitly open in both product sources and is still repo-proven in productive code. It is smaller and more implementation-ready than creation-time invariant hardening, and it does not depend on an external product decision like External Support Desk / PSA Handoff.
- **Why not local**: The compatibility drift is not confined to one screen or helper. It spans the `Finding` model, workflow service, shared filter catalog, badge language, capability registry, role mappings, canonical summary builders, and workflow-facing tests. A local rename would leave inconsistent product truth in other entry points.
- **Approval class**: Cleanup
- **Red flags triggered**: Multiple micro-specs for one domain. Defense: this slice is intentionally limited to canonical status and RBAC vocabulary cleanup only, while creation-time invariants and external support handoff remain explicit follow-up candidates.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 1 | Wiederverwendung: 2 | **Gesamt: 11/12**
- **Decision**: approve
## Selection Rationale
- `Remove Legacy Acknowledged Finding Status Compatibility` is still active in [docs/product/spec-candidates.md](/Users/ahmeddarrazi/Documents/projects/wt-plattform/docs/product/spec-candidates.md#L172) and [docs/product/implementation-ledger.md](/Users/ahmeddarrazi/Documents/projects/wt-plattform/docs/product/implementation-ledger.md#L183) and remains a concrete semantics blocker instead of a speculative cleanup.
- Repo truth still shows acknowledged drift in the canonical findings model and workflow seams, including `Finding::STATUS_ACKNOWLEDGED`, `Finding::openStatusesForQuery()`, `FilterOptionCatalog::findingStatuses()`, `Capabilities::TENANT_FINDINGS_ACKNOWLEDGE`, and findings-derived summary builders.
- This slice is narrower and safer than `Enforce Creation-Time Finding Invariants` because it removes visible and shared workflow ambiguity first without widening generator hardening or recurrence rules.
- `Cross-Tenant Compare and Promotion v1` is not the next preparation target here because the repo already has refreshed Spec 043 ready for later implementation work.
- `External Support Desk / PSA Handoff` stays deferred because it still depends on a concrete external-desk target and broader commercialization workflow decisions, while this cleanup is fully repo-based today.
## Spec Scope Fields *(mandatory)*
- **Scope**: tenant + canonical-view
- **Primary Routes**:
- `/admin/t/{tenant}/findings`
- `/admin/t/{tenant}/findings/{record}`
- existing canonical `/admin` summary and inbox surfaces that derive open-finding counts or previews from shared findings queries
- existing findings table and filter surfaces that use shared finding-status catalog options
- existing tenant review, review-pack, and support-diagnostic surfaces only where they render findings-derived open-work summaries, counts, or disclosure text
- **Data Ownership**:
- Tenant-owned `Finding` and related `FindingException` truth remain canonical and keep required `workspace_id` plus `tenant_id` anchors.
- Workspace, canonical summary, review/report, and diagnostic consumers stay derived over tenant-owned findings truth; this feature introduces no new persistence, no mirror entity, and no migration data store.
- Historical pre-production findings rows do not justify a compatibility table, alias, or fallback reader.
- **RBAC**:
- Tenant membership remains the isolation boundary for findings visibility and surviving finding workflow mutations.
- Canonical findings workflow permissions stay capability-first and tenant-scoped; `tenant_findings.acknowledge` is removed rather than preserved as an alias.
- Non-members remain deny-as-not-found and entitled members missing surviving findings capabilities remain forbidden on the affected mutation paths.
For canonical-view specs, the spec MUST define:
- **Default filter behavior when tenant-context is active**: Canonical `/admin` summary and inbox surfaces that launch from tenant context continue to prefilter to the current tenant, but they must do so with canonical open-status handling only and without an acknowledged compatibility branch.
- **Explicit entitlement checks preventing cross-tenant leakage**: Existing workspace membership and visible-tenant filtering remain authoritative on canonical summary surfaces. The cleanup must not widen findings queries or previews beyond entitled tenants while removing acknowledged compatibility.
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
- **Cross-cutting feature?**: yes
- **Interaction class(es)**: status messaging, workflow helper text, shared badges, shared filter vocabularies, canonical summary counts and previews, capability language
- **Systems touched**: `App\Models\Finding`, `App\Services\Findings\FindingWorkflowService`, `App\Support\Filament\FilterOptionCatalog`, `App\Support\Auth\Capabilities`, `App\Services\Auth\RoleCapabilityMap`, existing findings resource surfaces, existing findings-derived canonical summary builders, `App\Services\TenantReviews\TenantReviewSectionFactory`, and `App\Support\SupportDiagnostics\SupportDiagnosticBundleBuilder`
- **Existing pattern(s) to extend**: shared finding-status helpers, shared filter and badge catalogs, existing findings workflow actions, existing capability registry, and existing canonical summary builders remain the only supported paths
- **Shared contract / presenter / builder / renderer to reuse**: `Finding::openStatuses()`, shared `BadgeCatalog` finding-status semantics, `FilterOptionCatalog::findingStatuses()`, the canonical capability registry, and existing summary builders that already derive open findings from shared helpers
- **Why the existing shared path is sufficient or insufficient**: the shared paths are sufficient once the legacy acknowledged branch is removed. They are the reason this cleanup must land centrally instead of through page-local exceptions or label overrides.
- **Allowed deviation and why**: none
- **Consistency impact**: triage wording, open counts, badges, filters, review/report disclosure text, diagnostic issue summaries, disabled helper text, and role guidance must all converge on the same canonical finding-status language in the same slice.
- **Review focus**: reviewers must verify that no productive code path, shared filter, badge label, capability alias, review/report disclosure, diagnostic summary, or workflow-facing test still treats `acknowledged` as current findings workflow truth.
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
- **Touches OperationRun start/completion/link UX?**: no
- **Shared OperationRun UX contract/layer reused**: `N/A`
- **Delegated start/completion UX behaviors**: `N/A`
- **Local surface-owned behavior that remains**: existing findings and summary surfaces remain read/write or read-only according to their current workflows; no `OperationRun` start semantics are introduced or removed by this status cleanup.
- **Queued DB-notification policy**: `N/A`
- **Terminal notification path**: `N/A`
- **Exception required?**: none
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
N/A - no shared provider or platform seam is widened. This slice only removes legacy findings workflow compatibility inside the existing findings domain.
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|---|---|---|---|---|---|---|
| Tenant findings register and detail: remove acknowledged wording from statuses, filters, and workflow affordances | yes | Native Filament + shared workflow primitives | row actions, header actions, badges, filters | list, detail, action state | no | Canonical triage language only |
| Canonical findings-derived summaries: governance inbox, workspace overview, customer health, and similar previews use canonical open-status handling only | yes | Native Filament + shared summary builders | dashboard cards, inbox previews, counters, drilldowns | page, widget, query state | no | Summary counts and previews stop carrying a hidden acknowledged branch |
| Shared findings status filters and badges: remove legacy acknowledged option and label | yes | Shared badge and filter catalog primitives | status messaging, filter vocabulary, badge semantics | catalog, table filter state | no | No `legacy acknowledged` affordance remains on productive findings surfaces |
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Tenant findings register and detail | Primary Decision Surface | Decide how to triage or continue work on a finding | canonical status, severity, due or SLA signals, responsibility, and canonical workflow actions | evidence, history, related runs, and exception detail after opening the finding | Primary because this is where tenant operators act on findings today | Keeps findings work centered on one canonical lifecycle path | Removes a parallel acknowledged label that competes with the real next action |
| Canonical findings-derived summaries | Secondary Context Surface | Decide where follow-up exists before drilling into findings work | counts, previews, and urgency signals derived from canonical open statuses only | the findings register or detail after navigation | Not primary because these surfaces route operators into findings work rather than owning the mutations themselves | Keeps overview or inbox surfaces honest about what is actually open | Removes mismatched counts and pseudo-open summary branches |
## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Tenant findings register and detail | operator-MSP | canonical findings status, responsibility, due state, and workflow affordances | history, evidence, exception detail, and related runs after opening the record | raw or support-only detail remains on existing deeper routes and capability gates | `Triage finding` or continue canonical workflow | low-level evidence and audit detail stay secondary | status is stated once in canonical terms and deeper sections add evidence rather than alternate vocabulary |
| Canonical findings-derived summaries | operator-MSP | canonical counts, previews, and urgency signals only | secondary drilldowns to the findings register and detail | raw evidence is never the default content on the summary surface | `Open findings` | detailed evidence and audit context stay on deeper surfaces | summaries describe open work once and rely on the findings register for detailed truth |
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Tenant findings register and detail | List / Table / Bulk | CRUD / List-first Resource | Open a finding and continue the canonical workflow | full-row navigation to finding detail | required | existing row `More` actions and detail-header actions only | existing destructive-like actions remain in grouped or detail-header placements | `/admin/t/{tenant}/findings` | `/admin/t/{tenant}/findings/{record}` | tenant context, status filters, responsibility, due state | Findings / Finding | canonical findings workflow state and urgency | none |
| Canonical findings-derived summaries | Monitoring / Queue / Workbench | Context-first summary and preview shell | open a filtered findings view for the relevant tenant or queue | card or preview drilldown into the findings register | forbidden | secondary links only | none | existing canonical `/admin` summary and inbox pages | `/admin/t/{tenant}/findings` | workspace context, tenant filter, preview scope | Findings follow-up / Findings follow-up | where open work exists under the canonical status set | none |
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Tenant findings register and detail | Tenant operator | Decide how to triage, assign, continue, resolve, close, or risk-accept a finding | List/detail | What should I do next with this finding? | canonical status, severity, responsibility, due or SLA state, and current workflow affordances | evidence, exception history, audit context, related operations | lifecycle, urgency, responsibility, governance validity | TenantPilot only for the existing findings workflow actions | Triage, Start progress, Assign, Resolve, Risk accept | existing destructive-like workflow actions only |
| Canonical findings-derived summaries | Workspace or portfolio operator | Decide where follow-up exists before drilling into findings work | Summary and preview | Where is open findings work waiting right now? | canonical counts, previews, due urgency, and tenant context | deeper findings detail after navigation | lifecycle and urgency only | none on the summary surface itself | Open findings | none |
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
- **Test purpose / classification**: Feature, Unit, Heavy-Governance
- **Validation lane(s)**: fast-feedback, confidence, heavy-governance
- **Why this classification and these lanes are sufficient**: focused feature coverage proves canonical findings workflows and findings-derived summaries stop exposing acknowledged semantics, while narrow unit coverage proves the shared status helper, filter catalog, and capability cleanup stay centralized. One retained heavy-governance guard layer remains appropriate because status-like badge/filter drift can reappear through shared seams even after the main behavior is corrected.
- **New or expanded test families**: focused findings workflow cleanup coverage, focused findings-summary consistency coverage, and bounded filter or capability cleanup coverage. No browser family is introduced.
- **Fixture / helper cost impact**: low and likely net-neutral to slightly negative. Acknowledged-only fixtures and compatibility expectations should be consolidated or deleted instead of adding new heavy setup.
- **Heavy-family visibility / justification**: retained shared guard coverage for status-like tokens and filter-catalog usage remains explicit so a local reintroduction of acknowledged semantics cannot survive through shared UI seams. No new heavy-governance family is introduced.
- **Special surface test profile**: standard-native-filament, global-context-shell
- **Standard-native relief or required special coverage**: standard Filament and domain coverage are sufficient for the findings resource and canonical summaries. Required extra proof is shared guard coverage for badge and filter drift.
- **Reviewer handoff**: reviewers must confirm that acknowledged disappears together from the model helper, workflow rules, shared filter options, shared badge language, role/capability vocabulary, and summary counts or previews. They must also confirm that verification acknowledgement and onboarding acknowledgement remain untouched.
- **Budget / baseline / trend impact**: net-neutral to slightly negative because the slice should remove acknowledged-only compatibility expectations rather than widen the suite.
- **Escalation needed**: none
- **Active feature PR close-out entry**: Guardrail
- **Planned validation commands**:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/RemoveAcknowledgedCompatibilityWorkflowTest.php tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php tests/Unit/Support/GovernanceInbox/GovernanceInboxSectionBuilderTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Findings/FindingStatusSemanticsTest.php tests/Unit/Support/Filament/FindingStatusFilterCatalogTest.php tests/Feature/Auth/RemoveAcknowledgedCapabilityAliasTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoAdHocStatusBadgesTest.php tests/Feature/Guards/FilamentTableStandardsGuardTest.php`
## RBAC / Isolation Considerations
- Tenant findings mutations remain tenant-scoped and follow existing deny-as-not-found versus forbidden semantics: non-members remain `404`, entitled members missing a surviving findings capability remain `403` on mutation.
- Canonical `/admin` summary and inbox surfaces continue to derive only from tenants the actor can see in the current workspace. Removing acknowledged compatibility must not broaden canonical previews or counts beyond the current visible-tenant boundary.
- `tenant_findings.acknowledge` is removed rather than preserved as an alias. Canonical findings workflow language stays capability-first and centered on the surviving findings capabilities.
- This slice does not add a new role family, a new authorization plane, or a new hidden compatibility bypass.
## Auditability
- No new audit action ID is introduced by this cleanup.
- Existing findings workflow audit actions such as triage, assignment, in-progress, resolve, close, reopen, and risk acceptance remain the canonical audit language for surviving workflow actions.
- Pre-production historical acknowledgement fields or audit rows do not justify a compatibility renderer, label shim, or preserved active-workflow vocabulary.
- The implementation should ensure that operator-facing surfaces do not continue to advertise `acknowledged` as a current workflow outcome merely because historical audit or fixture data once used it.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Use One Canonical Findings Workflow Language (Priority: P1)
As a tenant operator, I want findings surfaces to speak in one canonical workflow language so I can triage and continue work without guessing whether `acknowledged` and `triaged` still mean different things.
**Why this priority**: This is the core user-facing value of the cleanup. If findings still speak two different workflow languages, the slice has failed.
**Independent Test**: Open the findings register and detail for a tenant with open findings and verify that statuses, filters, badges, and workflow affordances use canonical findings vocabulary only.
**Acceptance Scenarios**:
1. **Given** an entitled tenant operator opens the findings register, **When** the page renders, **Then** no current status badge, filter option, or helper text exposes `acknowledged` as a valid findings workflow state.
2. **Given** an open finding is ready for triage or progress, **When** the operator uses the surviving workflow affordances, **Then** the workflow uses canonical `triaged` semantics rather than an acknowledge alias.
3. **Given** a finding has already reached a terminal state, **When** the operator opens it, **Then** the terminal states remain unchanged and no new replacement state is introduced.
---
### User Story 2 - Keep Summary Counts, Reports, and Diagnostics Honest (Priority: P1)
As a workspace or portfolio operator, I want shared counts, previews, review/report disclosures, and diagnostic summaries to match the findings register so I can trust what is actually open without a hidden acknowledged branch skewing the numbers.
**Why this priority**: Shared summary drift is one of the main reasons this cleanup cannot stay local. If summaries, review/report disclosures, diagnostics, and lists diverge, operators lose trust in the overview surfaces.
**Independent Test**: Compare the findings register with the affected canonical summary and inbox surfaces plus findings-derived review/report and support-diagnostic consumers for the same tenant or workspace context and verify that the same canonical open-status set drives all of them.
**Acceptance Scenarios**:
1. **Given** a canonical summary surface shows open findings work for a tenant, **When** the operator drills into the findings register, **Then** the summary counts and previews align with the same canonical open-status set.
2. **Given** the operator changes tenant or workspace context, **When** canonical summaries reload, **Then** they continue to derive findings work only from canonical open statuses and the currently entitled tenant set.
3. **Given** a tenant review, review-pack, or support-diagnostic surface renders findings-derived open-work disclosure, **When** the operator opens that surface, **Then** the disclosure text, counts, and issue grouping use the same canonical open-status set and do not present `acknowledged` as current work.
---
### User Story 3 - Keep RBAC Language Canonical (Priority: P2)
As a tenant manager or owner, I want role guidance and capability-driven findings actions to use one canonical permission language so workflow help and disabled states stay understandable.
**Why this priority**: The acknowledged alias is not only a status problem. It also keeps role and action guidance inconsistent across the same workflow.
**Independent Test**: Review capability-driven findings surfaces and role expectations after the cleanup and verify that they reference surviving findings capabilities only.
**Acceptance Scenarios**:
1. **Given** a tenant member can triage findings, **When** the findings UI explains or gates the action, **Then** it refers to the canonical triage capability and not an acknowledge alias.
2. **Given** a tenant member lacks the required surviving capability, **When** they attempt the affected findings action, **Then** the existing forbidden behavior remains and no acknowledge-specific permission branch is used.
### Edge Cases
- Local or historical pre-production rows may still contain `acknowledged`; this slice does not add a migration shim, fallback reader, or preserved UI label to keep that branch alive.
- Removing acknowledged from shared helpers must update list surfaces, summary counts, preview queries, filters, and badges together; otherwise the cleanup would create a new mismatch instead of removing one.
- Verification-check acknowledgement and onboarding-verification acknowledgement are separate domains and must not be renamed or removed as collateral damage in this slice.
- Resolved, closed, and risk-accepted findings behavior remains distinct and must not be collapsed while removing the acknowledged compatibility path.
## Requirements *(mandatory)*
**Constitution alignment (LEAN-001 / STATE-001 / SPEC-GATE-001):** This is a pre-production cleanup slice. It removes a legacy findings workflow branch rather than introducing new state, persistence, or abstraction. Compatibility shims, fallback readers, historical fixture preservation, and capability aliases are out of scope.
**Constitution alignment (XCUT-001 / BADGE-001):** Because the drift survives in shared status helpers, shared filter catalogs, shared badge language, and shared summary builders, the cleanup must land through the shared paths themselves. No page-local override or secondary presenter may keep acknowledged alive.
**Constitution alignment (RBAC-UX):** Tenant membership and capability rules stay unchanged except for removing the acknowledged alias from the findings capability vocabulary. Non-members remain `404`; entitled members missing the surviving capability remain `403` on mutations.
**Constitution alignment (TEST-GOV-001):** Proof stays in focused feature, unit, and bounded heavy-governance guard coverage. The slice should remove acknowledged-only expectations rather than creating a broader or heavier new test family.
**Constitution alignment (UI-FIL-001 / UI-NAMING-001 / DECIDE-001 / OPSURF-001):** Findings surfaces remain native Filament or shared summary surfaces. Canonical findings vocabulary must stay consistent across badges, filters, helper text, row actions, disabled states, and drilldown summaries without introducing a new local status language.
### Functional Requirements
- **FR-254-001**: The system MUST retire `acknowledged` as a productive findings workflow status and remove any status helper that treats it as a current canonical findings state.
- **FR-254-002**: Shared open-status query helpers and findings-derived summary builders MUST rely on the canonical open findings status set only and MUST NOT preserve a hidden acknowledged compatibility branch.
- **FR-254-003**: Shared findings filter catalogs, status badges, and related helper text MUST stop exposing `acknowledged` or `legacy acknowledged` as a valid findings workflow affordance.
- **FR-254-004**: Findings workflow actions and guards MUST authorize and mutate against canonical triage semantics only; the active findings workflow must not require or preserve an acknowledge alias.
- **FR-254-005**: The canonical capability registry, role mappings, and workflow-facing authorization expectations MUST remove `tenant_findings.acknowledge` rather than keeping it as a stale alias.
- **FR-254-006**: Productive code paths and workflow-facing tests MUST stop writing, expecting, or advertising `acknowledged` as a valid current findings workflow status.
- **FR-254-007**: Existing findings flows remain functional and in scope only for regression protection across `new`, `triaged`, `in_progress`, `reopened`, `resolved`, `closed`, and `risk_accepted` outcomes.
- **FR-254-008**: The feature MUST NOT reintroduce repair tooling, backfill semantics, new workflow states, migration shims, fallback readers, or historical compatibility logic to preserve the removed acknowledged branch.
- **FR-254-009**: The feature MUST NOT alter verification-check acknowledgement, onboarding-verification acknowledgement, or other non-finding acknowledgement domains unless a path directly depends on findings status compatibility, in which case that dependency must be removed instead of widening the slice.
- **FR-254-010**: Tenant-owned findings keep existing `workspace_id` plus `tenant_id` ownership anchors; no new persisted alias, auxiliary mapping table, or compatibility truth is introduced.
## UI Action Matrix *(mandatory when Filament is changed)*
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Findings resource list/detail | `app/Filament/Resources/FindingResource.php` and related pages | no acknowledge-named action or helper text remains; surviving workflow utilities keep canonical wording | full-row click to finding detail remains canonical | existing canonical findings workflow actions only | existing grouped bulk actions only, with no acknowledged vocabulary | existing empty state remains unchanged | existing detail-header workflow actions keep canonical wording only | `N/A` | yes, unchanged for surviving workflow actions | Remove acknowledged vocabulary from filters, badges, disabled helper text, and action guidance without introducing a replacement action |
| Canonical findings summaries and inbox shells | existing `/admin` pages and widgets using shared findings summary builders | no new header actions; drilldown links only | same-page cards, counters, or preview links remain canonical | none | none | existing empty states remain, but they must not mention acknowledged compatibility | `N/A` | `N/A` | no new audit event | This slice updates counts, previews, and wording only |
### Key Entities *(include if feature involves data)*
- **Canonical finding status**: The current findings lifecycle language used on productive findings surfaces and queries. After this cleanup it consists only of the surviving canonical statuses already present in the findings workflow.
- **Findings-derived summary surface**: Any canonical `/admin` overview, inbox, widget, or preview surface that derives open findings work from the shared finding-status helper rather than from a local list of status strings.
- **Findings capability mapping**: The shared capability and role-mapping truth that determines which tenant members can use the surviving findings workflow actions.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Zero productive findings filters, badges, helper texts, or workflow affordances expose `acknowledged` as a current findings workflow status.
- **SC-002**: Zero supported findings permissions or role mappings expose `tenant_findings.acknowledge` after the cleanup.
- **SC-003**: All in-scope findings-derived summary surfaces and findings register surfaces use the same canonical open-status set during regression validation.
- **SC-004**: Representative regression proof still passes for the surviving findings workflow from `new` through `triaged`, `in_progress`, `resolved`, and `risk_accepted` outcomes without introducing a replacement compatibility branch.
## Dependencies
- The canonical findings model and workflow seams where acknowledged compatibility still survives, including the shared findings status helper, workflow service, filter catalog, and capability registry.
- Existing findings-derived summary builders that currently rely on shared open-status helpers for inbox, health, and preview surfaces.
- Existing findings resource and workflow-facing tests that still preserve or assert acknowledged semantics.
## Assumptions
- The current repo truth treats `triaged` as the canonical operator-facing findings workflow semantics and keeps `acknowledged` only as cleanup debt.
- LEAN-001 still applies because the product remains pre-production; historical or local findings rows do not justify compatibility behavior in this slice.
- Spec 253 already covers the adjacent backfill-runtime-surface cleanup, so this slice should not reopen that work while cleaning status semantics.
- Cross-Tenant Compare and Promotion is already refreshed as Spec 043 and is therefore not the next open preparation target here.
- Verification-check acknowledgement remains a separate domain and must not be pulled into this findings cleanup.
## Risks
- Hidden acknowledged residues may still survive in shared summary builders, status badges, or old test fixtures even after the main findings workflow seam is cleaned.
- Local or stale pre-production data containing acknowledged may surface unexpected failures if implementation removes compatibility before all relevant fixtures and productive write paths are updated together.
- Overbroad cleanup could accidentally touch verification or onboarding acknowledgement semantics, which would violate the intended slice boundary.
## Out of Scope
- Removing or revisiting the already-separated backfill-runtime-surface cleanup slice
- Enforcing creation-time finding invariants or generator hardening beyond what is needed to stop preserving acknowledged compatibility
- Broader findings lifecycle redesign, new workflow states, or new customer-facing workflow surfaces
- Historical data migration, translation helpers, fallback readers, or compatibility-specific test preservation
- Verification-check acknowledgement, onboarding acknowledgement UX, or non-finding acknowledgement domains
- External Support Desk / PSA Handoff or other commercialization workflow work
## Follow-up Candidates
1. `Enforce Creation-Time Finding Invariants` remains the next findings hardening candidate after this semantics cleanup because generator and recurrence guarantees still need explicit protection.
2. `External Support Desk / PSA Handoff` remains an explicit deferred candidate for commercialization flow maturity once the repo names a concrete external desk target.
3. `Cross-Tenant Compare and Promotion v1` remains covered by refreshed Spec 043 and should continue on that track instead of being reopened inside this cleanup slice.