260 lines
19 KiB
Markdown
260 lines
19 KiB
Markdown
# Implementation Plan: OperationRun Terminal Outcome Feedback v1
|
|
|
|
**Branch**: `269-operationrun-terminal-outcome-feedback` | **Date**: 2026-05-05 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `/specs/269-operationrun-terminal-outcome-feedback/spec.md`
|
|
|
|
## Summary
|
|
|
|
This plan prepares one bounded refinement over the repo's existing shell activity feedback. The current `BulkOperationProgress` surface already shows active work and recent terminal rows, but terminal success and unresolved follow-up still share too much generic terminal-update behavior. The implementation path is to keep the existing shell host, links, and progress contract intact while splitting terminal success from terminal follow-up copy and browser-session tertiary semantics, then record the final rule in `docs/ui/tenantpilot-enterprise-ui-standards.md`.
|
|
|
|
Filament remains on Livewire v4, no panel-provider registration changes are required (`apps/platform/bootstrap/providers.php` remains authoritative), no globally searchable resource is added, no asset registration change is expected, and no destructive action is introduced.
|
|
|
|
## Inherited Baseline / Explicit Delta
|
|
|
|
### Inherited baseline
|
|
|
|
- `OperationRun` already provides the execution-truth model and current tenant/workspace scoping.
|
|
- `BulkOperationProgress` already hosts the shell activity surface on tenant-scoped pages.
|
|
- `OperationUxPresenter`, `OperationStatusNormalizer`, `OperationRunProgressContract`, `OperationRunLinks`, `OperationRunUrl`, and `ActiveRuns` already own the current status, progress, and link semantics.
|
|
- `ActivityFeedbackSurfaceTest`, `BulkOperationProgressDbOnlyTest`, and `OperationActivityFeedbackSmokeTest` already prove core shell behavior.
|
|
|
|
### Explicit delta in this plan
|
|
|
|
- split terminal-success shell behavior from unresolved terminal-follow-up shell behavior
|
|
- preserve active-state helper, progress, and canonical-link behavior unchanged unless terminal-outcome refinement requires a local adjustment
|
|
- keep unresolved terminal follow-up explicitly reviewable instead of generically dismissible
|
|
- keep terminal success briefly dismissible and clearly no-action-needed during the current 30-second shell-visible success window from `ActiveRuns`
|
|
- keep acknowledge and dismiss behavior browser-session-only
|
|
- update `docs/ui/tenantpilot-enterprise-ui-standards.md` with the terminal outcome contract
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4, Laravel 12, Filament v5, Livewire v4
|
|
**Primary Dependencies**: current Ops-UX support classes, native Filament widgets or Blade, current badge infrastructure, Pest v4
|
|
**Storage**: PostgreSQL via existing `operation_runs`; browser-session state only for current shell collapse or acknowledgement behavior; no new DB storage
|
|
**Testing**: Pest Feature coverage plus one required browser smoke
|
|
**Validation Lanes**: fast-feedback, confidence, browser
|
|
**Target Platform**: existing Laravel monolith in `apps/platform`, admin or operator plane only
|
|
**Project Type**: Web application (Laravel monolith with Filament)
|
|
**Performance Goals**: no new query families, no duplicate polling loops, and no additional shell host surfaces
|
|
**Constraints**: no new persistence, no new lifecycle family, no new notification policy, no dashboard card, and no panel/provider/asset changes
|
|
**Scale/Scope**: one current shell host, one standards update, and one browser-session tertiary-action rule
|
|
|
|
## Likely Affected Repo Surfaces
|
|
|
|
- `apps/platform/app/Livewire/BulkOperationProgress.php`
|
|
- `apps/platform/resources/views/livewire/bulk-operation-progress.blade.php`
|
|
- `apps/platform/app/Support/OpsUx/OperationUxPresenter.php`
|
|
- `apps/platform/app/Support/OpsUx/ActiveRuns.php`
|
|
- `apps/platform/public/js/tenantpilot/ops-ux-progress-widget-poller.js`
|
|
- `apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php`
|
|
- `apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php`
|
|
- `apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php`
|
|
- `docs/ui/tenantpilot-enterprise-ui-standards.md`
|
|
|
|
## UI / Filament & Livewire Fit
|
|
|
|
- Keep the changed shell host Filament-native and local to the existing Livewire component.
|
|
- The shell remains decision-first: one dominant primary action, one concise helper line, and one lifecycle-sensitive tertiary action.
|
|
- Monitoring collection and detail pages remain diagnostics-first drill-through targets. The shell must not restate their evidence-heavy content.
|
|
- Successful terminal rows stay briefly visible with no-action-needed semantics; unresolved terminal follow-up stays explicitly reviewable.
|
|
- Browser-session `Acknowledge` stays local to the current browser session and must not become a server-side workflow state.
|
|
- No new asset registration, panel configuration, or provider registration change is planned.
|
|
|
|
## RBAC / Policy Fit
|
|
|
|
- Existing `OperationRun` policies remain the first and only visibility gate.
|
|
- The shell continues to derive rows only after tenant context and policy filtering.
|
|
- No plane expansion, no new action surface, and no new authorization rule are introduced.
|
|
- Canonical Operations collection and detail pages remain the only drill-through owners for deeper diagnostics.
|
|
|
|
## Audit / Logging Fit
|
|
|
|
- Existing queued toasts, browser events, and terminal DB notifications remain authoritative and unchanged.
|
|
- Existing Monitoring and audit behavior remain the only audit trail. No page-view audit stream is introduced.
|
|
- Because the slice changes presentation only, `OperationRun.status` and `OperationRun.outcome` ownership remain service-owned and unchanged.
|
|
|
|
## Data & Query Fit
|
|
|
|
- The shell host continues to derive rows from current-tenant `OperationRun` truth.
|
|
- The current 30-second terminal-success grace window in `ActiveRuns::shellVisibleQueryForTenantId()` remains the source of truth for recent successful terminal visibility in this slice.
|
|
- Terminal success and terminal follow-up remain derived display states only; they do not create new persisted fields.
|
|
- Acknowledge and dismiss remain browser-session scoped and must not be written to the database or to the run record.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: changed surfaces
|
|
- **Native vs custom classification summary**: native Filament plus a bounded local shell refinement
|
|
- **Shared-family relevance**: Ops UX lifecycle feedback, canonical run links
|
|
- **State layers in scope**: shell, page, browser-session
|
|
- **Audience modes in scope**: operator-MSP
|
|
- **Decision/diagnostic/raw hierarchy plan**: decision-first on the shell host, diagnostics-first on Operations collection/detail
|
|
- **Raw/support gating plan**: raw and support detail stay on existing diagnostics surfaces only
|
|
- **One-primary-action / duplicate-truth control**: each visible shell state keeps one dominant primary action; grouped `Review operations` remains only the label variant of the canonical collection link also exposed as `Show all operations`, and the shell differentiates `success` from `follow-up` through helper and tertiary wording instead of duplicate diagnostics
|
|
- **Handling modes by drift class or surface**: review-mandatory
|
|
- **Repository-signal treatment**: review-mandatory
|
|
- **Special surface test profiles**: global-context-shell
|
|
- **Required tests**: functional-core, named-browser-smoke
|
|
- **Exception path and spread control**: none planned; any attempt to add persisted acknowledgement, dashboard work, or a second lifecycle surface resolves as `reject-or-split`
|
|
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: yes
|
|
- **Systems touched**: current shell hint, canonical run links, current run guidance, current progress contract, current shell poller, UI standards
|
|
- **Shared abstractions reused**: `OperationUxPresenter`, `OperationStatusNormalizer`, `OperationRunProgressContract`, `OperationRunLinks`, `OperationRunUrl`, `ActiveRuns`, `OpsUxBrowserEvents`
|
|
- **New abstraction introduced? why?**: none planned; keep the change local to the existing shell component and helper seams unless a tiny readability helper becomes necessary during implementation
|
|
- **Why the existing abstraction was sufficient or insufficient**: the repo already owns truthful state and links; the missing piece is the terminal-outcome decision contract on the shell
|
|
- **Bounded deviation / spread control**: do not create a second terminal-outcome presenter family, a registry, or a persisted acknowledgement model
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: yes, for post-completion shell follow-through and drill-through links only
|
|
- **Central contract reused**: current Ops-UX shell contract via `OperationUxPresenter`, `OperationRunLinks`, `OperationRunUrl`, `OperationRunProgressContract`, and `OpsUxBrowserEvents`
|
|
- **Delegated UX behaviors**: current queued toast wording, canonical `View operation`, grouped `Review operations`, and `Show all operations` links, current browser-event dispatch, and existing terminal DB-notification lifecycle remain delegated to the shared contract
|
|
- **Surface-owned behavior kept local**: success vs follow-up helper copy and lifecycle-sensitive tertiary action wording only
|
|
- **Queued DB-notification policy**: `N/A` - unchanged
|
|
- **Terminal notification path**: unchanged central lifecycle mechanism
|
|
- **Exception path**: none
|
|
|
|
## Provider Boundary & Portability Fit
|
|
|
|
- **Shared provider/platform boundary touched?**: no
|
|
- **Provider-owned seams**: `N/A`
|
|
- **Platform-core seams**: existing `OperationRun` truth, links, and operator vocabulary only
|
|
- **Neutral platform terms / contracts preserved**: `Operation`, `View operation`, `Review operations`, `Show all operations`, `completed successfully`, `review needed`
|
|
- **Retained provider-specific semantics and why**: none
|
|
- **Bounded extraction or follow-up path**: none
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before implementation begins and again before merge.*
|
|
|
|
- Inventory-first: PASS. The slice is fully derived from existing `OperationRun` truth.
|
|
- Read/write separation: PASS. No new write path or retry surface is introduced.
|
|
- Graph contract path: PASS. No Graph/provider interaction is added.
|
|
- Deterministic capabilities: PASS. Existing `OperationRun` policies remain authoritative.
|
|
- RBAC-UX: PASS. No plane expansion; tenant/admin visibility stays on current guards and deny-as-not-found semantics.
|
|
- Run observability: PASS. Existing start contract, terminal notifications, and Monitoring ownership remain unchanged while the shell only refines terminal-outcome meaning.
|
|
- Ops-UX lifecycle: PASS. No change to service-owned status/outcome transitions or `summary_counts` semantics.
|
|
- Data minimization: PASS. The shell remains compact and does not surface raw evidence by default.
|
|
- Test governance: PASS. Proof stays bounded to focused Feature coverage plus one browser smoke.
|
|
- Proportionality / no premature abstraction: PASS. The default implementation stays local to the existing shell host and standards document.
|
|
- Persisted truth / behavioral state: PASS. No new table, no new lifecycle, no new persisted acknowledgement or dismiss state.
|
|
- Shared pattern first / UI semantics / Filament-native UI: PASS. Existing helpers and badge semantics stay central, and the shell moves closer to a precise decision-first contract.
|
|
- Provider boundary: PASS. No provider/platform seam changes.
|
|
- Filament/Laravel panel safety: PASS. Filament v5 stays on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, no globally searchable resource is introduced, and no new assets are planned.
|
|
|
|
**Gate evaluation**: PASS.
|
|
|
|
## Test Governance Check
|
|
|
|
- **Test purpose / classification by changed surface**: Feature for terminal-outcome shell behavior; one required browser smoke for live shell interaction
|
|
- **Affected validation lanes**: fast-feedback, confidence, browser
|
|
- **Why this lane mix is the narrowest sufficient proof**: Feature coverage proves success vs follow-up copy, tertiary actions, browser-session-only acknowledgement, and the absence of progress UI after completion. The browser smoke remains reserved for real shell interaction and re-open behavior.
|
|
- **Narrowest proving command(s)**:
|
|
- `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.php`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php`
|
|
- **Fixture / helper / factory / seed / context cost risks**: low to moderate; reuse current `OperationRun` factories, tenant helpers, and shell smoke helpers instead of introducing new provider-heavy defaults
|
|
- **Expensive defaults or shared helper growth introduced?**: no
|
|
- **Heavy-family additions, promotions, or visibility changes**: none
|
|
- **Surface-class relief / special coverage rule**: `global-context-shell`
|
|
- **Closing validation and reviewer handoff**: reviewers should rerun the focused commands above, then confirm that unresolved terminal follow-up uses `Acknowledge` or review wording, successful completion stays dismissible, and new run-enqueue events still reopen the shell.
|
|
- **Budget / baseline / trend follow-up**: none expected beyond a small feature-local increase
|
|
- **Review-stop questions**: did the shell stay bounded, did unresolved follow-up stop using generic dismiss semantics, did terminal rows stay progress-free, and did acknowledgement remain browser-session-only?
|
|
- **Escalation path**: `reject-or-split` for any dashboard expansion, persisted acknowledgement state, or notification-policy change
|
|
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage
|
|
- **Why no dedicated follow-up spec is needed**: this package already narrows the live shell contract to the remaining terminal-outcome seam; larger dashboard or progress topics remain explicit follow-up candidates instead of hidden work here.
|
|
|
|
## Authorization Verification Fit
|
|
|
|
- Reuse the existing shell Feature proof to verify no-tenant and no-capability suppression, tenant-safe filtering, and the absence of inaccessible run exposure on the shell host.
|
|
- Keep that verification local to the current shell test family; do not create a separate authorization test family for this slice.
|
|
|
|
## Preparation Review Outcome
|
|
|
|
- **Review outcome class**: `acceptable-special-case`
|
|
- **Workflow outcome**: `keep`
|
|
- **Test-governance outcome**: `keep`
|
|
- **Reason**: the automatic candidate queue is intentionally empty, but this manual promotion is still justified because current repo truth leaves a bounded terminal-outcome gap on a live shell surface that is smaller and safer than the deferred dashboard or broader progress follow-ups.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/269-operationrun-terminal-outcome-feedback/
|
|
├── spec.md
|
|
├── plan.md
|
|
├── tasks.md
|
|
└── checklists/
|
|
└── requirements.md
|
|
```
|
|
|
|
This preparation package intentionally stays on the core artifacts plus the readiness checklist. The repo already contains the relevant Ops-UX truth, shell host, and proof surfaces, so no extra research, data-model, quickstart, or contracts package is required for a bounded implementation handoff.
|
|
|
|
### Source Code (expected implementation surfaces)
|
|
|
|
```text
|
|
apps/platform/app/Livewire/BulkOperationProgress.php
|
|
apps/platform/resources/views/livewire/bulk-operation-progress.blade.php
|
|
apps/platform/app/Support/OpsUx/OperationUxPresenter.php
|
|
apps/platform/app/Support/OpsUx/ActiveRuns.php
|
|
apps/platform/public/js/tenantpilot/ops-ux-progress-widget-poller.js
|
|
apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php
|
|
apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php
|
|
apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php
|
|
docs/ui/tenantpilot-enterprise-ui-standards.md
|
|
```
|
|
|
|
**Structure Decision**: keep the implementation local to the existing Ops-UX shell seams and standards document. Do not introduce a second activity framework or a dashboard-owned run-state model in this slice.
|
|
|
|
## Data / Migration Implications
|
|
|
|
- No migration or new table is planned.
|
|
- No new persisted user preference is allowed.
|
|
- No new cache layer, backfill, or deploy step should be required.
|
|
|
|
## Rollout Considerations
|
|
|
|
- Filament remains v5 on Livewire v4. No panel-provider change is required, and provider registration remains in `apps/platform/bootstrap/providers.php`.
|
|
- No global search change is required because the slice changes a shell widget, not a resource.
|
|
- No destructive action is added.
|
|
- No new asset registration is expected; if future work ever registers assets, deployment still runs `cd apps/platform && php artisan filament:assets` outside this slice.
|
|
|
|
## Risk Controls
|
|
|
|
- Reject any implementation that leaves unresolved terminal follow-up on generic `Dismiss` semantics.
|
|
- Reject any implementation that introduces a new `OperationRun` lifecycle, a persisted acknowledgement model, or a dashboard active-operations card in this slice.
|
|
- Reject any implementation that reintroduces progress UI after terminal transition.
|
|
- Reject any implementation that changes notification policy, route ownership, or shell polling scope.
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 0 - Confirm Current Terminal Outcome Truth
|
|
|
|
- Verify the current shell host, current helper seams, and current proof owners for successful terminal items, unresolved terminal follow-up, and browser-session collapse or acknowledge behavior.
|
|
|
|
### Phase 1 - Split Success From Follow-Up Semantics
|
|
|
|
- Keep terminal success calm and dismissible.
|
|
- Make unresolved terminal follow-up explicitly reviewable and acknowledge-only at the shell level.
|
|
|
|
### Phase 2 - Keep Browser-Session Outcome Actions Local
|
|
|
|
- Preserve current browser-session-only shell calmness.
|
|
- Ensure new run-enqueue events reopen the shell.
|
|
|
|
### Phase 3 - Record The Guardrail And Validate
|
|
|
|
- Update the standards document.
|
|
- Run the focused Feature proof and the named browser smoke.
|
|
|
|
## Proportionality Review
|
|
|
|
- **Current operator problem**: terminal follow-up still looks too much like harmless completion in the live shell surface.
|
|
- **Existing structure is insufficient because**: the broader shell feedback exists already, but its current terminal-outcome semantics are still too generic for honest decision-first behavior.
|
|
- **Narrowest correct implementation**: refine the existing shell component, helper text, and browser-session tertiary actions only.
|
|
- **Ownership cost created**: minimal shell branching plus focused tests and one standards update.
|
|
- **Alternative intentionally rejected**: a tiny copy-only patch was rejected because it would not define the durable `success vs follow-up` action contract or prevent regression.
|
|
- **Release truth**: current-release truth. The repo already ships the shell activity surface; this slice only hardens the remaining terminal-outcome seam. |