Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #486
137 lines
11 KiB
Markdown
137 lines
11 KiB
Markdown
# Implementation Report: Spec 419 - M365 TCM Workload Registry Expansion
|
|
|
|
## Preflight
|
|
|
|
- Date: 2026-06-26
|
|
- Branch: `419-m365-tcm-workload-registry-expansion`
|
|
- HEAD before implementation: `4aaec352 feat: add coverage v2 operator surface (#485)`
|
|
- Dirty state before implementation: active `specs/419-m365-tcm-workload-registry-expansion/` artifacts were untracked; no unrelated tracked code changes were present.
|
|
- Dirty state after implementation: expected Spec 419 code/test/spec artifacts only.
|
|
- Activated skills/gates:
|
|
- `spec-kit-implementation-loop`: active implementation workflow.
|
|
- `.agent workflows/spec-readiness-gate`: PASS; spec, plan, tasks, and checklist existed with no blocking open questions.
|
|
- `.agent repo-contracts/product-surface-gate`: PASS with existing-surface data impact.
|
|
- `.agent temporary-migrations/tcm-cutover-guard`: PASS; no capture, restore, customer claim, or UI activation.
|
|
- `pest-testing`: used for Pest 4 unit/feature/browser tests.
|
|
- `browsertest`: used for focused existing-surface browser proof.
|
|
- Dependency context: Specs 414, 415, 417, and 418 were read-only context and were not modified.
|
|
- Stop conditions: none hit.
|
|
|
|
## Files Changed
|
|
|
|
- `apps/platform/app/Support/TenantConfiguration/Workload.php`
|
|
- `apps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.php`
|
|
- `apps/platform/app/Services/TenantConfiguration/SupportedScopeResolver.php`
|
|
- `apps/platform/app/Services/TenantConfiguration/ClaimGuard.php`
|
|
- `apps/platform/database/migrations/2026_06_26_000419_expand_tenant_configuration_workloads.php`
|
|
- `apps/platform/tests/Unit/Support/TenantConfiguration/CoverageKernelValueTest.php`
|
|
- `apps/platform/tests/Unit/Support/TenantConfiguration/ResourceTypeRegistryTest.php`
|
|
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec419M365WorkloadRegistryTest.php`
|
|
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec419M365ClaimGuardTest.php`
|
|
- `apps/platform/tests/Feature/TenantConfiguration/TenantConfigurationResourceTypeRegistryTest.php`
|
|
- `apps/platform/tests/Feature/TenantConfiguration/TenantConfigurationSupportedScopeTest.php`
|
|
- `apps/platform/tests/Feature/TenantConfiguration/Spec419M365RegistryExpansionTest.php`
|
|
- `apps/platform/tests/Browser/Spec419M365RegistryOperatorSurfaceSmokeTest.php`
|
|
- `specs/419-m365-tcm-workload-registry-expansion/tasks.md`
|
|
- `specs/419-m365-tcm-workload-registry-expansion/implementation-report.md`
|
|
|
|
## Implementation Summary
|
|
|
|
- Expanded `Workload` to `intune`, `entra`, `exchange`, `teams`, `security_compliance`, `defender`, `purview`, `tenantpilot`, and `unknown`.
|
|
- Added a reversible migration to update the PostgreSQL workload check constraint, seed 24 representative M365 registry rows, and seed 7 inactive planning scopes.
|
|
- Added 24 active registry-only resource type definitions:
|
|
- Entra: `conditionalAccessPolicy`, `securityDefaults`, `application`, `servicePrincipal`, `roleDefinition`, `administrativeUnit`
|
|
- Exchange: `transportRule`, `acceptedDomain`, `sharedMailbox`, `remoteDomain`, `mailboxPlan`, `organizationConfig`
|
|
- Teams: `appPermissionPolicy`, `appSetupPolicy`, `meetingPolicy`, `messagingPolicy`, `teamsUpdateManagementPolicy`, `voiceRoute`
|
|
- Security and Compliance: `labelPolicy`, `retentionCompliancePolicy`, `dlpCompliancePolicy`, `autoSensitivityLabelPolicy`, `protectionAlert`, `complianceTag`
|
|
- Represented Defender and Purview only in aggregate planning metadata, not as fake certified resource types.
|
|
- Kept `ResourceTypeRegistry::defaultCanonicalTypes()` Intune-only so default capture paths do not silently expand to M365.
|
|
- Added Claim Guard statement checks that block broad M365, certified, restore-ready, complete-tenant, all-resource, and unscoped percent claims. Follow-up hardening made this token-based rather than dependent on one wording/order, so variants such as `M365 certified coverage`, `Microsoft 365 certified coverage`, and `M365 restore-ready coverage` are blocked.
|
|
|
|
## Registry Defaults
|
|
|
|
- New non-Intune rows use `source_class = tcm`.
|
|
- New non-Intune rows use `support_state = out_of_scope`.
|
|
- New non-Intune rows use `default_coverage_level = detected`.
|
|
- New non-Intune rows use `default_evidence_state = not_captured`.
|
|
- New non-Intune rows use `default_identity_state = derived`.
|
|
- New non-Intune rows use `default_claim_state = internal_only`.
|
|
- New non-Intune rows set `allows_beta_claims`, `allows_graph_fallback_claims`, and `allows_certified_claims` to false.
|
|
- Restore posture is conservative: high-risk entries are `not_restorable`; remaining representative entries are `preview_only`; none are `restorable`.
|
|
- Catalog metadata uses existing JSONB `metadata`: `documentation_status`, `catalog_source`, `catalog_last_reviewed_at`, `source_aliases`, `risk_tier`, `default_restore_posture`, `is_full_catalog`, `catalog_import_batch`, and `customer_claims_allowed`.
|
|
- Full-vs-partial decision: all new M365 catalog rows/scopes are partial representative planning truth with `is_full_catalog = false`.
|
|
|
|
## Supported Scopes
|
|
|
|
Added inactive planning scopes:
|
|
|
|
- `m365_tcm_registry_detected`
|
|
- `entra_tcm_registry_detected`
|
|
- `exchange_tcm_registry_detected`
|
|
- `teams_tcm_registry_detected`
|
|
- `security_compliance_tcm_registry_detected`
|
|
- `m365_tcm_generic_future`
|
|
- `m365_tcm_certified_none`
|
|
|
|
All new M365 scopes use `minimum_coverage_level = detected`, `customer_claims_allowed = false`, `is_active = false`, and registry-only metadata. Existing active Intune scopes remain the only active supported scopes, preserving the Coverage v2 operator surface default scope.
|
|
|
|
## Guard Proof
|
|
|
|
- No runtime capture path added: no Graph client, provider gateway, HTTP remote call, capture job, scheduler sync, or runtime Microsoft documentation fetch was introduced.
|
|
- No concrete resource data added by registry sync: `TenantConfigurationResource` and `TenantConfigurationResourceEvidence` remain untouched by defaults/sync.
|
|
- No `tenant_id` ownership truth added to registry definition tables or Spec 419 changed files.
|
|
- No workload mini-platform added: no Entra/Exchange/Teams/SecurityCompliance/Defender/Purview tables, models, engines, or namespaces.
|
|
- No v1 compatibility path added: no v1 adapter, fallback reader, dual write, or old gap taxonomy.
|
|
- No broad M365 claim is allowed. Internal registry-scoped denominator wording returns `internal_only` only when explicitly requested for operator/internal context.
|
|
- Rollback guard proof: rollback now deletes only rows tagged with the exact Spec 419 `catalog_import_batch`; if a later migration promotes a Non-Intune row/scope by changing that metadata, rollback preserves it and keeps the PostgreSQL workload check compatible with remaining workloads.
|
|
|
|
## Product Surface Close-Out
|
|
|
|
- No runtime UI route, Filament page/provider, navigation entry, Blade view, Livewire component, action, report, download, customer output, asset, or rendered label was edited.
|
|
- Product Surface Impact: existing Spec 418 Coverage v2 operator surface has data-driven impact because active registry rows now render.
|
|
- UI Surface Impact: existing Coverage v2 resource type registry table can show new M365 rows; no new controls or routes.
|
|
- Page archetype: internal/operator registry/readiness surface.
|
|
- Surface budget: existing table/filter/inspect affordances only.
|
|
- Technical Annex/deep-link demotion: catalog/source details remain internal registry metadata, not customer proof.
|
|
- Canonical status vocabulary: existing Coverage v2 enum vocabulary only; no legacy gap vocabulary.
|
|
- Product Surface exceptions: none.
|
|
- Focused browser proof: PASS via `tests/Browser/Spec419M365RegistryOperatorSurfaceSmokeTest.php`.
|
|
- Human Product Sanity: PASS. Browser proof showed registry rows with conservative labels (`Out of scope`, `Detected`, `Not included`, `Internal only`), no broad M365 coverage/certification/restore-ready labels, no table capture/restore/certify/publish/export/download/report actions, inactive M365 planning scope keys not rendered, Livewire present, no console or JavaScript errors, and no remote Graph/TCM/provider resource loads.
|
|
- Visible complexity outcome: broader registry data on the existing surface; no new page family.
|
|
|
|
## Filament / Livewire / Assets
|
|
|
|
- Livewire v4.0+ compliance: unchanged; no Livewire code was edited.
|
|
- Provider registration location: unchanged; Laravel panel providers remain registered through `apps/platform/bootstrap/providers.php`.
|
|
- Global search: no Filament Resource changes; no globally searchable resource added or changed.
|
|
- Destructive/high-impact actions: none added.
|
|
- Asset strategy: no new global or on-demand assets; no `filament:assets` deployment requirement introduced.
|
|
- Testing plan: unit, feature/static, pgsql constraint proof, and focused browser smoke were run.
|
|
|
|
## Deployment Impact
|
|
|
|
- Migration impact: yes. `2026_06_26_000419_expand_tenant_configuration_workloads.php` updates the PostgreSQL workload check constraint and upserts registry/scope rows.
|
|
- Rollback impact: deletes only exact Spec 419 planning scopes and M365 registry rows identified by the Spec 419 import-batch metadata. It restores the Intune-only workload check when no later Non-Intune rows remain; if later Non-Intune rows remain, it preserves those rows and constrains to the remaining workload values instead of damaging future entries.
|
|
- Environment variables: none.
|
|
- Queues/workers/scheduler: none.
|
|
- Storage/volumes: none.
|
|
- Assets: none.
|
|
- Staging expectation: run migrations and the focused registry/pgsql/browser validation before production promotion.
|
|
|
|
## Validation
|
|
|
|
- `cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/ResourceTypeRegistry.php`: PASS
|
|
- `cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/SupportedScopeResolver.php`: PASS
|
|
- `cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/ClaimGuard.php`: PASS
|
|
- `cd apps/platform && ./vendor/bin/sail php -l database/migrations/2026_06_26_000419_expand_tenant_configuration_workloads.php`: PASS
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Unit/Support/TenantConfiguration tests/Feature/TenantConfiguration`: PASS, 102 passed, 9 skipped
|
|
- `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/TenantConfiguration/Spec419M365RegistryExpansionTest.php`: PASS, 7 passed
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Browser/Spec419M365RegistryOperatorSurfaceSmokeTest.php`: PASS, 1 passed, 28 assertions
|
|
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`: PASS
|
|
- `git diff --check`: PASS
|
|
|
|
## Deferred Work
|
|
|
|
- Actual M365 capture, compare, render, restore, certification, customer reports, dashboards, and customer-facing M365 claims remain deferred to future specs.
|
|
- Defender and Purview remain workload-status metadata only until a later spec defines representative resource types with reviewed source truth.
|