TenantAtlas/specs/270-operationrun-progress-contract/tasks.md
ahmido ca61fa17dc 270-operationrun-progress-contract: OperationRun progress contract (#325)
Automated PR created by Copilot agent: commits workspace changes, adds specs and tests.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #325
2026-05-04 16:36:50 +00:00

14 KiB

description
Task list for OperationRun Progress Contract v1

Tasks: OperationRun Progress Contract v1

Input: Design documents from specs/270-operationrun-progress-contract/
Prerequisites: specs/270-operationrun-progress-contract/spec.md, specs/270-operationrun-progress-contract/plan.md, specs/270-operationrun-progress-contract/checklists/requirements.md

Review Artifact: specs/270-operationrun-progress-contract/checklists/requirements.md is the outcome-of-record for the review outcome class, workflow outcome, and test-governance outcome. If implementation widens into counted-writer rollout, dashboard drift work, or a new persisted progress model, update that artifact before continuing.

Tests: REQUIRED (Pest). Keep proof bounded to one new unit suite plus focused Ops-UX feature coverage. Browser coverage remains owned by specs/268-operationrun-activity-feedback/ and must not be pulled into this slice implicitly. Operations: No new OperationRun type, no queue-family changes, no notification-policy changes, no new summary_counts keys, and no new lifecycle ownership. Existing queued toasts, terminal notifications, run-enqueued browser events, and canonical OperationRun links remain authoritative. RBAC: Reuse current OperationRun policies and tenant context guards. No tenantless leakage from tenant surfaces; covered surfaces stay inert when no selected tenant or viewAny capability exists. Shared Pattern Reuse: Reuse SummaryCountsNormalizer, OperationSummaryKeys, ActiveRuns, OperationStatusNormalizer, OperationUxPresenter, OperationRunService, BulkOperationProgress, and docs/ui/tenantpilot-enterprise-ui-standards.md. Do not create a second local progress helper in Blade or Livewire. Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration remains unchanged in apps/platform/bootstrap/providers.php. No new panel, resource, or asset strategy is allowed. This slice changes shared progress semantics only. Organization: Tasks are grouped by user story so the shared contract, the shell adoption, and the future-boundary documentation remain independently reviewable.

Test Governance Notes

  • Lane mix stays Unit plus Feature.
  • Prefer extending ActivityFeedbackSurfaceTest, BulkOperationProgressDbOnlyTest, and SummaryCountsWhitelistTest before creating broader families.
  • Browser proof stays with Spec 268 and must not become a hidden requirement here.
  • Validation commands must stay file-scoped and run through Sail.

Phase 1: Setup (Shared Context)

Purpose: confirm the bounded slice, the inherited Ops-UX rules, and the specific ad hoc progress seam before runtime edits begin.

  • T001 Review specs/270-operationrun-progress-contract/spec.md, specs/270-operationrun-progress-contract/plan.md, specs/270-operationrun-progress-contract/checklists/requirements.md, docs/product/spec-candidates.md, docs/product/roadmap.md, specs/268-operationrun-activity-feedback/spec.md, specs/055-ops-ux-rollout/spec.md, docs/ui/tenantpilot-enterprise-ui-standards.md, and .specify/memory/constitution.md together so the slice stays on repo-real progress truth and keeps 269, 271, 272, and 273 explicitly out of scope.
  • T002 [P] Confirm the current writer and sanitizer seams in apps/platform/app/Services/OperationRunService.php, apps/platform/app/Support/OpsUx/SummaryCountsNormalizer.php, and apps/platform/app/Support/OpsUx/OperationSummaryKeys.php.
  • T003 [P] Confirm the current visible progress host and reader seams in apps/platform/app/Support/OpsUx/ActiveRuns.php, apps/platform/app/Livewire/BulkOperationProgress.php, and apps/platform/resources/views/livewire/bulk-operation-progress.blade.php.
  • T004 [P] Confirm current proof owners in apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php, apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php, and apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php, then record the exact shell-progress drift seam that the new unit suite must own.

Phase 2: Foundational (Blocking Prerequisites)

Purpose: settle the progress contract and proof owners before the visible shell host is refactored.

Critical: no user-story runtime work should begin until this phase is complete.

  • T005 [P] Create failing unit coverage in apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php for none, activity, counted, safe phased, and safe composite capability mapping, queued indeterminate handling, terminal no-progress handling, and outcome-counter rejection.
  • T006 [P] Extend apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php for shell adoption of the shared contract: determinate progress only from running plus trustworthy processed/total, no counted progress for queued runs, and no progress line or percentage for terminal runs.
  • T007 [P] Extend apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php only as needed so the new contract still reuses numeric-only whitelist semantics and does not create hidden progress inputs from non-whitelisted keys.
    • Note: no file edit was required because the existing whitelist suite already proved the contract continued to consume the canonical numeric-only keys without introducing new progress inputs.

Checkpoint: the shared contract and focused proof owners are settled before implementation begins.


Phase 3: User Story 1 - Derive truthful progress modes from existing run truth (Priority: P1)

Goal: one shared Ops-UX helper classifies progress capability and render model from current OperationRun truth.

Independent Test: create queued, running, and terminal runs with varying summary_counts, then verify the new unit suite classifies them correctly without involving a UI host.

Tests for User Story 1

  • T008 [P] [US1] Add any additional dataset or fixture coverage needed in apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php for current real run shapes such as inventory sync, review-pack generation, and bulk jobs that already emit processed and total.

Implementation for User Story 1

  • T009 [US1] Introduce one shared progress contract/helper under apps/platform/app/Support/OpsUx/ that derives progress capability and render-safe output from OperationRun status, outcome, sanitized summary_counts, and current trusted context only.
  • T010 [US1] Reuse or extend apps/platform/app/Support/OpsUx/SummaryCountsNormalizer.php, apps/platform/app/Support/OpsUx/OperationSummaryKeys.php, and apps/platform/app/Support/OpsUx/OperationStatusNormalizer.php only as needed so lifecycle semantics and progress semantics stay separate but consistent.
    • Note: the implementation reused the existing normalizer and status helper without modifying their source, which kept progress semantics bounded to the new contract helper.

Checkpoint: User Story 1 is independently functional when one shared helper owns the progress semantics.


Phase 4: User Story 2 - Keep the current shell host on the shared contract (Priority: P1)

Goal: the current shell activity hint consumes the shared contract instead of local progress math.

Independent Test: render the shell surface with queued, running, and terminal runs, then verify the shell shows counted progress only when the shared contract allows it and otherwise falls back to activity-only or terminal semantics.

Tests for User Story 2

  • T010A [P] [US2] Extend apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php so the shell stays inert for missing-tenant or unauthorized actors and does not expose progress-derived copy for runs the actor cannot view.
    • Note: repo truth kept the missing-tenant inert-state proof in BulkOperationProgressDbOnlyTest.php, while tenant-scoped visibility remained covered by the existing DB-only tenant-scoping assertion.
  • T011 [P] [US2] Extend apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php for queued indeterminate state, clamped counted progress, and terminal no-progress behavior at the shell host hydration boundary.

Implementation for User Story 2

  • T012 [US2] Refactor apps/platform/resources/views/livewire/bulk-operation-progress.blade.php and apps/platform/app/Livewire/BulkOperationProgress.php so the shell host consumes the shared progress contract and no longer computes percentages or progress eligibility inline.
    • Note: repository truth only required the Blade host seam to change; BulkOperationProgress.php remained unchanged because it already handed the correct run collection to the view.
  • T013 [US2] Update apps/platform/app/Support/OpsUx/ActiveRuns.php only if needed so shell-visible progress availability stays aligned with the shared contract; if implementation reveals another consumer with local progress math, stop and update the spec, plan, and checklist before touching it.
    • Note: no ActiveRuns.php change was required; no second shell-visible local progress calculator was found.

Checkpoint: User Story 2 is independently functional when the shell surface no longer owns progress semantics ad hoc.


Phase 5: User Story 3 - Document future-safe progress boundaries (Priority: P2)

Goal: the UI standards and feature package define how future counted, phased, and composite work must extend the contract.

Independent Test: review the standards update and the focused proving suite together, then confirm that counted rollout, phase/composite rollout, and dashboard follow-up remain named follow-up specs rather than hidden scope here.

Implementation for User Story 3

  • T014 [US3] Update docs/ui/tenantpilot-enterprise-ui-standards.md with canonical progress modes, the rule that processed and total are the only v1 determinate source, the rule that outcome counters remain outcome-only, the queued indeterminate rule, the terminal no-progress rule, and the safe future boundaries for phased and composite categories.
  • T015 [US3] Review the resulting implementation to confirm it introduces no new summary_counts keys, no writer rollout, no dashboard-specific progress surface, and no persisted progress mode.

Checkpoint: User Story 3 is independently functional when the standards doc and feature package leave clear extension rules for later specs.


Phase 6: Polish & Cross-Cutting Validation

Purpose: validate the bounded slice, stop drift, and hand off a clean implementation path.

  • T016 [P] Run export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php.
  • T017 [P] Run 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/OpsUx/SummaryCountsWhitelistTest.php.
  • T018 [P] Run export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent for touched platform files.
  • T019 [P] Review touched code against docs/ui/tenantpilot-enterprise-ui-standards.md and confirm the shell remains decision-first, diagnostics-light, Filament-native, and backed by one shared progress contract.
  • T020 [P] Review touched code to confirm Filament stays on Livewire v4, provider registration remains unchanged in apps/platform/bootstrap/providers.php, no new assets were registered, and no new OperationRun lifecycle or notification path was introduced.
  • T021 [P] Review touched code to confirm the implementation reuses existing poller families and introduces no new parallel polling loops while adopting the shared progress contract.

Dependencies & Execution Order

Phase Dependencies

  • Phase 1 (Setup): no dependencies; start immediately.
  • Phase 2 (Foundational): depends on Phase 1 and blocks user-story work.
  • Phase 3 (US1): depends on Phase 2 and establishes the shared progress contract.
  • Phase 4 (US2): depends on Phase 3 because the shell must consume the shared contract rather than invent its own logic.
  • Phase 5 (US3): depends on Phase 3 and should land with US2 so the contract and extension boundaries stay aligned.
  • Phase 6 (Polish): depends on all desired user stories being complete.

User Story Dependencies

  • US1 (P1): independently testable after Phase 2 and delivers the core enterprise-truth contract.
  • US2 (P1): independently testable after Phase 3 and delivers the real visible shell adoption.
  • US3 (P2): independently testable after Phase 3 and is still required for package completion because future rollout ownership is part of the approved scope.

Within Each User Story

  • Write the listed Pest coverage first and make it fail for the intended gap.
  • Land the shared progress helper before removing local shell math.
  • Re-run the narrowest affected validation command after each story checkpoint before moving on.

Implementation Strategy

Suggested MVP Scope

  • MVP = US1 + US2, because the package only delivers value once the shared contract exists and the current visible shell host consumes it.

Incremental Delivery

  1. Complete Phase 1 and Phase 2.
  2. Deliver US1.
  3. Deliver US2 on top of the shared helper.
  4. Add US3 documentation and boundary hardening.
  5. Finish with focused validation and formatting.

Team Strategy

  1. Settle the shared contract and unit proof owner first.
  2. Keep shell-adoption edits serialized around BulkOperationProgress and its Blade view.
  3. Do not widen into writer rollout or dashboard follow-up while implementing this package.

Deferred Follow-Ups / Non-Goals

  • 271 — Counted Progress Rollout v1
  • 272 — OperationRun Phase & Composite Progress v1
  • 273 — Tenant Dashboard Active Operations Summary Card
  • any browser-smoke expansion beyond the currently-owned Spec 268 overlap proof
  • any new writer-side rollout that adds or changes summary_counts.total or summary_counts.processed
  • any persisted progress mode, registry, or dashboard redesign