TenantAtlas/specs/436-exchange-content-backed-evidence-promotion-slice-1/plan.md
Ahmed Darrazi 053a33c172
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 7m12s
feat: promote Exchange content-backed evidence
2026-07-09 15:55:44 +02:00

15 KiB

Implementation Plan: Exchange Content-Backed Evidence Promotion Slice 1

Branch: feat/436-exchange-content-backed-evidence-promotion-slice-1 | Date: 2026-07-08 | Spec: spec.md Input: Feature specification from specs/436-exchange-content-backed-evidence-promotion-slice-1/spec.md

Summary

Promote exactly transportRule, remoteDomain, and inboundConnector to append-only internal content-backed Coverage v2 evidence through the Exchange PowerShell capture adapter. The implementation must replace the current generic/comparable normalizer write path with Spec 435 structured envelopes, target-specific normalizers, and hash builder; preserve Spec 434 identity/content-only guards and empty-collection policy; consume Spec 433 readiness, Spec 432 runner boundary, and Spec 430 command contracts; and add no UI, migration, trigger, compare/render, certification, restore, or customer claim.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12, Filament 5, Livewire 4 Primary Dependencies: Existing Laravel services, Coverage v2 models, Pest 4, Exchange PowerShell support classes Storage: PostgreSQL through existing tenant_configuration_resources and tenant_configuration_resource_evidence; no migration planned Testing: Pest 4 Unit and Feature tests Validation Lanes: fast-feedback/confidence; PostgreSQL lane only if implementation unexpectedly touches migration/schema behavior and the spec is amended Target Platform: Laravel platform app under apps/platform Project Type: web monolith backend-only slice Performance Goals: deterministic per-item normalization/hash without external calls during tests; no UI render path or browser cost Constraints: no raw stdout/stderr evidence, no raw payload outside evidence storage, no generic/comparable normalizer promotion path, no evidence on unsafe identity or failed gates Scale/Scope: exactly three Exchange resource types and fake-runner test coverage

UI / Surface Guardrail Plan

  • Guardrail scope: no operator-facing surface change.
  • Affected routes/pages/actions/states/navigation/panel/provider surfaces: N/A.
  • No-impact class, if applicable: backend-only.
  • Native vs custom classification summary: N/A.
  • Shared-family relevance: backend evidence/OperationRun only; no rendered shared interaction family.
  • State layers in scope: backend capture/evidence only.
  • Audience modes in scope: N/A.
  • Decision/diagnostic/raw hierarchy plan: raw provider payload remains evidence-storage-only; diagnostics stay internal; no product layer.
  • Raw/support gating plan: raw payload stored only in evidence storage; no UI support/raw surface.
  • One-primary-action / duplicate-truth control: N/A.
  • Handling modes by drift class or surface: hard-stop-candidate for any UI, route, trigger, report, Review Pack, PDF, or customer output.
  • Repository-signal treatment: review-mandatory for any guarded path change; hard-stop for UI/migration/trigger scope.
  • Special surface test profiles: N/A.
  • Required tests or manual smoke: browser N/A - no rendered UI surface changed.
  • Exception path and spread control: none.
  • Active feature PR close-out entry: N/A - no rendered UI surface changed.
  • UI/Productization coverage decision: No UI surface impact.
  • Coverage artifacts to update: none.
  • No-impact rationale: backend-only evidence promotion through existing tables and services.
  • Navigation / Filament provider-panel handling: checked no-impact; no provider registration/global search/asset changes.
  • Screenshot or page-report need: no.

Product Surface Contract Plan

  • Product Surface Contract reference: docs/product/standards/product-surface-contract.md.
  • No-legacy posture: canonical replacement; no compatibility exception.
  • Page archetype and surface budget plan: N/A.
  • Technical Annex and deep-link demotion plan: OperationRun details, raw evidence payloads, IDs, source keys, payloads, normalized payloads, and hashes stay internal and are not rendered.
  • Canonical status vocabulary plan: N/A for UI.
  • Product Surface exceptions: none.
  • Browser verification plan: N/A - no rendered UI surface changed.
  • Human Product Sanity plan: N/A.
  • Visible complexity outcome target: neutral.
  • Implementation report target: specs/436-exchange-content-backed-evidence-promotion-slice-1/implementation-report.md.

Filament / Livewire / Deployment Posture

  • Livewire v4 compliance: unchanged; no Livewire runtime code planned.
  • Panel provider registration location: no panel change; Laravel provider registration remains apps/platform/bootstrap/providers.php.
  • Global search posture: no Resource/global search change.
  • Destructive/high-impact action posture: none; no UI action or start surface added.
  • Asset strategy: no assets; filament:assets is not newly required.
  • Testing plan: Unit/Feature for adapter wiring, target normalizers, hash determinism, identity blocking, append-only evidence, OperationRun safety, redaction, no-promotion, no-surface, and regressions.
  • Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, or Dokploy runtime changes planned.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes, backend evidence/capture only.
  • Systems touched: Exchange PowerShell adapter/eligibility/identity/content-only guard, structured output envelope, target normalizers, hash builder, Coverage v2 writer/upserter, OperationRun safe context, provider readiness.
  • Shared abstractions reused: tenant_configuration.capture, OperationSummaryKeys, ExchangePowerShellStructuredOutputEnvelope, ExchangePowerShellEvidenceNormalizer, ExchangePowerShellHashInputBuilder, CanonicalIdentityResolver, CoverageResourceUpserter, CoverageEvidenceWriter.
  • New abstraction introduced? why?: none planned. Use existing Spec 434/435 classes. If a helper is needed, keep it private/narrow and document in the report.
  • Why the existing abstraction was sufficient or insufficient: Coverage v2 storage and Spec 434/435 services are sufficient. The current adapter normalizer path is insufficient because it still uses GenericPayloadNormalizer and ExchangeTeamsComparablePayloadNormalizer.
  • Bounded deviation / spread control: Exchange-specific normalization stays provider-owned and does not alter platform-core evidence table semantics.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: no rendered UX; internal OperationRun ownership/context only.
  • Central contract reused: existing tenant_configuration.capture lifecycle conventions.
  • Delegated UX behaviors: N/A.
  • Surface-owned behavior kept local: none.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: unchanged.
  • Exception path: none; adding a new operation/start UX requires spec amendment.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes.
  • Provider-owned seams: Exchange PowerShell command contracts, source surface, structured item shape, target-specific normalizers, protected field handling.
  • Platform-core seams: Coverage v2 evidence/resource storage, OperationRun truth, workspace/managed-environment/provider scope, identity hard-stop, redaction/no-customer-output, no-promotion posture.
  • Neutral platform terms / contracts preserved: provider connection, managed environment, evidence, capture outcome, content-backed, operation run, canonical identity, payload hash.
  • Retained provider-specific semantics and why: transportRule, remoteDomain, inboundConnector, and Exchange PowerShell contract names are required for this bounded first Exchange slice.
  • Bounded extraction or follow-up path: Spec 437 can promote comparable/renderable only after Spec 436 passes.

Constitution Check

Principle Plan Result Notes
Inventory-first / evidence truth PASS Writes existing Coverage v2 evidence as internal source-backed proof; no customer/product truth.
Read/write separation PASS Backend evidence append only through trusted flow; no destructive or restore/apply action.
Graph contract path PASS Exchange PowerShell path must not route through Graph gateway or fake Graph endpoints.
Deterministic capabilities PASS Spec 433 readiness and provider capability stay gate truth.
RBAC / workspace isolation PASS Existing scope fields and provider connection scope required; no route/action change.
OperationRun truth PASS tenant_configuration.capture is evidence owner; invocation operation remains runner truth.
Summary counts PASS Use allowed keys or amend spec before adding keys.
Data minimization PASS Raw structured provider item only in evidence storage; no raw stdout/stderr/transcripts.
Test governance PASS Unit/Feature focused tests; Browser N/A.
Proportionality PASS No new table, OperationRun type, UI framework, or status family planned.
Provider boundary PASS Exchange semantics remain provider-owned.
Product Surface PASS N/A - no rendered UI surface changed.

Test Governance Check

  • Test purpose / classification by changed surface: Unit for normalizer/hash/identity blockers; Feature for DB-backed evidence append, OperationRun safety, append-only/latest-pointer, redaction, no-surface guard.
  • Affected validation lane(s): fast-feedback/confidence. Browser N/A.
  • Fixture/helper/factory/seed/context cost: reuse existing Spec 430-435 fake runner/readiness fixtures; keep provider/workspace setup explicit.
  • Heavy-governance or browser family impact: none.
  • Narrowest reviewer command: focused Spec436 tests plus listed regression filters.
  • Budget/baseline/trend follow-up: none expected.
  • Review outcome target: document-in-feature for any bounded non-blocking conditions; reject-or-split for UI/migration/trigger/target expansion/no-promotion violations.

Technical Approach

  1. Re-check Spec 435 PASS/merge-ready state and current branch/dirty state.
  2. Add failing focused tests for adapter wiring, target-specific normalizer usage, hash determinism, identity blocking, append-only evidence, raw payload location, OperationRun sanitization, no-promotion, no-surface, and no-tenant-id behavior.
  3. Update ExchangePowerShellEvidenceCaptureAdapter so non-empty eligible Exchange captures build a Spec 435 envelope from runner output, evaluate target-specific normalizer readiness, use normalized target payloads and ExchangePowerShellHashInputBuilder hash output, and append evidence with content-only cap.
  4. Remove or bypass GenericPayloadNormalizer and ExchangeTeamsComparablePayloadNormalizer for Exchange evidence promotion; preserve generic Graph capture path.
  5. Keep Spec 434 eligibility, identity, content-only, and empty-collection behavior intact.
  6. Ensure OperationRun context/summary remains sanitized and uses allowed summary keys.
  7. Run focused tests, regressions, Pint, git diff --check, and complete the implementation report.

Domain / Model Implications

  • No new models, migrations, tables, columns, enum/status family, OperationRun type, UI state, or customer output artifact.
  • Existing TenantConfigurationResource latest pointer update remains the source for latest evidence state.
  • Existing TenantConfigurationResourceEvidence stores raw structured provider item, normalized payload, hash, source metadata, operation, scope, and content-backed coverage state.

Data / Migration Plan

No migration. Runtime must use existing Coverage v2 tables. If a schema gap is discovered, implementation must stop and amend spec/plan/tasks before proceeding.

Security / RBAC / Redaction Plan

  • Reuse trusted backend flow and provider/capture authorization.
  • Preserve workspace, managed environment, and provider connection scope checks.
  • Require combined Exchange readiness before evidence append.
  • Keep protected Exchange config out of OperationRun context/logs/summaries/customer output.
  • Store raw structured provider item only in evidence storage.
  • Add sentinel tests for credential, token, stdout/stderr, transcript, normalizer preview, hash preview, and protected connector/config fields.

Implementation Phases

Phase 0 - Preflight

  • Capture branch, HEAD, and git status --short.
  • Confirm Spec 435 PASS/merge-ready and prerequisite proof from Specs 430-435.
  • Confirm no UI/routes/jobs/schedules/listeners/migration/tenant_id scope.

Phase 1 - Adapter Integration Update

  • Wire Exchange adapter to Spec 435 structured envelope.
  • Wire Exchange adapter to Spec 435 target normalizers.
  • Wire Exchange adapter to Spec 435 hash input builder.
  • Remove/avoid generic/Teams comparable normalizer path for Exchange evidence.
  • Preserve Graph/generic capture path.

Phase 2 - Evidence Persistence

  • Use Coverage v2 evidence writer.
  • Persist raw structured provider payload in evidence storage only.
  • Persist normalized target payload.
  • Persist payload hash.
  • Link OperationRun.
  • Preserve append-only behavior.
  • Update latest pointer according to repo pattern.

Phase 3 - Target Evidence Promotion

  • Implement transportRule capture.
  • Implement remoteDomain capture with stable identity only.
  • Implement inboundConnector capture with stable identity/redaction only.
  • Keep blocked states explicit.

Phase 4 - Blocking / Empty / Failure Semantics

  • Block readiness failures.
  • Block unsupported provider capability.
  • Block output failures.
  • Block unsafe identity.
  • Preserve empty collection no-evidence policy.
  • Add exact blocker outcomes and prove persisted evidence capture_outcome values stay within existing repo-allowed values.

Phase 5 - Redaction / No-Promotion

  • Prove OperationRun context sanitized.
  • Prove raw payload only in evidence storage.
  • Prove content-backed-only coverage.
  • Prove no UI/jobs/schedules/listeners/customer output.

Phase 6 - Regression / Report

  • Run focused tests and regressions.
  • Run Pint.
  • Run git diff --check.
  • Complete implementation report.

Rollout Considerations

  • Staging/production deployment impact: none beyond code/test deployment.
  • No env vars, migrations, queues, scheduler, storage, asset build, reverse proxy, or Dokploy change planned.
  • Rollback is reverting the adapter/test changes and the Spec 436 artifacts.

Stop Conditions

Stop and amend/split if implementation needs:

  • UI, routes, Filament, Livewire, assets, global search, provider registration, reports, Review Packs, customer output, jobs, schedules, listeners, console commands, or browser proof.
  • migration/schema changes, new evidence table, tenant_id, new OperationRun type, or new persisted outcome/summary key.
  • target expansion beyond the three included types.
  • compare/render/certification/restore/customer claim.
  • Graph gateway fallback or fake Graph endpoints.
  • durable collection-level empty proof.