## 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
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-compareapps/platform/app/Filament/Pages/EnvironmentDashboard.phpapps/platform/app/Filament/Widgets/Dashboard/EnvironmentDashboardOverview.phpapps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-overview.blade.phpapps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-context-chips.blade.phpapps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.phpapps/platform/app/Filament/Pages/BaselineCompareLanding.phpapps/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, existingOperationRunPolicy, existing operation detail routes, andBaselineCompareService::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:assetsdeployment posture unchanged.
Current Repo Truth Summary
Existing verified Environment Dashboard surfaces:
EnvironmentDashboardextends FilamentDashboardand rendersEnvironmentDashboardContextChips,ManagedEnvironmentTriageArrivalContinuity,DashboardKpis, andEnvironmentDashboardOverview.EnvironmentDashboard::getUrl()resolves route-ownedManagedEnvironmentand strips workspace/environment parameters intoManagedEnvironmentLinks::viewUrl().EnvironmentDashboardSummaryBuilderalready 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:
BaselineCompareLandingis environment-owned at slugworkspaces/{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, andnav. BaselineCompareStats::forTenant()derives states includingno_tenant,no_assignment,no_snapshot,invalid_scope,comparing,failed,idle, andready.- Existing compare start action uses
Action::make('compareNow')->requiresConfirmation()->action(...),BaselineCompareService::startCompare(),UiEnforcement,OperationUxPresenter, andOpsUxBrowserEvents. - 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.phpapps/platform/app/Filament/Widgets/Dashboard/EnvironmentDashboardOverview.phpapps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-overview.blade.phpapps/platform/resources/views/filament/widgets/dashboard/environment-dashboard-context-chips.blade.phpapps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.phpapps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummary.phpapps/platform/app/Filament/Pages/BaselineCompareLanding.phpapps/platform/resources/views/filament/pages/baseline-compare-landing.blade.phpapps/platform/resources/lang/en/*andapps/platform/resources/lang/de/*only where touched copy follows existing localization conventions.
Tests, only during later implementation:
apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.phpapps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.phpapps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.phpapps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.phpapps/platform/tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.phpapps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.phpapps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.phpapps/platform/tests/Feature/Rbac/DriftLandingUiEnforcementTest.phpapps/platform/tests/Feature/Navigation/Spec322AdminSurfaceScopeContractTest.phpapps/platform/tests/Feature/Navigation/Spec322EnvironmentCtaUrlContractTest.phpapps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentCopyNeutralizationGuardTest.phpapps/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:
ManagedEnvironmentand workspace relation.ProviderConnectionstatus/health/consent/readiness fields.ManagedEnvironmentPermissionand required permissions view model.TenantBackupHealthResolver,TenantBackupHealthAssessment, backup sets/schedules.RestoreSafetyResolverand restore/recovery evidence presentation.TenantGovernanceAggregateResolver,Finding,FindingException, and baseline compare stats.EvidenceSnapshot,EnvironmentReview,ReviewPack, and related links.OperationRunattention/freshness/outcome andOperationRunLinks.
- Baseline drift/action state must derive from:
BaselineTenantAssignment,BaselineProfile,BaselineSnapshot,BaselineSnapshotTruthResolver.BaselineCompareStats,TenantGovernanceAggregate,BaselineCompareSummaryAssessment,operatorExplanation.Findingdrift 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_SYNCthrough existingUiEnforcement. - Baseline profile links:
BaselineProfileResourceauthorization/policies. - Drift findings:
FindingResource/ finding capabilities. - Evidence snapshots:
EvidenceSnapshotPolicy/ evidence capability. - Review and review packs:
EnvironmentReviewResource,ReviewPackResource, policies. - Operation proof:
OperationRunPolicyand link helpers. - Diagnostics/raw detail:
SUPPORT_DIAGNOSTICS_VIEWor 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
tenantplatform-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
Tenantallowed, 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 platformtenantcopy. - 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:assetschange beyond existing deployment posture. - Staging validation should focus on route-owned environment behavior, no-baseline/action-needed states, diagnostics collapsed, and no static
tenantcopy.
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.