TenantAtlas/specs/430-exchange-powershell-adapter-contract-slice-1/plan.md
ahmido 9b58a5696d feat: add Exchange PowerShell adapter contract slice 1 (#497)
Spec 430: Exchange PowerShell adapter contract slice 1. Validation was not rerun during PR creation handoff; branch contains implementation report and tests.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #497
2026-07-05 12:08:16 +00:00

17 KiB

Implementation Plan: Exchange PowerShell Adapter Contract Slice 1

Branch: 430-exchange-powershell-adapter-contract-slice-1 | Date: 2026-07-04 | Spec: specs/430-exchange-powershell-adapter-contract-slice-1/spec.md Input: Feature specification from specs/430-exchange-powershell-adapter-contract-slice-1/spec.md

Summary

Implement a narrow Coverage v2 Exchange PowerShell adapter contract slice for exactly transportRule, remoteDomain, and inboundConnector. The implementation must add structured, allowlisted read-only command contracts, fake-runner testability, resolver support, metadata for permissions/identity/response shape/redaction/normalization, and no-promotion tests. It must not perform live provider execution, create evidence, create OperationRuns, add UI, add migrations by default, or claim compare/render/certification/restore/customer readiness.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12, Filament 5, Livewire 4. Primary Dependencies: existing Laravel app, Coverage v2 TenantConfiguration services, Pest 4. Storage: PostgreSQL via Sail, but no new persistence or migrations are expected. Testing: Pest 4 unit and focused feature tests. Validation Lanes: fast-feedback for focused unit/feature tests; confidence for selected regression tests if existing filters require it. Target Platform: Laravel platform app under apps/platform. Project Type: monorepo with Laravel platform application. Performance Goals: no live provider work; resolver/metadata checks should remain deterministic and cheap. Constraints: no shell execution in tests, no Microsoft service calls, no evidence persistence, no OperationRuns, no UI, no tenant_id, no fallback readers, no legacy shims. Scale/Scope: three Exchange target types and their adapter-contract metadata only.

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 source-contract behavior.
  • Native vs custom classification summary: N/A.
  • Shared-family relevance: none.
  • State layers in scope: none for UI; backend resolver state only.
  • Audience modes in scope: N/A.
  • Decision/diagnostic/raw hierarchy plan: N/A.
  • Raw/support gating plan: no raw provider payloads, transcripts, stdout/stderr, or diagnostics are rendered or persisted.
  • One-primary-action / duplicate-truth control: N/A.
  • Handling modes by drift class or surface: report-only, because no rendered surface changes.
  • Repository-signal treatment: hard stop if UI files, routes, Filament providers/resources/pages/widgets, Livewire components, reports, downloads, or customer outputs enter scope.
  • Special surface test profiles: N/A.
  • Required tests or manual smoke: browser proof is N/A - no rendered UI surface changed.
  • Exception path and spread control: none.
  • Active feature PR close-out entry: implementation report.
  • UI/Productization coverage decision: No UI surface impact.
  • Coverage artifacts to update: none.
  • No-impact rationale: adapter contracts are backend/source-contract metadata only.
  • Navigation / Filament provider-panel handling: no panel/provider change.
  • Screenshot or page-report need: no.

Product Surface Contract Plan

  • Product Surface Contract reference: N/A for runtime; no rendered product surface changed.
  • No-legacy posture: canonical addition; no legacy aliases, fallback readers, hidden routes, or duplicate UI.
  • Page archetype and surface budget plan: N/A.
  • Technical Annex and deep-link demotion plan: N/A; no OperationRun/evidence/raw IDs/source keys/payloads are rendered.
  • Canonical status vocabulary plan: no product-facing status vocabulary changes.
  • 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/430-exchange-powershell-adapter-contract-slice-1/implementation-report.md.

Filament / Livewire / Deployment Posture

  • Livewire v4 compliance: N/A - no runtime UI change; repo baseline is Livewire v4.
  • Panel provider registration location: no panel change; Laravel 12 panel providers remain in apps/platform/bootstrap/providers.php.
  • Global search posture: no Filament Resource changed; no global search change.
  • Destructive/high-impact action posture: none; no actions exposed.
  • Asset strategy: no assets; filament:assets not required by this spec.
  • Testing plan: no pages/widgets/relation managers/actions/browser smoke. Backend unit/feature tests only.
  • Deployment impact: no env vars, no migrations expected, no queues/scheduler/storage/assets. If a migration becomes necessary, stop and amend this plan.

Shared Pattern & System Fit

  • Cross-cutting feature marker: no operator-facing cross-cutting interaction class.
  • Systems touched: Coverage v2 source-contract/resolver path and claim guard/no-promotion tests.
  • Shared abstractions reused: existing CoverageSourceContractResolver, ResourceTypeRegistry, CoverageIdentityStrategyRegistry, Claim Guard or repo-equivalent guard path, and TenantConfiguration test patterns where applicable.
  • New abstraction introduced? why?: a narrow command contract/runner boundary may be introduced or extended because structured command allowlisting and fake-runner proof are the core safety requirement.
  • Why the existing abstraction was sufficient or insufficient: existing Coverage v2 can block missing contracts and capture eligibility, but does not yet encode allowlisted Exchange PowerShell command contracts.
  • Bounded deviation / spread control: no Exchange mini-platform; keep provider-specific command details behind source-contract metadata.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: no.
  • Central contract reused: N/A.
  • Delegated UX behaviors: N/A.
  • Surface-owned behavior kept local: none.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: N/A.
  • Exception path: none.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes.
  • Provider-owned seams: Exchange Online PowerShell source surface, cmdlet names, command response shapes, permission notes, provider-native identifiers, protected configuration details.
  • Platform-core seams: workspace, managed environment, provider connection, Coverage v2 source-contract state, target type registry, identity handoff, evidence/no-evidence gates, claim boundaries.
  • Neutral platform terms / contracts preserved: source surface, adapter contract, command contract, target type, provider connection, managed environment, evidence state, claim boundary, restore tier.
  • Retained provider-specific semantics and why: the three Get-* cmdlets are the safety allowlist and must remain explicit.
  • Bounded extraction or follow-up path: document-in-feature. Spec 431 handles live capture/execution; Teams and Exchange Admin API get later slices.

Constitution Check

GATE: Must pass before implementation. Re-check after design and before close-out.

  • Inventory-first: no inventory/evidence observations are created in this slice.
  • Read/write separation: only read-only command contracts are representable; no write/change behavior.
  • Graph contract path: no Graph calls. Do not guess Graph endpoints for these Exchange types.
  • Deterministic capabilities: resolver output and claim boundaries must be testable.
  • RBAC-UX: no user-facing action; permission metadata only. Future execution must enforce server-side authorization and scope.
  • Workspace isolation: provider connection scope remains workspace + managed environment + provider connection; no provider-native tenant ID becomes ownership truth.
  • Tenant isolation: no tenant-scoped routes or UI.
  • Run observability: no OperationRun in this slice; future live provider work must be OperationRun-backed.
  • OperationRun start UX: N/A.
  • Data minimization: no raw transcripts/stdout/stderr/provider payloads; redaction metadata must exist before capture.
  • Test governance: Unit/Feature lane classification is explicit; no browser or heavy-governance expansion planned.
  • Proportionality: the new adapter boundary is justified by three concrete target types and command-injection/no-provider-call safety.
  • No premature abstraction: do not build a generic multi-provider PowerShell framework; implement the narrow Exchange PowerShell contract boundary only.
  • Persisted truth: no new table/entity/artifact.
  • Behavioral state: reuse repo-equivalent states; do not introduce a broad status family.
  • UI semantics: no UI.
  • Provider boundary: provider-specific command semantics stay behind source-contract metadata.
  • V1 explicitness / few layers: explicit target-type contracts before any generalized framework.
  • Spec discipline / bloat check: adjacent evidence/UI/Teams/Admin API concerns are follow-up specs.
  • Filament/UI rules: N/A.

Test Governance Check

  • Test purpose / classification by changed surface: Unit for command contracts, fake runner, metadata, resolver decisions; Feature only if resolver/no-runtime-capture behavior is already feature-tested or needs DB-backed proof.
  • Affected validation lanes: fast-feedback plus selected confidence regressions.
  • Why this lane mix is the narrowest sufficient proof: risks are backend safety and no-promotion behavior, not UI.
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec430 --compact
    • selected Spec 426/427/428/417/420 regressions
  • Fixture / helper / factory / seed / context cost risks: response fixtures and fake runner should remain local and cheap; no default provider/workspace/browser setup.
  • Expensive defaults or shared helper growth introduced?: no; any fake runner helper must be opt-in.
  • Heavy-family additions, promotions, or visibility changes: none expected.
  • Surface-class relief / special coverage rule: browser N/A.
  • Closing validation and reviewer handoff: record exact focused tests, pass counts/assertions, regressions, Pint, git diff --check, and git status --short in the implementation report.
  • Budget / baseline / trend follow-up: none expected.
  • Review-stop questions: reject/split if tests require live provider setup, shell execution, broad workspace context defaults, or UI/browser proof.
  • Escalation path: split if live execution, evidence, UI, additional target types, or broad adapter framework appears.
  • Active feature PR close-out entry: implementation report.
  • Why no dedicated follow-up spec is needed: this spec is itself the narrow adapter-contract slice; follow-ups are already named for execution/evidence/UI/customer readiness.

Project Structure

Documentation (this feature)

specs/430-exchange-powershell-adapter-contract-slice-1/
├── spec.md
├── plan.md
├── tasks.md
└── checklists/
    └── requirements.md

Source Code (expected implementation surfaces)

Use current repo conventions before adding files. Likely touched surfaces:

apps/platform/app/Services/TenantConfiguration/
├── CoverageSourceContractResolver.php
├── ResourceTypeRegistry.php
├── CoverageIdentityStrategyRegistry.php
└── Exchange PowerShell adapter contract support files named after T003 confirms sibling conventions

apps/platform/config/
└── source-contract or provider contract config only if T003 confirms the current repo pattern requires it

apps/platform/tests/Unit/Support/TenantConfiguration/
└── Spec430*Test.php

apps/platform/tests/Feature/TenantConfiguration/
└── Spec430*Test.php (only if DB-backed/source-contract feature proof is required)

Forbidden source surfaces:

apps/platform/routes/**
apps/platform/app/Filament/**
apps/platform/app/Livewire/**
apps/platform/database/migrations/** (unless spec is amended)
jobs, scheduled tasks, provider capture services, customer report outputs, browser tests

Structure Decision: Keep implementation in the existing TenantConfiguration/Coverage v2 source-contract path. Add only a narrow Exchange PowerShell contract boundary if current code has no equivalent.

File Path Decision: T003 must verify sibling conventions and record the exact support/config paths before any runtime source edit.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
New or extended command-contract boundary Prevents raw PowerShell, command injection, mutation commands, and provider calls before capture exists Resolver-only exceptions would not prove command safety or fake-runner behavior
Source-contract metadata for three Exchange types Required to unblock later capture while preserving no-claim state Broad Cohort 1 implementation would be too large and mix Exchange/Teams/Admin API concerns

Proportionality Review

  • Current operator problem: release reviewers need proof that Exchange capture will later use safe, allowlisted contracts rather than arbitrary PowerShell or guessed endpoints.
  • Existing structure is insufficient because: current resolver can fail closed, but not represent the Exchange PowerShell command safety boundary.
  • Narrowest correct implementation: three concrete command contracts and a fake-runner boundary; no live execution and no broader adapter framework.
  • Ownership cost created: metadata and tests must evolve with Exchange source behavior.
  • Alternative intentionally rejected: raw strings, direct shell execution, Graph endpoint guesses, one-off resolver promotions, or all Cohort 1 at once.
  • Release truth: future-release preparation required immediately to unblock Spec 431.

Implementation Phases

tasks.md intentionally expands these plan phases into finer-grained execution checkpoints. Dependency order is authoritative; numeric phase labels do not need a one-to-one match.

Phase 0 - Preflight

  • Confirm branch, HEAD, clean state, Spec 429 completion, selected target types, excluded types, and no-implementation boundaries.
  • Verify current repo classes and tests before choosing exact file names.

Phase 1 - Contract Shape

  • Add or extend a structured Exchange PowerShell command contract shape.
  • Add allowlist and parameter policy.
  • Add fake command runner boundary and structured success/failure result shape.
  • Ensure no raw shell strings are accepted.

Phase 2 - Target Contracts

  • Add contracts for transportRule, remoteDomain, and inboundConnector.
  • Include permission, response-shape, identity handoff, redaction, normalization handoff, claim boundary, and restore-tier metadata.

Phase 3 - Resolver Integration

  • Integrate with CoverageSourceContractResolver or repo-equivalent path.
  • Promote included types only to verified pending-capture / adapter-contract-available.
  • Preserve blocked/deferred states for excluded types.

Phase 4 - Safety And No-Promotion Proof

  • Add command allowlist and fake-runner tests.
  • Add metadata tests.
  • Add no evidence, no OperationRun, no provider call, no compare/render/certification/restore/customer claim tests.
  • Add no tenant_id, no fallback reader, no legacy shim, no mini-platform checks.

Phase 5 - Regression And Report

  • Run focused tests and selected regressions.
  • Run Pint and git diff --check.
  • Complete implementation-report.md with required proof matrices.

Rollout Considerations

  • Staging validation is required before production promotion for any runtime code, but this slice should not require migrations, env vars, queues, scheduler, storage, or assets.
  • If live Exchange execution, credentials, app-only auth, queueing, consent, or provider permission checks become necessary, stop and split to Spec 431 or an execution-hardening spec.

Risk Controls

  • Command allowlist is static.
  • Unknown commands/parameters fail closed.
  • Mutation command families fail closed.
  • Fake runner only in tests.
  • Production runner, if present, remains disabled/inert for this spec.
  • Resolver states remain no-evidence/no-claim.
  • Permission model is marked pending runtime validation unless proven.
  • Redaction metadata is required before capture.
  • Exchange cmdlets and response fields remain provider-owned source details, not platform-core ownership truth, customer vocabulary, or customer-safe labels.
  • Future execution handoff scope remains workspace, managed-environment, and provider-connection based; provider-native tenant identifiers remain metadata only.
  • Excluded types are explicitly tested.

Analyze Result

Preparation analyze is recorded in this package by static cross-artifact review after artifact creation. Any findings must be fixed only in spec.md, plan.md, tasks.md, or checklists/requirements.md; application code is out of scope for preparation.