TenantAtlas/specs/419-m365-tcm-workload-registry-expansion/plan.md
ahmido 5252398063 feat: expand m365 tcm workload registry (#486)
Automated PR provided by Codex via Gitea API.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #486
2026-06-26 22:36:24 +00:00

20 KiB

Implementation Plan: Spec 419 - M365 TCM Workload Registry Expansion

Branch: 419-m365-tcm-workload-registry-expansion | Date: 2026-06-26 | Spec: specs/419-m365-tcm-workload-registry-expansion/spec.md Input: Feature specification from /specs/419-m365-tcm-workload-registry-expansion/spec.md

Summary

Expand the existing Coverage v2 registry so TenantPilot can classify Microsoft 365 TCM workload families as registry-only/detected planning truth without activating capture, compare, render, restore, certification, customer output, or UI changes. The implementation should reuse TenantConfigurationResourceType, TenantConfigurationSupportedScope, ResourceTypeRegistry, Coverage v2 enum/check constraints, metadata JSONB, and ClaimGuard. New non-Intune entries default conservatively and broad M365 claims remain blocked.

Technical Context

Language/Version: PHP 8.4.x, Laravel 12.x Primary Dependencies: existing Coverage v2 TenantConfiguration models/services/enums, Pest 4, PostgreSQL via Sail Storage: Existing tenant_configuration_resource_types and tenant_configuration_supported_scopes; JSONB metadata preferred for catalog/documentation metadata. No new core table by default. Testing: Pest 4 / PHPUnit 12 via Sail Validation Lanes: fast-feedback, confidence, PostgreSQL lane if enum/check constraints or JSONB/query constraints change, focused browser if active rows/scopes render on the existing Spec 418 surface Target Platform: Laravel Sail locally, Dokploy/container deployment for staging/production Project Type: Laravel monolith under apps/platform Performance Goals: deterministic local registry sync/seed, no remote calls, no runtime docs fetch, bounded test fixtures Constraints: registry-only, no runtime UI route/action changes, existing-surface data-impact proof if rendered, no Graph/TCM/provider calls, no concrete evidence rows, no tenant_id, no mini-platform tables/classes, no broad M365 customer claims Scale/Scope: representative or full static M365 TCM catalog entries for Entra, Exchange, Teams, Security and Compliance, plus safe workload-level Defender/Purview status

UI / Surface Guardrail Plan

  • Guardrail scope: no runtime UI code change, no new route, and no new action; existing operator-facing Coverage v2 surface may change data-driven rows/scopes.
  • Affected routes/pages/actions/states/navigation/panel/provider surfaces: existing Spec 418 Coverage v2 readiness/resource-type registry surface only, via active registry data. No route, navigation, action, panel provider, Blade, or Livewire file change is planned.
  • No-impact class, if applicable: not applicable if new rows/scopes render. This is a backend registry/config/persistence seed with possible existing-surface data impact.
  • Native vs custom classification summary: N/A.
  • Shared-family relevance: no UI shared-family change.
  • State layers in scope: registry/persistence state plus existing Coverage v2 operator table/filter/scope data; no shell/page/detail/URL state changes.
  • Audience modes in scope: N/A.
  • Decision/diagnostic/raw hierarchy plan: existing rendered hierarchy only. Registry metadata must avoid customer-proof wording, raw provider payloads, and proof semantics.
  • Raw/support gating plan: no raw payload or provider response storage in manifest metadata.
  • One-primary-action / duplicate-truth control: no actions.
  • Handling modes by drift class or surface: hard stop if runtime UI file edits, route, navigation, action, report, customer output, or rendered labels are needed. Data-driven rows/scopes on the existing Spec 418 surface require focused proof.
  • Repository-signal treatment: no UI audit registry update unless implementation amends scope.
  • Special surface test profiles: N/A.
  • Required tests or manual smoke: unit and feature/static guards plus focused existing-surface browser proof if new active rows/scopes render.
  • Exception path and spread control: none.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage with either focused existing-surface proof or explicit proof that no rendered output changed.
  • UI/Productization coverage decision: Existing operator surface data impact only; no UI code change.
  • Coverage artifacts to update: active Spec 419 artifacts and implementation report only. Do not rewrite Spec 418.
  • No-impact rationale: no runtime UI files are planned, but active registry rows/scopes may render on the existing generic Spec 418 surface.
  • Navigation / Filament provider-panel handling: no panel/provider registration change.
  • Screenshot or page-report need: focused browser proof is required if rendered rows/scopes change.

Product Surface Contract Plan

  • Product Surface Contract reference: docs/product/standards/product-surface-contract.md.
  • No-legacy posture: canonical Coverage v2 registry expansion; no compatibility exception.
  • Page archetype and surface budget plan: existing internal/operator Coverage v2 readiness and registry inspection surface. Use the existing table/filter/modal budget only.
  • Technical Annex and deep-link demotion plan: Registry metadata must not create customer-facing proof, raw provider output, or raw technical output. Source/catalog notes remain internal metadata.
  • Canonical status vocabulary plan: Use existing internal Coverage v2 enums plus explicit registry-only/detected wording. Do not introduce page-local M365 coverage truth.
  • Product Surface exceptions: none.
  • Browser verification plan: focused existing-surface browser proof if active rows/scopes render; otherwise document proof that rendered output did not change.
  • Human Product Sanity plan: required if active rows/scopes render; otherwise N/A with proof.
  • Visible complexity outcome target: slightly broader existing registry data, no new surface family.
  • Implementation report target: specs/419-m365-tcm-workload-registry-expansion/implementation-report.md.

Filament / Livewire / Deployment Posture

  • Livewire v4 compliance: Livewire v4.x remains the required runtime. No Livewire code is planned.
  • Panel provider registration location: Laravel 12 panel providers remain in apps/platform/bootstrap/providers.php; no panel/provider change is planned.
  • Global search posture: no Filament Resource changes. If a Resource is unexpectedly added, stop and amend the spec.
  • Destructive/high-impact action posture: none. No action may mutate tenant/provider state, start capture, restore, certify, publish, export, or override claims.
  • Asset strategy: no assets. filament:assets not required unless scope is amended to register Filament assets.
  • Testing plan: focused unit/feature/static guard tests for registry, manifest/defaults, supported scopes, Claim Guard, default-scope preservation, no runtime capture, no mini-platform, no tenant_id, plus focused existing-surface browser proof if active rows/scopes render.
  • Deployment impact: migrations/check constraints likely if workload enum values are persisted with PostgreSQL checks. No env vars, queues, scheduler, storage, assets, or workers. Static registry/seed changes must be validated on staging before production.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes at domain-contract level; no UI interaction family.
  • Systems touched: TenantConfigurationResourceType, TenantConfigurationSupportedScope, ResourceTypeRegistry, ClaimGuard, Workload, possible enum/check constraints, registry tests.
  • Shared abstractions reused: existing Coverage v2 registry/scope/claim guard paths.
  • New abstraction introduced? why?: none by default. A static manifest/config file is allowed only if it replaces scattered arrays and remains local reviewed data.
  • Why the existing abstraction was sufficient or insufficient: Existing registry is sufficient for resource type and supported-scope truth, but its current workload enum/check values are Intune-only.
  • Bounded deviation / spread control: no M365-specific engine, table, dashboard, capture service, provider framework, or UI presenter.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: no.
  • Central contract reused: N/A.
  • Delegated UX behaviors: N/A.
  • Surface-owned behavior kept local: none.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: N/A.
  • Exception path: none.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes.
  • Provider-owned seams: Microsoft workload names, TCM catalog source URLs, source aliases, Microsoft documentation review metadata, Graph fallback/beta source classification.
  • Platform-core seams: workload enum/check constraints, canonical resource type, source class, support state, coverage/evidence/identity/claim defaults, supported scopes, restore tier, Claim Guard.
  • Neutral platform terms / contracts preserved: provider connection, managed environment, resource type, workload, source class, supported scope, coverage level, evidence state, claim state, restore tier.
  • Retained provider-specific semantics and why: Microsoft M365 workload labels remain because this spec is explicitly an M365 TCM registry expansion. They stay source metadata and classification, not ownership truth.
  • Bounded extraction or follow-up path: document-in-feature if a static manifest path is introduced; follow-up-spec only for capture/compare/render/restore/certification packs.

Constitution Check

  • Inventory/evidence truth: PASS. Registry entries are denominator/planning truth only and do not create evidence rows.
  • Read/write separation: PASS. No tenant/provider write action or restore path.
  • Graph contract path: PASS. No Graph calls; no hardcoded endpoints outside contracts.
  • Deterministic capabilities: PASS. Defaults are deterministic and testable.
  • RBAC-UX: PASS. No new UI/action. Future consumers must enforce existing RBAC.
  • Workspace isolation: PASS. Registry definitions are platform/product metadata; concrete evidence remains workspace/managed-environment scoped.
  • OperationRun: PASS. No queued/remote work.
  • Evidence/currentness: PASS. not_captured remains explicit for new entries.
  • Customer output: PASS. No Review Pack/report/customer surface changes.
  • Provider boundary: PASS with Microsoft source metadata bounded to registry fields.
  • Product Surface: PASS for data-driven existing-surface impact if active rows/scopes render; otherwise N/A only with proof that no rendered output changed.
  • Test governance: PASS. Unit/feature/pgsql-if-needed lanes named; no browser/heavy family.
  • Proportionality: PASS. Workload enum/registry expansion is justified by false-claim prevention and future pack consistency.
  • No premature abstraction: PASS if implementation reuses existing registry.
  • Persisted truth: PASS. Registry definitions are durable product metadata; no new core table by default.
  • Behavioral state: PASS with existing conservative support/coverage/evidence/claim/restore values. New source/support/restore states require amendment.
  • No legacy / pre-production lean: PASS. No compatibility paths, tenant_id, v1 adapters, fallback readers, or dual writes.

Test Governance Check

  • Test purpose / classification by changed surface: Unit for enum/default manifest/Claim Guard; Feature for persisted registry/supported scopes/no-overclaim/no-runtime/no-mini-platform/no-tenant-id; PostgreSQL if migrations/check constraints change.
  • Affected validation lanes: fast-feedback, confidence, pgsql only if schema/check constraints are changed, focused browser if active rows/scopes render on the existing Spec 418 operator surface.
  • Why this lane mix is the narrowest sufficient proof: The change is registry/config/persistence truth. Unit and feature/static guards prove registry/default/claim behavior; focused browser proof is required only for the existing rendered surface when new active rows/scopes become visible.
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec419M365WorkloadRegistryTest.php tests/Unit/Support/TenantConfiguration/Spec419M365ResourceTypeManifestTest.php tests/Unit/Support/TenantConfiguration/Spec419M365ClaimGuardTest.php tests/Unit/Support/TenantConfiguration/Spec419M365RestoreTierDefaultTest.php tests/Unit/Support/TenantConfiguration/Spec419M365DocumentationStatusTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec419M365RegistryExpansionTest.php tests/Feature/TenantConfiguration/Spec419M365SupportedScopesTest.php tests/Feature/TenantConfiguration/Spec419M365NoOverclaimTest.php tests/Feature/TenantConfiguration/Spec419M365NoRuntimeCaptureTest.php tests/Feature/TenantConfiguration/Spec419M365NoMiniPlatformTest.php tests/Feature/TenantConfiguration/Spec419M365NoTenantIdTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec419M365RegistryOperatorSurfaceSmokeTest.php if active rows/scopes render on the existing operator surface, or the repo-equivalent focused browser smoke path
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/TenantConfiguration/Spec419M365RegistryExpansionTest.php tests/Feature/TenantConfiguration/Spec419M365SupportedScopesTest.php if migrations/check constraints/indexes change
    • git diff --check
  • Fixture / helper / factory / seed / context cost risks: keep M365 registry factories/fixtures local or opt-in; do not make broad workspace/provider setup default.
  • Expensive defaults or shared helper growth introduced?: none expected.
  • Heavy-family additions, promotions, or visibility changes: focused existing-surface browser smoke only when rows/scopes render; no broad browser family by default.
  • Surface-class relief / special coverage rule: browser proof may be N/A only when implementation proves no rendered output changed.
  • Closing validation and reviewer handoff: implementation report records exact files, matrices, default-scope proof, no-overclaim proof, no-runtime proof, no-tenant-id proof, no-mini-platform proof, Product Surface/browser proof or N/A proof, commands/results, and deferred work.
  • Budget / baseline / trend follow-up: none expected unless PostgreSQL lane or guard tests become broad.
  • Review-stop questions: lane fit, partial/full catalog honesty, broad claim blocking, no runtime capture, no mini-platform, no tenant_id, no runtime UI code scope, and Product Surface data-impact proof.
  • Escalation path: document-in-feature for contained metadata/enum expansion; follow-up-spec for capture, UI, full-catalog import tooling, or new registry tables.
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
  • Why no dedicated follow-up spec is needed: this is the bounded registry denominator expansion; downstream capability packs are listed separately.

Project Structure

Documentation (this feature)

specs/419-m365-tcm-workload-registry-expansion/
+-- spec.md
+-- plan.md
+-- tasks.md
+-- checklists/
    +-- requirements.md

Source Code (likely affected in later implementation)

apps/platform/app/
+-- Services/TenantConfiguration/
|   +-- ResourceTypeRegistry.php
|   +-- ClaimGuard.php
+-- Support/TenantConfiguration/
|   +-- Workload.php
|   +-- SourceClass.php
|   +-- SupportState.php
|   +-- CoverageLevel.php
|   +-- EvidenceState.php
|   +-- ClaimState.php
|   +-- RestoreTier.php
+-- Models/
    +-- TenantConfigurationResourceType.php
    +-- TenantConfigurationSupportedScope.php

apps/platform/database/migrations/
+-- <new migration if enum/check constraints or metadata columns require schema change>

apps/platform/tests/
+-- Unit/Support/TenantConfiguration/
+-- Feature/TenantConfiguration/

Structure Decision: Reuse the existing Coverage v2 registry and scope infrastructure. Prefer existing metadata JSONB and static registry definitions. Do not add workload-specific tables/classes or a parallel M365 registry service.

Implementation Phases

Phase 0 - Preflight

Capture branch, HEAD, dirty state, activated skills, current Coverage v2 registry/service names, related completed-spec guardrail, and stop conditions. Confirm no unrelated dirty files before implementation.

Phase 1 - Inspect Existing Registry Truth

Inspect current enum values/check constraints, ResourceTypeRegistry::defaultDefinitions(), existing supported scope definitions, default scope selection, ClaimGuard, migrations, factories, and Spec 418 surface behavior. Map draft terms to current repo states before editing.

Phase 2 - Tests First: Workload And Manifest Defaults

Add focused tests for workload values, representative M365 entries, Defender/Purview supported-scope metadata, documentation status metadata, full-vs-seeded catalog markers, default scope preservation, and conservative default support/coverage/evidence/claim/restore states.

Phase 3 - Tests First: Claim And Guard Boundaries

Add Claim Guard/no-overclaim tests and static/feature guards for no runtime docs fetch, no Graph/TCM calls, no concrete evidence rows, no tenant_id, and no mini-platform tables/classes.

Phase 4 - Registry And Scope Expansion

Expand workload enum/check values, static resource type defaults or manifest/config, supported-scope planning entries, aggregate M365 workload metadata, default-scope safeguards, metadata conventions, and idempotent sync/upsert behavior.

Phase 5 - Claim Guard Expansion

Block broad M365, certified, restore-ready, complete-tenant, all-resource, and unscoped percent claims. Allow only explicit internal registry-only denominator-scoped wording when safe.

Phase 6 - Persistence And PostgreSQL Validation

If migrations/check constraints/columns change, keep them reversible and narrow. Run focused PostgreSQL validation for changed TenantConfiguration paths.

Phase 7 - Product Surface Data-Impact Verification

Confirm no UI route, page, navigation, Filament provider, action, report, download, customer output, or browser-visible claim changed. If active registry rows/scopes render on the existing Spec 418 surface, run focused browser proof that the page remains internal/operator-only, no broad M365 coverage label appears, default scope behavior is intentional, and no capture/restore/certify/report/download action appears. If runtime UI code changes are required, stop and amend artifacts before implementation continues.

Phase 8 - Validation And Implementation Report

Run Pint dirty, focused unit/feature tests, PostgreSQL lane if required, and git diff --check. Complete implementation report with workload/resource matrices and required no-overclaim/no-runtime/no-tenant-id/no-mini-platform proof.

Stop Conditions

Stop and update spec.md, plan.md, and tasks.md before continuing if any of these appear:

  • Capture, compare, render, restore, apply, certify, publish, export, customer report, Review Pack, or dashboard behavior is needed.
  • Graph/TCM/provider remote work or runtime Microsoft documentation fetch is needed.
  • A new UI route/page/navigation/action/table/form/rendered label is needed.
  • Existing Coverage v2 operator surface default scope changes without explicit Product Surface/browser proof.
  • A full static catalog import is too large for bounded review and the implementation cannot mark the catalog partial.
  • A new SourceClass, SupportState, or RestoreTier value is needed without proportionality proof and tests.
  • tenant_id appears as Coverage v2 ownership truth.
  • A workload-specific table, model, engine, provider framework, or mini-platform appears.
  • Partial catalog wording implies full M365 coverage.
  • A broad M365/certified/restore-ready/customer claim needs to be allowed.