Automated PR for spec 426 exchange teams core evidence identity readiness. Includes service changes and coverage/requirement/spec updates from commit fb4dc20c.
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #493
132 lines
10 KiB
Markdown
132 lines
10 KiB
Markdown
# Implementation Report: Spec 426 - Exchange / Teams Core Evidence & Stable Identity Readiness
|
|
|
|
**Branch**: `426-exchange-teams-core-evidence-identity-readiness`
|
|
**HEAD**: `33e496c1 feat: complete spec 425 enta certified compare pack (#492)`
|
|
**Implementation date**: 2026-07-02
|
|
**Result**: PASS WITH CONDITIONS for Spec 426 closure; FAIL-safe for source-backed evidence readiness
|
|
|
|
## Gate Result
|
|
|
|
- Activated skills/gates: `pest-testing`, Spec Readiness Gate, provider-freshness semantics, and TCM cutover guard for the post-review fix. Earlier implementation work also used workspace/RBAC/OperationRun/evidence/customer-output/Product Surface gates.
|
|
- Closure gate: `PASS WITH CONDITIONS`.
|
|
- Condition: Spec 426 proves fail-safe behavior for Exchange/Teams source-backed evidence. It does not prove readiness, capture support, compare support, render support, or certification. Typed normalizer/hash tests are future-contract helper proof only.
|
|
- Source-backed evidence readiness gate: FAIL-safe/blocked because no verified production-safe source contract exists for the four mandatory types.
|
|
- Completed dependency specs 414, 415, 417, 418, 419, 420, 422, and 425 remain read-only context. No completed spec artifacts were rewritten.
|
|
- Review correction: removed unverified Graph v1.0 endpoint claims for `mailFlowRule`, `acceptedDomains`, `teamsAppPermissionPolicy`, and `teamsMeetingPolicy`.
|
|
- Final dirty state: runtime service/config/test changes plus active Spec 426 artifacts, as expected for this active spec.
|
|
|
|
## Files Changed
|
|
|
|
- Source contracts and capture:
|
|
- `apps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.php`
|
|
- `apps/platform/app/Services/TenantConfiguration/GenericContentEvidenceCaptureService.php`
|
|
- `apps/platform/config/graph_contracts.php` was verified to contain no unverified final Spec 426 contract entries; it has no final diff in this correction.
|
|
- Stable identity:
|
|
- `apps/platform/app/Services/TenantConfiguration/CoverageIdentityStrategyRegistry.php`
|
|
- Tests:
|
|
- Focused Spec 426 unit and feature tests under `apps/platform/tests/Unit/Support/TenantConfiguration/` and `apps/platform/tests/Feature/TenantConfiguration/`
|
|
- Updated Spec 417/420 expectations so the four Exchange/Teams types remain fail-closed until verified contracts exist
|
|
- Spec artifacts:
|
|
- `spec.md`, `plan.md`, `tasks.md`, this implementation report
|
|
|
|
## Source Contract Matrix
|
|
|
|
| Type | Contract key | Endpoint | Source class | Outcome |
|
|
|---|---|---|---|---|
|
|
| `transportRule` | none | none | none | `capture_blocked_missing_contract` |
|
|
| `acceptedDomain` | none | none | none | `capture_blocked_missing_contract` |
|
|
| `appPermissionPolicy` | none | none | none | `capture_blocked_missing_contract` |
|
|
| `meetingPolicy` | none | none | none | `capture_blocked_missing_contract` |
|
|
|
|
No endpoint guessing, direct HTTP, runtime documentation lookup, provider bypass, or guessed Microsoft Graph source contract remains. Capture attempts stop before `ProviderGateway` / `GraphClientInterface` calls for these four types.
|
|
|
|
## Evidence Matrix
|
|
|
|
| Type | Capture outcome | Provider call | Resource row | Evidence row | Empty/fake behavior |
|
|
|---|---|---:|---:|---:|---|
|
|
| `transportRule` | `capture_blocked_missing_contract` | no | no | no | no fake resource/evidence |
|
|
| `acceptedDomain` | `capture_blocked_missing_contract` | no | no | no | no fake resource/evidence |
|
|
| `appPermissionPolicy` | `capture_blocked_missing_contract` | no | no | no | no fake resource/evidence |
|
|
| `meetingPolicy` | `capture_blocked_missing_contract` | no | no | no | no fake resource/evidence |
|
|
|
|
OperationRun summaries remain flat numeric counts. Blocked runs record sanitized blocked outcomes only; no raw payload, provider response body, secret, mail content, Teams content, or raw permission context is placed in run context or audit metadata.
|
|
|
|
## Identity Matrix
|
|
|
|
| Type | Strategy | Stable identity inputs | Explicitly rejected |
|
|
|---|---|---|---|
|
|
| `transportRule` | `tcm.exchange.transport_rule.v1` | `id`, `sourceId`, `Guid`, `RuleId` | `Identity`, display/name fields, order, payload hash |
|
|
| `acceptedDomain` | `tcm.exchange.accepted_domain.v1` | `id`, `sourceId`, `DomainName`, `domainName` | `Identity`, display/name fields, domain type/default flag |
|
|
| `appPermissionPolicy` | `tcm.teams.app_permission_policy.v1` | `id`, `sourceId`, `policyId` | `Identity`, display/name fields, settings/app hash |
|
|
| `meetingPolicy` | `tcm.teams.meeting_policy.v1` | `id`, `sourceId`, `policyId` | `Identity`, display/name fields, settings hash |
|
|
|
|
`CanonicalIdentityResolver` remains the only identity path. `Identity`-only payloads resolve to `missing_external_id`, not stable identity.
|
|
|
|
## Readiness Matrix
|
|
|
|
| Type | `content_backed` | `identity_strategy_hardened` | `compare_render_ready` | `certified` | `restore_ready` | `customer_claimable` |
|
|
|---|---:|---:|---:|---:|---:|---:|
|
|
| `transportRule` | no | yes | no | no | no | no |
|
|
| `acceptedDomain` | no | yes | no | no | no | no |
|
|
| `appPermissionPolicy` | no | yes | no | no | no | no |
|
|
| `meetingPolicy` | no | yes | no | no | no | no |
|
|
|
|
Typed normalizer/hash/redaction tests remain as helper proof for future valid source payloads. They are not used to claim source-backed evidence or certification readiness. Post-review coverage now also proves that typed helper output keeps stable source identity fields (`Guid`, `RuleId`, `DomainName`, `policyId`, `sourceId`), that the future typed capture handoff preserves that type-specific `source_identity`, that contract-level volatile fields are excluded from typed unsupported diagnostics/material hashes, and that payload hashes ignore volatile-field diagnostics.
|
|
|
|
## Claim Guard And Redaction
|
|
|
|
- Certified, restore-ready, full Exchange/Teams/Microsoft 365, and customer-ready claims remain blocked.
|
|
- Internal compare/render wording remains bounded by Claim Guard, but this report does not claim source-backed compare/render readiness for the four mandatory types.
|
|
- Redaction tests cover provider secrets, tokens, raw provider markers, mail subject/body-like fields, and Teams recording/transcript-like fields in normalized/helper output.
|
|
|
|
## Product Surface / Filament Contract
|
|
|
|
- No runtime UI files, routes, navigation, Filament resources/pages/widgets, actions, reports, exports, or customer outputs were changed.
|
|
- Product Surface decision: `N/A - no rendered UI surface changed`.
|
|
- Product Surface exceptions: none.
|
|
- Browser proof: `N/A - no rendered UI surface changed`.
|
|
- Human Product Sanity: `N/A - no rendered UI surface changed`.
|
|
- Livewire v4 compliance: unchanged; Filament v5 remains on Livewire v4.
|
|
- Provider registration: unchanged; Laravel provider registration remains in `apps/platform/bootstrap/providers.php`.
|
|
- Global search: unchanged; no resource/global search behavior was added.
|
|
- Destructive/high-impact actions: none added.
|
|
- Asset strategy: no new assets; no new `filament:assets` deployment requirement.
|
|
|
|
## Deployment Impact
|
|
|
|
- Migrations: none.
|
|
- Environment variables: none.
|
|
- Queues/cron: no new workers or schedules; existing OperationRun-backed capture job reused.
|
|
- Storage/volumes: none.
|
|
- Assets: none.
|
|
- Runtime config: no new Exchange/Teams graph contract entries remain; deploy through the normal container/config-cache path.
|
|
- Staging/Production: do not promote Exchange/Teams certification from this branch. Next sequence is Spec 427 verified source contract enablement, Spec 428 content-backed evidence promotion, Spec 429 compare/render promotion, and only later certification. A future verified provider contract must pass staging before evidence promotion or certification proceeds.
|
|
|
|
## Validation
|
|
|
|
Passed after post-review fix and closure review:
|
|
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec426`
|
|
- terminated with Signal 9 in the container runner.
|
|
- Not a closure blocker because the equivalent direct file runs below passed.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsSourceContractResolverTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsCanonicalIdentityTest.php`
|
|
- 22 passed, 124 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsPayloadNormalizationFromSourceTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsEvidenceHashTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsClaimGuardReadinessTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsRedactionTest.php`
|
|
- 24 passed, 77 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsCoreEvidenceReadinessTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsStableIdentityReadinessTest.php`
|
|
- 3 passed, 69 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsProviderScopeTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoCertificationTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoRestoreTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoMiniPlatformTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsClaimGuardFeatureTest.php`
|
|
- 7 passed, 55 assertions.
|
|
- Direct file Spec 426 total:
|
|
- 56 passed, 325 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php tests/Feature/TenantConfiguration/Spec420M365CaptureOperationRunTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureSourceContractResolverTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureEligibilityTest.php tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php`
|
|
- 16 passed, 259 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec420M365GenericEvidenceOperatorSurfaceSmokeTest.php`
|
|
- 1 passed, 44 assertions.
|
|
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
|
|
- passed.
|
|
- `git diff --check`
|
|
- passed.
|
|
|
|
Spec 426 browser validation remains `N/A - no rendered UI surface changed`; the Spec 420 browser regression fixture changed and passed.
|