## Summary - extract baseline compare orchestration behind an explicit strategy contract and registry - preserve the current Intune compare path through a dedicated `IntuneCompareStrategy` - harden compare launch and review surfaces for mixed, unsupported, incomplete, and strategy-failure truth - add Spec 203 artifacts, focused regression coverage, and future-domain strategy proof tests ## Testing - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Baselines/CompareStrategyRegistryTest.php tests/Unit/Baselines/CompareSubjectResultContractTest.php tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php tests/Feature/Baselines/BaselineComparePreconditionsTest.php tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php tests/Feature/Filament/BaselineCompareMatrixPageTest.php tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - no new Filament panel/provider registration changes - no global-search resource changes - no new asset registration or deployment step changes Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #233
21 KiB
Tasks: Baseline Compare Engine Strategy Extraction
Input: Design documents from /specs/203-baseline-compare-strategy/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/baseline-compare-strategy.logical.openapi.yaml, quickstart.md
Tests: Required. This feature changes runtime compare orchestration, existing Filament start surfaces, and canonical baseline_compare run truth, so Pest unit, feature, Filament, and existing browser smoke coverage must be added or extended.
Operations: This feature reuses the existing baseline_compare OperationRun lifecycle only. No new run type, queued notification channel, or alternate monitoring surface should be introduced.
RBAC: Existing workspace and tenant compare capabilities remain authoritative. Tasks must preserve 404 vs 403 semantics while treating unsupported or mixed scope as compare truth rather than authorization.
Operator Surfaces: The affected surfaces are the existing baseline profile detail, baseline compare matrix, tenant baseline compare landing, and canonical operation run detail.
Filament UI Action Surfaces: Existing Compare now and Compare assigned tenants actions remain the primary launch actions. No new destructive action is added.
Proportionality: Add only the narrow compare-support namespace under apps/platform/app/Support/Baselines/Compare/ and avoid a broader compare plugin framework.
Organization: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is US1 -> US2 -> US3 -> US4, with US1 as the MVP cut after the shared compare-contract foundation is in place.
Phase 1: Setup (Shared Infrastructure)
Purpose: Prepare focused test seams for compare strategy selection, compare-result contracts, and future-domain proof coverage.
- T001 Create the compare strategy registry unit test scaffold in
apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php - T002 [P] Create the compare subject result contract unit test scaffold in
apps/platform/tests/Unit/Baselines/CompareSubjectResultContractTest.php - T003 [P] Create the future-domain compare strategy support fixture and feature test scaffold in
apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.phpandapps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php
Checkpoint: Dedicated Spec 203 test entry points exist and the compare extraction can proceed without mixing this slice into unrelated suites.
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Establish the shared compare strategy, selection, and subject-result contracts before any story-specific behavior lands.
CRITICAL: No user story work should start before this phase is complete.
- T004 [P] Add foundational capability, selection-state, and result-contract expectations in
apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.phpandapps/platform/tests/Unit/Baselines/CompareSubjectResultContractTest.php - T005 [P] Add shared preflight selection and single-strategy handoff coverage in
apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.phpandapps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php - T006 [P] Extend compare run lifecycle and summary-count guard coverage in
apps/platform/tests/Feature/Guards/OperationLifecycleOpsUxGuardTest.php,apps/platform/tests/Feature/OpsUx/OperationSummaryKeysSpecTest.php, andapps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php - T007 Implement compare selection enums and subject-result value objects in
apps/platform/app/Support/Baselines/Compare/CompareStrategyKey.php,apps/platform/app/Support/Baselines/Compare/StrategySelectionState.php,apps/platform/app/Support/Baselines/Compare/CompareState.php,apps/platform/app/Support/Baselines/Compare/CompareSubjectIdentity.php,apps/platform/app/Support/Baselines/Compare/CompareSubjectProjection.php,apps/platform/app/Support/Baselines/Compare/CompareFindingCandidate.php, andapps/platform/app/Support/Baselines/Compare/CompareSubjectResult.php - T008 Implement the compare strategy contract, capability record, selection record, orchestration context, and registry in
apps/platform/app/Support/Baselines/Compare/CompareStrategy.php,apps/platform/app/Support/Baselines/Compare/CompareStrategyCapability.php,apps/platform/app/Support/Baselines/Compare/CompareStrategySelection.php,apps/platform/app/Support/Baselines/Compare/CompareOrchestrationContext.php, andapps/platform/app/Support/Baselines/Compare/CompareStrategyRegistry.php - T009 Wire shared strategy bootstrap and run-context handoff into
apps/platform/app/Services/Baselines/BaselineCompareService.phpandapps/platform/app/Jobs/CompareBaselineToTenantJob.php
Checkpoint: The repo can model one supported compare strategy family, reject non-deterministic selection at the contract layer, preserve Ops-UX lifecycle guards, and hand a structured compare context into the existing compare job.
Phase 3: User Story 1 - Preserve current Intune compare through an explicit boundary (Priority: P1) MVP
Goal: Keep the current supported Intune compare behavior stable while moving domain-specific compare logic behind one explicit strategy boundary.
Independent Test: Start supported Intune compare from the existing tenant and workspace surfaces and verify findings, summaries, and trust semantics remain unchanged through the extracted strategy path.
Tests for User Story 1
Note
: Write these tests first and confirm they fail before implementation.
- T010 [P] [US1] Extend supported Intune compare classification and finding parity coverage in
apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php, andapps/platform/tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php - T011 [P] [US1] Extend supported-scope launch, run-outcome, and summary parity coverage in
apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php,apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php, andapps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php - T012 [P] [US1] Extend explanation, why-no-findings, and evidence-contract parity coverage in
apps/platform/tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareExplanationFallbackTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php, andapps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php
Implementation for User Story 1
- T013 [US1] Implement the explicit
IntuneCompareStrategyand register its supported capability family inapps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.phpandapps/platform/app/Support/Baselines/Compare/CompareStrategyRegistry.php - T014 [US1] Route supported compare starts through deterministic strategy selection and record the chosen strategy in
apps/platform/app/Services/Baselines/BaselineCompareService.phpandapps/platform/app/Jobs/CompareBaselineToTenantJob.php - T015 [US1] Move Intune-only subject discovery, normalizer selection, RBAC role-definition branching, and projection shaping behind the strategy boundary in
apps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.phpandapps/platform/app/Jobs/CompareBaselineToTenantJob.php - T016 [US1] Feed existing finding, summary, explanation, and badge semantics from
CompareSubjectResultwithout changing supported Intune outcomes inapps/platform/app/Support/Baselines/BaselineCompareStats.php,apps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php,apps/platform/app/Support/Baselines/BaselineCompareExplanationRegistry.php,apps/platform/app/Support/Badges/BadgeDomain.php, andapps/platform/app/Support/Badges/BadgeCatalog.php
Checkpoint: Supported Intune compare remains independently functional and regression-protected through the new explicit strategy seam.
Phase 4: User Story 2 - Reject unsupported or mixed-domain compare scope honestly (Priority: P1)
Goal: Fail unsupported or mixed compare scope before enqueue so operators never launch misleading compare work.
Independent Test: Attempt tenant and workspace fan-out compare with unsupported, inactive, and mixed-family canonical scope and confirm the start surfaces reject the work before any compare run is started.
Tests for User Story 2
Note
: Write these tests first and confirm they fail before implementation.
- T017 [P] [US2] Extend unsupported, mixed-family, and inactive-type compare gating coverage in
apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.phpandapps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php - T018 [P] [US2] Extend start-surface rejection truth and authorization continuity in
apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php,apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php, andapps/platform/tests/Feature/Filament/BaselineCompareMatrixPageTest.php
Implementation for User Story 2
- T019 [US2] Enforce supported, unsupported, and mixed selection outcomes before run creation in
apps/platform/app/Services/Baselines/BaselineCompareService.phpandapps/platform/app/Support/Baselines/Compare/CompareStrategyRegistry.php - T020 [US2] Add operator-safe compare rejection reason codes and diagnostics mapping in
apps/platform/app/Support/Baselines/BaselineCompareReasonCode.php,apps/platform/app/Support/Baselines/BaselineCompareStats.php, andapps/platform/app/Support/ReasonTranslation/ReasonTranslator.php - T021 [US2] Surface truthful unsupported and mixed-scope launch messaging on the existing compare pages in
apps/platform/app/Filament/Resources/BaselineProfileResource.php,apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php,apps/platform/app/Filament/Pages/BaselineCompareMatrix.php, andapps/platform/app/Filament/Pages/BaselineCompareLanding.php
Checkpoint: Unsupported or mixed compare scope is independently blocked before run creation and explained truthfully on the existing launch surfaces.
Phase 5: User Story 3 - Keep one platform compare story while allowing domain-specific logic (Priority: P2)
Goal: Prove that a future non-Intune strategy can participate in the same compare lifecycle without forcing policy-only platform defaults.
Independent Test: Register a non-Intune test strategy against canonical scope and confirm the entrypoint resolves it deterministically, executes the shared lifecycle, and emits structured compare results without Intune fallbacks.
Tests for User Story 3
Note
: Write these tests first and confirm they fail before implementation.
- T022 [P] [US3] Add unit coverage for future-domain capability matching, deterministic selection, and no-implicit-fallback behavior in
apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php - T023 [P] [US3] Add non-Intune strategy lifecycle coverage using
apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.phpandapps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php
Implementation for User Story 3
- T024 [US3] Register strategy-owned domain, subject-class, and subject-type capability declarations without policy-only defaults in
apps/platform/app/Support/Baselines/Compare/CompareStrategyCapability.php,apps/platform/app/Support/Baselines/Compare/CompareStrategyRegistry.php, andapps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.php - T025 [US3] Keep platform summary and explanation aggregation domain-neutral by consuming strategy projections instead of policy defaults in
apps/platform/app/Support/Baselines/BaselineCompareStats.php,apps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php, andapps/platform/app/Support/Baselines/BaselineCompareExplanationRegistry.php - T026 [US3] Keep the unified finding lifecycle strategy-neutral by consuming
CompareFindingCandidateandCompareSubjectProjectioninapps/platform/app/Jobs/CompareBaselineToTenantJob.phpandapps/platform/app/Support/Baselines/Compare/CompareSubjectResult.php
Checkpoint: The compare lifecycle is independently capable of resolving and consuming a non-Intune strategy without cloning the platform orchestration path.
Phase 6: User Story 4 - Preserve truthful degraded and failed states (Priority: P2)
Goal: Keep unsupported, incomplete, ambiguous, and failed compare outcomes distinct so the new boundary does not blur operator trust semantics.
Independent Test: Exercise unsupported-subject, incomplete-evidence, ambiguous-match, and strategy-failure cases and verify the compare landing and canonical run detail keep those outcomes distinct from no drift.
Tests for User Story 4
Note
: Write these tests first and confirm they fail before implementation.
- T027 [P] [US4] Extend ambiguous, incomplete, unsupported-subject, and strategy-failure coverage in
apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php, andapps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php - T028 [P] [US4] Extend operator truth coverage for degraded and failed compare states in
apps/platform/tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php,apps/platform/tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php,apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php, andapps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php
Implementation for User Story 4
- T029 [US4] Map strategy
unsupported,incomplete,ambiguous, andfailedstates to stable compare reasons and summary counts inapps/platform/app/Support/Baselines/BaselineCompareReasonCode.php,apps/platform/app/Support/Baselines/BaselineCompareStats.php, andapps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php - T030 [US4] Persist secondary strategy diagnostics and degraded-state evidence without collapsing run outcome truth in
apps/platform/app/Jobs/CompareBaselineToTenantJob.php,apps/platform/app/Support/Baselines/BaselineCompareEvidenceGapDetails.php, andapps/platform/app/Support/Baselines/BaselineCompareExplanationRegistry.php - T031 [US4] Update compare landing and canonical run-detail review surfaces for unsupported, incomplete, ambiguous, and failed states in
apps/platform/app/Filament/Pages/BaselineCompareLanding.php,apps/platform/app/Filament/Resources/OperationRunResource.php, andapps/platform/resources/views/filament/pages/baseline-compare-landing.blade.php
Checkpoint: Degraded and failed compare states remain independently reviewable and never collapse into calm no-drift semantics.
Phase 7: Polish & Cross-Cutting Concerns
Purpose: Lock the slice down with operator-copy review, performance and browser smoke regression guards, and explicit Sail verification.
- T032 [P] Recheck launch-surface operator copy and naming consistency in
apps/platform/app/Filament/Resources/BaselineProfileResource.php,apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php, andapps/platform/app/Filament/Pages/BaselineCompareLanding.php - T033 [P] Recheck matrix and run-detail diagnostic wording plus scope-language consistency in
apps/platform/app/Filament/Pages/BaselineCompareMatrix.php,apps/platform/app/Filament/Resources/OperationRunResource.php, andapps/platform/resources/views/filament/pages/baseline-compare-landing.blade.php - T034 [P] Extend compare performance and enqueue-only regression coverage in
apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.phpandapps/platform/tests/Feature/Operations/BaselineQueueRuntimeGuardTest.php - T035 [P] Extend matrix browser smoke, no-silent-fallback assertions, and final launch-truth regressions in
apps/platform/tests/Browser/Spec190BaselineCompareMatrixSmokeTest.php,apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php, andapps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.php - T036 Run the focused Sail test pack from
specs/203-baseline-compare-strategy/quickstart.mdagainst the changed unit, feature, Filament, and browser files - T037 Run formatting and final Ops-UX guard verification in
apps/platform/tests/Feature/Guards/OperationLifecycleOpsUxGuardTest.php,apps/platform/tests/Feature/OpsUx/OperationSummaryKeysSpecTest.php,apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php, andapps/platform/tests/Feature/OpsUx/NoQueuedDbNotificationsTest.php
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies; can start immediately.
- Foundational (Phase 2): Depends on Setup completion; blocks all user stories.
- User Story 1 (Phase 3): Depends on Foundational completion; this is the recommended MVP cut.
- User Story 2 (Phase 4): Depends on Foundational completion and is easiest to review after US1 proves the supported strategy path stays stable.
- User Story 3 (Phase 5): Depends on Foundational completion and on the extracted result contract from US1.
- User Story 4 (Phase 6): Depends on Foundational completion and benefits from US1 and US2 because degraded truth builds on the extracted strategy path and explicit rejection semantics.
- Polish (Phase 7): Depends on all desired user stories being complete.
User Story Dependencies
- US1: No dependencies beyond Foundational.
- US2: No hard dependency beyond Foundational, but it should follow US1 so the supported path is already stable before rejected paths are hardened.
- US3: Depends on the shared compare contract from Foundational and the extracted strategy path from US1.
- US4: Depends on the shared compare contract from Foundational and should follow US1 and US2 so run truth and rejection truth are already explicit.
Within Each User Story
- Write the story tests first and confirm they fail before implementation.
- Keep compare start orchestration in
BaselineCompareService.phpand execution inCompareBaselineToTenantJob.php; story work should not introduce a parallel compare workflow. - Finish each story's focused verification before moving to the next priority.
Parallel Opportunities
T002andT003can run in parallel afterT001.T004,T005, andT006can run in parallel beforeT007throughT009.- Within US1,
T010,T011, andT012can run in parallel. - Within US2,
T017andT018can run in parallel. - Within US3,
T022andT023can run in parallel. - Within US4,
T027andT028can run in parallel. T032,T033,T034, andT035can run in parallel once implementation is complete.
Parallel Example: User Story 1
# Parallel test pass for US1
T010 Extend supported Intune compare classification and finding parity coverage
T011 Extend supported-scope launch, run-outcome, and summary parity coverage
T012 Extend explanation, why-no-findings, and evidence-contract parity coverage
Parallel Example: User Story 2
# Parallel test pass for US2
T017 Extend unsupported, mixed-family, and inactive-type compare gating coverage
T018 Extend start-surface rejection truth and authorization continuity
Parallel Example: User Story 3
# Parallel test pass for US3
T022 Add unit coverage for future-domain capability matching and deterministic selection
T023 Add non-Intune strategy lifecycle coverage with FakeCompareStrategy
Parallel Example: User Story 4
# Parallel test pass for US4
T027 Extend ambiguous, incomplete, unsupported-subject, and strategy-failure coverage
T028 Extend operator truth coverage for degraded and failed compare states
Implementation Strategy
MVP First
- Finish Setup and Foundational work.
- Deliver US1 to prove Intune compare survives the extraction behind one explicit strategy.
- Validate US1 independently before widening the slice.
Incremental Delivery
- Add US2 to reject unsupported or mixed scope honestly before enqueue.
- Add US3 to prove future-domain strategy participation without policy-only defaults.
- Add US4 to harden degraded and failed compare truth on the existing review surfaces.
- Finish with copy review, performance and browser smoke guards, and the explicit Sail verification pack from Phase 7.
Parallel Team Strategy
- One contributor completes Setup and Foundational tasks.
- After Foundation is green:
- Contributor A takes US1.
- Contributor B prepares US2 test coverage and launch-surface hardening.
- Contributor C prepares US3 registry and fake-strategy proof work.
- Contributor D prepares US4 degraded-truth coverage and review-surface hardening.
- Merge back for Phase 7 guard, performance, browser smoke, formatting, and focused Sail verification.