# Implementation Plan: Compare Job Legacy Drift Path Cleanup **Branch**: `205-compare-job-cleanup` | **Date**: 2026-04-14 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/205-compare-job-cleanup/spec.md` **Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/205-compare-job-cleanup/spec.md` **Note**: This plan treats Spec 205 as a mechanical closure cleanup. It removes only the dead pre-strategy drift-compute path from `CompareBaselineToTenantJob`, keeps the current strategy-driven compare execution unchanged, and uses focused regression plus guard coverage to prove no behavior drift. ## Summary Delete `computeDrift()` and its exclusive helper cluster from `CompareBaselineToTenantJob`, preserve the existing `CompareStrategyRegistry` -> `IntuneCompareStrategy` execution path, remove dead imports and misleading internal descriptions that survive only because of the retained legacy block, and verify unchanged behavior through focused compare execution, finding, and guard tests. ## Technical Context **Language/Version**: PHP 8.4.15 **Primary Dependencies**: Laravel 12, Filament v5, Livewire v4, Pest v4, Laravel Sail, existing `BaselineCompareService`, `CompareBaselineToTenantJob`, `CompareStrategyRegistry`, `IntuneCompareStrategy`, `CurrentStateHashResolver`, and current finding lifecycle services **Storage**: PostgreSQL via existing baseline snapshots, baseline snapshot items, inventory items, `operation_runs`, findings, and current run-context JSON; no new storage planned **Testing**: Pest feature and guard tests run through Laravel Sail, with focused compare execution and file-content guard coverage **Target Platform**: Laravel web application under `apps/platform` with queue-backed compare execution in Sail/Docker **Project Type**: web application in a monorepo (`apps/platform` plus `apps/website`) **Performance Goals**: Preserve current compare start latency and compare job throughput, add no new remote calls or DB writes, and keep operator-facing compare and monitoring surfaces behaviorally unchanged **Constraints**: No behavior change, no new abstraction or persistence, no operator-facing surface changes, no `OperationRun` lifecycle changes, and keep the PR mechanically small and reviewable **Scale/Scope**: One queued compare job, one compare start service boundary, one active strategy registry, one active Intune strategy, existing finding and run writers, and a small focused regression slice ## Constitution Check *GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing because the feature removes code without altering scope, auth, persistence, or UI contracts.* | Principle | Pre-Research | Post-Design | Notes | |-----------|--------------|-------------|-------| | Inventory-first / snapshots-second | PASS | PASS | Compare still reads existing workspace baseline snapshots and inventory-backed current state; no new compare truth is introduced. | | Read/write separation | PASS | PASS | Existing compare runs still write only current run, finding, and audit truth; the cleanup adds no new write path. | | Graph contract path | PASS | PASS | No new Microsoft Graph path or contract is introduced. | | Deterministic capabilities | PASS | PASS | Existing strategy selection and capability behavior remain unchanged because the registry and strategy classes stay intact. | | Workspace + tenant isolation | PASS | PASS | No workspace, tenant, or route-scope behavior changes are planned. | | RBAC-UX authorization semantics | PASS | PASS | No authorization rules, capability checks, or cross-plane behavior are changed. | | Run observability / Ops-UX | PASS | PASS | Existing `baseline_compare` run creation, summary counts, and completion semantics remain authoritative and unchanged. | | Data minimization | PASS | PASS | No new persisted diagnostics or helper truth is added; dead internal code is removed instead. | | Proportionality / anti-bloat | PASS | PASS | The feature deletes an obsolete path and introduces no new structure. | | No premature abstraction | PASS | PASS | No new factory, resolver, registry, strategy, or support layer is introduced. | | Persisted truth / behavioral state | PASS | PASS | No new table, stored artifact, status family, or reason family is added. | | UI semantics / few layers | PASS | PASS | No new presentation layer or surface behavior is introduced. | | Filament v5 / Livewire v4 compliance | PASS | PASS | No Filament or Livewire API changes are part of this cleanup. | | Provider registration location | PASS | PASS | No panel or provider change is required; Laravel 11+ provider registration remains in `bootstrap/providers.php`. | | Global search hard rule | PASS | PASS | No searchable resource or search behavior is touched. | | Destructive action safety | PASS | PASS | No destructive action is added or changed. | | Asset strategy | PASS | PASS | No new assets are introduced and existing `filament:assets` deployment behavior remains unchanged. | ## Filament-Specific Compliance Notes - **Livewire v4.0+ compliance**: Unchanged. The feature touches no Filament surface or Livewire component and does not introduce legacy APIs. - **Provider registration location**: Unchanged. If any panel/provider review is needed later, Laravel 11+ still requires `bootstrap/providers.php`. - **Global search**: No globally searchable resource is added or changed. - **Destructive actions**: No destructive action is introduced; existing confirmation and authorization rules remain untouched. - **Asset strategy**: No new panel or shared assets are required. Deployment handling of `cd apps/platform && php artisan filament:assets` remains unchanged. - **Testing plan**: Focus on the required compare cleanup pack only: compare execution and findings regressions, gap and reason-code coverage, `Spec116OneEngineGuardTest`, `Spec118NoLegacyBaselineDriftGuardTest`, existing `OperationRun` and summary-count guards, and the enqueue-path matrix action regression. No new page, widget, relation manager, or action surface coverage is required. ## Phase 0 Research Research outcomes are captured in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/205-compare-job-cleanup/research.md`. Key decisions: - Treat the current `CompareStrategyRegistry` -> `IntuneCompareStrategy` execution path as the only supported compare engine. - Delete the dead `computeDrift()` cluster rather than retaining it as deprecated or archived code. - Preserve `CompareSubjectResult`, finding upsert, summary aggregation, gap handling, and run completion semantics exactly as they currently operate through the live strategy path. - Use one focused compare pack covering execution fidelity, finding lifecycle, gap and reason outcomes, `OperationRun` lifecycle guards, summary-count guards, and the no-legacy orchestration guard as the minimum reliable regression slice. - Keep the contract artifact logical and internal, documenting invariants of the unchanged execution boundary instead of inventing a new external API. ## Phase 1 Design Design artifacts are created under `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/205-compare-job-cleanup/`: - `research.md`: cleanup decisions, rationale, and rejected alternatives - `data-model.md`: existing persisted truth and internal compare contracts preserved by the cleanup - `contracts/compare-job-legacy-drift-cleanup.logical.openapi.yaml`: logical internal contract for the unchanged compare start and execution boundaries plus the no-legacy guard invariant - `quickstart.md`: implementation and verification order for the cleanup Design decisions: - `CompareBaselineToTenantJob` remains the compare execution entry point, but only the live orchestration methods stay after cleanup. - `CompareStrategyRegistry`, `IntuneCompareStrategy`, `CompareStrategySelection`, `CompareOrchestrationContext`, `CompareSubjectResult`, and `CompareFindingCandidate` remain reused unchanged. - Existing persisted truth in baseline snapshots, inventory, findings, and `operation_runs` remains authoritative; no migration or compatibility layer is added. - Guard coverage remains the explicit enforcement point preventing legacy drift computation from re-entering the orchestration file. - Existing `OperationRun` lifecycle and summary-count guards remain part of the required verification surface because the cleanup still edits the compare executor. - No route, UI, RBAC, or `OperationRun` design change is planned. ## Project Structure ### Documentation (this feature) ```text specs/205-compare-job-cleanup/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── spec.md ├── contracts/ │ └── compare-job-legacy-drift-cleanup.logical.openapi.yaml └── checklists/ └── requirements.md ``` ### Source Code (repository root) ```text apps/platform/ ├── app/ │ ├── Jobs/ │ │ └── CompareBaselineToTenantJob.php │ ├── Services/ │ │ └── Baselines/ │ │ ├── BaselineCompareService.php │ │ ├── CurrentStateHashResolver.php │ │ └── Evidence/ │ └── Support/ │ └── Baselines/ │ └── Compare/ │ ├── CompareStrategyRegistry.php │ ├── CompareStrategySelection.php │ ├── CompareSubjectResult.php │ ├── CompareFindingCandidate.php │ └── IntuneCompareStrategy.php └── tests/ ├── Feature/ │ ├── BaselineDriftEngine/ │ │ └── FindingFidelityTest.php │ ├── Baselines/ │ │ ├── BaselineCompareFindingsTest.php │ │ ├── BaselineCompareGapClassificationTest.php │ │ ├── BaselineCompareWhyNoFindingsReasonCodeTest.php │ │ └── BaselineCompareMatrixCompareAllActionTest.php │ └── Guards/ │ ├── Spec116OneEngineGuardTest.php │ ├── Spec118NoLegacyBaselineDriftGuardTest.php │ └── OperationLifecycleOpsUxGuardTest.php │ ├── Operations/ │ │ └── BaselineOperationRunGuardTest.php │ └── OpsUx/ │ ├── OperationSummaryKeysSpecTest.php │ └── SummaryCountsWhitelistTest.php ``` **Structure Decision**: Keep the cleanup inside the existing compare orchestration file and current compare regression surfaces. No new namespace, support layer, or package structure is introduced. ## Complexity Tracking No constitution exception or complexity justification is required. Spec 205 removes an obsolete implementation branch and introduces no new persistence, abstraction, state family, or semantic framework. ## Proportionality Review Not triggered. This feature introduces no new enum or status family, DTO or presenter layer, persisted artifact, interface or registry, or cross-domain taxonomy. ## Implementation Strategy ### Phase A - Confirm dead call graph - Confirm that `handle()` no longer reaches `computeDrift()` or its candidate helper cluster. - Confirm that the live path still runs through strategy selection, strategy resolution, `strategy->compare(...)`, normalization, finding upsert, and run completion. - Record the final helper delete list before editing to avoid removing shared orchestration methods. ### Phase B - Delete the legacy drift cluster - Remove `computeDrift()` and every helper method used exclusively by that legacy path. - Remove only the imports, comments, and internal descriptions that become dead because of the delete. - Keep shared orchestration helpers such as evidence resolution, result normalization, summary aggregation, gap merging, and finding lifecycle methods untouched. ### Phase C - Preserve the live orchestration contract - Leave `BaselineCompareService`, `CompareStrategyRegistry`, and `IntuneCompareStrategy` behavior unchanged unless a direct compile or test failure requires a minimal follow-up. - Preserve the existing `baseline_compare` run context shape, summary count rules, gap handling, reason translation, and finding lifecycle semantics. - Avoid any naming sweep, contract redesign, or opportunistic cleanup outside the dead cluster. ### Phase D - Guard and regression verification - Keep or tighten the existing no-legacy guard so the removed path cannot silently re-enter the orchestration file. - Run focused compare execution, gap and reason-code regression, and `OperationRun` lifecycle and summary-count guard tests to prove the delete is mechanically safe. - Format the touched PHP files with Pint after the cleanup is implemented. ## Risk Assessment | Risk | Impact | Likelihood | Mitigation | |------|--------|------------|------------| | A supposedly dead helper is still used by the live orchestration path | High | Medium | Confirm call sites before deletion and keep the initial regression pack focused on execution, findings, gap and reason outcomes, and run-lifecycle guards. | | The cleanup grows into a broader refactor while the job file is open | Medium | Medium | Constrain edits to dead methods, direct import fallout, and guard or test changes required by the delete. | | Existing guard tests are too weak or too token-specific to prevent reintroduction | Medium | Medium | Reuse `Spec118NoLegacyBaselineDriftGuardTest` and extend it with the removed method names only if the current assertions do not cover the dead-path cluster clearly enough. | | A regression test depends on deleted internal structure rather than behavior | Medium | Low | Update such tests to assert live compare outcomes and orchestration invariants rather than private helper presence. | ## Test Strategy - Run `tests/Feature/BaselineDriftEngine/FindingFidelityTest.php` as the primary execution and evidence-fidelity regression slice. - Run `tests/Feature/Baselines/BaselineCompareFindingsTest.php` to protect finding generation, recurrence, summary counts, and run completion outcomes. - Run `tests/Feature/Baselines/BaselineCompareGapClassificationTest.php` and `tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php` to protect gap handling, warning outcomes, and reason translation behavior. - Run `tests/Feature/Guards/Spec116OneEngineGuardTest.php` to keep the one-engine orchestration invariant explicit while the dead fallback cluster is removed. - Run `tests/Feature/Guards/OperationLifecycleOpsUxGuardTest.php`, `tests/Feature/Operations/BaselineOperationRunGuardTest.php`, `tests/Feature/OpsUx/OperationSummaryKeysSpecTest.php`, and `tests/Feature/OpsUx/SummaryCountsWhitelistTest.php` to keep `OperationRun` lifecycle and summary-count guarantees intact. - Run `tests/Feature/Guards/Spec118NoLegacyBaselineDriftGuardTest.php` to lock the orchestration boundary against legacy drift helper re-entry. - Run `tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php` as the required enqueue-path regression slice for the focused cleanup pack. - Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` after the code change.