## Summary - implement the canonical operation type source-of-truth slice across operation writers, monitoring surfaces, onboarding flows, and supporting services - add focused contract and regression coverage for canonical operation type handling - include the generated spec 239 artifacts for the feature slice ## Validation - browser smoke PASS for `/admin` -> workspace overview -> operations -> operation detail -> tenant-scoped operations drilldown - spec/plan/tasks/quickstart artifact analysis cleaned up to a no-findings state - automated test suite not run in this session Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #276
8.3 KiB
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
- Start the local stack:
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail up -d
- Work on branch
239-canonical-operation-type-source-of-truth. - Keep the slice tightly bounded to
operation_typetruth only. Do not widen into broader governed-subject cleanup, monitoring IA changes, or historical data backfill.
Implementation Sequence
- Normalize the core contract first:
app/Support/OperationCatalog.phpapp/Support/OperationRunType.phpconfig/tenantpilot.phpPreserve already-canonical dotted codes that still contain underscore segments, includingbackup_set.update,directory.role_definitions.sync,tenant.review_pack.generate,tenant.evidence.snapshot.generate,entra.admin_roles.scan, andrbac.health_check.
- Converge the first-slice write owners:
app/Services/Providers/ProviderOperationRegistry.phpapp/Services/Providers/ProviderOperationStartGate.phpapp/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php- any touched service or job start sites still emitting
OperationRunType::...->valueor raw aliases
- Bound compatibility to read time only:
- keep alias resolution centralized in
OperationCatalog - normalize onboarding draft
bootstrap_operation_typeson load, save, and start - do not add dual-write, fallback writers, or data backfill
- keep alias resolution centralized in
- Converge read models, links, and audit-adjacent metadata:
app/Filament/Resources/OperationRunResource.phpapp/Support/Filament/FilterOptionCatalog.phpapp/Support/OpsUx/OperationUxPresenter.phpapp/Support/References/Resolvers/OperationRunReferenceResolver.phpapp/Support/OperationRunLinks.phpapp/Services/Audit/AuditEventBuilder.phpapp/Services/OperationRunService.phpapp/Services/SystemConsole/OperationRunTriageService.phpapp/Services/Runbooks/FindingsLifecycleBackfillRunbookService.php
- 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.phpapp/Services/Evidence/Sources/OperationsSummarySource.phpapp/Services/Onboarding/OnboardingLifecycleService.phpapp/Http/Controllers/AdminConsentCallbackController.phpapp/Services/Inventory/InventorySyncService.phpapp/Services/BackupScheduling/BackupScheduleDispatcher.phpapp/Services/ReviewPackService.phpapp/Services/Evidence/EvidenceSnapshotService.phpapp/Services/TenantReviews/TenantReviewService.php
Tests To Update Or Add
- Canonical resolution and write-truth unit coverage:
tests/Unit/Support/OperationTypeResolutionTest.phptests/Unit/Support/OperationRunTypeCanonicalContractTest.phptests/Unit/Providers/ProviderOperationRegistryCanonicalTypeTest.phptests/Unit/Providers/ProviderOperationStartGateTest.php
- Operations filters and onboarding feature coverage:
tests/Feature/Filament/OperationRunListFiltersTest.phptests/Feature/Filament/RecentOperationsSummaryWidgetTest.phptests/Feature/Monitoring/AuditCoverageOperationsTest.phptests/Feature/Monitoring/OperationsTenantScopeTest.phptests/Feature/Monitoring/OperationsDbOnlyRenderTest.phptests/Feature/Operations/TenantlessOperationRunViewerTest.phptests/Feature/ManagedTenantOnboardingWizardTest.phptests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.phptests/Feature/Rbac/OnboardingWizardUiEnforcementTest.phptests/Feature/Guards/OperationRunLinkContractGuardTest.php
- Anti-drift heavy-governance coverage:
tests/Architecture/PlatformVocabularyBoundaryGuardTest.phptests/Feature/OpsUx/UnknownOperationTypeLabelTest.phptests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php
Focused Verification
If you are reviewing the artifact set before implementation, start with the current repo baseline:
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:
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:
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:
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:
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
Review Focus
- Confirm touched writers emit canonical dotted codes directly and do not rely on
canonicalCode()as a second translation step. - Confirm filter options collapse alias variants into one canonical selection while still matching historical rows where required.
- Confirm onboarding resume, save, and start behavior normalizes historical bootstrap selections and persists canonical codes only.
- Confirm operations tenant-scope behavior, tenantless detail navigation, related-run links, summary widgets, and non-leakage guarantees remain intact after canonicalization.
- Confirm DB-only monitoring render paths remain DB-only and do not introduce new query fan-out or render-time remote work.
- Confirm audit-adjacent metadata, triage payloads, and runbook alerts stop copying raw
run->typeas current-releaseoperation_typetruth. - 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
Guardrailunless 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: historicaloperation_runs.typealiases, 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-specboundary and is not part of this slice.