# Research — Tenant Dashboard Productization v1

**Date**: 2026-05-02  
**Spec**: [spec.md](spec.md)

This document resolves the planning decisions for the smallest safe productization follow-up on the tenant dashboard.

## Decision 1 — Keep the existing tenant dashboard route as the canonical tenant landing surface

**Decision**: Productize the existing [../../apps/platform/app/Filament/Pages/TenantDashboard.php](../../apps/platform/app/Filament/Pages/TenantDashboard.php) page at `/admin/t/{tenant}` instead of creating a second tenant landing page, new panel, or portal shell.

**Rationale**:
- The repo already routes tenant selection, onboarding completion, support diagnostics bundles, and portfolio arrival continuity back to this page.
- The product gap is the current composition and decision hierarchy, not missing routing or missing tenant context.
- Reusing the existing page preserves current workspace and tenant isolation behavior and keeps the slice bounded.

**Alternatives considered**:
- Add a second tenant-home page.
  - Rejected: duplicates the existing tenant route and widens shell-level information architecture scope.
- Convert the page into a new Resource.
  - Rejected: the dashboard is still a derived landing surface, not a new persisted model family.

## Decision 2 — Collapse the current widget stack behind one bounded dashboard summary composition

**Decision**: Replace the current seven-widget first-screen stack with one bounded dashboard summary and composite overview surface while keeping current widgets as truth seams or migration sources.

**Rationale**:
- The current stack splits posture, recovery, baseline compare, findings, and operations into separate blocks that operators must manually reconcile.
- A single dashboard-local summary layer is the narrowest way to apply the new caps on KPI count, header actions, and recommended actions while keeping fallback behavior coherent.
- The constitution allows a narrow abstraction here because the existing local shape is insufficient for the required operator workflow.

**Alternatives considered**:
- Keep the widget stack and only adjust copy or spacing.
  - Rejected: leaves priority fragmented and does not satisfy the decision-first first-screen contract.
- Introduce a generic dashboard framework.
  - Rejected: imports unnecessary structure beyond current release truth.

## Decision 3 — Preserve arrival-context continuity as a thin contextual strip, not as a first-screen dominant block

**Decision**: Keep [../../apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php](../../apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php) as a conditional contextual strip when arrival metadata exists, but do not let it displace the new decision-first hierarchy.

**Rationale**:
- Arrival continuity is already a real workflow seam for portfolio triage and should not be discarded.
- It is contextual support information, not the primary tenant posture surface.
- Keeping it conditional preserves continuity without repeating the tenant's main problem summary.

**Alternatives considered**:
- Remove the arrival surface entirely.
  - Rejected: breaks an existing workflow continuity seam.
- Leave the current arrival block as a top-of-page dominant widget.
  - Rejected: it competes with the new posture and next-action summary.

## Decision 4 — Use the existing Governance Inbox as the primary canonical governance queue when the operator can open it

**Decision**: Treat [../../apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php](../../apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php) as a repo-real primary follow-up destination because it already supports workspace membership checks, tenant prefiltering, family filters, and calm empty-state behavior.

**Rationale**:
- The page already accepts `tenant_id` query input, resolves a selected tenant from current authorized tenants, and keeps workspace-safe visibility rules.
- This allows the dashboard to use `Open governance inbox` or a narrower `Review findings` style CTA without inventing a new governance queue.
- The inbox already behaves as a decision-oriented canonical surface rather than a raw storage list.

**Alternatives considered**:
- Always link directly to findings.
  - Rejected: loses the chance to route operators into the existing canonical governance queue when it is the better working surface.
- Invent a dashboard-only governance queue.
  - Rejected: fake route and clear scope expansion.

## Decision 5 — Keep risk and exception follow-up on the existing FindingException resource

**Decision**: Use [../../apps/platform/app/Filament/Resources/FindingExceptionResource.php](../../apps/platform/app/Filament/Resources/FindingExceptionResource.php) and its current list or view pages as the repo-real risk-exception surface for dashboard follow-up.

**Rationale**:
- The resource already exposes tenant-scoped stats, status badges, and view routes for exception records.
- The repo already treats exceptions and accepted-risk governance as tenant-owned truth.
- The dashboard needs summary and drill-through, not a new accepted-risk page.

**Alternatives considered**:
- Introduce a new `Accepted Risks` dashboard route.
  - Rejected: unnecessary duplication of exception truth.
- Keep risk information as non-actionable summary only.
  - Rejected: the spec requires next actions and real follow-up paths.

## Decision 6 — Treat required permissions as the provider-health follow-up seam

**Decision**: Use [../../apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php](../../apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php) and [../../apps/platform/app/Support/Links/RequiredPermissionsLinks.php](../../apps/platform/app/Support/Links/RequiredPermissionsLinks.php) as the repo-real provider blockage and follow-up seam.

**Rationale**:
- Repo discovery did not surface a dedicated tenant provider-health page equivalent to the mockup card.
- Required-permissions truth already gives overall status, missing counts, feature impacts, freshness, and deep-link generation.
- This is the narrowest current-release implementation that keeps provider detail on provider-owned surfaces.

**Alternatives considered**:
- Add a new tenant provider-health page.
  - Rejected: scope expansion and unnecessary new surface.
- Use vague provider health text without an actual destination.
  - Rejected: breaks the repo-real follow-up requirement.

## Decision 7 — Reuse existing review, evidence, and review-pack routes for customer-safe output readiness

**Decision**: Reuse the current customer-review and artifact surfaces instead of inventing a customer-view route.

**Rationale**:
- [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) already supports tenant-prefiltered customer-safe review consumption.
- [../../apps/platform/app/Filament/Resources/TenantReviewResource.php](../../apps/platform/app/Filament/Resources/TenantReviewResource.php), [../../apps/platform/app/Filament/Resources/ReviewPackResource.php](../../apps/platform/app/Filament/Resources/ReviewPackResource.php), and [../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php](../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php) already own detailed truth and capability checks.
- [../../apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php](../../apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php) already exposes latest-pack and generation-decision seams if a retained action needs them.

**Alternatives considered**:
- Add a new `Open customer view` route.
  - Rejected: fake maturity and explicit spec violation.
- Keep output readiness as static copy only.
  - Rejected: loses the real downstream handoff surfaces that already exist.

## Decision 8 — Reuse canonical operations continuity for recent runs and follow-up

**Decision**: Keep [../../apps/platform/app/Filament/Pages/Monitoring/Operations.php](../../apps/platform/app/Filament/Pages/Monitoring/Operations.php) and [../../apps/platform/app/Support/OperationRunLinks.php](../../apps/platform/app/Support/OperationRunLinks.php) as the only canonical operations follow-up path.

**Rationale**:
- The canonical operations page already applies dashboard prefilter state and preserves tenant continuity.
- `OperationRunLinks` already centralizes labels and URLs.
- The dashboard needs calmer recent-run summary, not a second operations viewer.

**Alternatives considered**:
- Keep a full operations table as the first-screen primary surface.
  - Rejected: breaks the decision-first contract.
- Add a dashboard-local operations detail layer.
  - Rejected: duplicates the canonical monitoring surface.

## Decision 9 — Demote support request and diagnostics utilities out of the primary header plane

**Decision**: Do not keep support request and diagnostics as the default dominant header actions when the dashboard is productized. If retained, they move to a clearly secondary utility position.

**Rationale**:
- The spec caps visible header actions at two and requires the header to stay decision-first.
- The current page header is utility-heavy rather than governance-first.
- Support request and diagnostics remain real features, but they are not the primary tenant-governance action on first load.

**Alternatives considered**:
- Leave support utilities in the main header and squeeze governance actions elsewhere.
  - Rejected: preserves the current action hierarchy problem.
- Remove support utilities entirely.
  - Rejected: unnecessary functionality loss.

## Decision 10 — Use existing dashboard truth and customer-health phrasing patterns instead of inventing a new dashboard score vocabulary

**Decision**: Reuse existing badge semantics and calm reason/impact phrasing patterns from current dashboard and customer-health surfaces rather than introducing a new dashboard-specific scoring language.

**Rationale**:
- Existing badge semantics are already centralized.
- [../../apps/platform/app/Filament/System/Pages/Directory/Concerns/BuildsCustomerHealthDecisionData.php](../../apps/platform/app/Filament/System/Pages/Directory/Concerns/BuildsCustomerHealthDecisionData.php) already demonstrates reason/impact/recommended-action phrasing that is calm and enterprise-safe.
- The spec forbids creating a new local status taxonomy.

**Alternatives considered**:
- Add a new composite dashboard score or taxonomy.
  - Rejected: violates proportionality and risks duplicate truth.
- Leave current widget-local wording unchanged.
  - Rejected: misses the productization goal.

## Decision 11 — Keep browser proof bounded to one new tenant-dashboard smoke

**Decision**: Expand existing dashboard feature tests and add exactly one browser smoke covering the productized tenant landing flow.

**Rationale**:
- The repo already contains dashboard DB-only, truth-alignment, scope, arrival-context, and RBAC tests that are the right base to expand.
- The main user-visible risk is first-screen information hierarchy and action density, which merits one real-browser pass.
- A broader browser family would increase test-governance cost without materially better proof.

**Alternatives considered**:
- Add multiple browser tests for every card and every follow-up route.
  - Rejected: too broad for a bounded productization slice.
- Rely on feature tests only.
  - Rejected: does not prove the primary first-screen operator flow under real rendering.