TenantAtlas/specs/098-settings-slices-v1-backup-drift-ops/spec.md
ahmido c57f680f39 feat: Workspace settings slices v1 (backup, drift, operations) (#120)
Implements Spec 098: workspace-level settings slices for Backup retention, Drift severity mapping, and Operations retention/threshold.

Spec
- specs/098-settings-slices-v1-backup-drift-ops/spec.md

What changed
- Workspace Settings page: grouped Backup/Drift/Operations sections, unset-input UX w/ helper text, per-setting reset actions (confirmed)
- Settings registry: adds/updates validation + normalization (incl. drift severity mapping normalization to lowercase)
- Backup retention: adds workspace default + floor clamp; job clamps effective keep-last up to floor
- Drift findings: optional workspace severity mapping; adds `critical` severity support + badge mapping
- Operations pruning: retention computed per workspace via settings; scheduler unchanged; stuck threshold is storage-only

Safety / Compliance notes
- Filament v5 / Livewire v4: no Livewire v3 usage; relies on existing Filament v5 + Livewire v4 stack
- Provider registration unchanged (Laravel 11+/12 uses bootstrap/providers.php)
- Destructive actions: per-setting reset uses Filament actions with confirmation
- Global search: not affected (no resource changes)
- Assets: no new assets registered; no `filament:assets` changes

Tests
- vendor/bin/sail artisan test --compact tests/Feature/SettingsFoundation/WorkspaceSettingsManageTest.php \
  tests/Feature/SettingsFoundation/WorkspaceSettingsViewOnlyTest.php \
  tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php \
  tests/Feature/Drift/DriftPolicySnapshotDriftDetectionTest.php \
  tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php \
  tests/Unit/Badges/FindingBadgesTest.php

Formatting
- vendor/bin/sail bin pint --dirty

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #120
2026-02-16 03:18:33 +00:00

12 KiB

Feature Specification: 098 — Settings Slices v1 (Backup + Drift + Operations)

Feature Branch: 098-settings-slices-v1-backup-drift-ops
Created: 2026-02-16
Status: Draft
Input: Workspace-level settings slices for Backup, Drift severity mapping, and Operations retention/thresholds with safe defaults.

Spec Scope Fields (mandatory)

  • Scope: workspace
  • Primary Routes: Workspace Settings screen (admin UI)
  • Data Ownership: workspace-owned settings values (key/value) + audit log entries for setting changes
  • RBAC: workspace membership required; view vs manage capability-gated; deny-as-not-found for non-members

Clarifications

Session 2026-02-16

  • Q: Which “Reset to default” scope do you want on the Workspace Settings UI? → A: Per-setting reset (each key individually).
  • Q: When an admin clicks “Save” and multiple settings change at once, how should audit logging behave? → A: One audit log entry per key changed.
  • Q: Should we enforce a validation constraint between backup.retention_keep_last_default and backup.retention_min_floor? → A: Allow any values; effective retention is always clamped to backup.retention_min_floor.
  • Q: For settings that are currently unset (so the system uses defaults), how should the UI present them? → A: Leave input unset, show helper text with the default/effective value.
  • Q: In drift.severity_mapping, should severity values be case-sensitive? → A: Case-insensitive; normalize to lowercase on save.

User Scenarios & Testing (mandatory)

User Story 1 - Configure backup retention defaults (Priority: P1)

As a workspace admin, I want to configure workspace-wide defaults for backup retention so that enterprise workspaces can tune policy without code/config changes.

Why this priority: Backup retention is a common enterprise requirement and impacts storage cost and governance.

Independent Test: Can be tested by setting/unsetting workspace settings and verifying backup retention behavior remains unchanged by default and changes deterministically when configured.

Acceptance Scenarios:

  1. Given no workspace settings exist for backup retention, When a backup retention decision is made, Then behavior matches the current baseline (no change).
  2. Given a workspace default retention value is configured, When a backup retention decision is made without a more specific override, Then the configured default is used.
  3. Given a retention “floor” value is configured, When any calculated retention value is below the floor, Then the effective retention is clamped up to the floor.
  4. Given a per-schedule override is configured, When that override is below the configured floor, Then the override is clamped up to the floor.

User Story 2 - Configure drift severity mapping (Priority: P2)

As a workspace admin, I want to map drift finding types to severities so that findings align with enterprise risk posture and triage practices.

Why this priority: Severity directly affects how teams triage drift; a one-size-fits-all default is too rigid for enterprise.

Independent Test: Can be tested by saving a mapping, generating findings for mapped/unmapped types, and verifying severities are assigned correctly.

Acceptance Scenarios:

  1. Given no drift severity mapping exists, When a drift finding is produced, Then its severity defaults to “medium”.
  2. Given a mapping exists for a specific finding type, When a drift finding with that type is produced, Then the mapped severity is applied.
  3. Given a mapping contains an unknown/unsupported severity value, When an admin attempts to save it, Then the save is rejected and no invalid values are persisted.

User Story 3 - Configure operations retention and stuck threshold (Priority: P3)

As a workspace admin, I want to configure retention for operations/run records and store a “stuck run” threshold so that data lifecycle and operational heuristics are workspace-tunable.

Why this priority: Retention policies and operational thresholds vary widely between organizations and audit requirements.

Independent Test: Can be tested by saving retention/threshold settings and verifying the retention cutoff used by pruning changes accordingly while no new automatic actions occur.

Acceptance Scenarios:

  1. Given no operations retention setting exists, When operations/run pruning is executed, Then the cutoff matches the current baseline (no change).
  2. Given an operations retention setting exists, When pruning is executed, Then the cutoff is derived from the configured retention days.
  3. Given a stuck threshold is configured, When the Workspace Settings screen is re-opened, Then the configured value is shown exactly as saved.
  4. Given a stuck threshold is configured, When operations/run behavior is observed, Then no automatic remediation or auto-handling is performed in this feature scope.

Edge Cases

  • Attempting to save invalid numeric ranges (too low/high) is rejected and does not persist.
  • Attempting to save invalid JSON (malformed) for drift mapping is rejected.
  • Attempting to save drift mapping with non-string keys is rejected.
  • Two admins editing settings concurrently results in deterministic persisted state (last write wins) and both attempts are auditable.
  • A user without manage capability can view settings (read-only) but cannot submit changes.
  • A non-member cannot discover the Workspace Settings screen or any values (deny-as-not-found).

Requirements (mandatory)

Constitution alignment (required): This feature MUST remain DB-only for screen rendering and MUST NOT introduce Microsoft Graph calls as part of rendering or saving these settings. Any setting mutation MUST be auditable.

Dependencies & Assumptions

  • This feature depends on an existing workspace settings foundation that provides: workspace-scoped storage, consistent defaults, centralized validation, RBAC capability enforcement, and audit logging for changes.
  • No tenant-specific override UI is included in v1; only workspace-wide configuration is in scope.
  • The default values for all settings keys match the current baseline behavior at the time this feature ships.

Constitution alignment (RBAC-UX):

  • Authorization planes involved: workspace-scoped admin UI.
  • Non-member / not entitled to workspace scope → 404 (deny-as-not-found).
  • Member but missing manage capability → 403 on mutation attempts; UI remains read-only.

Constitution alignment (OPS/observability): This feature does not introduce a new long-running operation type; it changes which configuration values are used by existing behavior. All admin-initiated mutations MUST produce audit log entries.

Functional Requirements

  • FR-001: System MUST support workspace-level configuration for the following setting keys:
    • backup.retention_keep_last_default
    • backup.retention_min_floor
    • drift.severity_mapping
    • operations.operation_run_retention_days
    • operations.stuck_run_threshold_minutes
  • FR-002: System MUST preserve existing behavior when none of the above settings are configured (defaults MUST match the current baseline).
  • FR-003: System MUST validate and reject invalid setting values, ensuring no invalid configuration is silently persisted.
  • FR-004: Workspace Settings UI MUST present the above keys grouped into three sections (Backup, Drift, Operations) and MUST be fully functional without any external API calls.
  • FR-004a: For any setting key that is currently unset, the UI MUST keep the input in an “unset” state and MUST display helper text indicating the default (currently effective) value.
  • FR-005: Users with view capability MUST be able to view current effective settings but MUST NOT be able to change them.
  • FR-006: Users with manage capability MUST be able to change settings and reset individual settings back to defaults.
  • FR-007: Resetting a setting to default MUST be a confirmed (destructive-like) action.
  • FR-008: System MUST write audit log entries for each settings update and reset-to-default event including: workspace identity, actor identity, setting key, old value, new value, and timestamp.
  • FR-008a: When a single save operation changes multiple keys, the system MUST write one audit log entry per key changed.

Backup slice requirements

  • FR-009: backup.retention_keep_last_default MUST be an integer between 1 and 365.
  • FR-010: backup.retention_min_floor MUST be an integer between 1 and 365.
  • FR-011: Effective backup retention MUST never be lower than backup.retention_min_floor (applies to defaults and any more specific overrides).
  • FR-011a: The system MUST NOT reject configuration solely because backup.retention_min_floor exceeds backup.retention_keep_last_default; instead, the effective retention MUST be clamped to the floor.

Drift slice requirements

  • FR-012: drift.severity_mapping MUST be a JSON object mapping finding_type (string) → severity.
  • FR-013: Allowed severity values MUST be limited to: low, medium, high, critical.
  • FR-013a: Severity values MUST be accepted case-insensitively and normalized to lowercase when persisted.
  • FR-014: If a finding type has no mapping entry, severity MUST default to medium.

Operations slice requirements

  • FR-015: operations.operation_run_retention_days MUST be an integer between 7 and 3650.
  • FR-016: Pruning of operations/run records MUST use the configured retention days when set; otherwise it MUST behave as the baseline.
  • FR-017: operations.stuck_run_threshold_minutes MUST be an integer between 0 and 10080.
  • FR-018: operations.stuck_run_threshold_minutes MUST be a stored configuration value only; it MUST NOT introduce auto-remediation or auto-handling behavior in this feature scope.

UI Action Matrix (mandatory when Filament is changed)

Surface Location Header Actions Inspect Affordance (List/Table) Row Actions (max 2 visible) Bulk Actions (grouped) Empty-State CTA(s) View Header Actions Create/Edit Save+Cancel Audit log? Notes / Exemptions
Page Workspace Settings (admin UI) Save; Reset setting to default (per-setting, confirmed) N/A N/A N/A N/A N/A Save + Cancel Yes View capability: read-only fields; Manage capability: editable + submit; Non-member: 404

Key Entities (include if feature involves data)

  • Workspace Setting: A workspace-owned key/value configuration item with validation rules and a default.
  • Audit Log Entry: An immutable record of a settings update or reset-to-default event.
  • Drift Finding Type: A classification string used to identify the type of drift finding for severity mapping.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: When no settings are configured for these keys, backup retention behavior, drift severity behavior, and operations pruning behavior match the baseline in automated regression tests.
  • SC-002: An authorized workspace admin can update each of the 5 settings and observe the new effective value reflected in the Workspace Settings screen immediately after save.
  • SC-003: 100% of settings updates and reset-to-default actions produce an audit log entry with key, old value, and new value.
  • SC-004: Invalid configuration attempts (out-of-range numbers, invalid JSON, unsupported severities) are rejected and do not change persisted settings.