# Quickstart: Canonical Operation Type Source of Truth ## Goal Make dotted canonical `operation_type` codes the single normative platform contract for the touched slice, while keeping only a bounded read-side compatibility seam for historical `operation_runs.type` rows and persisted onboarding draft state. ## Prerequisites 1. Start the local stack: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail up -d ``` 2. Work on branch `239-canonical-operation-type-source-of-truth`. 3. Keep the slice tightly bounded to `operation_type` truth only. Do not widen into broader governed-subject cleanup, monitoring IA changes, or historical data backfill. ## Implementation Sequence 1. Normalize the core contract first: - `app/Support/OperationCatalog.php` - `app/Support/OperationRunType.php` - `config/tenantpilot.php` Preserve already-canonical dotted codes that still contain underscore segments, including `backup_set.update`, `directory.role_definitions.sync`, `tenant.review_pack.generate`, `tenant.evidence.snapshot.generate`, `entra.admin_roles.scan`, and `rbac.health_check`. 2. Converge the first-slice write owners: - `app/Services/Providers/ProviderOperationRegistry.php` - `app/Services/Providers/ProviderOperationStartGate.php` - `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` - any touched service or job start sites still emitting `OperationRunType::...->value` or raw aliases 3. Bound compatibility to read time only: - keep alias resolution centralized in `OperationCatalog` - normalize onboarding draft `bootstrap_operation_types` on load, save, and start - do not add dual-write, fallback writers, or data backfill 4. Converge read models, links, and audit-adjacent metadata: - `app/Filament/Resources/OperationRunResource.php` - `app/Support/Filament/FilterOptionCatalog.php` - `app/Support/OpsUx/OperationUxPresenter.php` - `app/Support/References/Resolvers/OperationRunReferenceResolver.php` - `app/Support/OperationRunLinks.php` - `app/Services/Audit/AuditEventBuilder.php` - `app/Services/OperationRunService.php` - `app/Services/SystemConsole/OperationRunTriageService.php` - `app/Services/Runbooks/FindingsLifecycleBackfillRunbookService.php` 5. Tighten tests and fixture defaults so new current-release writes stop teaching aliases as normal truth. Additional concrete seams explicitly called out by the task plan within this same slice: - `app/Support/Operations/OperationLifecyclePolicy.php` - `app/Services/Evidence/Sources/OperationsSummarySource.php` - `app/Services/Onboarding/OnboardingLifecycleService.php` - `app/Http/Controllers/AdminConsentCallbackController.php` - `app/Services/Inventory/InventorySyncService.php` - `app/Services/BackupScheduling/BackupScheduleDispatcher.php` - `app/Services/ReviewPackService.php` - `app/Services/Evidence/EvidenceSnapshotService.php` - `app/Services/TenantReviews/TenantReviewService.php` ## Tests To Update Or Add 1. Canonical resolution and write-truth unit coverage: - `tests/Unit/Support/OperationTypeResolutionTest.php` - `tests/Unit/Support/OperationRunTypeCanonicalContractTest.php` - `tests/Unit/Providers/ProviderOperationRegistryCanonicalTypeTest.php` - `tests/Unit/Providers/ProviderOperationStartGateTest.php` 2. Operations filters and onboarding feature coverage: - `tests/Feature/Filament/OperationRunListFiltersTest.php` - `tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php` - `tests/Feature/Monitoring/AuditCoverageOperationsTest.php` - `tests/Feature/Monitoring/OperationsTenantScopeTest.php` - `tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php` - `tests/Feature/Operations/TenantlessOperationRunViewerTest.php` - `tests/Feature/ManagedTenantOnboardingWizardTest.php` - `tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php` - `tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php` - `tests/Feature/Guards/OperationRunLinkContractGuardTest.php` 3. Anti-drift heavy-governance coverage: - `tests/Architecture/PlatformVocabularyBoundaryGuardTest.php` - `tests/Feature/OpsUx/UnknownOperationTypeLabelTest.php` - `tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php` ## Focused Verification If you are reviewing the artifact set before implementation, start with the current repo baseline: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationTypeResolutionTest.php tests/Unit/Providers/ProviderOperationStartGateTest.php tests/Unit/Onboarding/OnboardingDraftResolverTest.php ``` After the planned canonical-contract tests land, run the expanded narrow proving lane: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationTypeResolutionTest.php tests/Unit/Support/OperationRunTypeCanonicalContractTest.php tests/Unit/Providers/ProviderOperationRegistryCanonicalTypeTest.php tests/Unit/Providers/ProviderOperationStartGateTest.php tests/Unit/Onboarding/OnboardingDraftResolverTest.php ``` Then run the representative operator-surface proof: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/OperationRunListFiltersTest.php tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php tests/Feature/Monitoring/AuditCoverageOperationsTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php ``` Then run the guardrail proof that keeps `operation_type` platform-core, blocks raw alias drift, and preserves workspace or tenant non-leakage: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Architecture/PlatformVocabularyBoundaryGuardTest.php tests/Feature/Guards/OperationRunLinkContractGuardTest.php tests/Feature/OpsUx/UnknownOperationTypeLabelTest.php tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php ``` If PHP files were changed, finish with formatting: ```bash export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent ``` ## Review Focus 1. Confirm touched writers emit canonical dotted codes directly and do not rely on `canonicalCode()` as a second translation step. 2. Confirm filter options collapse alias variants into one canonical selection while still matching historical rows where required. 3. Confirm onboarding resume, save, and start behavior normalizes historical bootstrap selections and persists canonical codes only. 4. Confirm operations tenant-scope behavior, tenantless detail navigation, related-run links, summary widgets, and non-leakage guarantees remain intact after canonicalization. 5. Confirm DB-only monitoring render paths remain DB-only and do not introduce new query fan-out or render-time remote work. 6. Confirm audit-adjacent metadata, triage payloads, and runbook alerts stop copying raw `run->type` as current-release `operation_type` truth. 7. Confirm no new compatibility writer, no new table, no broader vocabulary cleanup, and no new asset or global-search change slipped into the slice. ## Guardrail Close-Out - Validation before handoff should show that write-time truth is canonical, read-time compatibility is bounded, and raw alias drift is blocked by tests rather than reviewer memory alone. - The close-out decision for this feature should remain `Guardrail` unless implementation expands into broader vocabulary or migration work, in which case the slice should be split. - Implementation close-out keeps the bounded compatibility seam as `document-in-feature`: historical `operation_runs.type` aliases, queued-run reauthorization, filter matching, and persisted onboarding draft values are normalized on read, while provider registry/start paths and current-release writers reject or avoid legacy aliases. - Broader provider/domain vocabulary cleanup remains a `follow-up-spec` boundary and is not part of this slice.