# Implementation Close-Out: Spec 382 - Baseline Matching Pipeline and Canonicalization v1 Date: 2026-06-15 ## Scope Delivered - Added provider-resource canonical key validation to prevent display-derived strings from being accepted as canonical provider subject keys. - Added matching support objects and services: - `BaselineSubjectDescriptor` - `MatchingOutcome` - `FoundationCoverageResolver` - `SubjectMatchingPipeline` - Integrated matching into baseline compare before `policy_type|subject_key` keying can collapse candidates. - Kept payload drift/no-drift ownership inside existing compare strategies. - Removed legacy subject-key matching, display-name matching fallback, display-name-derived canonical key generation, and old compare payload readers from the Spec 382 matching path. - Added binding-aware compare coverage, identity-required gap coverage, and fake-provider canonical identity coverage. - Added a Spec 382 migration that drops `provider_resource_bindings.legacy_subject_key` because the column was introduced by the committed Spec 381 migration. ## No Surface Impact - UI impact: none. - Filament impact: none. - Livewire impact: none; project remains on Livewire v4.1.4. - Panel/provider registration impact: none; Laravel 12 panel providers remain registered through `bootstrap/providers.php`. - Global search impact: none; no resources/pages were added or changed. - Destructive/high-impact actions: none added. Existing provider-resource binding decisions keep existing authorization and audit behavior. - Asset strategy: none added; no global or on-demand assets changed. `filament:assets` deployment behavior is unchanged. - Migrations/schema impact: `provider_resource_bindings.legacy_subject_key` is dropped by a Spec 382 migration. No new persisted entity, index family, env var, queue, scheduler, storage, route, UI, asset, Filament, or Livewire surface is introduced. - Environment variables: none. - Queues/scheduler/storage: no new queue names, scheduler entries, or storage paths. - Browser smoke: not run because this spec has no UI surface. ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Baselines/Matching tests/Unit/Services/Baselines/Matching tests/Unit/Support/Baselines/BaselineSubjectKeyCanonicalIdentityTest.php tests/Unit/Support/Resources/ResourceIdentityTest.php tests/Unit/Support/Resources/ProviderResourceDescriptorTest.php` - 19 passed, 103 assertions. - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderResources/ProviderResourceBindingServiceTest.php tests/Feature/ProviderResources/ProviderResourceBindingAuthorizationTest.php` - 20 passed, 75 assertions. - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineCompareProviderResourceBindingCanonicalIdentityTest.php tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php tests/Feature/Baselines/BaselineCompareGapClassificationTest.php` - 4 passed, 70 assertions. - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Evidence/BaselineDriftPostureSourceTest.php tests/Feature/ReviewPack/Spec349ReviewPackResolutionGuidanceTest.php` - 9 passed, 43 assertions. - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - pass. - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --test --format agent` - pass. - `git diff --check` - pass. ## PostgreSQL Lane Targeted database-backed Sail tests ran through Laravel migrations, including the Spec 382 drop-column migration. No new indexes, constraints, locks, or PostgreSQL-specific query behavior were added. ## Post-Implementation Analysis - No changes were made to completed dependency specs `specs/163-baseline-subject-resolution/`, `specs/380-management-report-pdf-staging-runtime-validation/`, or `specs/381-provider-resource-identity-binding/`. - No matching code calls `GraphClientInterface`, provider gateways, or provider runtime clients. - Matching proof metadata is sanitized and does not include raw operator notes. - Core matching does not branch on Microsoft display labels. - Display names are labels/descriptions only; they are not matching inputs, canonical-key inputs, binding lookup inputs, or successful compare resolution inputs. - No UI, Filament, Livewire, Blade, route, config, scheduler, queue-name, storage, env, or asset file changed. - No in-scope post-implementation findings remain open. ## Deployment Impact - Staging: normal application deployment and test validation are sufficient. - Production: run normal Laravel migrations so the legacy identity column is dropped. No queue worker, scheduler, volume, or environment-variable step is required. - Rollback: rolling back the Spec 382 migration restores the dropped column, but product behavior intentionally remains no-legacy-identity unless code is rolled back too.