24 KiB
Feature Specification: OperationRun Terminal Outcome Feedback v1
Feature Branch: 269-operationrun-terminal-outcome-feedback
Created: 2026-05-05
Status: Ready for implementation
Input: Manual promotion from docs/product/spec-candidates.md after repo-based verification against the current shell implementation, tests, and roadmap backlog.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: The tenant shell already shows recent terminal
OperationRunstates, but the current surface still collapses successful completion and unresolved follow-up into one generic terminal-update model. Terminal follow-up rows can still read like they are safely dismissible instead of clearly needing review. - Today's failure: A blocked, partial, or failed run can render with the same generic terminal banner framing and
Dismisssemantics as a no-action-needed success. That weakens the shell's decision-first promise because unresolved work can look like harmless noise. - User-visible improvement: Operators can immediately distinguish
done, no action neededfromcompleted, review still neededin the shell without opening Monitoring first. Successful terminal items stay briefly calm and dismissible, while unresolved follow-up states use explicit acknowledge or review wording. - Smallest enterprise-capable version: tighten the current tenant-shell activity hint only: keep active-state behavior intact, keep canonical links intact, split terminal success from terminal follow-up copy and tertiary actions, and keep acknowledgement browser-session-only.
- Explicit non-goals: no new activity tray, no dashboard active-operations card, no new
OperationRunlifecycle, no new progress contract, no notification-policy rewrite, no persisted acknowledgement state, and no new diagnostics surface. - Permanent complexity imported: one tighter shell-state contract, small copy or action branching in the existing shell helper or view, focused Feature plus browser proof, and one standards-document update.
- Why now: repo truth already includes the broader shell activity surface from Spec 268, and the next visible gap is no longer active-work feedback. It is terminal-outcome honesty on the same surface.
- Why not local: a one-line copy tweak would not encode the lifecycle-specific action contract, the
success vs follow-updistinction, or the durable UI guardrail that stops this seam from drifting again. - Approval class: Workflow Compression
- Red flags triggered: shared interaction family, shell-level operator surface
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 2 | Wiederverwendung: 1 | Gesamt: 11/12
- Decision: approve
Spec Scope Fields (mandatory)
- Scope: tenant
- Primary Routes:
/admin/t/{tenant}/...tenant-scoped start and work surfaces that host the shell activity hint/admin/operationsremains the canonical collection drill-through/admin/operations/{run}remains the canonical detail drill-through
- Data Ownership: existing tenant-owned
OperationRuntruth only; no new persisted projection, no new user preference store, and no new queue or notification state - RBAC: current
OperationRunpolicies remain authoritative. Non-members or out-of-scope tenant contexts stay deny-as-not-found (404semantics through current tenant/admin boundaries). In-scope actors only see terminal states they can already view through the canonical Operations routes.
Cross-Cutting / Shared Pattern Reuse (mandatory)
- Cross-cutting feature?: yes
- Interaction class(es): shell status messaging, navigation links, lifecycle-sensitive tertiary actions
- Systems touched:
BulkOperationProgress,OperationUxPresenter,OperationStatusNormalizer,OperationRunProgressContract,ActiveRuns,OperationRunLinks,OperationRunUrl,OpsUxBrowserEvents, anddocs/ui/tenantpilot-enterprise-ui-standards.md - Existing pattern(s) to extend: current shell activity feedback, canonical
View operationandShow all operationslinks, current progress-contract enforcement, and browser-session collapse behavior - Shared contract / presenter / builder / renderer to reuse:
App\Support\OpsUx\OperationUxPresenter,App\Support\OpsUx\OperationStatusNormalizer,App\Support\OpsUx\OperationRunProgressContract,App\Support\OpsUx\OperationRunUrl,App\Support\OpsUx\ActiveRuns,App\Support\OpsUx\OpsUxBrowserEvents, andApp\Support\OperationRunLinks - Why the existing shared path is sufficient or insufficient: the repo already owns truthful link, status, and progress semantics. What remains open is a narrower shell-level terminal-outcome contract, not a new framework.
- Allowed deviation and why: none planned. Keep the refinement local to the existing shell component and its helpers.
- Consistency impact:
Hide activity,DismissorClose,Acknowledge,View operation, groupedReview operations, and the banner helper copy must describe active, successful, and unresolved follow-up states consistently across Feature proof, browser smoke, and the standards document.Review operationsis the grouped label variant of the same canonical collection link also exposed asShow all operations, not a second collection action. - Review focus: verify that unresolved follow-up no longer inherits generic dismiss semantics, that terminal success stays no-action-needed, and that the shell still uses canonical links with no new lifecycle or persistence.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: yes
- Shared OperationRun UX contract/layer reused: existing Ops-UX shell contract through
OperationUxPresenter,OperationRunUrl,OperationRunLinks,OperationRunProgressContract, andOpsUxBrowserEvents - Delegated start/completion UX behaviors: current queued-toast wording, canonical Operations links, current browser event contract, and existing terminal DB-notification lifecycle remain delegated to the shared path
- Local surface-owned behavior that remains: terminal success vs follow-up copy, lifecycle-sensitive tertiary action wording, and browser-session-only acknowledge or dismiss behavior on the shell host
- Queued DB-notification policy:
N/A- unchanged - Terminal notification path: unchanged central lifecycle mechanism
- Exception required?: none
Provider Boundary / Platform Core Check (mandatory)
N/A - no shared provider or platform-core seam changes. The slice only tightens shell semantics over existing platform-owned OperationRun truth.
UI / Surface Guardrail Impact (mandatory)
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Tenant shell activity hint | yes | Native Filament + existing Livewire/Blade shell surface | Ops UX lifecycle feedback, canonical run links, browser-session calmness | shell, page, browser-session | no | Tightens terminal outcome semantics only; no new surface family |
Decision-First Surface Role (mandatory)
| 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 |
|---|---|---|---|---|---|---|---|
| Tenant shell activity hint | Primary Decision Surface | Decide whether the most recent terminal outcome needs no action, acknowledgement, or immediate review | Operation label, lifecycle state, terminal recency, one next-step cue, and one canonical primary action | Full diagnostics, logs, payloads, and evidence stay in Operations collection/detail | Primary because this is the post-start and post-completion surface where operators decide whether to keep working or inspect a run | Follows start-surface workflow, not diagnostics-page storage structure | Prevents unresolved follow-up from blending into harmless completion noise |
Audience-Aware Disclosure (mandatory)
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Tenant shell activity hint | operator-MSP | Operation label, terminal success or follow-up state, short recency line, concise next-step cue, and canonical primary action | Detailed failure context, run history, and full outcome diagnostics remain on Operations pages | Raw payloads, log details, and support-only evidence stay off the shell | View operation for one visible item or Review operations when unresolved follow-up is mixed or grouped |
Raw and support detail stay diagnostics-only; acknowledge stays browser-session-only | The shell states the next decision once and does not restate full Monitoring prose |
UI/UX Surface Classification (mandatory)
| 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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Tenant shell activity hint | Monitoring hint | Activity shell hint | Decide whether to review a just-finished run or keep working | One explicit View operation or grouped Review operations action |
forbidden | One grouped overflow path to Show all operations plus one lifecycle-sensitive tertiary action |
none | /admin/operations in current tenant context |
/admin/operations/{run} in current tenant context |
Current tenant shell context | Operations / Operation | Terminal success vs unresolved follow-up, recency, and the next action | none |
Operator Surface Contract (mandatory)
| 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 |
|---|---|---|---|---|---|---|---|---|---|---|
| Tenant shell activity hint | Tenant operator | Decide whether a recent terminal outcome is safely complete or still needs review | Start-surface shell hint | Does this run need anything from me now? | Operation label, terminal outcome, recency, concise guidance, and canonical open or review action | Operations detail, logs, and evidence | lifecycle, follow-up-needed, progress-availability | none | View operation, Review operations, Show all operations |
none |
UI Action Matrix: N/A - no Filament Resource, RelationManager, or Page action matrix changes are introduced. The shell hint remains a widget-level monitoring hint with one dominant navigation action and one browser-session tertiary affordance.
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no
- New persisted entity/table/artifact?: no
- New abstraction?: no
- New enum/state/reason family?: no
- New cross-domain UI framework/taxonomy?: no
- Current operator problem: terminal follow-up still inherits generic dismiss semantics on the shell, which blurs
review neededwithdone, no action needed. - Existing structure is insufficient because: the current shell already has terminal rows, but its copy and tertiary action rules are still too broad to encode lifecycle-correct operator decisions.
- Narrowest correct implementation: refine the existing shell component, helper text, and browser-session tertiary actions only, then document the rule in the standards file.
- Ownership cost: small shell branching plus focused Feature and browser coverage.
- Alternative intentionally rejected: a copy-only tweak was rejected because it would not define the durable
success vs follow-upaction contract or stop future regression. - Release truth: current-release truth. The repo already ships the shell activity surface; this slice only hardens its terminal semantics.
Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.
Canonical replacement is preferred over preservation.
Testing / Lane / Runtime Impact (mandatory)
- Test purpose / classification: Feature plus one required browser smoke for the shell action and overlap contract
- Validation lane(s): fast-feedback, confidence, browser
- Why this classification and these lanes are sufficient: Feature coverage proves the lifecycle-specific terminal copy, tertiary actions, and browser-session-only acknowledgement semantics on the current shell host. The browser smoke is the narrowest credible proof that the tightened terminal actions stay reachable without reintroducing obstruction.
- New or expanded test families: extend
apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php, extendapps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php, and extendapps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php - Fixture / helper cost impact: low to moderate. Reuse current
OperationRunfactories, tenant helpers, and shell smoke helpers; do not add provider-heavy setup or persisted acknowledgement fixtures. - Heavy-family visibility / justification: no heavy-governance family. The browser proof stays explicit and bounded to the shell overlap plus action-label contract.
- Special surface test profile: global-context-shell
- Standard-native relief or required special coverage: standard Feature coverage is primary; one browser smoke remains required for live shell interaction
- Reviewer handoff: reviewers must confirm that successful terminal items stay dismissible, unresolved follow-up uses acknowledge or review semantics, terminal rows never show progressbars, and the shell still reopens on new run-enqueue events.
- Budget / baseline / trend impact: small feature-local increase only
- Escalation needed:
reject-or-splitif implementation widens into dashboard cards, new notification policy, new persistence, or a secondOperationRunlifecycle surface - Active feature PR close-out entry: Guardrail / Smoke Coverage
- Planned validation commands:
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.phpexport PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php
User Scenarios & Testing (mandatory)
User Story 1 - Terminal Success Feels Complete, Not Risky (Priority: P1)
As a tenant operator, I need successful terminal runs to stay briefly visible with calm success semantics, so I can see that work finished and dismiss it without confusing it with unresolved follow-up.
Why this priority: post-completion trust is the first decision point after work finishes, and it should stay explicitly no-action-needed.
Independent Test: seed one recently completed successful run, open a tenant-scoped shell surface, and verify the shell shows success-specific copy, no active progress UI, and Dismiss or Close semantics during the current 30-second shell-visible success window preserved by ActiveRuns.
Acceptance Scenarios:
- Given a run completes successfully, When the shell refreshes during the current 30-second terminal-success grace window from
ActiveRuns::shellVisibleQueryForTenantId(), Then the shell shows success-specific copy, keepsView operationas the canonical primary action, and usesDismissorCloseas the tertiary action. - Given a recent successful terminal item is visible, When the shell renders it, Then it does not show a determinate or indeterminate progress bar.
User Story 2 - Terminal Follow-Up Stays Explicitly Reviewable (Priority: P1)
As a tenant operator, I need unresolved terminal runs to stay clearly review-worthy on the shell, so I do not treat a failed or partial outcome as safely dismissible noise.
Why this priority: unresolved terminal outcomes are the real decision risk in the current shell semantics.
Independent Test: seed one failed, partial, or blocked terminal run, open a tenant-scoped shell surface, and verify the shell shows follow-up-specific copy, canonical review or detail navigation, and Acknowledge instead of generic dismiss semantics.
Acceptance Scenarios:
- Given a run completes with a follow-up-needed outcome, When the shell refreshes, Then the shell keeps the run visible with follow-up-specific guidance and uses
Acknowledgeas the local tertiary action. - Given both active work and unresolved terminal follow-up are visible, When the shell chooses its grouped primary action, Then the grouped action favors review-oriented wording over no-action-needed success wording.
- Given a terminal follow-up item is visible, When the shell renders it, Then it does not show active-progress UI and does not use
Dismissas the tertiary label.
User Story 3 - Acknowledge Stays Browser-Session Only (Priority: P1)
As a tenant operator, I need terminal follow-up acknowledgement to stay local to my current browser session, so the shell can stay calm without inventing a server-side review state.
Why this priority: the slice must remain a presentation refinement, not a new workflow system.
Independent Test: acknowledge an unresolved terminal item in the current browser session, then trigger a new run-enqueued event and verify the shell reopens without any database-backed acknowledgement state.
Acceptance Scenarios:
- Given an unresolved terminal item is visible, When the operator clicks
Acknowledge, Then the shell hides that item only for the current browser session. - Given the shell is hidden or acknowledged in the current browser session, When a new run is enqueued for the current tenant, Then the shell reopens so the operator does not miss new work.
Edge Cases
- Successful terminal items must not overwrite unresolved follow-up emphasis when both types are visible in the same shell state.
- Unresolved terminal follow-up must not inherit generic
Dismiss updatescopy when the shell shows a grouped primary action. - Terminal outcome items must not reintroduce progressbars, indeterminate bars, or fake percentages after completion.
- No tenant context or no
viewAny OperationRuncapability keeps the shell inert and leak-free. - Browser-session acknowledgement must not mutate the
OperationRunrecord or persist across new browser sessions. - The current 30-second terminal-success grace window from
ActiveRuns::shellVisibleQueryForTenantId()remains the source of truth unless a later spec deliberately changes it.
Requirements (mandatory)
Constitution alignment summary: This feature adds no Graph calls, no new write path, no new OperationRun lifecycle, no new notification policy, and no new persistence. It reuses the current shell activity surface, current progress contract, current canonical links, and current browser-session event flow.
Functional Requirements
- FR-001: The shell MUST continue deriving terminal outcome presentation from existing
OperationRuntruth and current shared helpers. It MUST NOT create a second lifecycle, status taxonomy, or persisted shell state. - FR-002: Recent successful terminal items MUST use success-specific shell copy and a no-action-needed posture, keep canonical Operations navigation, and use
DismissorCloseas the browser-session tertiary action during the current 30-second terminal-success grace window preserved inActiveRuns::shellVisibleQueryForTenantId(). - FR-003: Unresolved terminal follow-up items that still require operator review MUST use follow-up-specific shell copy and
Acknowledgeas the browser-session tertiary action. They MUST NOT reuse generic dismiss semantics. - FR-004: Mixed shell states that include unresolved terminal follow-up MUST preserve review-oriented emphasis in grouped helper copy and primary action wording. Successful completion MUST NOT dominate unresolved follow-up messaging.
- FR-005: Terminal success and terminal follow-up items MUST NOT render determinate or indeterminate progress UI after completion.
- FR-006: Canonical
View operation, groupedReview operations, andShow all operationslinks MUST remain helper-generated through the existing shared path.Review operationsis only the grouped label variant of the canonical collection link. The slice MUST NOT introduce raw route strings. - FR-007: Browser-session
Hide activity,DismissorClose, andAcknowledgebehavior MUST remain browser-session-only. The implementation MUST NOT persist acknowledgement or dismiss state on theOperationRunrecord or in a new table. - FR-008: A new accepted run in the current browser session MUST reopen the shell if it was previously hidden or acknowledged locally.
- FR-009:
docs/ui/tenantpilot-enterprise-ui-standards.mdMUST record the terminal outcome contract for the shell activity hint, including the difference between success dismissal and follow-up acknowledgement semantics.
Authorization and Safety Requirements
- AR-001: Current tenant/admin-plane authorization semantics remain unchanged: out-of-scope tenant access stays deny-as-not-found (
404semantics) and in-scope visibility continues to reuse server-sideOperationRunpolicies. - AR-002: No shell state in this slice may expose a run the actor cannot already reach through the canonical Operations routes.
- AR-003: No destructive or mutating action is introduced. Acknowledge and dismiss are browser-session-only presentation controls.
Non-Functional Requirements
- NFR-001: Filament remains v5 on Livewire v4. No panel-provider registration change is allowed, and
apps/platform/bootstrap/providers.phpremains authoritative. - NFR-002: No new panel, no new globally searchable resource, and no new asset registration strategy are allowed.
- NFR-003: Polling remains bounded to the current shell host. The slice MUST NOT add a second polling loop or a second active-awareness host surface.
- NFR-004: Existing progress-contract and badge semantics remain authoritative. No page-local terminal-status color mapping or progress heuristics may be introduced.
Deferred Follow-Ups / Explicit Non-Goals
- Tenant dashboard active-operations summary card
- New
OperationRunprogress-contract or counted-progress rollout work - Phase or composite progress modeling
- A persisted reviewed, investigated, or acknowledged state over terminal follow-up
- Activity tray or inbox v2
- Notification-policy changes for queued or terminal lifecycle events
Key Entities
- Terminal success shell item: a derived, non-persisted shell item for a recently completed successful run that stays briefly visible, conveys no-action-needed completion, and remains locally dismissible.
- Terminal follow-up shell item: a derived, non-persisted shell item for a terminal run that still needs operator review and therefore uses acknowledge or review semantics instead of generic dismissal.
- Browser-session terminal-outcome state: non-persisted shell-level state that remembers local hide, dismiss, and acknowledge choices only for the current browser session.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Focused Feature proof shows a recent successful terminal item with success-specific copy, no active-progress UI, and
DismissorClosesemantics. - SC-002: Focused Feature proof shows an unresolved terminal follow-up item with review-specific copy and
Acknowledgesemantics instead of generic dismiss wording. - SC-003: Focused Feature proof shows mixed active-plus-follow-up shell states keeping follow-up emphasis in grouped helper copy and grouped primary action wording.
- SC-004: The named browser smoke continues to prove that the shell actions remain reachable, collapse or acknowledge behavior stays browser-session-only, and new run-enqueue events reopen the shell.