## Summary - add Spec 185 workspace recovery posture visibility artifacts under `specs/185-workspace-recovery-posture-visibility` - promote tenant backup health and recovery evidence onto the workspace overview with separate metrics, attention ordering, calmness coverage, and tenant-dashboard drill-throughs - batch visible-tenant backup/recovery derivation to keep the workspace overview query-bounded - align follow-up fixes from the authoritative suite rerun, including dashboard truth-alignment fixtures, canonical backup schedule tenant context, guard-path cleanup, smoke-fixture credential removal, and robust theme asset manifest handling ## Testing - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Filament/PanelThemeAssetTest.php tests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php` - focused regression pack for the previously failing cases passed - full suite JUnit run passed: `3401` tests, `18849` assertions, `0` failures, `0` errors, `8` skips ## Notes - no new schema or persisted workspace recovery model - no provider-registration changes; Filament/Livewire stack remains on Filament v5 and Livewire v4 - no new destructive actions or global search changes Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #216
26 KiB
Implementation Plan: Workspace Recovery Posture Visibility
Branch: 185-workspace-recovery-posture-visibility | Date: 2026-04-09 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/185-workspace-recovery-posture-visibility/spec.md
Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/185-workspace-recovery-posture-visibility/spec.md
Note: This plan keeps workspace recovery posture derived from existing tenant backup-health and recovery-evidence truth. It hardens /admin for workspace-first triage without introducing a new recovery-confidence engine, a new persisted workspace posture model, or a broad IA rewrite.
Summary
Promote the existing tenant-level backup-health and recovery-evidence truth onto /admin so a workspace operator can answer, in one scan, how many visible tenants need backup follow-up, how many need recovery-evidence follow-up, which tenant should be opened first, and whether workspace calmness includes those domains. The implementation will keep WorkspaceOverviewBuilder as the orchestration boundary, reuse TenantBackupHealthResolver and RestoreSafetyResolver::dashboardRecoveryEvidence() as the source-of-truth seams, add batch-friendly visible-tenant derivation to avoid uncontrolled per-tenant query fanout, extend WorkspaceSummaryStats and WorkspaceNeedsAttention with separate backup and recovery signals, and route new workspace drillthroughs to the affected tenant dashboard as the canonical first landing. Focused Pest coverage will protect aggregation, priority ordering, checked domains, calmness boundaries, drillthrough continuity, RBAC-safe omission, and representative DB-only render costs.
Technical Context
Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12, Filament v5, Livewire v4, Pest v4, existing WorkspaceOverviewBuilder, WorkspaceSummaryStats, WorkspaceNeedsAttention, TenantBackupHealthResolver, TenantBackupHealthAssessment, RestoreSafetyResolver, tenant dashboard widgets, WorkspaceCapabilityResolver, CapabilityResolver, and the current workspace overview Blade surfaces
Storage: PostgreSQL unchanged; no schema change, new cache table, or persisted workspace recovery artifact is planned
Testing: Pest feature tests and Livewire-style widget tests through Laravel Sail, reusing existing workspace overview tests plus focused upstream backup and recovery truth guards
Target Platform: Laravel monolith web application in Sail locally and containerized Linux deployment in staging and production
Project Type: web application
Performance Goals: Keep /admin DB-only at render time, preserve bounded query behavior for representative visible-tenant workspaces, avoid naive per-tenant resolver fanout, and keep restore-history candidate evaluation aligned with the existing latest-10 tenant recovery posture rule
Constraints: No new recovery-confidence engine, no new persisted workspace posture model, no new portfolio matrix page, no new Graph calls, no new panel/provider changes, no over-strong recovery claims, no hidden-tenant leakage, and no drift away from tenant dashboard as the canonical triage destination
Scale/Scope: One workspace overview page, one builder, two existing workspace widgets, one calmness contract, visible-tenant aggregation for moderate tenant counts, and focused regression coverage for metrics, attention, calmness, drillthroughs, RBAC, and query-bounded rendering
Constitution Check
GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.
| Principle | Pre-Research | Post-Design | Notes |
|---|---|---|---|
| Inventory-first / snapshots-second | PASS | PASS | Existing tenant backup sets, schedules, restore runs, and restore-result attention remain the only source truths. No new inventory or snapshot ownership is introduced. |
| Read/write separation | PASS | PASS | The slice is read-only workspace overview hardening. No new write path, preview flow, or remote mutation is added. |
| Graph contract path | N/A | N/A | No Graph calls or contract-registry changes are required. |
| Deterministic capabilities | PASS | PASS | Existing workspace and tenant capability registries remain authoritative. Aggregation uses visible tenants only and does not invent new permission semantics. |
| RBAC-UX authorization semantics | PASS | PASS | /admin remains workspace-scoped; drillthrough stays in the tenant plane; non-members remain 404; members missing deeper capability keep safe disabled or fallback navigation without hidden-tenant leakage. |
| Workspace and tenant isolation | PASS | PASS | The plan keeps visible-tenant filtering as the aggregation boundary and keeps tenant dashboard drillthrough explicit. |
| Run observability / Ops-UX | PASS | PASS | No new OperationRun, notification surface, or lifecycle change is introduced. Existing operations remain diagnostic context only. |
| Data minimization | PASS | PASS | No new persistence or broader route exposure is planned. Only already-visible tenant truth is promoted onto the workspace home. |
| Proportionality / no premature abstraction | PASS | PASS | The plan extends WorkspaceOverviewBuilder and existing truth helpers instead of introducing a workspace recovery subsystem, presenter framework, or persisted score. |
| Persisted truth / behavioral state | PASS | PASS | New attention families and checked domains are derived presentation semantics with operator consequences on ordering and calmness only; no new persisted domain state is introduced. |
| UI semantics / few layers | PASS | PASS | Backup health and recovery evidence are rendered directly from existing truth on existing widgets; no new badge framework or interpretation pipeline is added. |
| Badge semantics (BADGE-001) | PASS | PASS | Existing badge and tone semantics remain authoritative. The workspace overview will not invent a new portfolio recovery badge language. |
| Filament-native UI / Action Surface Contract | PASS | PASS | WorkspaceOverview, WorkspaceSummaryStats, and WorkspaceNeedsAttention remain read-only navigation surfaces. No destructive or redundant action model is added. |
| Filament UX-001 / HDR-001 | PASS | PASS | No create/edit flows or new record headers are introduced. The landing page keeps the existing layout and makes recovery triage more visible within that structure. |
| Filament v5 / Livewire v4 compliance | PASS | PASS | The design stays inside Filament v5 and Livewire v4. No Livewire v3-era patterns are introduced. |
| Provider registration location | PASS | PASS | No panel or provider change is required. Laravel 11+ provider registration remains in bootstrap/providers.php. |
| Global search hard rule | PASS | PASS | No global-searchable resource behavior is changed in this slice. |
| Destructive action safety | PASS | PASS | The feature introduces no destructive action. Existing destructive actions remain unchanged and confirmed where already required. |
| Asset strategy | PASS | PASS | No new assets are planned. Deployment continues to use cd apps/platform && php artisan filament:assets unchanged if assets are built elsewhere in the product. |
| Testing truth (TEST-TRUTH-001) | PASS | PASS | The plan adds tests for business consequences: false calmness, wrong counts, wrong priority order, hidden-tenant leakage, lost drillthrough context, and query regressions. |
Phase 0 Research
Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/185-workspace-recovery-posture-visibility/research.md.
Key decisions:
- Keep
WorkspaceOverviewBuilderas the only workspace orchestration boundary rather than creating a new workspace recovery posture service. - Reuse
TenantBackupHealthResolverandRestoreSafetyResolver::dashboardRecoveryEvidence()as the source-of-truth seams; do not duplicate tenant posture mapping inside a second workspace-only interpretation layer. - Add narrow visible-tenant bulk derivation support around the existing tenant truth helpers so workspace rendering can stay query-bounded instead of calling single-tenant resolvers naively for every visible tenant.
- Count backup and recovery attention by affected visible tenant, not by raw backup errors, raw restore runs, or a blended workspace score.
- Keep backup health and recovery evidence separate on summary metrics, attention items, and calmness copy; reject any single blended workspace recovery label.
- Use the tenant dashboard as the canonical drillthrough for new workspace backup-health and recovery-evidence items, with choose-tenant as the multi-tenant metric fallback and existing deeper backup or restore surfaces left as secondary tenant-local navigation.
- Extend calmness and checked domains explicitly with
backup_healthandrecovery_evidenceinstead of silently implying those domains were checked. - Insert new attention families above activity-only operations and alerts while preserving the current governance-first intent of workspace attention ordering.
- Reuse existing workspace overview test seams and DB-only query guard patterns rather than creating a new browser harness or portfolio cache layer.
Phase 1 Design
Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/185-workspace-recovery-posture-visibility/:
research.md: implementation decisions, constraints, and rejected alternatives for workspace recovery posture visibilitydata-model.md: existing tenant truth models plus the derived visible-tenant and workspace-overview projections used by this slicecontracts/workspace-recovery-posture-visibility.openapi.yaml: internal surface contract for workspace summary metrics, attention items, calmness, and tenant-dashboard drillthroughquickstart.md: focused implementation and verification workflow for workspace recovery posture visibility
Design decisions:
WorkspaceOverviewBuilderremains the builder boundary and becomes responsible for deriving visible-tenant backup and recovery context, workspace metrics, new attention candidates, and honest calmness from visible tenants only.- Existing tenant backup-health truth remains authoritative; the workspace layer only consumes the posture, reason, claim boundary, and tenant-safe action contract already implied by that truth.
- Existing tenant recovery-evidence truth remains authoritative; the workspace layer only consumes
overview_state, reason, summary, claim boundary, and latest relevant run continuity. - The implementation keeps summary metrics separate: one metric for backup-attention tenants and one metric for recovery-attention tenants, in addition to the existing governance, activity, and alert metrics.
- New workspace attention items are tenant-bound records carrying tenant label, family, severity, bounded reason text, and a primary tenant-dashboard destination. They do not introduce a new workspace recovery page.
- Workspace calmness remains bounded to visible tenants and now explicitly names backup health and recovery evidence in the checked-domain contract and calm-state copy.
- Existing deeper tenant backup-set or restore-run surfaces remain downstream from the tenant dashboard instead of becoming the primary workspace landing, which keeps drillthrough predictable and aligned with the spec’s workspace-first triage goal.
- Query-bounded implementation is handled through visible-tenant batch derivation over latest backup basis, schedule follow-up, and capped restore-history candidates; no persisted workspace cache or materialized posture artifact is introduced.
Project Structure
Documentation (this feature)
specs/185-workspace-recovery-posture-visibility/
├── spec.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ └── workspace-recovery-posture-visibility.openapi.yaml
├── checklists/
│ └── requirements.md
└── tasks.md
Source Code (repository root)
apps/platform/
├── app/
│ ├── Filament/
│ │ ├── Pages/
│ │ │ ├── WorkspaceOverview.php
│ │ │ ├── ChooseTenant.php
│ │ │ └── TenantDashboard.php
│ │ └── Widgets/
│ │ ├── Dashboard/
│ │ │ ├── DashboardKpis.php
│ │ │ ├── NeedsAttention.php
│ │ │ └── RecoveryReadiness.php
│ │ └── Workspace/
│ │ ├── WorkspaceSummaryStats.php
│ │ ├── WorkspaceNeedsAttention.php
│ │ └── WorkspaceRecentOperations.php
│ ├── Models/
│ │ ├── BackupSchedule.php
│ │ ├── BackupSet.php
│ │ ├── RestoreRun.php
│ │ ├── OperationRun.php
│ │ ├── AlertDelivery.php
│ │ └── Tenant.php
│ └── Support/
│ ├── BackupHealth/
│ │ ├── TenantBackupHealthAssessment.php
│ │ └── TenantBackupHealthResolver.php
│ ├── RestoreSafety/
│ │ ├── RestoreResultAttention.php
│ │ └── RestoreSafetyResolver.php
│ └── Workspaces/
│ └── WorkspaceOverviewBuilder.php
├── resources/
│ └── views/
│ └── filament/
│ ├── pages/
│ │ └── workspace-overview.blade.php
│ └── widgets/
│ └── workspace/
│ └── workspace-needs-attention.blade.php
└── tests/
└── Feature/
└── Filament/
├── WorkspaceOverviewAccessTest.php
├── WorkspaceOverviewAuthorizationTest.php
├── WorkspaceOverviewContentTest.php
├── WorkspaceOverviewDbOnlyTest.php
├── WorkspaceOverviewDrilldownContinuityTest.php
├── WorkspaceOverviewEmptyStatesTest.php
├── WorkspaceOverviewGovernanceAttentionTest.php
├── WorkspaceOverviewRecoveryAttentionTest.php
├── WorkspaceOverviewLandingTest.php
├── WorkspaceOverviewNavigationTest.php
├── WorkspaceOverviewOperationsTest.php
├── WorkspaceOverviewPermissionVisibilityTest.php
├── WorkspaceOverviewSummaryMetricsTest.php
├── DashboardRecoveryPosturePerformanceTest.php
├── DashboardKpisWidgetTest.php
└── NeedsAttentionWidgetTest.php
Structure Decision: Keep the work entirely inside the existing Laravel and Filament monolith. Extend the current workspace overview builder, workspace widgets, and existing tenant truth helpers instead of creating a new workspace recovery domain or a second portfolio-truth layer.
Complexity Tracking
No Constitution Check violations are planned. No exception beyond the spec’s approved derived attention-family addition is currently justified.
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| — | — | — |
Proportionality Review
The feature adds derived workspace attention families and checked-domain markers, but no new persistence, no new abstraction layer, and no new cross-domain framework.
- Current operator problem: Workspace operators cannot quickly see which visible tenants are backup-weak or recovery-evidence-weak, so portfolio triage remains tenant-by-tenant.
- Existing structure is insufficient because: Tenant truth exists, but the workspace home does not yet aggregate or prioritize it.
- Narrowest correct implementation: Extend the existing workspace overview builder and widgets to consume existing tenant truth and present it as separate backup and recovery signals.
- Ownership cost created: Additional workspace aggregation logic, a small amount of ordering and copy logic, and focused regression coverage for counts, calmness, drillthrough, RBAC, and performance.
- Alternative intentionally rejected: A dedicated portfolio matrix, a persisted workspace recovery score, or a new recovery-confidence engine.
- Release truth: Current-release truth. The slice surfaces already-existing tenant truth on the existing workspace landing page.
Implementation Strategy
Phase A — Derive Visible-Tenant Backup And Recovery Contexts Without A New Workspace Engine
Goal: Reuse existing tenant-level truth while keeping workspace rendering query-bounded.
| Step | File | Change |
|---|---|---|
| A.1 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Extend the visible-tenant context build step to carry backup-health posture, backup-health reason metadata, recovery-evidence overview state, recovery-evidence reason metadata, and primary tenant-dashboard drillthrough context for every visible tenant. |
| A.2 | apps/platform/app/Support/BackupHealth/TenantBackupHealthResolver.php and apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php |
Add narrow bulk or prefetch-friendly derivation seams that let the workspace builder compute visible-tenant backup and recovery posture without naively invoking the current single-tenant resolvers in an uncontrolled loop. Keep the logic in the existing source-of-truth helpers rather than duplicating it in a workspace-only mapper. |
| A.3 | apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php and focused new or updated workspace builder coverage |
Prove that the expanded workspace overview remains DB-only and query-bounded for representative multi-tenant scenarios once backup and recovery signals are enabled. |
Phase B — Add Separate Workspace Summary Metrics For Backup And Recovery Attention
Goal: Let the workspace stat strip answer how many visible tenants need backup follow-up versus recovery-evidence follow-up.
| Step | File | Change |
|---|---|---|
| B.1 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Add backup_attention_tenants and recovery_attention_tenants summary metrics that count visible tenants with non-calm backup or recovery posture. Keep these counts tenant-based, not raw-issue-based. |
| B.2 | apps/platform/app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php and apps/platform/resources/views/filament/pages/workspace-overview.blade.php |
Render the new metrics using the existing stats strip, with descriptions that keep backup health and recovery evidence separate and bounded. |
| B.3 | apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php |
Cover separate metrics, honest descriptions, zero-problem states, and metric destinations for one-tenant and multi-tenant affected sets. |
Phase C — Introduce Backup-Health And Recovery-Evidence Workspace Attention Families
Goal: Make workspace attention tell the operator which tenant to open first and why.
| Step | File | Change |
|---|---|---|
| C.1 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Add backup_health attention items for visible tenants with absent, stale, or degraded backup posture and recovery_evidence attention items for visible tenants with weakened or unvalidated recovery evidence. |
| C.2 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Integrate the new items into the existing priority ordering so recovery and backup items rank above activity-only operations and alerts while preserving the current governance-first intent of the workspace queue. |
| C.3 | apps/platform/resources/views/filament/widgets/workspace/workspace-needs-attention.blade.php and apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php |
Reuse the existing workspace attention rendering contract so each new item shows tenant label, family, bounded reason, and one clear tenant-dashboard action or a safe disabled state. |
| C.4 | apps/platform/tests/Feature/Filament/WorkspaceOverviewRecoveryAttentionTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php |
Cover absent, stale, degraded, weakened, and unvalidated ordering, ensure no_recent_issues_visible never becomes a workspace problem item, and prove the new families preserve existing governance and operations queue intent. |
Phase D — Make Calmness Honest About Backup Health And Recovery Evidence
Goal: Remove false calmness by omission and make checked domains explicit.
| Step | File | Change |
|---|---|---|
| D.1 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Extend checked_domains with backup_health and recovery_evidence, suppress calmness whenever visible tenants trigger either family, and keep calmness bounded to visible tenants. |
| D.2 | apps/platform/resources/views/filament/pages/workspace-overview.blade.php and any calmness-copy consumers |
Update calmness copy so calm states explicitly say that backup health and recovery evidence were included, and non-calm states explain that visible tenants still need attention in those domains. |
| D.3 | apps/platform/tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php |
Verify that calmness is only true when backup and recovery are both checked and quiet, and that zero-tenant or low-permission states do not masquerade as healthy calmness. |
Phase E — Preserve Tenant-Safe Drillthrough Continuity
Goal: Ensure workspace recovery or backup items land on a tenant surface that still explains the same weakness.
| Step | File | Change |
|---|---|---|
| E.1 | apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php |
Make the tenant dashboard the primary destination for new backup-health and recovery-evidence items, and use choose-tenant as the metric fallback when more than one visible tenant is affected. |
| E.2 | Existing tenant dashboard widgets and continuity seams only if needed | Pass lightweight reason context only where an existing tenant surface already supports it; otherwise rely on the tenant dashboard’s existing backup-health and recovery-evidence presentation to preserve the reason without adding new routing shells. |
| E.3 | apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php |
Prove that workspace drillthrough opens the correct tenant, stays tenant-safe, and degrades to a safe disabled or fallback state when a more specific downstream route is unavailable. |
Phase F — Lock In RBAC And Performance Guardrails
Goal: Prevent hidden-tenant leakage and render-path regressions once recovery and backup signals are live on /admin.
| Step | File | Change |
|---|---|---|
| F.1 | apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php |
Verify that hidden tenants do not appear in counts, item labels, or reason text, and that calmness remains bounded to visible tenants. |
| F.2 | apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php |
Verify that read-only workspace members still receive truthful summary visibility while downstream capability limits stay enforced with the existing 404/403 semantics. |
| F.3 | apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php and upstream dashboard recovery performance tests |
Verify that the workspace path remains query-bounded and that the underlying tenant recovery-evidence derivation still respects the existing latest-10 candidate cap. |
| F.4 | cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent and focused Pest runs |
Required formatting and targeted verification before the implementation is considered complete. |
Key Design Decisions
D-001 — Workspace Truth Remains Derived From Tenant Truth
The workspace overview does not define new recovery confidence. It only aggregates tenant backup-health and tenant recovery-evidence states that already exist.
D-002 — Batch Derivation Lives At Existing Truth Seams
Performance hardening belongs in the existing TenantBackupHealthResolver and RestoreSafetyResolver seams or in tightly scoped builder prefetch support, not in a new workspace cache layer or second mapping engine.
D-003 — Backup And Recovery Stay Separate Everywhere
Metrics, attention items, calmness copy, and contracts must distinguish backup weakness from recovery-evidence weakness so the operator knows what kind of problem exists.
D-004 — Tenant Dashboard Is The Primary Workspace Drillthrough
The workspace overview should land the operator on the affected tenant dashboard first. That keeps the flow workspace-first and lets the tenant truth explain itself before the operator decides to dive into backup sets or restore runs.
D-005 — Calmness Must Name The Domains It Actually Checked
The workspace can only say it is calm if backup health and recovery evidence were actually checked and were quiet for visible tenants. Silent inclusion is not enough.
Risk Assessment
- If bulk derivation duplicates tenant truth instead of reusing existing resolver semantics, workspace and tenant views could drift.
- If the tenant dashboard drillthrough is bypassed too aggressively in favor of deep links, the workspace flow will become harder to scan and harder to reason about under RBAC.
- If new recovery and backup items are inserted above everything else, the existing governance-first workspace triage could regress; if they are inserted too low, the new slice will not solve the operator workflow gap.
- If calmness wording is updated without checked-domain expansion, the UI could still sound honest while remaining semantically incomplete.
- If metrics count raw backup sets or raw restore runs instead of affected tenants, the workspace answer will be noisy instead of actionable.
Phase 1 — Agent Context Update
Run after artifact generation:
.specify/scripts/bash/update-agent-context.sh copilot