wip: restore readiness adapter updates

This commit is contained in:
Ahmed Darrazi 2026-06-20 11:13:24 +02:00
parent 9912d94563
commit 920f726ace
9 changed files with 972 additions and 4 deletions

View File

@ -828,7 +828,8 @@ private function supportingSignals(
$overview = is_array($requiredPermissions['overview'] ?? null) $overview = is_array($requiredPermissions['overview'] ?? null)
? $requiredPermissions['overview'] ? $requiredPermissions['overview']
: []; : [];
$providerPermissionsReady = $this->providerPermissionsTone($overview) === 'success'; $providerPermissionsValue = $this->providerPermissionsValue($overview);
$providerPermissionsTone = $this->providerPermissionsTone($overview);
$operationCount = (int) ($activeOperationSummary['count'] ?? 0); $operationCount = (int) ($activeOperationSummary['count'] ?? 0);
$operationsAction = $operationCount > 0 && is_string($activeOperationSummary['secondaryActionUrl'] ?? null) $operationsAction = $operationCount > 0 && is_string($activeOperationSummary['secondaryActionUrl'] ?? null)
? [ ? [
@ -878,8 +879,8 @@ private function supportingSignals(
$this->supportingSignal( $this->supportingSignal(
key: 'provider_permissions', key: 'provider_permissions',
label: 'Provider permissions', label: 'Provider permissions',
value: $providerPermissionsReady ? 'Ready' : 'Missing', value: $providerPermissionsValue,
tone: $providerPermissionsReady ? 'success' : 'danger', tone: $providerPermissionsTone,
action: $this->requiredPermissionsAction($tenant, $user, $this->overviewText('action_open_required_permissions')), action: $this->requiredPermissionsAction($tenant, $user, $this->overviewText('action_open_required_permissions')),
), ),
$this->supportingSignal( $this->supportingSignal(

View File

@ -7,11 +7,11 @@
use App\Models\OperationRun; use App\Models\OperationRun;
use App\Models\ProviderConnection; use App\Models\ProviderConnection;
use App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder; use App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder;
use App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder;
use App\Support\OperationCatalog; use App\Support\OperationCatalog;
use App\Support\OperationRunLinks; use App\Support\OperationRunLinks;
use App\Support\OperationRunOutcome; use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus; use App\Support\OperationRunStatus;
use App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use function Pest\Laravel\mock; use function Pest\Laravel\mock;
@ -278,6 +278,41 @@ function mockEnvironmentDashboardSummaryPermissions(array $overview = []): void
->and($attentionOperations['Permission posture check']['icon'] ?? null)->toBe('heroicon-m-key'); ->and($attentionOperations['Permission posture check']['icon'] ?? null)->toBe('heroicon-m-key');
}); });
it('keeps stale complete provider permissions out of missing supporting signals', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
mockEnvironmentDashboardSummaryPermissions([
'overall' => 'needs_attention',
'counts' => [
'missing_application' => 0,
'missing_delegated' => 0,
],
'freshness' => [
'is_stale' => true,
'last_refreshed_at' => now()->subDays(31)->toIso8601String(),
],
]);
$summary = app(EnvironmentDashboardSummaryBuilder::class)
->build($tenant, $user)
->toArray();
$kpis = collect($summary['kpis'])->keyBy('key');
$governanceStatus = collect($summary['governanceStatus'])->keyBy('key');
$supportingSignals = collect($summary['supportingSignals'])->keyBy('key');
$readinessDimensions = collect($summary['readinessDimensions'])->keyBy('key');
expect($kpis['missing_permissions']['value'] ?? null)->toBe(0)
->and($governanceStatus['provider_permissions']['value'] ?? null)->toBe('Needs attention')
->and($governanceStatus['provider_permissions']['tone'] ?? null)->toBe('warning')
->and($governanceStatus['provider_permissions']['description'] ?? null)->toContain('Required permissions currently look complete.')
->and($governanceStatus['provider_permissions']['description'] ?? null)->toContain('The verification snapshot is stale.')
->and($supportingSignals['provider_permissions']['value'] ?? null)->toBe('Needs attention')
->and($supportingSignals['provider_permissions']['tone'] ?? null)->toBe('warning')
->and($readinessDimensions['provider_permissions']['status'] ?? null)->toBe('Needs attention')
->and($readinessDimensions['provider_permissions']['tone'] ?? null)->toBe('warning');
});
it('shows calm honest fallbacks when no urgent tenant follow-up is visible', function (): void { it('shows calm honest fallbacks when no urgent tenant follow-up is visible', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner'); [$user, $tenant] = createUserWithTenant(role: 'owner');

View File

@ -0,0 +1,92 @@
# Requirements Quality Checklist: Restore Readiness Resolution Adapter v1
**Purpose**: Validate preparation artifacts before implementation starts.
**Created**: 2026-06-20
**Feature**: `specs/390-restore-readiness-resolution-adapter-v1/spec.md`
## Candidate Selection
- [x] Direct user-provided candidate source recorded.
- [x] Automatic queue status checked and summarized.
- [x] Deferred alternatives recorded.
- [x] Completed related specs identified as context only.
- [x] No completed historical spec was rewritten.
- [x] Spec number 390 intentionally selected from user draft and adjacent completed context.
## Scope Quality
- [x] Feature goal is clear and operator-facing.
- [x] Scope, Primary Routes, Data Ownership, and RBAC requirements are explicitly declared.
- [x] Mode B is selected as the default implementation mode.
- [x] Generic resolution framework is explicitly out of scope.
- [x] Adapter registry is explicitly out of scope.
- [x] Generic persistence is explicitly out of scope.
- [x] Review-publication resolution persistence reuse is explicitly forbidden.
- [x] Restore auto-execution from guidance actions is explicitly forbidden.
- [x] New navigation, dashboard, global search, and notification-center surfaces are explicitly out of scope.
## Requirements Completeness
- [x] User stories cover blocked, ready, persisted, and unauthorized states.
- [x] Functional requirements are testable.
- [x] Non-functional requirements are testable.
- [x] Edge cases include stale basis, unsaved wizard state, execution states, and legacy statuses.
- [x] Success criteria are measurable.
- [x] No unresolved blocking clarification is present.
- [x] Assumptions are documented.
## Existing-System Alignment
- [x] RestoreRun remains the persisted restore record.
- [x] RestoreSafetyResolver remains the source for checks/preview currentness concepts.
- [x] Restore Preview remains the preview owner.
- [x] OperationRun remains execution/evidence truth.
- [x] Restore Wizard remains the preparation input owner.
- [x] Existing tenant/workspace/environment scoping is preserved.
- [x] Existing view/manage capability split is preserved.
## UI and Filament Safety
- [x] Existing Restore create/view surfaces are the only planned UI surfaces.
- [x] Changed Restore create/view surfaces include UI/UX Surface Classification.
- [x] Changed Restore create/view surfaces include page contract fields and state ownership.
- [x] Durable UI/productization coverage update is required because UI impact is material.
- [x] Decision-first copy requirements are included.
- [x] Copy must state preparation actions do not execute Restore.
- [x] Filament v5 / Livewire v4 compliance is recorded in plan.
- [x] Laravel provider registration location is recorded in plan.
- [x] Global-search hard rule is recorded in plan and tasks.
- [x] Destructive-action confirmation rule is recorded in spec, plan, and tasks.
- [x] Asset strategy and `filament:assets` deployment condition are recorded.
- [x] Testing approach for Filament pages/actions is recorded.
## Data and Runtime Safety
- [x] No new migration is planned.
- [x] No new environment variable is planned.
- [x] No new queue worker is planned.
- [x] No scheduled command is planned.
- [x] No storage/volume change is planned.
- [x] No Microsoft Graph render-time call is planned.
- [x] Staging validation requirement is recorded.
## Testability
- [x] Unit test expectations cover readiness derivation.
- [x] Feature/Filament test expectations cover authorization and UI behavior.
- [x] Testing/lane/runtime impact includes lane classification, fixture cost, heavy-family decision, budget/trend expectation, and escalation outcome.
- [x] Query-count budget is measurable and has a validation task.
- [x] Stale guidance action protection is explicitly tested.
- [x] Execution confirmation/safety gate preservation is explicitly tested.
- [x] Browser smoke expectations are recorded for visible UI changes.
- [x] Validation commands are included.
## Implementation Readiness
- [x] Tasks are dependency-ordered.
- [x] Contract/spec-package artifacts are required before app code changes.
- [x] Provider seam classification and OperationRun UX contract reuse are covered.
- [x] Audit/evidence reuse verification is covered.
- [x] Stop conditions are explicit.
- [x] Delivery notes include required Filament output contract items.
- [x] Tasks avoid marking implementation work complete during preparation.

View File

@ -0,0 +1,329 @@
# Implementation Plan: Restore Readiness Resolution Adapter v1
**Branch**: `390-restore-readiness-resolution-adapter-v1`
**Spec**: `specs/390-restore-readiness-resolution-adapter-v1/spec.md`
**Created**: 2026-06-20
**Mode**: Mode B - Restore-local guidance on existing Restore surfaces
## Summary
Implement a Restore-owned readiness adapter that derives decision-first guidance from existing Restore state and shows the operator the next safe preparation or inspection action. The adapter must reuse existing RestoreRun, RestoreSafetyResolver, Restore Preview, confirmation, OperationRun, tenant scoping, and Filament surfaces.
The v1 implementation must not create a generic resolution engine, adapter registry, new persistence table, global search surface, or automatic execution path. Persisted generic resolution cases are deferred because current repo truth shows only review-publication-specific resolution persistence.
## Technical Context
**Language/Version**: PHP 8.4.15
**Framework**: Laravel 12.52.0
**Admin UI**: Filament 5.2.1
**Reactive UI**: Livewire 4.1.4
**Testing**: Pest 4.3.1 / PHPUnit 12
**Database**: PostgreSQL
**Local dev**: Laravel Sail first
**Package constraints**: Do not add dependencies without explicit approval.
Relevant existing code:
- `apps/platform/app/Models/RestoreRun.php`
- `apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php`
- `apps/platform/app/Support/RestoreRunStatus.php`
- `apps/platform/app/Filament/Resources/RestoreRunResource.php`
- `apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php`
- `apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ViewRestoreRun.php`
- `apps/platform/app/Filament/Resources/RestoreRunResource/Presenters/RestoreRunCreatePresenter.php`
- `apps/platform/app/Filament/Resources/RestoreRunResource/Presenters/RestoreRunDetailPresenter.php`
- `apps/platform/app/Support/Auth/Capabilities.php`
Relevant completed context specs:
- `specs/386-review-publication-resolution-workflow-v1/`
- `specs/387-review-publication-resolution-decision-ux-v1/`
- `specs/388-resolution-proof-currentness-contract-v1/`
- `specs/389-governance-inbox-resolution-intake-v1/`
These specs inform the decision-first pattern only. Their completed artifacts and review-publication persistence must not be rewritten.
## Constitution Check
- **Workspace first**: Pass. Guidance is scoped to existing workspace/tenant/environment RestoreRun surfaces.
- **RBAC first**: Pass with implementation requirement. View guidance must require view access; mutating preparation actions must require manage access server-side.
- **Audit first**: Pass with implementation requirement. User-triggered preparation mutations must preserve existing operation/audit evidence paths.
- **Restore safety**: Pass. Execution remains controlled by existing safety gates, confirmation, and OperationRun execution truth.
- **Spec before code**: Pass. This plan and tasks define implementation boundaries before app code changes.
- **Proportionality review**: Pass. New local state/action contracts are allowed; new persistence and generic frameworks are not.
## Filament v5 / Livewire v4 Compliance Plan
- Filament work must use Filament v5 APIs only.
- Livewire v4.0+ is required and present.
- Laravel 11+ panel providers must remain registered through `bootstrap/providers.php`; this feature does not require a new panel provider.
- `RestoreRunResource` already has a View page, satisfying the global-search hard rule if it remains globally searchable. If implementation touches global search behavior, explicitly verify or disable search.
- Destructive actions must use `Action::make(...)->action(...)` plus `->requiresConfirmation()`. This feature should not add destructive actions.
- Navigation-only actions must use `->url(...)` and must not be described as confirmed modal actions unless Filament v5 docs are verified.
- No new heavy global assets are planned. If assets are registered despite this plan, deploy must run `cd apps/platform && php artisan filament:assets`.
- Test pages/widgets/actions as Livewire components, not static resource classes.
## UI / Productization Guardrails
The feature touches existing operational UI, not marketing or landing content.
Required UI behavior:
- Use compact decision-first copy that fits existing Filament panel density.
- Keep Restore Wizard as the preparation input owner.
- Keep Restore Preview as the preview owner.
- Keep RestoreRun View as a status/evidence inspection surface, not a new workflow hub.
- Keep OperationRun links as evidence links only.
- Avoid a top-level dashboard, nav item, global search result, or notification center integration.
- Avoid visible instructional walls of text.
- Avoid implying that a preparation action executes or approves a restore.
UI coverage to update during implementation if the visible surface materially changes:
- Durable UI/productization coverage registry artifacts under `docs/ui-ux-enterprise-audit/` for the changed RestoreRun create/view surfaces.
- Existing UI coverage/report for RestoreRun create/view where those artifacts exist.
- `docs/ui-ux-enterprise-audit/target-experience-briefs/restore-safety-workflow.md` if existing documentation requires alignment, or an explicit checked target-brief no-change note inside the coverage update.
- Browser smoke notes for blocked, stale, ready, and read-only states.
Do not claim `No UI surface impact` for this feature unless the spec is updated first with a checked rationale. The default implementation path is to update UI coverage artifacts because RestoreRun create/view behavior changes.
## Shared Pattern and System Fit
This feature may introduce a Restore-specific support namespace, for example:
- `apps/platform/app/Support/RestoreReadinessResolution/`
Allowed local contracts:
- Restore readiness summary value object.
- Restore reason/action identifiers.
- Restore next-action planner.
- Restore guidance basis/fingerprint helper.
- Restore presenter adapter that converts readiness summaries into Filament-safe display data.
Disallowed contracts:
- Generic `ActionResolution` model or table.
- Generic adapter registry.
- Generic status taxonomy shared across unrelated domains.
- Review-publication resolution persistence reuse.
- Provider-specific Graph execution logic in the readiness layer.
## Data Model / Storage Plan
No database migration is expected.
Implementation must use existing persisted data:
- `restore_runs.requested_items`
- `restore_runs.preview`
- `restore_runs.results`
- `restore_runs.metadata`
- `restore_runs.group_mapping`
- `restore_runs.operation_run_id`
- `backup_sets`
- `operation_runs`
If implementation discovers that persistence is required to satisfy acceptance criteria, stop and update `spec.md`, `plan.md`, and `tasks.md` before creating any migration. The update must include a new proportionality review and rollback/forward plan.
## OperationRun UX Impact
OperationRun remains execution/evidence truth.
Implementation must:
- Reuse the central OperationRun Start UX Contract for any OperationRun-linked evidence or operation-entry affordance.
- Reuse existing OperationRun links/presenters where available.
- Show queued/running RestoreRun states as execution states, not preparation states.
- Avoid creating OperationRun records from the readiness guidance layer.
- Avoid queuing database notifications from the readiness guidance layer. Queued/terminal notifications remain owned by the existing lifecycle mechanism unless this spec is updated first.
- Avoid duplicate operation status rendering that conflicts with existing OperationRun UX.
- Treat this feature as deep-link/inspect-only for OperationRun. It must not create, queue, deduplicate, resume, block, or complete OperationRun records.
## Provider Boundary
The touched seam is platform-core presentation over existing RestoreRun, BackupSet, RestoreSafetyResolver, and OperationRun data. Provider-owned semantics remain inside existing Restore services, Graph contract registry, and provider integration seams.
The readiness adapter is provider-neutral within the current RestoreRun domain. It must not call Microsoft Graph directly and must not assume provider-specific restore capabilities beyond existing RestoreRun/BackupSet/preview data. Any provider-specific hotspot discovered during implementation must be resolved in-feature by keeping it behind existing provider-owned seams, or escalated as a follow-up spec if it would leak into platform-core contracts or vocabulary.
Provider expansion or provider-specific readiness plugins require a later spec.
## Security and Authorization Plan
Implementation must:
- Reuse existing workspace/tenant/environment scoping traits and policies used by RestoreRunResource.
- Require tenant view capability for inspection.
- Require tenant manage capability for mutating preparation actions.
- Reject stale actions server-side when the basis/fingerprint no longer matches.
- Avoid leaking inaccessible backup payload details, environment names, or OperationRun links.
- Preserve existing 403/404 distinction as used by existing RestoreRun pages.
## Testing Plan
### Unit Tests
Add focused tests for:
- Readiness summary derivation for missing checks.
- Readiness summary derivation for stale checks.
- Readiness summary derivation for missing preview.
- Readiness summary derivation for stale preview.
- Ready state with current checks and preview.
- Execution state for queued/running RestoreRun.
- Historical state for completed/partial/failed/cancelled/aborted RestoreRun.
- Deterministic next safe action ordering.
- Basis/fingerprint mismatch handling.
### Feature / Filament Tests
Add or update tests for:
- RestoreRun create wizard guidance in blocked, stale, and ready states.
- RestoreRun view guidance for persisted records.
- Read-only user can inspect permitted readiness details but cannot invoke mutating preparation actions.
- Manage user can invoke allowed preparation action through existing Restore action path.
- Existing final execution still requires confirmation and safety gate inputs.
- Global search hard rule remains satisfied or disabled if touched.
### Browser Smoke
Use the repository browser smoke pattern if the UI change is visible:
- Authorized manage user sees blocked guidance and next safe action.
- Authorized manage user sees stale preview guidance.
- Authorized manage user sees ready-for-confirmation guidance.
- Read-only user sees inspection-only affordances.
- No visible copy implies automatic execution.
### Test Governance / Runtime Impact
Implementation must keep test scope proportional:
- Unit lane proves Restore-local derivation and side-effect-free behavior.
- Feature/Filament lane proves authorization, wizard/view rendering, stale-action rejection, and execution-gate preservation.
- Browser lane is limited to feature-local visible workflow smoke for blocked, stale, ready, and read-only states.
- Fixture/context setup must stay opt-in and use existing factories/helpers. Do not introduce broad provider/workspace/membership defaults.
- No new heavy-governance test family is expected. If implementation creates one, stop and update the spec/plan/tasks first.
- Query-count validation must compare the Restore create/view render against the pre-feature fixture baseline and stay within the spec budget.
- Expected lane decision: `keep`. Escalate as `document-in-feature` only if measured runtime or fixture cost materially changes; use `follow-up-spec` for recurring structural cost.
### Validation Commands
Preferred full validation:
```bash
cd apps/platform && ./vendor/bin/sail artisan test
cd apps/platform && ./vendor/bin/sail pint --dirty
```
Focused validation should be added to implementation notes once concrete test paths exist.
## Project Structure
Expected implementation paths:
```text
apps/platform/app/Support/RestoreReadinessResolution/
apps/platform/app/Filament/Resources/RestoreRunResource.php
apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php
apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ViewRestoreRun.php
apps/platform/app/Filament/Resources/RestoreRunResource/Presenters/RestoreRunCreatePresenter.php
apps/platform/app/Filament/Resources/RestoreRunResource/Presenters/RestoreRunDetailPresenter.php
apps/platform/tests/Unit/Support/RestoreReadinessResolution/
apps/platform/tests/Feature/Filament/
apps/platform/tests/Feature/Restore/
```
Spec-package implementation support artifacts to create during implementation:
```text
specs/390-restore-readiness-resolution-adapter-v1/artifacts/current-restore-flow-inventory.md
specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-readiness-state-matrix.md
specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-requirement-map.md
specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-ui-copy-contract.md
```
No expected paths:
```text
apps/platform/database/migrations/*restore_readiness*
apps/platform/app/Models/*ResolutionCase*
apps/platform/app/Models/*ResolutionStep*
apps/platform/app/Support/ActionResolution/
apps/platform/app/Filament/Resources/*Resolution*
```
## Implementation Phases
### Phase 0 - Repo Verification
Verify current RestoreRun surfaces, policies, presenters, RestoreSafetyResolver methods, OperationRun link helpers, and test fixture patterns. Record findings in `artifacts/current-restore-flow-inventory.md`.
### Phase 1 - Local Contracts
Define Restore-local readiness states, reasons, next-action identifiers, and copy rules. Record the state matrix, requirement map, and UI copy contract in spec-package contract files before app code changes.
### Phase 2 - Readiness Derivation
Implement a side-effect-free readiness resolver/planner that consumes existing Restore state and safety resolver outputs. Unit test all state transitions and next-action priority.
### Phase 3 - Stale Basis Protection
Implement action basis/fingerprint protection for any mutating preparation action exposed by the guidance UI. Reject stale action attempts with a clear notification and no mutation.
### Phase 4 - Create Wizard Integration
Integrate guidance into the existing RestoreRun create wizard/presenter without replacing the wizard. Keep controls compact and use existing action semantics.
### Phase 5 - Persisted RestoreRun View Integration
Add local status/evidence guidance to the existing RestoreRun view page. Do not create persisted resolution cases.
### Phase 6 - Authorization and Evidence
Verify view/manage split, OperationRun link access, and no data leakage for inaccessible related records.
### Phase 7 - Validation
Run unit, feature, Filament, browser smoke, Pint, and static diff checks. Update coverage notes only where repo conventions require it.
## Complexity Tracking
| Potential complexity | Status | Mitigation |
| --- | --- | --- |
| New state/reason family | Accepted | Keep Restore-local and documented in contracts. |
| Generic resolution persistence | Rejected | Defer to later spec. |
| Adapter registry | Rejected | Use direct Restore-local support classes. |
| Extra navigation/global search | Rejected | Existing Restore surfaces only. |
| Execution bypass risk | Rejected | Existing confirmation/safety gates remain mandatory. |
| UI sprawl | Controlled | Decision-first compact guidance only. |
## Deployment Plan
Default deployment impact:
- No migration.
- No environment variable.
- No new queue worker.
- No new scheduler.
- No new storage volume.
- No new global frontend asset.
Validation and rollout:
- Validate in local Sail.
- Validate on Staging before Production because Restore is an Intune-critical workflow.
- Production promotion only after confirming no-auto-execute behavior, authorization behavior, and stale guidance rejection.
## Stop Conditions
Stop implementation and update the spec before continuing if any of the following becomes necessary:
- A new database table or migration.
- A generic resolution case abstraction.
- Reuse of review-publication resolution persistence for Restore.
- A new global navigation or dashboard surface.
- A new provider-specific restore backend.
- Direct Microsoft Graph calls from readiness derivation.
- Any execution path that bypasses existing final confirmation.

View File

@ -0,0 +1,355 @@
# Feature Specification: Restore Readiness Resolution Adapter v1
**Feature Branch**: `390-restore-readiness-resolution-adapter-v1`
**Created**: 2026-06-20
**Status**: Ready for implementation planning
**Input**: User-provided candidate draft at `/Users/ahmeddarrazi/Downloads/spec-390-restore-readiness-resolution-adapter-v1-improved.md`
## Candidate Selection Summary
Spec 390 is selected as a direct, user-provided manual candidate. It follows the completed resolution-readiness work in Specs 386 through 389 and applies the proven decision-first pattern to Restore preparation without turning it into a generic workflow framework.
The active automatic queue in `docs/product/spec-candidates.md` has no safe next-best-prep target remaining. Manual backlog alternatives were deferred because they either require explicit promotion or are broader than this bounded Restore-owned slice.
Completed-spec guardrail result:
- `specs/386-review-publication-resolution-workflow-v1/` is completed and remains historical context only.
- `specs/387-review-publication-resolution-decision-ux-v1/` is completed and remains historical context only.
- `specs/388-resolution-proof-currentness-contract-v1/` is completed and remains historical context only.
- `specs/389-governance-inbox-resolution-intake-v1/` is completed and remains historical context only.
- No existing `specs/390-restore-readiness-resolution-adapter-v1/` artifact existed before this preparation branch.
Current repo truth shows the persisted resolution tables are review-publication-specific (`review_publication_resolution_cases`, `review_publication_resolution_steps`) and are not an approved generic action-key storage foundation. Therefore this spec selects Mode B for v1: Restore-local readiness guidance on existing Restore surfaces. Persisted generic resolution cases for Restore are out of scope unless a later spec explicitly creates and approves a generic persistence foundation.
## Spec Candidate Check
| Dimension | Score | Rationale |
| --- | ---: | --- |
| Nutzen | 2 | Restore is a critical admin workflow where blocked preparation must be explainable and safe. |
| Dringlichkeit | 2 | Existing Restore code already has readiness gates, but the user-facing path from blocked state to next safe action is fragmented. |
| Scope | 2 | The v1 slice is bounded to existing RestoreRun create/view surfaces and local derived guidance. |
| Komplexitaetslast | 1 | The draft introduces readiness states, reason families, and action planning, so implementation must stay Restore-local. |
| Produktnaehe | 2 | The result directly improves restore operator workflow and safety. |
| Wiederverwendung | 1 | It reuses existing RestoreSafetyResolver, RestoreRun, OperationRun, and Filament surfaces, but must not reuse review-specific persistence. |
**Decision**: Approved as a bounded Core Enterprise feature with Mode B selected for v1.
**Scope shrink applied during preparation**:
- No generic workflow engine.
- No adapter registry.
- No new global navigation or global search surface.
- No automatic execution of Restore.
- No new persistence tables by default.
- No reuse of review-publication resolution persistence for Restore.
- No replacement of the Restore Wizard, RestoreSafetyResolver, Restore Preview, validation gates, confirmation, or OperationRun execution truth.
## Scope
### In Scope
- Derive a Restore-owned readiness summary from existing RestoreRun, wizard state, backup set, preview, checks, and OperationRun evidence.
- Show decision-first guidance when Restore cannot continue safely.
- Present deterministic next safe actions such as run checks, regenerate preview, review group mappings, review backup selection, open evidence, or return to confirmation when ready.
- Protect against stale guidance by tying guidance to the same basis/fingerprint concepts already used by Restore safety code.
- Support in-memory wizard state without creating orphaned persisted resolution cases.
- Support persisted RestoreRun records with local guidance on the existing view surface where the underlying record exists.
- Keep all execution truth inside existing Restore execution gates, confirmation, OperationRun, and safety validation.
### Out of Scope
- Generic resolution framework, adapter registry, or cross-domain workflow engine.
- Persisted generic resolution cases or steps for Restore.
- New restore-specific database tables.
- New top-level navigation, global search result type, dashboard widget, or notification center intake.
- Automatic Restore execution, queued execution from guidance actions, or bypass of confirmation.
- Replacement of RestoreSafetyResolver, existing preview generation, checks, or execution services.
- Microsoft Graph write calls from the readiness guidance layer.
- Broad redesign of Restore Wizard layout beyond the guidance and action affordances needed by this feature.
## Spec Scope Fields
- **Scope**: Existing tenant/environment-scoped Restore preparation and RestoreRun inspection surfaces in the Filament admin panel.
- **Primary Routes**:
- `GET admin/workspaces/{workspace}/environments/{environment}/restore-runs`
- `GET admin/workspaces/{workspace}/environments/{environment}/restore-runs/create`
- `GET admin/workspaces/{workspace}/environments/{environment}/restore-runs/{record}`
- **Route Names**:
- `filament.admin.resources.workspaces.{workspace}.environments.{environment}.restore-runs.index`
- `filament.admin.resources.workspaces.{workspace}.environments.{environment}.restore-runs.create`
- `filament.admin.resources.workspaces.{workspace}.environments.{environment}.restore-runs.view`
- **Data Ownership**: Existing `restore_runs`, `backup_sets`, and `operation_runs` remain the only persisted records involved. Restore readiness summary, reason, next action, and basis/fingerprint values are derived and non-persisted. Tenant-bound RestoreRun data remains scoped by workspace plus managed environment/tenant authorization; unsaved wizard state remains in-memory only.
- **RBAC Requirements**: Workspace/tenant/environment non-members must receive deny-as-not-found behavior through existing page/resource authorization. Members without view capability must not inspect readiness. Members without manage capability must not mutate preparation state and server-side execution must fail with capability denial. UI visibility is not authorization.
- **Canonical View Status**: This is not a new tenantless canonical view. Existing environment-scoped RestoreRun create/view surfaces remain the canonical operator surfaces for this feature.
## User Problem
Restore operators can reach blocked, stale, or incomplete preparation states where the platform prevents unsafe execution, but the next safe recovery action is not always obvious. This creates support risk and can lead to repeated previews, skipped checks, or confusion between "not ready" and "failed."
This feature makes the Restore preparation state understandable without weakening the existing safety gates.
## Primary Operator Copy Contract
The experience must use decision-first, safety-first language:
- "Restore can't continue yet."
- "Next safe action."
- "This will not execute the restore."
- "This guidance is based on the current restore scope and preview state."
- "The restore still requires final confirmation before execution."
The UI must avoid language that implies the readiness action executes the restore, approves a restore, or overrides a safety gate.
## Users and Permissions
| Actor | Capability expectation | Allowed by this spec |
| --- | --- | --- |
| Workspace member with tenant view access | Inspect Restore readiness and evidence for accessible tenant/environment records. | View guidance and evidence links only. |
| Workspace member with tenant manage access | Perform existing Restore preparation actions. | Run checks, generate/regenerate preview, update wizard preparation inputs through existing Restore UI paths. |
| User without workspace membership or environment access | No access. | Existing access checks continue to block the surface. |
| User without manage access | No mutation. | Guidance actions that mutate preparation state are hidden or blocked by policy/server checks. |
UI visibility is not authorization. All mutating preparation actions must still enforce server-side access checks.
## User Scenarios and Tests
### User Story 1 - Blocked Restore Shows the Next Safe Action (Priority: P1)
As an authorized restore operator, I want a blocked Restore preparation state to explain why Restore cannot continue and which safe action should happen next, so that I can recover without guessing.
**Acceptance Criteria**:
1. Given a Restore wizard state with missing or stale checks, when the operator reaches the preparation step, then the UI states that Restore cannot continue yet and shows "Run readiness checks" as the next safe action.
2. Given a Restore wizard state with a stale preview basis, when the operator reaches confirmation, then the UI blocks execution guidance and shows "Regenerate preview" as the next safe action.
3. Given a blocked state, when the operator sees the next safe action, then the copy states that the action will not execute the restore.
### User Story 2 - Current Readiness Allows Continuation Without Extra Friction (Priority: P1)
As an authorized restore operator, I want current checks and preview evidence to be recognized, so that I can continue to confirmation without unnecessary repeated work.
**Acceptance Criteria**:
1. Given current checks and preview that match the selected Restore scope, when the operator reviews readiness, then the UI shows the Restore is ready for final confirmation.
2. Given current evidence with an OperationRun link, when the operator inspects details, then the UI links to the existing evidence where allowed.
3. Given current readiness, when the operator proceeds, then existing final confirmation and execution gates still apply.
### User Story 3 - Persisted RestoreRun Records Explain Their State (Priority: P2)
As an operator reviewing a saved RestoreRun, I want the view page to explain whether the run is draft, previewed, pending, running, completed, failed, cancelled, or stale, so that I can decide what to inspect next.
**Acceptance Criteria**:
1. Given a draft or scoped RestoreRun with incomplete preparation, when an authorized user opens its view page, then the page shows local readiness guidance and next safe inspection/preparation action.
2. Given a queued or running RestoreRun, when an authorized user opens its view page, then the page emphasizes existing OperationRun execution truth rather than preparation guidance.
3. Given a completed, partial, failed, cancelled, or legacy-aborted RestoreRun, when an authorized user opens its view page, then the page links to existing result/evidence details and does not offer preparation actions that would imply mutation of that historical run.
### User Story 4 - Unauthorized Users Cannot Mutate Preparation State (Priority: P2)
As a tenant owner, I want Restore readiness actions to obey existing RBAC boundaries, so that read-only users cannot run preparation mutations.
**Acceptance Criteria**:
1. Given a user with tenant view access but not tenant manage access, when the user sees readiness guidance, then mutating preparation actions are unavailable and server-side calls are rejected.
2. Given a user without workspace or environment access, when the user tries to access Restore readiness surfaces directly, then existing authorization behavior is preserved.
3. Given a user with manage access, when the user starts a preparation action, then the action logs or preserves existing audit/evidence behavior already associated with that Restore preparation action.
## Requirements
### Functional Requirements
- **FR-390-001**: The system MUST produce a Restore readiness summary from existing Restore state, including selected backup set, selected scope/items, checks state, preview state, group mapping requirements, execution status, and available OperationRun evidence.
- **FR-390-002**: The readiness summary MUST identify whether Restore is blocked, needs preparation, ready for final confirmation, executing, completed, failed, cancelled, or historical/non-actionable.
- **FR-390-003**: The readiness summary MUST identify the primary reason Restore cannot continue when it is not ready.
- **FR-390-004**: The readiness summary MUST identify one deterministic next safe action when a safe action exists.
- **FR-390-005**: The next safe action MUST be preparation-only unless it delegates to the existing final confirmation path.
- **FR-390-006**: The next safe action copy MUST state when the action will not execute the restore.
- **FR-390-007**: The system MUST protect against stale action execution by comparing the action's basis/fingerprint with the current Restore basis before performing a mutating preparation action.
- **FR-390-008**: The system MUST use existing RestoreSafetyResolver concepts for preview/check currentness where possible instead of creating a parallel source of truth.
- **FR-390-009**: The system MUST keep Restore execution authorization, confirmation, validation, and queueing inside the existing Restore execution path.
- **FR-390-010**: The system MUST NOT execute a Restore as part of a readiness guidance action.
- **FR-390-011**: The system MUST NOT create review-publication resolution cases or steps for Restore.
- **FR-390-012**: The system MUST NOT introduce generic resolution persistence in this v1 spec.
- **FR-390-013**: The system MUST support in-memory wizard state by showing inline guidance only.
- **FR-390-014**: The system MUST support persisted RestoreRun records by showing local guidance on existing Restore view surfaces where the record already exists.
- **FR-390-015**: The system MUST not create orphaned persisted cases for unsaved wizard state.
- **FR-390-016**: The system MUST keep the Restore Wizard as the owner of preparation input collection.
- **FR-390-017**: The system MUST keep Restore Preview as the owner of preview content.
- **FR-390-018**: The system MUST keep OperationRun as the owner of execution/evidence truth.
- **FR-390-019**: The system MUST show evidence links only where the current user is authorized to access the linked record.
- **FR-390-020**: The system MUST preserve existing tenant/workspace/environment scoping.
- **FR-390-021**: Mutating readiness/preparation actions MUST require the same manage capability expected by existing Restore preparation actions.
- **FR-390-022**: Read-only inspection MUST require the same view capability expected by existing RestoreRun view access.
- **FR-390-023**: Any new destructive or high-impact Filament action introduced by implementation MUST execute through `Action::make(...)->action(...)`, enforce server-side authorization, and include `->requiresConfirmation()` when destructive.
- **FR-390-024**: URL-only navigation actions MUST not be described as confirmed actions unless Filament v5 documentation is verified for that behavior.
- **FR-390-025**: Global search behavior MUST remain valid for `RestoreRunResource`: either the resource has an Edit/View page if searchable, or global search is explicitly disabled.
- **FR-390-026**: The implementation MUST provide meaningful empty or inactive states for any table, list, or repeated readiness item it adds.
- **FR-390-027**: The implementation MUST not add heavy global frontend assets for this feature.
- **FR-390-028**: The implementation MUST use existing Filament v5 and Livewire v4 patterns and avoid Filament v3/v4 APIs.
- **FR-390-029**: The implementation MUST avoid new Microsoft Graph calls during page render or readiness display.
- **FR-390-030**: The implementation MUST not assume a provider-specific restore backend beyond the existing RestoreRun data and service abstractions.
- **FR-390-031**: The implementation MUST maintain auditability for user-triggered preparation mutations by reusing or preserving existing operation/audit trails where available.
- **FR-390-032**: The implementation MUST include tests proving that stale guidance cannot mutate an out-of-date Restore preparation state.
- **FR-390-033**: The implementation MUST include tests proving read-only users cannot trigger mutating preparation actions.
- **FR-390-034**: The implementation MUST include tests proving execution still requires existing final confirmation and safety gates.
### Non-Functional Requirements
- **NFR-390-001**: Readiness derivation MUST be deterministic for the same Restore state.
- **NFR-390-002**: Readiness derivation MUST be side-effect-free.
- **NFR-390-003**: Readiness display MUST not materially increase query count on Restore create/view pages.
- **NFR-390-004**: Readiness copy MUST be concise enough to fit existing Filament panel surfaces on desktop and mobile.
- **NFR-390-005**: The implementation MUST be testable without external Microsoft Graph calls.
- **NFR-390-006**: The implementation MUST be deployable without new environment variables, queue workers, scheduled commands, or persistent storage by default.
## UI Surface Impact
| Surface | Impact |
| --- | --- |
| RestoreRun create wizard | Existing page changed. Adds decision-first readiness guidance and next safe action affordances in current wizard steps. |
| RestoreRun view page | Existing page changed. Adds local readiness/status explanation for persisted runs where useful. |
| RestoreRun list table | No required change. Do not add new bulk or row mutation unless implementation proves a narrow need and updates this spec first. |
| Global search | No new result type. Validate existing RestoreRunResource hard rule if the implementation touches resource search behavior. |
| Navigation | No new top-level navigation, cluster, widget, or dashboard surface. |
| OperationRun links | Existing evidence links may be reused where authorization permits. |
## UI/UX Surface Classification
This feature materially changes reachable operator-facing surfaces. No `No UI surface impact` decision is claimed. Implementation must update the durable UI/productization coverage registry under `docs/ui-ux-enterprise-audit/` for the changed RestoreRun create/view surfaces, or stop and update this spec if repo coverage tooling proves a narrower checked decision is required.
| Surface | Page archetype | Surface class | Native/custom/shared | Primary persona | Primary operator question | Dominant next action | Dangerous actions | State ownership |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| RestoreRun create wizard | Create/Edit staged workflow | Preparation workflow surface | Native Surface using Filament wizard/presenter paths; no UI exception planned | Tenant operator/manager preparing a restore | "What prevents this restore from being safe to confirm, and what should I do next?" | Run checks, regenerate preview, review mappings, or continue to final confirmation when ready | Existing final Restore execution remains the dangerous action and stays behind existing confirmation/hard-confirm gates | Requested/draft/restorable state is owned by the Restore wizard and RestoreSafetyResolver-derived basis; readiness display is derived presentation only |
| RestoreRun view page | View/Detail status surface | Detail/status inspection surface | Native Surface using existing RestoreRun detail presenter paths; no UI exception planned | Tenant operator/manager or read-only reviewer inspecting a saved restore | "What state is this RestoreRun in, what evidence exists, and is any safe preparation/inspection action available?" | Inspect evidence, open OperationRun, or return to the create/preparation flow only where existing state permits | No new dangerous action; historical states must not expose preparation mutations | Inspect/execution state is owned by RestoreRun and OperationRun; local guidance must not duplicate or override execution truth |
Page contract details:
- Default-visible information: readiness/status, primary reason, next safe action, mutation scope, and final-confirmation requirement.
- Diagnostics-only information: raw basis/fingerprint details, raw preview/check payload fragments, and support evidence metadata.
- Support/raw evidence gating: diagnostic/raw links require authorized view access to the related RestoreRun, BackupSet, environment, or OperationRun record.
- Duplicate-truth prevention: RestoreSafetyResolver remains checks/preview currentness truth; RestoreRun remains persisted restore status truth; OperationRun remains execution/evidence truth.
- Status-like readiness cues must use existing BadgeCatalog/BadgeRenderer or another central shared status path when rendered as badges; page-local badge colors or ad hoc status styling are not allowed.
- Multiple audience handling: read-only users get inspection-only affordances; tenant-manage users may see preparation actions; non-members must not learn the record exists.
## UI Action Matrix
| Action | Surface | Mutates preparation state | Executes Restore | Authorization | Confirmation |
| --- | --- | ---: | ---: | --- | --- |
| Run readiness checks | RestoreRun create wizard | Yes | No | Tenant manage | Existing action semantics, add confirmation only if implementation makes it high-impact/destructive. |
| Generate preview | RestoreRun create wizard | Yes | No | Tenant manage | Existing action semantics. |
| Regenerate preview | RestoreRun create wizard | Yes | No | Tenant manage | Existing action semantics, stale basis protection required. |
| Review group mappings | RestoreRun create wizard | User edits existing input | No | Tenant manage | Not destructive by itself. |
| Open evidence | RestoreRun create/view | No | No | Tenant view for linked record | Navigation action only. |
| Continue to confirmation | RestoreRun create wizard | No direct mutation | No | Tenant manage | Existing final confirmation still required before execution. |
| Execute restore | Existing Restore execution path | Yes | Yes | Tenant manage plus existing gates | Existing confirmation, hard confirm, safety validation, and OperationRun execution truth remain mandatory. |
## Key Entities and Concepts
This spec prefers existing entities and local derived value objects over new persisted models.
- **RestoreRun**: Existing persisted restore record. Owns restore status, selected scope, preview/results metadata, group mapping, idempotency key, and OperationRun linkage.
- **BackupSet**: Existing source for backup payload selection and restore scope.
- **OperationRun**: Existing evidence/execution truth for queued/running/completed operational work.
- **RestoreSafetyResolver**: Existing source for scope basis, preview basis, checks basis, preview integrity, checks integrity, and execution readiness concepts.
- **Restore Readiness Summary**: New local derived contract describing the current Restore preparation decision and reason. It is not a database entity.
- **Restore Next Safe Action**: New local derived contract describing a safe preparation or inspection action. It is not an execution command.
- **Restore Guidance Basis/Fingerprint**: New or reused deterministic basis value used to reject stale readiness actions.
## Proportionality Review
This feature introduces a local Restore-specific readiness summary/action contract and possibly a small Restore-specific state/reason family. It does not introduce a new persisted entity, generic workflow engine, cross-domain taxonomy, or storage abstraction.
**Constitution review result**:
- New persisted entity: No.
- New database table: No.
- New enum/status family: Yes, but only local Restore readiness/reason/action identifiers derived from existing Restore state.
- New abstraction: Yes, bounded to Restore readiness derivation and presentation.
- New taxonomy/framework: No. Generic action resolution remains out of scope.
- Canonical user-facing view: No new canonical view. Existing Restore create/view surfaces remain the canonical surfaces.
- Reuse before build: Required. RestoreSafetyResolver, RestoreRun, RestoreRun presenters, OperationRun links, existing policies/capabilities, and Filament action patterns must be reused where possible.
The proportional response is to create Restore-local contracts and tests, not persistence or a generic adapter system.
## Edge Cases
- RestoreRun has a legacy `aborted` status. Treat it as historical/non-actionable and preserve existing display compatibility.
- RestoreRun has stale checks but current preview. The next safe action must prioritize checks before confirmation.
- RestoreRun has current checks but stale preview. The next safe action must prioritize preview regeneration.
- RestoreRun is queued or running. Guidance must defer to OperationRun execution truth and avoid preparation actions.
- RestoreRun is completed, partial, failed, cancelled, or completed with errors. Guidance must explain result/evidence inspection and avoid preparation mutations.
- Wizard state is unsaved. Guidance must remain inline and non-persisted.
- User loses manage access after the page renders. Mutating action must fail server-side.
- Restore scope changes after readiness action render. Action must fail stale basis validation and ask the operator to refresh/regenerate.
- BackupSet or environment access is unavailable. Guidance must show safe blocked state without leaking inaccessible names or payload details.
## Success Criteria
- **SC-390-001**: In tests, a blocked Restore preparation state produces one clear reason and one deterministic next safe action.
- **SC-390-002**: In tests, current checks and preview allow continuation to final confirmation while still requiring existing execution confirmation gates.
- **SC-390-003**: In tests, stale basis data prevents mutating readiness/preparation actions.
- **SC-390-004**: In tests, read-only users can inspect allowed readiness information but cannot trigger mutating preparation actions.
- **SC-390-005**: Browser smoke coverage verifies blocked, stale, and ready Restore wizard states with no copy implying automatic execution.
- **SC-390-006**: No new migration, environment variable, queue, scheduled command, global asset registration, or navigation surface is required for v1.
## Testing Expectations
Implementation must include:
- Unit tests for Restore readiness derivation from representative Restore states.
- Unit or feature tests for stale basis protection.
- Feature/Filament tests for RestoreRun create wizard guidance and action authorization.
- Feature/Filament tests for RestoreRun view guidance on persisted records.
- Tests proving existing execution confirmation/safety gates are still required.
- Browser smoke coverage for at least blocked, stale, and ready states if UI changes are visible in the panel.
## Testing / Lane / Runtime Impact
- **Runtime behavior impact**: Yes. The implementation changes visible RestoreRun create/view behavior and adds derived readiness support code.
- **Affected validation lanes**:
- Unit: Restore-local readiness resolver, reason/action selection, stale basis comparison, side-effect-free behavior.
- Feature/Filament: RestoreRun create/view rendering, action authorization, stale-action rejection, execution-gate preservation.
- Browser: Feature-local smoke for blocked, stale, ready, and read-only visible UI states.
- **Fixture/helper/factory/seed/context cost**: Use existing Workspace, ManagedEnvironment, BackupSet, RestoreRun, OperationRun, membership, and capability fixtures/factories. Do not introduce provider, workspace, membership, or browser context as implicit defaults in shared helpers.
- **Heavy-family decision**: Keep. Browser coverage is feature-local smoke because the feature materially changes visible operator workflow; do not create a new broad heavy-governance family.
- **Runtime budget/baseline/trend impact**: No material suite-cost increase is expected. If browser or fixture expansion materially changes runtime, document the measured impact in the implementation PR and escalate as `document-in-feature`; recurring/structural cost must become `follow-up-spec`.
- **Query budget**: Restore readiness display must not add more than two database queries to the default Restore create or view render compared with the pre-feature fixture baseline. Authorized evidence links may add relationship loading only when visible and must be eager-loaded or documented.
- **Escalation outcome**: `keep`, provided implementation stays Restore-local and avoids generic persistence, hidden heavy fixtures, and broad browser families.
Preferred local validation commands:
```bash
cd apps/platform && ./vendor/bin/sail artisan test
cd apps/platform && ./vendor/bin/sail pint --dirty
```
Focused commands may be used during implementation once concrete test paths exist.
## Deployment and Runtime Impact
- Database migrations: Not expected for v1.
- Environment variables: Not expected.
- Queue workers: No new workers expected.
- Scheduled commands: Not expected.
- Storage/volumes: Not expected.
- Filament assets: No new heavy assets expected. If registered assets are added despite this plan, deployment must include `cd apps/platform && php artisan filament:assets`.
- Staging validation: Required because Restore is an Intune-critical flow, even though v1 is guidance/preparation-only.
- Production promotion: Validate on Staging first, including authorization and no-auto-execute behavior.
## Assumptions
- Existing RestoreRun create/view pages remain the primary surfaces.
- Existing RestoreSafetyResolver and RestoreRun presenter classes provide enough state to derive readiness without new persistence.
- Existing tenant manage/view capabilities remain the correct authorization boundary for Restore preparation and inspection.
- Mode B is sufficient for v1 because current resolution persistence is review-publication-specific.
- Any future generic resolution persistence requires a separate spec and proportionality review.
## Open Questions
No blocking product questions remain for preparation. Implementation must verify exact class names, route names, and test fixture helpers before editing application code.
## Follow-Up Candidates
- Persisted generic resolution case foundation, if a future cross-domain action-resolution model is explicitly approved.
- Governance Inbox Restore readiness intake, after Restore-local guidance proves stable.
- Provider-specific Restore adapter expansion, after the local Restore contract is validated.
- Restore preview item-level remediation guidance, if operators need row-level recovery actions.

View File

@ -0,0 +1,156 @@
# Tasks: Restore Readiness Resolution Adapter v1
**Input**: `specs/390-restore-readiness-resolution-adapter-v1/spec.md`, `specs/390-restore-readiness-resolution-adapter-v1/plan.md`
**Branch**: `390-restore-readiness-resolution-adapter-v1`
**Mode**: Mode B - Restore-local guidance only
## Execution Rules
- Do not implement a generic resolution framework.
- Do not add a database migration unless `spec.md` and `plan.md` are updated first.
- Do not reuse review-publication resolution persistence for Restore.
- Do not add top-level navigation, global search surfaces, dashboards, or notification-center intake.
- Do not execute Restore from a readiness guidance action.
- Keep Restore execution behind existing confirmation, validation, and OperationRun paths.
- Keep all tasks unchecked until implementation work is actually completed.
## Phase 1: Repo Verification and Spec-Package Contracts
- [ ] T001 Verify current RestoreRun create/view routes, page classes, presenter classes, actions, and authorization methods in `apps/platform/app/Filament/Resources/RestoreRunResource.php` and nested page/presenter files.
- [ ] T002 Verify current RestoreSafetyResolver public methods and state contracts in `apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php`.
- [ ] T003 Verify current RestoreRun status family in `apps/platform/app/Support/RestoreRunStatus.php`, including legacy statuses.
- [ ] T004 Verify OperationRun link/presenter/helper patterns used by RestoreRun and related operational pages.
- [ ] T005 Verify existing test fixture/factory patterns for RestoreRun, BackupSet, ManagedEnvironment, Workspace, and OperationRun.
- [ ] T006 Verify `RestoreRunResource` global-search behavior: confirm it has View/Edit page if searchable, or explicitly disable global search if implementation changes search behavior.
- [ ] T007 Create `specs/390-restore-readiness-resolution-adapter-v1/artifacts/current-restore-flow-inventory.md` documenting the verified Restore flow, existing safety gates, and exact code seams to reuse.
- [ ] T008 Create `specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-readiness-state-matrix.md` defining Restore-local states, reasons, and priority ordering.
- [ ] T009 Create `specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-requirement-map.md` mapping each readiness reason to existing RestoreSafetyResolver inputs, RestoreRun fields, and required authorization.
- [ ] T010 Create `specs/390-restore-readiness-resolution-adapter-v1/contracts/restore-ui-copy-contract.md` with approved decision-first copy and forbidden execution-implying copy.
- [ ] T011 Re-check the proportionality review after the contract files are drafted; update `spec.md` and `plan.md` before coding if any task implies new persistence or generic infrastructure.
## Phase 2: Tests First - Readiness Derivation
- [ ] T012 Add unit test coverage for missing checks readiness in `apps/platform/tests/Unit/Support/RestoreReadinessResolution/`.
- [ ] T013 Add unit test coverage for stale checks readiness in `apps/platform/tests/Unit/Support/RestoreReadinessResolution/`.
- [ ] T014 Add unit test coverage for missing preview readiness in `apps/platform/tests/Unit/Support/RestoreReadinessResolution/`.
- [ ] T015 Add unit test coverage for stale preview readiness in `apps/platform/tests/Unit/Support/RestoreReadinessResolution/`.
- [ ] T016 Add unit test coverage for current checks plus current preview ready state.
- [ ] T017 Add unit test coverage for group-mapping-required readiness where existing Restore state exposes that requirement.
- [ ] T018 Add unit test coverage for queued and running RestoreRun states deferring to OperationRun execution truth.
- [ ] T019 Add unit test coverage for completed, partial, failed, cancelled, legacy aborted, and completed-with-errors states as historical/non-actionable.
- [ ] T020 Add unit test coverage proving next safe action selection is deterministic for the same Restore state.
- [ ] T021 Add unit test coverage proving readiness derivation is side-effect-free and does not persist or dispatch work.
## Phase 3: Tests First - Authorization and Stale Action Protection
- [ ] T022 Add feature or Filament test proving a tenant-view-only user can inspect allowed readiness guidance but cannot invoke mutating preparation actions.
- [ ] T023 Add feature or Filament test proving a user without workspace/environment access cannot inspect Restore readiness through direct route access.
- [ ] T024 Add feature or Filament test proving tenant-manage access is required for mutating preparation guidance actions.
- [ ] T025 Add feature or unit test proving a stale guidance basis/fingerprint rejects a mutating preparation action without changing Restore state.
- [ ] T026 Add feature test proving existing Restore execution still requires final confirmation, hard confirm, and current safety gates.
- [ ] T027 Add feature test proving readiness guidance actions do not create OperationRun records directly.
- [ ] T028 Add feature test proving readiness guidance does not create review-publication resolution cases or steps.
## Phase 4: Restore-Local Support Implementation
- [ ] T029 Create a Restore-local support namespace under `apps/platform/app/Support/RestoreReadinessResolution/`.
- [ ] T030 Implement a Restore readiness summary value object or DTO aligned with `contracts/restore-readiness-state-matrix.md`.
- [ ] T031 Implement Restore-local reason identifiers and next-action identifiers without adding a generic taxonomy.
- [ ] T032 Implement a side-effect-free Restore readiness resolver that consumes RestoreRun or wizard state plus RestoreSafetyResolver outputs.
- [ ] T033 Implement deterministic next-action priority ordering matching the contract matrix.
- [ ] T034 Implement a Restore guidance basis/fingerprint helper that reuses existing scope/checks/preview basis concepts where possible.
- [ ] T035 Implement presenter-friendly formatting for readiness status, reason, next action, evidence, and no-auto-execute copy.
- [ ] T036 Ensure the resolver performs no Graph calls, no queue dispatches, no database writes, and no OperationRun creation.
- [ ] T037 Ensure the resolver handles in-memory wizard state without requiring a persisted RestoreRun id.
- [ ] T038 Ensure the resolver handles persisted RestoreRun records without creating new resolution cases.
## Phase 5: Create Wizard Integration
- [ ] T039 Integrate Restore readiness guidance into `RestoreRunCreatePresenter` or the existing create wizard presentation path.
- [ ] T040 Show blocked guidance for missing checks with "This will not execute the restore" copy.
- [ ] T041 Show stale preview guidance with regenerate-preview as the next safe action.
- [ ] T042 Show ready-for-confirmation guidance without bypassing existing final confirmation controls.
- [ ] T043 Wire preparation actions through existing Restore wizard action methods where possible.
- [ ] T044 Add basis/fingerprint validation before any mutating preparation action exposed by the guidance UI.
- [ ] T045 Return a clear notification or inline error when a stale action is rejected.
- [ ] T046 Ensure read-only users do not see or cannot activate mutating preparation actions.
- [ ] T047 Ensure guidance copy fits existing Filament panel layout at desktop and mobile widths.
- [ ] T048 Avoid adding heavy assets, custom global CSS, or published Filament internals.
## Phase 6: Persisted RestoreRun View Integration
- [ ] T049 Integrate local guidance into `RestoreRunDetailPresenter` or the existing RestoreRun view presentation path.
- [ ] T050 Show draft/scoped/checked/previewed persisted runs as preparation states where applicable.
- [ ] T051 Show pending/queued/running runs as execution states that defer to OperationRun evidence.
- [ ] T052 Show completed/partial/failed/cancelled/aborted/completed-with-errors runs as historical result states.
- [ ] T053 Add authorized OperationRun evidence links only where the current user may access the linked record.
- [ ] T054 Avoid preparation mutation actions on historical/non-actionable RestoreRun states.
- [ ] T055 Preserve existing row click, view page, and lifecycle action behavior on RestoreRun list/table.
## Phase 7: Filament Actions, Notifications, and Empty States
- [ ] T056 Review any new Filament action against v5 patterns and use `Action::make(...)->action(...)` for execution actions.
- [ ] T057 Add `->requiresConfirmation()` to any destructive action if implementation introduces one; otherwise document that no destructive action was introduced.
- [ ] T058 Ensure URL-only actions use `->url(...)` and are not described as modal-confirmed actions.
- [ ] T059 Add explicit success/error/stale notifications for user-triggered preparation mutations where outcomes are not instantly obvious.
- [ ] T060 Add meaningful empty/inactive states for any repeated readiness item or evidence list introduced.
- [ ] T061 Confirm no new panel provider registration is required; if it becomes required, register through `bootstrap/providers.php` only.
## Phase 8: UI Coverage and Browser Smoke
- [ ] T062 Add or update Filament feature tests for blocked wizard guidance.
- [ ] T063 Add or update Filament feature tests for stale preview guidance.
- [ ] T064 Add or update Filament feature tests for ready-for-confirmation guidance.
- [ ] T065 Add or update Filament feature tests for read-only inspection behavior.
- [ ] T066 Add or update Filament feature tests for persisted RestoreRun view guidance.
- [ ] T067 Run browser smoke for blocked, stale, ready, and read-only Restore guidance states if visible UI changed.
- [ ] T068 Verify no visible copy implies automatic Restore execution.
- [ ] T069 Update durable UI/productization coverage registry artifacts under `docs/ui-ux-enterprise-audit/` for the changed RestoreRun create/view surfaces.
- [ ] T070 Update `docs/ui-ux-enterprise-audit/target-experience-briefs/restore-safety-workflow.md` if the implementation changes the documented target experience; otherwise record an explicit checked target-brief no-change decision in the coverage update.
## Phase 9: Regression and Safety Validation
- [ ] T071 Run focused unit tests for `Support/RestoreReadinessResolution`.
- [ ] T072 Run focused Restore feature tests.
- [ ] T073 Run focused Filament RestoreRunResource tests.
- [ ] T074 Run the full platform test suite with `cd apps/platform && ./vendor/bin/sail artisan test` when feasible.
- [ ] T075 Run `cd apps/platform && ./vendor/bin/sail pint --dirty`.
- [ ] T076 Run `git diff --check`.
- [ ] T077 Verify no database migration was added.
- [ ] T078 Verify no new environment variables, queues, scheduled commands, storage volumes, or global assets were added.
- [ ] T079 Verify no review-publication resolution models/tables are referenced by Restore readiness code.
- [ ] T080 Verify no generic adapter registry or action-resolution framework was introduced.
- [ ] T081 Verify no Restore readiness code calls Microsoft Graph directly.
- [ ] T082 Verify no Restore execution path bypasses existing final confirmation and safety gates.
- [ ] T083 Verify `RestoreRunResource` global search behavior still satisfies the Filament v5 View/Edit-page rule or is explicitly disabled.
- [ ] T084 Verify Restore readiness display stays within the spec query budget for default Restore create/view renders, or document the measured exception and update the spec before delivery.
- [ ] T085 Verify mutating preparation actions preserve/reuse existing audit or operation evidence behavior; document why no audit event is required for any non-mutating path.
- [ ] T086 Verify the provider seam remains platform-core presentation over existing RestoreRun/BackupSet/RestoreSafetyResolver/OperationRun data and does not leak provider-specific semantics into platform-core contracts.
- [ ] T087 Verify OperationRun-linked UI reuses the central OperationRun Start UX Contract, remains deep-link/inspect-only, and does not queue DB notifications from readiness guidance.
- [ ] T088 Verify status-like readiness cues use BadgeCatalog/BadgeRenderer or another central shared status path instead of page-local badge styling.
## Phase 10: Delivery Notes
- [ ] T089 Document implementation validation results in the final response, including tests run and any skipped browser checks.
- [ ] T090 State Livewire v4.0+ compliance in the final implementation response.
- [ ] T091 State provider registration impact in the final implementation response.
- [ ] T092 State global-search status for RestoreRunResource in the final implementation response.
- [ ] T093 State destructive-action/confirmation/authorization handling in the final implementation response.
- [ ] T094 State asset strategy and whether `filament:assets` is needed in the final implementation response.
- [ ] T095 State the testing plan/results in the final implementation response.
## Dependencies
- Phase 1 must complete before app code changes.
- Phase 2 and Phase 3 tests should be written before or alongside Phase 4 support implementation.
- Phase 4 must complete before UI integration in Phases 5 and 6.
- Phase 5 and Phase 6 can proceed independently after Phase 4.
- Phase 8 browser smoke depends on visible UI integration.
- Phase 9 must complete before delivery.
## Parallel Work Candidates
- T012 through T021 can be split by readiness state after contracts exist.
- T022 through T028 can be split by authorization/stale-action concern after fixture patterns are verified.
- T049 through T055 can proceed in parallel with T039 through T048 after the support resolver is stable.
- T062 through T066 can be written in parallel with UI integration once page/presenter seams are known.

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB