30 KiB
Feature Specification: OperationRun Activity Feedback v1
Feature Branch: 268-operationrun-activity-feedback
Created: 2026-05-03
Status: Ready for implementation
Input: Manual promotion from docs/product/spec-candidates.md after the 2026-05-03 repo-based next-best-prep re-audit.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem:
OperationRunis already the repo-real execution truth, but the current tenant-shell activity hint drops the feedback loop as soon as work becomes terminal, so operators can see work running and then lose the confirmation/follow-up state immediately. - Today's failure: Operators can queue work and still get feedback that can cover primary actions. Once a run finishes, the current
BulkOperationProgressshell widget disappears immediately and does not provide a short terminal-success confirmation or an explicit unresolved follow-up state in the same surface. - User-visible improvement: Operators get one calm, truthful activity hint on tenant-scoped start surfaces, with at most three visible items, canonical
View operationlinks, honest progress treatment, a brief terminal-success confirmation, and unresolved terminal follow-up states that do not disappear silently. - Smallest enterprise-capable version: refactor the current tenant-shell activity hint to align with the existing Ops-UX 3-surface contract, add a bounded terminal-success/follow-up phase to the same surface, and update the UI standards so future hosts do not drift.
- Explicit non-goals: no activity tray v2, no DB-backed hide preferences, no new
OperationRuntypes or status families, no notification lifecycle rewrite, no permanent terminal inbox, and no host-widget migration beyond the current global activity widget. - Permanent complexity imported: no new persisted model; one browser-session rule set for active hide plus terminal dismiss/acknowledge affordances, focused Pest/browser coverage, one standards-document addition, and only a tiny local helper if the existing shell component cannot stay readable without it.
- Why now: the overlap bug is already verified, and the constitution already defines a non-negotiable three-surface contract for
OperationRun. The shell hint needs to align before more local run snippets drift from that contract. - Why not local: a pure CSS tweak would not encode the terminal feedback-loop, honest-progress, canonical-link, and calmness rules in either the implementation or the standards guidance.
- Approval class: Workflow Compression
- Red flags triggered: shared interaction family, shell-level surface, session-local UI state
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve
Spec Scope Fields (mandatory)
- Scope: tenant
- Primary Routes:
/admin/t/{tenant}/...tenant-scoped start surfaces that currently receive the shared activity hint from the tenant-panel shell/admin/operationsand/admin/operations/{run}remain the diagnostics drill-through targets and canonical collection/detail routes; shell overflow opens/admin/operationswith the selected tenant as a contextualtenant_idprefilter, and that query-param prefilter wins over session/default state on initial mount
- Data Ownership: existing
OperationRuntruth with tenant-bound operational ownership semantics enforced through workspace + tenant entitlement checks; the current nullable-tenant exception remains limited to canonical workspace-context monitoring views; no new persisted projection or preference store - RBAC: existing
OperationRunpolicies remain authoritative. Non-members or out-of-scope tenant contexts remain hidden (404semantics through the current tenant/admin boundaries); in-scope actors only see hints for runs they can already view.
Cross-Cutting / Shared Pattern Reuse (mandatory)
- Cross-cutting feature?: yes
- Interaction class(es): status messaging, navigation links, shell active-awareness hints
- Systems touched:
BulkOperationProgress, tenant-panel render-hook shell feedback, canonical run links, current queued toasts, current activity poller, UI standards - Existing pattern(s) to extend:
OperationUxPresenter,OperationStatusNormalizer,OperationRunLinks,OperationRunUrl,ActiveRuns,OpsUxBrowserEvents, current active-ops shell widget - Shared contract / presenter / builder / renderer to reuse:
App\Support\OpsUx\OperationUxPresenter,App\Support\OpsUx\OperationStatusNormalizer,App\Support\OperationRunLinks,App\Support\OpsUx\OperationRunUrl,App\Support\OpsUx\ActiveRuns,apps/platform/resources/views/livewire/bulk-operation-progress.blade.php - Why the existing shared path is sufficient or insufficient: the repo already has truthful run-state, guidance, badge, and link semantics. What is missing is a constitution-aligned implementation of the shell contract: honest progress while active, a bounded terminal-success/follow-up handoff, canonical links, and non-obstructive placement.
- Allowed deviation and why: none by default. Keep the refactor local to the current shell component and its views; only extract a tiny helper if the existing component cannot remain readable otherwise.
- Consistency impact:
View operationwording, overflow/Show all operationsaffordances, progressbar eligibility, lifecycle-sensitive tertiary action labels, bounded terminal success/follow-up visibility, and browser-session hide/dismiss/acknowledge behavior must stay aligned with the Ops-UX constitution and the standards doc. - Review focus: verify that the shell keeps queued/running truth, shows only bounded terminal-success/follow-up states, never shows fake progress after completion, introduces no raw route strings, and remains non-obstructive.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: yes
- Shared OperationRun UX contract/layer reused: current Ops-UX start contract through
OperationUxPresenter,OperationRunLinks,OperationRunUrl,OpsUxBrowserEvents, and current DB-notification lifecycle - Delegated start/completion UX behaviors: current queued toast wording, canonical
View operationlink generation, tenant-safe URL resolution, currentrun-enqueuedbrowser event, and existing terminal DB-notification lifecycle all remain delegated to the shared path - Local surface-owned behavior that remains: the shell surface owns bounded layout, recent terminal-success/follow-up visibility, and browser-session hide/dismiss/acknowledge affordances only; it does not own lifecycle truth, severity mapping, or run-link routing
- Queued DB-notification policy:
N/A- unchanged, explicit opt-in policy remains as-is - Terminal notification path: unchanged central lifecycle mechanism
- Exception required?: none
Provider Boundary / Platform Core Check (mandatory)
- Shared provider/platform boundary touched?: no
- Boundary classification:
N/A - Seams affected:
N/A - Neutral platform terms preserved or introduced:
Operation,View operation,Show all operations,queued,running,active - Provider-specific semantics retained and why: none
- Why this does not deepen provider coupling accidentally: the feature only reshapes execution feedback over existing platform-owned
OperationRuntruth and current link helpers - Follow-up path: none
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 surface | Ops UX start feedback, terminal handoff, canonical run links | shell, page, browser-session | no | Must stop covering primary actions on row-action-heavy pages and must keep terminal success/follow-up bounded |
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 an active or just-finished operation needs immediate inspection or no further action | Operation label, lifecycle state, one next-step cue, View operation, progress only when valid, and brief terminal confirmation/follow-up |
Full run detail, logs, evidence, diagnostics stay in Operations pages | Primary because it appears immediately after a start action and must support the next operator decision without opening Monitoring first | Follows start-surface workflow, not storage structure | Replaces a floating overlay and closes the feedback loop without turning the shell into a monitoring page |
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, queued/running state, recent terminal-success/follow-up state, elapsed or completion age, canonical open link, honest progress if valid | One concise guidance line only when it clarifies the next step | Raw payloads, failure summaries, logs, debug context | View operation |
Raw/support detail stays in Operations detail; browser-session hide/dismiss/acknowledge remains local to the shell | The hint states only what is needed for the next decision and does not restate diagnostics-first detail 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 | Open the most relevant active or just-finished operation | One explicit View operation link per item |
forbidden | Overflow navigation only (Show all operations) plus one lifecycle-sensitive tertiary affordance on the grouped action row |
none | /admin/operations?tenant_id={currentTenant} as a contextual prefilter on initial mount |
/admin/operations/{run} with current tenant context |
Current tenant context from the selected tenant shell | Operations / Operation | Queued/running state, completion/follow-up state, elapsed/completion age, valid progress only while active | 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 queued/running or just-completed operation needs inspection, acknowledgement, or no action | Start-surface hint | What operation state do I need to react to right now? | Operation label, lifecycle state, elapsed/completion age, canonical open link, valid progress only while active | Detailed run diagnostics and evidence on Operations pages | lifecycle, progress-availability | none | View operation, Show all operations, lifecycle-sensitive tertiary affordance when needed |
none |
UI Action Matrix: N/A - no Filament Resource, RelationManager, or Page action surface is being introduced or reclassified. The changed surface remains a shell/widget hint with one dominant navigation action and no destructive controls.
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no
- New persisted entity/table/artifact?: no
- New abstraction?: no by default
- New enum/state/reason family?: no
- New cross-domain UI framework/taxonomy?: no
- Current operator problem: queued/running operations do not have one calm, constitution-aligned shell contract today, and the current overlay both blocks primary actions and drops the completion/follow-up loop immediately.
- Existing structure is insufficient because: the repo already centralizes links, badges, and guidance semantics, but the current shell implementation does not enforce bounded terminal handoff, honest post-completion semantics, or non-obstructive placement clearly.
- Narrowest correct implementation: refactor the existing shell component and views locally, keep
OperationRuntruth authoritative, add a brief terminal-success/follow-up phase plus browser-session hide/dismiss/acknowledge behavior, and update the standards doc. - Ownership cost: one browser-session state rule set, focused Feature/browser coverage, and a standards-doc update.
- Alternative intentionally rejected: a shell-only CSS adjustment was rejected because it would not encode the active-only, honest-progress, and canonical-link rules or leave a durable guardrail for future hosts.
- Release truth: current-release truth. The repo already owns the active-ops widget and the Ops-UX constitution; this slice aligns the current shell to that truth.
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 non-obstructive shell contract
- Validation lane(s): fast-feedback, confidence, browser
- Why this classification and these lanes are sufficient: the real contract is shell behavior on the existing Livewire/Filament host. Feature tests prove active plus bounded terminal selection, links, progress rules, and lifecycle-sensitive tertiary copy; one browser smoke is the narrowest credible proof that the shell remains non-obstructive.
- New or expanded test families: extend
apps/platform/tests/Feature/OpsUx/, extendapps/platform/tests/Feature/Guards/OperationRunLinkContractGuardTest.php, and add one named browser smoke - Fixture / helper cost impact: low to moderate. Reuse existing operation-run factories, tenant context helpers, and current Livewire widget tests; do not add provider-heavy browser setup or new default seeds.
- Heavy-family visibility / justification: no heavy-governance lane. Browser proof is explicit and limited to the overlap/non-obstruction contract.
- Special surface test profile: global-context-shell
- Standard-native relief or required special coverage: standard Feature coverage is primary; one browser smoke is required for the row-action overlap contract
- Reviewer handoff: reviewers must confirm the shell routes through canonical link helpers, shows no fake percentage or percentage text, keeps successful completion visible briefly, does not silently drop follow-up failures, and passes the named browser smoke.
- Budget / baseline / trend impact: small feature-local increase only
- Escalation needed:
reject-or-splitif implementation expands into tray v2, notification lifecycle changes, or a new persisted hide/acknowledgement model - 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/BulkOperationProgressDbOnlyTest.php tests/Feature/OpsUx/ProgressWidgetOverflowTest.php tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php tests/Feature/Guards/OperationRunLinkContractGuardTest.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 - See Calm Active-Operations Feedback After Starting Work (Priority: P1)
As a tenant operator, I need the shell-level active-ops hint to surface the most relevant queued/running operations without covering page actions, so I can decide whether to inspect a run immediately or keep working.
Why this priority: this is the direct fix for the known overlap seam and the most valuable current-release improvement.
Independent Test: create queued/running runs for a tenant, open a tenant-scoped start surface, and verify the shell hint shows at most three active items, preserves one canonical View operation link per item, and remains non-obstructive.
Acceptance Scenarios:
- Given a tenant has queued and running runs, When the operator opens a tenant-scoped start surface, Then the shell hint shows at most three active items with one canonical
View operationlink each and an overflow path toShow all operations. - Given a row-action-heavy page is visible while the shell hint is active, When the operator targets a primary page action, Then the activity hint does not cover or block that action.
- Given an active item needs brief context for the next decision, When the shell hint renders it, Then it may show at most one concise next-step cue and does not expand into diagnostics prose.
User Story 2 - Keep The Feedback Loop Honest Across Terminal Transitions (Priority: P1)
As a tenant operator, I need the shell hint to stay honest when work becomes terminal, so I see a brief success confirmation or an unresolved follow-up state in the same surface instead of losing the feedback loop immediately.
Why this priority: the overlap fix is not sufficient unless the shell also completes the run-state feedback loop without inventing a second lifecycle surface.
Independent Test: seed queued/running runs alongside just-completed successful runs and terminal follow-up runs, open a tenant-scoped start surface, and verify the shell keeps recent success visible briefly, keeps unresolved follow-up visible, and never shows fake progress after completion.
Acceptance Scenarios:
- Given a queued/running run transitions to successful completion, When the shell hint refreshes shortly afterward, Then it keeps that run visible briefly with a terminal-success state,
View operation,Show all operations, and aDismissorClosetertiary affordance. - Given a queued/running run transitions to blocked, partial, failed, or reconciled terminal follow-up, When the shell hint refreshes, Then it keeps that follow-up visible instead of dropping it silently and uses a lifecycle-appropriate tertiary affordance such as
Acknowledge. - Given a run exposes deterministic progress counts while active, When the shell hint renders that run, Then it may show clamped determinate progress, and When the run becomes terminal, Then it switches to terminal state copy instead of showing fake progress after completion.
User Story 3 - Keep Hide / Dismiss / Acknowledge Browser-Session Only (Priority: P1)
As a tenant operator, I need queued/running, successful, and unresolved terminal hints to use the right local-only affordance for the current browser session, so the activity surface stays calm without inventing a server-side acknowledgement system.
Why this priority: it is the smallest safe calmness control that keeps lifecycle semantics explicit while staying within the existing Ops-UX contract.
Independent Test: open a tenant-scoped start surface with active and terminal items, use the lifecycle-sensitive tertiary affordances, and verify active items use Hide activity, successful terminal items use Dismiss/Close, unresolved terminal items use Acknowledge, and all of those controls remain browser-session-only.
Acceptance Scenarios:
- Given queued/running items are visible, When the operator uses the tertiary affordance, Then it is labeled
Hide activityand the current browser session remembers that choice without creating any database-backed preference. - Given only recent successful terminal items are visible, When the operator uses the tertiary affordance, Then it is labeled
DismissorCloseand the shell hint may also auto-dismiss after the short terminal-success grace window. - Given only unresolved terminal follow-up items are visible, When the operator uses the tertiary affordance, Then it is labeled
Acknowledgeand remains browser-session-only instead of persisting on theOperationRunrecord. - Given the shell hint is hidden and a new run is accepted in the current browser session, When the shared
run-enqueuedevent fires, Then the shell hint reappears so the operator does not miss newly started work.
Edge Cases
- No selected tenant or no
viewAny OperationRuncapability means the shell hint stays inert and does not poll or leak rows. - More than three qualifying shell-visible rows must produce deterministic ordering and an overflow path that routes through the canonical collection helper.
- Just-completed successful runs remain visible only for the short terminal-success grace window and never keep an active progressbar after completion.
- Terminal follow-up runs (
blocked,partial,failed, reconciled terminal failures) must not auto-disappear silently from the shell immediately after transition, even though the canonical dashboard/Operations follow-up surfaces remain authoritative. - The shell hint must not introduce raw route strings; all run detail/collection links continue to flow through the canonical helper family.
- Browser-session hide, dismiss, or acknowledge state must not persist across browser sessions or mutate the
OperationRunrecord.
Requirements (mandatory)
Constitution alignment summary: This feature adds no Graph calls, no new write path, no new OperationRun lifecycle state, and no new persistence. It reuses the existing Ops-UX start contract, keeps OperationRun.status / OperationRun.outcome service-owned, leaves terminal DB notifications unchanged, and narrows the current global active-ops shell widget to the constitution-safe active-awareness contract.
Functional Requirements
- FR-001: The implementation MUST derive shell activity items from existing
OperationRuntruth plus current shared helpers such asOperationUxPresenter,OperationStatusNormalizer,OperationRunLinks, and badge semantics. It MUST NOT create a second lifecycle, severity model, or persisted projection. - FR-002: The tenant shell activity hint MUST always surface current active runs (
queued|running) for the current tenant from existingOperationRuntruth. - FR-003: When a queued/running run transitions to successful completion, the shell hint MUST keep a compact terminal-success state visible briefly in the same surface instead of removing it immediately.
- FR-004: The terminal-success state MUST show the operation label, a success pill such as
Completed successfully, a completion-recency line, concise no-action-needed guidance, canonicalView operationandShow all operationslinks, and a tertiaryDismissorCloseaffordance. It MUST NOT show fake active progress after completion. - FR-005: Blocked, partial, failed, and reconciled terminal follow-up runs MUST NOT auto-disappear silently from the shell immediately after transition. The shell hint MUST keep them visible on the existing surface until they are acknowledged or otherwise handled through the canonical follow-up surfaces.
- FR-006: The tenant shell activity hint MUST show at most three prioritized items for the current tenant and MUST expose one canonical
View operationlink per item plus one canonical overflow path toShow all operationswhen more qualifying items exist. The overflow path MUST open the canonical Operations collection with the selected tenant encoded as the contextualtenant_idprefilter; on initial mount that requested tenant prefilter takes precedence over session/default state, and any restored local filters may only narrow within that tenant scope rather than broaden it. - FR-007: The tenant shell activity hint MUST stop behaving as a fixed overlay that covers primary actions. Non-obstructive placement is part of the contract, not an optional polish step.
- FR-008: Determinate progress MUST appear only when
summary_counts.totalandsummary_counts.processedare valid numeric values while the run is active. Determinate progress MUST be clamped to0-100, and the shell hint MUST NOT display fake active progress after terminal transition. - FR-009: The lifecycle-sensitive tertiary affordance MUST use state-matching wording:
Hide activityfor queued/running shell hints,DismissorClosefor terminal-success hints, andAcknowledgefor unresolved terminal follow-up hints. - FR-010: Browser-session hide, dismiss, and acknowledge behavior MUST stay browser-session-only. A newly accepted run in the current session MUST re-open the shell hint.
- FR-011: The implementation MUST update
docs/ui/tenantpilot-enterprise-ui-standards.mdwith the shell activity-feedback pattern, including canonical links, bounded terminal-success/follow-up scope, progressbar eligibility, item limits, lifecycle-sensitive tertiary actions, hide/dismiss/acknowledge boundaries, and anti-patterns such as fake percentages or overlays that cover actions. - FR-012: Operations collection/detail pages remain diagnostics-first drill-through targets. The shell hint MAY show at most one concise next-step cue when it materially clarifies whether inspection is needed, and it MUST NOT duplicate full diagnostics, logs, raw payloads, or support-only evidence.
Authorization and Safety Requirements
- AR-001: Tenant/admin-plane authorization semantics stay unchanged: out-of-scope tenant access remains deny-as-not-found (
404semantics through current tenant/admin boundaries), while in-scope visibility continues to reuse server-sideOperationRunpolicies. - AR-002: No surface in this slice may emit a run row or link the actor cannot already view through the current canonical Operations routes.
- AR-003: No destructive or mutating action is introduced. Existing run start surfaces and existing detail pages remain responsible for initiation/retry behavior and any confirmation requirements they already own.
Non-Functional Requirements
- NFR-001: The slice MUST stay Filament-native and Livewire v4-compatible. No panel-provider registration change is allowed;
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 must remain intentional and bounded. The shell hint may continue to use the current poller family, but the implementation must not add parallel uncoordinated polling loops or additional active-awareness hosts in this slice.
- NFR-004: Badge semantics remain centralized through existing badge infrastructure; no host surface may add its own status/outcome color mapping.
Deferred Follow-Ups / Explicit Non-Goals
- Host-widget migration pass beyond the current global shell activity widget
- Polling and UI calmness standard beyond the v1 scope
- Notification/activity lifecycle standardization beyond the current start contract
- Any permanent inbox or tray treatment for terminal/follow-up operation states beyond the bounded shell grace/follow-up contract
- Activity tray / center v2
- Persistent reviewed / investigated semantics over failed or blocked runs
Key Entities
- Shell activity item: a derived, non-persisted summary of one visible
OperationRunin the shell, including operation label, lifecycle state, canonical detail/collection links, and progress treatment only when truthful. - Terminal success shell item: a derived, non-persisted shell item for a just-completed successful run that remains visible briefly to close the feedback loop and confirm that no further action is needed.
- Terminal follow-up shell item: a derived, non-persisted shell item for a blocked, partial, failed, or reconciled terminal run that remains visible on the shell until the operator acknowledges it locally or handles it on the canonical follow-up surfaces.
- Browser-session shell state: a non-persisted shell-level state that remembers hide, dismiss, and acknowledge choices only for the current browser session.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: In the focused validation fixture with more than three qualifying tenant rows, the shell activity hint shows no more than three visible items plus exactly one overflow path to
Show all operations. - SC-002: On the validated row-action-heavy smoke surface, primary page actions remain clickable while the shell activity hint is visible.
- SC-003: In validation coverage where a queued/running run transitions to successful completion, the shell activity hint keeps that run visible briefly with success semantics and no fake active progress after completion.
- SC-004: In validation coverage where a queued/running run transitions to blocked, partial, failed, or reconciled terminal follow-up, the shell activity hint does not drop that follow-up silently from the shell immediately after transition.
- SC-005: The shell hint routes through the canonical helper family and keeps the guard coverage free of new raw operation-link bypasses.