TenantAtlas/specs/421-entra-core-comparable-renderable-pack/plan.md
Ahmed Darrazi 19037e1dd8
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m15s
feat: complete spec 421 Entra comparable/renderable pack
2026-06-27 23:42:58 +02:00

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 CoverageV2Readiness page, 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, or 100% 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 changed with 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:assets is 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 agent
    • cd 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.php
    • cd 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.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php if rendered output changes
    • git diff --check

Likely Repo Surfaces

Runtime implementation should verify current names before editing, but likely surfaces are:

  • apps/platform/app/Services/TenantConfiguration/GenericPayloadNormalizer.php
  • apps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.php
  • apps/platform/app/Services/TenantConfiguration/ClaimGuard.php
  • apps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.php
  • apps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.php
  • apps/platform/app/Filament/Pages/TenantConfiguration/CoverageV2Readiness.php
  • apps/platform/app/Filament/Widgets/TenantConfiguration/CoverageV2ResourceTypesTable.php
  • apps/platform/app/Filament/Widgets/TenantConfiguration/CoverageV2ResourceInstancesTable.php
  • New bounded helper files under apps/platform/app/Services/TenantConfiguration/ if needed, such as EntraComparablePayloadNormalizer.php, EntraCoverageComparator.php, and EntraRenderableSummaryBuilder.php.
  • Focused Spec 421 tests under apps/platform/tests/Unit/Support/TenantConfiguration/, apps/platform/tests/Feature/TenantConfiguration/, and apps/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_level and existing CoverageLevel values can represent comparable / 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_id appears 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 securityDefaults promotion 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.