17 KiB
17 KiB
Implementation Report: Spec 421 - Entra Core Comparable / Renderable Pack
Status
- Result: implementation loop completed; manual review findings fixed; final validation passed.
- Active spec directory:
specs/421-entra-core-comparable-renderable-pack. - Branch:
421-entra-core-comparable-renderable-pack. - HEAD at implementation start:
a73a8f58 feat: complete m365 generic evidence coverage pack (#487). - Initial dirty state: active spec directory was untracked; no unrelated runtime files were dirty.
- Final dirty state: expected active spec, runtime, test, and implementation-report changes only.
- Historical specs: Specs 414, 415, 417, 418, 419, and 420 were used as read-only dependency context only. No files under those completed spec directories were modified or stripped of validation history.
Activated Skills And Gates
- Activated skills:
spec-kit-implementation-loop,pest-testing,browsertest. - Repo gates applied: spec readiness, workspace scope safety, RBAC/action safety, evidence anchor contract, Product Surface, TCM cutover guard, and Filament/Livewire v5 change loop.
- Gate result before code: pass with bounded conditions.
- Hard-gate stop conditions: none hit. No new capture/source contract, restore/apply, certification, customer output, OperationRun type, route/navigation/action, persisted compare table, Entra table family, provider mini-platform, or
tenant_idownership path was introduced. - Analysis/fix iterations: one implementation/test/fix iteration plus one post-review fix iteration. The focused unit run exposed a camelCase redaction gap for
privateKey;CoveragePayloadRedactorwas fixed to match compacted key forms. Manual review then exposed that typed render summaries were not hard-gated on same-scope content-backed captured renderable evidence and that compare output was not visible at runtime; both findings were fixed. A related Spec 420 runtime test was updated because Conditional Access evidence now correctly promotes fromcontent_backedtorenderable. Browser review later exposed a narrow-viewport clipping issue on the existing Coverage v2 readiness badge; the badge was made non-shrinking/nowrap and the focused browser smoke now asserts it remains fully inside the section. A follow-up browser review exposed redundantResource typecell content; the default table now shows the human label only, with canonical technical values remaining in inspect details.
Files Changed
- Runtime:
apps/platform/app/Services/TenantConfiguration/ClaimGuard.phpapps/platform/app/Services/TenantConfiguration/CoverageEvidenceWriter.phpapps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.phpapps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.phpapps/platform/app/Services/TenantConfiguration/EntraComparablePayloadNormalizer.phpapps/platform/app/Services/TenantConfiguration/EntraCoverageComparator.phpapps/platform/app/Services/TenantConfiguration/EntraRenderableSummaryBuilder.phpapps/platform/resources/views/filament/modals/tenant-configuration/coverage-v2-resource-inspect.blade.php
- Existing test update:
apps/platform/tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php
- New Spec 421 tests:
apps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraConditionalAccessNormalizerTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraComparableDiffTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraRenderableSummaryTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraRedactionTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraClaimGuardTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoRestoreNoCertificationTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoTenantIdTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoMiniPlatformTest.phpapps/platform/tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php
- Spec artifacts:
specs/421-entra-core-comparable-renderable-pack/tasks.mdspecs/421-entra-core-comparable-renderable-pack/implementation-report.md
Implementation Summary
- Added bounded Entra typed helpers under the existing Tenant Configuration service boundary:
EntraComparablePayloadNormalizerEntraCoverageComparatorEntraRenderableSummaryBuilder
conditionalAccessPolicyis the only promoted type. It now receives deterministic typed normalization, compare output, operator-safe render summaries, and evidence-gatedCoverageLevel::Renderablepromotion when captured as content-backed evidence.securityDefaults,application,servicePrincipal,roleDefinition, andadministrativeUnitremain unpromoted/deferred because current repo truth does not prove content-backed evidence for them without new capture/source-contract scope.- Existing
CoveragePayloadRedactornow also catches camelCase and separator-free sensitive key forms such asprivateKey. CoverageV2ReadinessReadModel::inspectDetails()exposes a typed render summary only when latest evidence is same-scope, content-backed, captured, renderable, and supported by the bounded Entra summary builder.- The existing Coverage v2 inspect slide-over now displays the safe Conditional Access summary and a bounded material-change compare summary while keeping raw payloads, previous/current raw compare values, source endpoints, provider response bodies, tokens, secrets, restore/certification/customer claims, and high-impact actions out of the default surface.
Entra Evidence Matrix
| Canonical type | Current repo truth | Spec 421 result | Provider/render calls |
|---|---|---|---|
conditionalAccessPolicy |
Explicit Spec 420 content-backed source contract path exists | promoted to typed comparable/renderable when captured; coverage level renderable |
capture remains existing path; render/compare are DB-only |
securityDefaults |
registry planning row only; no proven content-backed evidence | deferred/unpromoted | no provider/render call |
application |
registry planning row only; no proven content-backed evidence | deferred/unpromoted | no provider/render call |
servicePrincipal |
registry planning row only; no proven content-backed evidence | deferred/unpromoted | no provider/render call |
roleDefinition |
registry planning row only; no proven content-backed evidence | deferred/unpromoted | no provider/render call |
administrativeUnit |
registry planning row only; no proven content-backed evidence | deferred/unpromoted | no provider/render call |
Normalizer / Compare / Render Proof
- Normalization:
- Produces deterministic Conditional Access typed shape.
- Ignores volatile Graph context, etag, created, and modified timestamps.
- Sorts unordered scalar lists for stable compare.
- Tracks unsupported field names and redacted field paths as diagnostics.
- Compare:
- Emits classifications:
added,removed,changed,unchanged,ignored_volatile,redacted, andunsupported_field. - Uses derived non-persisted importance labels:
critical,important,informational. - Marks state changes critical; target/grant/session/condition changes important; volatile, unsupported, and redacted diagnostics informational.
- Emits classifications:
- Render:
- Shows Conditional Access display name, state, user/group/role/application targets, client/platform/location/risk conditions, grant controls, session controls, claim state, identity state, capture time, material compare status/field labels, unsupported fields, and redacted field names.
- Does not render raw payload, raw Graph response, source endpoint, provider body, before/after compare values, tokens, credential values, private keys, authorization headers, cookies, or unneeded PII.
Claim Guard, Redaction, And Safety Proof
- Claim Guard now permits only scoped internal operator wording for selected Entra comparable/renderable support.
- Claim Guard blocks certified, restore-ready, customer-ready, all-resource, full, and 100 percent Entra/M365 claims.
- Redaction tests prove render and compare output exclude secret values from credential-like keys, authorization headers, cookies, OperationRun diagnostic context, and audit metadata.
Spec421EntraNoRestoreNoCertificationTestproves Conditional Access remains not restorable, not certified, and internal-only by registry default.Spec421EntraNoTenantIdTestproves the changed runtime files do not introducetenant_id.Spec421EntraNoMiniPlatformTestproves this implementation did not add Spec 421 Entra-specific migrations, models, routes, or Filament resources.
Product Surface Close-Out
- No-legacy posture: canonical Coverage v2 extension; no compatibility exception.
- UI Surface Impact: existing Coverage v2 technical annex / internal operator inspect surface changed.
- Product Surface Impact: existing rendered inspect slide-over now shows safe Conditional Access typed summary plus bounded material compare status.
- Page archetype: Technical Annex / internal operator evidence inspection surface.
- Surface budget: pass. No new page, route, navigation, action family, customer surface, report, export, or download was added.
- Technical Annex/deep-link demotion: raw payload, source endpoint, source keys, provider IDs, OperationRun context, and evidence internals remain secondary/diagnostic; raw payload values are not default-visible.
- Canonical status vocabulary: existing Coverage v2 labels only; no
Entra covered, certified, restore-ready, customer-ready, full coverage, or 100 percent labels. - Product Surface exceptions: none.
- Human Product Sanity: pass. The inspect modal answers what the selected Conditional Access policy is, whether it is enabled, who/apps it targets, what controls apply, whether material changes exist versus prior comparable evidence, and which diagnostics are unsupported/redacted without implying certification, restore, or customer proof.
- Visible complexity outcome: decreased for selected Conditional Access evidence because operators no longer need to infer meaning from raw payloads.
Browser Proof
- Browser proof required: yes, rendered Coverage v2 output changed.
- Focused path: existing Coverage v2 readiness route for a seeded workspace and managed environment with prior comparable Conditional Access evidence and latest content-backed renderable evidence.
- Test:
apps/platform/tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php. - Result: passed.
- Verified:
- page loads in
/adminworkspace/managed-environment context - Conditional Access row is visible with
RenderableandInternal only - inspect slide-over opens from the existing primary link column
- typed summary shows display name, state, users, applications, grant controls, compare summary, material change field label, redacted fields
- no raw secrets, certified/restore-ready/customer-ready/full/100 percent Entra claims, high-impact actions, console errors, JavaScript errors, or Graph/TCM/provider network calls during render
- page loads in
Filament v5 Output Contract
- Livewire v4.0+ compliance: unchanged; the existing Filament v5/Livewire v4 surface is exercised by the focused browser test.
- Provider registration location: no panel/provider registration changed. Laravel 12 providers remain under
apps/platform/bootstrap/providers.php. - Global search: no Filament Resource global-search behavior changed; no new Resource was added.
- Destructive/high-impact actions: none added or changed. No restore/apply/capture/export/certify action was introduced.
- Asset strategy: no assets registered and no frontend bundles changed.
php artisan filament:assetsis not newly required beyond existing deployment practice. - Testing plan: unit, feature, related regression, and browser lanes were run.
Validation Commands
cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/EntraComparablePayloadNormalizer.php- passed.cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/EntraCoverageComparator.php- passed.cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/EntraRenderableSummaryBuilder.php- passed.cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/CoverageEvidenceWriter.php- passed.cd apps/platform && ./vendor/bin/sail php -l app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.php- passed.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 tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.php tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.php tests/Feature/TenantConfiguration/Spec421EntraNoRestoreNoCertificationTest.php tests/Feature/TenantConfiguration/Spec421EntraNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec421EntraNoMiniPlatformTest.php- passed, 24 tests / 98 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php- passed, 1 test / 52 assertions.cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent- passed.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 tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.php tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.php tests/Feature/TenantConfiguration/Spec421EntraNoRestoreNoCertificationTest.php tests/Feature/TenantConfiguration/Spec421EntraNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec421EntraNoMiniPlatformTest.php tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php- passed, 25 tests / 150 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec415CoverageRedactionTest.php tests/Unit/Support/TenantConfiguration/Spec415GenericPayloadNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php tests/Unit/Support/TenantConfiguration/Spec420M365GenericPayloadNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureClaimGuardTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureRedactionTest.php tests/Feature/TenantConfiguration/Spec415GenericContentBackedCaptureTest.php tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php tests/Feature/TenantConfiguration/Spec420M365NoOverclaimTest.php tests/Browser/Spec420M365GenericEvidenceOperatorSurfaceSmokeTest.php- passed, 23 tests / 248 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php tests/Feature/Filament/CoverageV2ReadinessPageTest.php- passed, 12 tests / 189 assertions.git diff --check- passed.- Post-browser-comment validation: focused integrated-browser check at narrow viewport confirmed the
Readybadge rendered as full text within the Activation readiness section;cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.phppassed, 1 test / 53 assertions. - Post-resource-type-redundancy validation: the Resource instances table now omits the redundant canonical type line from the default
Resource typecell while keeping canonical type available in inspect details; the focused browser smoke asserts this table-cell behavior.
Deployment Impact
- Migrations: none.
- Environment variables: none.
- Queue/cron: no new queue or scheduled work; existing capture path remains unchanged.
- Storage/volumes: none.
- Assets: none.
- Dokploy/staging: deploy as ordinary app code/test/view change. Staging validation should include the focused Coverage v2 inspect path before production promotion.
- Rollback: revert code/view/test changes. No data migration or compatibility step required.
Deferred Work And Residual Risk
- Deferred by spec: Security Defaults content-backed capture/source contract, application/service principal comparable/renderable pack, role definition and administrative unit comparable/renderable pack, certified compare, restore/apply, customer reports, Review Pack output, exports/downloads, and broad M365/Entra claims.
- Residual risk: this proves deterministic typed semantics for captured Conditional Access payloads in the existing internal Coverage v2 path; it does not certify real Microsoft tenant-wide Entra coverage.
- Remaining in-scope findings: none after the focused test/fix loop.