--- description: "Task list for Counted Progress Rollout v1" --- # Tasks: Counted Progress Rollout v1 **Input**: Design documents from `specs/271-counted-progress-rollout/` **Prerequisites**: `specs/271-counted-progress-rollout/spec.md`, `specs/271-counted-progress-rollout/plan.md`, `specs/271-counted-progress-rollout/checklists/requirements.md` **Review Artifact**: `specs/271-counted-progress-rollout/checklists/requirements.md` is the outcome-of-record for the review outcome class, workflow outcome, and test-governance outcome. If implementation widens into baseline phase/composite rollout, dashboard work, or a new persisted progress model, update that artifact before continuing. **Tests**: REQUIRED (Pest). Keep proof bounded to existing Unit plus Feature suites for Ops-UX, inventory, review packs, evidence snapshots, and backup sets. Browser coverage remains owned by `specs/268-operationrun-activity-feedback/` and must not become a hidden requirement here. **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; counted progress must remain invisible for inaccessible runs. **Shared Pattern Reuse**: Reuse `OperationRunProgressContract`, `SummaryCountsNormalizer`, `OperationSummaryKeys`, `OperationRunService`, existing shell progress adopters, and `docs/ui/tenantpilot-enterprise-ui-standards.md`. Do not create a second local progress helper in Blade, Livewire, or jobs. **Filament / Panel Guardrails**: Filament remains v5 on Livewire v4. Provider registration remains unchanged in `apps/platform/bootstrap/providers.php`. No new panel, resource, global-search behavior, or asset strategy is allowed. This slice changes run-count truth only. **Organization**: Tasks are grouped by user story so inventory sync, artifact generation, enumerated backup-set add/restore fan-out, and the future-boundary documentation remain independently reviewable. ## Test Governance Notes - Lane mix stays Unit plus Feature. - Prefer extending existing domain suites before creating a new family. - 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 manual-promotion slice, the inherited Ops-UX rules, and the repo-real stable-unit seams before runtime edits begin. - [x] T001 Review `specs/271-counted-progress-rollout/spec.md`, `specs/271-counted-progress-rollout/plan.md`, `specs/271-counted-progress-rollout/checklists/requirements.md`, `docs/product/spec-candidates.md`, `docs/product/roadmap.md`, `specs/270-operationrun-progress-contract/spec.md`, `specs/268-operationrun-activity-feedback/spec.md`, `docs/ui/tenantpilot-enterprise-ui-standards.md`, and `.specify/memory/constitution.md` together so the slice stays on repo-real counted progress and keeps baseline phase/composite work explicitly out of scope. - [x] T002 [P] Confirm the current writer and sanitizer seams in `apps/platform/app/Services/OperationRunService.php`, `apps/platform/app/Support/OpsUx/OperationRunProgressContract.php`, `apps/platform/app/Support/OpsUx/SummaryCountsNormalizer.php`, and `apps/platform/app/Support/OpsUx/OperationSummaryKeys.php`. - [x] T003 [P] Confirm the selected stable-unit writer seams in `apps/platform/app/Jobs/RunInventorySyncJob.php`, `apps/platform/app/Jobs/GenerateReviewPackJob.php`, `apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php`, `apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php`, `apps/platform/app/Jobs/BulkBackupSetRestoreJob.php`, and `apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php`. - [x] T004 [P] Confirm the explicit exclusions in `apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php` and `apps/platform/app/Jobs/CompareBaselineToTenantJob.php`, then confirm the shell-proof owners in `apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php`, `apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php`, and `apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php`. --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: settle the shared contract guardrail and the focused proof owners before domain jobs are changed. **Critical**: no user-story runtime work should begin until this phase is complete. - [x] T005 [P] Create or extend failing coverage in `apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php` for the selected counted run shapes and the explicit rule that baseline capture/compare remain phased under the current contract. - [x] T006 [P] Extend `apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php` and `apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php` so the shell shows counted progress only when a selected run family emits trustworthy `processed` and `total`, and stays indeterminate or non-counted elsewhere. - [x] T007 [P] Extend `apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php` only if needed so the rollout still reuses numeric-only whitelist semantics, introduces no new summary keys, and does not allow outcome counters to masquerade as progress. **Checkpoint**: the shared contract boundary and focused proof owners are settled before implementation begins. --- ## Phase 3: User Story 1 - See truthful counted progress for inventory sync (Priority: P1) **Goal**: inventory sync exposes truthful counted progress from its current deterministic work-unit set. **Independent Test**: start a sync run with multiple attempted work units, drive mixed outcomes, and verify that `total` initializes once, `processed` increments once per completed unit, and the shell can render counted progress while the run is active. ### Tests for User Story 1 - [x] T008 [P] [US1] Extend `apps/platform/tests/Feature/Inventory/RunInventorySyncJobTest.php` for deterministic `total` initialization, zero-unit handling, one-per-unit `processed` increments, mixed success/failure handling, and `processed <= total` invariants. ### Implementation for User Story 1 - [x] T009 [US1] Update `apps/platform/app/Jobs/RunInventorySyncJob.php` and `apps/platform/app/Services/Inventory/InventorySyncService.php` only as needed so inventory sync seeds `summary_counts.total` from deterministic attempted work units and increments `processed` exactly once per completed unit through `OperationRunService`. - [x] T010 [US1] Review the inventory-sync terminal summary merge path so completion preserves truthful counted progress and does not overwrite running counts with incompatible totals or outcome math. **Checkpoint**: User Story 1 is independently functional when inventory sync can truthfully enter counted mode without changing the shared contract. --- ## Phase 4: User Story 2 - See truthful counted progress for review and evidence artifact generation (Priority: P1) **Goal**: review-pack generation and evidence-snapshot generation expose truthful counted progress from the deterministic work sets already present in repo truth. **Independent Test**: queue both run families, verify each job initializes `total` from its current deterministic work set, increments `processed` as work items complete, and leaves the shell on truthful counted or non-counted states only. ### Tests for User Story 2 - [x] T011 [P] [US2] Extend `apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php` and `apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php` for deterministic `total` initialization, zero-unit handling, running `processed` increments, and truthful terminal behavior. - [x] T012 [P] [US2] Extend `apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php` or `apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php` only as needed so the shell proves counted adoption for these writer shapes without introducing view-local progress math. ### Implementation for User Story 2 - [x] T013 [US2] Update `apps/platform/app/Jobs/GenerateReviewPackJob.php` and `apps/platform/app/Services/ReviewPackService.php` only as needed so `summary_counts.total` comes from the final post-option-filtered file map and `processed` advances as archive entries are written. - [x] T014 [US2] Update `apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php` and `apps/platform/app/Services/Evidence/EvidenceSnapshotService.php` only as needed so `summary_counts.total` comes from the persisted payload item set and `processed` advances once per created item. - [x] T015 [US2] Review review-pack and evidence failure paths so terminal outcomes remain authoritative and no stale counted progress or impossible percentages survive a failed run. **Checkpoint**: User Story 2 is independently functional when artifact-generation runs can truthfully enter counted mode through the existing contract. --- ## Phase 5: User Story 3 - Standardize counted progress for existing backup and restore fan-out paths (Priority: P2) **Goal**: current backup/restore fan-out paths follow one total/processed discipline rather than a mix of partial or launcher-only count behavior. **Independent Test**: execute current backup-set add and bulk restore flows with mixed success, skip, and failure results, then verify that parent totals initialize once, child workers advance `processed` exactly once per planned unit, and `maybeCompleteBulkRun()` owns parent completion. ### Tests for User Story 3 - [x] T016 [P] [US3] Extend `apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php` and `apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php` for one-time `total` initialization, zero-unit handling, exact `processed` increments, mixed child outcomes, and helper-owned completion. - [x] T017 [P] [US3] Review `apps/platform/app/Jobs/Operations/BackupSetDeleteWorkerJob.php` and `apps/platform/app/Jobs/Operations/BackupSetForceDeleteWorkerJob.php` only to confirm they remain out of scope for `271`; record that exclusion or any follow-up in the review artifact instead of widening the implementation slice. ### Implementation for User Story 3 - [x] T018 [US3] Standardize `apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php`, `apps/platform/app/Jobs/BulkBackupSetRestoreJob.php`, and `apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php` on one total/processed discipline through `OperationRunService` helpers. - [x] T019 [US3] Keep the backup/restore rollout limited to `AddPoliciesToBackupSetJob`, `BulkBackupSetRestoreJob`, and `BackupSetRestoreWorkerJob`; record any additional seam as follow-up explicitly instead of widening the implementation slice. - [x] T020 [US3] Review parent/child retry, archived, not-found, and skipped paths so `processed` advances exactly once per planned unit and parent completion remains helper-owned. **Checkpoint**: User Story 3 is independently functional when the selected backup/restore fan-out paths share one truthful count discipline. --- ## Phase 6: User Story 4 - Preserve the future boundary in standards and review artifacts (Priority: P2) **Goal**: future contributors can extend counted progress without silently widening this slice into phase/composite rollout or a second progress framework. **Independent Test**: review the standards update and the completed proof list together, then confirm that baseline phase/composite rollout, dashboard work, and any non-deterministic writer families remain named follow-ups rather than hidden scope here. ### Implementation for User Story 4 - [x] T021 [US4] Update `docs/ui/tenantpilot-enterprise-ui-standards.md` with the current counted-rollout rules: `processed` and `total` remain the only determinate v1 source, outcome counters remain outcome-only, and baseline phase/composite families stay excluded until their follow-up spec. - [x] T022 [US4] Review the resulting package and touched code to confirm there is still no baseline phase/composite widening, no second progress helper, no new summary key, no new panel/asset/global-search change, and no new notification-policy change. **Checkpoint**: User Story 4 is independently functional when future-extension boundaries are explicit in both docs and the feature package. --- ## Phase 7: Polish & Cross-Cutting Validation **Purpose**: validate the bounded slice, stop drift, and hand off a clean implementation path. - [x] T023 [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`. - [x] T024 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Inventory/RunInventorySyncJobTest.php tests/Feature/ReviewPack/ReviewPackGenerationTest.php tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php tests/Unit/BulkBackupSetRestoreJobTest.php tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php`. - [x] T025 [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. - [x] T026 [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. - [x] T027 [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. --- ## 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 first truthful counted writer family. - **Phase 4 (US2)**: depends on Phase 2 and should land after or alongside US1 so artifact-generation runs adopt the same count discipline. - **Phase 5 (US3)**: depends on Phase 2 and should land after the first counted families so backup/restore fan-out follows the same helper-owned pattern. - **Phase 6 (US4)**: depends on Phases 3 through 5 so the documented boundary matches the implemented slice. - **Phase 7 (Polish)**: depends on all desired user stories being complete. ### User Story Dependencies - **US1 (P1)**: independently testable after Phase 2 and delivers the cleanest counted rollout target. - **US2 (P1)**: independently testable after Phase 2 and delivers visible counted progress for governance artifact generation. - **US3 (P2)**: independently testable after Phase 2 and completes the approved backup/restore fan-out part of the candidate. - **US4 (P2)**: independently testable after Phases 3 through 5 and is required for package completion because the narrowed `271`/`272` boundary is part of the approved scope. ### Within Each User Story - Write or extend the listed Pest coverage first and make it fail for the intended gap. - Land the writer-side counted-truth changes before adjusting any shared shell assertions that depend on those writers. - Re-run the narrowest affected validation command after each story checkpoint before moving on. --- ## Implementation Strategy ### Suggested MVP Scope - MVP = **US1 + US2**, because the first enterprise-visible value arrives once inventory and artifact-generation runs can truthfully enter counted mode through the current shell adopter. ### Incremental Delivery 1. Complete Phase 1 and Phase 2. 2. Deliver US1. 3. Deliver US2. 4. Deliver US3. 5. Land US4 documentation and boundary hardening. 6. Finish with focused validation and formatting. ### Team Strategy 1. Settle the shared contract boundary and proof owners first. 2. Keep inventory, artifact-generation, and backup/restore edits serialized per family. 3. Do not widen into baseline phase/composite rollout, dashboard follow-up work, or a second progress framework while implementing this package. --- ## Deferred Follow-Ups / Non-Goals - `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 cannot prove deterministic work units - any persisted progress mode, registry, or dashboard redesign