## Summary - introduce a shared operator outcome taxonomy with semantic axes, severity bands, and next-action policy - apply the taxonomy to operations, evidence/review completeness, baseline semantics, and restore semantics - harden badge rendering, tenant-safe filtering/search behavior, and operator-facing summary/notification wording - add the spec kit artifacts, reference documentation, and regression coverage for diagnostic-vs-primary state handling ## Testing - focused Pest coverage for taxonomy registry and badge guardrails - operations presentation and notification tests - evidence, baseline, restore, and tenant-scope regression tests ## Notes - Livewire v4.0+ compliance is preserved in the existing Filament v5 stack - panel provider registration remains unchanged in bootstrap/providers.php - no new globally searchable resource was added; adopted resources remain tenant-safe and out of global search where required - no new destructive action family was introduced; existing actions keep their current authorization and confirmation behavior - no new frontend asset strategy was introduced; existing deploy flow with filament:assets remains unchanged Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #186
10 KiB
10 KiB
Research: Operator Outcome Taxonomy and Cross-Domain State Separation
Decision 1: Keep the badge infrastructure and fix the taxonomy feeding it
- Decision: Reuse
BadgeCatalog,BadgeRenderer, and the existing badge-domain architecture as the canonical rendering path, and focus the foundation on semantic-axis definitions, term rules, severity rules, and minimal contract enforcement at the shared badge boundary. - Rationale: The repo already has centralized rendering infrastructure and audit work describes the plumbing as sound. The systemic problem is not how badges render but how different domains feed overloaded meanings into the same rendering layer.
- Alternatives considered:
- Replace the entire badge system with a new UI-state framework: rejected because it solves the wrong problem and would create avoidable churn.
- Fix each badge mapper independently without a shared foundation: rejected because that would reproduce the current drift under new names.
- Keep the current mappings and only improve helper copy: rejected because false-warning color and label semantics would remain structurally wrong.
Decision 2: Publish one canonical reference document under product documentation
- Decision: The shared taxonomy reference should be published as
docs/product/operator-semantic-taxonomy.mdand treated as the source of truth for downstream domain specs and operator-facing copy decisions. - Rationale: The audit material, roadmap, and spec-candidate sequencing already live under product-oriented documentation. The taxonomy is a product truth document first and a code contract second, so it belongs where product and engineering follow-up specs can reference it consistently.
- Alternatives considered:
- Put the reference only inside the spec folder: rejected because downstream specs and ongoing product work need a durable cross-spec reference after planning is complete.
- Put the reference under
docs/ui/: rejected because the problem is not purely visual UI guidance; it is product semantics that affect notifications, audit prose, and run summaries as well. - Encode the taxonomy only in code comments: rejected because non-code stakeholders and future spec authors need a stable human-readable reference.
Decision 3: The first slice should include bounded real adoption, not only prose
- Decision: The foundation slice should ship both the shared taxonomy definition and a bounded adoption set covering operations, evidence and review completeness, baseline snapshot semantics, and restore semantics.
- Rationale: A reference document without any applied adoption leaves the repo vulnerable to immediate semantic drift and would not prove that the taxonomy is executable. The spec's acceptance criteria require an applied adoption set.
- Alternatives considered:
- Ship only the reference document and defer all code adoption: rejected because it would not create any enforcement or executable proof.
- Apply the taxonomy to every affected domain in one release: rejected because the rollout would become too large and hard to validate.
- Apply the taxonomy only to one domain such as baselines: rejected because the feature's value is cross-domain alignment, not a local cleanup.
Decision 4: Diagnostic-only states need a contract-level severity guard
- Decision: Introduce a shared badge-contract concept that distinguishes primary operator states from diagnostic-only states and supports a guard that rejects warning or danger severity on diagnostic-only values.
- Rationale: The audit identifies product-support and renderer-maturity facts as repeatedly surfacing as warnings. If the foundation only defines prose rules, a future mapper can silently violate them. A contract-level guard makes the taxonomy enforceable in CI.
- Alternatives considered:
- Rely on reviewer discipline only: rejected because the problem is systemic and already slipped through multiple domains.
- Encode the rule as page-level helper methods: rejected because local helpers do not create a cross-domain invariant.
- Ban all gray or informational diagnostic states: rejected because diagnostic-only information still needs a supported visual form.
Decision 5: Valid-empty and freshness must be treated as separate cross-domain concerns
- Decision: The taxonomy must explicitly separate valid-empty, completeness, and freshness semantics, and the first slice should apply that rule to
EvidenceCompletenessStateandTenantReviewCompletenessStatein addition to the more visible operations, baseline, and restore surfaces. - Rationale: The audit identifies false-red
Missingstates and passive-grayStalestates as trust-damaging patterns. These are foundational semantics, not niche edge cases, and they affect both tenant detail surfaces and canonical review surfaces. - Alternatives considered:
- Leave completeness and freshness to downstream evidence-only work: rejected because the taxonomy would remain incomplete and operators would keep seeing the most obvious false alarms.
- Model freshness as only helper copy, not a state axis: rejected because severity and attention meaning are the core issue.
- Treat zero-data states uniformly as
Missing: rejected because valid-empty tenants are not failures.
Decision 6: Operations should be the proving ground for cause-specific, action-oriented states
- Decision: Use operations outcomes, notifications, and summary lines as the first proving ground for the taxonomy's
blocked,partial, and summary-language rules. - Rationale:
OperationRunOutcomeBadge,OperationUxPresenter, andSummaryCountsNormalizeralready centralize cross-domain operator language for many flows. Improving them demonstrates immediate product value and sets the vocabulary that reason-code translation will later consume. - Alternatives considered:
- Start with restore only because it is safety-critical: rejected because operations are more centralized and affect more domains quickly.
- Start with provider health only: rejected because it would not address the broadest shared language path.
- Defer operations until reason-code translation exists: rejected because the taxonomy is the prerequisite that reason-code translation depends on.
Decision 7: Downstream domain specs should consume the taxonomy, but the foundation may still touch a few low-isolation cross-domain terms
- Decision: Keep major domain rewrites in follow-up specs, but allow the foundation to directly normalize low-isolation cross-domain terms that appear in many places and do not justify their own dedicated spec, such as simple completeness or support-maturity labels.
- Rationale: The audit and candidate notes treat major baselines, restore, evidence, and provider semantics as downstream work. However, some overloaded terms are lightweight and shared enough that the foundation should resolve them centrally to avoid leaving obvious contradictions in place.
- Alternatives considered:
- Forbid all code changes outside shared badge contracts: rejected because the spec requires a real adoption set.
- Pull all domain-specific enum redesign into the foundation: rejected because that would turn the foundation into an unshippable monolith.
- Leave lightweight terms untouched until every downstream spec lands: rejected because drift would remain visible on day one.
Decision 8: The rollout needs explicit adoption order and guard-backed stop points
- Decision: Roll out in this order: shared reference and badge contract, operations wording, evidence and review completeness semantics, baseline snapshot semantics, then restore semantics. Each step should be guarded before the next begins.
- Rationale: The order follows both strategic value and centralization. Shared contracts come first, then the most centralized cross-domain wording path, then the most obvious false-alarm states, then the domain-specific high-noise and high-risk surfaces.
- Alternatives considered:
- Roll out by team ownership rather than semantic priority: rejected because the trust problem is cross-domain and needs one operator-centered order.
- Roll out baselines before operations: rejected because operations provide faster shared leverage and a natural bridge to later reason-code translation.
- Extend the first slice into provider, inventory, onboarding, or verification semantics: rejected because it would blur accountability and make the semantic cleanup harder to validate.
- Roll out everything behind one big feature flag: rejected because the repo already uses test-backed staged hardening more effectively than dormant global flags.
Decision 9: Meta-fallback must stay diagnostic and must not inflate baseline gap counts
- Decision: Treat
meta_fallbackand renderer-fallback notes as diagnostic evidence-maturity context, not as primary coverage gaps. - Rationale: The shipped baseline slice now separates
Support limited,Mixed evidence detail, and fallback notes from true coverage gaps. Operators should only seeCoverage gaps need reviewwhen a real data-coverage issue exists. - Alternatives considered:
- Count every fallback or renderer limitation as a gap: rejected because it recreates the false-warning problem this feature is fixing.
- Hide fallback detail entirely: rejected because technical truth still matters for troubleshooting and roadmap follow-up.
- Model fallback only in prose outside the taxonomy: rejected because the diagnostic boundary needs a shared, testable contract.
Decision 10: First-slice taxonomy labels should be resolved in already-authorized views, not through global search
- Decision: Keep the adopted operations, evidence snapshot, baseline snapshot, and tenant review resources out of global search while normalizing their canonical and tenant-context labels through
BadgeCatalog. - Rationale: Filament v5 global search remains a leak surface when shared labels, hints, and summaries can imply hidden tenant state. The implemented slice keeps the vocabulary inside views that already have tenant and workspace authorization.
- Alternatives considered:
- Make every adopted resource globally searchable immediately: rejected because the slice is semantics-first, not search-first, and the leak risk outweighs the value.
- Add page-local label overrides instead of registry-backed options and summaries: rejected because that would reintroduce drift and defeat BADGE-001.
- Leave filters and summary labels on raw enum values: rejected because it would preserve the same operator confusion even after the badges were fixed.