TenantAtlas/specs/330-environment-dashboard-baseline-compare-productization/plan.md
ahmido 0c7adefe5b Spec 330: environment dashboard baseline compare productization (#392)
## Summary
- add the baseline compare landing experience for the environment dashboard productization flow
- expand the environment dashboard overview and summary-building logic to support richer baseline comparison states and assessments
- update the supporting Blade templates for the new compare and overview presentation
- add English and German translations for the baseline compare surface
- include the Spec 330 planning and task artifacts alongside the implementation

## Tests
- touched browser, feature, and unit coverage for the new baseline compare flow
- updated test files include `Spec330EnvironmentDashboardBaselineCompareSmokeTest`, `BaselineCompareLandingWhyNoFindingsTest`, `Spec330EnvironmentDashboardBaselineCompareProductizationTest`, `HeaderContextBarTest`, and `ManagedEnvironmentModelTest`
- no additional test run was performed as part of this commit/push/PR workflow

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #392
2026-05-20 20:32:39 +00:00

25 KiB

Implementation Plan: Spec 330 - Environment Dashboard / Baseline Compare Productization

Branch: 330-environment-dashboard-baseline-compare-productization | Date: 2026-05-19 | Spec: specs/330-environment-dashboard-baseline-compare-productization/spec.md Input: User-provided Spec 330 and repo inspection.

Summary

Productize two existing environment-owned strategic surfaces into decision-first governance pages:

Is this environment ready, blocked, stale, or requiring review?
Which baseline drift requires action?

The implementation must keep current routes, source truth, RBAC, environment-owned scope, and OperationRun semantics. It must not add new backend readiness/drift/proof engines. Environment Dashboard should elevate status, reason, impact, proof, and one primary next action before technical detail. Baseline Compare should elevate assignment, compare trust, drift impact, evidence/proof, and one primary next action before findings detail, raw diff, or diagnostics.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12.52.0. Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Tailwind CSS 4.2.2. Storage: PostgreSQL; no schema change expected. Testing: Pest 4 Feature/Livewire/Browser tests. Validation Lanes: confidence and browser; targeted navigation/context guard filters. Target Platform: Laravel Sail locally; Dokploy/container deployment posture unchanged. Project Type: Laravel monolith under apps/platform. Performance Goals: DB-only page render; no Graph/provider API calls during render; no broad new query families. Constraints: No new persisted truth, migration, package, queue, scheduler, storage, env var, deployment asset, compatibility route, or legacy alias support. Scale/Scope: Two existing environment-owned Filament pages, existing widget/view structures, feature-local payload helpers if needed, focused tests, and browser smoke.

UI / Surface Guardrail Plan

  • Guardrail scope: changed existing operator-facing strategic environment-owned surfaces.
  • Affected routes/pages/actions/states/navigation/panel/provider surfaces:
    • /admin/workspaces/{workspace}/environments/{environment}
    • /admin/workspaces/{workspace}/environments/{environment}/baseline-compare
    • apps/platform/app/Filament/Pages/EnvironmentDashboard.php
    • apps/platform/app/Filament/Widgets/Dashboard/EnvironmentDashboardOverview.php
    • apps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-overview.blade.php
    • apps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-context-chips.blade.php
    • apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php
    • apps/platform/app/Filament/Pages/BaselineCompareLanding.php
    • apps/platform/resources/views/filament/pages/baseline-compare-landing.blade.php
  • No-impact class, if applicable: N/A.
  • Native vs custom classification summary: Native Filament Dashboard/Page/Widget plus existing Blade composition; no new UI framework.
  • Shared-family relevance: dashboard signals, status messaging, action links, proof links, OperationRun links, baseline compare state, diagnostics disclosure.
  • State layers in scope: route-owned environment, page payload, widget payload, Baseline Compare launch query state (baseline_profile_id, subject_key, nav), and existing session/context guard behavior.
  • Audience modes in scope: operator-MSP, manager, governance operator, support reviewer where authorized.
  • Decision/diagnostic/raw hierarchy plan: decision first, proof path visible, diagnostics collapsed, raw/support hidden or gated.
  • Raw/support gating plan: collapsed by default and capability-gated through existing support diagnostics/raw capabilities where exposed.
  • One-primary-action / duplicate-truth control: one dominant next action per page; secondary links/cards support the decision rather than repeat the same verdict.
  • Handling modes by drift class or surface: review-mandatory for UI-002 and UI-061 strategic surfaces; document-in-feature for any UI coverage registry no-change decision.
  • Repository-signal treatment: Spec 325 target images are direction only; runtime claims must be repo-verified, derived, unavailable, or deferred.
  • Special surface test profiles: global-context-shell, monitoring-state-page, shared-detail-family.
  • Required tests or manual smoke: Feature/Livewire tests for decision layout, false-green guard, RBAC/scope/disclosure plus Pest Browser smoke for explicit environment routes, no-baseline/action-needed/drift states, diagnostics collapsed, raw detail hidden, cross-workspace denial, and static tenant copy guard.
  • Exception path and spread control: none expected. Any new dangerous action, schema, capability, backend proof source, or route family requires spec/plan/tasks update first.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • UI/Productization coverage decision: active spec package carries productization proof. Update UI coverage registry only if route/archetype/coverage classification changes; otherwise document why UI-002/UI-061 plus Spec 325 artifacts are sufficient.
  • Coverage artifacts to update: none expected unless implementation changes route/archetype state.
  • Navigation / Filament provider-panel handling: no panel provider registration changes expected. Laravel 12 panel providers remain in apps/platform/bootstrap/providers.php.
  • Screenshot or page-report need: screenshots required; full page report optional unless implementation materially changes coverage classification.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes.
  • Systems touched: Environment Dashboard page, dashboard widgets, dashboard summary builder, Baseline Compare Landing page/view, baseline stats/aggregate helpers, backup/recovery helpers, provider permission view models, OperationRun links, resource policies, UiEnforcement, and browser fixtures/tests.
  • Shared abstractions reused: EnvironmentDashboardSummaryBuilder, EnvironmentDashboardSummary, BaselineCompareStats, TenantGovernanceAggregateResolver, OperationRunLinks, ManagedEnvironmentLinks, OperationUxPresenter, OpsUxBrowserEvents, BadgeRenderer, UiEnforcement, policies/capability resolvers.
  • New abstraction introduced? why?: none. Page-local private helpers may be added only to reduce Blade complexity or duplicate payload calculation.
  • Why the existing abstraction was sufficient or insufficient: Existing paths provide source truth, authorization, links, compare state, backup/recovery/readiness signals, and OperationRun proof. They do not fully enforce the first-read decision hierarchy and collapsed diagnostics disclosure.
  • Bounded deviation / spread control: no public readiness/proof/disclosure framework; keep composition local to the two surfaces.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, through existing Baseline Compare start action and proof links. No new OperationRun type or lifecycle behavior.
  • Central contract reused: OperationRunLinks, OperationUxPresenter, OpsUxBrowserEvents, existing OperationRunPolicy, existing operation detail routes, and BaselineCompareService::startCompare().
  • Delegated UX behaviors: compare queued toast, run-enqueued browser event, open operation link, blocked/cannot-start messaging, and tenant/workspace-safe URLs stay on the existing Ops UX path.
  • Surface-owned behavior kept local: display-only proof availability labels and next-action hierarchy.
  • Queued DB-notification policy: unchanged / N/A.
  • Terminal notification path: unchanged.
  • Exception path: none.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: display-only provider readiness/permissions and static copy guard.
  • Provider-owned seams: existing provider connection, Microsoft/Entra/Intune required permissions, provider tenant ID where source records require it.
  • Platform-core seams: workspace, environment, readiness, proof, baseline, drift, evidence, operation, review, diagnostics.
  • Neutral platform terms / contracts preserved: workspace, environment, provider, required permissions, operation proof, evidence, review, baseline, drift, diagnostics.
  • Retained provider-specific semantics and why: Microsoft/Entra/Intune can remain at source/provider-boundary labels only.
  • Bounded extraction or follow-up path: Provider Readiness Productization remains a separate follow-up spec.

Constitution Check

  • Inventory-first, snapshots-second: Environment and compare surfaces derive from last-observed inventory, explicit snapshots, backups, evidence, reviews, and operations; no new source truth is created.
  • Read/write separation by default: Pages remain read/decision-first. Existing compare start is the only high-impact operation start and already requires confirmation/authorization/OperationRun.
  • Single Contract Path to Graph: No Graph/provider API calls may be added to page render.
  • Deterministic Capabilities: Reuse existing Capabilities, CapabilityResolver, resource policies, UiEnforcement, and route authorization.
  • RBAC-UX: UI visibility is not security. Server-side policies/gates remain authoritative for operations, evidence, review packs, backup/restore, provider permissions, and diagnostics.
  • Workspace/environment isolation: Both pages require explicit route-bound environment. Non-member or mismatched workspace/environment access is 404.
  • OperationRun UX: Existing compare start and operation links reuse shared OperationRun UX helpers; no local lifecycle/notification behavior.
  • UI-COV-001: Existing strategic surfaces UI-002 and UI-061 materially change. Active spec package must carry repo-truth map, tests, screenshots, and coverage close-out decision.
  • TEST-GOV-001: Targeted Feature and Browser lanes are explicit. Browser cost is named and scoped.
  • PROP-001 / BLOAT-001: No new source of truth, persisted entity, enum/status family, public abstraction, proof engine, or cross-domain UI framework.
  • UI-FIL-001: Use native Filament components/shared primitives first; custom Blade must preserve Filament semantics, accessibility, dark mode, and one-primary-action hierarchy.
  • Filament v5 / Livewire v4: Livewire v4.0+ compliance required. No Livewire v3 or Filament v3/v4 APIs.
  • Panel provider location: panel providers remain in apps/platform/bootstrap/providers.php; no provider registration change expected.
  • Global search: no resource global search change expected. If a resource is touched, it must retain safe View/Edit pages or disable global search.
  • Destructive/high-impact actions: no destructive action introduced. Existing compare start remains confirmed/capability-gated/OperationRun-backed.
  • Assets: no Filament asset registration expected; filament:assets deployment posture unchanged.

Current Repo Truth Summary

Existing verified Environment Dashboard surfaces:

  • EnvironmentDashboard extends Filament Dashboard and renders EnvironmentDashboardContextChips, ManagedEnvironmentTriageArrivalContinuity, DashboardKpis, and EnvironmentDashboardOverview.
  • EnvironmentDashboard::getUrl() resolves route-owned ManagedEnvironment and strips workspace/environment parameters into ManagedEnvironmentLinks::viewUrl().
  • EnvironmentDashboardSummaryBuilder already derives context, posture, KPIs, recommended actions, governance status, readiness cards, active operation summary, and recent operations from existing models/services.
  • Current dashboard view renders recommended actions, governance status, active operations requiring attention, and right-side readiness cards.
  • Existing browser tests already assert dashboard context chips, KPI cards, readiness cards, ranked actions, and no table-first layout.

Existing verified Baseline Compare surfaces:

  • BaselineCompareLanding is environment-owned at slug workspaces/{workspace}/environments/{environment}/baseline-compare.
  • It rejects old workspace-style /admin/baseline-compare-landing?environment_id= URLs and remembered environment fallback.
  • It strips legacy scope keys from generated URLs while preserving baseline_profile_id, subject_key, and nav.
  • BaselineCompareStats::forTenant() derives states including no_tenant, no_assignment, no_snapshot, invalid_scope, comparing, failed, idle, and ready.
  • Existing compare start action uses Action::make('compareNow')->requiresConfirmation()->action(...), BaselineCompareService::startCompare(), UiEnforcement, OperationUxPresenter, and OpsUxBrowserEvents.
  • Current Blade already has explanation/stats, no-assignment/no-snapshot empty states, coverage warnings, evidence gap details, findings summaries, and diagnostics section; diagnostics are currently rendered when present and must become collapsed/default-secondary.

Known productization gaps:

  • Environment Dashboard needs a more explicit decision card/question and proof/action panel instead of equal-weight dashboard sections.
  • Environment Dashboard readiness dimensions should map to source truth and unavailable states in the spec map before implementation.
  • Baseline Compare needs a first-read drift/action decision card, no-baseline actionable unavailable state, proof/disclosure panel, and raw diff/diagnostics collapsed by default.
  • Baseline Compare must avoid false all-clear copy when zero findings coexist with evidence/coverage/trust gaps.

Existing Repository Surfaces Likely Affected

Runtime files, only during later implementation:

  • apps/platform/app/Filament/Pages/EnvironmentDashboard.php
  • apps/platform/app/Filament/Widgets/Dashboard/EnvironmentDashboardOverview.php
  • apps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-overview.blade.php
  • apps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-context-chips.blade.php
  • apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php
  • apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummary.php
  • apps/platform/app/Filament/Pages/BaselineCompareLanding.php
  • apps/platform/resources/views/filament/pages/baseline-compare-landing.blade.php
  • apps/platform/resources/lang/en/* and apps/platform/resources/lang/de/* only where touched copy follows existing localization conventions.

Tests, only during later implementation:

  • apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.php
  • apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php
  • apps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.php
  • apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php
  • apps/platform/tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.php
  • apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php
  • apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php
  • apps/platform/tests/Feature/Rbac/DriftLandingUiEnforcementTest.php
  • apps/platform/tests/Feature/Navigation/Spec322AdminSurfaceScopeContractTest.php
  • apps/platform/tests/Feature/Navigation/Spec322EnvironmentCtaUrlContractTest.php
  • apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentCopyNeutralizationGuardTest.php
  • apps/platform/tests/Browser/Spec330EnvironmentDashboardBaselineCompareSmokeTest.php

Spec/UI artifacts:

  • specs/330-environment-dashboard-baseline-compare-productization/repo-truth-map.md
  • screenshot artifacts under specs/330-environment-dashboard-baseline-compare-productization/artifacts/screenshots/
  • optional UI coverage registry updates only if implementation materially changes route/archetype/coverage state.

Domain / Model Implications

  • No new model, table, migration, enum, status family, persisted display state, or public service contract.
  • Environment readiness must derive from:
    • ManagedEnvironment and workspace relation.
    • ProviderConnection status/health/consent/readiness fields.
    • ManagedEnvironmentPermission and required permissions view model.
    • TenantBackupHealthResolver, TenantBackupHealthAssessment, backup sets/schedules.
    • RestoreSafetyResolver and restore/recovery evidence presentation.
    • TenantGovernanceAggregateResolver, Finding, FindingException, and baseline compare stats.
    • EvidenceSnapshot, EnvironmentReview, ReviewPack, and related links.
    • OperationRun attention/freshness/outcome and OperationRunLinks.
  • Baseline drift/action state must derive from:
    • BaselineTenantAssignment, BaselineProfile, BaselineSnapshot, BaselineSnapshotTruthResolver.
    • BaselineCompareStats, TenantGovernanceAggregate, BaselineCompareSummaryAssessment, operatorExplanation.
    • Finding drift findings/severity counts.
    • Evidence gap summaries/details and compare diagnostics only as secondary/collapsed context.
    • Existing compare OperationRun relation and links.

UI / Filament Implications

  • Filament v5 and Livewire v4.0+ compliance must be preserved.
  • Keep panel provider registration unchanged.
  • Use Filament sections/buttons/badges/actions and existing shared primitives where suitable.
  • Avoid fake charts, fake health, fake compliance, fake customer-safe, fake restore confidence, or generic KPI dashboard expansion.
  • Environment Dashboard target order:
    • header/scope
    • main readiness decision card
    • readiness dimensions
    • right-side proof/action/disclosure panel
    • ranked next actions
    • operations/reviews/evidence/backup/provider details as secondary context
    • diagnostics collapsed
  • Baseline Compare target order:
    • header/scope
    • main drift/action decision card
    • no-baseline visual Compare readiness stepper/pipeline and compact available inputs when compare is blocked by missing assignment
    • assignment / compare trust / drift summary only when a baseline-backed compare state exists
    • right-side evidence/proof/disclosure panel
    • findings/evidence-gap summary
    • raw diff/details collapsed or secondary

Livewire / Page State Implications

  • Environment Dashboard and Baseline Compare must rely on route-owned environment context.
  • Baseline Compare launch context (baseline_profile_id, subject_key, nav) remains initialization/query state only; it must not override environment ownership.
  • Existing BaselineCompareLanding::monitoringPageStateContract() should remain consistent with Spec 198/319 contracts.
  • Clean old workspace-style URLs and legacy query aliases must not establish environment context.
  • Cross-workspace route mismatches stay 404.

RBAC / Policy Implications

Reuse existing authorization:

  • Environment page visibility: environment membership and TENANT_VIEW.
  • Provider permissions/readiness: required permissions routes and existing provider/permission capabilities.
  • Backup posture: backup-set/schedule capabilities and policies.
  • Restore/recovery proof: restore-run/backup capabilities and policies.
  • Baseline compare view: environment access and TENANT_VIEW.
  • Compare start: TENANT_SYNC through existing UiEnforcement.
  • Baseline profile links: BaselineProfileResource authorization/policies.
  • Drift findings: FindingResource / finding capabilities.
  • Evidence snapshots: EvidenceSnapshotPolicy / evidence capability.
  • Review and review packs: EnvironmentReviewResource, ReviewPackResource, policies.
  • Operation proof: OperationRunPolicy and link helpers.
  • Diagnostics/raw detail: SUPPORT_DIAGNOSTICS_VIEW or stricter existing raw/support capability.

No new permission semantics should be added unless implementation proves existing capabilities cannot express the action and spec/plan/tasks are updated first.

Audit / Observability Implications

  • No new audit events are expected for read-only productization.
  • Existing support diagnostics modal on Environment Dashboard already writes audit/telemetry and must remain authorized/redacted.
  • Existing Baseline Compare start audit/OperationRun behavior remains unchanged.
  • Do not imply OperationRun completion proves environment health or compare acceptability.

Test Strategy

Feature/Livewire tests:

  • Repo truth map existence and required sections.
  • Environment Dashboard decision layout.
  • Environment Dashboard no false green when proof is missing.
  • Environment Dashboard ranked next actions.
  • Baseline Compare decision layout.
  • Baseline Compare no-baseline actionable unavailable state.
  • Baseline Compare drift/evidence state with raw details hidden by default.
  • Diagnostics hidden/collapsed by default across both pages.
  • Environment-owned route contract and legacy alias rejection.
  • Static tenant platform-copy guard.
  • RBAC for visible/hidden actions and raw diagnostics.

Browser tests:

  • Explicit Environment Dashboard route non-empty/action-needed state.
  • Explicit Baseline Compare route no-baseline state.
  • Baseline Compare compare/drift state if fixtures support it.
  • Diagnostics collapsed and raw details absent by default.
  • Cross-workspace/invalid environment safe denial.
  • Dynamic display name containing Tenant allowed, static tenant copy absent.
  • Required screenshots under the Spec 330 artifacts path.

Validation:

  • Targeted Feature/Livewire tests.
  • Targeted Browser smoke.
  • Context/route guard filter for EnvironmentDashboard, BaselineCompare, AdminSurfaceScope, EnvironmentOwned, LegacyTenant, and Spec322.
  • pint --dirty.
  • git diff --check.

Implementation Phases

Phase 1 - Repo Truth And Current UI Audit

  • Inspect Environment Dashboard page/widget/summary builder/tests.
  • Inspect Baseline Compare Landing page/view/stats/tests.
  • Inspect Spec 325 target images/briefs and UI audit reports.
  • Create/update repo-truth-map.md.
  • Confirm exact source/capability/fallback for every visible element.
  • Stop if a desired visible element requires new backend truth.

Phase 2 - Environment Dashboard Productization

  • Add a first-read readiness question and decision card.
  • Refine existing summary builder/widget payloads to expose status/reason/impact/proof/next-action without new state persistence.
  • Add/right-size proof/action panel and ranked actions.
  • Keep useful existing cards/details as secondary context.
  • Collapse diagnostics/raw support by default.

Phase 3 - Baseline Compare Productization

  • Add a first-read drift/action question and decision card.
  • Render no-baseline/no-snapshot/no-compare states as actionable unavailable states.
  • Show assignment, compare trust, drift impact, evidence/proof, and operation proof before findings/raw details.
  • Collapse raw diff/diagnostics by default.
  • Preserve existing compare start action semantics and matrix/detail links.

Phase 4 - Route, RBAC, Copy, And Disclosure Guards

  • Verify route-owned environment context.
  • Reject remembered fallback and legacy aliases.
  • Guard cross-workspace mismatches.
  • Gate/hide unavailable actions.
  • Preserve dynamic names containing Tenant; remove static platform tenant copy.
  • Ensure no false green claims.

Phase 5 - Browser Smoke And Screenshots

  • Add browser smoke file.
  • Create required screenshots where generated.
  • Confirm diagnostics collapsed and raw details absent by default.
  • Confirm no context drift.

Phase 6 - Validation And Close-Out

  • Run focused Feature/Livewire/browser tests.
  • Run targeted Spec 314-322 context guards.
  • Run Pint and diff check.
  • Report full suite status honestly.
  • Record no migrations/packages/env/queues/storage/deployment assets/backcompat/legacy aliases.

Risk Controls

  • Treat Spec 325 images as direction only; map every visible element to repo truth.
  • Use unavailable/deferred states instead of inventing proof.
  • Do not broaden Baseline Compare Matrix scope.
  • Do not turn Environment Dashboard into a generic M365/admin-center status page.
  • Keep OperationRun as execution proof, not health proof.
  • Keep raw diagnostics collapsed/capability-gated.

Rollout / Deployment Considerations

  • No migration expected.
  • No seeders expected.
  • No env var expected.
  • No queue/scheduler/storage change expected.
  • No package change expected.
  • No deployment asset change expected unless implementation unexpectedly registers Filament assets; current expectation is no filament:assets change beyond existing deployment posture.
  • Staging validation should focus on route-owned environment behavior, no-baseline/action-needed states, diagnostics collapsed, and no static tenant copy.

Candidate Selection Gate

Passed. Spec 330 was directly user-provided, is aligned with Spec 325 strategic target surfaces and post-Spec 329 follow-up sequencing, is not already present as an active/completed package, preserves completed Specs 314-329, and is scoped to two existing environment-owned pages.

Spec Readiness Gate

Expected pass after spec.md, plan.md, tasks.md, repo-truth-map.md, and checklists/requirements.md are generated and preparation analysis finds no blocking consistency issues.