TenantAtlas/specs/204-platform-core-vocabulary-hardening/plan.md
2026-04-14 08:07:40 +02:00

27 KiB

Implementation Plan: Platform Core Vocabulary Hardening

Branch: 204-platform-core-vocabulary-hardening | Date: 2026-04-13 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/204-platform-core-vocabulary-hardening/spec.md Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/204-platform-core-vocabulary-hardening/spec.md

Note: This plan hardens platform-core and platform-near vocabulary by extending the existing governance, operation, and reason-translation layers already in the codebase, rather than introducing a parallel framework or broad rename sweep.

Summary

Reuse the existing App\Support\Governance, App\Support\OperationCatalog, App\Support\OperationRunType, and App\Support\ReasonTranslation seams to define one maintained code-side platform vocabulary glossary, resolve mixed stored operation type codes through one canonical domain-aware operation vocabulary, classify platform reason families separately from domain-owned reason codes, and harden platform-near compare, snapshot, monitoring, review, and reporting contracts to prefer governed-subject descriptors over false-universal policy_type wording. Keep Intune-owned tables, Graph contracts, and adapter-local metadata intentionally Intune-specific, preserve historical run and filter compatibility through alias resolution instead of a mass rewrite, and add regression guards so touched platform surfaces cannot drift back into implicit Intune-as-universal semantics.

Technical Context

Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12, Filament v5, Livewire v4, Pest v4, Laravel Sail, existing GovernanceSubjectTaxonomyRegistry, BaselineScope, CompareStrategyRegistry, OperationCatalog, OperationRunType, ReasonTranslator, ReasonResolutionEnvelope, ProviderReasonTranslator, and current Filament monitoring or review surfaces
Storage: PostgreSQL via existing operation_runs.type, operation_runs.context, baseline_profiles.scope_jsonb, baseline_snapshot_items, findings, evidence payloads, and current config-backed registries; no new top-level tables planned
Testing: Pest unit, feature, architecture, and focused Filament Livewire tests run through Laravel Sail
Target Platform: Laravel monolith web application under apps/platform with queue-backed operations and Filament admin or operator surfaces
Project Type: web application in a monorepo (apps/platform plus apps/website)
Performance Goals: Keep operation label and reason translation resolution fully in-process, avoid new remote calls on monitoring or review pages, preserve current operation list and filter responsiveness, and avoid request-path schema rewrites or query fan-out caused by vocabulary hardening
Constraints: No repo-wide rename sweep, no fake generic rewrite of Intune adapters, no new panel or provider, no new assets, no break in historical run filtering or labeling, no change to current 404 or 403 semantics, keep compatibility explicitly transitional, and prefer wrapper or alias hardening over broad schema churn
Scale/Scope: One existing governance namespace, one existing operation vocabulary seam, one existing reason-translation seam, several monitoring or review surfaces, a small set of platform-near compare and snapshot contracts, optional targeted platform-owned persistence wrappers, and focused regression coverage across monitoring, reason translation, and baseline compare or snapshot surfaces

Constitution Check

GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing with narrow proportionality exceptions documented below.

Principle Pre-Research Post-Design Notes
Inventory-first / snapshots-second PASS PASS The feature hardens vocabulary only; inventory, snapshots, and external Microsoft truth sources remain unchanged.
Read/write separation PASS PASS Most work is read-path and presentation-path hardening. Any touched persisted write path stays on existing model or service flows and keeps existing audit and authorization behavior.
Graph contract path PASS PASS No new Microsoft Graph path or graph_contracts.php entry is introduced. Intune-owned Graph terminology remains in the adapter layer.
Deterministic capabilities PASS PASS Existing taxonomy, compare strategy, and operation catalog seams remain deterministic and testable. Any new vocabulary mapping is code-side and snapshot-testable.
Workspace + tenant isolation PASS PASS Monitoring, compare, and review surfaces keep current workspace and tenant scope enforcement. Vocabulary hardening must not expose hidden records through labels or explanations.
RBAC-UX authorization semantics PASS PASS No new authorization plane or capability family is added. Non-members remain 404, in-scope capability denials remain 403, and no new raw capability strings are introduced.
Run observability / Ops-UX PASS PASS Existing OperationRun lifecycle, summary counts, notifications, and DB-only monitoring rules remain unchanged. Operation type hardening is alias and presentation aware, not a run-lifecycle redesign.
Data minimization PASS PASS No new persisted entity or external payload is introduced. Existing JSON context and derived presentation payloads are hardened in place.
Proportionality / anti-bloat PASS PASS The plan extends existing governance, operation, and reason translation seams instead of introducing a second registry framework or presentation pipeline.
No premature abstraction PASS PASS The glossary, alias map, and reason-family classification are narrow extensions to already-existing abstractions rather than brand-new plugin points.
Persisted truth / behavioral state PASS PASS No new top-level persisted truth is added. Any touched reason-family or operation-type classification remains derived unless a platform-owned field cannot be safely wrapped.
UI semantics / few layers PASS PASS Reason ownership and canonical labels are derived through the existing translation and catalog layers. The plan does not add a second operator-semantics framework.
Filament v5 / Livewire v4 compliance PASS PASS All touched UI surfaces remain on existing Filament v5 + Livewire v4 resources, pages, widgets, and detail views.
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 new globally searchable resource is introduced. Touched resources continue their current search behavior and existing view-detail capability.
Destructive action safety PASS PASS No new destructive action is introduced. Existing destructive actions remain unchanged and must keep confirmation plus authorization.
Asset strategy PASS PASS No new global or on-demand assets are planned. Existing deployment handling of cd apps/platform && php artisan filament:assets remains unchanged.

Filament-Specific Compliance Notes

  • Livewire v4.0+ compliance: The touched monitoring and review surfaces stay on Filament v5 + Livewire v4 and the plan introduces no legacy API usage.
  • Provider registration location: No new panel or provider is required; bootstrap/providers.php remains the only relevant provider registration location.
  • Global search: No new globally searchable resource is added. OperationRunResource already has a detail surface, and touched baseline surfaces keep their existing view or search posture.
  • Destructive actions: This feature adds no new destructive action. Existing destructive actions must retain ->requiresConfirmation() and server-side authorization.
  • Asset strategy: No asset registration changes are planned. Deployment handling of cd apps/platform && php artisan filament:assets remains unchanged.
  • Testing plan: Extend unit coverage for glossary and alias resolution, extend reason-translation and architecture guard coverage for ownership boundaries, extend monitoring and Filament operation-run coverage for canonical labels and filter continuity, and extend baseline snapshot or compare coverage for platform-near subject vocabulary hardening.

Phase 0 Research

Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/204-platform-core-vocabulary-hardening/research.md.

Key decisions:

  • Keep the maintained glossary inside the existing App\Support\Governance namespace rather than creating a second documentation-only or config-only source of truth.
  • Treat existing stored operation type codes as compatibility aliases and resolve them through one canonical domain-aware operation vocabulary contract.
  • Evolve OperationCatalog into the central canonical operation registry rather than introducing a parallel catalog.
  • Keep ProviderReasonCodes, RbacReason, and BaselineCompareReasonCode domain-owned and derive platform reason families at the existing ReasonTranslation boundary.
  • Prefer governed-subject descriptors built from subject_type_key and subject_type_label on platform-owned or platform-near payloads while preserving Intune-owned policy_type where the object is truly adapter-owned.
  • Use wrapper-first and alias-first hardening for platform-owned JSON and presentation contracts before considering any schema change.
  • Limit registry hardening to explicit ownership descriptors around current registries instead of building a universal plugin system.
  • Add regression guards that prevent false-universal Intune vocabulary from reappearing on touched platform surfaces.

Phase 1 Design

Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/204-platform-core-vocabulary-hardening/:

  • research.md: architecture decisions and rejected alternatives for vocabulary ownership, operation types, reason families, and platform-near discriminator hardening
  • data-model.md: glossary, operation alias resolution, platform reason family, registry ownership, and platform subject descriptor contracts
  • contracts/platform-core-vocabulary-hardening.logical.openapi.yaml: logical internal contract for glossary lookup, operation type resolution, reason translation, registry ownership lookup, and platform subject descriptor normalization
  • quickstart.md: implementation and verification sequence for the feature

Design decisions:

  • Reuse the current governance namespace for canonical term definitions and ownership descriptors instead of creating a second top-level framework.
  • Keep OperationRunType and OperationCatalog as the existing operation vocabulary seam, but add canonical operation codes, domain grouping, and explicit legacy alias resolution.
  • Extend ReasonResolutionEnvelope and ReasonTranslator so operator-facing explanations carry explicit ownership and platform reason-family metadata without renaming domain reason codes.
  • Harden platform-near compare, snapshot, monitoring, and review payloads to prefer domain_key, subject_class, subject_type_key, and subject_type_label semantics rather than using policy_type as a universal noun.
  • Preserve Intune-owned tables, config registries, Graph contracts, and adapter metadata as intentionally Intune-specific.
  • Keep compatibility explicitly temporary and visible in code so old names are readable but not treated as equally canonical.

Project Structure

Documentation (this feature)

specs/204-platform-core-vocabulary-hardening/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── spec.md
├── contracts/
│   └── platform-core-vocabulary-hardening.logical.openapi.yaml
└── checklists/
    └── requirements.md

Source Code (repository root)

apps/platform/
├── app/
│   ├── Filament/
│   │   ├── Pages/
│   │   │   ├── BaselineCompareLanding.php
│   │   │   └── BaselineCompareMatrix.php
│   │   ├── Resources/
│   │   │   ├── OperationRunResource.php
│   │   │   └── EvidenceSnapshotResource.php
│   │   ├── System/
│   │   │   └── Pages/
│   │   │       ├── Ops/
│   │   │       │   ├── Runs.php
│   │   │       │   ├── Failures.php
│   │   │       │   └── Stuck.php
│   │   │       └── Directory/
│   │   │           ├── ViewTenant.php
│   │   │           └── ViewWorkspace.php
│   │   │   └── Widgets/
│   │   │       ├── ControlTowerRecentFailures.php
│   │   │       └── ControlTowerTopOffenders.php
│   │   └── Widgets/
│   │       └── Dashboard/RecentOperations.php
│   ├── Jobs/
│   │   └── CompareBaselineToTenantJob.php
│   ├── Models/
│   │   └── OperationRun.php
│   ├── Services/
│   │   ├── Audit/
│   │   │   └── AuditEventBuilder.php
│   │   └── Baselines/
│   │       └── SnapshotRendering/
│   │           └── BaselineSnapshotPresenter.php
│   └── Support/
│       ├── Governance/
│       │   ├── GovernanceDomainKey.php
│       │   ├── GovernanceSubjectClass.php
│       │   ├── GovernanceSubjectTaxonomyRegistry.php
│       │   ├── GovernanceSubjectType.php
│       │   ├── PlatformVocabularyGlossary.php
│       │   ├── PlatformVocabularyTerm.php
│       │   ├── RegistryOwnershipDescriptor.php
│       │   ├── PlatformSubjectDescriptor.php
│       │   └── PlatformSubjectDescriptorNormalizer.php
│       ├── Providers/
│       │   ├── ProviderReasonCodes.php
│       │   └── ProviderReasonTranslator.php
│       ├── ReasonTranslation/
│       │   ├── Contracts/
│       │   ├── ReasonResolutionEnvelope.php
│       │   ├── ReasonTranslator.php
│       │   └── ReasonPresenter.php
│       ├── Baselines/
│       │   ├── BaselineCompareReasonCode.php
│       │   ├── BaselineScope.php
│       │   └── Compare/
│       │       ├── CompareSubjectProjection.php
│       │       └── CompareSubjectResult.php
│       ├── Filament/
│       │   └── FilterOptionCatalog.php
│       ├── OperationCatalog.php
│       └── OperationRunType.php
├── config/
│   └── tenantpilot.php
└── tests/
    ├── Architecture/
    │   └── ReasonTranslationPrimarySurfaceGuardTest.php
    ├── Feature/
    │   ├── Authorization/
    │   │   └── ReasonTranslationScopeSafetyTest.php
    │   ├── Baselines/
    │   │   ├── BaselineCompareExecutionGuardTest.php
    │   │   ├── BaselineCompareDriftEvidenceContractTest.php
    │   │   └── BaselineCompareWhyNoFindingsReasonCodeTest.php
    │   ├── Filament/
    │   │   ├── OperationRunListFiltersTest.php
    │   │   ├── OperationRunEnterpriseDetailPageTest.php
    │   │   ├── OperationRunBaselineTruthSurfaceTest.php
    │   │   ├── BaselineCompareLandingWhyNoFindingsTest.php
    │   │   └── BaselineCompareSummaryConsistencyTest.php
    │   ├── Monitoring/
    │   │   └── OperationRunResolvedReferencePresentationTest.php
    │   └── ReasonTranslation/
    │       ├── GovernanceReasonPresentationTest.php
    │       └── ReasonTranslationExplanationTest.php
    └── Unit/
        ├── Baselines/
        │   └── SnapshotRendering/BaselineSnapshotPresenterTest.php
        └── Support/
            ├── Governance/
            │   ├── PlatformVocabularyGlossaryTest.php
            │   ├── RegistryOwnershipDescriptorTest.php
            │   └── PlatformSubjectDescriptorNormalizerTest.php
            ├── OperationTypeResolutionTest.php
            ├── ReasonTranslation/
            │   ├── ExecutionDenialReasonTranslationTest.php
            │   ├── ProviderReasonTranslationTest.php
            │   ├── RbacReasonTranslationTest.php
            │   ├── ReasonResolutionEnvelopeTest.php
            │   └── TenantOperabilityReasonTranslationTest.php

Structure Decision: Keep the work inside the existing governance, operation, baseline compare, and reason-translation seams. Add one narrow glossary and ownership layer under app/Support/Governance and small extensions to current catalogs or envelopes rather than introducing a second cross-cutting framework. The intended implementation surface is one glossary, one operation-resolution seam, one reason-owner extension, and one subject normalizer; any additional named contracts from the data model should be realized only as small value objects under those seams when keeping them inline would duplicate meaning across multiple touched surfaces.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
Code-side platform vocabulary glossary and ownership descriptors The codebase already has governance and compare vocabulary primitives, but it lacks one maintained source that explains canonical platform terms, registry ownership, and where Intune-native terms remain valid A spec-only note or scattered inline comments would not keep code, tests, and review surfaces aligned once changes start landing
Canonical operation type alias resolution Historical stored operation codes are mixed between canonical domain-aware names and older underscore names; the platform needs one future-safe vocabulary model without breaking current run history or filters An immediate rewrite of all persisted operation types is too risky, while leaving the mixed names equally canonical defeats the purpose of the hardening
Platform reason-family classification at the translation boundary Platform surfaces need to distinguish domain-neutral cause families from domain-owned causes without flattening Provider, RBAC, and baseline compare reasons into one misleading universal enum Renaming every existing domain reason code into a platform-wide code family would add churn, blur ownership, and break current translation paths unnecessarily

Proportionality Review

  • Current operator problem: Monitoring, compare, evidence, and review surfaces still expose platform meaning through a mix of Intune-shaped operation names, reason codes, and subject terms, which makes the product's architecture harder to understand and more error-prone for future work.
  • Existing structure is insufficient because: Current governance taxonomy, compare strategy, operation catalog, and reason translation seams exist, but they do not yet define one canonical boundary for platform vocabulary ownership, alias handling, or subject descriptor hardening across touched platform surfaces.
  • Narrowest correct implementation: Extend the existing governance namespace, operation catalog, and reason translation envelope with glossary, ownership, alias, and descriptor metadata; harden only the touched platform-near payloads and surfaces; preserve Intune-owned persistence and catalogs where they are legitimately domain-specific.
  • Implementation preference: Extend existing seams first and add standalone support types only where they replace repeated array-shape ambiguity across multiple touched surfaces.
  • Ownership cost created: Ongoing glossary maintenance, explicit alias retirement review, additional architecture and regression tests, and careful review of touched platform-near payloads to keep compatibility temporary.
  • Alternative intentionally rejected: A broad repo-wide rename or a brand-new platform vocabulary framework. The rename sweep creates churn without enough boundary discipline, and the new framework would over-abstract a problem that current seams can solve more narrowly.
  • Release truth: current-release platform-boundary clarification with compatibility support, not speculative multi-domain infrastructure

Implementation Strategy

Phase A - Canonical Glossary and Ownership Boundaries

  • Add a narrow code-side glossary under app/Support/Governance that defines canonical platform terms and ownership layers.
  • Make the contributor boundary explicit so touched concepts can be classified as platform_core, cross_domain_governance, or intune_specific without relying on historical naming.
  • Classify current registries and catalogs as platform_core, cross_domain_governance, or intune_specific, starting with governance taxonomy, operation catalog, provider reason registries, and Intune policy type config.
  • Document forbidden false-universal aliases for platform contexts, especially policy_type where the surface is not explicitly Intune-owned.

Phase B - Operation Vocabulary Canonicalization

  • Extend OperationCatalog and related helpers to resolve one canonical domain-aware operation code from stored or legacy operation type values.
  • Update touched run-creating services, jobs, and launch surfaces to emit canonical operation codes on new writes wherever this spec changes the flow.
  • Expose canonical operation_type on touched read models, summaries, filters, and exports even where persisted storage continues to use operation_runs.type.
  • Keep OperationRunType readable for current services and jobs, but add alias and grouping metadata so monitoring, filters, audit prose, and run detail surfaces render canonical meaning consistently.
  • Update touched monitoring and review surfaces to rely on canonical in-process resolution rather than raw stored strings, without introducing render-time external calls or query fan-out.

Phase C - Reason Ownership and Platform Reason Families

  • Extend ReasonResolutionEnvelope and ReasonTranslator so translated explanations carry explicit ownership and platform reason-family metadata.
  • Keep ProviderReasonCodes, RbacReason, and BaselineCompareReasonCode domain-owned and namespaced.
  • Ensure operator-facing surfaces show platform reason meaning first and domain-specific cause detail second when both are present.

Phase D - Platform-Neutral Subject and Contract Hardening

  • Harden platform-near compare, snapshot, monitoring, and review payloads to prefer domain_key, subject_class, subject_type_key, and subject_type_label descriptors where available.
  • Audit platform-owned persisted payloads, especially operation_runs.context, compare subcontext payloads, and evidence payloads touched by this spec, and normalize them through wrapper or presenter contracts before any rename is considered.
  • Reduce or remove false-universal policy_type usage from touched run context, compare payloads, snapshot rendering, and reporting summaries while keeping Intune-owned persistence untouched.
  • Prefer wrapper or projection hardening for platform-owned JSON and presenter contracts before any schema change is considered.

Phase E - Transition, Guardrails, and Verification

  • Keep compatibility explicitly temporary with one canonical name per platform concept and documented legacy aliases.
  • Add regression and architecture guards so touched platform surfaces cannot reintroduce raw mixed operation codes, false-universal Intune vocabulary, non-in-process resolution paths, or request-time query fan-out on monitoring and review reads.
  • Validate no-regression Intune-first behavior across monitoring, compare, evidence, review, and snapshot surfaces touched by the hardening.

Risk Assessment

Risk Impact Likelihood Mitigation
Canonical operation aliasing turns into permanent dual vocabulary High Medium Define one canonical operation code per stored alias, make alias status explicit in code, and add tests that new writes on touched flows do not introduce new legacy names.
A platform surface still leaks policy_type after wrapper hardening High Medium Audit touched compare, snapshot, run-context, and presenter contracts; add feature and architecture tests around those surfaces.
Reason-family hardening duplicates or conflicts with existing explanation semantics Medium Medium Extend the current envelope and translator instead of adding a second explanation pipeline, and validate against existing reason-translation and baseline compare explanation tests.
Monitoring filters, labels, or audit prose break when operation types are canonicalized Medium Medium Route filters and labels through canonical resolution and extend OperationRunListFiltersTest, monitoring presentation tests, and audit-event coverage.
The implementation drifts into Intune adapter rewrites or schema churn Medium Low Keep ownership descriptors explicit, prefer wrapper-first hardening, and require a focused proportionality review before any schema change on a platform-owned field.

Test Strategy

  • Add focused unit coverage for the platform glossary and operation vocabulary alias resolution.
  • Extend tests/Unit/Support/ReasonTranslation/ReasonResolutionEnvelopeTest.php, ProviderReasonTranslationTest.php, and RbacReasonTranslationTest.php for ownership and platform reason-family metadata.
  • Extend tests/Architecture/ReasonTranslationPrimarySurfaceGuardTest.php so platform surfaces cannot bypass canonical translation or leak raw domain-owned codes as universal platform reasons.
  • Extend tests/Feature/Filament/OperationRunListFiltersTest.php, OperationRunEnterpriseDetailPageTest.php, OperationRunBaselineTruthSurfaceTest.php, RecentOperationsSummaryWidgetTest.php, ProviderConnectionsDbOnlyTest.php, InventoryItemResourceTest.php, BackupScheduleCrudTest.php, and OnboardingEntryPointTest.php for canonical operation labels, grouping, launch-surface wording, and filter continuity.
  • Extend tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php and tests/Feature/System/Spec114/ControlTowerDashboardTest.php so historical and canonical operation codes render the same operator meaning during transition across both monitoring pages and monitoring widgets.
  • Extend tests/Feature/ReasonTranslation/GovernanceReasonPresentationTest.php and ReasonTranslationExplanationTest.php so platform and domain explanation layering remains explicit.
  • Extend tests/Unit/Baselines/SnapshotRendering/BaselineSnapshotPresenterTest.php, tests/Feature/Evidence/EvidenceSnapshotResourceTest.php, tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php, and BaselineCompareWhyNoFindingsReasonCodeTest.php for platform-near subject vocabulary hardening without Intune behavior regression.
  • Extend tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php, tests/Feature/TenantReview/TenantReviewExecutivePackTest.php, tests/Feature/TenantReview/TenantReviewUiContractTest.php, tests/Feature/ReviewPack/ReviewPackGenerationTest.php, and tests/Feature/ReviewPack/ReviewPackWidgetTest.php so reporting and executive-pack summaries honor the same canonical vocabulary and explanation ownership rules.
  • The focused completion gate for this spec is the full quickstart verification pack, which includes every suite named in the story-level and continuity test tasks plus the final architecture and authorization guard suites.
  • Keep existing compare start-surface, baseline summary, and RBAC-related coverage green so vocabulary hardening does not change authorization or workflow semantics.