# Feature Specification: Exchange PowerShell Adapter Contract Slice 1 **Feature Branch**: `430-exchange-powershell-adapter-contract-slice-1` **Created**: 2026-07-04 **Status**: Draft **Input**: User-provided draft "Spec 430 - Exchange PowerShell Adapter Contract Slice 1" plus repo evidence from Spec 429. ## Activated Skills And Gate Preflight - **Activated skill**: `spec-kit-next-best-prep` because the user requested preparation of the next Spec Kit package without implementation. - **Repo hard-gate context consulted**: `workflows/spec-readiness-gate`, `repo-contracts/provider-freshness-semantics`, `repo-contracts/evidence-anchor-contract`, `repo-contracts/workspace-scope-safety`, `repo-contracts/operation-run-truth`, and `temporary-migrations/tcm-cutover-guard`. - **Current branch before Spec Kit execution**: `platform-dev`. - **HEAD before Spec Kit execution**: `0e2cea30 spec: add Exchange Teams source-surface catalog adapter strategy (#496)`. - **Dirty state before Spec Kit execution**: clean. - **Current branch after Spec Kit execution**: `430-exchange-powershell-adapter-contract-slice-1`. - **Hard-gate stop conditions**: none for preparation. Runtime stop conditions are carried into this spec: no live provider execution, no evidence, no OperationRun, no UI, no customer claims, no `tenant_id`, no fallback readers, no legacy adapters. ## Candidate Selection Result - **Selected candidate**: Spec 430 - Exchange PowerShell Adapter Contract Slice 1. - **Source location**: user-provided draft attachment and `specs/429-exchange-teams-source-surface-catalog-adapter-strategy/implementation-report.md`, which names `new_exchange_powershell_adapter` as the recommended first Spec 430 runtime path and lists `transportRule`, `remoteDomain`, and `inboundConnector` in Cohort 1. - **Why selected**: Spec 429 completed the source-surface catalog and left a narrow runtime follow-up: create an Exchange PowerShell adapter contract boundary before any content-backed evidence capture. Current repo search found no existing `specs/430-*` package. - **Why close alternatives were deferred**: - `acceptedDomain` and `organizationConfig` are deferred because Spec 429 identifies possible Exchange Admin API involvement and preview/RBAC concerns. - `outboundConnector` is deferred so the first connector proof covers one connector direction only. - Teams PowerShell targets are deferred to a later Teams-specific adapter contract slice. - Content-backed capture, compare/render, certification, restore, and customer output are deferred to Specs 431+ because this slice must not create product-readiness claims. - **Completed-spec guardrail result**: Specs 426-429 are completed or implementation-closed context and were not modified. No existing Spec 430 package was found. - **Smallest viable implementation slice**: exactly `transportRule`, `remoteDomain`, and `inboundConnector` command contracts using `exchange_online_powershell_rest` and `new_exchange_powershell_adapter`, with fake-runner testability and no live execution. - **Feature description fed into Spec Kit**: Prepare a safe, allowlisted Exchange PowerShell adapter contract boundary for `transportRule`, `remoteDomain`, and `inboundConnector` using `exchange_online_powershell_rest`, without live provider execution, evidence, OperationRuns, UI, compare/render, certification, restore, customer claims, or `tenant_id`. ## Spec Candidate Check *(mandatory - SPEC-GATE-001)* - **Problem**: Exchange/Teams Coverage v2 remains blocked because selected Exchange target types have no repo-safe source adapter contract boundary. - **Today's failure**: The platform correctly reports missing contracts, but cannot safely proceed to content-backed Exchange capture without risking one-off PowerShell execution, over-broad target selection, command injection, permission overclaiming, or customer readiness claims. - **User-visible improvement**: Reviewers and later implementers get a narrow, testable contract proving which Exchange cmdlets are allowed and which claims remain blocked before any provider capture occurs. - **Smallest enterprise-capable version**: Three read-only Exchange target types only: `transportRule`, `remoteDomain`, and `inboundConnector`; structured command contracts; static allowlist; fake runner; resolver state; metadata for permission, identity, response shape, redaction, normalization, and claim boundaries. - **Explicit non-goals**: No live Exchange connection, provider call, PowerShell shell execution, evidence persistence, OperationRun, UI, routes, navigation, compare/render, certification, restore/apply, customer report, Teams adapter, Exchange Admin API adapter, `acceptedDomain`, `organizationConfig`, `outboundConnector`, or `tenant_id`. - **Permanent complexity imported**: A narrow adapter contract shape, command-contract metadata, fake runner boundary, resolver integration, and focused tests. No new persisted entity/table and no product UI taxonomy. - **Why now**: Spec 429 explicitly makes this the next prerequisite before Spec 431 can perform OperationRun-backed content-backed evidence capture. - **Why not local**: Local hardcoded resolver exceptions would not prove command allowlisting, parameter rejection, fake-runner safety, permission metadata, or no-promotion behavior. - **Approval class**: Core Enterprise. - **Red flags triggered**: New adapter abstraction and source-contract metadata. Defense: three real command contracts plus command-injection and no-provider-call safety require a structured boundary; scope is intentionally narrower than the full Cohort 1. - **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexität: 1 | Produktnähe: 1 | Wiederverwendung: 2 | **Gesamt: 10/12**. - **Decision**: approve for preparation; implementation must remain bounded to the three target types. ## Spec Scope Fields *(mandatory)* - **Scope**: workspace + managed environment + provider connection semantics, without new persisted ownership. - **Primary Routes**: none. - **Data Ownership**: no new persistence is planned. Any runtime metadata must remain attached to Coverage v2 source-contract/provider-boundary configuration or support classes; provider-native tenant identifiers remain metadata only. - **RBAC**: no new user action is exposed. Permission metadata must not widen consent or claim least privilege without runtime validation. For canonical-view specs: - **Default filter behavior when tenant-context is active**: N/A - no rendered or queryable UI view. - **Explicit entitlement checks preventing cross-tenant leakage**: No runtime surface is introduced. Any future provider execution is deferred and must re-resolve workspace, managed environment, and provider connection scope before execution. ## No Legacy / No Backward Compatibility Constraint *(mandatory)* TenantPilot is pre-production unless this spec explicitly records a compatibility exception. - **Compatibility posture**: canonical narrow addition to Coverage v2 source-contract behavior. - **Legacy aliases, fallback readers, hidden routes, duplicate UI, old labels, or historical fixtures kept?**: no. - **Why clean replacement is safe now**: current repo truth expects missing Exchange source contracts to fail closed until a verified adapter contract exists; no production compatibility path is required. ## UI Surface Impact *(mandatory - UI-COV-001)* Does this spec add, remove, rename, or materially change any reachable UI surface? - [x] No UI surface impact - [ ] Existing page changed - [ ] New page/route added - [ ] Navigation changed - [ ] Filament panel/provider surface changed - [ ] New modal/drawer/wizard/action added - [ ] New table/form/state added - [ ] Customer-facing surface changed - [ ] Dangerous action changed - [ ] Status/evidence/review presentation changed - [ ] Workspace/environment context presentation changed No-impact rationale: Spec 430 defines backend/source-contract behavior only. It must not edit runtime UI files, routes, Filament resources/pages/widgets, navigation, reports, downloads, customer outputs, or browser-rendered diagnostics. ## UI/Productization Coverage *(mandatory when UI Surface Impact is not "No UI surface impact"; otherwise write `N/A - no reachable UI surface impact` plus rationale)* N/A - no reachable UI surface impact. The implementation must stop and amend this spec if UI changes become necessary. ## Product Surface Impact *(mandatory for UI-affecting specs; otherwise write `N/A - no rendered product surface changed` plus rationale)* Reference: `docs/product/standards/product-surface-contract.md`. - **Product Surface Contract applies?**: no - no rendered product surface changes. - **Page archetype**: N/A. - **Primary user question**: N/A. - **Primary action**: N/A. - **Surface budget result**: N/A. - **Technical Annex / deep-link demotion**: N/A for runtime; the implementation must not render OperationRun, evidence, raw payload, IDs, source keys, detectors, fingerprints, logs, or provider diagnostics. - **Canonical status vocabulary**: internal resolver states only; no product-facing status label changes. - **Visible complexity impact**: neutral. - **Product Surface exceptions**: none. ## Browser Verification Plan *(mandatory)* - **Browser proof required?**: no. - **No-browser rationale**: `N/A - no rendered UI surface changed`. - **Focused path when required**: N/A. - **Primary interaction to execute**: N/A. - **Console, Livewire, Filament, network, and 500-error checks**: N/A. - **Full-suite failure triage**: N/A unless UI changes are introduced after spec amendment. ## Human Product Sanity Check *(mandatory)* - **Required?**: no. - **No-human-sanity rationale**: N/A - no product surface changed. - **Reviewer questions**: N/A. - **Planned result location**: implementation report should record `N/A - no rendered UI surface changed`. ## Product Surface Merge Gate Checklist *(mandatory)* - [x] No-legacy posture or approved exception recorded. - [x] Product Surface Impact is completed or `N/A` is justified. - [x] Browser proof is completed or `N/A - no rendered UI surface changed` is justified. - [x] Human Product Sanity is completed or not applicable with rationale. - [x] Product Surface exceptions are documented or `none`. - [x] Implementation report will state Livewire v4 compliance, provider registration location, global search posture, destructive/high-impact action posture, asset strategy, tests/browser result, deployment impact, and visible complexity outcome. ## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)* - **Cross-cutting feature?**: no. - **Interaction class(es)**: N/A. - **Systems touched**: N/A. - **Existing pattern(s) to extend**: N/A. - **Shared contract / presenter / builder / renderer to reuse**: N/A. - **Why the existing shared path is sufficient or insufficient**: N/A. - **Allowed deviation and why**: none. - **Consistency impact**: no operator-facing interaction language changes. - **Review focus**: verify no notifications, action links, navigation, reports, or evidence viewers are added. ## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)* - **Touches OperationRun start/completion/link UX?**: no. - **Shared OperationRun UX contract/layer reused**: N/A. - **Delegated start/completion UX behaviors**: N/A. - **Local surface-owned behavior that remains**: none. - **Queued DB-notification policy**: N/A. - **Terminal notification path**: N/A. - **Exception required?**: none. ## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)* - **Shared provider/platform boundary touched?**: yes. - **Boundary classification**: mixed. Coverage v2 source-contract state, resolver behavior, evidence gates, claim guards, workspace/managed-environment/provider-connection scope, and no-promotion semantics are platform-core. Exchange PowerShell cmdlets, source response shapes, permission names, and provider-native identifiers are provider-owned source details. - **Seams affected**: Coverage source contract resolver, resource type registry metadata where required, source contract metadata, command allowlist, fake command runner test boundary, Claim Guard/no-promotion tests, identity handoff metadata, redaction metadata. - **Neutral platform terms preserved or introduced**: workspace, managed environment, provider connection, target type, source surface, source contract, adapter contract, command contract, evidence state, claim boundary, restore tier. - **Provider-specific semantics retained and why**: `Get-TransportRule`, `Get-RemoteDomain`, and `Get-InboundConnector` are retained because the source surface is Exchange Online PowerShell and command identity is the safety boundary. - **Why this does not deepen provider coupling accidentally**: provider-specific cmdlet details remain metadata behind Coverage v2 source-contract boundaries; no provider-native tenant ID becomes platform ownership truth; no UI/customer vocabulary is introduced. - **Follow-up path**: document-in-feature for this slice; live execution and content-backed evidence are deferred to Spec 431 or a dedicated execution-hardening spec. ## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)* N/A - no operator-facing surface change. ## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)* N/A - no operator-facing surface change. ## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)* N/A - no operator-facing surface change. ## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)* N/A - no operator-facing surface change. ## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)* N/A - no operator-facing surface change. ## Proportionality Review *(mandatory when structural complexity is introduced)* - **New source of truth?**: no persisted source of truth. The source contract remains derived/configured runtime behavior. - **New persisted entity/table/artifact?**: no. - **New abstraction?**: yes - a narrow Exchange PowerShell adapter command-contract/runner boundary may be introduced or extended. - **New enum/state/reason family?**: no new broad status family. Reuse repo-equivalent resolver states and add only local structured failure reasons if needed for command-contract validation. - **New cross-domain UI framework/taxonomy?**: no. - **Current operator problem**: reviewers cannot safely approve Exchange evidence capture while the repo lacks a contract that prevents arbitrary PowerShell, mutation commands, provider calls, and customer claims. - **Existing structure is insufficient because**: Coverage v2 can fail closed for missing contracts, but it cannot represent allowlisted Exchange PowerShell commands, response-shape metadata, or fake-runner safety for this source surface. - **Narrowest correct implementation**: three concrete command contracts plus a structured runner boundary; no live runner, no UI, no persistence, and no full Exchange mini-platform. - **Ownership cost**: adapter metadata and focused tests must be maintained as Exchange command contracts evolve; future live capture must honor this boundary. - **Alternative intentionally rejected**: raw command strings, direct shell execution, Graph endpoint guesses, Exchange Admin API substitution, one-off resolver exceptions, and implementing the entire Cohort 1. - **Release truth**: future-release preparation that is an immediate prerequisite for the next content-backed evidence slice. ### Compatibility posture This feature assumes a pre-production environment. Backward compatibility, legacy aliases, migration shims, historical fixtures, fallback readers, and compatibility-specific tests are out of scope unless explicitly required by an amended spec. ## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)* - **Test purpose / classification**: Unit and focused Feature tests. Browser is N/A. - **Validation lane(s)**: fast-feedback for adapter contracts, resolver state, fake runner, metadata, and no-promotion tests; confidence lane for selected regressions if existing focused files require it. - **Why this classification and these lanes are sufficient**: this slice is backend/source-contract only. The key risks are command safety, resolver state, metadata completeness, and no evidence/OperationRun/product promotion. - **New or expanded test families**: focused Spec 430 unit/feature tests under existing TenantConfiguration/Coverage v2 test families. No browser family. - **Fixture / helper cost impact**: response-shape fixtures and fake command runner only; no provider setup, no shell setup, no workspace membership browser state. - **Heavy-family visibility / justification**: none expected. If regression filters become broad or costly, document command, result, and direct-file fallback. - **Special surface test profile**: N/A. - **Standard-native relief or required special coverage**: N/A - no Filament/UI surface. - **Reviewer handoff**: verify tests prove allowlist, rejected mutation/raw/unknown commands, resolver states, metadata presence, no provider calls, no evidence, no OperationRun, no claims, no `tenant_id`, and no mini-platform. - **Budget / baseline / trend impact**: expected neutral; no browser or heavy-governance expansion planned. - **Escalation needed**: none if scope stays bounded; split if live execution, UI, evidence, or broader target types appear. - **Active feature PR close-out entry**: implementation report. - **Planned validation commands**: - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec430 --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec426 --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec427 --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec428 --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec417 --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec420 --compact` - `git diff --check` - `git status --short` ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Verify Exchange PowerShell Command Contracts (Priority: P1) As a release reviewer, I need the first Exchange PowerShell adapter slice to expose only structured, allowlisted read-only command contracts for `transportRule`, `remoteDomain`, and `inboundConnector`. **Why this priority**: This is the command-safety gate. Without it, later capture could drift into arbitrary shell execution or mutation commands. **Independent Test**: Run focused command-contract and allowlist tests proving only `Get-TransportRule`, `Get-RemoteDomain`, and `Get-InboundConnector` are representable, while raw command strings, mutation families, and unknown parameters are rejected. **Acceptance Scenarios**: 1. **Given** the Exchange PowerShell adapter contract registry, **When** `transportRule` is resolved, **Then** the contract names `Get-TransportRule` and marks it as read-only, collection-shaped, fake-runner-testable, and pending capture. 2. **Given** a mutation command such as `Set-TransportRule`, **When** a command contract is requested, **Then** the adapter rejects it before runner execution. 3. **Given** a raw command string or unknown parameter, **When** the runner boundary receives it, **Then** it returns a structured rejection without shell execution. --- ### User Story 2 - Resolve Included Types Without Promoting Excluded Types (Priority: P2) As a future capture implementer, I need the Coverage v2 resolver to return a verified pending-capture source-contract state only for the three included target types. **Why this priority**: Spec 431 must know exactly which Exchange types are eligible for later capture and which remain blocked or deferred. **Independent Test**: Run resolver tests proving `transportRule`, `remoteDomain`, and `inboundConnector` return repo-equivalent `contract_verified_pending_capture` and `adapter_contract_available`, while excluded Exchange/Teams types remain blocked or deferred. **Acceptance Scenarios**: 1. **Given** the resolver receives `remoteDomain`, **When** it evaluates source-contract availability, **Then** it returns a verified pending-capture contract with Exchange PowerShell metadata and no evidence state. 2. **Given** the resolver receives `outboundConnector`, `acceptedDomain`, `organizationConfig`, or a Teams type, **When** it evaluates source-contract availability, **Then** those types remain excluded, blocked, or deferred. --- ### User Story 3 - Preserve No-Evidence And No-Claim Boundaries (Priority: P3) As a product reviewer, I need this adapter-contract slice to avoid any customer, restore, compare/render, certification, or evidence claim. **Why this priority**: The adapter contract is a prerequisite, not product readiness. Overclaiming here would weaken the safety guarantees from Specs 426-429. **Independent Test**: Run no-promotion tests proving no evidence rows, OperationRuns, provider calls, compare/render states, certification states, restore-ready states, customer claims, UI changes, `tenant_id`, or mini-platform artifacts appear. **Acceptance Scenarios**: 1. **Given** the three included contracts are available, **When** claim guard behavior is evaluated, **Then** only an internal/operator-safe statement that adapter contracts exist is allowed. 2. **Given** the implementation finishes, **When** the repository diff is reviewed, **Then** no migrations, routes, Filament resources, Livewire components, jobs, provider calls, evidence rows, OperationRuns, or customer report outputs were added. ### Edge Cases - Valid empty collection must differ from permission denied, command unavailable, adapter unavailable, malformed response, and unexpected object shape. - Display name alone must never produce stable identity. - Least-privilege requirements must not be marked fully proven without runtime evidence. - Command output must be structured; human-formatted console text, transcripts, stdout, and stderr are not authoritative evidence. - Sensitive fields and provider error text must be redacted before logs, failures, or diagnostics. ## Requirements *(mandatory)* ### Functional Requirements - **FR-430-001**: The implementation MUST include exactly `transportRule`, `remoteDomain`, and `inboundConnector`. - **FR-430-002**: The implementation MUST use source surface `exchange_online_powershell_rest` and adapter pattern `new_exchange_powershell_adapter` or repo-equivalent names. - **FR-430-003**: The implementation MUST provide structured command contracts for `Get-TransportRule`, `Get-RemoteDomain`, and `Get-InboundConnector`. - **FR-430-004**: The command boundary MUST reject raw command strings, unknown command names, unknown parameters, script blocks, pipeline fragments, semicolon-separated commands, redirection, file writes, module installation, and arbitrary operator-supplied command text. - **FR-430-005**: The command boundary MUST reject write or mutation command families including `Set-*`, `New-*`, `Remove-*`, `Enable-*`, `Disable-*`, `Update-*`, `Start-*`, `Stop-*`, `Invoke-*`, `Search-*`, `Export-*`, and `Import-*`. - **FR-430-006**: Tests MUST use a fake command runner and MUST NOT execute a real shell, call Microsoft services, or require Exchange Online connectivity. - **FR-430-007**: Each target type MUST include source contract metadata for canonical type, workload, source surface, adapter pattern, command name, command contract version, collection/singleton shape, expected response shape, identity fields, permission model, permission failure modes, redaction rules, volatile fields, normalization handoff, capture eligibility, claim state, and restore tier. - **FR-430-008**: The resolver MUST return repo-equivalent `contract_verified_pending_capture` and `adapter_contract_available` for the three included types. - **FR-430-009**: The resolver MUST preserve blocked or deferred states for non-included Exchange/Teams types, including `acceptedDomain`, `organizationConfig`, `mailboxPlan`, `outboundConnector`, `sharingPolicy`, Teams policy types, and `externalAccessPolicy`. - **FR-430-010**: Permission metadata MUST distinguish known documentation notes from runtime-proven least privilege and MUST mark runtime validation as pending when proof is incomplete. - **FR-430-011**: Identity handoff metadata MUST use `stable_candidate`, `derived_candidate`, `identity_unsafe`, or `unknown` repo-equivalent semantics and MUST prevent display-name-only stable identity. - **FR-430-012**: Redaction metadata MUST forbid tokens, secrets, authorization headers, cookies, certificate private material, passwords, raw transcripts, raw shell stdout/stderr, mail body/content, mailbox content, file content, and Teams transcript/content from logs, diagnostics, or evidence. - **FR-430-013**: Target-specific protected configuration such as email addresses, domains, IP ranges, certificate names, header names, rule patterns, and connector routing metadata MUST be classified as protected configuration. - **FR-430-014**: The implementation MUST NOT create content-backed evidence, raw provider payload persistence, normalized evidence persistence, provider capture, OperationRuns, jobs, scheduled tasks, routes, Filament pages, Livewire components, database `tenant_id`, Exchange-specific evidence tables, legacy shims, fallback readers, compare/render promotion, certification, restore-ready state, customer-ready state, or customer claims. - **FR-430-015**: Claim Guard or repo-equivalent tests MUST allow only the internal/operator-safe statement: "Exchange PowerShell adapter contracts exist for transportRule, remoteDomain, and inboundConnector." - **FR-430-016**: Browser verification MUST remain `N/A - no rendered UI surface changed` unless the spec is amended before UI work. ### Non-Functional Requirements - **NFR-430-001**: Security posture MUST fail closed for unknown command names, unknown parameters, raw command text, mutation command families, and unsupported response shapes. - **NFR-430-002**: Test execution MUST be deterministic and offline; no test may require Exchange Online connectivity, Microsoft credentials, installed PowerShell modules, shell execution, or network access. - **NFR-430-003**: Redaction posture MUST prevent secrets, tokens, raw transcripts, raw shell stdout/stderr, mail/message body content, mailbox content, file content, and Teams transcript/content from entering logs, diagnostics, OperationRun context, or evidence payloads. - **NFR-430-004**: Provider boundary posture MUST keep Exchange-specific cmdlets and response fields as provider-owned source details, not platform-core ownership truth or customer vocabulary. - **NFR-430-005**: Workspace/managed-environment/provider-connection scope MUST be preserved for any future execution handoff, and provider-native tenant identifiers MUST remain metadata only. - **NFR-430-006**: Observability posture MUST remain explicit: this slice creates no OperationRun, while any later live execution must be OperationRun-backed in a separate spec. - **NFR-430-007**: Product surface posture MUST remain `N/A - no rendered UI surface changed`; any UI, route, report, download, readiness badge, restore action, or customer output requires spec amendment before implementation. - **NFR-430-008**: Test governance MUST keep focused Spec 430 tests in the narrowest honest lane and record any broadened regression cost in the implementation report. ## UI Action Matrix *(mandatory when Filament is changed)* N/A - no Filament Resource, RelationManager, Page, action, table, form, navigation, global search, or panel provider changes are in scope. ### Key Entities *(include if feature involves data)* - **Exchange PowerShell command contract**: Structured, allowlisted representation of one read-only Exchange PowerShell cmdlet, its allowed parameters, response shape, permission metadata, identity handoff, redaction rules, and normalization handoff. - **Exchange PowerShell fake runner**: Test-only runner boundary that accepts structured contracts and returns structured success/failure results without shell execution or provider calls. - **Coverage source contract resolver decision**: Existing repo-equivalent decision result that changes only the included types from missing adapter/contract blockers to verified pending capture while preserving no-promotion states. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-430-001**: Focused tests prove `Get-TransportRule`, `Get-RemoteDomain`, and `Get-InboundConnector` are the only allowlisted command contracts in this slice. - **SC-430-002**: Focused tests prove raw command strings, unknown parameters, and mutation command families are rejected before execution. - **SC-430-003**: Resolver tests prove the three included types return verified pending-capture states and all explicitly excluded types remain blocked or deferred. - **SC-430-004**: Metadata tests prove permission, response-shape, identity, redaction, normalization, claim boundary, and restore-tier metadata exists for each included type. - **SC-430-005**: No-promotion tests prove no evidence, OperationRun, provider call, compare/render, certification, restore, customer claim, UI, `tenant_id`, legacy shim, fallback reader, or Exchange mini-platform appears. - **SC-430-006**: Validation report records focused tests, selected regressions, Pint, `git diff --check`, and `git status --short`. ## Runtime / Data Impact Allowed runtime changes: - source contract descriptors - adapter contract value objects or narrow support classes - resolver integration - fake command runner - command allowlist - response-shape fixtures - redaction metadata - claim guard tests Preferred data impact: no migrations. Forbidden runtime/data changes: - evidence rows - OperationRuns - provider calls - jobs or scheduled tasks - routes - Filament pages/resources/widgets - Livewire components - database `tenant_id` - Exchange-specific evidence tables - legacy snapshot adapters - fallback readers ## Target Type Contract Notes ### `transportRule` - **Command**: `Get-TransportRule`. - **Shape**: collection. - **Identity handoff**: prefer stable rule identity fields from source output such as GUID-like identifiers; display name alone is unsafe. - **Protected configuration**: rules can include conditions, exceptions, actions, state, priority/order, mode, domains, addresses, words, patterns, and header names. Message body/content must never be captured. ### `remoteDomain` - **Command**: `Get-RemoteDomain`. - **Shape**: collection. - **Identity handoff**: distinguish default remote domain from custom remote domains; domain/name alone is a candidate only if source contract proves stability. - **Protected configuration**: remote domains are Exchange configuration objects and can expose external communication posture. ### `inboundConnector` - **Command**: `Get-InboundConnector`. - **Shape**: collection. - **Identity handoff**: connector identity must not rely on display name alone if stable source identifiers are available. - **Protected configuration**: domains, IPs, TLS settings, certificate names, and partner/on-premises routing metadata are protected configuration data. ## Related Specs And Prerequisites This spec may proceed only after these historical packages remain complete and unmodified as context: - `specs/414-tcm-first-coverage-core-cutover` - `specs/415-generic-content-backed-capture` - `specs/417-canonical-identity-engine` - `specs/419-m365-tcm-workload-registry-expansion` - `specs/420-m365-generic-evidence-coverage-pack` - `specs/426-exchange-teams-core-evidence-identity-readiness` - `specs/427-exchange-teams-verified-source-contract-enablement` - `specs/428-exchange-teams-content-backed-evidence-promotion` - `specs/429-exchange-teams-source-surface-catalog-adapter-strategy` ## Risks | Risk | Severity | Mitigation | | --- | ---: | --- | | Adapter contract mistaken for live capture | High | No-evidence/no-OperationRun/no-provider-call tests | | PowerShell command injection | High | Structured command contracts and strict allowlist | | Mutation command accidentally allowed | High | Reject mutation family tests | | Real shell execution in tests | High | Fake runner only | | Permission model overclaimed | High | Runtime-validation-pending metadata | | Identity overclaimed | High | Identity handoff only; display-name-only rejection | | Redaction too weak | High | Redaction metadata tests | | Excluded types accidentally included | Medium | Explicit exclusion tests | | Exchange mini-platform appears | Medium | Coverage v2 architecture/no-mini-platform tests | | Customer claim appears | High | Claim Guard tests | | `tenant_id` returns | High | Static/no-tenant ownership tests | ## Assumptions - Spec 429 remains the authoritative current source-surface catalog for the first Exchange adapter path. - Exchange PowerShell connection and authentication details are intentionally deferred to Spec 431 or a dedicated execution-hardening spec. - Current repo terminology may differ slightly; implementation should use repo-canonical class, enum, and state names rather than literal draft names when equivalents exist. - No application implementation was performed during preparation. ## Open Questions None block implementation. The exact class names and file placement must be selected from current repo conventions during implementation. ## Follow-Up Spec Candidates - Spec 431 - Exchange content-backed evidence promotion slice using OperationRun-backed capture. - Exchange comparable/renderable promotion after content-backed evidence exists. - Teams PowerShell adapter contract slice. - Exchange Admin API contract slice for `acceptedDomain` and `organizationConfig` if preview/RBAC constraints are acceptable. - Outbound connector slice after inbound connector contract proof. ## Candidate Selection Gate Result PASS. The selected candidate is directly provided by the user, aligns with Spec 429, is not already covered by an active/completed Spec 430, is narrow enough for a bounded implementation loop, and keeps adjacent concerns as follow-up specs. ## Spec Readiness Gate Result PASS for preparation. `spec.md`, `plan.md`, `tasks.md`, and `checklists/requirements.md` exist and define a bounded, testable, no-implementation-ready package.