TenantAtlas/specs/330-environment-dashboard-baseline-compare-productization/repo-truth-map.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

119 lines
19 KiB
Markdown

# Spec 330 Repo Truth Map
Status: implemented
Created: 2026-05-19
Purpose: classify each Environment Dashboard and Baseline Compare productization element before runtime implementation.
## Classification Legend
- `repo-verified`: exact runtime source exists and was inspected.
- `foundation-real`: backend model/service/policy exists, but exact page binding still needs implementation verification.
- `derived from existing model`: display value can be derived from existing persisted/domain truth.
- `empty/unavailable state`: no safe source/action exists for v1; show explicit unavailable state or omit.
- `deferred future capability`: outside Spec 330 and must not be shown as live runtime truth.
## Required Data Areas
| Data area | Repo source | Preparation finding | Classification |
|---|---|---|---|
| ManagedEnvironment | `App\Models\ManagedEnvironment`, `ManagedEnvironmentLinks`, environment routes | Environment-owned route, workspace relation, display name, slug, provider links are repo-real | repo-verified |
| Provider connection/readiness | `ProviderConnection`, `EnvironmentDashboardSummaryBuilder::primaryProviderConnection()`, provider health fields | Existing primary provider chip/health/readiness sources exist; page binding already used by dashboard cards | repo-verified |
| Required permissions | `ManagedEnvironmentPermission`, `ManagedEnvironmentRequiredPermissionsViewModelBuilder`, required permissions route | Existing dashboard summary derives missing application/delegated permissions and action links | repo-verified |
| Backup sets | `BackupSet`, `TenantBackupHealthResolver`, backup-set resources | Backup health/posture is existing repo truth; exact dashboard wording must stay derived | repo-verified |
| Restore runs | `RestoreRun`, `RestoreSafetyResolver`, restore-run resources | Recovery proof/restore safety exists as derived dashboard evidence; no new recovery engine | foundation-real |
| Recovery proof | `RestoreSafetyResolver::dashboardRecoveryEvidence()`, `TenantRecoveryTriagePresentation` | Current dashboard already considers recovery evidence state in posture | repo-verified |
| Baseline profile assignment | `BaselineTenantAssignment`, `BaselineProfile` | Baseline Compare stats resolve assignment/no-assignment state | repo-verified |
| Baseline snapshots | `BaselineSnapshot`, `BaselineSnapshotTruthResolver` | Compare availability depends on consumable active/effective snapshot | repo-verified |
| Baseline compare result | `BaselineCompareStats`, `OperationRun`, compare summary/outcome fields | Compare state, latest run, coverage, evidence gaps, findings, failure state are existing truth | repo-verified |
| Drift findings | `Finding`, `FindingResource`, `BaselineCompareStats::findingAttentionCounts()` | Findings/severity and attention counts exist; use only scoped/authorized links | repo-verified |
| Risk exceptions / accepted risks | `FindingException`, `FindingExceptionResource`, exception stats in summary builder | Dashboard already derives exception stats; accepted-risk copy must remain honest | repo-verified |
| Evidence snapshots | `EvidenceSnapshot`, `EvidenceSnapshotResource`, latest evidence snapshot in summary builder | Dashboard can link/show latest evidence; Baseline Compare has evidence gap details from runs | repo-verified |
| Review packs | `ReviewPack`, `ReviewPackResource`, dashboard latest review pack | Dashboard summary uses latest review pack/customer output card | repo-verified |
| Environment reviews | `EnvironmentReview`, `EnvironmentReviewResource`, `EnvironmentReviewComposer` | Latest/current review cards and links exist | repo-verified |
| OperationRuns | `OperationRun`, `OperationRunLinks`, `OperationUxPresenter` | Existing execution proof and attention summaries exist; OperationRun is proof/context, not health certification | repo-verified |
| Audit links if present | `AuditLog`, related resource/action records | Audit trail exists but Environment Dashboard/Baseline Compare direct audit links must be implementation-verified before display | foundation-real |
## UI Element Map
| UI element | Surface | Source model/service/page | Status source | Authorization/capability | Workspace/Environment scope | OperationRun/evidence/baseline/drift link | Fallback/empty state | Classification |
|---|---|---|---|---|---|---|---|---|
| Environment Dashboard route | Environment Dashboard | `EnvironmentDashboard`, `ManagedEnvironmentLinks::viewUrl()` | route binding | environment membership + `TENANT_VIEW` | explicit `/admin/workspaces/{workspace}/environments/{environment}` | child resource links | 404 when inaccessible | repo-verified |
| Environment title/context | Environment Dashboard | `EnvironmentDashboard::getTitle()`, context chips widget | environment/workspace/provider records | page access | route-bound environment | latest activity from provider/review/evidence/operations | title without provider/latest activity when missing | repo-verified |
| Main readiness question | Environment Dashboard | new view copy over existing widget | static copy + summary payload | page access | route-bound environment | none | still show question with unavailable state | derived from existing model |
| Readiness status | Environment Dashboard | `EnvironmentDashboardSummaryBuilder::posture()` | missing permissions, aggregate, backup health, recovery evidence, actions | page access | route-bound environment | links via recommended actions | `Action needed` or `Unavailable` | repo-verified |
| Readiness reason | Environment Dashboard | recommended action reason or aggregate headline | existing action/aggregate strings | page access | route-bound environment | action target | `Reason unavailable` | derived from existing model |
| Readiness impact | Environment Dashboard | recommended action impact or aggregate supporting message | existing action/aggregate strings | page access | route-bound environment | action target | `Impact unavailable` | derived from existing model |
| Primary next action | Environment Dashboard | `recommendedActions[0]` and header action | route/action URL + capability | existing resource policies/capabilities | route-bound environment | provider/backup/evidence/review/operation/baseline links | disabled/unavailable when no safe action | repo-verified |
| Ranked next actions | Environment Dashboard | `EnvironmentDashboardSummaryBuilder::recommendedActions()` | priorities and candidate actions | existing resource policies/capabilities | route-bound environment | multiple child routes | empty calm/unavailable state | repo-verified |
| Provider readiness dimension | Environment Dashboard | `ProviderConnection`, required permissions VM | provider health/status/check timestamps | provider/permission capabilities | route-bound environment | required permissions route | `Provider readiness unavailable` | repo-verified |
| Required permissions dimension | Environment Dashboard | permissions VM overview counts | missing application/delegated counts | required permissions visibility | route-bound environment | required permissions route | `Permissions unavailable` | repo-verified |
| Backup posture dimension | Environment Dashboard | `TenantBackupHealthResolver` | backup health posture/headline | backup capabilities | route-bound environment | backup-set/schedule routes | `Backup proof missing` | repo-verified |
| Recovery proof dimension | Environment Dashboard | `RestoreSafetyResolver`, recovery presentation | recovery evidence state | restore/backup capabilities | route-bound environment | restore/backup routes | `Recovery proof unavailable` / stale | foundation-real |
| Baseline assignment dimension | Environment Dashboard | `BaselineTenantAssignment`, aggregate | assignment/compare summary | baseline/profile capabilities | route-bound environment | Baseline Compare route | `Baseline not assigned` | derived from existing model |
| Baseline compare / drift dimension | Environment Dashboard | `TenantGovernanceAggregateResolver`, `BaselineCompareStats` | aggregate family/headline/counts | finding/baseline visibility | route-bound environment | Baseline Compare / findings | `Compare unavailable` | repo-verified |
| Evidence freshness dimension | Environment Dashboard | latest `EvidenceSnapshot` | generated/expires/status fields | evidence capability/policy | route-bound environment | evidence snapshot route | `Evidence unavailable` | repo-verified |
| Review freshness dimension | Environment Dashboard | latest `EnvironmentReview` | published/generated/updated timestamps | review capability/policy | route-bound environment | review route/customer workspace | `No recent review` | repo-verified |
| Accepted risks dimension | Environment Dashboard | `FindingException` stats | active/expiring/expired/pending counts | finding exception capability | route-bound environment | finding exceptions route | `No accepted risk record` / unavailable | repo-verified |
| Operations requiring attention | Environment Dashboard | `OperationRun` attention query | problem class/freshness/outcome | operation visibility | route-bound environment | operation detail/hub | no attention summary | repo-verified |
| Right proof/action panel | Environment Dashboard | page/widget payload over sources above | source-specific availability | per-link capability | route-bound environment | operation/evidence/review/backup/provider links | explicit unavailable rows | derived from existing model |
| Support diagnostics disclosure | Environment Dashboard | existing support diagnostics action/modal | support diagnostics bundle | `SUPPORT_DIAGNOSTICS_VIEW` | route-bound environment | audit log via existing action | hidden/disabled when unauthorized | repo-verified |
| Raw provider payloads | Environment Dashboard | provider raw payloads/logs | sensitive raw data | support-only future | N/A | N/A | never default-visible | deferred future capability |
| Baseline Compare route | Baseline Compare | `BaselineCompareLanding`, slug route | route binding | environment membership + `TENANT_VIEW` | explicit `/admin/workspaces/{workspace}/environments/{environment}/baseline-compare` | baseline/run/finding links | 404 when inaccessible | repo-verified |
| Baseline Compare generated URL | Baseline Compare | `BaselineCompareLanding::getUrl()`, `ManagedEnvironmentLinks::baselineCompareUrl()` | URL helper | environment access | route-bound environment | preserves baseline profile/subject/nav launch context | `/admin` fallback when no environment | repo-verified |
| Legacy alias stripping | Baseline Compare | `LEGACY_SCOPE_QUERY_KEYS`, `withoutLegacyScopeQuery()` | query key removal | page access | aliases do not set scope | none | query ignored/route rejected | repo-verified |
| Remembered fallback rejection | Baseline Compare | `BaselineCompareEnvironmentRouteContractTest`, `canAccess()` | route-owned environment | environment access | explicit route only | none | 404/false access | repo-verified |
| Main drift question | Baseline Compare | new view copy over existing page | static copy + stats payload | page access | route-bound environment | none | still show question with unavailable state | derived from existing model |
| Assigned baseline state | Baseline Compare | `BaselineCompareStats`, `BaselineTenantAssignment`, `BaselineProfile` | assignment/profile fields | baseline/profile visibility | route-bound environment | baseline profile/matrix routes | `Baseline not assigned` | repo-verified |
| Snapshot/compare availability | Baseline Compare | `BaselineSnapshotTruthResolver`, `BaselineCompareStats` | effective snapshot/reason code | page access | route-bound environment | capture/run proof if exists | `No complete snapshot` / unavailable | repo-verified |
| Compare trust | Baseline Compare | operator explanation, summary assessment, coverage/evidence gap fields | trust/evaluation/coverage state | page access | route-bound environment | run/evidence gap links | `Compare unavailable` | repo-verified |
| Drift impact | Baseline Compare | findings count/severity counts, aggregate | `Finding` and stats counts | finding visibility | route-bound environment | findings route/matrix | `No drift result` / `No usable result` | repo-verified |
| Reason | Baseline Compare | `reasonCode`, `reasonMessage`, operator explanation | reason translation / stats | page access | route-bound environment | run details | `Reason unavailable` | repo-verified |
| Evidence path | Baseline Compare | evidence gaps, snapshot, OperationRun, findings | stats fields/run context | page/finding/run/evidence capabilities | route-bound environment | operation/finding/matrix/evidence gap details | `Evidence unavailable` | foundation-real |
| Primary next action | Baseline Compare | page-local derived from state + existing actions | state and authorized route/action | `TENANT_SYNC` for compare start; resource policies for links | route-bound environment | compare/run/baseline/findings/matrix links | unavailable when no safe action | derived from existing model |
| No-baseline compare readiness flow | Baseline Compare | `BaselineCompareLanding` page-local payload | missing assignment, snapshot id, latest inventory/evidence proof, compare run availability | page access; links stay in decision card | route-bound environment | no new operation | show ordered visual stepper/pipeline with missing/unavailable states only | derived from existing model |
| No-baseline available inputs | Baseline Compare | `InventoryItem`, latest completed inventory sync `OperationRun`, compare `operationRunId`, baseline assignment/snapshot state | repo-backed availability labels | page access | route-bound environment | environment snapshot / operation proof / baseline snapshot availability | unavailable when no repo-backed input exists | derived from existing model |
| Assignment unlocks copy | Baseline Compare | static explanatory copy bounded to assignment outcome | no runtime health/drift claim | page access | route-bound environment | none | omit outside no-baseline state | derived from existing model |
| Compare now action | Baseline Compare | `compareNowAction()` | state in idle/ready/failed | `TENANT_SYNC`, `UiEnforcement` | route-bound environment | creates `OperationRun` via service | disabled when not startable | repo-verified |
| Operation proof link | Baseline Compare | `operationRunId`, `getRunUrl()`, `OperationRunLinks` | latest compare run | operation visibility | route-bound environment | operation detail | `Operation proof unavailable` | repo-verified |
| Findings/diff summary | Baseline Compare | findings/severity counts, evidence gaps | stats fields | finding visibility | route-bound environment | findings route/matrix | no findings / unavailable with trust caveat | repo-verified |
| Evidence gap details | Baseline Compare | `BaselineCompareEvidenceGapDetails`, include partial | run diagnostics/gap details | page access; raw remains secondary | route-bound environment | detail section only | hidden when no gaps | repo-verified |
| Raw compare diagnostics | Baseline Compare | `baselineCompareDiagnostics`, JSON viewer include | diagnostics array from run | support/raw capability or collapsed default | route-bound environment | run details | collapsed/hidden by default | foundation-real |
| Raw diff payload | Baseline Compare | raw compare output/diagnostics | not safe default | support-only future | route-bound environment | run detail if authorized | never default-visible | deferred future capability |
| Static tenant copy guard | Both | runtime copy/tests | string assertions | N/A | route-bound environment copy uses Environment | N/A | dynamic names allowed | repo-verified |
## Required Runtime Element Decisions
| Element | v1 decision |
|---|---|
| New environment readiness engine | deferred future capability; do not build |
| New persisted readiness status | deferred future capability; do not build |
| New baseline/drift engine | deferred future capability; do not build |
| New evidence generator | deferred future capability; do not build |
| New backup/recovery proof engine | deferred future capability; do not build |
| Generic health/compliance/protected/customer-safe badge | deferred future capability; do not show unless exact repo proof supports the exact claim |
| Environment readiness status | derive from existing dashboard summary, backup, recovery, permissions, baseline, evidence, review, risk, and operation truth |
| Baseline assignment state | derive from existing `BaselineTenantAssignment` and `BaselineProfile` |
| Compare availability/trust | derive from existing `BaselineCompareStats`, snapshot truth, run state, coverage, evidence gaps, and operator explanation |
| Drift impact | derive from existing findings/severity/evidence gap state |
| Operation proof | link only through existing run relations/helpers and authorization |
| No-baseline readiness flow | visualize required pipeline inputs, dependency order, current blocker, and current availability only; do not show fake drift data or duplicate lower summary cards |
| Diagnostics | collapsed/hidden by default and capability-aware if exposed |
| Raw provider payloads / raw diff | never default-visible |
| Dangerous/mutating actions | do not add; existing compare start remains confirmed/capability-gated/OperationRun-backed |
| Legacy query aliases | rejected/neutralized; do not support |
## Implementation Update Rule
If implementation discovers that a planned UI element has no safe source, no authorization path, or would require new persisted truth, the element must become `empty/unavailable state` or `deferred future capability`. Do not create backend foundation inside Spec 330 without updating `spec.md`, `plan.md`, `tasks.md`, and this map first.
## Close-out Coverage Note
- Runtime changes stayed within the existing UI-002 Environment Dashboard and UI-061 Baseline Compare strategic surfaces. The no-baseline Compare readiness flow is a page-local visual stepper over existing assignment, snapshot, inventory/evidence, and OperationRun truth. No route archetype, panel provider, global search, navigation family, persisted entity, enum/status family, migration, package, queue, scheduler, env var, storage, deployment asset, or compatibility route was added.
- The existing UI coverage registry remains sufficient because Spec 330 carries the feature-local truth map, focused Feature/Livewire coverage, explicit browser smoke, and screenshots under `specs/330-environment-dashboard-baseline-compare-productization/artifacts/screenshots/`.
- Final screenshot artifacts:
- `environment-dashboard-readiness-workbench.png`
- `environment-dashboard-action-needed.png`
- `baseline-compare-no-baseline.png`
- `baseline-compare-decision-workbench.png`
- Final classification: implemented elements are derived from existing repository truth. Raw provider payloads, raw compare diagnostics, raw diff, and raw OperationRun context remain hidden/collapsed by default and are not treated as default operator evidence.