## Summary - add the Spec 194 governance action catalog, friction classes, reason policies, and regression guards - align exception, review, evidence, finding, tenant, provider connection, and system run actions to the shared semantics model - add focused feature, RBAC, audit, unit, and browser coverage, including the tenant detail triage header consistency update ## Verification - ran the focused Spec 194 verification pack from the quickstart and task plan - ran targeted tenant triage coverage after the detail-header update - ran `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Filament Notes - Filament v5 / Livewire v4 compliance preserved - provider registration remains in `apps/platform/bootstrap/providers.php` - globally searchable resources were not changed - destructive actions remain confirmation-gated and server-authorized - no new Filament assets were introduced; the existing `cd apps/platform && php artisan filament:assets` deploy step stays unchanged Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #229
48 KiB
Feature Specification: Governance Friction Hardening and Operator Vocabulary
Feature Branch: 194-governance-friction-hardening
Created: 2026-04-12
Status: Proposed
Input: User description: "Spec 194 - Governance Friction Hardening & Operator Vocabulary"
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: Governance-relevant actions across the admin panel still use inconsistent confirm depth, reason capture, danger styling, and operator wording for equivalent decisions.
- Today's failure: Operators can perform similar exception, review, evidence, run-triage, and tenant lifecycle actions with different semantic weight depending on the surface, which weakens audit clarity and increases misjudgment risk.
- User-visible improvement: Similar governance decisions will feel the same across queue, detail, workspace, and system surfaces, while harmless navigation and export actions remain visibly lighter.
- Smallest enterprise-capable version: Inventory all in-scope governance actions, group them into action families, assign one friction class per action, align the highest-risk families first, document exceptions, and add a lightweight regression gate for future actions.
- Explicit non-goals: No new governance states, no new workflow engine, no header-layout rewrite, no dispatch/preflight refactor, no new audit domain, and no generic action DSL.
- Permanent complexity imported: A small semantic layer with friction classes F0-F3, reason rules, a vocabulary canon, and a documented exception path.
- Why now: Spec 192 and Spec 193 solve surface placement and hierarchy, but not the semantics of the governance actions themselves.
- Why not local: The same action families already appear across queue, detail, workspace, and system surfaces, so page-by-page fixes would not stop drift.
- Approval class: Core Enterprise
- Red flags triggered: Cross-surface taxonomy risk and multi-surface remediation breadth risk. Defense: no new persistence, no new domain workflow, and no generic framework beyond the smallest shared rule model.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve
Spec Scope Fields (mandatory)
- Scope: canonical-view
- Primary Routes:
- Existing tenant admin detail pages under
/admin/t/{tenant}/...for findings, finding exceptions, evidence snapshots, and tenant reviews - Existing workspace admin surfaces under
/admin/...for finding exception queueing, operations, audit, and workspace tenant lifecycle - Existing system operation run detail pages under
/system/ops/...
- Existing tenant admin detail pages under
- Data Ownership:
- No new tables, persisted entities, or ownership boundaries are introduced.
- Tenant-owned records remain tenant-owned: findings, finding exceptions, evidence snapshots, and tenant reviews.
- Workspace queue and monitoring pages continue to present existing workspace-visible or entitled cross-tenant views only.
- System run pages continue to expose existing platform-visible run records only.
- RBAC:
- Tenant admin plane
/admin/t/{tenant}keeps tenant membership plus capability checks for finding, exception, evidence, and review actions. - Workspace admin plane
/adminkeeps workspace membership and capability checks for queue review and tenant lifecycle actions. - System plane
/systemkeeps platform capabilities for operational triage.
- Tenant admin plane
For canonical-view specs, the spec MUST define:
- Default filter behavior when tenant-context is active: Workspace monitoring pages may keep an entitled tenant prefilter or remembered context, but the same action family must retain the same friction class whether the operator arrived through workspace scope or a narrower tenant-prefiltered route.
- Explicit entitlement checks preventing cross-tenant leakage: Re-grouping, relabeling, or friction alignment must not bypass existing Gates, Policies, UiEnforcement helpers, or capability registries. Non-members remain deny-as-not-found, scoped records remain tenant-safe, and workspace/system pages must not hint at inaccessible tenant detail.
Decision-First Surface Role (mandatory when operator-facing surfaces are changed)
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Finding Exceptions Queue | Primary Decision Surface | Approve or reject a pending exception request | Tenant, finding summary, validity, request age, and whether a decision is pending now | Tenant detail, finding detail, request history, evidence references | Primary because this is the workspace approval inbox | Follows pending-governance review, not storage objects | Removes switching between queue, finding detail, and tenant detail before deciding |
| ViewFindingException | Primary Decision Surface | Renew or revoke an existing exception | Current validity, expiry, owner, status, and whether renewal or revocation is allowed | Related finding, evidence references, prior decisions | Primary because active exception lifecycle should remain decidable on one page | Follows exception maintenance workflow | Avoids reconstructing state from audit or related records |
| ViewEvidenceSnapshot | Secondary Context Surface | Decide whether evidence remains valid and inspect its current truth | Artifact truth, completeness, status, expiry, and whether expiration is available | Operation run, review pack, raw evidence dimensions | Not primary because visits are usually inspection-first, but lifecycle mutation still needs governed semantics | Supports evidence inspection with occasional lifecycle intervention | Prevents refresh and expiry from reading as equivalent generic mutations |
| ViewTenantReview | Primary Decision Surface | Publish, archive, or continue a review lifecycle | Review status, readiness, publication state, and next lifecycle step | Pack export and deeper evidence context | Primary because review publication is a formal governance moment | Follows review release workflow | Prevents publish, export, and archive from blurring together |
| ViewFinding | Secondary Context Surface | Close, reopen, or route a finding into exception governance | Current status, severity, governance posture, and queue availability | Related records and deeper operational evidence | Secondary because it often feeds a later governance step | Aligns with finding triage and escalation | Keeps queue/navigation actions distinct from lifecycle mutation |
| TenantlessOperationRunViewer | Secondary Context Surface | Inspect one run and understand whether any follow-up exists | Run identity, scope, outcome, freshness, and follow-up availability | Related links, restore continuation, detailed diagnostics | Secondary because the surface is context-first unless it genuinely owns intervention | Supports monitoring review before intervention | Prevents context and navigation from feeling like governance mutation |
| System ViewRun | Primary Decision Surface | Retry, cancel, or mark a run investigated | Run identity, current outcome, retryability, cancellability, and investigation need | Related runbooks and downstream operational context | Primary because it is the platform triage point for run intervention | Follows operations workflow | Makes the difference between retry, cancel, and investigated immediately legible |
| ViewTenant / EditTenant | Primary Decision Surface | Archive or restore a tenant lifecycle state | Current lifecycle state and currently allowed lifecycle action | Supporting setup and external context | Primary because tenant lifecycle is a formal operating-state decision | Follows tenant lifecycle governance | Prevents archive/restore from behaving like routine utilities |
UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Finding Exceptions Queue | Queue / Workbench | Governance decision workbench | Approve or reject the selected request | Explicit inspect action selects the request and opens in-page detail | forbidden | Scope, filters, and related navigation stay outside the decision lane | Review-selected decision group only | Existing workspace exception queue route | Same page with selected exception context plus tenant detail drilldown | Workspace scope and optional tenant prefilter | Finding exceptions / exception request | Whether a decision-ready request is selected now | none |
| ViewFindingException | Detail / Decision | Governance lifecycle detail | Renew or revoke the exception | Canonical tenant detail page | not applicable | Safe related navigation stays secondary | Revocation remains separated from renewal | Existing tenant exception list route | Existing tenant exception detail route | Active tenant context only | Finding exception / exception | Whether the exception is active, expiring, or revocable | none |
| ListEvidenceSnapshots | List / Table | Read-only registry report with lifecycle row action | Inspect a snapshot or expire an obsolete one | Clickable row opens snapshot detail | required | Row-level More menu only for non-primary mutation | Expire snapshot stays grouped under More |
Existing tenant evidence index route | Existing tenant evidence detail route | Active tenant context only | Evidence snapshots / snapshot | Current evidence truth and next step | none |
| ViewEvidenceSnapshot | Detail / Context | Evidence lifecycle detail | Refresh evidence or expire snapshot | Canonical tenant snapshot detail page | not applicable | Related operation/review navigation stays contextual | Expire snapshot remains danger-separated from Refresh evidence |
Existing tenant evidence index route | Existing tenant evidence detail route | Active tenant context only | Evidence snapshot / snapshot | Whether the snapshot is current, complete, and still valid | none |
| ViewTenantReview | Detail / Decision | Governance release detail | Publish review, export pack, or archive review | Canonical tenant review detail page | not applicable | Export and next-review actions stay secondary | Archive stays in a separate danger group | Existing tenant review register route | Existing tenant review detail route | Active tenant context only | Tenant reviews / review | Publication readiness and current lifecycle state | none |
| ViewFinding | Detail / Context | Finding lifecycle and governance context detail | Close, reopen, or route into exception governance | Canonical tenant finding detail page | not applicable | Related record and queue navigation stay separate from workflow mutation | Any destructive-like lifecycle action stays in the workflow family, not as navigation | Existing tenant findings route | Existing tenant finding detail route | Active tenant context only | Findings / finding | Governance posture and next action | none |
| TenantlessOperationRunViewer | Detail / Monitoring | Workspace run context viewer | Refresh or follow related run context | Canonical workspace operation detail page | forbidden | Scope, return, refresh, and related links remain structured and context-first | No destructive triage action is promoted unless the surface genuinely owns it | Existing workspace operations route | Existing tenantless run detail route | Workspace scope and optional tenant-origin context | Operations / operation run | Whether the run needs attention and what follow-up exists | context-first viewer |
| System ViewRun | Detail / Decision | Platform run triage detail | Retry, cancel, or mark the run investigated | Canonical system run detail page | forbidden | Navigation back to runs and runbooks stays secondary | Cancel is clearly separated as the strongest action | Existing system runs route | Existing system run detail route | Platform/system scope only | Operations / operation run | Whether intervention is possible and how severe it is | none |
| ViewTenant / EditTenant | Detail / Lifecycle | Workspace tenant lifecycle surface | Archive or restore the tenant | Canonical workspace tenant view/edit pages | not applicable | Setup and external links remain outside lifecycle semantics | Archive and restore stay inside one lifecycle family with explicit severity | Existing workspace tenant register route | Existing workspace tenant view/edit routes | Workspace scope only | Tenants / tenant | Whether the tenant is active or archived and which lifecycle action is allowed | none |
Operator Surface Contract (mandatory when operator-facing surfaces are changed)
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Finding Exceptions Queue | Workspace approver | Approve or reject pending exception requests | Queue workbench | What request needs a formal decision right now? | Request state, tenant, finding summary, validity, review urgency, selection state | Related finding detail and full tenant exception detail | governance validity, request status, urgency | TenantPilot only | Approve exception, Reject exception | Reject exception may be negative governance, but does not automatically become F3 |
| ViewFindingException | Tenant manager | Renew or revoke an existing exception | Detail decision surface | Is this exception still justified, and what lifecycle step is warranted now? | Current validity, status, owner, expiry, renewal eligibility, revocation eligibility | Evidence references and decision history | lifecycle, governance validity, expiry | TenantPilot only | Renew exception | Revoke exception |
| ViewEvidenceSnapshot | Tenant operator | Refresh or formally expire the active evidence basis | Detail context surface | Is this evidence still valid to govern from? | Artifact truth, completeness, freshness, expiry, latest related operation | Review-pack and operation drilldowns, raw evidence dimensions | evidence validity, completeness, freshness | TenantPilot only | Refresh evidence | Expire snapshot |
| ViewTenantReview | Tenant reviewer | Publish or archive review lifecycle state | Detail decision surface | Is this review ready for formal release, continuation, or closure? | Review status, readiness, summary truth, next lifecycle step | Exported pack and supporting evidence detail | lifecycle, completeness, readiness | TenantPilot only | Publish review, Create next review | Archive review |
| ViewFinding | Tenant operator | Close, reopen, or route a finding into exception governance | Detail context surface | Does this finding need lifecycle closure, reopening, or governed exception handling? | Finding status, severity, governance posture, queue availability | Related navigation and deeper evidence | lifecycle, governance posture, severity | TenantPilot only | Close, Reopen, Request exception | Close is lifecycle-significant but not equivalent to tenant- or run-level destructive action |
| TenantlessOperationRunViewer | Workspace operator | Inspect run state and understand whether follow-up exists | Monitoring detail viewer | What happened, what scope does it affect, and is any further action warranted? | Run identity, scope, outcome, freshness, follow-up availability | Related links, restore continuation, detailed failure reasons | execution outcome, freshness, lifecycle attention | Must remain explicit when a follow-up mutation is exposed | Refresh, Open related context | None by default on this surface |
| System ViewRun | Platform operator | Retry, cancel, or mark a run investigated | Platform decision surface | Which intervention is justified for this run, and how serious is it? | Run identity, current outcome, action availability, investigation need | Runbooks and related operational context | execution outcome, retryability, cancellation state | Must be explicit per action before execution | Retry, Mark investigated | Cancel |
| ViewTenant / EditTenant | Workspace operator | Archive or restore a tenant lifecycle state | Lifecycle detail/edit surface | Should this tenant remain active, or should its lifecycle state change formally? | Current lifecycle state and currently allowed lifecycle action | Supporting setup or external reference context | lifecycle readiness | TenantPilot only | Restore | Archive |
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no
- New persisted entity/table/artifact?: no
- New abstraction?: yes
- New enum/state/reason family?: yes
- New cross-domain UI framework/taxonomy?: yes
- Current operator problem: Operators currently infer governance severity from local page conventions instead of one stable product rule, which weakens safety and audit clarity.
- Existing structure is insufficient because: Surface-layout rules alone do not determine confirm depth, reason obligation, danger semantics, or canonical verb choice across panels.
- Narrowest correct implementation: Introduce one narrow derived governance-action catalog, friction classes, reason rules, a vocabulary canon, and documented exceptions. Do not add new workflow states, new persistence, or a generic execution framework.
- Ownership cost: Ongoing review of new governance actions against the matrix, lightweight documentation upkeep for exceptions, and focused regression tests.
- Alternative intentionally rejected: Purely local page cleanup was rejected because it would not stop the same governance family from drifting again on another surface.
- Release truth: current-release operator safety and semantic consistency
User Scenarios & Testing (mandatory)
User Story 1 - Make a Formal Exception Decision Safely (Priority: P1)
As a workspace approver, I want approving, rejecting, renewing, and revoking exception requests to use predictable friction and vocabulary so I can understand the seriousness of the action before I commit it.
Why this priority: Exception approval and exception lifecycle maintenance are the clearest governance decisions already spread across queue and detail surfaces.
Independent Test: This can be tested by reviewing the queue and exception detail surfaces alone and confirming that the same action family keeps the same confirm depth, reason expectation, and wording on both surfaces.
Acceptance Scenarios:
- Given a pending exception request on Finding Exceptions Queue, When the operator chooses approve or reject, Then the modal language, reason handling, and severity cues match the shared rule for formal exception decisions.
- Given an active exception on ViewFindingException, When the operator chooses renew or revoke, Then the page uses the same exception-family vocabulary and the stronger lifecycle action is clearly separated from the lighter one.
User Story 2 - Distinguish Governance Lifecycle from Technical Refresh (Priority: P1)
As a tenant reviewer, I want publication, archival, refresh, and evidence expiry actions to feel semantically distinct so I do not confuse a technical refresh with a formal governance decision.
Why this priority: Review and evidence surfaces already mix technical and governance-adjacent lifecycle actions, making them the highest-value place to harden semantics after exception handling.
Independent Test: This can be tested by reviewing ViewTenantReview and ViewEvidenceSnapshot without changing any other page and verifying that publish, archive, and expire semantics are clearly distinct from export or refresh.
Acceptance Scenarios:
- Given a mutable tenant review, When the operator compares Publish review, Export executive pack, and Archive review, Then publication and archival read as governance lifecycle steps while export remains clearly non-governance.
- Given an evidence snapshot that can still be expired, When the operator compares Refresh evidence and Expire snapshot, Then refresh reads as a lower-friction operational action and expiry reads as a governed lifecycle invalidation.
User Story 3 - Intervene on Runs with Calibrated Severity (Priority: P2)
As a platform operator, I want retry, cancel, and mark investigated to communicate different levels of seriousness so I can choose the right intervention without over- or under-reacting.
Why this priority: Run triage is a high-impact area where cancel and retry should never look like sibling actions with equivalent weight.
Independent Test: This can be tested entirely on run viewers by verifying that retry remains lighter, mark investigated captures rationale, and cancel is clearly the strongest action.
Acceptance Scenarios:
- Given a system run that can be retried or cancelled, When the header renders, Then Retry and Cancel are visibly differentiated by friction class and danger semantics.
- Given a run that needs explanation but not cancellation, When the operator marks it investigated, Then a reason is required and the action does not impersonate either retry or cancel semantics.
User Story 4 - Keep Tenant Lifecycle Clear Without Inflating All Actions (Priority: P3)
As a workspace operator, I want tenant archive and restore actions to be consistent across View and Edit surfaces without turning every lifecycle action into a maximal danger event.
Why this priority: Tenant lifecycle is an important medium-priority family that should be aligned once the highest-risk governance families are stabilized.
Independent Test: This can be tested by comparing ViewTenant and EditTenant and confirming that archive and restore keep the same vocabulary, confirm depth, and danger rules on both surfaces.
Acceptance Scenarios:
- Given an active tenant, When Archive is available on ViewTenant and EditTenant, Then the action uses the same wording, strong separation, and reason expectations on both surfaces.
- Given an archived tenant, When Restore is available, Then it remains clearly distinct from Archive and does not inherit unnecessary high-risk semantics.
Edge Cases
- If the same action family appears on a queue, a record page, and a system page, the surface type must not silently change the friction class.
- If a lower-risk operational action sits next to a formal governance action, the lower-risk action must not inherit danger styling or mandatory-reason burden just because of proximity.
- If a legacy surface exposes only one side of a canonical pair, the visible action still has to use the project-wide verb and friction rule for that family.
- If a structured form already captures required governance fields, the operator must still see a clear rationale prompt where the family rule requires explanation.
- If a future direct risk-acceptance surface is introduced, it must inherit the same vocabulary and reason rules currently carried by finding exception governance.
- If a surface does not genuinely own a governance mutation, it must not promote a navigation shortcut or export as if it were a formal decision action.
Requirements (mandatory)
Constitution alignment (required): This feature changes operator-facing governance semantics on existing write actions only. It introduces no new Microsoft Graph contract, no new queued workflow, and no new persistence. Existing mutations keep their current preview, confirmation, audit, and tenant-isolation rules; any DB-only governance mutation that does not create an OperationRun must continue to emit the existing audit trail.
Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001): This feature deliberately adds only the smallest semantic layer needed now: friction classes, reason rules, a vocabulary canon, and documented exceptions. It does not add a generic action framework, new domain states, or a persisted matrix table.
Constitution alignment (OPS-UX): Existing actions that already create or reuse OperationRun objects, such as review refresh, evidence refresh, verification, and run retry/cancel flows, keep the current Ops-UX contract: toast intent-only, progress in monitoring surfaces, terminal DB notification where applicable, and service-owned OperationRun.status / OperationRun.outcome transitions. Spec 194 harmonizes only semantics, not operation lifecycle mechanics.
Constitution alignment (RBAC-UX): The affected planes are tenant admin /admin/t/{tenant}, workspace admin /admin, and system /system. No cross-plane access is widened. Non-members or users lacking entitled scope remain 404, members missing capability remain 403, and every destructive-like action still requires confirmation plus server-side authorization through existing Policies, Gates, or capability-backed helpers. Regression coverage must include at least one positive and one negative authorization path across tenant, workspace, and system families touched by this spec.
Constitution alignment (OPS-EX-AUTH-001): Not applicable. This spec does not touch login handshakes or /auth/* routes.
Constitution alignment (BADGE-001): This spec does not introduce new badge domains. Danger, severity, and lifecycle emphasis must continue to derive from centralized badge or action semantics rather than page-local color language.
Constitution alignment (UI-FIL-001): UI changes remain on native Filament Action, ActionGroup, ViewRecord, ListRecords, and existing shared helpers such as UiEnforcement. The feature must avoid page-local button frameworks or ad-hoc border/color systems. Semantic emphasis is carried through action grouping, action color, confirmation depth, and copy, not custom markup.
Constitution alignment (UI-NAMING-001): Each governance family must preserve one domain-first verb across buttons, modal headings, required-reason prompts, notifications, run titles, and audit prose. The operator verb must describe the business effect, not an implementation step or storage concern.
Constitution alignment (DECIDE-001): The Decision-First Surface Role table above defines which surfaces are primary decision surfaces and which remain secondary context or evidence surfaces. The feature keeps one governance case decidable in one place and prevents secondary exports, navigation, or related links from competing with the actual decision moment.
Constitution alignment (UI-CONST-001 / UI-SURF-001 / ACTSURF-001 / UI-HARD-001 / UI-EX-001 / UI-REVIEW-001 / HDR-001): The UI/UX Surface Classification and Operator Surface Contract tables above define one inspect model per surface, the likely next operator action, placement for secondary and destructive actions, canonical nouns, scope signals, and any exception rationale. No affected surface may quietly mix navigation, review context, and governance mutation as undifferentiated peers.
Constitution alignment (ACTSURF-001 - action hierarchy): Navigation, mutation, selected-context actions, and dangerous actions must remain structurally separated. ActionGroup usage must be meaningful rather than a mixed catch-all, and any exception must be justified as a real workflow need, not a convenience shortcut.
Constitution alignment (OPSURF-001): Default-visible content stays operator-first. Diagnostics and raw evidence remain secondary. Mutating actions must disclose mutation scope before execution where the underlying action affects more than local UI state, and the safe-execution pattern for stronger actions remains visible through wording and confirmation structure.
Constitution alignment (UI-SEM-001 / LAYER-001 / TEST-TRUTH-001): This feature introduces semantic rules without adding a new presenter stack or persisted mirror. Domain truth remains in existing models and services; the new cross-cutting layer only governs action classification, operator copy, and friction consistency. Tests must verify business-visible consequences, not an indirection layer.
Constitution alignment (Filament Action Surfaces): The Action Surface Contract is expected to remain satisfied on all affected surfaces. Each surface must keep exactly one primary inspect/open model, no redundant View actions should be added, no empty ActionGroup placeholders may be introduced, and destructive actions must continue to use Action::make(...)->action(...)->requiresConfirmation(). No exemption is planned beyond existing context-only related-link groupings on already classified surfaces.
Constitution alignment (UX-001 - Layout & Information Architecture): Existing screen layouts, infolists, empty states, and table affordances remain intact. Spec 194 changes action semantics and grouping only; it does not justify converting infolists into disabled forms, removing list filters, or weakening empty-state clarity.
Design Principles
- Gleiches Risiko, gleiche Friction-Klasse: Actions mit vergleichbarer Governance-Bedeutung verwenden dieselbe Grundklasse, unabhaengig von Surface oder Panel.
- Danger ist semantisch, nicht dekorativ: Danger signalisiert Risiko, Irreversibilitaet oder starke Wirkung und ist kein allgemeiner Mutations-Akzent.
- Reason-Capture ist bewusst abgestuft: Nicht jede Mutation braucht eine Begruendung, aber formale Governance-Entscheidungen und starke Lifecycle-Eingriffe schon.
- Operator-Vokabular ist systemweit lesbar: Aehnliche Handlungen verwenden dieselben oder bewusst kompatiblen Verben.
- Friction wird nicht lokal improvisiert: Confirm, optionaler Grund, Pflichtgrund und Danger-Trennung werden nicht pro Surface neu erfunden.
- Cross-cutting schlaegt lokale Eleganz: Lokale Convenience rechtfertigt keine stille Governance-Ausnahme.
Friction Taxonomy
| Klasse | Bedeutung | Bestaetigung | Reason-Capture | Danger-Semantik | Typische Beispiele |
|---|---|---|---|---|---|
| F0 | Informational / Low Impact | keine zusaetzliche Friction | kein Grund | kein Danger | Open related record, Open approval queue, Export executive pack, Show all operations |
| F1 | Confirmed Operational Action | Bestaetigung erforderlich | kein Grund oder optional | nur wenn die Wirkung real riskant oder schwer reversibel ist | Refresh review, Refresh evidence, Retry run, Restore tenant |
| F2 | Explained Governance Action | Bestaetigung erforderlich | Grund erforderlich oder strukturiert eindeutig gefuehrt | abhaengig von Wirkung, aber immer semantisch klar | Approve exception, Reject exception, Renew exception, Publish review, Expire snapshot, Close finding, Reopen finding, Mark investigated |
| F3 | High-Risk / High-Impact Governance Action | strikte Bestaetigung | Grund zwingend | Danger zwingend und getrennte Platzierung | Revoke exception, Cancel run, Archive tenant, Archive review, kuenftige override- oder force-nahe Aktionen |
Eine action darf nur mit dokumentierter Ausnahme von ihrer Standardklasse abweichen.
Reason Capture Rules
- RL0 - none: F0 actions verlangen keinen Grund und duerfen keine kuenstliche Governance-Frage erzeugen.
- RL1 - optional: F1 actions duerfen einen optionalen Grund erlauben, wenn zusaetzlicher Kontext hilfreich ist, duerfen ihn aber nicht ohne dokumentierten Sonderfall verpflichtend machen.
- Current-release F1 decision: In dieser Release-Stufe verwenden
Refresh evidence,Retry, undRestoretrotz bestaetigter Ausfuehrung keinen zusaetzlichen Freitext-Grund. Optionale F1-Begruendung bleibt ausserhalb von Spec 194, bis ein dokumentierter Sonderfall sie wirklich braucht. - RL2 - required: F2 und F3 actions muessen eine explizite Begruendung oder eine gleichwertig strukturierte formale Erklaerung erfassen.
- Audit propagation: Jede verpflichtende oder eingegebene Begruendung muss in Audit-Prosa, Lifecycle-Historie oder Operation-Kontext wiederauffindbar sein, sofern die zugrunde liegende action heute auditierbar ist.
Vocabulary Canon
- Formale Entscheidungs-Paare verwenden Approve / Reject.
- Exception-Lifecycle verwendet Renew exception / Revoke exception.
- Risk-acceptance-Semantik verwendet, sobald sie direkt sichtbar ist, Accept risk / Renew acceptance / Revoke acceptance. Bis dahin tragen Finding Exception Surfaces diese Semantik stellvertretend.
- Review-Lifecycle verwendet Publish review / Archive review / Create next review.
- Evidence verwendet Refresh evidence fuer technische Regeneration und Expire snapshot fuer formale Invalidierung. Publish / Expire bleibt fuer einen spaeteren echten Veroeffentlichungs-Lifecycle reserviert und darf nicht als Synonym fuer technischen Refresh missbraucht werden.
- Finding-Lifecycle verwendet Close / Reopen.
- Tenant-Lifecycle verwendet Archive / Restore.
- Run-Triage verwendet Retry / Cancel / Mark investigated.
- Euphemismen oder unnoetig wechselnde Synonyme wie
Dismiss,Release,Reset, oderDeactivatesind fuer diese Familien nur mit dokumentierter Ausnahme zulaessig.
Functional Requirements
- FR-194-001 Governance inventory: Alle in Scope liegenden governance actions muessen in einer projektweiten inventory- und family-Sicht erfasst werden.
- FR-194-002 Exact classification: Jede inventarisierte governance action muss genau einer Friction-Klasse F0, F1, F2 oder F3 zugeordnet werden.
- FR-194-003 Family-first consistency: Gleichartige actions muessen in action families gebuendelt werden, damit die Klasse nicht still pro Surface neu definiert wird.
- FR-194-004 F0 rule: F0 actions duerfen weder Pflichtbestaetigung noch reason-capture noch danger-styling verwenden.
- FR-194-005 F1 rule: F1 actions verlangen Bestaetigung, aber standardmaessig keinen Pflichtgrund. Danger ist nur zulaessig, wenn die fachliche Wirkung tatsaechlich erhoehtes Risiko traegt.
- FR-194-006 F2 rule: F2 actions verlangen Bestaetigung und explizite Erklaerung. Die Operator-Entscheidung muss spaeter nachvollziehbar bleiben.
- FR-194-007 F3 rule: F3 actions verlangen Bestaetigung, Pflichtgrund, danger-styling und eine von Standardaktionen getrennte Platzierung.
- FR-194-008 Reason propagation: Fuer F2- und F3-actions muss die Begruendung im bestehenden Audit- oder Lifecycle-Nachweis wiederauftauchen. F1 darf keine stille Pflichtbegruendung einfuehren.
- FR-194-009 Danger discipline: Danger darf nicht inflationaer auf gewoehnliche Mutationen ausgedehnt werden. Hochwirksame und leichte Zustandsaenderungen muessen klar unterscheidbar bleiben.
- FR-194-010 Navigation separation: Navigation, Export, reine Kontextwechsel und harmlose registry-actions muessen von governance actions semantisch getrennt bleiben.
- FR-194-011 Exception decision family:
Approve exception,Reject exception,Renew exception, undRevoke exceptionmuessen als gemeinsame governance-family mit klaren Standardklassen und Gruenden behandelt werden. - FR-194-012 Review lifecycle family:
Publish review,Archive review, undCreate next reviewmuessen semantisch mit der review-lifecycle-Logik abgestimmt sein.Export executive packbleibt ausdruecklich ausserhalb dieser governance-friction. - FR-194-013 Evidence lifecycle family: Evidence lifecycle actions muessen zwischen technischem refresh und formaler invalidierung unterscheiden.
Refresh evidencedarf nicht wieExpire snapshotbehandelt werden. - FR-194-014 Run triage family:
Retry,Cancel, undMark investigatedmuessen projektweit als klar unterscheidbare run-triage-family behandelt werden, unabhaengig davon, auf welcher run-surface sie auftauchen. - FR-194-015 Finding lifecycle family:
CloseundReopenauf findings muessen dasselbe wording- und reason-Modell verwenden, auch wenn sie als header-, row-, oder bulk-action angeboten werden. - FR-194-016 Tenant lifecycle family:
ArchiveundRestoreauf ViewTenant und EditTenant muessen dieselbe confirm-, reason-, und danger-Logik verwenden. - FR-194-017 Risk acceptance continuity: Wo risk-acceptance-Semantik direkt oder indirekt sichtbar wird, darf sie keine konkurrierende lokale Vokabelfamilie erzeugen.
- FR-194-018 Mutation scope disclosure: Jede F2- oder F3-action muss den tatsaechlichen Wirkungsscope vor der Ausfuehrung in verstaendlicher Operator-Sprache kommunizieren.
- FR-194-019 Copy alignment: Button-Labels, modal-heading, modal-body, success-notification, audit-prosa und run-titel derselben family muessen dieselbe domain-Sprache verwenden.
- FR-194-020 No silent exceptions: Jede bewusste Abweichung von Standardklasse, reason-Regel oder Vokabular muss als dokumentierter Sonderfall markiert sein.
- FR-194-021 Regression gate: Neue governance actions duerfen nicht ohne Eintrag in die gemeinsame friction- und vocabulary-Matrix, dokumentierten reason-level und exception-status eingefuehrt werden.
- FR-194-022 Verification coverage: Browser smoke checks und gezielte page- oder action-Tests muessen die high-priority-families und den regression gate abdecken.
- FR-194-023 Authorization continuity: Keine alignment-Massnahme darf bestehende 404- oder 403-Semantik, capability checks oder deny-as-not-found-Verhalten veraendern.
- FR-194-024 Destructive action safety: Alle destruktiven oder destruktiv wirkenden governance actions muessen weiterhin ueber bestaetigte Filament execution-actions laufen und serverseitig autorisiert bleiben.
Governance Action Matrix
| Priority | Action | Primary Surfaces | Standard Friction | Reason Level | Danger Expectation | Vocabulary Default |
|---|---|---|---|---|---|---|
| High | Approve exception | Finding Exceptions Queue | F2 | required | no by default | Approve exception |
| High | Reject exception | Finding Exceptions Queue | F2 | required | visually distinct from approval, but not automatically F3 | Reject exception |
| High | Renew exception | ViewFindingException, related finding actions | F2 | required | no by default | Renew exception |
| High | Revoke exception | ViewFindingException, related finding actions | F3 | required | required | Revoke exception |
| High | Publish review | ViewTenantReview | F2 | required | no by default | Publish review |
| High | Archive review | ViewTenantReview | F3 | required | required | Archive review |
| High | Refresh evidence | ViewEvidenceSnapshot | F1 | none | no | Refresh evidence |
| High | Expire snapshot | ViewEvidenceSnapshot, ListEvidenceSnapshots | F2 | required | required | Expire snapshot |
| High | Retry run | System ViewRun and any future triage-owned admin run surface | F1 | none | no | Retry |
| High | Mark investigated | System ViewRun and any future triage-owned admin run surface | F2 | required | no by default | Mark investigated |
| High | Cancel run | System ViewRun and any future triage-owned admin run surface | F3 | required | required | Cancel |
| Medium | Close finding | ViewFinding, Finding resource actions | F2 | required | no by default | Close |
| Medium | Reopen finding | ViewFinding, Finding resource actions | F2 | required | no by default | Reopen |
| Medium | Archive tenant | ViewTenant, EditTenant | F3 | required | required | Archive |
| Medium | Restore tenant | ViewTenant, EditTenant | F1 | none | no | Restore |
| Low / no-op | Export executive pack | ViewTenantReview | F0 | none | no | Export executive pack |
| Low / no-op | Open queue, open related, show all, close details | Queue, detail, and monitoring surfaces | F0 | none | no | Use explicit navigation verbs only |
Target Outcomes by Key Surface
- Finding Exceptions Queue: Approval and rejection stop feeling like ad-hoc queue buttons and become one clearly governed decision family.
- ViewFindingException: Renewal and revocation read as lifecycle decisions with calibrated differences in severity.
- ViewEvidenceSnapshot: Refresh and expiry no longer blur together as generic snapshot mutations.
- ViewTenantReview: Publish, export, create-next, and archive become semantically distinct rather than one mixed lifecycle strip.
- TenantlessOperationRunViewer / System ViewRun: Run context stays separate from real intervention, while Retry, Cancel, and Mark investigated become legibly different actions wherever triage exists.
- ViewTenant / EditTenant: Archive and Restore stop drifting between view and edit variants and carry one shared tenant-lifecycle meaning.
Non-Goals
- Creating new governance states, enums, or persisted workflows beyond the friction and reason rules themselves
- Rewriting header placement rules already governed by Spec 192 and Spec 193
- Changing dispatch, provider-start, or preflight behavior for operations
- Replacing existing audit infrastructure with a new audit domain
- Renaming the product or introducing broad copy churn outside in-scope governance families
- Forcing calm non-governance surfaces into a new friction model they do not need
UI Action Matrix (mandatory when Filament is changed)
If this feature adds or modifies any Filament Resource, RelationManager, or Page, fill out the matrix below.
For each surface, list the exact action labels, whether they are destructive, RBAC gating, whether the mutation writes an audit log, and any exemption or exception used.
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Finding Exceptions Queue | app/Filament/Pages/Monitoring/FindingExceptionsQueue.php | Scope, return, clear filters, tenant register, Selected context, Review selected | Inspect exception slide-over stays the only inspect affordance |
Inspect exception |
none | Clear filters |
Approve exception, Reject exception, Close details, Open tenant detail, Open finding |
n/a | yes | Review actions move to one governed exception family; Action Surface Contract remains satisfied |
| ViewFindingException | app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php | n/a | n/a | n/a | n/a | n/a | Renew exception, Revoke exception |
n/a | yes | Renew is F2, revoke is F3; no redundant View action |
| ViewFinding | app/Filament/Resources/FindingResource/Pages/ViewFinding.php | Back to origin, related record, open approval queue, Actions group | Canonical record view page | none | Existing finding bulk actions remain family-aligned, not redefined here | n/a | Close, Reopen, Request exception, plus existing workflow actions |
n/a | yes | Request exception remains navigation into exception governance, not a synonym for approval |
| Evidence snapshots index + detail | app/Filament/Resources/EvidenceSnapshotResource.php and app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php | Index keeps inspection primary; detail keeps Refresh evidence and Expire snapshot |
recordUrl() clickable row on index |
Expire snapshot under More only |
none | Create first snapshot remains non-governance create CTA |
Refresh evidence, Expire snapshot |
n/a | yes | Refresh stays F1; Expire stays governed and danger-separated |
| ViewTenantReview | app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php | Primary lifecycle action, More, and Danger groups |
Canonical record view page | none | none | n/a | Refresh review, Publish review, Export executive pack, Create next review, Archive review |
n/a | yes | Publish and archive must not inherit export semantics |
| TenantlessOperationRunViewer | app/Filament/Pages/Operations/TenantlessOperationRunViewer.php | Scope, back, show all, refresh, Open, optional resume-capture follow-up | Canonical tenantless run detail page | none | none | n/a | Context-first follow-up actions only | n/a | existing run or audit trail | No new destructive triage is added here unless the surface genuinely owns it |
| System ViewRun | app/Filament/System/Pages/Ops/ViewRun.php | Show all operations, go to runbooks, retry, cancel, mark investigated | Canonical system run detail page | none | none | n/a | Retry, Cancel, Mark investigated |
n/a | yes | Retry F1, Mark investigated F2, Cancel F3 |
| ViewTenant / EditTenant | app/Filament/Resources/TenantResource/Pages/ViewTenant.php and app/Filament/Resources/TenantResource/Pages/EditTenant.php | View keeps external, setup, and lifecycle groups; edit keeps lifecycle group | Canonical workspace tenant view or edit page | none | none | n/a | Archive, Restore |
Edit page keeps standard save and cancel | yes | Archive and restore must remain one consistent tenant-lifecycle family across both surfaces |
Key Entities (include if feature involves data)
- Governance Action Family: A named group of semantically equivalent operator actions, defined by canonical verb, standard friction class, reason level, danger expectation, mutation scope wording, and allowed exceptions.
- Friction Class Assignment: The explicit mapping of one operator action to F0, F1, F2, or F3 together with the applicable reason rule and danger rule.
- Documented Exception: A reviewed deviation from the standard family rule, including the affected surface, the rationale, and why it cannot safely follow the default pattern.
Assumptions
- There is currently no standalone direct risk-acceptance page; finding exception governance carries the present risk-acceptance semantics.
- Workspace approval of finding exceptions remains the canonical entry point for formal exception decisions.
- TenantlessOperationRunViewer may stay context-first if it does not genuinely own retry, cancel, or investigated mutations.
- Existing audit and lifecycle services already persist or expose the necessary operator rationale where these actions are currently governed.
Dependencies
- Spec 192 for record-page header and navigation discipline
- Spec 193 for monitoring surface action hierarchy and workbench semantics
- Existing capability registry,
UiEnforcement, Policies, and deny-as-not-found semantics - Existing audit logging and operation triage or lifecycle services for review, evidence, findings, runs, and tenant lifecycle actions
Risks
- Zu viel Friction fuer harmlose actions: The product becomes slower than necessary. Mitigation: strict F0 and F1 separation and explicit non-goals.
- Zu wenig Friction fuer hochwirksame actions: High-risk governance intervention stays undertoned. Mitigation: F3 defaults are explicit and exceptions must be documented.
- Vocabulary wird kosmetisch statt semantisch behandelt: Labels change but severity logic does not. Mitigation: every vocabulary decision is coupled to family, friction, and reason rules.
- Cross-surface drift bleibt bestehen: The same action behaves differently on queue, detail, and system surfaces. Mitigation: regression gate and shared family matrix.
Recommended Sequencing
- Inventory all in-scope governance actions and assign them to action families.
- Align exception, review, and evidence families first because they contain the densest formal governance decisions.
- Align run triage and tenant lifecycle families next, preserving panel-specific authorization but removing semantic drift.
- Add regression protection and browser smoke coverage after the core families are normalized.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: 100% of in-scope governance actions on the remediated surfaces are listed in the shared inventory with action family, friction class, reason level, danger expectation, and exception status.
- SC-002: 100% of high-priority action families use one consistent confirm depth and one consistent vocabulary set across every covered surface where that family appears.
- SC-003: Browser smoke review of all remediated surfaces shows that every F3 action is visually and semantically distinct from nearby F0 or F1 actions, with no undocumented exceptions.
- SC-004: Positive and negative authorization checks continue to pass for at least one tenant-plane, one workspace-plane, and one system-plane governance family after the alignment.