18 KiB
Implementation Plan: Spec 421 - Entra Core Comparable / Renderable Pack
Branch: 421-entra-core-comparable-renderable-pack | Date: 2026-06-27 | Spec: specs/421-entra-core-comparable-renderable-pack/spec.md
Input: Feature specification from /specs/421-entra-core-comparable-renderable-pack/spec.md
Summary
Promote selected Entra Coverage v2 evidence to comparable/renderable support without adding capture scope, restore, certification, customer output, or an Entra mini-platform. The mandatory implementation-ready slice is conditionalAccessPolicy because current repo truth already has a content-backed source contract path from Spec 420. securityDefaults, application, servicePrincipal, roleDefinition, and administrativeUnit remain evidence-gated and may be promoted only when preflight proves repo-real content-backed evidence already exists.
Technical Context
Language/Version: PHP 8.4.15, Laravel 12, Filament v5, Livewire v4
Primary Dependencies: Existing Tenant Configuration / Coverage v2 services, GraphClientInterface only for existing evidence capture paths, ClaimGuard, BadgeCatalog/BadgeRenderer, Pest 4
Storage: Existing PostgreSQL tables for tenant_configuration_resource_types, tenant_configuration_resources, and tenant_configuration_resource_evidence; no new table by default
Testing: Pest 4 unit, feature, and focused browser if rendered UI changes
Validation Lanes: fast-feedback, confidence, browser if rendered output changes
Target Platform: Laravel Sail locally, Dokploy container deployment for staging/production
Project Type: web app under apps/platform
Performance Goals: render/compare from persisted evidence only; no remote/provider calls during UI render
Constraints: no restore, no certification, no customer-facing claims, no new capture contract, no tenant_id, no Entra mini-platform, no new OperationRun type
Scale/Scope: one mandatory evidence-backed resource type (conditionalAccessPolicy), optional Entra types only if already content-backed and testable
UI / Surface Guardrail Plan
- Guardrail scope: existing internal/operator Coverage v2 surface may change through rendered evidence/status summaries.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces: existing
CoverageV2Readinesspage,CoverageV2ResourceTypesTable,CoverageV2ResourceInstancesTable, inspect slide-over, and read model if rendered summaries are exposed. No new route, navigation, panel provider, action, report, download, or customer surface. - No-impact class, if applicable: N/A - rendered data may change.
- Native vs custom classification summary: native Filament + existing widgets/read model.
- Shared-family relevance: evidence/status/read-only registry and inspect details.
- State layers in scope: page/detail evidence display; no shell/navigation state.
- Audience modes in scope: operator-MSP and support-platform; no customer/read-only output.
- Decision/diagnostic/raw hierarchy plan: typed summary first, diagnostics second, raw/support evidence hidden or secondary.
- Raw/support gating plan: raw payload not default-visible; secrets never shown.
- One-primary-action / duplicate-truth control: keep existing inspect link as the only action; no capture/restore/certify/export action.
- Handling modes by drift class or surface: Product Surface and browser proof are review-mandatory if rendered output changes; runtime UI expansion is hard-stop until spec/plan/tasks are amended.
- Repository-signal treatment: report-only for no new UI files; review-mandatory for existing rendered output changes; exception-required for any new surface/action.
- Special surface test profiles: shared-detail-family / standard-native-filament.
- Required tests or manual smoke: focused browser if rendered output changes; feature tests for no raw/default overclaim.
- Exception path and spread control: none.
- Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
- UI/Productization coverage decision: existing internal surface only; no coverage artifact unless UI scope expands.
- Coverage artifacts to update: none by default.
- No-impact rationale: N/A.
- Navigation / Filament provider-panel handling: no provider/panel/navigation change.
- Screenshot or page-report need: no page report by default; browser proof is sufficient for existing internal surface rendering.
Product Surface Contract Plan
- Product Surface Contract reference:
docs/product/standards/product-surface-contract.md. - No-legacy posture: canonical Coverage v2 extension; no compatibility exception.
- Page archetype and surface budget plan: Existing Technical Annex / internal operator evidence inspection surface; budgets pass because no new page/action family is added.
- Technical Annex and deep-link demotion plan: OperationRun links, evidence IDs, source keys, raw/normalized payloads, provider IDs, permission context, and unsupported fields remain secondary/diagnostic.
- Canonical status vocabulary plan: Use existing Coverage v2 labels and canonical status wording; no
Entra covered,certified,restore-ready,customer-ready, or100%labels. - Product Surface exceptions: none.
- Browser verification plan: focused Coverage v2 route/inspect flow if rendered output changes; otherwise
N/A - no rendered UI surface changedwith proof. - Human Product Sanity plan: required if rendered output changes; result in implementation report.
- Visible complexity outcome target: neutral or decreased.
- Implementation report target:
specs/421-entra-core-comparable-renderable-pack/implementation-report.md.
Filament / Livewire / Deployment Posture
- Livewire v4 compliance: Livewire v4.x confirmed; no Livewire v3 APIs.
- Panel provider registration location: no panel provider change; Laravel 12 provider registration remains
apps/platform/bootstrap/providers.php. - Global search posture: no Filament Resource global-search behavior changed; no new Resource.
- Destructive/high-impact action posture: none. No restore/apply/capture/export/certify action is introduced.
- Asset strategy: no assets by default;
filament:assetsis not newly required beyond existing deployment practice. - Testing plan: unit tests for typed behavior; feature tests for evidence-gated promotion, claims, redaction, scope, no overclaim; browser proof if rendered output changes.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, or assets expected.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched:
ResourceTypeRegistry,TenantConfigurationResourceType,TenantConfigurationResource,TenantConfigurationResourceEvidence,GenericPayloadNormalizer,CoveragePayloadRedactor,CoverageIdentityStrategyRegistry,CanonicalIdentityResolver,ClaimGuard,CoverageV2ReadinessReadModel, existing Coverage v2 widgets if rendered. - Shared abstractions reused: Existing Coverage v2 registry, evidence, identity, redaction, Claim Guard, badges, and read-only operator surface.
- New abstraction introduced? why?: Bounded Entra typed normalizer/comparator/render summary helpers may be introduced because generic payload sorting/redaction is insufficient for operator-safe Conditional Access comparison.
- Why the existing abstraction was sufficient or insufficient: Existing structures are sufficient for ownership, evidence, identity, claims, redaction, and rendering host; insufficient for typed Entra material-field semantics.
- Bounded deviation / spread control: Entra-specific field semantics stay inside bounded helpers/config for evidence-backed types and must not become a provider framework.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no new start/completion/link UX.
- Central contract reused: N/A by default; existing OperationRun links remain diagnostics only if already present.
- Delegated UX behaviors: N/A.
- Surface-owned behavior kept local: read-only inspect only.
- Queued DB-notification policy: N/A.
- Terminal notification path: N/A.
- Exception path: none. If compare/render becomes long-running or persisted as an operation, stop and amend the spec.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes.
- Provider-owned seams: Entra resource names, Graph field names, Conditional Access targeting/control semantics, optional Security Defaults fields.
- Platform-core seams: Coverage v2 evidence/resource state, coverage level, identity state, claim state, redaction boundary, workspace/managed-environment/provider connection ownership, Product Surface output.
- Neutral platform terms / contracts preserved: resource type, evidence, compare result, render summary, coverage level, claim state, identity state, provider connection, managed environment.
- Retained provider-specific semantics and why: Necessary to compare/render actual Entra evidence; bounded to current selected resource types.
- Bounded extraction or follow-up path: document-in-feature for optional type blockers; follow-up-spec for missing Security Defaults capture/source contract.
Constitution Check
- Inventory/evidence truth: PASS. Render/compare derives from existing last-observed evidence; it does not create customer proof.
- Read/write separation: PASS. No provider write, restore, apply, or mutating UI action.
- Graph contract path: PASS by default. No new capture or render-time Graph calls; any existing evidence remains from existing contract paths.
- Deterministic capabilities: PASS. Coverage-level promotion and compare behavior are testable.
- Workspace isolation: PASS with workspace + managed environment + provider connection scope requirements.
- RBAC-UX: PASS with existing Evidence View authorization and no action surface.
- OperationRun: PASS by default. No new OperationRun type or lifecycle; existing links remain diagnostics only.
- Evidence anchor/currentness: PASS if evidence is explicit and no fallback-to-latest is added.
- Customer output: PASS. No customer-facing output, report, download, or customer-ready claim.
- Provider boundary: PASS if Entra semantics stay in bounded typed helpers and provider-native IDs remain metadata.
- Product Surface: PASS with existing-surface proof and Product Surface exceptions
none. - Test governance: PASS with Unit/Feature/Browser-if-rendered lanes named.
- Proportionality: PASS. Typed helpers are justified by operator-safe compare/render and avoid new tables/frameworks.
- No premature abstraction: PASS if implementation avoids generic provider frameworks and separate Entra engines.
- Persisted truth: PASS by default. Existing evidence remains truth; compare/render derived unless spec amended.
- Behavioral state: PASS using existing coverage levels and derived non-persisted importance labels.
- No legacy / lean doctrine: PASS. No adapters, dual reads/writes, fallback readers, legacy aliases, or
tenant_id.
Testing / Lane / Runtime Impact
- Test purpose / classification by changed surface: Unit for normalization/compare/render/redaction/Claim Guard; Feature for evidence-gated promotion, RBAC/scope/no-overclaim/no-restore/no-certification/no-tenant-id/no-mini-platform; Browser if rendered Coverage v2 output changes.
- Validation lane(s): fast-feedback, confidence, browser-if-rendered.
- Fixture/helper/factory cost: minimal workspace/managed-environment/provider/evidence setup; fake payloads only; no live Graph/TCM calls.
- Heavy-family visibility: none expected.
- Reviewer handoff: confirm optional type blockers are documented, no runtime capture expansion occurred, and no hidden customer output or UI action was introduced.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec421EntraConditionalAccessNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraComparableDiffTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraRenderableSummaryTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraRedactionTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraClaimGuardTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.php tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.php tests/Feature/TenantConfiguration/Spec421EntraNoRestoreNoCertificationTest.php tests/Feature/TenantConfiguration/Spec421EntraNoTenantIdTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.phpif rendered output changesgit diff --check
Likely Repo Surfaces
Runtime implementation should verify current names before editing, but likely surfaces are:
apps/platform/app/Services/TenantConfiguration/GenericPayloadNormalizer.phpapps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.phpapps/platform/app/Services/TenantConfiguration/ClaimGuard.phpapps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.phpapps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.phpapps/platform/app/Filament/Pages/TenantConfiguration/CoverageV2Readiness.phpapps/platform/app/Filament/Widgets/TenantConfiguration/CoverageV2ResourceTypesTable.phpapps/platform/app/Filament/Widgets/TenantConfiguration/CoverageV2ResourceInstancesTable.php- New bounded helper files under
apps/platform/app/Services/TenantConfiguration/if needed, such asEntraComparablePayloadNormalizer.php,EntraCoverageComparator.php, andEntraRenderableSummaryBuilder.php. - Focused Spec 421 tests under
apps/platform/tests/Unit/Support/TenantConfiguration/,apps/platform/tests/Feature/TenantConfiguration/, andapps/platform/tests/Browser/if rendered output changes.
Domain / Model Implications
- No new database table, migration, persisted compare result table, or model is expected.
TenantConfigurationResourceEvidence.coverage_leveland existing CoverageLevel values can representcomparable/renderable.- Registry defaults for Entra types must not imply broad support or customer claims. Promotion should be evidence-gated and internal.
- Derived compare importance labels must not become a persisted taxonomy.
- Raw payload remains an internal evidence storage boundary; render summaries use redacted/normalized data.
Implementation Phases
Phase 0 - Preflight And Evidence Matrix
Capture branch, HEAD, dirty state, activated skills, related completed-spec guardrail, and stop conditions. Verify current Coverage v2 service names and evidence availability for all draft Entra types. Record which types are content-backed, blocked, or deferred.
Phase 1 - Tests First: Typed Semantics And Safety
Add focused Pest unit tests for Conditional Access normalization, deterministic compare, render summaries, volatile-field handling, redaction, and Claim Guard. Add evidence-gated tests for Security Defaults and optional types so missing evidence remains an explicit blocker.
Phase 2 - Evidence-Gated Promotion
Implement or extend the narrow promotion path so only content-backed, typed-tested resource evidence can report comparable/renderable support. Do not promote any missing-evidence type.
Phase 3 - Entra Typed Normalization
Add bounded typed normalization for Conditional Access and any evidence-backed optional type. Exclude volatile fields, preserve unsupported fields as diagnostics, and keep identity/source metadata separate.
Phase 4 - Entra Compare
Add deterministic compare semantics for selected typed payloads. Classify changes, ignore volatile fields, handle redacted values, use stable ordering, and attach derived bounded importance labels.
Phase 5 - Entra Render Summaries
Add operator-safe render summaries. Conditional Access summary must include state, targets, conditions, grant/session controls, claim/identity state, unsupported/redacted diagnostics, and last captured time without raw payload display.
Phase 6 - Claim Guard, Product Surface, RBAC, And Evidence Boundaries
Extend Claim Guard tests for Entra wording, ensure read model/surface output stays internal and authorized, and confirm no customer output, restore/certification, direct Graph calls, or raw default payload rendering.
Phase 7 - Browser Proof If Rendered
If rendered output changes, add focused browser proof for the existing Coverage v2 surface and inspect slide-over. Verify no console errors, no Livewire/Filament errors, no secrets/raw payload, and no restore/certify/customer-ready claim.
Phase 8 - Validation And Implementation Report
Run focused validation, git diff --check, and complete the implementation report with matrices, Product Surface close-out, tests, browser/no-browser, deployment impact, no completed-spec rewrite assertion, and deferred work.
Stop Conditions
- Security Defaults or optional Entra types need new capture/source contracts to become content-backed.
- Any implementation proposes restore/apply, certification, customer-facing output, Review Pack/report/PDF output, export/download, or broad coverage claims.
- A new OperationRun type, new capture start action, new route/navigation/dashboard, or new persisted compare table is proposed without amending the spec.
- Raw payloads, secrets, credentials, tokens, provider response bodies, or provider IDs become default-visible.
tenant_idappears as Coverage v2 ownership truth.- A separate Entra table family, engine, dashboard, or provider mini-platform appears.
- Render/compare performs Graph/TCM/provider/HTTP work at render time.
Draft-To-Repo Deviation Handling
- The user draft's minimum
securityDefaultspromotion is changed to evidence-gated promotion because current repo truth does not prove content-backed evidence for Security Defaults and the draft forbids faking typed support or adding missing capture. - The user draft's optional initial resource list remains as preflight candidates, not mandatory implementation scope.
- The implementation report must include a matrix explaining promoted and deferred types.