TenantAtlas/specs/268-operationrun-activity-feedback/spec.md
ahmido 867bd92370 Automated: 268-operationrun-activity-feedback — commit & PR (#324)
Automated commit and PR created by agent. Branch: 268-operationrun-activity-feedback-session-1777896580

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #324
2026-05-04 12:17:15 +00:00

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: OperationRun is 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 BulkOperationProgress shell 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 operation links, 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 OperationRun types 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/operations and /admin/operations/{run} remain the diagnostics drill-through targets and canonical collection/detail routes; shell overflow opens /admin/operations with the selected tenant as a contextual tenant_id prefilter, and that query-param prefilter wins over session/default state on initial mount
  • Data Ownership: existing OperationRun truth 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 OperationRun policies remain authoritative. Non-members or out-of-scope tenant contexts remain hidden (404 semantics 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 operation wording, overflow/Show all operations affordances, 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 operation link generation, tenant-safe URL resolution, current run-enqueued browser 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 OperationRun truth 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 OperationRun truth 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/, extend apps/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-split if 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.php
    • export 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:

  1. 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 operation link each and an overflow path to Show all operations.
  2. 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.
  3. 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:

  1. 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 a Dismiss or Close tertiary affordance.
  2. 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.
  3. 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:

  1. Given queued/running items are visible, When the operator uses the tertiary affordance, Then it is labeled Hide activity and the current browser session remembers that choice without creating any database-backed preference.
  2. Given only recent successful terminal items are visible, When the operator uses the tertiary affordance, Then it is labeled Dismiss or Close and the shell hint may also auto-dismiss after the short terminal-success grace window.
  3. Given only unresolved terminal follow-up items are visible, When the operator uses the tertiary affordance, Then it is labeled Acknowledge and remains browser-session-only instead of persisting on the OperationRun record.
  4. Given the shell hint is hidden and a new run is accepted in the current browser session, When the shared run-enqueued event fires, Then the shell hint reappears so the operator does not miss newly started work.

Edge Cases

  • No selected tenant or no viewAny OperationRun capability 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 OperationRun record.

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 OperationRun truth plus current shared helpers such as OperationUxPresenter, 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 existing OperationRun truth.
  • 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, canonical View operation and Show all operations links, and a tertiary Dismiss or Close affordance. 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 operation link per item plus one canonical overflow path to Show all operations when more qualifying items exist. The overflow path MUST open the canonical Operations collection with the selected tenant encoded as the contextual tenant_id prefilter; 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.total and summary_counts.processed are valid numeric values while the run is active. Determinate progress MUST be clamped to 0-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 activity for queued/running shell hints, Dismiss or Close for terminal-success hints, and Acknowledge for 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.md with 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 (404 semantics through current tenant/admin boundaries), while in-scope visibility continues to reuse server-side OperationRun policies.
  • 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.php remains 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 OperationRun in 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.