TenantAtlas/specs/245-customer-health-score/spec.md
ahmido 86505483bf
Some checks failed
Main Confidence / confidence (push) Failing after 52s
feat(customer-health): add decision card to tenant/workspace detail (spec 245) (#283)
Add Customer Health decision card to tenant & workspace detail pages (spec 245).

What I changed:
- Render a decision-first Customer Health card on tenant and workspace detail pages.
- Reuse `WorkspaceHealthSummaryQuery` and preserve `window` query param.
- Update attention widget link text to "Review health details" and include `?window=`.
- Add/adjust tests to cover new behavior and explainability.
- Run Pint formatting.

Compare URL: https://git.cloudarix.de/ahmido/TenantAtlas/compare/dev...245-customer-health-score

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #283
2026-04-27 08:30:01 +00:00

340 lines
37 KiB
Markdown

# Feature Specification: Customer Health Score
**Feature Branch**: `245-customer-health-score`
**Created**: 2026-04-27
**Status**: Ready for implementation
**Input**: User description: "Promote the roadmap-fit candidate Customer Health Score as a narrow, implementation-ready slice that derives an explainable workspace health summary from existing telemetry, onboarding readiness, provider connection health, operation outcomes, findings pressure, and review-pack readiness, then surfaces one attention-oriented summary on the existing system dashboard without introducing CRM, predictive scoring, billing collection, or customer-facing account-management workflows."
## Spec Candidate Check *(mandatory — SPEC-GATE-001)*
- **Problem**: TenantPilot still requires founder-style manual inspection across onboarding, provider connections, failed runs, findings, review packs, and telemetry to understand which workspaces actually need attention.
- **Today's failure**: The product exposes isolated health clues, but no explainable workspace-level summary. Operators must reconstruct risk by hopping between `/system`, tenant directory, run lists, and tenant surfaces, which delays support and masks silent customer/workspace deterioration.
- **User-visible improvement**: A platform operator can open the existing `/system` dashboard and immediately see which workspaces are healthy, which need attention, why they need attention, and which existing platform-safe surface to open next. When the operator follows that link into the existing system tenant or workspace detail, the page repeats the decision-first health explanation above the existing diagnostics.
- **Smallest enterprise-capable version**: Add one derived customer-health query path with six fixed first-slice dimensions, reuse the existing system dashboard and window selector, show aggregate health counts plus an attention-needed workspace list, and keep the entire slice read-only and non-persistent.
- **Explicit non-goals**: No CRM or customer-success suite, no billing collection or entitlement enforcement, no predictive churn model, no customer-facing health portal, no tenant/admin-plane health viewer, no new persisted score table, no background recomputation job, and no AI-generated account-management actions.
- **Permanent complexity imported**: One bounded `CustomerHealth` support namespace, one derived summary query path, one small fixed dimension catalog, two dashboard widgets, and focused unit plus feature coverage.
- **Why now**: Self-Service Tenant Onboarding & Connection Readiness, Support Diagnostic Pack, Operational Controls, Product Usage & Adoption Telemetry, and Product Knowledge are now specced or implemented. Customer Health Score is the smallest next slice that turns those foundations into one operator-facing attention signal before lifecycle communication, AI assistance, or broader portfolio workflows expand.
- **Why not local**: Local counters on the system dashboard or one-off health badges in the directory would either duplicate logic across surfaces or hide how onboarding, provider, operational, governance, review-pack, and adoption truth combine into one explainable workspace summary.
- **Approval class**: Core Enterprise
- **Red flags triggered**: New abstraction, many-signal summary. Defense: the slice stays derived-only, reuses the existing `SystemHealth` level language, fixes the first-slice dimension inventory at six signals, and limits UI impact to the existing `/system` dashboard.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexität: 1 | Produktnähe: 2 | Wiederverwendung: 2 | **Gesamt: 10/12**
- **Decision**: approve
## Spec Scope Fields *(mandatory)*
- **Scope**: platform, workspace, tenant
- **Primary Routes**:
- `/system` existing system dashboard for aggregate health counts and the attention-needed workspace list
- existing platform-safe deep links from those widgets into the system tenant directory and system operations surfaces
- existing `/system/directory/tenants/{tenant}` and `/system/directory/workspaces/{workspace}` residual detail pages as read-only health follow-up surfaces
- **Data Ownership**: No new persisted customer-health truth is introduced. The summary is derived from existing tenant-owned product truths such as `product_usage_events`, `provider_connections`, `operation_runs`, `findings`, `review_packs`, and onboarding-readiness state already owned by existing onboarding/session/provider records.
- **RBAC**: Reads remain platform-plane only through the existing `/system` dashboard access gate. No tenant/admin-plane or customer-facing health surface is introduced in this slice.
For canonical-view specs, the spec MUST define:
- **Default filter behavior when tenant-context is active**: N/A - the first slice is a platform-plane dashboard addition under `/system`, not a tenant-context admin view.
- **Explicit entitlement checks preventing cross-tenant leakage**: The slice exposes derived counts and system-safe drilldown links only to existing platform users who can already access the system dashboard. It does not expose raw tenant-owned health rows or create any cross-plane deep link into `/admin` tenant surfaces.
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
- **Cross-cutting feature?**: yes
- **Interaction class(es)**: dashboard signals/cards, read-only attention list, system-safe deep links, status badges
- **Systems touched**: `App\Filament\System\Pages\Dashboard`, existing system dashboard widget family, `App\Support\ProductTelemetry\ProductTelemetrySummaryQuery`, `App\Services\Providers\ProviderConnectionStateProjector`, `App\Support\SystemConsole\StuckRunClassifier`, existing `Finding` and `ReviewPack` truth queries, and existing system link helpers
- **Existing pattern(s) to extend**: the `/system` dashboard widget composition, the existing dashboard time-window selector, `ControlTowerHealthIndicator`, and `ControlTowerTopOffenders`
- **Shared contract / presenter / builder / renderer to reuse**: `StatsOverviewWidget`, existing custom system widgets, `BadgeRenderer` with `BadgeDomain::SystemHealth`, `SystemConsoleWindow`, `SystemOperationRunLinks`, and existing system directory links
- **Why the existing shared path is sufficient or insufficient**: Existing shared paths already solve dashboard placement, read-only system-plane rendering, time-window selection, and system-safe navigation. They are insufficient because none of them currently derives one explainable workspace-health summary from multiple existing truths.
- **Allowed deviation and why**: One bounded `CustomerHealth` support namespace is allowed to centralize health derivation. Page-local health arithmetic, widget-local badge vocabularies, or duplicated query seams are not allowed.
- **Consistency impact**: Overall health levels must reuse the existing `SystemHealth` vocabulary (`ok`, `warn`, `critical`, `unknown`), and the first-slice dimension labels plus time-basis copy must remain consistent between summary widgets and any linked system-safe detail flow.
- **Review focus**: Reviewers must verify that the slice stays derived-only, does not add a hidden score table, does not invent a second badge taxonomy, does not create platform-to-admin deep links, and does not broaden into customer-success or billing workflow scope.
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
- **Touches OperationRun start/completion/link UX?**: no
- **Shared OperationRun UX contract/layer reused**: N/A - the slice reads existing run truth only and may link to existing system run lists.
- **Delegated start/completion UX behaviors**: N/A
- **Local surface-owned behavior that remains**: N/A
- **Queued DB-notification policy**: N/A
- **Terminal notification path**: N/A
- **Exception required?**: none
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
- **Shared provider/platform boundary touched?**: yes
- **Boundary classification**: mixed
- **Seams affected**: provider verification and consent statuses as one health-dimension input, review-pack status labels, telemetry family activity, and system-safe health copy
- **Neutral platform terms preserved or introduced**: customer health, workspace health, health dimension, attention needed, engagement freshness, review readiness, operational stability
- **Provider-specific semantics retained and why**: Microsoft-specific provider consent and verification outcomes remain inside the provider-health dimension because they are existing current-release truth owned by provider-connection workflows.
- **Why this does not deepen provider coupling accidentally**: The top-level summary stays platform-owned and explainable. Provider-specific codes and statuses are consumed only as one input dimension and are not promoted into a new platform taxonomy.
- **Follow-up path**: Customer Lifecycle Communication and later portfolio workflows may reuse the summary, but they remain separate specs.
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|---|---|---|---|---|---|---|
| System dashboard customer-health KPI widget | yes | Native Filament + shared stats widget | dashboard signals/cards | page, widget, window query | no | Read-only KPI addition on existing `/system` dashboard |
| System dashboard attention-needed workspace widget | yes | Native system widget family with custom Blade view | dashboard signals/cards, read-only attention list, navigation links | page, widget, detail-link state | no | Compact list of unhealthy workspaces only; no new page or workbench |
| System tenant and workspace residual detail pages customer-health decision card | yes | Existing custom system detail pages | linked follow-up context, decision-first explanation | page, window query | no | Read-only summary card above existing diagnostics; no new page or mutation |
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| System dashboard customer-health KPI widget | Secondary Context Surface | Decide whether overall platform attention is rising and whether to inspect unhealthy workspaces now | Count of healthy, warning, critical, and unknown workspaces for the selected window | Existing system tenant directory, operations list, and source surfaces remain evidence | Secondary because it frames attention, not the underlying remediation workflow | Fits the founder or platform-operator control-tower loop | Replaces manual reconstruction across onboarding, telemetry, runs, and findings surfaces |
| System dashboard attention-needed workspace widget | Secondary Context Surface | Decide which workspace to inspect next and which source truth is driving the problem | Workspace name, overall level, dominant dimensions, and one platform-safe next link | Existing system-safe detail surfaces and linked source contexts | Secondary because the actual action still happens on existing system detail and run surfaces | Keeps the dashboard as a triage layer, not a second operations workbench | Surfaces the next workspace to inspect without requiring freeform database or log inspection |
| System tenant and workspace residual detail pages customer-health decision card | Primary Decision Context | Decide why this workspace is `critical`, `warn`, or `unknown` before reading lower-level diagnostics | Overall level, repeated top drivers, operator impact, and recommended next action | Existing connectivity, permissions, tenant, and recent-run sections remain the lower-level evidence | Primary because the card turns the residual detail page into an explain-first follow-up instead of a diagnostic puzzle | Keeps `/system` drilldowns decision-first while preserving the existing read-mostly detail shape | Removes the need to infer the health reason from several independent sections |
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| System dashboard customer-health KPI widget | Dashboard / Overview / KPI widget | Read-only operational summary | Decide whether there is platform-wide attention pressure | In-page stat cards | forbidden | none | none | `/system` | `/system` | Existing dashboard time window and health-level counts | Customer health / Workspace health | Current health-level distribution for visible workspaces | none |
| System dashboard attention-needed workspace widget | Dashboard / Overview / compact list widget | Read-only attention registry | Open the most relevant existing system-safe detail surface for one unhealthy workspace | Named link per workspace row | forbidden | One explicit platform-safe next link per row | none | `/system` | existing linked system detail surfaces only | Workspace label, dominant dimensions, and selected time window | Attention-needed workspaces / Workspace | Which workspace needs review next and why | Compact dashboard widget justified because the list is triage-only, not a new registry page |
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| System dashboard customer-health KPI widget | Platform operator | Decide whether customer or workspace health is deteriorating overall | Dashboard summary | How many workspaces are healthy, unknown, warning, or critical right now? | Level counts, selected time window, and clear empty or unknown handling | Raw contributing rows, provider-specific details, and per-tenant evidence stay out of the widget | overall health level only | none | existing dashboard time-window selection only | none |
| System dashboard attention-needed workspace widget | Platform operator | Decide which workspace to inspect next and what kind of issue is driving it | Compact attention list | Which workspace needs attention first, and what is the dominant reason? | Workspace label, overall level, top one or two non-ok dimensions, and one system-safe next link | Full source record sets, provider codes, detailed finding counts, and review-pack internals remain in linked surfaces | overall level plus dominant health dimensions | none | open linked system-safe detail surface | none |
| System tenant and workspace residual detail pages customer-health decision card | Platform operator | Decide what to review first on the current detail page | Read-only follow-up summary | Why is this workspace unhealthy or unknown, and what should I inspect next? | Overall health, repeated top drivers, operator impact, recommended next action, and preserved selected-window context for windowed dimensions | Lower-level connectivity, permission, tenant, and recent-run evidence remains in the existing sections below | overall level plus dominant health dimensions | none | open existing linked follow-up surfaces only when already present on the page | none |
## 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 |
|---|---|---|---|---|---|---|---|---|---|---|
| System dashboard page | `App\Filament\System\Pages\Dashboard` | Existing `Time window` header action only; no new header actions | n/a | n/a | none | n/a | n/a | n/a | no | Action Surface Contract remains satisfied because the feature adds read-only widgets only and does not alter the page-level mutation model |
| Attention-needed workspace widget | `App\Filament\System\Widgets\CustomerHealthTopWorkspaces` | none | One named platform-safe next link per row; row click remains forbidden | Max one visible next link, chosen as `Review health details` or `Open runs` based on the dominant reason | none | One explanatory empty state with no CTA when no workspace needs attention | n/a | n/a | no | Every row must still expose one platform-safe next link. If no more specific route fits, the row falls back to the existing system tenant-detail context rather than inventing a new surface or showing no link |
**List-surface standard reference:** The attention-needed workspace widget is a compact list surface and MUST be reviewed against `/Users/ahmeddarrazi/Documents/projects/wt-plattform/docs/product/standards/list-surface-review-checklist.md` before implementation sign-off. Accepted v1 exceptions are limited to compact dashboard-widget constraints: no persistence trio, no bulk actions, no row click, and no empty-state CTA because this surface is triage-only rather than a standalone registry page.
## Proportionality Review *(mandatory when structural complexity is introduced)*
- **New source of truth?**: no
- **New persisted entity/table/artifact?**: no
- **New abstraction?**: yes
- **New enum/state/reason family?**: no - the slice reuses existing `SystemHealth` levels
- **New cross-domain UI framework/taxonomy?**: no
- **Current operator problem**: the platform has no single explainable workspace-health summary even though the underlying truth already exists in onboarding, provider, operations, findings, review packs, and telemetry.
- **Existing structure is insufficient because**: the existing structures each explain one domain only. None can honestly answer which workspace is unhealthy overall without duplicating cross-domain query logic or forcing manual reconstruction.
- **Narrowest correct implementation**: add one bounded derived-query path and one small fixed dimension catalog, then surface it on the existing system dashboard only.
- **Ownership cost**: one support namespace, two dashboard widgets, fixed dimension rules, and focused unit plus feature coverage.
- **Alternative intentionally rejected**: a persisted score table, a customer-success page, a background recomputation pipeline, or an opaque weighted scoring engine.
- **Release truth**: current-release truth
### Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.
Canonical replacement is preferred over preservation.
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
- **Test purpose / classification**: Unit, Feature
- **Validation lane(s)**: fast-feedback, confidence
- **Why this classification and these lanes are sufficient**: Unit tests can prove health-level derivation, dimension precedence, unknown handling, and signal inclusion rules. Feature tests can prove dashboard rendering, platform-plane authorization, and system-safe link behavior without browser automation.
- **New or expanded test families**: One focused `CustomerHealth` unit family plus a small set of `/system` feature tests for summary widgets, explainability, and authorization.
- **Fixture / helper cost impact**: Moderate. Reuse existing workspaces, tenants, provider connections, onboarding sessions, product-usage events, operation runs, findings, and review packs. Avoid new browser helpers, seeded dashboards, or heavy system defaults.
- **Heavy-family visibility / justification**: none
- **Special surface test profile**: standard-native-filament
- **Standard-native relief or required special coverage**: standard native Filament feature coverage is sufficient because the slice adds read-only widgets only.
- **Reviewer handoff**: Reviewers must confirm that the health summary is derived-only, that `unknown` and stale data are not silently treated as healthy, that system-safe links remain on the platform plane, that no new persistence appears, and that the selected window affects only the intended windowed dimensions.
- **Budget / baseline / trend impact**: Low-to-moderate increase in narrow unit plus feature coverage only.
- **Escalation needed**: none
- **Active feature PR close-out entry**: Guardrail
- **Test-governance outcome**: keep
- **Planned validation commands**:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/CustomerHealth/CustomerHealthDimensionCatalogTest.php tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php`
## Functional Requirements
- **FR-001**: The system MUST derive one workspace-health summary from exactly six first-slice dimensions: onboarding readiness, provider connection health, operational stability, governance pressure, review-pack readiness, and engagement freshness.
- **FR-002**: The system MUST compute the overall workspace health level from existing `SystemHealth` semantics with explicit precedence: `critical` outranks `warn`, `warn` outranks `unknown`, and `unknown` outranks `ok`.
- **FR-003**: The system MUST keep the first slice derived-only. No persisted score table, asynchronous recomputation store, or secondary health ledger may be introduced.
- **FR-004**: The existing `/system` dashboard MUST show aggregate health counts and an attention-needed workspace list using the existing dashboard window selector for windowed dimensions.
- **FR-005**: The system MUST keep platform-safe navigation boundaries. Health widgets may link only to existing platform-plane system surfaces, never directly to tenant-admin `/admin` routes.
- **FR-006**: The system MUST make stale or missing source truth explicit. Missing or stale inputs must not silently produce `ok`.
- **FR-007**: Review-pack readiness in the first slice MUST stay narrow: it may reflect recent review-pack requests and the latest relevant pack status, but it must not become a quarterly review-obligation engine.
- **FR-008**: The slice MUST not introduce any new customer-facing communication, entitlement, billing, or AI workflow.
## Non-Functional Requirements
- **NFR-001**: The summary query must stay bounded and reusable from the existing system dashboard without new background jobs or remote calls.
- **NFR-002**: Widget copy must remain calm, explainable, and dashboard-first rather than CRM-like, sales-like, or predictive.
- **NFR-003**: Health-level rendering must reuse existing badge or status semantics instead of inventing a second color or severity language.
## UX Requirements
- **UX-001**: The dashboard must remain triage-first. Summary counts and dominant reasons are visible by default; raw counts and low-level diagnostics stay behind existing linked surfaces.
- **UX-002**: The slice must not become a new workbench page. `/system` remains the only first-slice entry point, and any health follow-up must stay inside existing residual detail pages rather than creating a new health detail page.
- **UX-003**: The widget and the linked residual detail decision card must distinguish point-in-time dimensions from windowed dimensions in their copy or presentation so operators do not assume one false time basis.
## RBAC / Security Requirements
- **SEC-001**: Only existing platform users who can already access `/system` may see customer-health widgets.
- **SEC-002**: No tenant/admin-plane, customer-facing, or raw-row viewer may be introduced in this slice.
- **SEC-003**: System-safe deep links must remain guarded by existing platform-plane route policies and must not reveal tenant-admin paths or scoped data to the wrong plane.
## Auditability / Observability Requirements
- **OBS-001**: The slice must reuse existing product truths and must not duplicate audit entries or OperationRun records for derived reads.
- **OBS-002**: The source dimension set and level precedence must be testable so future changes cannot silently redefine health semantics.
## Data / Truth-Source Requirements
- **DATA-001**: Onboarding readiness must reuse existing onboarding-session and readiness truth rather than a copied health field.
- **DATA-002**: Provider connection health must reuse provider-owned verification and consent truth rather than a new platform-owned provider score.
- **DATA-003**: Operational stability must reuse existing failed and stuck `OperationRun` truth within the selected `SystemConsoleWindow`.
- **DATA-004**: Governance pressure must reuse existing findings and risk-acceptance truth.
- **DATA-005**: Review-pack readiness must reuse existing review-pack truth plus recent request context where needed.
- **DATA-006**: Engagement freshness must reuse existing `product_usage_events` truth rather than page views or ad-hoc counters.
- **DATA-007**: Archived workspaces must be excluded from active portfolio counts, and archived tenants must not contribute source truth into active workspace-health derivation.
## Review-Pack Readiness Rule
`Recent` means the currently selected dashboard window. Request context is derived from existing review-pack request telemetry when available, falling back to a `ReviewPack` created for the same workspace inside that same window.
| Condition | Review-pack readiness level | Notes |
|---|---|---|
| No request context and no relevant pack activity in the selected window | `unknown` | The first slice does not infer quarterly review obligations from silence |
| Request context exists in the selected window and no relevant pack is usable yet | `warn` | Covers queued, running, or not-yet-materialized pack generation |
| Latest relevant pack in the selected window is ready and not expired | `ok` | A usable recent pack exists |
| Latest relevant pack in the selected window is failed or expired | `critical` | Recent review-pack work ended unusably and needs attention |
## Attention Ordering Rule
The attention-needed workspace list is deterministic in v1:
1. Higher overall health severity sorts first: `critical` before `warn` before `unknown`
2. Within the same overall level, workspaces with more non-`ok` dimensions sort first
3. Remaining ties sort by workspace name ascending, then workspace id ascending
## User Scenarios & Testing *(mandatory)*
### User Story 1 - See Portfolio Health At A Glance (Priority: P1)
As a platform operator, I need the existing `/system` dashboard to summarize customer or workspace health so I can tell quickly whether attention pressure is rising.
**Why this priority**: Without an aggregate signal, operators still need to inspect several unrelated surfaces before they even know whether a health problem exists.
**Independent Test**: Seed workspaces with different combinations of healthy, warning, critical, and unknown source truth and verify that `/system` renders the correct health-level counts, explicit unknown handling, and a visible cue for windowed versus point-in-time dimensions.
**Acceptance Scenarios**:
1. **Given** multiple visible workspaces with mixed source truth, **When** an authorized platform user opens `/system`, **Then** the dashboard shows aggregate counts for `ok`, `warn`, `critical`, and `unknown` workspaces using the first-slice health rules.
2. **Given** a workspace has only stale or missing source truth for one or more dimensions, **When** the dashboard renders, **Then** that workspace is not shown as healthy by default.
3. **Given** the summary mixes operational and point-in-time signals, **When** the dashboard renders, **Then** the widget shows a visible cue that operations and engagement honor the selected window while onboarding, provider, governance, and review-readiness remain state-based.
---
### User Story 2 - Review Attention-Needed Workspaces With Explainable Reasons (Priority: P1)
As a platform operator, I need a compact list of the workspaces that need attention most so I know where to inspect next and why.
**Why this priority**: Aggregate counts alone do not reduce support load unless operators can immediately identify which workspace needs review and what category of issue is driving that state.
**Independent Test**: Seed multiple unhealthy workspaces and confirm the dashboard lists them with overall health level, dominant dimensions, and one platform-safe next link per row.
**Acceptance Scenarios**:
1. **Given** multiple warning or critical workspaces, **When** the dashboard renders, **Then** the attention-needed widget lists the worst workspaces first with overall level and dominant health dimensions.
2. **Given** a workspace row offers a next action, **When** the user activates that action, **Then** the link stays on an existing platform-plane system surface and does not deep-link into `/admin` tenant routes.
3. **Given** the operator follows a health-detail link from the dashboard, **When** the linked system tenant or workspace detail page renders, **Then** a decision-first customer-health card appears above the existing diagnostics and repeats the same dominant health drivers together with overall level, impact, and recommended next action.
---
### User Story 3 - Keep Health Honest And Narrow (Priority: P2)
As the product owner, I need the health summary to stay explainable and bounded so it does not become an opaque score, a hidden persistence layer, or a substitute for existing source truth.
**Why this priority**: A misleading or overbuilt score would add maintenance and trust debt immediately.
**Independent Test**: Inspect the derived summary rules and verify that unknown or mixed-time-basis inputs remain explicit, no new persistence appears, and no customer-facing workflow is introduced.
**Acceptance Scenarios**:
1. **Given** the first-slice dimension rules are evaluated, **When** one dimension is `critical` and another is `unknown`, **Then** the overall workspace level resolves deterministically and the dominant reasons remain explainable.
2. **Given** recent review-pack generation was requested but no usable pack is yet available, **When** the review-readiness dimension is evaluated, **Then** the workspace is not falsely shown as healthy.
3. **Given** a user without existing `/system` access attempts to read customer health, **When** they hit the surface, **Then** access stays denied through the existing platform-plane gate.
### Edge Cases
- Archived workspaces or tenants must not inflate active health counts.
- A workspace can have healthy current provider state but no recent engagement telemetry; the slice must make the time basis explicit instead of collapsing that into a misleading single timestamp.
- A recent review-pack request can exist before a ready pack exists; that gap must not render as healthy.
- A workspace with no onboarding-linked tenant yet must remain `unknown` or explicitly non-healthy rather than silently `ok`.
- Mixed workspace truth across several tenants must still produce one explainable workspace-level result without exposing raw tenant-owned rows on the dashboard.
## Acceptance Criteria
- The first slice derives workspace health from six fixed dimensions only and keeps all health truth derived from existing records.
- The existing `/system` dashboard exposes both aggregate health counts and an attention-needed workspace list.
- Operators can see dominant reasons for unhealthy workspaces without opening a second system page first.
- Unknown or stale source truth is explicit and never silently treated as healthy.
- The slice introduces no new persisted health entity, no customer-facing view, and no new platform-to-admin deep link.
## Out Of Scope
- Customer-facing health portals
- Billing or entitlement-aware health dimensions
- Automated customer lifecycle messaging
- Predictive scoring, churn scoring, or AI-generated recommendations
- A dedicated portfolio-health page outside the existing `/system` dashboard
- A new persisted workspace-health model or scheduled recomputation job
## Success Criteria
- A platform operator can identify whether any workspace needs attention, and which workspace to inspect first, within one `/system` dashboard visit.
- The first slice remains explainable enough that each visible non-healthy state can be tied back to one or two named dimensions.
- The package stays implementation-ready without introducing unresolved product decisions around billing, CRM, AI, or customer-facing UX.
## Assumptions
- Product Usage & Adoption Telemetry is available or implemented before this slice is delivered.
- Existing system dashboard access rules remain the correct audience gate for the first slice.
- Existing provider-connection, finding, review-pack, and run surfaces remain the source-of-truth owners for detailed inspection.
## Risks
- Too many first-slice dimensions would make the dashboard noisy; the dimension inventory is fixed at six for v1.
- Mixed point-in-time and windowed signals can confuse operators if the UI does not label them carefully.
- Review-pack readiness could drift into a broader compliance-workflow interpretation if it is not kept narrow.
## Open Questions
- None blocking the first slice. The v1 contract guarantees one platform-safe next link per workspace row by falling back to the existing system tenant-detail context when a more specific platform-plane route is not appropriate.
## Requirements *(mandatory)*
**Constitution alignment (required):** The slice adds no Microsoft Graph calls, no mutation flow, and no new queued or scheduled work. It derives read-only health summaries from existing onboarding, provider, telemetry, findings, review-pack, and `OperationRun` truth only.
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The feature introduces no new persistence and reuses existing health-level semantics. The only new structure is one bounded derived-query path plus a fixed dimension catalog because current-release operator workflow now needs a single explainable workspace-health summary.
**Constitution alignment (XCUT-001):** This slice explicitly extends the shared system dashboard widget family, system-safe links, and shared `SystemHealth` presentation instead of inventing a second health dashboard language.
**Constitution alignment (PROV-001):** Provider-specific verification and consent semantics remain provider-owned inputs only; the top-level customer-health summary stays platform-owned and neutral.
**Constitution alignment (TEST-GOV-001):** Proof stays in Unit + Feature lanes only. No heavy-governance or browser family is justified.
**Constitution alignment (OPS-UX):** Existing `OperationRun` start, completion, notification, and link semantics remain unchanged. The slice reads existing run truth and may link to existing system operations surfaces only.
**Constitution alignment (RBAC-UX):** Reads remain platform-plane only through existing `/system` access checks. No tenant/admin or customer-facing health viewer is introduced.
**Constitution alignment (BADGE-001):** The feature reuses existing `BadgeDomain::SystemHealth` rendering and does not add a new badge taxonomy.
**Constitution alignment (UI-FIL-001):** The only operator-facing changes are native Filament system widgets on the existing dashboard. No published views, panel provider changes, or custom asset pipeline changes are introduced.
**Constitution alignment (UI-NAMING-001):** Widget labels and dominant health reasons must remain operator-first and platform-neutral, such as `Customer health`, `Attention-needed workspaces`, `Provider health`, `Operational stability`, and `Engagement freshness`.
**Filament v5 / Livewire v4 compliance:** The slice remains fully inside the current Filament v5 + Livewire v4 stack.
**Provider registration location:** No provider registration changes are introduced; Laravel 11+ provider registration remains in `bootstrap/providers.php`.
**Global search rule:** No new resource or global-search participation is introduced.
**Destructive actions:** No destructive actions are added in this slice.
**Asset strategy:** No new global or on-demand assets are added. Deployment behavior for `filament:assets` remains unchanged.