TenantAtlas/specs/421-entra-core-comparable-renderable-pack/implementation-report.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

164 lines
17 KiB
Markdown

# 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_id` ownership 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`; `CoveragePayloadRedactor` was 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 from `content_backed` to `renderable`. 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 redundant `Resource type` cell 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.php`
- `apps/platform/app/Services/TenantConfiguration/CoverageEvidenceWriter.php`
- `apps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.php`
- `apps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.php`
- `apps/platform/app/Services/TenantConfiguration/EntraComparablePayloadNormalizer.php`
- `apps/platform/app/Services/TenantConfiguration/EntraCoverageComparator.php`
- `apps/platform/app/Services/TenantConfiguration/EntraRenderableSummaryBuilder.php`
- `apps/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.php`
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraComparableDiffTest.php`
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraRenderableSummaryTest.php`
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraRedactionTest.php`
- `apps/platform/tests/Unit/Support/TenantConfiguration/Spec421EntraClaimGuardTest.php`
- `apps/platform/tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.php`
- `apps/platform/tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.php`
- `apps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoRestoreNoCertificationTest.php`
- `apps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoTenantIdTest.php`
- `apps/platform/tests/Feature/TenantConfiguration/Spec421EntraNoMiniPlatformTest.php`
- `apps/platform/tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php`
- Spec artifacts:
- `specs/421-entra-core-comparable-renderable-pack/tasks.md`
- `specs/421-entra-core-comparable-renderable-pack/implementation-report.md`
## Implementation Summary
- Added bounded Entra typed helpers under the existing Tenant Configuration service boundary:
- `EntraComparablePayloadNormalizer`
- `EntraCoverageComparator`
- `EntraRenderableSummaryBuilder`
- `conditionalAccessPolicy` is the only promoted type. It now receives deterministic typed normalization, compare output, operator-safe render summaries, and evidence-gated `CoverageLevel::Renderable` promotion when captured as content-backed evidence.
- `securityDefaults`, `application`, `servicePrincipal`, `roleDefinition`, and `administrativeUnit` remain unpromoted/deferred because current repo truth does not prove content-backed evidence for them without new capture/source-contract scope.
- Existing `CoveragePayloadRedactor` now also catches camelCase and separator-free sensitive key forms such as `privateKey`.
- `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`, and `unsupported_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.
- 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.
- `Spec421EntraNoRestoreNoCertificationTest` proves Conditional Access remains not restorable, not certified, and internal-only by registry default.
- `Spec421EntraNoTenantIdTest` proves the changed runtime files do not introduce `tenant_id`.
- `Spec421EntraNoMiniPlatformTest` proves 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 `/admin` workspace/managed-environment context
- Conditional Access row is visible with `Renderable` and `Internal 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
## 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:assets` is 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 `Ready` badge rendered as full text within the Activation readiness section; `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php` passed, 1 test / 53 assertions.
- Post-resource-type-redundancy validation: the Resource instances table now omits the redundant canonical type line from the default `Resource type` cell 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.