# 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) ```text 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: ```text 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: ```text 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.