TenantAtlas/specs/420-m365-generic-evidence-coverage-pack/tasks.md
ahmido a73a8f5882 feat: complete m365 generic evidence coverage pack (#487)
Committing and publishing the current Spec 420 package changes.

Includes updated services, coverage tests, browser smoke coverage, and the spec/plan/tasks artifacts for the package.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #487
2026-06-27 12:24:00 +00:00

108 lines
13 KiB
Markdown

# Tasks: Spec 420 - M365 Generic Evidence Coverage Pack
**Input**: `specs/420-m365-generic-evidence-coverage-pack/spec.md`, `specs/420-m365-generic-evidence-coverage-pack/plan.md`, `specs/420-m365-generic-evidence-coverage-pack/checklists/requirements.md`
**Prerequisites**: Specs 414, 415, 417, 418, and 419 as read-only dependency context
**Tests**: Required. Runtime capture/evidence behavior must be covered with focused Pest unit and feature tests. Browser proof is required only if new M365 captured/blocked data renders on the existing Spec 418 Coverage v2 operator surface.
## Test Governance Checklist
- [x] Lane assignment is named and remains the narrowest sufficient proof for resolver, capture, evidence, identity, RBAC, OperationRun, and no-overclaim behavior.
- [x] Unit and Feature tests stay focused; PostgreSQL lane is explicit only if schema/check constraints change.
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default and opt-in.
- [x] Planned validation commands cover the change without pulling unrelated lane cost.
- [x] Browser proof is required for rendered existing-surface data impact, or explicitly `N/A - no rendered UI surface changed` with proof.
- [x] Human Product Sanity and Product Surface implementation-report close-out cover existing-surface data impact, or are N/A only with proof.
- [x] Material budget, baseline, trend, or escalation notes are recorded if test cost changes.
## Phase 1: Preflight And Dependency Guard
- [x] T001 Capture branch, HEAD, `git status --short`, activated skills, and hard-gate status in `specs/420-m365-generic-evidence-coverage-pack/implementation-report.md`.
- [x] T002 Confirm Specs 414, 415, 417, 418, and 419 are dependency context only and must not be modified.
- [x] T003 Inspect `apps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.php`, `GenericContentEvidenceCaptureService.php`, `CoverageResourceUpserter.php`, `CoverageEvidenceWriter.php`, `CoverageIdentityStrategyRegistry.php`, `ClaimGuard.php`, `StartTenantConfigurationCapture.php`, and `CaptureTenantConfigurationEvidenceJob.php`.
- [x] T004 Inspect `apps/platform/config/graph_contracts.php` for the current `conditionalAccessPolicy` contract and verify no explicit contracts exist for selected missing-contract types. If explicit contracts already exist for `acceptedDomain`, `appPermissionPolicy`, or `dlpCompliancePolicy`, stop and amend the package before implementation continues.
- [x] T005 Record draft-to-repo deviations: reuse `tenant_configuration.capture`, use existing `CaptureOutcome` values, and narrow first pack to `conditionalAccessPolicy`, `acceptedDomain`, `appPermissionPolicy`, and `dlpCompliancePolicy`.
- [x] T006 Stop if implementation would require compare, render, restore, certification, customer output, M365 dashboard, UI start action, endpoint guessing, direct HTTP, `tenant_id`, v1 compatibility, or workload-specific mini-platforms.
## Phase 2: Tests First - Source Contracts And Eligibility
- [x] T007 Add `apps/platform/tests/Unit/Support/TenantConfiguration/Spec420M365CaptureSourceContractResolverTest.php` proving `conditionalAccessPolicy` resolves only through an explicit repo-real source contract mapping.
- [x] T008 Add resolver tests proving `acceptedDomain`, `appPermissionPolicy`, and `dlpCompliancePolicy` return `capture_blocked_missing_contract` until explicit contracts exist.
- [x] T009 Add eligibility tests proving missing-contract decisions do not call provider gateway, do not guess endpoints from canonical type/source aliases, and keep stable reason codes.
- [x] T010 Add tests proving beta/unsupported states remain blocked through existing `CaptureOutcome` values and do not require a new outcome family.
- [x] T011 Add tests proving source metadata separates registry/source-class truth from actual source contract key, endpoint, source version, schema hash, and explicit null/unknown values when source version/schema hash is unavailable.
## Phase 3: Tests First - Identity, Normalization, Redaction, And Claims
- [x] T012 Add `apps/platform/tests/Unit/Support/TenantConfiguration/Spec420M365CaptureIdentityStrategyTest.php` covering selected resource identity strategies and no display-name-only stable identity.
- [x] T013 Add identity tests proving missing, unsupported, derived-without-claim, and conflict states block customer-facing claims.
- [x] T014 Add `Spec420M365GenericPayloadNormalizerTest.php` proving stable key ordering, volatile field stripping, and deterministic payload hash for a fake `conditionalAccessPolicy` payload.
- [x] T015 Add redaction coverage proving secret keys are redacted from normalized evidence payloads, permission context, OperationRun context/failure summary, audit metadata, and logs, with raw payload retained only inside the evidence raw-payload storage boundary.
- [x] T016 Add `Spec420M365CaptureClaimGuardTest.php` proving broad M365, certified, restore-ready, customer-ready, complete tenant, all-resource, and unscoped 100% claims are blocked.
## Phase 4: Tests First - Persistence, OperationRun, Authorization, And Scope
- [x] T017 Add `apps/platform/tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php` proving fake `conditionalAccessPolicy` capture persists a `TenantConfigurationResource` and append-only `TenantConfigurationResourceEvidence` row.
- [x] T018 Assert persisted evidence includes raw payload, normalized payload, deterministic `payload_hash`, source metadata, redacted permission context, `operation_run_id`, and `coverage_level = content_backed` only when a real payload was captured.
- [x] T019 Assert missing-contract selected types create no fake evidence rows and update only structured outcome/summary data.
- [x] T020 Add `Spec420M365CaptureOperationRunTest.php` proving existing `tenant_configuration.capture` lifecycle, service-owned transitions, numeric summary counts, retry/idempotency behavior, stale active-run or duplicate-run handling, bounded duplicate resource/evidence behavior, sanitized failure-summary behavior, and no raw payload in OperationRun context.
- [x] T021 Add `Spec420M365CaptureAuthorizationTest.php` covering non-member 404, missing environment entitlement 404 via existing capture authorization coverage, missing capability 403, operator/readonly denial, and allowed owner/manager behavior according to the current capability matrix.
- [x] T022 Add `Spec420M365ProviderConnectionScopeTest.php` proving cross-workspace and cross-environment provider connections are rejected before run creation and again at job execution time.
- [x] T023 Add `Spec420M365NoOverclaimTest.php`, `Spec420M365NoLegacyTest.php`, and `Spec420M365NoTenantIdTest.php` proving no customer claim activation, no old gap taxonomy/v1 adapter/fallback reader/dual write, and no `tenant_id`.
## Phase 5: Source Contract And Eligibility Implementation
- [x] T024 Update `CoverageSourceContractResolver` or its existing mapping path with the narrow selected M365 decisions required by tests.
- [x] T025 Map `conditionalAccessPolicy` to the repo-valid Graph contract only after verifying the contract exists and is safe for generic read capture; if it is missing or unsafe, stop and amend the package.
- [x] T026 Keep `acceptedDomain`, `appPermissionPolicy`, and `dlpCompliancePolicy` blocked with `capture_blocked_missing_contract` for Spec 420; do not add explicit contracts for those three types in this slice.
- [x] T027 Ensure no runtime endpoint path is derived from resource type strings or Spec 419 `source_aliases` metadata.
- [x] T028 Ensure source metadata is sufficient for implementation-report source-contract matrix, including explicit null/unknown source version/schema hash semantics, without leaking raw provider payloads or secrets.
## Phase 6: Identity, Evidence, And Claim Implementation
- [x] T029 Extend `CoverageIdentityStrategyRegistry` narrowly for selected M365 resource types.
- [x] T030 Ensure `CanonicalIdentityResolver` remains the only identity resolution path used by `CoverageResourceUpserter`.
- [x] T031 Ensure `CoverageResourceUpserter` and `CoverageEvidenceWriter` preserve selected M365 identity and claim state, same-scope provider connection, source metadata, and append-only evidence behavior.
- [x] T032 Ensure `GenericPayloadNormalizer` and `CoveragePayloadRedactor` cover selected fake M365 payload shapes and secret keys.
- [x] T033 Update `ClaimGuard` only if tests show existing M365 claim blocking is insufficient; do not create a parallel M365 claim guard.
## Phase 7: OperationRun, RBAC, Audit, And Guardrails
- [x] T034 Reuse `StartTenantConfigurationCapture`, `CaptureTenantConfigurationEvidenceJob`, and `OperationRunService`; do not add `tenant_configuration.m365_capture` unless proportionality review is amended.
- [x] T035 Ensure start path writes existing audit events with safe metadata and no raw payload or secrets.
- [x] T036 Ensure job/service path revalidates workspace, managed environment, provider connection, OperationRun type, and OperationRun target scope before provider work.
- [x] T037 Add or update static/focused guards proving no direct OperationRun status/outcome writes, no direct Graph/HTTP calls, no runtime docs fetch, and no workload-specific tables/classes/services.
- [x] T038 Confirm no Filament page/resource/widget/action, route, navigation entry, Blade view, Livewire component, customer output, report, download, restore/certify/export/publish action, scheduler, or new dashboard was added.
## Phase 8: Product Surface Data-Impact Verification
- [x] T039 If existing Spec 418 Coverage v2 surface renders captured/blocked M365 data, add and run `apps/platform/tests/Browser/Spec420M365GenericEvidenceOperatorSurfaceSmokeTest.php`.
- [x] T040 Browser proof must verify no broad M365 claim, no certified/restore-ready/customer-ready wording, no raw/normalized payload default display, no new capture/restore/certify/export/download action, no console/Livewire/500 errors, and no provider calls during render.
- [x] T041 Make the rendered-surface close-out decision explicit: if existing output changes, run browser proof and Human Product Sanity; if implementation proves no rendered output changes, document `N/A - no rendered UI surface changed` with exact proof in the implementation report.
- [x] T042 Record Human Product Sanity result if rendered output changes.
- [x] T043 Stop and amend `spec.md`, `plan.md`, and `tasks.md` before any runtime UI file, route, navigation, action, label, report, download, or customer surface edit.
## Phase 9: Validation And Close-Out
- [x] T044 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`.
- [x] T045 Run focused unit tests for Spec 420 source contracts, eligibility, normalizer, identity strategy, Claim Guard, and redaction.
- [x] T046 Run focused feature tests for Spec 420 evidence capture, OperationRun, authorization, provider scope, no-overclaim, no-legacy, and no-tenant-id.
- [x] T047 N/A - no migrations/check constraints/indexes changed, so no additional PostgreSQL lane was required.
- [x] T048 Run focused browser proof if existing rendered output changes.
- [x] T049 Run `git diff --check`.
- [x] T050 Complete `specs/420-m365-generic-evidence-coverage-pack/implementation-report.md` with candidate gate result, dirty state before/after, files changed, capture eligibility matrix, source-contract matrix, evidence matrix, OperationRun proof, authorization proof, provider scope proof, redaction/log proof, Claim Guard proof, no-tenant-id proof, no-legacy/no-mini-platform proof, Product Surface proof, tests run, deployment impact, and deferred work.
- [x] T051 Confirm no historical spec was rewritten or stripped of task, smoke, browser, or review history.
## Stop Conditions
Stop and update `spec.md`, `plan.md`, and `tasks.md` before continuing if any of these appear:
- Compare, render, restore, apply, certification, customer output, Review Pack/report, broad M365 dashboard, customer-facing claim activation, or new UI start action is needed.
- Graph/TCM/provider remote paths are guessed, hardcoded, scraped, or called outside `GraphClientInterface`/provider gateway contracts.
- Existing `tenant_configuration.capture` cannot support the lifecycle and a new OperationRun type is proposed without proportionality review.
- A new capture outcome, enum/status family, table, abstraction, or taxonomy is needed without proportionality review.
- Existing Coverage v2 operator surface would change beyond data-driven rows/outcomes without Product Surface/browser proof.
- Raw payload, normalized payload, permission context, provider response bodies, tokens, secrets, or internal diagnostics would render by default or enter logs/audit/OperationRun context/failure summary.
- `tenant_id` appears as Coverage v2 ownership truth.
- A workload-specific table, model, engine, namespace, dashboard, or mini-platform is introduced.
- A broad M365/certified/restore-ready/customer-ready/all-resource claim must be allowed.