# Implementation Plan: Remove Findings Lifecycle Backfill Runtime Surfaces **Branch**: `253-remove-findings-backfill-runtime-surfaces` | **Date**: 2026-04-28 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/spec.md` **Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/spec.md` **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts. ## Summary - Remove all shipped findings lifecycle backfill runtime and product surfaces by deleting the owning backfill service, jobs, commands, and registry traces instead of hiding labels locally. - Preserve the normal findings workflow exactly as-is for triage, assignment, progress, resolve, risk acceptance, ownership, SLA, due-date, and reviewable finding behavior, with regression proof kept explicit. - Keep the slice narrow: acknowledged-status cleanup and creation-time lifecycle invariant hardening remain separate follow-up specs, and OperationRun semantics are touched only by removing one obsolete runbook path rather than inventing a new run UX abstraction. ## Technical Context **Language/Version**: PHP 8.4 (Laravel 12) **Primary Dependencies**: Laravel 12 + Filament v5 + Livewire v4 + Pest; existing `UiEnforcement`, `OperationUxPresenter`, `OperationRunService`, `OperationCatalog`, `SystemOperationRunLinks`, `OperationRunLinks`, `AuditRecorder`, `WorkspaceAuditLogger`, and `PlatformCapabilities` **Storage**: PostgreSQL existing `findings`, `operation_runs`, `audit_logs`, and related runtime tables only; no new persistence, migration, or data backfill is planned **Testing**: Pest feature tests plus narrow unit and guard coverage **Validation Lanes**: fast-feedback, confidence, heavy-governance **Target Platform**: Sail-backed Laravel web application with tenant `/admin/t/{tenant}` surfaces, platform `/system` surfaces, and Artisan command/runtime entry points **Project Type**: web **Performance Goals**: after cleanup, no supported surface may enqueue or start `findings.lifecycle.backfill`; surviving findings workflows retain their current performance profile; the slice should reduce runtime and test surface rather than add new overhead **Constraints**: LEAN-001 replacement over compatibility shims; no replacement repair surface; no findings semantics redesign; no data migration; preserve current `404` vs `403` isolation semantics; no new Filament panel/provider work; no new assets or `filament:assets` deploy changes **Scale/Scope**: 1 cleanup slice touching 3 operator-facing surfaces, 2 console entry points, 1 shared runbook service cluster, 3 dedicated jobs, capability/operation/triage traces, and the backfill-specific test and docs footprint ## UI / Surface Guardrail Plan - **Guardrail scope**: changed surfaces - **Native vs custom classification summary**: native Filament plus existing shared action and run UX primitives - **Shared-family relevance**: header actions, runbook launch cards, operation labeling, operational-control and paused-state messaging, command/runtime entry points - **State layers in scope**: page, action/modal, detail/read-model - **Audience modes in scope**: operator-MSP, support-platform - **Decision/diagnostic/raw hierarchy plan**: decision-first / diagnostics-second / support-raw-third - **Raw/support gating plan**: existing capability-gated diagnostics only; no new raw or support surface is introduced - **One-primary-action / duplicate-truth control**: remove the maintenance CTA so tenant findings pages keep only canonical findings workflow actions and system pages keep only supported runbooks and supported controls - **Handling modes by drift class or surface**: review-mandatory - **Repository-signal treatment**: review-mandatory - **Special surface test profiles**: standard-native-filament, monitoring-state-page - **Required tests or manual smoke**: functional-core, state-contract - **Exception path and spread control**: none; source-trace removal is mandatory wherever shared registries or helper paths still emit findings backfill semantics - **Active feature PR close-out entry**: Guardrail ## Shared Pattern & System Fit - **Cross-cutting feature marker**: yes - **Systems touched**: `App\Filament\System\Pages\Ops\Runbooks`, `App\Filament\Resources\FindingResource\Pages\ListFindings`, `App\Console\Commands\TenantpilotBackfillFindingLifecycle`, `App\Console\Commands\TenantpilotRunDeployRunbooks`, `App\Services\Runbooks\FindingsLifecycleBackfillRunbookService`, `App\Services\Runbooks\FindingsLifecycleBackfillScope`, `App\Jobs\BackfillFindingLifecycleJob`, `App\Jobs\BackfillFindingLifecycleWorkspaceJob`, `App\Jobs\BackfillFindingLifecycleTenantIntoWorkspaceRunJob`, `App\Support\OperationCatalog`, `App\Support\Auth\PlatformCapabilities`, `App\Services\SystemConsole\OperationRunTriageService`, `App\Support\Livewire\TrustedState\TrustedStatePolicy`, `App\Support\Ui\ActionSurface\ActionSurfaceExemptions`, `Database\Seeders\PlatformUserSeeder`, and the related findings/runbook/console/control tests - **Shared abstractions reused**: `UiEnforcement`, `OperationUxPresenter`, `OpsUxBrowserEvents`, `OperationRunLinks`, `SystemOperationRunLinks`, `OperationRunService`, `OperationCatalog`, `AuditRecorder`, and `WorkspaceAuditLogger` - **New abstraction introduced? why?**: none; this is a subtractive cleanup that removes one bounded operation family and its traces - **Why the existing abstraction was sufficient or insufficient**: the existing shared abstractions are sufficient for surviving findings workflows and surviving operations. The cleanup must converge those shared families back to supported product truth instead of layering a replacement backfill path or compatibility wrapper on top. - **Bounded deviation / spread control**: none; where a shared catalog, capability registry, triage list, or test helper still names `findings.lifecycle.backfill`, the source trace itself must be removed instead of locally masked ## OperationRun UX Impact - **Touches OperationRun start/completion/link UX?**: yes - **Central contract reused**: existing shared OperationRun UX layer for surviving operation types only - **Delegated UX behaviors**: `N/A` for the removed findings lifecycle backfill path after cleanup; queued toast, `View run` or `Open operation` links, dedupe messaging, browser events, and terminal notifications remain unchanged for every other operation type - **Surface-owned behavior kept local**: none for the removed path - **Queued DB-notification policy**: `N/A` for the removed path - **Terminal notification path**: existing central lifecycle mechanism for surviving operations remains unchanged - **Exception path**: none ## Provider Boundary & Portability Fit - **Shared provider/platform boundary touched?**: no - **Provider-owned seams**: `N/A` - **Platform-core seams**: `N/A` - **Neutral platform terms / contracts preserved**: `N/A` - **Retained provider-specific semantics and why**: none - **Bounded extraction or follow-up path**: `N/A` ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Read/write separation: PASS - the slice removes shipped write entry points and introduces no new mutating path - Inventory-first / snapshots-second: PASS - inventory, backups, and snapshots are untouched - Graph contract path: PASS - no Microsoft Graph surface changes are involved - Deterministic capabilities: PASS - one platform capability constant and its seeder grant are removed rather than expanded; no new capability namespace is introduced - RBAC-UX: PASS - `/system` remains platform-only, `/admin/t/{tenant}` remains tenant-scoped, non-members stay `404`, in-scope users missing capability on surviving actions stay `403`, and cleanup must not widen or hide unrelated authorization semantics - Workspace isolation / tenant isolation: PASS - findings remain tenant-owned with required `workspace_id` and `tenant_id` anchors; no new cross-tenant surface or leakage path is introduced - OperationRun observability / Ops-UX: PASS - the feature removes one `OperationRun` start surface only; no new run type, no new feedback surface, and no local start UX dialect are introduced - OperationRun lifecycle ownership: PASS - no new lifecycle transition path is introduced; surviving operations remain service-owned - Automation / locking: PASS - queued backfill runtime paths are deleted rather than extended - Data minimization: PASS - no new persisted data or audit payload family is introduced - Test governance (`TEST-GOV-001`): PASS - proof remains in narrow feature plus unit lanes, with one retained heavy-governance source-scanning guard kept explicit because operational-control bypass residue must still be blocked after the control key and runbook service are removed - Proportionality (`PROP-001`) and no premature abstraction (`ABSTR-001`): PASS - the feature removes an obsolete runtime family and adds no new abstraction layer - Persisted truth (`PERSIST-001`): PASS - no new table, entity, artifact, or alias layer is introduced - Behavioral state (`STATE-001`): PASS - no new status or reason family is added; acknowledged cleanup remains a separate follow-up - UI semantics (`UI-SEM-001`): PASS - no new presentation taxonomy is added; labels disappear together with the runtime path - Shared pattern first (`XCUT-001`): PASS - the cleanup converges shared runbook, action, audit, and operation-label families by deletion instead of creating a parallel exception path - Provider boundary (`PROV-001`): PASS - no provider/platform seam changes are introduced - V1 explicitness / few layers (`V1-EXP-001`, `LAYER-001`): PASS - the narrowest solution is direct replacement and deletion, not shims or wrappers - Bloat check (`SPEC-DISC-001`, `BLOAT-001`): PASS - the slice is explicitly subtractive and keeps broader semantics work separate - Filament-native UI (`UI-FIL-001`): PASS - touched surfaces stay native Filament pages and actions; no custom UI framework or asset registration is needed - Global search rule: PASS - no new searchable resource is added, and this cleanup only removes a header action from the existing findings resource rather than changing its search contract - Panel/provider registration: PASS - Filament v5 remains on Livewire v4, and no panel or provider registration change is planned; Laravel 12 provider registration remains in `bootstrap/providers.php` if ever needed later - Asset strategy: PASS - no new panel or shared assets are planned, so no additional `filament:assets` deploy work is introduced ## Test Governance Check - **Test purpose / classification by changed surface**: Feature for system runbook removal, tenant findings action removal, console-entry removal, and findings workflow regression; Unit or guard coverage for operation catalog, capability, triage-list, and source-scanning trace cleanup - **Affected validation lanes**: fast-feedback, confidence, heavy-governance - **Why this lane mix is the narrowest sufficient proof**: the business truth is server-side surface removal plus unchanged canonical findings workflow behavior. Fast-feedback and confidence cover the runtime behavior directly. One retained heavy-governance source-scanning guard is still needed because the cleanup removes an operational-control key and runbook-service entry point that the existing guard already protects from ad-hoc bypass drift. - **Narrowest proving command(s)**: - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/OpsRunbooks/RemoveFindingsLifecycleBackfillRunbookSurfaceTest.php tests/Feature/System/OpsControls/RemoveFindingsLifecycleBackfillControlTraceTest.php tests/Feature/Findings/RemoveFindingsLifecycleBackfillActionTest.php tests/Feature/Console/RemoveFindingsLifecycleBackfillCommandsTest.php` - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationCatalog/RemoveFindingsLifecycleBackfillCatalogTraceTest.php tests/Unit/Support/Auth/RemoveFindingsLifecycleBackfillCapabilityTraceTest.php` - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php` - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingWorkflowRegressionTest.php` - **Fixture / helper / factory / seed / context cost risks**: remove or collapse backfill-only fixtures, control activations, and command test setup; keep findings workflow fixtures opt-in and local to regression tests - **Expensive defaults or shared helper growth introduced?**: no; expected net-negative because a dedicated backfill family and its source-scanning guard expectations should shrink - **Heavy-family additions, promotions, or visibility changes**: no new heavy family is added, but one existing heavy-governance guard remains explicit in the plan because the cleanup still depends on `tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php` - **Surface-class relief / special coverage rule**: standard-native-filament and monitoring-state-page relief are sufficient; assert absence and no side effects rather than browser-only choreography - **Closing validation and reviewer handoff**: reviewers should rerun the targeted commands, including the retained heavy-governance bypass guard, verify that no UI, CLI, deploy, control, catalog, capability, triage, trusted-state, or action-surface trace remains for `findings.lifecycle.backfill`, and confirm representative triage, assignment, progress, resolve, risk acceptance, ownership, SLA, and due-date findings flows still behave unchanged - **Budget / baseline / trend follow-up**: expected net decrease in focused feature and guard surface - **Review-stop questions**: did implementation leave a no-op compatibility shell, keep a hidden operation alias, preserve a dead blocked-state branch after the control key was already removed, or widen into acknowledged-status cleanup or lifecycle invariant redesign? - **Escalation path**: reject-or-split - **Active feature PR close-out entry**: Guardrail - **Why no dedicated follow-up spec is needed**: the cleanup is a bounded subtractive slice; deeper findings semantics and creation-time invariant work already have explicit follow-up candidates instead of hidden spillover ## Project Structure ### Documentation (this feature) ```text specs/253-remove-findings-backfill-runtime-surfaces/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── checklists/ │ └── requirements.md ├── contracts/ │ └── findings-backfill-runtime-surface-removal.contract.yaml └── tasks.md ``` ### Source Code (repository root) ```text apps/platform/ ├── app/ │ ├── Console/Commands/ │ │ ├── TenantpilotBackfillFindingLifecycle.php │ │ └── TenantpilotRunDeployRunbooks.php │ ├── Filament/ │ │ ├── Resources/FindingResource/Pages/ListFindings.php │ │ └── System/Pages/Ops/Runbooks.php │ ├── Jobs/ │ │ ├── BackfillFindingLifecycleJob.php │ │ ├── BackfillFindingLifecycleTenantIntoWorkspaceRunJob.php │ │ └── BackfillFindingLifecycleWorkspaceJob.php │ ├── Services/ │ │ ├── Runbooks/FindingsLifecycleBackfillRunbookService.php │ │ ├── Runbooks/FindingsLifecycleBackfillScope.php │ │ └── SystemConsole/OperationRunTriageService.php │ └── Support/ │ ├── Auth/PlatformCapabilities.php │ ├── Livewire/TrustedState/TrustedStatePolicy.php │ ├── OperationCatalog.php │ └── Ui/ActionSurface/ActionSurfaceExemptions.php ├── database/seeders/PlatformUserSeeder.php └── tests/ ├── Feature/ │ ├── Console/Spec113/DeployRunbooksCommandTest.php │ ├── Filament/Spec113/AdminFindingsNoMaintenanceActionsTest.php │ ├── Findings/OperationalControlFindingsBackfillGateTest.php │ ├── OperationalControls/NoAdHocOperationalControlBypassTest.php │ ├── System/OpsControls/OperationalControlManagementTest.php │ └── System/OpsRunbooks/ │ ├── FindingsLifecycleBackfillPreflightTest.php │ ├── FindingsLifecycleBackfillStartTest.php │ ├── OpsUxStartSurfaceContractTest.php │ └── OperationalControlRunbookGateTest.php └── Unit/Support/OperationalControls/OperationalControlCatalogTest.php ``` **Structure Decision**: Single Laravel web application. The implementation slice is subtractive and should stay inside the existing system page, tenant findings page, console command, shared runbook service, registry, and test directories instead of creating a new namespace or framework. ## Complexity Tracking No constitution violations are expected. This feature should reduce permanent complexity by deleting a productized repair path, its queue jobs, and its trace surface. ## Proportionality Review - **Current operator problem**: the repo still productizes a findings lifecycle repair path through runbooks, tenant findings actions, commands, operation labels, and tests even though current finding generators already write the required lifecycle fields directly - **Existing structure is insufficient because**: a local hide or feature flag would leave the service, jobs, commands, operation labels, triage support, and backfill-only tests alive, so the product would keep advertising deleted behavior through other surfaces - **Narrowest correct implementation**: delete the owning backfill service and job cluster, remove the UI and command entry points, remove capability and operation traces, and keep canonical findings workflows unchanged with targeted regression proof - **Ownership cost created**: negative; maintenance burden, suite cost, and operator confusion should all decrease - **Alternative intentionally rejected**: compatibility shims, no-op deploy command shells, historical alias preservation, or folding acknowledged-status cleanup and lifecycle invariant hardening into the same slice - **Release truth**: current-release truth ## Phase 0 — Research (output: `research.md`) See: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/research.md` Goals: - Confirm the narrowest deletion boundary across system UI, tenant UI, CLI, deploy/runtime hooks, jobs, registry traces, and test artifacts. - Confirm that LEAN-001 requires removal over compatibility shims for the backfill service, commands, operation aliases, and historical run UX support. - Record the partial operational-control cleanup already present in the repo so implementation removes remaining dead branches instead of reintroducing the control key. - Keep acknowledged-status cleanup and creation-time lifecycle invariants explicitly deferred while documenting the regression contract for normal findings workflows. ## Phase 1 — Design & Contracts (outputs: `data-model.md`, `contracts/`, `quickstart.md`) See: - `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/data-model.md` - `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/contracts/findings-backfill-runtime-surface-removal.contract.yaml` - `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/253-remove-findings-backfill-runtime-surfaces/quickstart.md` Design focus: - Remove the `Rebuild Findings Lifecycle` system runbook card, preflight, run modal, and related `OperationRun` launch UX from `Runbooks.php`. - Remove the tenant findings header action `Backfill findings lifecycle` and its queued, paused, and `Open operation` messaging from `ListFindings.php` while leaving canonical findings workflow actions untouched. - Delete `TenantpilotBackfillFindingLifecycle`, and delete `TenantpilotRunDeployRunbooks` if its only shipped responsibility remains lifecycle backfill. - Delete `FindingsLifecycleBackfillRunbookService` and the dedicated workspace plus tenant jobs that exist only to support the removed runtime path. - Remove `findings.lifecycle.backfill` traces from `PlatformCapabilities`, `PlatformUserSeeder`, `OperationCatalog`, `OperationRunTriageService`, test guards, docs, and backfill-specific feature tests. - Remove `FindingsLifecycleBackfillScope.php`, the backfill-specific trusted-state markers in `TrustedStatePolicy.php`, and the backfill-specific action-surface evidence in `ActionSurfaceExemptions.php` so no hidden surface or helper residue still implies support. - Treat current operational-control residue as cleanup input: the control catalog already rejects `findings.lifecycle.backfill`, so remaining blocked-start branches and tests should be removed rather than normalized. - Keep historical `OperationRun` and `AuditLog` rows as tolerated legacy data without adding alias layers, migrations, or new UI promises. ## Phase 1 — Agent Context Update After Phase 1 artifacts are generated, update Copilot context from the plan: - `/Users/ahmeddarrazi/Documents/projects/wt-plattform/.specify/scripts/bash/update-agent-context.sh copilot` ## Phase 2 — Implementation Outline (tasks created in `/speckit.tasks`) - Remove the system runbook entry points and the tenant findings header action for lifecycle backfill. - Delete the dedicated CLI and deploy/runtime command entry points for lifecycle backfill. - Delete the shared runbook service and the dedicated workspace or tenant backfill jobs. - Remove capability, seeder, operation-catalog, and system-console triage traces for `findings.lifecycle.backfill`. - Rewrite or delete backfill-only tests and docs, then add narrow absence plus regression coverage that proves the path stays gone while canonical findings workflows still work. - Verify no compatibility shim, no-op command shell, or replacement repair path survives the cleanup. ## Constitution Check (Post-Design) Re-check target: PASS. The post-design shape must still be net-negative complexity, contain no new persistence or abstraction, preserve Livewire v4 plus Filament v5 conventions, leave provider registration unchanged in `bootstrap/providers.php`, keep global search behavior unchanged, and keep the validation burden inside fast-feedback and confidence plus one explicit retained heavy-governance bypass guard only.