# Research: Backup Quality Truth Surfaces ## Decision 1: Derive backup quality from existing backup and version metadata instead of creating a persisted backup-health model - Decision: Build backup quality from the metadata already present on `BackupItem` and `PolicyVersion`, then aggregate backup-set truth from those per-item facts. Do not add a new table, column, or stored backup-health projection. - Rationale: The current data model already records the core quality signals this feature needs: metadata-only source markers, assignment fetch failures, orphaned assignments, warnings, scope-tag context, and integrity notes. The product problem is weak surfacing, not missing persistence. - Alternatives considered: - Persist a `backup_quality` or `backup_health` table. Rejected because it would create a second source of truth for information that is already derivable. - Add materialized quality fields to `backup_sets` or `policy_versions`. Rejected because the feature does not need independent lifecycle state. ## Decision 2: Keep capture lifecycle and backup quality as separate truths on every affected surface - Decision: Render capture lifecycle (`completed`, `partial`, `failed`, `archived`) independently from backup quality (`metadata-only present`, `assignment issues present`, degraded-count summary, or no degradations detected). - Rationale: Operators currently overread `completed` as `good backup`. The feature must stop that conflation without erasing the lifecycle truth that the system already tracks. - Alternatives considered: - Blend quality into one stronger status badge. Rejected because that would collapse two different truths into one ambiguous state. - Treat `completed` plus degraded counts as a new status family. Rejected because it would introduce new state where derived summary is sufficient. ## Decision 3: Reuse the central snapshot-mode badge and shared badge infrastructure instead of page-local mapping - Decision: Use the existing `BadgeDomain::PolicySnapshotMode` and `PolicySnapshotModeBadge` semantics for `full` versus `metadata only`. Any new quality chips or labels should stay inside shared badge or copy seams rather than page-local `match` statements. - Rationale: The codebase already centralizes status-like badge semantics, and Filament v5 tables or schema text badges can render those shared specs directly. This keeps backup quality aligned with BADGE-001 and avoids a second vocabulary for snapshot completeness. - Alternatives considered: - Add local badge mapping per surface. Rejected because it would drift from the central badge catalog. - Introduce a generic trust score badge. Rejected because the spec explicitly avoids a new scoring engine. ## Decision 4: Use existing Filament tables, infolists, enterprise-detail sections, and checkbox-list descriptions instead of a new UI shell - Decision: Implement the feature inside `BackupSetResource`, `BackupItemsRelationManager`, `PolicyVersionResource`, and `RestoreRunResource` using the current Filament table columns, infolist sections, enterprise-detail builder, and wizard descriptions. - Rationale: Filament v5 already supports badge columns, summary-first view content, relation-manager tables, and descriptive checkbox list options. The repository also already uses `enterpriseDetailPage()` for backup-set detail and schema-driven wizard steps for restore selection. - Alternatives considered: - Build a dedicated backup-health dashboard. Rejected because it is explicitly out of scope. - Add a custom client-side wizard overlay. Rejected because the needed truth is server-driven and fits existing Filament seams. ## Decision 5: Surface backup-set and item quality in restore selection before risk checks, but keep restore safety as a separate authority - Decision: Enrich restore wizard step 1 backup-set labels or helper copy and step 2 item descriptions with input-quality truth before preview or risk checks run. Do not block degraded selections at this stage unless existing restore safety already blocks them later. - Rationale: Operators need early warning before the risk-check stage, but this spec is about backup quality, not execution safety. The restore-safety layer already owns blocker and preview-only semantics. - Alternatives considered: - Leave degraded truth exclusively to restore risk checks. Rejected because it preserves the current late-discovery trust failure. - Prevent selecting degraded inputs in step 1 or step 2. Rejected because the spec requires truthful surfacing, not a new restore policy. ## Decision 6: Preserve truth visibility for `TENANT_VIEW` users even when restore actions remain unavailable - Decision: Quality truth remains visible on backup-set and policy-version surfaces for users who can view tenant backup or version records, even if they cannot create restore runs or use maintenance actions. - Rationale: Missing restore permission must not make degraded inputs appear calmer or cleaner. Authorization can suppress mutation, but it must not suppress source-of-truth visibility. - Alternatives considered: - Couple quality sections to restore permissions. Rejected because it would falsify the operator surface. - Rely on disabled restore actions as the quality indicator for lower-privilege users. Rejected because disabled actions are not an adequate explanation of input quality. ## Decision 7: Use `unknown quality` only when existing metadata cannot justify a stronger claim - Decision: Emit `unknown quality` only when the record lacks authoritative metadata for snapshot completeness or assignment-quality interpretation. Absence of an error is not enough to call an item or version `full` if the record never captured the relevant quality signal. - Rationale: Defaulting to `unknown` too often would hide real degradations, while defaulting to `full` from silence would overstate confidence. This feature needs a narrow, evidence-based fallback. - Alternatives considered: - Default all older records to `unknown`. Rejected because many records already carry usable source metadata. - Infer `full` whenever `metadata_only` is absent. Rejected because silence is not always proof of completeness. ## Decision 8: Extend the existing Pest and Livewire test surface rather than introducing a browser-first harness - Decision: Add focused unit coverage for backup-quality derivation and extend existing backup, version, restore-selection, and RBAC feature tests for UI truth. Keep the current Pest and Livewire patterns as the main verification path. - Rationale: The affected behavior is server-driven list, detail, and wizard state, which the current test suite already covers well. The repo also already has restore and RBAC tests that should remain authoritative. - Alternatives considered: - Rely only on manual validation. Rejected because the feature is specifically about preventing subtle trust regressions. - Introduce a large browser-only test pack. Rejected because the most important assertions are deterministic server-side state and rendered truth.