TenantAtlas/specs/271-counted-progress-rollout/plan.md
2026-05-05 02:26:31 +02:00

17 KiB

Implementation Plan: Counted Progress Rollout v1

Branch: 271-counted-progress-rollout | Date: 2026-05-05 | Spec: spec.md Input: Feature specification from /specs/271-counted-progress-rollout/spec.md

Summary

This plan prepares one bounded writer-rollout slice on top of the existing shared progress contract from Spec 270. The implementation path is to reuse OperationRunProgressContract and OperationRunService, add truthful total plus processed writes only where the repo already exposes deterministic work units, and leave baseline capture/compare on their current phased path. The slice must not invent totals, widen into phase/composite work, add new summary_counts keys, or redesign current Ops-UX surfaces.

Inherited Baseline / Explicit Delta

Inherited baseline

  • App\Support\OpsUx\OperationRunProgressContract already centralizes none, activity, counted, phased, and composite progress modes.
  • App\Services\OperationRunService already owns updateRun(), incrementSummaryCounts(), and maybeCompleteBulkRun() as the authoritative summary-count mutation path.
  • The current tenant shell adopter already consumes the shared progress contract and can render determinate counted progress when trustworthy counts exist.
  • Inventory sync, review-pack generation, evidence-snapshot generation, AddPoliciesToBackupSetJob, BulkBackupSetRestoreJob, and BackupSetRestoreWorkerJob are already repo-real workflows with current tests.
  • Baseline capture and baseline compare already expose evidence-capture phase hints, which the current progress contract classifies as phased before counted.

Explicit delta in this plan

  • roll out truthful counted inputs for selected stable-unit run families only
  • standardize parent and child count discipline across AddPoliciesToBackupSetJob, BulkBackupSetRestoreJob, and BackupSetRestoreWorkerJob
  • keep current shell and Operations detail surfaces unchanged except for consuming newly truthful count data
  • document the narrowed scope deviation from the original candidate wording: baseline capture/compare remain deferred because repo truth now places them on the phased/composite path

Technical Context

Language/Version: PHP 8.4, Laravel 12, Filament v5, Livewire v4
Primary Dependencies: current Ops-UX support classes, native Filament/Livewire shell feedback, Pest v4
Storage: PostgreSQL via existing operation_runs, review-pack, evidence-snapshot, backup-set, and restore 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 query families, no new polling loops, and no slower-than-current active-operation feedback
Constraints: no new summary_counts keys, no new persistence, no contract-precedence change, and no broad writer sweep
Scale/Scope: one shared contract reused across 4 selected run families plus one standards update and focused regression coverage

Likely Affected Repo Surfaces

  • apps/platform/app/Support/OpsUx/OperationRunProgressContract.php
  • apps/platform/app/Support/OpsUx/SummaryCountsNormalizer.php
  • apps/platform/app/Support/OpsUx/OperationSummaryKeys.php
  • apps/platform/app/Services/OperationRunService.php
  • apps/platform/app/Jobs/RunInventorySyncJob.php
  • apps/platform/app/Services/Inventory/InventorySyncService.php
  • apps/platform/app/Jobs/GenerateReviewPackJob.php
  • apps/platform/app/Services/ReviewPackService.php
  • apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php
  • apps/platform/app/Services/Evidence/EvidenceSnapshotService.php
  • apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php
  • apps/platform/app/Jobs/BulkBackupSetRestoreJob.php
  • apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php
  • apps/platform/tests/Unit/Support/OpsUx/OperationRunProgressContractTest.php
  • apps/platform/tests/Feature/Inventory/RunInventorySyncJobTest.php
  • apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php
  • apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php
  • apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php
  • apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php
  • apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php
  • apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.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, widget family, or dashboard card is introduced.
  • The shell stays decision-first. This slice changes only whether selected runs can legitimately enter the already-existing counted mode.
  • Operations collection/detail pages remain diagnostics-first drill-through targets. They inherit more truthful count data but no new layout or action model.
  • No panel registration, asset registration, or global-search changes are planned.

RBAC / Policy Fit

  • Existing capability gates for the initiating surfaces 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 remains on the existing launch and detail surfaces.

Audit / Logging Fit

  • Existing queued toasts and terminal notifications remain authoritative and unchanged.
  • Existing run audit remains the only audit trail for the counted rollout. No new run-local audit channel is introduced.
  • Parent/child bulk completion still flows through existing OperationRunService helpers instead of feature-local completion code.

Data & Query Fit

  • Progress truth remains fully derived from operation_runs.summary_counts plus existing contract logic.
  • Determinate progress stays limited to work with deterministic units known before or during processing.
  • Outcome counters remain summary truth and do not replace processed.
  • No migration, no new JSON schema, no cache layer, and no new persisted 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 run summaries
  • State layers in scope: shell
  • 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 progress mode derived from the shared contract
  • 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, summary-count service helpers, inventory/review/evidence/backup writers, shell adopter
  • Shared abstractions reused: OperationRunProgressContract, OperationRunService, SummaryCountsNormalizer, OperationSummaryKeys
  • New abstraction introduced? why?: none planned
  • Why the existing abstraction was sufficient or insufficient: rendering semantics are already centralized; the missing piece is writer-side counted input for specific repo-real workflows
  • Bounded deviation / spread control: keep all count mutation on OperationRunService; any run family without deterministic units stays out of scope rather than adding a local exception

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, for progress truth 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: launch inputs and current domain-specific validation 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: OperationRun truth, progress contract, shell feedback
  • Neutral platform terms / contracts preserved: Operation, progress, counted progress, activity, terminal outcome
  • 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 only enriches execution feedback over current OperationRun truth.
  • Read/write separation: PASS. No new external write path is introduced; current domain jobs keep their existing behavior and only improve run-count truth.
  • Graph contract path: PASS. No new Graph/provider seam is introduced.
  • Deterministic capabilities: PASS. Authorization and progress eligibility stay deterministic and testable.
  • RBAC-UX: PASS. Visibility remains on existing tenant/admin boundaries and 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; only count truth is enriched.
  • Ops-UX summary counts: PASS. The rollout stays on current whitelist semantics and numeric-only values.
  • Test governance: PASS. Proof remains bounded to Unit plus Feature.
  • Proportionality / no premature abstraction: PASS. No new abstraction or persistence is introduced.
  • Persisted truth / behavioral state: PASS. No new table, cache, or status 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 safeguards; Feature for selected writer rollouts and current shell adoption
  • Affected validation lanes: fast-feedback, confidence
  • Why this lane mix is the narrowest sufficient proof: domain feature suites already exist for the in-scope writer families, and the shared contract already has a focused unit suite. Browser proof remains owned by Spec 268 because this slice does not alter layout or clickability.
  • 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/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
  • Fixture / helper / factory / seed / context cost risks: low to moderate; reuse current tenant context helpers and current job-specific fixtures instead of introducing new provider-heavy harnesses
  • 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 families now emit truthful counts, excluded phased families remain excluded, and no writer bypasses OperationRunService
  • Budget / baseline / trend follow-up: none expected beyond a small feature-local increase
  • Review-stop questions: did any excluded run family sneak in, did any writer invent totals, did processed stay bounded by total, and did any new summary key or local progress helper appear?
  • Escalation path: reject-or-split for any baseline phased/composite widening, dashboard redesign, or persisted progress model
  • Active feature PR close-out entry: Guardrail / Smoke Coverage
  • Why no dedicated follow-up spec is needed: this package is itself the bounded writer-rollout follow-through on Spec 270; any remaining excluded families are already named as future follow-ups.

Project Structure

Documentation (this feature)

specs/271-counted-progress-rollout/
├── spec.md
├── plan.md
├── tasks.md
└── checklists/
    └── requirements.md

Source Code (expected implementation surfaces)

apps/platform/app/Support/OpsUx/
apps/platform/app/Services/OperationRunService.php
apps/platform/app/Jobs/RunInventorySyncJob.php
apps/platform/app/Services/Inventory/InventorySyncService.php
apps/platform/app/Jobs/GenerateReviewPackJob.php
apps/platform/app/Services/ReviewPackService.php
apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php
apps/platform/app/Services/Evidence/EvidenceSnapshotService.php
apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php
apps/platform/app/Jobs/BulkBackupSetRestoreJob.php
apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php
apps/platform/tests/Unit/Support/OpsUx/
apps/platform/tests/Feature/Inventory/
apps/platform/tests/Feature/ReviewPack/
apps/platform/tests/Feature/Evidence/
apps/platform/tests/Feature/BackupSets/
apps/platform/tests/Feature/OpsUx/
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 new progress rollout framework or a second writer abstraction.

Data / Migration Implications

  • No migration or schema change is planned.
  • No new persisted progress mode or preference is allowed.
  • No backfill is planned. Historical runs remain historical truth; the rollout affects future execution 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 run-count truth.
  • No destructive action or confirmation model changes are planned.
  • No deployment step beyond ordinary code deploy and current test validation is expected.

Risk Controls

  • Reject any implementation that changes progress-contract precedence to force phased runs into counted mode.
  • Reject any implementation that adds new summary_counts keys or uses outcome counters as hidden progress substitutes.
  • Reject any implementation that sets totals from speculative estimates instead of deterministic current work sets.
  • Reject any implementation that initializes parent totals multiple times or allows child retries to double-increment processed.
  • Reject any implementation that broadens the rollout to unrelated run families not named in the spec and tasks.

Implementation Phases

Phase 0 - Confirm Selected Stable-Unit Writer Seams

  • Verify current counted and terminal-only seams in inventory sync, review-pack generation, evidence-snapshot generation, AddPoliciesToBackupSetJob, BulkBackupSetRestoreJob, and BackupSetRestoreWorkerJob.
  • Reconfirm that baseline capture/compare remain phased under the current contract and stay out of scope.

Phase 1 - Roll Out Inventory And Artifact Writer Counts

  • Add or standardize total plus processed writes for inventory sync, review-pack generation, and evidence-snapshot generation.

Phase 2 - Standardize Enumerated Backup/Restore Fan-Out Counts

  • Align AddPoliciesToBackupSetJob, BulkBackupSetRestoreJob, and BackupSetRestoreWorkerJob on one total/processed discipline and current maybeCompleteBulkRun() semantics.

Phase 3 - Lock The Guardrail And Proof

  • Update the UI standards and focused tests so later run families do not re-open fake or partial counted rollout.

Proportionality Review

  • Current operator problem: determinable long-running work still looks indeterminate because selected writers do not persist counts early enough or consistently enough.
  • Existing structure is insufficient because: the shared contract already exists and cannot invent counted progress from terminal summaries alone.
  • Narrowest correct implementation: update only repo-verified stable-unit writers and leave all other families on their current truthful modes.
  • Ownership cost created: targeted job/service tests and one standards update.
  • Alternative intentionally rejected: broad all-writers rollout or phased-precedence changes were rejected because they would widen into a second spec.
  • Release truth: current-release truth. The repo already contains the contract, the visible adopter, and the selected writers needed for this rollout.