TenantAtlas/docs/ui/tenantpilot-enterprise-ui-standards.md
ahmido b2ec2f032f 272: OperationRun phase composite progress (#330)
Bring feature work for OperationRun phase composite progress into `platform-dev`. This PR contains the merged session commits and spec artifacts.

Notes:
- Session branch was merged into `272-operationrun-phase-composite-progress` locally and pushed.
- Please review specs and tests under `specs/272-operationrun-phase-composite-progress/`.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #330
2026-05-05 12:54:38 +00:00

32 KiB
Raw Blame History

TenantPilot Enterprise UI StandardsStatus: Active Owner: Product / Engineering Applies to: TenantPilot custom Filament UI surfaces Last reviewed: 2026-05-03 ---## 1. Purpose and ScopeThis document defines the mandatory UI standards for TenantPilot custom UI surfaces that are not fully covered by native Filament components.TenantPilot is an enterprise SaaS platform for Microsoft Tenant Governance, Evidence, Tenant Reviews, Drift Detection, Baselines, Provider Health, Supportability, and MSP-/Customer-Governance workflows.The UI goal is:- Governance-of-Record- decision-first UX- Filament-native enterprise SaaS look- calm operational surfaces- clear action hierarchy- no false affordances- no fake routes- no fake data- no fake customer-safe maturityThis document applies to:- dashboards- custom cards- page headers- context chips- KPI rows- status cards- aside cards- action rows- governance summaries- evidence and review surfaces- provider health surfaces- supportability surfaces- customer-safe read-only surfaces- empty states- progress/readiness blocks- custom table/list enhancements- custom form/detail layoutsNative Filament components MUST be used first. Custom UI is allowed only when native Filament patterns are insufficient for the product need.---## 2. Non-Negotiable PrinciplesTenantPilot custom UI MUST follow these principles:1. **Decision-first, diagnostics-second, evidence-third.**2. **Filament-native first.**3. **Exactly one visually dominant Primary Action per page.**4. **Status colors belong to badges, labels and chips — not to buttons.**5. **Hover implies interactivity.**6. **Interactive affordance requires a repo-real route/action and permitted capability.**7. **No fake data, fake progress, fake routes or fake customer maturity.**8. **Blade renders. Builders/ViewModels/Presenters decide.**9. **Customer-safe surfaces MUST NOT expose raw technical details by default.**10. **Custom UI MUST use documented patterns, not ad-hoc styles.**Custom UI MUST NOT introduce one-off styling for cards, hovers, buttons, badges, icons, progressbars, empty states or interactive rows.---## 3. Surface TaxonomyTenantPilot uses the following UI surface types.| Surface | Purpose | Example ||---|---|---|| Page Header | Context and primary action | Tenant Dashboard title + Findings prüfen || Context Bar / Context Chips | Lightweight environment context | Workspace, Provider, Latest activity || KPI Row | High-level measurable status | Findings, Operations, Permissions || Decision Card | Recommended next action | Findings prüfen || Status Card | Current posture/readiness | Governance Status || Aside Card | Compact secondary context | Provider Health || Interactive Row | Clickable status or operation row | Governance row with actionUrl || Static Row | Read-only status line | Governance row without actionUrl || Empty State | Honest unavailable state | Kein aktives Review || Progress Block | Real measured progress | 2/3 Findings with outcome || Technical Details | Progressive disclosure only | Logs, JSON, raw payload || Inline Alert | Short contextual warning/info | Missing permissions warning || Table/List Row | Structured list item | Operation runs, findings, reviews || Form Section | Grouped form inputs | Settings section || Detail Section | Read-only structured information | Review metadata |A surface MUST use the matching pattern from this document. Do not treat all surfaces as generic cards.---## 4. Filament-native FirstNative Filament components SHOULD be used whenever possible.Preferred native patterns include:- Filament Pages- Filament Widgets- Filament Stats Overview- Filament Tables- Filament Actions- Filament Badges- Filament Sections- Filament Forms- Filament Infolists- Filament Modals / Slide-overs where appropriateCustom Blade markup MAY be used when:- the desired product surface is not well represented by a native Filament component- a composed dashboard/card pattern is needed- a read-only productized summary is needed- the UI must combine several domain signals into one decision-first surfaceCustom Blade markup MUST still follow this document.---## 5. Page Header PatternThe page header establishes context and action hierarchy.A Page Header SHOULD contain:- title- optional subtitle- optional status pill- exactly one primary action, if a primary action exists- secondary actions grouped or visually de-emphasizedRules:- The Page Header MUST NOT contain a button flood.- The Page Header MUST NOT expose diagnostics as primary actions.- The Page Header MUST NOT show multiple equal-weight primary buttons.- The primary action MUST represent the most important next operator action.- Secondary actions SHOULD be gray/neutral or grouped behind a menu.Example:| Page | Primary Action | Secondary Actions ||---|---|---|| Tenant Dashboard | Findings prüfen | Support anfragen, Support-Diagnostik öffnen || Review Detail | Review fortsetzen / Publish | Export, Evidence anzeigen || Provider Health | Berechtigungen öffnen | Refresh, Details |---## 6. Card and Surface PatternCustom cards MUST use a quiet Filament-like surface.Recommended base:```html
...

Allowed:

bg-white

border border-gray-200

rounded-xl or rounded-2xl

compact, consistent padding

subtle shadow-sm only when the card represents a distinct elevated surface

Not allowed:

hard black borders

dark rings as default card borders

large colored status backgrounds

heavy shadows

unique one-off card treatments per feature

mixing different hover models in equivalent surfaces

Equivalent surface families MUST share the same hover and border model. For example: Interactive card row = border + hover:shadow-smStatic card row = border + no hover Do not mix: Governance rows = hover:bg-gray-50Recent operations = hover:shadow-sm unless there is a documented product reason.

  1. Interactive Row Pattern Hover is an affordance. A row MAY only have hover, pointer, focus or shadow interaction when it is actually interactive. 7.1 Interactive Row Allowed only when all of the following are true:

a repo-real route or action exists

the current user has the required capability/policy

the target is tenant/workspace scoped correctly

the interaction is useful in the product flow

Pattern:

render as if it navigates

render as if it performs an action

use cursor-pointer

use hover:shadow-sm

use focus-visible:ring

include stable data-testid

Interactive rows SHOULD use: border border-gray-200 bg-white hover:shadow-sm focus-visible:ring 7.2 Static Row When no route/capability exists:

render as static container

no hover state

no cursor pointer

no focus state

no fake action

no fake route

Static rows MUST NOT look clickable. 7.3 Anti-patterns Do not introduce:

div with hover but no click target

cursor-pointer without route/action

row looks clickable but only text is shown

fake target route added just to satisfy UI

hover background on static status rows

  1. Button and Action Hierarchy TenantPilot uses a strict action hierarchy. 8.1 Page Primary Action Each page MAY have at most one visually dominant primary action. Allowed:

primary color

filled button

page header placement

clear action label

Example: Tenant Dashboard: Findings prüfen 8.2 Secondary Actions All card, aside, row and support actions are secondary unless explicitly defined otherwise. Examples:

Review fortsetzen

Risiken prüfen

Erforderliche Berechtigungen öffnen

Export-Artefakte anzeigen

Backup-Status öffnen

Überfällige Findings öffnen

Required style:

gray/secondary/neutral

no status color

consistent height

consistent radius

consistent typography

consistent padding

8.3 Status Colors and Buttons Status colors MUST NOT be used as button colors. Status is represented through:

badge

chip

label

description text

Buttons communicate action hierarchy, not status. Bad: Failed = red buttonHealthy = green buttonWarning = yellow button Good: Failed = danger badge + gray action buttonHealthy = success badge + gray action buttonWarning = warning badge + gray action button

  1. Badge and Status Pattern Badges communicate state. Recommended mapping: MeaningBadge ToneReady / Healthy / Published / CompletesuccessWarning / Stale / Attention / Overdue soonwarningFailed / Error / BlockeddangerUnknown / Unavailable / Not configuredgray Rules:

badges MUST be small and quiet

status text MUST remain visible

color alone MUST NOT be the only status signal

badges MUST NOT become large colored panels

badges SHOULD NOT be duplicated by additional status icons unless needed for accessibility

buttons MUST NOT inherit badge/status colors

Example: Provider Health [Healthy] 0 missing permissions

  1. Icon Pattern Icons improve scanability. They do not replace labels or badges. Rules:

use Heroicons / Filament-native icons

size SHOULD be 16px / h-4 w-4

color SHOULD be neutral gray

exactly one semantic icon per row/action when used

icon describes type, not status

outcome/status remains in badges

no colorful icon bubbles

no decorative illustrations in operational surfaces

no large circle containers around standard operational icons

Recommended icon mapping: ConceptIconBaseline Compareheroicon-m-scaleEvidence Coverageheroicon-m-document-checkReviewheroicon-m-clipboard-document-checkProvider Permissionsheroicon-m-keyBackup / Recoveryheroicon-m-arrow-path-rounded-squareInventory Syncheroicon-m-arrow-pathReview Packheroicon-m-document-arrow-downReview Compositionheroicon-m-document-textEvidence Snapshotheroicon-m-document-duplicateProvider Healthheroicon-m-shield-checkPermission Postureheroicon-m-keyFindings / Attentionheroicon-m-shield-exclamationOverdue / Timeheroicon-m-clock Principle: Icon = TypeBadge = StatusButton = Action

  1. Progress Bar Pattern Progress bars are only allowed when real numerator/denominator or percent values exist. Allowed examples:

findings reviewed / total findings

findings with outcome / total findings

completed sections / total sections

evidence attached % only if real numerator/denominator exists

review completion % only if real section/status data exists

Not allowed:

fake percentages

static demo arrays

inferred readiness without real denominator

progress bars for Provider Health unless real progress data exists

progress bars for Risk Exceptions unless real progress data exists

Required:

visible text value remains present

role="progressbar"

aria-valuenow

aria-valuemin="0"

aria-valuemax="100"

percentage must be derived from repo-real values

Visual pattern:

full width

68px height

rounded-full

gray track

quiet primary/success/warning fill

no animation by default

Recommended markup shape:

Findings with outcome 2/3 (67%)
For custom progress bars, fixed inline height MAY be used when Tailwind height utilities are not reliably present in the loaded Filament theme.
  1. Context Chip Pattern Context chips provide lightweight environment context. Examples:

Workspace

Provider / Tenant type

Latest activity

Billing state

Scope

Rules:

chips SHOULD appear below the page header and above the KPI row

chips are not primary actions

chips MUST NOT collapse to 0px

long values SHOULD truncate

mobile MAY wrap

desktop SHOULD remain horizontal where possible

no fake provider labels

provider labels MUST be repo-real or neutral fallback

Allowed provider fallback: Provider-VerbindungProvider connection Do not invent: Microsoft Graph unless the repo-real provider identity supports it.

  1. Dashboard Main / Aside Pattern TenantPilot dashboards use a decision-first main/aside layout. Desktop:

Main content: col-span-8

Aside: col-span-4

Mobile:

stacked layout

Main content SHOULD contain:

recommended actions

governance status

primary decision surfaces

recent operational context where appropriate

Aside SHOULD contain:

current review

risk exceptions

provider health

customer-safe output

readiness context

Rules:

aside cards are compact

no long tables in aside

no raw logs/json in aside

each aside card has at most one action

actions inside aside cards are secondary/gray

aside cards must not imply unavailable product maturity

  1. Empty State Pattern Empty states must be honest and action-aware. Every empty state SHOULD include:

clear title

short explanation

optional next action only if repo-real route and capability exist

Good: Kein aktives ReviewFür diesen Tenant ist aktuell kein Review in Bearbeitung. Good: Keine kundensichere Ausgabe verfügbarErzeuge ein Review-Paket, sobald Evidence und Review bereit sind. Bad: Kunden-Workspace öffnen when no customer-safe workspace is repo-verified. Rules:

no fake CTA

no implied product maturity

no placeholder/demo content

no customer-safe claim without repo verification

no action without route and capability

  1. Loading, Stale and Error States 15.1 Loading Loading states SHOULD use:

skeleton

quiet placeholder

short loading text when needed

Avoid:

spinner spam

layout shifting

blocking entire dashboard unless necessary

15.2 Stale Stale states SHOULD show:

badge or label

reason if available

last refreshed/checked timestamp when repo-real

Stale states MUST NOT use alarming surfaces unless operator action is required. 15.3 Error Error states SHOULD show:

reason

impact

next action if available

Technical details MUST remain behind progressive disclosure. Never default to:

raw exception

JSON payload

stack trace

logs

raw API response

  1. Table and List Pattern Tables should remain Filament-native unless there is a strong product reason. Rules:

row hover only if row click is enabled

otherwise use explicit row action

status columns use badges

raw IDs hidden by default

technical columns behind toggle or detail view

destructive actions are never primary

no button flood in each row

no raw technical fields as default operator experience

TenantPilot tables SHOULD support decision-first scanning:

status

reason

impact

owner/scope

next action

details only on demand

Anti-pattern: Operator must inspect raw IDs, payloads and logs to understand what matters.

  1. Form and Detail Page Pattern 17.1 Forms Forms SHOULD:

group fields into sections

use clear section titles

keep primary save/submit action consistent

separate destructive actions

hide advanced/technical fields behind collapsible sections where appropriate

Forms MUST NOT:

expose raw internal fields as primary inputs unless needed

mix destructive and primary actions at equal visual weight

rely on placeholder text as the only explanation

17.2 Detail Pages Detail pages SHOULD:

be read-first

show status/reason/impact before technical details

use progressive disclosure for diagnostics

avoid looking like edit forms when read-only

Technical details SHOULD be grouped under: Technical DetailsDiagnosticsRaw Details and collapsed or secondary by default.

  1. Customer-safe Surface Rules Customer-safe surfaces must be read-only, calm and evidence-first. Rules:

no raw technical logs by default

no internal operation noise by default

no admin-only actions

no unsupported maturity claims

no Open customer workspace unless Customer Review Workspace is repo-verified

use Export-Artefakte anzeigen or Review-Paket öffnen when only artifacts/packs exist

customer-safe copy must be especially precise

customer-safe output must distinguish between:

Review Pack

Evidence Snapshot

Export Artifact

Customer Workspace

Do not label the whole customer-safe output as failed if only the latest export/review-pack generation failed. Prefer precise copy: Review-Paket fehlgeschlagenExport fehlgeschlagenKeine kundensichere Ausgabe verfügbar

  1. Component Ownership Rules Business logic belongs in:

SummaryBuilder

ViewModel

Presenter

Link service

Policy/capability layer

domain service

Blade may:

render fields

branch on explicit view model flags

render provided URLs/icons/badges/progress values

Blade MUST NOT:

invent routes

infer capabilities

calculate business status

hardcode provider maturity

calculate fake progress

infer customer-safe maturity

parse raw payloads for product decisions

duplicate business logic from services/builders

Preferred flow: Domain model/service→ SummaryBuilder/ViewModel/Presenter→ Blade render Not allowed: Blade template→ queries database→ invents status→ decides capability→ renders action

  1. Localization Rules Visible UI copy MUST use localization keys. Rules:

no new hardcoded user-facing copy in Blade

DE/EN mixture is accepted only as explicit Localization v1 debt

customer-facing copy must be especially careful

labels must not overclaim product maturity

status labels should use shared badge/status language where possible

Until Localization v1 is complete:

mixed language may exist in operator-only surfaces

new copy should still be added through localization files

PR/close-out notes SHOULD mention known localization debt when relevant

  1. Accessibility and Keyboard Rules Custom interactive UI MUST be accessible. Rules:

clickable navigation uses

actions use

or Filament Action components

do not use clickable div without semantics

focus-visible style required for custom interactive elements

icon-only buttons require accessible label

color alone must not communicate status

progress bars require ARIA attributes

keyboard navigation must not be broken

Required for progress bars: role="progressbar"aria-valuenow="..."aria-valuemin="0"aria-valuemax="100" Required for icon-only actions: aria-label="..." or visible text.

  1. Responsive, Truncation and Overflow Rules Custom UI MUST remain stable on desktop and mobile. Rules:

desktop dashboards may use main/aside grid

mobile stacks main and aside

chips may wrap on mobile

chips must not overlap

long names must truncate

no 0px grid columns

no horizontal scroll leaks

cards must not collapse due to long tenant/workspace/provider names

actions must remain visible and usable on mobile

Recommended: truncate long labelsuse minmax() carefullytest actual browser widthavoid fixed widths unless intentional Every dashboard-like custom surface SHOULD be checked in:

desktop viewport

narrow/mobile viewport

long tenant/workspace name scenario where practical

  1. Data Freshness Rules Governance, Evidence, Review and Provider statements SHOULD show freshness when repo-real freshness exists. Examples:

Last checked 20 minutes ago

Last snapshot 2 days ago

Latest activity 5 minutes ago

Likely stale

No recent signal

Rules:

stale data must not be presented as fresh

stale state should be quiet unless action is required

freshness belongs in badge/description/context, not aggressive layout

no fake timestamps

no generic “synced recently” without a real timestamp

  1. Raw Technical Details and Progressive Disclosure TenantPilot is not a raw admin mirror. Default surfaces MUST NOT show:

raw JSON

raw logs

stack traces

internal IDs

raw API payloads

technical exception details

provider-specific debug output

These MAY be available under:

Technical Details

Diagnostics

Raw Payload

Operation Log

Developer / Support view

Decision-first default: StatusReasonImpactNext Action Then: EvidenceDiagnosticsRaw Details

  1. Data-testid and Browser-Smoke Rules Custom UI surfaces SHOULD use stable data-testid attributes. Rules:

test product concepts, not styling implementation

avoid fragile assertions on Tailwind class order

avoid assertions on SVG attribute order

use browser smoke for layout-critical surfaces

use feature tests for capability/action visibility

use markup tests for stable structural contracts

do not assert exact class ordering unless explicitly testing a UI contract

Examples: tenant-dashboard-governance-statustenant-dashboard-secondary-actiontenant-dashboard-current-review-progresstenant-dashboard-context-chipstenant-dashboard-recommended-actiontenant-dashboard-recent-operation Browser-smoke SHOULD verify:

page loads

key sections render

critical layout does not collapse

important actions are visible/hidden correctly

no false interactive affordance where known

Browser-smoke SHOULD NOT rely on:

theme CSS being loaded in unit-test-only contexts

exact Tailwind class order

fragile screenshot pixel matching unless explicitly required

  1. UI Review Checklist Before merging custom UI changes:

Filament-native component was used where possible.

Custom styling follows this standard.

Exactly one visually dominant Primary Action exists on the page.

Card actions are secondary/gray.

Status colors are only used in badges/chips/labels.

Hover exists only on interactive elements.

Every interactive element has a repo-real route/action.

Capabilities/policies are respected.

Tenant/workspace scope is respected.

No fake routes were introduced.

No fake actions were introduced.

No fake progress or demo values were introduced.

Empty states are honest.

Customer-safe maturity is not overclaimed.

Raw JSON/logs are not shown by default.

Icons are small, neutral and semantic.

Progressbars include accessible attributes.

Mobile layout does not overlap or collapse.

Long labels truncate or wrap safely.

Browser smoke was run or explicitly documented as not run.

New visible copy uses localization keys.

Blade does not invent domain logic, routes, capabilities or maturity.

  1. Anti-Patterns Do not introduce:

hover without clickability

cursor-pointer without route/action

primary buttons inside cards

status-colored buttons

fake customer workspace actions

fake provider names

fake progress bars

static demo chart arrays

raw JSON/logs as default

technical table sprawl

new top-level page for every technical state

custom one-off card styles

mixed hover models in the same surface family

icon-only status without text

large colored status panels

decorative icon bubbles in operational UI

route guessing in Blade

capability guessing in Blade

customer-safe maturity overclaims

provider-specific hardcoding in platform core unless repo-real and scoped

destructive actions with primary visual weight

button floods in page headers or table rows

  1. Pattern Decision Matrix Use this matrix when choosing a pattern. NeedUseDo Not UseShow statusBadge / chip / labelButton colorShow actionButton / link / Filament ActionBadgeShow typeSmall neutral iconColored status iconShow progressProgress bar with real denominatorFake percentShow unavailable stateEmpty stateDisabled fake CTANavigate row row with hover/focusdiv hoverStatic informationStatic row/cardHover rowShow detailsProgressive disclosureRaw details by defaultCustomer outputReview Pack / Export Artifact wordingCustomer Workspace wording unless repo-real

  2. TenantPilot-specific Product Guardrails TenantPilot MUST avoid drifting into:

generic M365 admin mirror

helpdesk tool

raw device-action tool

debug surface collection

log viewer as primary UX

feature-per-page sprawl

TenantPilot SHOULD reinforce:

Governance-of-Record

OperationRun truth

Evidence-first reporting

capability-first RBAC

workspace-first multi-tenancy

customer-safe review consumption

decision-first surfaces

provider-extensible architecture

UI copy and actions MUST NOT claim a product capability is mature unless repo-verified. Examples: CapabilityAllowed CopyAvoidReview Pack existsReview-Paket öffnenKunden-Workspace öffnenExport artifact existsExport-Artefakte anzeigenCustomer Portal öffnenEvidence existsNachweise anzeigenAudit abgeschlossenProvider permissions missingBerechtigungen öffnenFix automaticallyCustomer Review Workspace not implementedKundensichere Ausgabe nicht verfügbarOpen customer workspace

29.1 OperationRun Activity Feedback Pattern The tenant-shell OperationRun activity hint is a bounded start-surface hint, not a second monitoring page.

It MUST:

derive rows from existing OperationRun truth only

show queued or running rows plus only the bounded terminal states that complete the same-shell feedback loop:

  • just-completed successful runs that remain visible briefly
  • unresolved terminal follow-up runs that were blocked, partial, failed, or automatically reconciled

render inside the TenantPilot application shell, directly below the topbar/context bar or inside the main content shell as a compact in-flow banner

stay in-flow and non-obstructive instead of floating over row actions or page CTAs

show at most three items in the shell

keep the visible shell order deterministic by using the existing shell ordering contract:

  • active queued or running rows first
  • unresolved terminal follow-up rows next
  • recent terminal success rows only as the bounded close-the-loop state

use one grouped banner action area with a dominant action that reflects whether the banner is about one operation or multiple operation updates:

  • when exactly one visible operation update is shown, use View operation to open that run detail
  • when multiple visible operation updates are shown, use Review operations to open the canonical Operations collection instead of any single run detail

use Active operations as the header label only when all visible rows are active queued or running work. If any visible row is terminal, switch the header label to Operation updates.

keep a secondary action labeled Show all operations and one lifecycle-sensitive tertiary affordance for the current browser session:

  • Hide activity for queued or running rows
  • Dismiss or Close for terminal-success rows
  • Dismiss for a single unresolved terminal follow-up row
  • Dismiss updates when multiple unresolved terminal follow-up rows are visible and no active work remains

use Show all operations to open the canonical Operations collection with the current tenant encoded as the contextual tenant_id prefilter

keep overflow copy collective and calm, for example 19 more operation updates available in Operations.

show at most one concise next-step cue per item and leave diagnostics, logs, raw payloads, and failure detail to the canonical Operations pages

show determinate progress only when summary_counts.total and summary_counts.processed are real numeric values, clamp the progressbar to 0-100, and only show processed or percentage text when it is derived from those repo-real values

derive progress treatment from one shared OperationRun progress contract instead of local Blade or widget math

allow counted progress only for current run families that persist truthful summary_counts.total plus summary_counts.processed during execution:

  • inventory sync
  • review-pack generation
  • evidence-snapshot generation
  • backup-set policy additions
  • backup-set bulk restore

keep all other run families on activity-only, phased, or composite treatment until they persist equally trustworthy progress truth through the shared contract

limit the current non-counted phase or composite contract to these run families only:

  • baseline_capture
  • baseline_compare
  • tenant.review.compose

keep queued rows activity-only even when a planned total exists

keep running rows without trustworthy processed and total counts activity-only or indeterminate

keep summary_counts.succeeded, summary_counts.failed, and summary_counts.skipped outcome-only; they must not silently replace processed as progress truth

for baseline_capture and baseline_compare, use canonical progress.phase metadata with short operator-safe, non-technical labels such as Preparing baseline capture., Capturing evidence., Refreshing comparison evidence., Evaluating baseline drift., Saving baseline snapshot., and Finalizing baseline comparison.

for tenant.review.compose, use canonical progress.composite metadata only for bounded aggregate status copy such as Review composition is aggregating 3 operations.; this remains composite indeterminate copy, not counted progress, even when operation_count is visible

when canonical phase or composite metadata is absent or malformed, degrade safely to the existing generic phased or composite fallback instead of inventing percentages, strategy detail, provider detail, or raw technical diagnostics in the shell

switch terminal-success rows to success-state copy instead of showing active progress after completion

record these as follow-up work instead of widening the current contract:

  • provider health or support-diagnostics progress rollout
  • review-pack or evidence-snapshot overlap with other progress specs
  • child-run graph persistence or composite child-link expansion
  • dashboard cards or workflow-engine generated progress explanations

keep hide or dismiss behavior browser-session-only and re-open the hint when a new run-enqueued event is accepted for the current tenant

It MUST NOT:

render as a detached document-level BODY_START banner above the TenantPilot application chrome

turn the shell hint into a permanent terminal inbox, tray, or second monitoring page

use raw route strings or non-canonical OperationRun links

show fake percentages, guessed completion, or fake progress

let outcome counters, aggregate operation counts, or phase hints masquerade as counted progress

show active progress UI after a run is already terminal

persist hide or dismiss state in the database or on the OperationRun record

render as a fixed overlay that can cover findings row actions, table actions, or page-primary actions

  1. Maintenance Rules This document is a living standard. Changes to this document SHOULD happen when:

a repeated UI decision appears in multiple specs

a new custom pattern is introduced

a drift issue is found during browser smoke

a Filament-native alternative becomes available

Localization v1 changes copy rules

Customer Review Workspace v1 changes customer-safe surface rules

Feature specs SHOULD NOT override this document casually. Any intentional exception SHOULD document:

affected surface

reason for exception

expected duration

follow-up cleanup if needed

  1. Minimal Constitution Reference The project constitution SHOULD reference this document with a short rule, not duplicate the full standard. Recommended constitution text:

Custom Filament UITenantPilot custom Filament UI MUST follow docs/ui/tenantpilot-enterprise-ui-standards.md.Feature specs MUST NOT introduce ad-hoc card, hover, button, badge, icon, progressbar, empty-state or interactive-row styling.Interactive affordance MUST only be used when a repo-real route/action and permitted capability exist.Status colors MUST be represented through badges, chips or labels, not through action buttons.Customer-safe maturity MUST NOT be implied by copy, routes or actions unless repo-verified.

  1. Spec / PR Close-out Reference Visible custom UI changes SHOULD include a short close-out note. Recommended format:

UI Standards CheckChanged custom UI surfaces:- ...Patterns used:- Card / Surface- Interactive Row- Secondary Action- Progress Bar- Empty StateConfirmed:- [ ] Filament-native used where possible- [ ] No ad-hoc styling- [ ] No fake data/routes/progress- [ ] Capabilities respected- [ ] Browser smoke run- [ ] Localization debt documented if applicable

  1. Quick Reference Buttons Page primary action = primary filledCard action = gray/secondaryAside action = gray/secondaryStatus = badge, not button color Rows Interactive row = route + capability + hover/focusStatic row = no hover, no pointer Icons SmallNeutralOne per row/actionType, not status Progress Only real numerator/denominator/percentText value remains visibleARIA requiredNo fake progress Customer-safe Do not imply Customer Review Workspace maturity unless repo-verifiedUse Review Pack / Export Artifact wording when that is what exists Blade Render onlyDo not invent domain logicDo not invent routesDo not infer capabilities