# Feature Specification: Unified Badge System (Single Source of Truth) v1 **Feature Branch**: `059-unified-badges` **Created**: 2026-01-22 **Status**: Draft **Input**: Suite-wide badge/chip standardization so the same underlying value always renders with the same meaning (label + color + optional icon) across tables, dashboards/KPIs, and detail views; tenant-safe and DB-only at render time where required. ## Clarifications ### Session 2026-01-22 - Q: What is the v1 migration coverage target? → A: Status-like badges suite-wide; tag/category chips later. - Q: What counts as “status-like” for v1 scope? → A: Status/health plus severity/risk signals. - Q: Should v1 introduce any new severity levels (e.g., “critical”), or standardize the existing severity values only? → A: Standardize existing severity values only (no new levels in v1). - Q: Should v1 include an automated “no ad-hoc badge semantics” guard beyond mapping tests? → A: Yes — tests plus a lightweight automated guard that flags ad-hoc mappings. - Q: What is the canonical meaning for drift finding severity (low | medium | high) in v1? → A: low = neutral, medium = warning, high = danger. ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Trustworthy status badges everywhere (Priority: P1) As a tenant admin, I can trust that status/health and severity/risk badges mean the same thing everywhere in the admin panel, so I can scan lists quickly and make the right decision. **Why this priority**: Inconsistent badge semantics create operational mistakes (false “success”, missed failures) and erode trust in the UI. **Independent Test**: View a representative set of pages that contain status/health and severity/risk badges (lists + detail views) and confirm the same underlying value always uses the same label and visual meaning across pages. **Acceptance Scenarios**: 1. **Given** a run is in the “queued” state, **When** I view it in any table, dashboard list, or detail view, **Then** it is clearly shown as “Queued” with a consistent visual meaning that indicates “waiting to start”. 2. **Given** a run is in the “running” state, **When** I view it in any table, dashboard list, or detail view, **Then** it is clearly shown as “Running” with a consistent visual meaning that indicates “in progress”. 3. **Given** a run is in a successful terminal state (“succeeded” / “completed”), **When** I view it anywhere, **Then** it is shown with a consistent “success” meaning and is never shown using warning/attention colors. 4. **Given** a finding has a high-severity value, **When** I view it in any table, dashboard list, or detail view, **Then** it is shown with a consistent “high severity” meaning and is never shown as a neutral or low-attention meaning. --- ### User Story 2 - Readable status badges in dark mode (Priority: P2) As a tenant admin, I can scan status badges in both light and dark mode without readability regressions. **Why this priority**: Badges are a high-density UI element; readability and correct “good/bad” signaling reduce cognitive load and prevent mistakes. **Independent Test**: Open key list pages and dashboards in dark mode and light mode and verify status badges remain readable without relying on fragile per-page styling overrides. **Acceptance Scenarios**: 1. **Given** I use dark mode, **When** I view status-like badges on common pages, **Then** badge text and any icons remain readable and do not rely on fragile per-page styling overrides. 2. **Given** a status badge includes an icon in a dense list, **When** I view it, **Then** the icon appearance matches the badge meaning and does not appear disabled unless the status is intentionally neutral. --- ### User Story 3 - Consistency stays enforced over time (Priority: P3) As a maintainer, I can update badge semantics in one place and have the change apply everywhere, and regressions are caught before release. **Why this priority**: Without enforcement, ad-hoc badge mappings quickly reappear and the UI drifts back into inconsistent meanings. **Independent Test**: Make a small change to a centralized badge definition and confirm it affects multiple UI surfaces; introduce a deliberately inconsistent mapping and confirm automated validation fails. **Acceptance Scenarios**: 1. **Given** a new status value is introduced, **When** it is not yet defined in the central badge system, **Then** it displays with a safe “unknown” meaning rather than being misrepresented as success or warning. 2. **Given** a developer attempts to reintroduce an ad-hoc badge mapping, **When** automated validation runs, **Then** it is detected and fails until the centralized definition is used. --- [Add more user stories as needed, each with an assigned priority] ### Edge Cases - A record has an unrecognized/legacy status value (null/empty/unknown string). - A record has an unrecognized/legacy severity/risk value. - The same status appears on multiple pages (list + detail) and must remain consistent. - A status value exists across multiple “domains” (e.g., “completed” used in different workflows) and must not be conflated if meanings differ. - Dark mode and high-contrast settings reduce readability of badge text or icons. - A page that must remain read-only/DB-only accidentally introduces side effects during render (for example, remote calls or background work). - Tenant switching occurs mid-session and badges must not leak cross-tenant data. ## Requirements *(mandatory)* **Constitution alignment (required):** If this feature introduces any Microsoft Graph calls, any write/change behavior, or any long-running/queued/scheduled work, the spec MUST describe contract registry updates, safety gates (preview/confirmation/audit), tenant isolation, run observability (`OperationRun` type/identity/visibility), and tests. If security-relevant DB-only actions intentionally skip `OperationRun`, the spec MUST describe `AuditLog` entries. ### Functional Requirements - **FR-001**: The system MUST define badge semantics centrally for each status badge “domain” used in the admin UI, including: label, color meaning, and (when applicable) an icon. - **FR-002**: The system MUST apply the centralized status badge semantics consistently across all status badge surfaces (tables, dashboards/KPIs, and detail views) so the same underlying value always renders with the same meaning. - **FR-003**: The system MUST clearly distinguish “status-like” badges (status/health and severity/risk signals) from tag/category chips so scope boundaries are unambiguous; v1 MUST standardize status-like badges suite-wide. - **FR-004**: The system MUST standardize the canonical meanings for run-like statuses at minimum: queued, running, succeeded/completed, partial, failed. - **FR-005**: Warning/attention colors (e.g., orange/yellow) MUST be reserved for “queued / needs attention / partial / in progress” meanings and MUST NOT represent success/completed outcomes. - **FR-006**: Badge rendering MUST remain tenant-safe: it must not display cross-tenant data and must rely only on data already available in the current tenant context. - **FR-007**: For designated DB-only pages (for example, Monitoring/Operations views), badge rendering MUST NOT trigger outbound network requests, background jobs, or other side effects during render or during automatic refresh/polling. - **FR-008**: Badge rendering MUST be performant and predictable: it must not require additional data lookups at view time and must not introduce noticeable delays on high-row-count tables. - **FR-009**: In dense tables, badges MAY include icons for scanability; when icons are shown, they MUST not appear disabled/gray unless the badge itself is intentionally neutral. - **FR-010**: The system MUST provide a safe default for unrecognized values (neutral + clearly labeled as unknown) to avoid misleading operators. - **FR-011**: The admin UI MUST be migrated so existing status-like badges/chips use the centralized system across the suite; tag/category chips are explicitly out of scope for v1 migration and may remain unchanged. - **FR-012**: The delivery MUST include automated regression checks that validate canonical mappings (including “success is never warning”) and prevent reintroducing ad-hoc badge semantics. - **FR-013**: This change MUST be limited to badge/chip rendering semantics; it MUST NOT change underlying workflow logic, status definitions, or page layouts beyond what is required to standardize badge rendering. - **FR-014**: Severity/risk badges (for example, findings severity) MUST be standardized and rendered consistently across all in-scope pages. - **FR-015**: The system MUST NOT introduce new severity levels as part of this feature; it MUST standardize and render existing severity values consistently. - **FR-016**: The delivery MUST include a lightweight automated guard that detects newly introduced ad-hoc status/health or severity/risk badge semantics and blocks release until the centralized system is used. - **FR-017**: Drift finding severity MUST have a canonical meaning: low = neutral, medium = warning, high = danger. ### Assumptions & Dependencies - Existing status values and business meanings are already established; this feature standardizes how they are presented, not what they mean. - A defined set of status-like badge domains exists across the suite (runs, findings status, tenant status, availability, enabled/disabled, severity/risk); any newly discovered status-like domains will be included in the v1 standardization scope. - Dark mode is supported and is considered in acceptance for badge readability. - Tag/category chip standardization (policy type/platform/environment) is deferred to a later version. - Severity level changes (such as adding “critical”) are deferred to a later version. ### Key Entities *(include if feature involves data)* - **Badge Domain**: A named category of values that share a consistent badge meaning (for example, “Operation run status”). - **Badge Definition**: The centralized mapping for a domain’s values to label + color meaning + optional icon. - **Status Badge**: A badge that communicates progress/outcome/health or severity/risk (for example, queued/running/succeeded). - **Tag Badge**: A badge that communicates categorization/metadata (for example, platform/type/environment). ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: For each defined status badge domain, the same value renders with the same label and visual meaning across all in-scope pages in 100% of validation runs. - **SC-002**: Across the in-scope admin UI, 0 instances exist where a success/completed outcome is presented using a warning/attention badge meaning. - **SC-003**: Viewing designated DB-only pages triggers 0 outbound network requests and 0 background work as a side effect of badge rendering, in 100% of regression runs. - **SC-004**: Status-badge-related UI regressions (incorrect label/color/icon meaning) decrease by at least 80% in the 30 days after release compared to the previous 30 days.