TenantAtlas/specs/360-operationrun-canonical-cutover-cleanup/tasks.md
ahmido 840c9bd28d refactor: rename ManagedEnvironment context badge to Environment context (#431)
Renames ManagedEnvironment context badge to Environment context as requested.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #431
2026-06-06 20:30:26 +00:00

19 KiB

Tasks: OperationRun Canonical Cutover Cleanup

Input: specs/360-operationrun-canonical-cutover-cleanup/spec.md, plan.md, and checklists/requirements.md
Prerequisites: spec.md and plan.md
Tests: REQUIRED (Pest). Keep proof bounded to Unit + Feature + PGSQL + one explicit Browser smoke.
Operations: Reuse current OperationRun lifecycle ownership. No new run status column, no new queue family, no new schema, and no destructive cleanup.
RBAC: Reuse current workspace-first run access plus current review capabilities. No new capability strings, no widened route access, and no cross-scope artifact resolution.
Shared Pattern Reuse: Reuse OperationRunService, current operations surfaces, OperationRunLinks, ArtifactTruthPresenter, and current review-start feedback. Introduce only one bounded adapter contract/registry-orchestrator seam plus one bounded run-correlation resolver.
Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration stays in apps/platform/bootstrap/providers.php. No new panel, route family, or asset strategy is allowed.
Organization: Tasks are grouped by user story so the adapter seam, dispatch/correlation truth, read-side canonicalization, and spec-closeout work remain independently reviewable.

Repo Baseline At Prep Time

  • Branch: 360-operationrun-canonical-cutover-cleanup
  • HEAD: 3a750726 feat: implement review compose reconciliation adapter (spec 359) (#430)
  • git status --short --branch before Spec 360 prep: clean on platform-dev; Spec Kit created this feature branch and copied the spec/plan templates
  • Spec 359 merge baseline: merged runtime behavior is the functional starting point; PGSQL validation remained locally blocked at merge time
  • Relevant runtime surfaces:
    • apps/platform/app/Services/AdapterRunReconciler.php
    • apps/platform/app/Services/OperationRunService.php
    • apps/platform/app/Jobs/ComposeEnvironmentReviewJob.php
    • apps/platform/app/Jobs/Middleware/TrackOperationRun.php
    • apps/platform/app/Jobs/Concerns/BridgesFailedOperationRun.php
    • apps/platform/app/Support/Operations/Reconciliation/EnvironmentReviewComposeDecision.php
    • apps/platform/app/Support/OperationCatalog.php
    • apps/platform/app/Support/OperationRunType.php
    • apps/platform/app/Support/OperationRunLinks.php
    • apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php
    • apps/platform/app/Support/OpsUx/OperationUxPresenter.php
    • apps/platform/app/Filament/Resources/OperationRunResource.php
    • apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
    • apps/platform/app/Filament/Resources/EnvironmentReviewResource.php
    • apps/platform/database/factories/OperationRunFactory.php
    • apps/platform/tests/Unit/Support/OperationTypeResolutionTest.php
  • Completed-spec context only: Spec 358 is the generic queue-truth baseline; do not rewrite its historical readiness or validation record
  • Historical numbering note: older references to another placeholder Spec 360 in specs/355-platform-sellable-smoke-matrix/ are context only and must not be treated as an existing spec package

Test Governance Checklist

  • Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in the smallest honest family, and the Browser or PGSQL additions remain explicit.
  • Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
  • Planned validation commands cover the change without widening into unrelated lane cost.
  • The declared monitoring/detail surface profile is explicit.
  • Any material budget, baseline, trend, or escalation note is recorded in the active feature close-out.

Phase 1: Setup (Repo Truth Inventory)

Purpose: confirm the merged Spec 359 baseline, the current cutover gaps, and the exact repo surfaces before runtime edits begin.

  • T001 Re-read spec.md, plan.md, checklists/requirements.md, .specify/memory/constitution.md, docs/ai-coding-rules.md, docs/architecture-guidelines.md, docs/testing-guidelines.md, docs/security-guidelines.md, docs/filament-guidelines.md, and specs/358-operationrun-queue-truth-foundation/{spec,plan,tasks}.md plus specs/359-operationrun-reconciliation-adapter-framework-review-compose-adapter/{spec,plan,tasks}.md together before touching runtime code.
  • T002 [P] Confirm the current reconciliation and write seams in apps/platform/app/Services/AdapterRunReconciler.php, apps/platform/app/Services/OperationRunService.php, apps/platform/app/Models/OperationRun.php, and apps/platform/app/Support/Operations/Reconciliation/EnvironmentReviewComposeDecision.php.
  • T003 [P] Confirm the current queue correlation seams in apps/platform/app/Jobs/Middleware/TrackOperationRun.php, apps/platform/app/Jobs/Concerns/BridgesFailedOperationRun.php, and the job classes that currently expose operationRunId, operationRun, or other correlation properties.
  • T004 [P] Confirm the current canonical type and read-side seams in apps/platform/app/Support/OperationCatalog.php, apps/platform/app/Support/OperationRunType.php, apps/platform/app/Support/OperationRunLinks.php, apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php, and apps/platform/database/factories/OperationRunFactory.php.
  • T005 Confirm that no new schema, no new panel/provider path, no new asset registration, and no new business adapter family are required; record any tension as reject-or-split instead of silently widening scope.
  • T005A Update specs/359-operationrun-reconciliation-adapter-framework-review-compose-adapter/tasks.md so the merged baseline, blocked PGSQL note, and deferred Spec 360 follow-through are explicit; completed during Spec 360 prep.

Phase 2: Foundational (Canonical Adapter and Service-Owned Metadata)

Purpose: settle one canonical adapter extension seam and keep all reconciliation writes in OperationRunService before touching jobs or readers.

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

  • T006 [P] Add failing Unit coverage in apps/platform/tests/Unit/Support/Operations/Reconciliation/Spec360CanonicalAdapterRegistryTest.php for adapter resolution of restore.execute, environment.review.compose, and unsupported types.
  • T007 [P] Add failing Unit coverage in apps/platform/tests/Unit/Support/Operations/Reconciliation/Spec360ReconciliationContextFormatTest.php for canonical context.reconciliation shape, idempotent merge behavior, previous status/outcome preservation, and related metadata normalization.
  • T008 Introduce the canonical adapter contract and registration or orchestration seam under apps/platform/app/Support/Operations/Reconciliation/ and refactor apps/platform/app/Services/AdapterRunReconciler.php so future adapters register instead of expanding a central match.
  • T009 Extend apps/platform/app/Services/OperationRunService.php so updateRunWithReconciliation() writes only the canonical context.reconciliation payload, normalizes related.type and related.id, and removes duplicate compatibility fields that are no longer justified.
  • T010 Keep restore behavior intact by moving restore.execute onto the same canonical adapter seam without broadening restore business logic or introducing a second write path.
  • T011 Update or add focused Unit coverage to prove adapter-owned paths cannot persist reconciliation state directly outside OperationRunService.

Checkpoint: one canonical adapter extension seam exists, OperationRunService still owns lifecycle writes, and current restore behavior remains functionally intact.


Phase 3: User Story 1 - Canonicalize the adapter-owned reconciliation seam (Priority: P1)

Goal: review-compose reconciliation becomes fully adapter or decision owned, and ComposeEnvironmentReviewJob becomes orchestration only.

Independent Test: run focused Unit and Feature coverage showing that review-compose decisions finalize through the canonical adapter seam and that the job no longer owns business reconciliation logic.

Tests for User Story 1

  • T012 [P] [US1] Add apps/platform/tests/Feature/Operations/Spec360CanonicalReconciliationCutoverTest.php covering adapter-owned review-compose finalization, unsupported handling, and service-owned reconciliation writes.
  • T013 [P] [US1] Add or extend focused duplicate and lineage coverage in apps/platform/tests/Feature/EnvironmentReview/Spec360ReviewComposeAdapterOwnershipTest.php so duplicate fingerprint recovery and superseded review lineages prove the adapter-owned path rather than job-local fallback behavior.

Implementation for User Story 1

  • T014 [US1] Refactor apps/platform/app/Jobs/ComposeEnvironmentReviewJob.php so it loads scope, delegates reconciliation decisions, delegates composition, and never writes business reconciliation metadata directly.
  • T015 [US1] Keep review-compose business truth inside apps/platform/app/Support/Operations/Reconciliation/EnvironmentReviewComposeDecision.php and any new local adapter class under apps/platform/app/Support/Operations/Reconciliation/, including duplicate recovery, ambiguous lineage, and scope-safety decisions.
  • T016 [US1] Keep apps/platform/app/Services/EnvironmentReviews/EnvironmentReviewService.php and apps/platform/app/Services/EnvironmentReviews/EnvironmentReviewComposer.php free of direct OperationRun reconciliation mutation and broad adapter knowledge.
  • T017 [US1] Ensure duplicate fingerprint recovery still ends in deterministic succeeded, blocked, or attention-required outcomes without ghost runs and without raw SQL becoming primary operator-facing truth.

Checkpoint: review-compose reconciliation is fully adapter-owned and the job is orchestration only.


Phase 4: User Story 2 - Align queued dispatch and failed-job correlation truth (Priority: P1)

Goal: queued dispatch metadata and failed-job correlation resolve through one canonical contract.

Independent Test: run focused Unit and Feature coverage showing that queued runs record canonical context.dispatch and that middleware plus failed-job bridging resolve the same OperationRun.

Tests for User Story 2

  • T018 [P] [US2] Add apps/platform/tests/Unit/Support/OperationRunDispatchContextTest.php for canonical context.dispatch keys, no synthetic job id, and canonical correlation version behavior.
  • T019 [P] [US2] Add apps/platform/tests/Feature/Operations/Spec360DispatchCorrelationTest.php covering shared correlation between TrackOperationRun, BridgesFailedOperationRun, and OperationRunService::dispatchOrFail().
  • T020 [P] [US2] Add PGSQL-sensitive duplicate or lock-aware follow-through to the Spec360 feature coverage where queue correlation or duplicate recovery depends on partial unique-index truth.

Implementation for User Story 2

  • T021 [US2] Extend apps/platform/app/Services/OperationRunService.php so dispatchOrFail() or the shared dispatch seam writes canonical context.dispatch metadata with job_class, queue, connection, dispatched_at, correlation_version, and operation_run_id.
  • T022 [US2] Introduce one shared run-correlation resolver or contract under apps/platform/app/Jobs/ or apps/platform/app/Support/Operations/ and update only apps/platform/app/Jobs/Middleware/TrackOperationRun.php plus apps/platform/app/Jobs/Concerns/BridgesFailedOperationRun.php to use it.
  • T023 [US2] Normalize only the directly touched OperationRunService::dispatchOrFail() lifecycle path to the canonical operationRunId or equivalent shared correlation contract, and remove hidden fallback property scanning there where it is no longer justified.
  • T024 [US2] Ensure unsupported or out-of-scope jobs fail closed: they may skip correlation cleanly, but they must not claim a wrong OperationRun, invent orphan semantics from missing queue ids, or pull unrelated bulkRunId or runId cleanup into this spec.

Checkpoint: dispatch metadata is canonical and middleware plus failed-job bridging share one correlation rule.


Phase 5: User Story 3 - Cut readers and operation-type truth over to canonical metadata (Priority: P2)

Goal: readers, writers, and operator-facing copy rely on canonical related metadata and canonical operation-type values instead of broad legacy fallback behavior.

Independent Test: run focused Unit, Feature, and one bounded Browser smoke to prove canonical type writes, canonical related metadata resolution, and calm operator wording on existing operations surfaces.

Tests for User Story 3

  • T025 [P] [US3] Add apps/platform/tests/Unit/Support/OperationTypeCanonicalizationTest.php or extend apps/platform/tests/Unit/Support/OperationTypeResolutionTest.php so current write paths and read-side alias inventory reflect the new canonical-only posture.
  • T026 [P] [US3] Add or extend focused read-side coverage for canonical related metadata in apps/platform/tests/Feature/Operations/Spec360CanonicalReconciliationCutoverTest.php or a companion feature file that exercises OperationRunLinks and ArtifactTruthPresenter.
  • T027 [P] [US3] Add apps/platform/tests/Browser/Spec360OperationRunCanonicalCutoverSmokeTest.php covering reconciled review-compose, stale queue truth from Spec 358, and canonical related review link behavior on the existing operations surfaces.

Implementation for User Story 3

  • T028 [US3] Update apps/platform/app/Support/OperationCatalog.php, apps/platform/app/Support/OperationRunType.php, apps/platform/app/Models/OperationRun.php, and apps/platform/database/factories/OperationRunFactory.php so touched writers use canonical operation types and unnecessary alias compatibility is removed or explicitly justified.
  • T029 [US3] Update apps/platform/app/Support/OperationRunLinks.php and apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php to prefer context.reconciliation.related before falling back to historical operation_run_id linkage, removing the fallback where pre-production history is the only reason it exists.
  • T030 [US3] Update apps/platform/app/Support/OpsUx/OperationUxPresenter.php, apps/platform/app/Filament/Resources/OperationRunResource.php, apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php, and apps/platform/app/Filament/Resources/EnvironmentReviewResource.php only as needed so existing operator surfaces stay calm and canonical.

Checkpoint: touched writers are canonical-only, readers prefer canonical related metadata, and existing operations surfaces explain the cutover calmly.


Phase 6: Polish & Validation

  • T032 [P] Refresh spec.md, plan.md, and checklists/requirements.md only if implementation proves a thinner or broader touched-file boundary than this prep package.
  • T033 [P] Run the primary in-scope fast-feedback or confidence gate:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec360
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec359
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec358
  • T034 [P] Run cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml --filter=Spec360.
  • T035 [P] Run the primary in-scope browser smoke:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec360OperationRunCanonicalCutoverSmokeTest.php
  • T036 [P] Run the bounded contextual review/report regressions from the active spec:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/CustomerReviewWorkspaceSmokeTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec357ReportProfilesSmokeTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/Spec357RenderedReportProfileTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/ReviewPackDownloadTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/EnvironmentReviewDerivedReviewPackTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/EnvironmentReviewExecutivePackTest.php
  • T037A [P] Run the known external probes separately and record them explicitly instead of silently folding them into the primary merge gate:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec347ReviewPackOutputReadinessSmokeTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EnvironmentReviewHeaderDisciplineTest.php
  • T038 [P] Run cd apps/platform && ./vendor/bin/pint --dirty.
  • T039 [P] Run git diff --check.
  • T040 [P] Record the final adapter contract shape, dispatch contract shape, correlation rule, alias-retirement decision, and bounded UI wording outcome in the active feature close-out entry Guardrail / Smoke Coverage.

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): no dependencies
  • Foundational (Phase 2): depends on Setup and blocks all story work
  • US1 (Phase 3): depends on Foundational completion
  • US2 (Phase 4): depends on Foundational completion and should land before broad reader cleanup
  • US3 (Phase 5): depends on US1 and US2 because canonical related metadata and canonical type truth rely on the settled adapter and dispatch contracts
  • Polish (Phase 6): depends on all desired user stories

Parallel Opportunities

  • T002, T003, and T004 can run in parallel.
  • T006 and T007 can run in parallel.
  • T012 and T013 can run in parallel.
  • T018, T019, and T020 can run in parallel.
  • T025, T026, and T027 can run in parallel.
  • T033 through T039 can run in parallel after implementation stabilizes, but the primary merge gate should be read out separately from contextual regressions and external probes.

Implementation Strategy

  1. Freeze the merged Spec 359 baseline and remove misleading artifact drift first.
  2. Land the canonical adapter and service-owned metadata seam before job or reader cleanup.
  3. Land dispatch and failed-job correlation on one contract before cutting readers and type writes over.
  4. Finish with canonical related-metadata readers, calm operator wording, and the bounded validation suite.

Non-Goals / Must-Not-Do

  • NT001 Do not add a new reconciled status column, boolean, or separate OperationRun truth table.
  • NT002 Do not add report, evidence, sync, backup, restore, or alert delivery business adapters in this feature.
  • NT003 Do not add a new queue/job family, a second operator-center UI, or a speculative provider framework.
  • NT004 Do not add compatibility shims or dual-write logic solely to preserve pre-production historical aliases or old fixtures.
  • NT005 Do not expose raw SQL, duplicate-key, or low-level framework error wording on operator-primary surfaces.