# Semantic Clarity — Spec Candidate Package

**Source audit:** `docs/audits/semantic-clarity-audit.md`  
**Date:** 2026-03-21  
**Author role:** Senior Staff Engineer / Enterprise SaaS Product Architect  
**Status:** Spec candidates — ready for spec authoring  

---

## 1. Recommended Spec Package Overview

### Problem recap (one paragraph)

The audit identified a systemic semantic collision problem: ~12 overloaded terms carrying 5–8 distinct meanings each, ~60% of warning-colored badges communicating non-governance facts, and no shared rules governing when a term, color, or badge severity applies. The problem spans every major domain. Local wording fixes without a shared taxonomy will produce new inconsistencies faster than they resolve old ones.

### Package structure

| # | Spec Candidate | Type | Priority | Depends on | Vehicle |
|---|---------------|------|----------|------------|--------|
| **F1** | Operator Semantic Taxonomy & Diagnostic Boundary | Foundation | P0 | — | New spec 156 |
| **D1** | Baseline Snapshot Fidelity Semantics | Domain adoption | P0 | F1 | New spec 157 |
| **D2** | Evidence Completeness Reclassification | Domain adoption | P0 | F1 | New spec 158 or merged into 153 |
| **D3** | Restore Lifecycle Semantic Clarity | Domain adoption | P0 | F1 | New spec 159 |
| **D4** | Operation Outcome & Notification Language | Domain adoption | P1 | F1 | New spec 160 or merged into 055 |
| **D5** | Inventory, Provider & Operability Semantics | Domain adoption | P1 | F1 | New spec 161 |
| **D6** | Tenant Review & Publication Readiness Semantics | Domain adoption (integrated) | P1 | F1 + D2 | Integrated into existing spec 155 |

**Total: 1 foundation + 5 new domain specs + 1 integrated domain mandate = 7 adoption scopes in 6–7 specs.**

> **D6 note:** Tenant Review / Publication Readiness is NOT a standalone spec. It is an explicit semantic adoption mandate integrated into spec 155 (Tenant Review Layer), which is already in draft. This package defines what 155 must adopt from F1 and ensures review/publication semantics do not implicitly disappear from the cleanup program.

### Why this split — not fewer, not more

**Why not one giant spec?**
- The foundation taxonomy is pure definition work (enums, color rules, term dictionary, classification rules). The domain specs are pure adoption work (update badge mappers, rewrite labels, restructure presenters). Mixing definition and adoption in one spec creates a 200+ task monster that blocks all domains until every domain is done.
- Domains have different rollout risk. Restore is safety-critical; inventory is cosmetic. They cannot share a "ship when everything is ready" gate.

**Why not page-by-page micro-specs?**
- Operations, notifications, and alerts share the same `OperationRunOutcome` + `OperationUxPresenter` pipeline. Splitting them would require coordinating term changes across three specs touching the same files.
- Evidence completeness and evidence freshness are the same enum (`EvidenceCompletenessState`) and the same evaluator (`EvidenceCompletenessEvaluator`). One spec.
- Inventory KPI, policy snapshot mode, and provider status all use the same "product support maturity" axis. One spec.

**Why these five domain splits specifically?**
1. **Baselines** — touches `FidelityState`, `GapSummary`, `BaselineSnapshotPresenter`, all baseline badge mappers, and the snapshot summary table. None of these files are shared with other domains.
2. **Evidence** — touches `EvidenceCompletenessState`, `EvidenceCompletenessEvaluator`, evidence sources, and evidence badge mappers. Overlaps with spec 153 (Evidence Domain Foundation) which is already in draft — D2 must coordinate with 153.
3. **Restore** — touches `RestoreRunStatus`, `RestoreResultStatus`, `RestorePreviewDecision`, restore badge mappers, and restore result templates. Safety-critical: wrong terminology in restore → wrong remediation decisions.
4. **Operations/Notifications** — touches `OperationRunOutcome`, `OperationUxPresenter`, `SummaryCountsNormalizer`, `RunFailureSanitizer`, and both notification classes. Cross-cuts run types. Overlaps with spec 055 (Ops-UX Rollout) — D4 must coordinate with 055.
5. **Inventory/Provider/Operability** — touches `InventoryKpiBadges`, `PolicySnapshotModeBadge`, `ProviderConnectionStatusBadge`, sync error messages, verification badges (`VerificationReportOverall`, `VerificationCheckStatus`), onboarding wizard feedback, and prerequisite/operability states. All share the "product readiness / prerequisite / operability" semantic axis. Lower risk, lower urgency.
6. **Review/Publication (into 155)** — touches `TenantReviewCompletenessState`, `TenantReviewReadinessGate` blocker messages, review section labels, publication blockers. These files belong to the review domain, which is already being designed by spec 155. Scoping review semantics into 155 avoids orphan ownership and ensures review-layer design incorporates the taxonomy from day one.

### What is NOT a separate spec

| Audit finding | Resolution | Why not a separate spec |
|--------------|------------|------------------------|
| Finding governance language (P1-6 "missing_support", P1-7 diff messages) | Foundation spec F1 adds "missing_support" → "No exception" to the term dictionary. Diff messages are adopted by spec 141 (Shared Diff Presentation Foundation) when it rolls out. | Fewer than 5 affected touchpoints. Two different existing specs already cover the adoption surface. |
| Alert email internal IDs (P2-7) | Folded into D4 (Operations/Notifications). | Same notification pipeline, same files. |
| Empty state next-step guidance (P2-5) | Already covered by spec 122 (Empty State Consistency Pass). | Spec 122 is in Ready for Implementation status. |
| Onboarding "Needs attention" / "Blocked" (P2-2) | Folded into D5 (Inventory, Provider & Operability Semantics). Onboarding verification and prerequisite terminology shares the same operability axis as provider and sync semantics. | Same "product readiness" axis; same files touched during provider/operability cleanup. |
| "Dry run" color (P2-3) | Folded into D3 (Restore). | Same restore badge mapper. |
| "Anchored evidence snapshot" jargon (P2-4) | Folded into D6 (integrated into spec 155). Review-layer jargon belongs in the review domain spec. | Two words in helper text; not spec-worthy alone. |
| "Stale" color for RBAC status | Foundation spec F1 color rules fix this globally. Badge mapper update is one line. | Trivially mechanical once foundation color rules exist. |

### Relationship to existing specs

| Existing spec | Relationship | Action |
|--------------|-------------|--------|
| **059-unified-badges** | F1 builds ON TOP of 059's infrastructure. 059 centralized the badge rendering pipeline. F1 defines what the pipeline should say. | No conflict. F1 references 059 as prerequisite infrastructure. |
| **060-tag-badge-catalog** | No overlap. 060 covers neutral metadata tags; this package covers status/severity semantics. | None. |
| **122-empty-state-consistency** | 122 covers empty state messaging. Some audit P2 findings (P2-5) are already addressed by 122. | Note in D-specs: "empty state language defers to 122." |
| **130-structured-snapshot-rendering** | 130 defines snapshot page structure. D1 defines what terminology appears on that page. D1 MAY be sequenced after 130 or adopted during 130 rollout. | D1 spec must reference 130 as the page structure authority. |
| **141-shared-diff-presentation-foundation** | 141 defines diff rendering. Audit finding P1-7 (diff-unavailable messages) is adopted when 141 rolls out. | P1-7 adoption note added to 141's scope, not a new spec. |
| **143-tenant-lifecycle-operability-context-semantics** | 143 covers tenant lifecycle naming. This package covers status/severity badge semantics. Orthogonal. | None. |
| **146-central-tenant-status-presentation** | 146 covers tenant lifecycle badge consistency. F1 color rules apply to 146's badge mappings, but 146's scope is lifecycle, not operational status. | F1 provides color rules that 146 adopts. |
| **153-evidence-domain-foundation** | 153 is redesigning the evidence domain. D2 defines the semantic terms for evidence completeness. **D2 MUST be coordinated with 153** — either merged into 153 scope or sequenced as a post-153 cleanup. | If 153 is still in draft: merge D2 scope into 153. If 153 is already in implementation: D2 becomes a follow-up. |
| **155-tenant-review-layer** | 155 is designing the review layer. **D6 is integrated into 155.** 155 must adopt F1 term dictionary for review completeness ("Partial" → coverage/freshness split), review readiness gate blocker messages (operator language + next-action), publication readiness labels, and section-level status terms. 155 references F1 as a hard dependency. | D6 adoption mandate added to 155 scope. 155 MUST NOT ship with collapsed completeness vocabulary. |
| **055-ops-ux-rollout** | 055 covers operation feedback patterns. D4 covers operation terminology. **D4 MUST be coordinated with 055.** | If 055 is still in draft: merge D4 scope into 055. If 055 delivered: D4 is a follow-up semantic layer. |

---

## 2. Foundation Spec Candidate: Operator Semantic Taxonomy & Diagnostic Boundary

**Suggested spec number:** 156  
**Suggested slug:** `operator-semantic-taxonomy`

### Problem statement

TenantPilot uses ~12 overloaded terms ("failed", "partial", "missing", "gaps", "unsupported", "stale", "blocked", etc.) to communicate 5–8 fundamentally different things across different domains. No shared rules exist for when a term applies, what color it gets, or whether it belongs in the operator's primary view or a diagnostic panel. Each domain independently chose its vocabulary, resulting in the same word meaning different things on different pages and different things being called by the same name.

### Why this spec is needed separately

Every domain spec in this package depends on a shared term dictionary, color rule set, and diagnostic/primary classification. Without F1, each domain spec would independently reinvent these rules, producing 5 slightly different taxonomies that re-create the current problem at a higher level of abstraction.

### Scope

**In scope:**
1. **Semantic axis definitions** — Formal definition of the 8–10 independent meaning axes the product must distinguish (execution outcome, data coverage, evidence depth, product support maturity, governance deviation, publication readiness, data freshness, operator actionability). Each axis gets a name, a definition, allowed values, and rules for which axis a given state belongs to.
2. **Canonical term dictionary** — A mapping from every currently overloaded term to its replacement terms, organized by axis. Example: "Partial" → "N of M processed" (execution outcome axis), "Limited detail" (evidence depth axis), "Incomplete coverage" (data coverage axis).
3. **Color severity rules** — Binding rules for when red/yellow/green/blue/gray apply, stated as decision criteria (not per-badge). These rules override domain-specific color choices where they conflict.
4. **Diagnostic boundary classification** — Rules for which states belong in the operator's primary view vs. expandable diagnostic panels. Product support maturity states (e.g., "fallback renderer", "no specialized handler") are classified as diagnostic-only.
5. **"Next action" policy** — Rule: every non-green, non-gray state MUST include either an inline explanation, a resolution link, or an explicit "no action needed" label. This is a design constraint, not an implementation spec.
6. **BadgeDomain color enforcement** — Update the `BadgeSpec` contract or `BadgeRenderer` to enforce that no mapper can assign danger/warning to a diagnostic-only axis. This is the ONE piece of code F1 touches.
7. **Term dictionary for cross-domain terms** — Finding governance "missing_support" → "No exception record", "Blocked" → "Prevented" with cause, "Reference only" → "Metadata captured" / "Summary view". These are terms that appear in fewer than 5 places and don't warrant a separate domain spec.

**Out of scope:**
- Rewriting any domain-specific badge mapper (that's D1–D5 work)
- Rewriting any presenter, DTO, or view template (that's D1–D5 work)
- Restructuring enums (changing enum cases/values is domain spec work; F1 only defines what the values SHOULD be)
- Any UI rendering changes, page layout changes, or Filament resource changes
- Empty state messaging (covered by spec 122)
- Diff presentation language (covered by spec 141)
- Tenant lifecycle terminology (covered by specs 143/146)

### Affected domains/pages/components

- `app/Support/Badges/BadgeSpec.php` — may add a diagnostic tier flag or color constraint
- `app/Support/Badges/BadgeRenderer.php` — may enforce color rules
- Cross-domain badge mappers — F1 defines rules they must follow; D-specs implement

### Shared dependencies

- Requires spec 059 (Unified Badges) to be implemented (it is — the badge infrastructure exists)
- Becomes a dependency for D1–D5 and for any future spec that introduces status badges

### Risks if deferred

- Every D-spec that ships without F1 invents its own term dictionary. When F1 finally ships, those D-specs need rework.
- New features (e.g., 153, 155) will adopt the old collapsed vocabulary because no authority document exists.
- The badge infrastructure (059) remains well-engineered but semantically wrong — good plumbing carrying bad water.

### Recommended priority: **P0**

### Recommended sequence: **First. Before any domain spec.**

### Deliverables

1. A `docs/product/operator-semantic-taxonomy.md` reference document (the term dictionary, axis definitions, color rules, diagnostic boundary)
2. Minimal code changes to `BadgeSpec`/`BadgeRenderer` to support diagnostic-tier classification
3. A test suite that validates: no badge mapper assigns danger/warning to a diagnostic-only axis value

---

## 3. Follow-Up Spec Candidates by Domain

### D1: Baseline Snapshot Fidelity Semantics

**Suggested spec number:** 157  
**Suggested slug:** `baseline-snapshot-fidelity-semantics`

**Problem statement:**
Every baseline snapshot containing policy types without a specialized renderer shows "Unsupported" (gray) and "Gaps present" (yellow) badges to operators. The top-level snapshot state reads "Captured with gaps" even when all requested data was successfully captured. This is the single highest-volume source of false warnings in the product. The cause is that `FidelityState` conflates product renderer maturity with data capture quality, and `GapSummary` conflates three distinct gap causes (renderer fallback, metadata-only capture, actual API error) into one count.

**Why this spec is needed separately:**
- Touches a cohesive set of files that no other domain shares: `FidelityState`, `GapSummary`, `BaselineSnapshotPresenter`, `RenderedSnapshot*` DTOs, `BaselineSnapshotFidelityBadge`, `BaselineSnapshotGapStatusBadge`, `baseline-snapshot-summary-table.blade.php`
- The P0 items (P0-1, P0-2) are in this domain
- Rollout risk is moderate: baselines are read-frequently but not safety-critical like restore

**Scope:**
- Reclassify `FidelityState` values using F1 axis definitions: "Full" and "Partial" stay on the evidence depth axis; "Unsupported" moves to the product support maturity axis (diagnostic-only); "ReferenceOnly" is renamed to match F1 term dictionary
- Restructure `GapSummary` to categorize gaps by cause: product limitation (diagnostic), capture mode choice (informational), actual API error (warning)
- Replace "Captured with gaps" label with axis-appropriate language per F1 rules
- Update `coverageHint` texts to use F1 operator language
- Move renderer-tier information to the diagnostic/expandable section per F1 diagnostic boundary

**Non-goals:**
- Changing the snapshot page layout or structure (that's spec 130)
- Adding new renderers or expanding renderer coverage
- Changing how snapshots are captured or stored
- Baseline compare diff language (that's spec 141)
- Evidence completeness evaluation or freshness logic (that's D2 — see boundary rule below)

**Boundary with D2 (evidence completeness):**
D1 owns everything INSIDE a baseline snapshot's rendering pipeline: how the snapshot describes the quality and depth of its own captured items. D2 owns everything INSIDE the evidence completeness evaluation pipeline: whether an evidence dimension (baselines, findings, operations, permissions) has data and how fresh that data is. Concretely:
- `FidelityState` → D1 (snapshot rendering quality per item)
- `GapSummary` → D1 (capture-level notes within a snapshot)
- `BaselineSnapshotPresenter` → D1 (snapshot-level presentation)
- `EvidenceCompletenessState` → D2 (cross-dimension coverage evaluation)
- `EvidenceCompletenessEvaluator` → D2 (aggregation across dimensions)
- Evidence sources (e.g. `FindingsSummarySource`) → D2 (dimension-level data availability)

D1 does NOT touch evidence sources or completeness evaluators. D2 does NOT touch fidelity states, gap summaries, or snapshot presenters. The two specs share no files.

**Affected domains/pages/components:**
- `FidelityState` enum
- `GapSummary` class
- `BaselineSnapshotPresenter`
- `RenderedSnapshotGroup`, `RenderedSnapshotItem`, `RenderedSnapshot` DTOs
- `BaselineSnapshotFidelityBadge`, `BaselineSnapshotGapStatusBadge`
- `baseline-snapshot-summary-table.blade.php`
- `baseline-snapshot-technical-detail.blade.php`
- `FallbackSnapshotTypeRenderer` (label/message changes only)
- `BaselineSnapshotResource` (column label changes)

**Shared dependencies:** F1 (Operator Semantic Taxonomy)

**Risks if deferred:**
- Every baseline snapshot in every production tenant continues to show yellow warnings that are not governance problems
- Operators learn to ignore yellow badges, which masks real issues when they appear
- Spec 130 (Structured Snapshot Rendering) ships with the wrong vocabulary baked into its page structure

**Recommended priority:** P0  
**Recommended sequence:** 2nd (immediately after F1)

---

### D2: Evidence Completeness Reclassification

**Suggested spec number:** 158  
**Suggested slug:** `evidence-completeness-reclassification`

**Problem statement:**
`EvidenceCompletenessState` conflates three independent axes: data coverage (is there data?), data freshness (is it recent?), and evidence depth (how detailed?). A new tenant with zero findings shows red "Missing" for the findings dimension, which is a valid empty state, not missing evidence. "Stale" uses gray (passive/archived), but stale evidence is operationally risky and should prompt action. Evidence sources like `FindingsSummarySource` return "Missing" when the answer should be "No findings" (valid zero state).

**Why this spec is needed separately:**
- Touches `EvidenceCompletenessState` enum, `EvidenceCompletenessEvaluator`, all evidence source classes, and evidence badge mappers — files shared with no other domain
- The P0 item (P0-3) is in this domain
- **Must coordinate with spec 153 (Evidence Domain Foundation)** which is redesigning the evidence domain. If 153 is still in draft, D2 scope should be merged into 153. If 153 is in implementation, D2 becomes a follow-up.

**Scope:**
- Separate `EvidenceCompletenessState` into two independent axes per F1: coverage (`Full` / `Incomplete` / `NotApplicable` / `NotCollected`) and freshness (`Current` / `Aging` / `Overdue`)
- Fix evidence sources to return `NotApplicable` instead of `Missing` when the underlying data source is legitimately empty (e.g., zero findings is not "missing findings")
- Apply F1 color rules: `Overdue` freshness gets yellow/warning (action recommended); `NotApplicable` coverage gets gray/neutral (no action needed); `NotCollected` gets blue/info (collection available but not yet performed)
- Update `EvidenceCompletenessEvaluator` worst-case-wins logic to evaluate coverage and freshness independently

**Non-goals:**
- Changing what evidence is captured or how snapshots are generated (that's spec 153)
- Redesigning the evidence snapshot page layout
- Adding new evidence dimensions or sources
- Publication readiness logic changes (that's D6/spec 155)
- Review completeness state (`TenantReviewCompletenessState`) — that is D6's scope, integrated into spec 155
- Baseline snapshot fidelity states, gap summaries, or snapshot presenter changes — that is D1's scope (see D1 boundary rule)

**Boundary with D1 (baseline snapshot fidelity):**
D2 owns cross-dimension evidence coverage and freshness evaluation. D2 does NOT touch anything inside the baseline snapshot rendering pipeline. Specifically: `FidelityState`, `GapSummary`, `BaselineSnapshotPresenter`, and all `RenderedSnapshot*` DTOs are exclusively D1 territory. D2 may consume D1's output (e.g., "does a baseline snapshot exist and is it current?") but never modifies how snapshots describe their internal quality.

**Affected domains/pages/components:**
- `EvidenceCompletenessState` enum
- `EvidenceCompletenessEvaluator`
- `EvidenceCompletenessBadge`
- `FindingsSummarySource`, `OperationsSummarySource`, and sibling evidence sources
- `EvidenceSnapshotResource` (column labels)

**Shared dependencies:** F1 (Operator Semantic Taxonomy)

**Risks if deferred:**
- Every new tenant and every stable tenant shows red/yellow evidence badges that are not real problems
- Spec 153 (Evidence Domain Foundation) ships with the collapsed `Missing` / `Stale` vocabulary
- Spec 155 (Tenant Review Layer) inherits wrong completeness signals for review readiness

**Recommended priority:** P0  
**Recommended sequence:** 3rd (after F1 and D1, or merged into spec 153 if 153 is still in draft)

---

### D3: Restore Lifecycle Semantic Clarity

**Suggested spec number:** 159  
**Suggested slug:** `restore-lifecycle-semantic-clarity`

**Problem statement:**
The restore workflow has 13 run-level lifecycle states (most products have 4–6), 7 item-level result statuses, and 5 preview decisions. Three different yellow/warning states have three different meanings. "Partial" means something different at run level vs. item level. "Manual required" gives no guidance. "Skipped" conflates intentional exclusion with forced bypass. "Completed with errors" is a legacy state whose semantics are ambiguous. Form helper text uses jargon ("preview-only types", "foundations", "scope tags", "Entra ID group Object ID (GUID)") that operators cannot parse.

**Why this spec is needed separately:**
- Restore is **safety-critical**: wrong interpretation of restore state → wrong remediation decisions → tenant in unknown configuration state
- Touches a cohesive and isolated set of files: `RestoreRunStatus`, `RestoreResultStatus`, `RestorePreviewDecision`, all restore badge mappers, `restore-results.blade.php`, `restore-run-checks.blade.php`
- Must be independently testable and deployable because restore rollout risk is the highest of any domain

**Scope:**
- Rationalize `RestoreRunStatus` to a clear lifecycle: map 13 states to a smaller canonical set per F1 axis definitions, with legacy states explicitly deprecated and mapped to canonical equivalents
- Separate item-level `RestoreResultStatus` meanings: "Applied" (success), "Skipped — excluded by operator" vs. "Skipped — precondition not met" (two distinct states), "Failed" with cause category
- Replace "Manual required" with specific next-action guidance per F1 next-action policy
- Replace "Partial" (yellow) at run level with "N of M items applied" (quantified outcome per F1 execution outcome axis)
- Distinguish "Dry run" from success more clearly (per F1: blue/info for preview states, green for applied states)
- Move Graph error codes behind diagnostic expandable per F1 diagnostic boundary; show operator-facing categorized messages
- Replace jargon in form helper text with operator language

**Non-goals:**
- Changing restore execution logic, job orchestration, or preview/apply mechanics
- Adding new restore capabilities or policy type support
- Restructuring the restore wizard flow (that's spec 011)
- Changing pre-flight check logic (only changing how results are labeled)

**Affected domains/pages/components:**
- `RestoreRunStatus` enum
- `RestoreResultStatus` enum
- `RestorePreviewDecision` enum
- `RestoreRunStatusBadge`, `RestoreResultStatusBadge`, `RestorePreviewDecisionBadge`
- `RestoreCheckSeverityBadge`
- `RestoreRunResource` (form helper text, infolist labels, table columns)
- `restore-results.blade.php`
- `restore-run-checks.blade.php`

**Shared dependencies:** F1 (Operator Semantic Taxonomy)

**Risks if deferred:**
- Operators misinterpret "Partial" restore state and take wrong remediation action
- "Manual required" items are not actioned because operator doesn't know what to do
- "Completed with errors" legacy state continues to create ambiguity about whether the tenant is in a consistent state

**Recommended priority:** P0  
**Recommended sequence:** 4th (after F1; can run in parallel with D1/D2 if different engineers work on them)

---

### D4: Operation Outcome & Notification Language

**Suggested spec number:** 160  
**Suggested slug:** `operation-outcome-notification-language`

**Problem statement:**
`OperationRunOutcome.PartiallySucceeded` is a yellow badge with no item-level breakdown. `Blocked` gives no cause. Failure messages are truncated to 140 characters and contain internal reason codes (`RateLimited`, `ProviderAuthFailed`). Terminal notifications say "Completed with warnings" without explaining what warnings or where to find them. Summary counts use raw keys like `errors_recorded` and `report_deduped`. "Running in the background" provides no monitoring guidance.

**Why this spec is needed separately:**
- Operations are the cross-cutting execution pipeline — every domain's actions flow through `OperationRunOutcome` and `OperationUxPresenter`
- Touches notification classes, presenter layer, and summary normalizer — files that are shared across all run types
- **Must coordinate with spec 055 (Ops-UX Rollout)** — if 055 is still in draft, merge D4 scope into 055; if 055 is delivered, D4 is a follow-up semantic layer

**Scope:**
- Replace "Partially succeeded" with quantified outcome: show item success/failure counts in the badge or badge tooltip per F1 execution outcome axis
- Add cause-specific explanations to "Blocked": "Prevented — insufficient permissions", "Prevented — provider not connected", etc. per F1 term dictionary
- Replace `RunFailureSanitizer` internal reason codes with operator-facing categorized messages per F1 diagnostic boundary
- Update `OperationRunQueued` and `OperationRunCompleted` notifications to include next-action guidance per F1 next-action policy
- Replace summary count raw keys with operator terms in `SummaryCountsNormalizer`
- Add monitoring guidance to queued notification ("View progress in Operations")
- Remove internal delivery IDs and event type codes from email alert bodies (P2-7)

**Non-goals:**
- Changing operation execution logic, job orchestration, or queue mechanics
- Changing the operations table page layout or filters
- Adding new operation types
- Operation auto-refresh or polling behavior (that's spec 123)

**Affected domains/pages/components:**
- `OperationRunOutcome` enum values (labels only, not case names)
- `OperationRunOutcomeBadge`
- `OperationUxPresenter`
- `SummaryCountsNormalizer`
- `RunFailureSanitizer`
- `OperationRunQueued`, `OperationRunCompleted` notification classes
- `EmailAlertNotification`
- `OperationRunResource` (column labels, infolist descriptions)

**Shared dependencies:** F1 (Operator Semantic Taxonomy)

**Risks if deferred:**
- Every partial or failed operation across all domains leaves the operator without enough information to decide next steps
- "Blocked" operations across 4 domains continue to provide zero diagnostic value
- New operation types introduced by other specs inherit the vague vocabulary

**Recommended priority:** P1  
**Recommended sequence:** 5th (after F1 and P0 domain specs; can run in parallel with D5)

---

### D5: Inventory, Provider & Operability Semantics

**Suggested spec number:** 161  
**Suggested slug:** `inventory-provider-operability-semantics`

**Problem statement:**
Three related domains share the "product readiness / prerequisite / operability" semantic axis and all exhibit the same pattern: product or platform states presented as operator-actionable warnings.

1. **Inventory:** KPI badges show "Partial" (yellow) for policy types that are preview-only — a product support maturity fact, not a data quality signal. `PolicySnapshotModeBadge` shows "Metadata only" with warning color for capture modes that are correct and expected.
2. **Sync & Provider:** Sync error messages are mechanically constructed from error codes (`str_replace('_', ' ', $errorCode)`) with no retry guidance. Provider connection statuses ("Needs consent", "Degraded") give no explanation of what, where, or who.
3. **Onboarding & Verification:** `VerificationReportOverall` uses "Needs attention" (non-specific across missing delegated permissions and stale data) and "Blocked" (reads as "system is frozen" rather than "missing required application permissions"). `VerificationCheckStatus.Fail` is ambiguous (check execution failed vs. check assertion failed). Wizard notifications ("Tenant not available", "Draft is not resumable") give no explanation or recovery guidance.

All three sub-domains conflate product/platform prerequisites with operator-actionable urgency.

**Why this spec is needed separately:**
- All three sub-domains sit on the same semantic axis: "is the platform/product ready for this operation?"
- Inventory pages are high-frequency scanning surfaces (daily). Onboarding/verification is lower frequency but high-stakes (first impression, setup correctness).
- The affected files form a cohesive group not shared with D1–D4: inventory badges, provider badges, verification badges, sync error formatting, onboarding wizard feedback.

**Scope:**

*Inventory:*
- Reclassify "Partial" KPI items from warning to product-tier indicator (neutral/info) per F1 product support maturity axis (diagnostic-only)
- Replace "Metadata only" warning badge with neutral "Summary capture" indicator per F1 term dictionary

*Sync & Provider:*
- Replace `str_replace`-constructed sync error messages with operator-facing categorized messages per F1 next-action policy
- Add explanation and resolution context to provider statuses: "Needs consent — grant admin consent in Azure portal" per F1 next-action policy
- Add "Degraded — [specific impact]" to provider health badge per F1 next-action rules

*Onboarding & Verification:*
- Replace "Needs attention" with cause-specific labels per F1 term dictionary: "Missing delegated permissions" vs. "Stale verification data" instead of a single collapsed term
- Replace "Blocked" with "Requires application permissions" or equivalent actionable label per F1 next-action policy
- Disambiguate `VerificationCheckStatus.Fail`: separate check execution failure from check assertion failure per F1 execution outcome axis
- Replace wizard notification messages ("Tenant not available", "Draft is not resumable") with cause + recovery guidance per F1 next-action policy
- Ensure verification assist panel labels use F1 operator language (the panel's structure is already well-designed; only labels change)

**Non-goals:**
- Changing sync logic, provider connection mechanics, or capture modes
- Adding new policy type support or inventory capabilities
- Restructuring the inventory page layout (that's specs 040/041)
- Coverage table design (that's spec 124)
- Changing verification check logic or onboarding wizard flow mechanics
- Changing provider connection mechanics (that's spec 081)
- Permission posture evaluation logic (that's specs 083/104)

**Affected domains/pages/components:**
- `InventoryKpiBadges` / `InventoryKpiHeader` widget
- `PolicySnapshotModeBadge`
- `ProviderConnectionStatusBadge`, `ProviderConnectionHealthBadge`
- `InventorySyncService` (error message formatting only)
- `PolicyResource` (sync action messages, snapshot mode helper text)
- `InventoryCoverage` page (badge labels)
- `VerificationReportOverall` enum and badge
- `VerificationCheckStatus` enum and badge
- `ManagedTenantOnboardingVerificationStatusBadge`
- `VerificationAssistViewModelBuilder` (label changes only)
- `ManagedTenantOnboardingWizard` (notification messages only)
- `verification-required-permissions-assist.blade.php` (label changes only)

**Shared dependencies:** F1 (Operator Semantic Taxonomy)

**Risks if deferred:**
- Perpetual yellow badges in daily-use inventory surfaces train operators to ignore all warnings
- Provider "Degraded" and "Needs consent" states remain unactionable
- New inventory features inherit mechanically constructed error messages
- Onboarding first impression continues to show "Blocked" / "Needs attention" without explanation — damages trust during setup
- Verification specs (074, 075, 084) that ship without F1-aligned terminology bake in the collapsed vocabulary

**Recommended priority:** P1  
**Recommended sequence:** 6th (after F1; can run in parallel with D4)

---

### D6: Tenant Review & Publication Readiness Semantics (integrated into spec 155)

**Vehicle:** Existing spec 155 (`tenant-review-layer`)  
**NOT a standalone spec.** This is an explicit adoption mandate that spec 155 must fulfill.

**Problem statement:**
`TenantReviewCompletenessState` inherits the same "Partial" / "Stale" / "Missing" conflation as `EvidenceCompletenessState`. Publication readiness gate messages use collapsed vocabulary: "{Section} is stale and must be refreshed before publication" gives no guidance on HOW to refresh. "{Section} is missing" conflates "section text hasn't been generated yet" with "underlying data doesn't exist." "Anchored evidence snapshot" is jargon. Review highlight bullets are well-written (a positive example), but completeness/freshness/readiness labels are not.

**Why integrated into 155 instead of standalone:**
- Spec 155 is already designing the review layer from scratch. Adding a parallel spec for review semantics would create dual ownership of the same files.
- The review completeness model is being defined NOW in 155. Incorporating F1 rules during design is cheaper than retrofitting after 155 ships.
- The affected file set (`TenantReviewCompletenessState`, `TenantReviewReadinessGate`, `TenantReviewComposer`, `TenantReviewSectionFactory`, `ReviewPackResource`) is entirely within 155's scope.

**What spec 155 MUST adopt from F1:**

1. **Completeness axis separation** — `TenantReviewCompletenessState` must separate coverage from freshness, matching D2's approach for evidence. "Partial" must be replaced with axis-specific terms (incomplete coverage vs. limited depth vs. outdated freshness). "Stale" must get action-prompting color (yellow/warning), not passive gray.

2. **Publication readiness gate messages** — Every blocker surfaced by `TenantReviewReadinessGate` must include:
   - What is blocked (specific section name)
   - Why it is blocked (specific cause: stale data, missing section, incomplete evidence)
   - How to resolve it (link to refresh action, link to evidence collection, link to missing data source)
   - Per F1 "next action" policy

3. **Section-level status labels** — Review sections must use F1-compliant terms:
   - "Missing" → "Not generated" (section) or "No data source" (underlying data absent)
   - "Stale" → "Outdated — last updated {date}" with yellow/warning color
   - "Anchored evidence snapshot" → "Review evidence base" or "Evidence snapshot"

4. **Publication readiness presentation** — "Ready for publication" remains appropriate. Blockers must use F1 severity colors (red for hard blockers, yellow for soft warnings). The current gate logic is well-designed; only the messages it surfaces need F1 alignment.

**Non-goals (for D6 mandate):**
- Changing review composition logic, section generation, or pack export mechanics
- Redesigning the review page layout
- Adding new review sections or evidence dimensions
- Evidence completeness reclassification (that's D2's scope — 155 consumes D2's output)

**Affected domains/pages/components:**
- `TenantReviewCompletenessState` enum and badge
- `TenantReviewReadinessGate` (message texts only)
- `TenantReviewComposer` / `TenantReviewSectionFactory` (section labels and status descriptions)
- `ReviewPackResource` (column labels, helper text)
- `TenantReviewResource` (infolist labels, status descriptions)

**Shared dependencies:** F1 (Operator Semantic Taxonomy), D2 output (evidence completeness model)

**Risks if this mandate is omitted:**
- Spec 155 ships with collapsed "Partial" / "Missing" / "Stale" vocabulary, requiring a retrofit PR after F1 lands
- Review readiness gates surface vague blockers that operators cannot act on
- The review layer — a stakeholder-facing surface — launches with the same semantic collisions found in the audit

**Recommended priority:** P1  
**Recommended sequence:** Ships with spec 155. If 155 is in implementation before F1 lands, D6 becomes a mandatory follow-up PR.

---

## 4. Recommended Implementation Order

```
Phase 1: Foundation
  ┌────────────────────────────────────────────────┐
  │  F1: Operator Semantic Taxonomy                │
  │  (term dictionary, color rules, diagnostic     │
  │   boundary, BadgeSpec enforcement)             │
  └────────────────────┬───────────────────────────┘
                       │
Phase 2: P0 Domain Adoption (can run in parallel)
  ┌────────────────────┼───────────────────────────┐
  │                    │                            │
  ▼                    ▼                            ▼
 D1: Baseline         D2: Evidence              D3: Restore
 Snapshot             Completeness              Lifecycle
 Fidelity             Reclassification          Semantic
 Semantics                                      Clarity
  │                    │                            │
  │  coordinate        │  coordinate                │
  │  with 130          │  with 153                  │
  └────────────────────┼───────────────────────────┘
                       │
Phase 3: P1 Domain Adoption (can run in parallel)
  ┌────────────────────┼───────────────────────────┐
  │                    │                            │
  ▼                    ▼                            │
 D4: Operation        D5: Inventory,               │
 Outcome &            Provider &                   │
 Notification         Operability                  │
 Language             Semantics                     │
  │                    │                            │
  │  coordinate        │                            │
  │  with 055          │                            │
  └────────────────────┴───────────────────────────┘
```

### Sequencing rationale

1. **F1 first** — non-negotiable. It produces the term dictionary and color rules that all 5 domain specs reference. Without it, domain specs invent their own terms.
2. **D1 second** — highest-volume false warning source. Every baseline snapshot shows wrong badges. Most visible daily impact.
3. **D2 alongside D1 or merged into 153** — P0 severity but scope may be absorbed by spec 153 (Evidence Domain Foundation) if 153 is still in draft. If 153 is already in implementation, D2 ships as a follow-up.
4. **D3 alongside D1/D2** — P0 severity for safety reasons. Can be staffed in parallel with D1/D2 because file sets don't overlap.
5. **D4 and D5 in Phase 3** — P1 priority. Both are independent and can run in parallel. D4 should coordinate with 055 (Ops-UX Rollout) if that spec is still active.
6. **D6 concurrent with 155** — D6 is not a separate ship date. Its adoption mandate is fulfilled when spec 155 ships with F1-compliant vocabulary. If 155 is already in implementation when F1 lands, D6 becomes a mandatory follow-up PR into 155's branch.

### Calendar independence

Each D-spec can ship independently. There is no "all 5 must ship together" gate. The foundation spec is the only hard prerequisite. Domain specs can be reordered within their phase based on team capacity.

---

## 5. What Must Be Fixed in the Foundation First vs. Left to Domain Specs

### Foundation (F1) MUST deliver before any domain spec ships

| Deliverable | Why it blocks domain specs |
|------------|--------------------------|
| **Semantic axis definitions** (8–10 axes with names, definitions, allowed values) | Domain specs need to know which axis each of their states belongs to. Without this, D1 might put "FidelityState.Unsupported" on the "data quality" axis while D5 puts "PolicySnapshotMode.MetadataOnly" on the "product support" axis — same semantic problem, different words. |
| **Canonical term dictionary** mapping old terms → new terms | Domain specs apply the dictionary. If the dictionary doesn't exist yet, each domain spec writes its own and we get 5 dialects. |
| **Color severity rules** stated as decision criteria | Domain specs update badge mappers. If color rules aren't defined, D1 picks yellow for "Limited detail" while D2 picks gray — inconsistent again. |
| **Diagnostic boundary classification** (which axis values are diagnostic-only) | Domain specs need to know what to move to expandable panels. Without this rule, each domain spec makes a different judgment about what operators "need" to see. |
| **"Next action" policy** (non-green/non-gray states MUST include explanation or link) | Domain specs rewrite badge tooltips and helper text. Without this constraint, some will add guidance and some won't. |

### Foundation (F1) MUST NOT try to do

| Anti-scope | Why |
|-----------|-----|
| Rewrite any badge mapper | Badge mapper changes are domain-specific. F1 provides the rules; D-specs apply them. If F1 tries to update all 43 badge mappers, it becomes a 150-task mega-spec. |
| Rename enum cases | Enum case changes trigger migration, factory, test, and code reference updates across the domain. This is domain spec work with domain-specific testing. |
| Update view templates | Template changes require domain-specific context about page layout, user flow, and UX. F1 is a taxonomy rulebook, not a UI spec. |
| Define page layout or information hierarchy | That's the job of domain page specs (130, 133, etc.). F1 defines what terms appear; page specs define where and how. |

---

## 6. Risks of Doing Local Wording Cleanups Without the Foundation Spec

### Risk 1: Dialect drift

Without a shared taxonomy, each domain spec independently defines what "Partial" means in its context. D1 replaces "Partial" with "Limited detail". D3 replaces "Partial" with "Incomplete restore". D4 replaces "Partially succeeded" with "Mixed outcome". An operator moving between domains still encounters 3 different words for overlapping concepts. The audit's central finding — semantic collision — is replaced by semantic fragmentation.

### Risk 2: Color rule conflicts

Without shared color rules, D1 might decide "metadata-only capture" is gray (neutral) while D5 decides the same concept ("metadata only snapshot mode") is yellow (warning). The badge infrastructure (059) faithfully renders both. The operator sees the same underlying fact in two different severity colors.

### Risk 3: Diagnostic boundary inconsistency

Without a shared diagnostic boundary, D1 moves "Unsupported" (product maturity) to a diagnostic panel, but D5 leaves "Metadata only" (same semantic axis — product support maturity) in the primary badge. The product now has partial diagnostic separation, which is arguably worse than none: it implies that items NOT moved to diagnostics are confirmed operator-relevant, which isn't true.

### Risk 4: Incompatible "next action" patterns

Without a shared next-action policy, D3 adds detailed resolution guidance to every restore warning badge (because restore is safety-critical) while D4 adds none to operation warnings (because operations seem lower risk). The product develops uneven affordance depth: restore badges are helpful, operation badges are vague. Operators trust restore status but don't trust operation status.

### Risk 5: Rework cost

Each domain spec shipped without the foundation will need partial rework when the foundation ships. The rework isn't catastrophic (term substitutions, color changes), but it adds test churn, review cycles, and regression risk. Shipping F1 first avoids this entirely.

### Risk 6: New specs inherit old vocabulary

Specs 153 (Evidence Domain Foundation) and 155 (Tenant Review Layer) are actively in draft. If they ship before F1, they will bake the collapsed vocabulary ("Missing", "Partial", "Stale") into their domain designs. These are foundational domain specs — retrofitting them is significantly more expensive than incorporating F1 rules during their initial design.

**Bottom line:** The foundation spec is small (one reference document + one badge enforcement constraint + one test suite). The cost of doing it first is low. The cost of NOT doing it first grows linearly with every domain spec that ships without it.
