# Implementation Plan: Spec 335 - Restore Run Detail / Post-Execution Proof Productization - **Branch**: `335-restore-run-detail-post-execution-proof-productization` - **Date**: 2026-05-29 - **Spec**: `specs/335-restore-run-detail-post-execution-proof-productization/spec.md` - **Input**: User-provided draft + repo inspection for truth (RestoreRun/OperationRun/EvidenceSnapshot + current Filament view implementation) ## Summary Refactor the Restore Run detail surface into a decision-first post-execution result/proof/evidence view. This work is UI/productization only: - derive a top-level "restore result decision" contract from existing persisted fields (`restore_runs.results`, `restore_runs.metadata`, `restore_runs.operation_run_id`) and (when present) linked `evidence_snapshots` - render one default-visible hierarchy: status/reason/impact/next action first; proof/evidence state explicit; diagnostics collapsed - keep raw payloads and diagnostics behind disclosure - preserve RBAC, tenant/workspace isolation, and existing route/context behavior No restore execution backend changes are in scope. ## Technical Context - **Language/Version**: PHP 8.4.x - **Primary Dependencies**: Laravel 12.x, Filament v5, Livewire v4 - **Storage**: PostgreSQL (tenant-owned `restore_runs`, `operation_runs`, `evidence_snapshots`) - **Testing**: Pest v4 + Livewire component testing; Browser tests for smoke/screenshots - **Validation Lanes**: confidence + browser - **Target Platform**: Laravel Sail (local); Dokploy (deploy) posture unchanged - **Project Type**: Laravel monolith under `apps/platform` - **Performance Goals**: avoid new expensive queries; prefer existing eager loads; only query evidence snapshots when an `operation_run_id` exists - **Constraints**: no new packages; no migrations unless explicitly justified and approved in-spec - **Scale/Scope**: one Filament view surface + related presenters/blade entries + tests/screenshots ## UI / Surface Guardrail Plan - **Guardrail scope**: changed operator-facing detail surface (dangerous workflow result/proof) - **Affected routes/pages/actions/states/navigation/panel/provider surfaces**: - Restore Run detail view (`RestoreRunResource` view page) - Restore result presentation (existing infolist entry view: `filament/infolists/entries/restore-results.blade.php`) - Restore proof/evidence presentation (new or reused proof-aside surface) - **Native vs custom classification summary**: native Filament page with shared primitives + a small amount of custom Blade in infolist entries - **Shared-family relevance**: status messaging + proof/evidence deep links; diagnostics disclosure; shared OperationRun/Evidence viewers - **State layers in scope**: page + detail + URL (optional dashboard context param already exists) - **Audience modes in scope**: operator-MSP; no customer-facing change - **Decision/diagnostic/raw hierarchy plan**: decision-first; diagnostics collapsed and secondary - **Raw/support gating plan**: collapsed disclosures; never default-show raw payloads, exception text, or Graph error details as primary message - **One-primary-action / duplicate-truth control**: exactly one dominant next action in the decision card; avoid repeating equivalent banners/cards in multiple sections - **Handling modes**: review-mandatory (truth boundary / dangerous-workflow UX) - **Special surface test profiles**: shared-detail-family + dangerous workflow proof surface - **Required tests or manual smoke**: Feature/Livewire tests for contract visibility + RBAC/isolation; Browser smoke for screenshots and dark mode - **Exception path and spread control**: if evidence is not repo-backed for restore runs, UI must state "unavailable" (do not invent) - **Active feature PR close-out entry**: Guardrail / Exception / Smoke Coverage - **UI/Productization coverage decision**: existing route/archetype; cover via Spec 335 screenshots + Feature/Browser tests ## Shared Pattern & System Fit - **Cross-cutting feature marker**: yes (proof/evidence link semantics, decision-first status hierarchy) - **Systems touched**: - `App\Support\RestoreSafety\RestoreSafetyResolver` (result attention truth) - `App\Support\Badges\BadgeRenderer` (status/evidence badge semantics) - `App\Support\OperationRunLinks` + `OperationRunResource` (proof deep link) - `EvidenceSnapshotResource` (evidence deep link, when present) - **Shared abstractions reused**: reuse existing copy/badges and link resolvers; do not create new global status frameworks - **New abstraction introduced?**: optional, narrow presenter for the Restore Run detail decision contract (derived only, no persistence) - **Bounded deviation / spread control**: any presenter must live feature-locally and remain a pure derived view-model (no caching, no global registry) ## OperationRun UX Impact - Link UX only: the Restore Run detail page will expose "Operation proof" and deep-link to the existing OperationRun view. - No start/enqueue/dedupe semantics change. - URLs must be generated via existing link helpers (`OperationRunLinks` / Filament resource `getUrl(...)`) to preserve workspace/environment context. ## Data / Migrations - No migrations planned. - No new persisted fields planned. - Evidence is read-only: if evidence snapshots are present for the linked `operation_run_id`, show them; otherwise show honest "unavailable". ## Implementation Approach ### Phase 1 - Repo Truth (pre-work) - Document restore run model fields/statuses and result structures in `repo-truth-map.md`. - Document the visible result/proof state machine in `restore-result-state-contract.md`. - Confirm existing Restore Run view implementation and tests (current infolist entries and `RestoreResultAttentionSurfaceTest`). ### Phase 2 - Result Presenter / View Model (derived only) - If needed, introduce a derived presenter that returns the UI contract: - status label + reason + impact + primary next action - operation proof state + URL (when authorized) - post-run evidence state + URL (when repo-backed) - result summary counts (from `restore_runs.metadata` and `restore_runs.results`) - diagnostics default = collapsed ### Phase 3 - Detail Page UI - Switch Restore Run view from "entries list" toward a main/aside layout: - Main: decision card + result summary + item outcomes (table) + secondary run details - Aside: proof panel (source backup, target environment, requested by, operation proof, post-run evidence, audit trail) + diagnostics disclosure - Ensure raw payloads remain behind disclosure. ### Phase 4 - Proof/Evidence Links - Operation proof: - show status and link to OperationRun view when the restore run is linked to an operation run - show "unavailable" when no operation run exists - Evidence: - query evidence snapshots for the restore run's `operation_run_id` (tenant-scoped) and surface state + link when present - otherwise show "unavailable" (no fake "recovery verified") ### Phase 5 - Tests + Browser Screenshots - Add/extend Feature tests to assert: - decision question and status label for key states - operation proof and evidence states are explicit - diagnostics collapsed by default; raw payload not visible by default - tenant/workspace isolation and capability gating (deny-as-not-found vs forbidden semantics preserved) - Add a Browser smoke/screenshot test that captures the required screenshot set under the Spec 335 artifact path. ## Validation Commands Planned (narrow) commands for implementation review: ```bash cd apps/platform ./vendor/bin/sail artisan test \ tests/Feature/Filament/Spec335RestoreRunDetailProductizationTest.php \ tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php \ --compact ``` ```bash cd apps/platform ./vendor/bin/sail php vendor/bin/pest \ tests/Browser/Spec335RestoreRunDetailProductizationSmokeTest.php \ --compact ``` ```bash cd apps/platform ./vendor/bin/sail pint --dirty git diff --check ```