# Implementation Plan: OperationRun Phase & Composite Progress v1 **Branch**: `272-operationrun-phase-composite-progress` | **Date**: 2026-05-05 | **Spec**: [spec.md](./spec.md) **Input**: Feature specification from `/specs/272-operationrun-phase-composite-progress/spec.md` ## Summary This plan prepares the bounded non-counted follow-up to Spec 270 and the adjacent counted boundary from Spec 271. The implementation path is to reuse `OperationRunProgressContract`, `OperationUxPresenter`, and `OperationRunService`, add canonical operator-safe phase metadata for `baseline_capture` and `baseline_compare`, and add one bounded composite summary path for `tenant.review.compose` from existing aggregate operation truth. The slice must not invent fake percentages, reopen counted rollout work, add a workflow engine, create a child-run graph, or widen into provider health, support diagnostics, or dashboard work. ## Inherited Baseline / Explicit Delta ### Inherited baseline - `App\Support\OpsUx\OperationRunProgressContract` already centralizes `none`, `activity`, `counted`, `phased`, and `composite` progress modes. - The current contract already classifies baseline evidence-capture context as `phased` and aggregate multi-run truth as `composite`, but it currently returns only generic placeholder labels. - `App\Jobs\CaptureBaselineSnapshotJob` and `App\Jobs\CompareBaselineToTenantJob` already persist repo-real baseline phase-shaped context, including eligibility and evidence-capture stats. - `App\Services\TenantReviews\TenantReviewService` and `App\Jobs\ComposeTenantReviewJob` already create the canonical `tenant.review.compose` run type, and current evidence snapshot summaries already contain aggregate operation counts used later in tenant review composition. - The current tenant shell adopter already renders generic phased/composite fallbacks through the shared contract without inventing a percentage. - Spec 271 already owns truthful counted rollout for stable-unit families and must remain distinct from this slice. ### Explicit delta in this plan - add canonical operator-safe phase metadata and label derivation for `baseline_capture` and `baseline_compare` - add one bounded composite summary path for `tenant.review.compose` from current aggregate operation truth - keep counted, terminal, and generic activity semantics unchanged except for consuming more truthful non-counted detail - document the narrowed candidate boundary explicitly: review-pack and evidence-snapshot overlap remain with Spec 271, while provider health and support diagnostics remain deferred until repo-real queued progress truth exists ## Technical Context **Language/Version**: PHP 8.4, Laravel 12, Filament v5, Livewire v4 **Primary Dependencies**: existing Ops-UX contract/presenter classes, current baseline services/jobs, current tenant-review services/jobs, Pest v4 **Storage**: PostgreSQL via existing `operation_runs`, baseline, evidence snapshot, and tenant review tables **Testing**: Pest Unit + Feature **Validation Lanes**: fast-feedback, confidence **Target Platform**: existing Laravel monolith in `apps/platform` **Project Type**: web application (Laravel monolith with Filament) **Performance Goals**: no new poller family, no new query family, and no slower-than-current activity feedback disclosure **Constraints**: no fake percentages, no new `summary_counts` keys, no new persistence, no child-run graph, no dashboard redesign, and no provider-health or support-diagnostics rollout **Scale/Scope**: one shared contract extension across 3 selected run families plus one UI standards update and focused regression coverage ## Likely Affected Repo Surfaces - `apps/platform/app/Support/OpsUx/OperationRunProgressContract.php` - `apps/platform/app/Support/OpsUx/OperationUxPresenter.php` - `apps/platform/app/Support/OpsUx/OperationStatusNormalizer.php` - `apps/platform/app/Services/OperationRunService.php` - `apps/platform/app/Services/Baselines/BaselineCaptureService.php` - `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php` - `apps/platform/app/Jobs/CompareBaselineToTenantJob.php` - `apps/platform/app/Services/TenantReviews/TenantReviewService.php` - `apps/platform/app/Jobs/ComposeTenantReviewJob.php` - `apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php` - `apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php` - `apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php` - `apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php` - `apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php` - `apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php` - `apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php` - `apps/platform/tests/Feature/Baselines/BaselineCompareResumeTokenTest.php` - `apps/platform/tests/Feature/TenantReview/TenantReviewOperationsUxTest.php` - `apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php` - `apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php` - `apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php` - `apps/platform/tests/Feature/Baselines/BaselineProfileAuthorizationTest.php` - `docs/ui/tenantpilot-enterprise-ui-standards.md` ## UI / Filament & Livewire Fit - The visible adopter remains the existing tenant-shell activity feedback surface. No new page, dashboard card, widget family, or top-level monitoring surface is introduced. - Canonical Operations collection/detail routes remain diagnostics-first drill-through targets. They may inherit safer phase/composite disclosure through the shared presenter path, but they do not gain a second progress framework. - The shell remains decision-first. This slice only improves whether selected runs can describe truthful non-counted phase/composite state. - Filament stays v5 on Livewire v4. Provider registration remains unchanged in `apps/platform/bootstrap/providers.php`. ## RBAC / Policy Fit - Existing capability gates for baseline capture, baseline compare, and tenant review remain unchanged. - Existing `OperationRun` policies remain the only progress-visibility gate. - No new mutation surface is introduced, so current server-side authorization and confirmation behavior stays on the existing launch/detail surfaces. ## Audit / Logging Fit - Existing queued toasts and terminal notifications remain authoritative and unchanged. - Existing audit ownership remains the only audit trail for the covered runs; no new run-local audit channel is introduced. - Progress detail remains derived execution truth inside the current `OperationRun` ownership model, not a second audit or event stream. ## Data & Query Fit - Progress truth remains fully derived from existing `operation_runs.context`, `operation_runs.summary_counts`, and current contract logic. - Selected phase metadata stays inside existing `context` JSON and does not create a new persisted entity. - Composite progress for `tenant.review.compose` stays bounded to currently available aggregate operation truth from evidence snapshot or review summary data. - No migration, no new JSON table, no cache layer, and no new persisted user preference or progress mode are planned. ## UI / Surface Guardrail Plan - **Guardrail scope**: changed surfaces - **Native vs custom classification summary**: native Filament + existing Livewire/Blade shell surface - **Shared-family relevance**: Ops-UX activity feedback and current run summaries - **State layers in scope**: shell, detail compatibility - **Audience modes in scope**: operator-MSP - **Decision/diagnostic/raw hierarchy plan**: decision-first on shell, diagnostics-second on Operations detail - **Raw/support gating plan**: unchanged; raw/support detail remains on diagnostics surfaces only - **One-primary-action / duplicate-truth control**: keep one dominant `View operation` action and one shared progress contract that now supplies richer non-counted labels - **Handling modes by drift class or surface**: review-mandatory - **Repository-signal treatment**: review-mandatory - **Special surface test profiles**: global-context-shell - **Required tests or manual smoke**: functional-core, state-contract - **Exception path and spread control**: none planned - **Active feature PR close-out entry**: Guardrail / Smoke Coverage ## Shared Pattern & System Fit - **Cross-cutting feature marker**: yes - **Systems touched**: Ops-UX progress contract, Ops-UX presenter, baseline jobs/services, tenant-review queue/composition path, shell activity feedback - **Shared abstractions reused**: `OperationRunProgressContract`, `OperationUxPresenter`, `OperationStatusNormalizer`, `OperationRunService` - **New abstraction introduced? why?**: no new top-level abstraction planned; extend the current contract/presenter path only - **Why the existing abstraction was sufficient or insufficient**: classification already exists; what is missing is canonical operator-safe phase/composite detail for selected run families - **Bounded deviation / spread control**: selected families only; any additional run family without repo-real truthful phase/composite detail stays on current generic fallback ## OperationRun UX Impact - **Touches OperationRun start/completion/link UX?**: yes, for active progress meaning only - **Central contract reused**: existing OperationRun Start UX Contract plus `OperationRunProgressContract` - **Delegated UX behaviors**: queued toast, canonical run links, `run-enqueued` event, and terminal-notification lifecycle remain delegated and unchanged - **Surface-owned behavior kept local**: current launch inputs, detailed diagnostics, and domain-specific result explanations stay local to their current surfaces - **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**: `OperationRun` truth, Ops-UX contract/presenter, baseline and tenant-review execution truth - **Neutral platform terms / contracts preserved**: `Operation`, `activity`, `phase progress`, `composite progress`, `terminal outcome` - **Retained provider-specific semantics and why**: none - **Bounded extraction or follow-up path**: provider health and support diagnostics remain an explicit later follow-up if queued progress truth exists later ## Constitution Check *GATE: Must pass before implementation begins and again before merge.* - Inventory-first: PASS. The slice only enriches current execution feedback over existing operational truth. - Read/write separation: PASS. No new external write path is introduced; current domain jobs keep their existing product responsibilities and only persist better progress detail in `OperationRun` context. - Graph contract path: PASS. No new Graph or provider contract is introduced. - Deterministic capabilities: PASS. Authorization and run visibility remain deterministic and testable. - RBAC-UX: PASS. Visibility remains on existing tenant/admin boundaries and current `OperationRun` policies. - Run observability: PASS. Long-running work still flows through current `OperationRun` ownership and current Ops-UX surfaces. - Ops-UX lifecycle: PASS. `status` and `outcome` ownership remains on `OperationRunService`; this slice only adds richer non-counted detail. - Ops-UX summary counts: PASS. No new `summary_counts` key is planned. - Test governance: PASS. Proof remains bounded to Unit plus Feature. - Proportionality / no premature abstraction: PASS. No new workflow engine, child-run graph, or second presenter path is introduced. - Persisted truth / behavioral state: PASS. No new table, cache, or lifecycle family is added. - Shared pattern first / UI semantics / Filament-native UI: PASS. Existing Ops-UX path remains central and the visible adopter is unchanged. - Provider boundary: PASS. No provider/platform seam change. - Filament/Laravel panel safety: PASS. Filament v5 stays on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, and no assets change. **Gate evaluation**: PASS. ## Test Governance Check - **Test purpose / classification by changed surface**: Unit for contract precedence and label derivation; Feature for selected baseline and tenant-review writer seams plus current shell adoption - **Affected validation lanes**: fast-feedback, confidence - **Why this lane mix is the narrowest sufficient proof**: the shared contract already has a focused unit suite, and the selected run families already have domain feature suites that can prove current context/summary truth without adding new browser or heavy-governance obligations - **Narrowest proving command(s)**: - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php` - `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 tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php tests/Feature/Baselines/BaselineCaptureTest.php tests/Feature/Baselines/BaselineCompareResumeTokenTest.php tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php tests/Feature/TenantReview/TenantReviewOperationsUxTest.php tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/TenantReview/TenantReviewRbacTest.php tests/Feature/Baselines/BaselineProfileAuthorizationTest.php` - **Fixture / helper / factory / seed / context cost risks**: low to moderate; reuse current tenant context helpers, existing baseline helpers, and current tenant-review fixtures instead of adding a new provider-heavy harness - **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**: rerun the two proving commands above and verify that selected run families now expose truthful non-counted detail, the full precedence chain `phased > composite > counted > activity` still holds, counted semantics stay counted-only, malformed metadata degrades safely, current `404`/`403` visibility semantics remain intact, no new polling loop was introduced, and excluded families remain excluded - **Budget / baseline / trend follow-up**: none expected beyond a small feature-local increase - **Review-stop questions**: did any run family leak raw technical phase labels, did any composite summary masquerade as a percentage, did any excluded family sneak in, and did any new `summary_counts` key or workflow framework appear? - **Escalation path**: `reject-or-split` for any provider-health/support expansion, dashboard work, child-run graph persistence, or workflow-engine drift - **Active feature PR close-out entry**: Guardrail / Smoke Coverage - **Why no dedicated follow-up spec is needed**: this package is itself the bounded non-counted progress follow-up to Spec 270; remaining excluded ideas are already named as explicit later follow-ups. ## Project Structure ### Documentation (this feature) ```text specs/272-operationrun-phase-composite-progress/ ├── spec.md ├── plan.md ├── tasks.md └── checklists/ └── requirements.md ``` ### Source Code (expected implementation surfaces) ```text apps/platform/app/Support/OpsUx/ apps/platform/app/Services/OperationRunService.php apps/platform/app/Services/Baselines/BaselineCaptureService.php apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php apps/platform/app/Jobs/CompareBaselineToTenantJob.php apps/platform/app/Services/TenantReviews/TenantReviewService.php apps/platform/app/Jobs/ComposeTenantReviewJob.php apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php apps/platform/tests/Unit/Support/OpsUx/ apps/platform/tests/Feature/OpsUx/ apps/platform/tests/Feature/Baselines/ apps/platform/tests/Feature/TenantReview/ apps/platform/tests/Feature/Filament/ docs/ui/tenantpilot-enterprise-ui-standards.md ``` **Structure Decision**: keep the rollout local to current jobs/services plus the existing Ops-UX support family. Do not introduce a workflow engine, child-run graph, or second progress framework. ## Data / Migration Implications - No migration or schema change is planned. - No new persisted progress mode or preference is allowed. - Selected phase/composite detail remains inside existing `operation_runs.context` JSON only. - No backfill is planned. Historical runs remain historical truth; the rollout affects future execution and active-run rendering only. ## Rollout Considerations - Filament remains v5 on Livewire v4. Provider registration remains in `apps/platform/bootstrap/providers.php`. - No global search or asset change is required because the slice changes only current run-progress truth. - No destructive action or confirmation model changes are planned. - No deployment step beyond ordinary code deploy, focused tests, and current formatting validation is expected. ## Risk Controls - Reject any implementation that turns phase/composite labels into fake percentages or a synthetic progress bar. - Reject any implementation that leaks raw technical step names, exception class names, or transport details into the default operator-facing progress label. - Reject any implementation that adds a child-run graph or persists `child_run_ids` as a new framework instead of a bounded current-release need. - Reject any implementation that widens the rollout to provider health, support diagnostics, review-pack, or evidence-snapshot overlap without an explicit follow-up spec. - Reject any implementation that changes counted precedence or adds a new `summary_counts` key to compensate for missing phase/composite truth. ## Implementation Phases ### Phase 0 - Confirm The Selected Non-Counted Seams - Verify the current phase and composite fallback behavior in `OperationRunProgressContract`, the current shell adopter, the current baseline jobs, and the current tenant-review queue/composition path. - Reconfirm that provider health, support diagnostics, review-pack overlap, and child-run graph persistence remain out of scope. ### Phase 1 - Roll Out Baseline Phase Metadata - Add canonical operator-safe phase metadata for `baseline_capture` and `baseline_compare` over the repo-real lifecycle boundaries that already exist today. ### Phase 2 - Roll Out Tenant Review Composite Summary - Seed a bounded composite summary for `tenant.review.compose` from current evidence-basis operation truth and keep it explicitly non-counted. ### Phase 3 - Lock The Guardrail And Proof - Update the UI standards and focused tests so later non-counted progress work extends one contract rather than inventing new semantics. ## Proportionality Review - **Current operator problem**: current non-counted runs know more than the product currently says, yet the shell still shows vague generic fallback copy. - **Existing structure is insufficient because**: the shared contract can classify `phased` and `composite`, but it cannot yet explain them with canonical operator-safe detail for selected run families. - **Narrowest correct implementation**: update only selected repo-real phase/composite families and keep all other work on current generic fallback or counted semantics. - **Ownership cost created**: selected context writes in existing jobs/services, focused tests, and one standards update. - **Alternative intentionally rejected**: a workflow engine, child-run graph, or fake percentage model was rejected because all would be structurally heavier and less truthful than the current-release need. - **Release truth**: current-release truth. The repo already contains the contract, the shell adopter, the baseline phase hints, and the tenant-review aggregate truth needed for this rollout.