TenantAtlas/specs/205-compare-job-cleanup/plan.md
2026-04-14 23:51:36 +02:00

15 KiB

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)

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)

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.