TenantAtlas/specs/433-exchange-credential-permission-evidence-support/plan.md
Ahmed Darrazi 158071bfb4
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 5m4s
feat: add Exchange credential permission evidence readiness
2026-07-08 01:53:53 +02:00

31 KiB

Implementation Plan: Exchange Credential and Permission Evidence Support

Branch: 433-exchange-credential-permission-evidence-support | Date: 2026-07-07 | Spec: specs/433-exchange-credential-permission-evidence-support/spec.md Input: Feature specification from specs/433-exchange-credential-permission-evidence-support/spec.md

Summary

Refine Exchange PowerShell credential and permission evidence readiness for the existing Spec 432 production runner gate and existing provider capability/readiness evaluation. The implementation should make credential evidence explicit, provider-scoped, workspace-scoped, managed-environment-scoped, current, auditable, and redaction-safe; make Exchange.ManageAsApp permission evidence current and scoped; introduce or reuse a combined readiness result; and ensure exchange_powershell_invoke is Supported only when both credential and permission evidence pass. No Exchange calls, PowerShell execution, content-backed evidence, new UI/routes/navigation/assets/global search, jobs, schedules, listeners, reports, customer claims, or tenant_id are in scope. Existing provider capability/readiness surfaces can render changed status output through existing code paths and must be browser-checked.

Technical Context

Language/Version: PHP 8.4 / Laravel 12 Primary Dependencies: Existing Laravel monolith, Filament v5 / Livewire v4 baseline unchanged Storage: PostgreSQL. Default is no new table; possible minimal provider-agnostic migration only if existing metadata is insufficient. Testing: Pest 4 focused unit and feature tests Validation Lanes: fast-feedback/confidence focused tests; PostgreSQL lane if migration/JSONB/index behavior changes; focused read-only browser proof for existing provider capability/readiness surfaces Target Platform: Laravel Sail local; Dokploy staging/production with Exchange production runner disabled by default Project Type: Laravel monolith under apps/platform Performance Goals: Readiness checks must be local DB/config evaluation only; no provider calls, process execution, or render-time work Constraints: No secrets/raw payloads in context/logs/tests; no Exchange execution; no new UI/routes/navigation/assets/global search; no customer claims; no tenant_id Scale/Scope: Existing Exchange PowerShell invocation operation and exchange_powershell_invoke capability for Spec 430 target slice only

Preflight Findings

  • Current branch before Spec Kit execution: platform-dev.
  • HEAD before Spec Kit execution: f4e34212 feat: add Exchange PowerShell production runner gate (#499).
  • Initial dirty state before Spec Kit execution: clean.
  • Spec Kit helper created branch: 433-exchange-credential-permission-evidence-support.
  • No existing specs/433-* directory or *433* branch was found before preparation.
  • Spec 431's historical "Spec 433" label for content-backed evidence promotion is superseded by the Spec 432 follow-up decision; content-backed promotion is now Spec 434.
  • docs/product/spec-candidates.md marks the automatic next-best-prep queue empty/manual-only; this spec is selected because the user directly provided a P0 draft.
  • Spec 432 implementation report records PASS and proves the runner boundary, disabled default, production config gate, runtime checker, credential resolver, permission evaluator, process executor, command builder/output guards, OperationRun context sanitization, no evidence, no UI, no migration, and no tenant_id.
  • Current apps/platform/config/tenantpilot.php includes:
    • tenantpilot.features.exchange_powershell_invocation
    • tenantpilot.features.exchange_powershell_production_runner
    • tenantpilot.exchange_powershell.credentials.supported_reference_kinds
    • runtime knobs under tenantpilot.exchange_powershell.runtime
  • Current ProviderCredential has provider_connection_id, type, credential_kind, source, encrypted hidden payload, last_rotated_at, and expires_at.
  • Current ProviderCredentialKind has client_secret, certificate, and federated; managed identity is not a first-class enum case.
  • Current ManagedEnvironmentPermission has workspace_id, managed_environment_id, permission_key, status, last_checked_at, and JSONB details; current persistence is unique by managed_environment_id + permission_key, with provider-connection scope represented only through details.
  • Current ExchangePowerShellCredentialReferenceResolver blocks missing credentials, client-secret credentials, expired certificates, unsupported certificate/federated/managed-identity states, and unknown kinds, but does not yet prove all first-class accessibility/wrong-scope/source/currentness states from the draft.
  • Current ExchangePowerShellPermissionEvidenceEvaluator uses Exchange.ManageAsApp, last_checked_at, and scoped details with a hard-coded 30-day threshold.
  • Current ProviderCapabilityRegistry defines exchange_powershell_invoke with provider requirement keys provider.exchange_powershell_invocation and permissions.admin_consent.
  • Current ProviderCapabilityEvaluator has a stored Exchange permission fallback and hard-coded 30-day currentness behavior.

UI / Surface Guardrail Plan

  • Guardrail scope: existing provider capability/readiness status presentation only.
  • Affected routes/pages/actions/states/navigation/panel/provider surfaces: existing Provider Connection capability/readiness presentation, existing Environment Required Permissions provider-capability section, and existing verification-assist provider-capability presentation where they render provider capability/readiness output.
  • No-impact class, if applicable: no new route, page, component, navigation, action, asset, global-search behavior, report, dashboard, or customer surface is introduced.
  • Native vs custom classification summary: reuse existing Filament/Blade rendering and existing provider capability/readiness status vocabulary; do not add a runtime Product Surface framework.
  • Shared-family relevance: provider capability/readiness and OperationRun context; existing rendered provider-readiness family must remain canonical and redacted.
  • State layers in scope: credential evidence state, permission evidence state, combined readiness state, provider capability status, runner-gate blocker state, OperationRun context.
  • Audience modes in scope: internal operator/reviewer through existing provider readiness/capability surfaces; no customer/read-only claim surface.
  • Decision/diagnostic/raw hierarchy plan: default surfaces show only canonical readiness/capability result and safe high-level blocker labels. Raw credential details, permission details, provider payloads, OperationRun context, stdout/stderr, IDs used only for scope checks, and support diagnostics stay demoted from default views.
  • Raw/support gating plan: Raw credential material, raw permission payloads, raw provider payloads, and sensitive exception messages are forbidden from context/loggable output and default rendered surfaces.
  • One-primary-action / duplicate-truth control: no new primary action; provider capability and runner gate must consume the same readiness truth.
  • Handling modes by drift class or surface: status-only change on existing surfaces; any new UI file, route, or action requires spec/plan amendment before implementation continues.
  • Repository-signal treatment: Filament/provider panel file changes are out of scope unless the spec is amended. Service/provider binding changes are product-surface relevant when their output is rendered by existing surfaces.
  • Special surface test profiles: focused read-only browser smoke for existing provider capability/readiness surfaces.
  • Required tests or manual smoke: focused browser proof plus Human Product Sanity for the existing provider capability/readiness surfaces after implementation.
  • Exception path and spread control: none.
  • Active feature PR close-out entry: credential and permission evidence readiness guardrail, existing provider capability/readiness surfaces browser-checked, no new rendered UI surface introduced.
  • UI/Productization coverage decision: existing page/status presentation changed.
  • Coverage artifacts to update: implementation report only.
  • No-impact rationale: N/A - existing rendered provider readiness/capability surfaces are affected by evaluator output.
  • Navigation / Filament provider-panel handling: no panel/provider registration changes; Laravel panel providers remain in apps/platform/bootstrap/providers.php.
  • Screenshot or page-report need: focused browser screenshot/proof for the existing affected surfaces.

Product Surface Contract Plan

  • Product Surface Contract reference: docs/product/standards/product-surface-contract.md.
  • No-legacy posture: canonical addition/replacement only; no aliases, fallback readers, duplicate UI, hidden routes, or historical fixtures.
  • Page archetype and surface budget plan: existing provider readiness/capability surfaces; no new panel, table, action, or diagnostic drawer.
  • Technical Annex and deep-link demotion plan: OperationRun remains internal execution truth and is not customer proof. Raw evidence, credential details, permission details, provider diagnostics, and logs are not default-visible.
  • Canonical status vocabulary plan: reuse existing ProviderCapabilityStatus and provider-readiness vocabulary unless a new behavior-backed state passes proportionality review.
  • Product Surface exceptions: none.
  • Browser verification plan: focused read-only smoke for existing provider capability/readiness surfaces.
  • Human Product Sanity plan: required for existing provider readiness/capability status presentation.
  • Visible complexity outcome target: neutral-to-reduced; more truthful readiness without extra default-visible technical detail.
  • Implementation report target: specs/433-exchange-credential-permission-evidence-support/implementation-report.md.

Filament / Livewire / Deployment Posture

  • Livewire v4 compliance: repo baseline remains Livewire v4; no Livewire runtime code planned.
  • Panel provider registration location: no panel/provider change; Laravel panel providers remain in apps/platform/bootstrap/providers.php.
  • Global search posture: no Filament resource or global search behavior changed.
  • Destructive/high-impact action posture: no UI action added. Backend runner readiness remains read-only gating. Any live invocation remains controlled by existing Spec 432 gates and provider-run authorization.
  • Asset strategy: no assets; filament:assets is not required for this slice.
  • Testing plan: no pages/widgets/relation managers/actions are added; focused browser proof covers existing provider capability/readiness surfaces because evaluator output is rendered there.
  • Deployment impact: possible new fail-closed config key for permission currentness only; possible provider-agnostic migration only if existing metadata is insufficient. No queues, schedules, storage, assets, or browser build impact.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes.
  • Systems touched:
    • apps/platform/app/Services/TenantConfiguration/ExchangePowerShellCredentialReferenceResolver.php
    • apps/platform/app/Services/TenantConfiguration/ExchangePowerShellPermissionEvidenceEvaluator.php
    • apps/platform/app/Services/TenantConfiguration/ExchangePowerShellProductionRunner.php
    • apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInvocationGate.php
    • possible new ExchangePowerShellInvocationReadinessEvaluator.php
    • apps/platform/app/Support/Providers/Capabilities/ProviderCapabilityEvaluator.php
    • apps/platform/app/Support/Providers/Capabilities/ProviderCapabilityRegistry.php only if requirement keys/status behavior need adjustment
    • apps/platform/app/Models/ProviderCredential.php
    • apps/platform/app/Support/Providers/ProviderCredentialKind.php only if managed identity becomes first-class
    • apps/platform/app/Models/ManagedEnvironmentPermission.php
    • apps/platform/config/tenantpilot.php
  • Shared abstractions reused: provider credential/reference model, managed-environment permission rows, provider capability evaluator/registry, OperationRun lifecycle/context safety, Spec 432 runner gate.
  • New abstraction introduced? why?: A combined readiness evaluator may be introduced so provider capability and runner gate consume one evidence truth. This is justified by security/readiness correctness and avoids duplicated local checks.
  • Why the existing abstraction was sufficient or insufficient: Existing resolvers/evaluators already block many unsafe cases, but readiness is split between credential resolver, permission evaluator, provider capability fallback, and production runner. Spec 433 should remove drift and add missing evidence metadata/currentness/accessibility proof.
  • Bounded deviation / spread control: No generic provider readiness framework, no Exchange mini-platform, no UI pattern, no evidence writer, no customer-output path.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes, backend context safety only.
  • Central contract reused: existing Spec 432 invocation path and OperationRunService.
  • Delegated UX behaviors: N/A - no toast, run link, artifact link, browser event, queued DB notification, dedupe messaging, or surface-owned URL resolution.
  • Surface-owned behavior kept local: none.
  • Queued DB-notification policy: N/A.
  • Terminal notification path: unchanged central lifecycle mechanism.
  • Exception path: none.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes.
  • Provider-owned seams: Exchange PowerShell credential support, Exchange.ManageAsApp, Exchange invocation readiness, Exchange-specific blocker naming where bounded.
  • Platform-core seams: provider connection scope, credential-reference metadata, managed-environment permission evidence, provider capability, OperationRun context, currentness/source metadata, redaction.
  • Neutral platform terms / contracts preserved: provider connection, credential reference, permission evidence, currentness, observed/verified/source metadata, readiness, workspace, managed environment, blocker reason.
  • Retained provider-specific semantics and why: Exchange.ManageAsApp and Exchange PowerShell invocation are retained because this is an Exchange runner readiness spec, not a multi-provider abstraction.
  • Bounded extraction or follow-up path: document-in-feature. If evidence metadata proves generally useful, it must remain provider-agnostic. Content-backed evidence promotion remains Spec 434.

Constitution Check

  • Inventory-first: no inventory, snapshot, backup, or tenant configuration evidence truth is created.
  • Read/write separation: no provider writes, no Exchange calls, no PowerShell execution. Gating remains read-only local evaluation.
  • Graph contract path: no Graph calls are added and no Graph contract path changes.
  • Deterministic capabilities: exchange_powershell_invoke must be deterministically evaluated from readiness evidence and tested.
  • RBAC-UX: implementation must preserve workspace/environment entitlement and provider-run capability behavior from Spec 432; non-member/wrong scope 404; member missing capability 403 or repo-equivalent.
  • Workspace isolation: provider connection, credential reference, permission evidence, and readiness must all resolve within the same workspace.
  • Tenant/managed-environment isolation: environment-owned permission evidence must match managed_environment_id; provider connection must belong to the same environment.
  • OperationRun truth: OperationRun remains execution truth only and cannot become evidence/customer proof.
  • OperationRun context: safe readiness/blocker state only; no credential material, raw permission payload, raw provider output, or sensitive exceptions.
  • Ops-UX summary counts: no new summary count key expected. If one is unavoidable, update OperationSummaryKeys::all() and test.
  • Provider freshness semantics: stale permission evidence blocks and is not labeled ready.
  • Evidence anchor contract: no tenant configuration evidence rows or evidence anchors are created.
  • Product Surface Contract: applies because existing provider capability/readiness surfaces render changed evaluator output; no new UI surface is introduced.
  • Test governance: focused unit/feature tests; PostgreSQL lane if schema changes; focused browser lane for existing provider capability/readiness surfaces.
  • Proportionality: any new metadata, state, or evaluator must solve current safety risk and be narrower than a generic provider framework.
  • No premature abstraction: no generic PowerShell/provider readiness framework until more real cases require it.
  • Persisted truth: migration only if evidence metadata must outlive the originating run and cannot be safely represented today.
  • Behavioral state: each new state must block/allow execution, change capability support, drive audit/readiness proof, or protect redaction.
  • Provider boundary: provider-specific Exchange terms stay in provider-owned seams and do not become platform-core ownership truth.
  • Pre-production lean doctrine: replace ambiguous readiness behavior cleanly; no compatibility aliases or fallback readers.

Test Governance Check

  • Test purpose / classification by changed surface: Unit tests for pure readiness/evaluator behavior; Feature tests for provider capability, runner-gate integration, OperationRun context safety, no-promotion guards, and migration/no-migration proof.
  • Affected validation lanes: fast-feedback/confidence; PostgreSQL if migration/JSONB/index behavior changes; focused read-only browser proof for existing provider capability/readiness surfaces.
  • Why this lane mix is the narrowest sufficient proof: The change is evidence-readiness and local gate evaluation with no live provider calls; focused browser proof is needed because provider capability/readiness output is rendered by existing surfaces.
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec433 --compact
    • cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec432 --compact
    • selected Spec 431/430/426/427/417/419/420 and provider capability regressions
    • PostgreSQL lane if migration is added
    • focused read-only browser proof for existing provider capability/readiness surfaces
    • cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • git diff --check
  • Fixture / helper / factory / seed / context cost risks: workspace, managed environment, provider connection, provider credential, permission evidence, currentness thresholds, OperationRun context. Keep setup explicit and opt-in.
  • Expensive defaults or shared helper growth introduced?: no planned defaults.
  • Heavy-family additions, promotions, or visibility changes: focused browser proof for existing provider capability/readiness surfaces; PostgreSQL validation only if migration requires it.
  • Surface-class relief / special coverage rule: no new rendered surface, but existing rendered readiness status requires browser proof and Human Product Sanity.
  • Closing validation and reviewer handoff: implementation report must list exact commands, pass/fail counts, dirty state, and any safe residual conditions.
  • Budget / baseline / trend follow-up: none expected.
  • Review-stop questions: verify no Exchange call, no PowerShell execution, no evidence rows, no new UI, no trigger surface, no credential material, no raw permission payload, no tenant_id, no Exchange-specific table, no provider capability overclaim, and no raw details on existing provider readiness surfaces.
  • Escalation path: reject-or-split if implementation attempts content-backed capture, live invocation, UI/routes/jobs/schedules/listeners, customer output, broad metadata framework, or Exchange-specific persistence.
  • Active feature PR close-out entry: credential and permission evidence readiness guardrail with existing provider capability/readiness surfaces browser-checked and no new rendered UI surface introduced.
  • Why no dedicated follow-up spec is needed: Routine readiness hardening belongs in Spec 433. Content-backed Exchange evidence and customer output are separate later specs.

Project Structure

Documentation (this feature)

specs/433-exchange-credential-permission-evidence-support/
|-- spec.md
|-- plan.md
|-- tasks.md
|-- checklists/
|   `-- requirements.md
`-- implementation-report.md       # created by later implementation loop

Source Code (likely affected by later implementation)

apps/platform/app/Models/ProviderCredential.php
apps/platform/app/Models/ManagedEnvironmentPermission.php
apps/platform/app/Support/Providers/ProviderCredentialKind.php
apps/platform/app/Support/Providers/Capabilities/ProviderCapabilityEvaluator.php
apps/platform/app/Support/Providers/Capabilities/ProviderCapabilityRegistry.php
apps/platform/app/Services/TenantConfiguration/ExchangePowerShellCredentialReferenceResolver.php
apps/platform/app/Services/TenantConfiguration/ExchangePowerShellPermissionEvidenceEvaluator.php
apps/platform/app/Services/TenantConfiguration/ExchangePowerShellProductionRunner.php
apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInvocationGate.php
apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInvocationReadinessEvaluator.php
apps/platform/config/tenantpilot.php
apps/platform/tests/Unit/Support/TenantConfiguration/
apps/platform/tests/Feature/TenantConfiguration/
apps/platform/tests/Feature/Providers/

Possible migration files only if existing metadata is insufficient:

apps/platform/database/migrations/*_add_provider_credential_evidence_metadata.php
apps/platform/database/migrations/*_add_managed_environment_permission_evidence_metadata.php

Forbidden source changes:

apps/platform/routes/**
apps/platform/app/Filament/**
apps/platform/app/Livewire/**
apps/platform/resources/views/**
apps/platform/app/Jobs/**
apps/platform/app/Listeners/**
apps/platform/app/Console/**
customer report/review-pack/PDF output code
new Exchange-specific credential or permission tables
tenant_id ownership columns
legacy shim or fallback reader paths

Structure Decision: Use the existing TenantConfiguration service path and provider capability/readiness paths. Do not create a new Exchange subsystem or base folder without amending the spec.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
Combined readiness evaluator Capability and runner gate must share one readiness truth. Keeping separate local checks risks Supported capability while runner blocks, or runner pass while capability is unknown.
New credential/permission blocker states Each state changes execution/capability behavior and redaction/audit interpretation. Collapsing to unknown hides missing vs expired vs inaccessible vs wrong-scope safety conditions.
Possible provider-agnostic metadata migration Only if current fields cannot safely represent source/observed/verified/accessibility/currentness. Exchange-specific tables or free-form implicit details would deepen provider coupling or weaken query/audit safety.

Proportionality Review

  • Current operator problem: Prevent false readiness and unsafe live invocation for Exchange PowerShell before evidence capture is allowed.
  • Existing structure is insufficient because: Current code blocks many cases, but readiness is split across resolvers/evaluators and some evidence metadata is implicit or hard-coded.
  • Narrowest correct implementation: Refine existing provider credential, permission evidence, capability, and runner gate paths. Add one combined readiness result if needed.
  • Ownership cost created: Focused service/test surface and possible small provider-agnostic metadata upkeep.
  • Alternative intentionally rejected: Admin-consent-only support, client-secret support, Exchange-specific persistence, UI readiness labels, and evidence promotion.
  • Release truth: Current-release safety prerequisite for Spec 434.

Implementation Phases

Phase 0 - Preflight

  • Capture branch, HEAD, and dirty state.
  • Confirm Spec 432 implementation report remains PASS with no open merge-blocking runner safety findings.
  • Confirm current code paths for credential resolver, permission evaluator, capability evaluator, runner gate, credential model, permission model, and config.
  • Confirm no Exchange calls, PowerShell execution, evidence promotion, new UI, trigger surface, customer output, migration, or tenant_id is planned before the data-model decision.
  • Confirm the existing provider capability/readiness surfaces that render ProviderCapabilityEvaluator/registry output and will need focused browser proof after implementation.

Phase 1 - Data Model Decision

  • Inspect ProviderCredential, ProviderCredentialKind, ManagedEnvironmentPermission, current migrations, and current evaluator behavior.
  • Decide no-migration versus minimal provider-agnostic metadata migration.
  • If no migration, document how current fields/details safely represent accessibility, source, observed, verified, currentness, and scope, including the current managed_environment_id + permission_key uniqueness and provider-connection matching through details.
  • If no migration, prove nonmatching or missing details.provider_connection_id fails closed and no fallback-to-latest/admin-consent-only behavior exists.
  • If migration is required, stop runtime implementation and update spec.md plus this plan.md with exact fields, ownership semantics, constraints/indexes, rollback posture, and proportionality review before adding schema code.
  • After an approved migration amendment, add tests proving provider-agnostic fields, reversibility where practical, no secret material, no raw payloads, no Exchange-specific table, and no tenant_id.

Phase 2 - Credential Evidence

  • Extend or refactor ExchangePowerShellCredentialReferenceResolver to return explicit credential evidence states and safe context.
  • Keep client-secret blocked.
  • Add distinct inaccessible state only when observable from repo-owned fields or an approved metadata migration; otherwise collapse to a safe fail-closed state with tests.
  • Add wrong-scope/unvalidated/currentness states when supported by repo truth; do not invent fake precision from unavailable credential metadata.
  • Decide certificate support versus explicit safe block.
  • Decide federated support versus explicit safe block.
  • Decide managed identity support versus explicit safe block and whether a first-class enum case is warranted.
  • Add redaction tests for credential payloads, references, exception messages, and OperationRun/loggable output.

Phase 3 - Permission Evidence

  • Extend or refactor ExchangePowerShellPermissionEvidenceEvaluator to make Exchange.ManageAsApp source/currentness/scope metadata first-class enough for the gate.
  • Make currentness threshold configurable or explicitly justify/test the fixed 30-day threshold.
  • Enforce workspace, managed environment, provider connection, provider, status, source/observed/verified, and staleness rules.
  • Decide and test the current no-migration one-row-per-environment/permission-key behavior versus a spec-approved provider-connection-specific migration.
  • Preserve admin-consent-not-sufficient behavior.
  • Ensure manual/admin assertions cannot pass unless explicitly verified by repo policy and tested; default fail-closed.

Phase 4 - Combined Readiness

  • Add ExchangePowerShellInvocationReadinessEvaluator or repo-canonical equivalent if needed.
  • Require credential readiness and permission evidence readiness.
  • Return safe pass/blocker states with no raw material.
  • Ensure ProviderCapabilityEvaluator and ExchangePowerShellProductionRunner use the same readiness truth or equivalent shared result.

Phase 5 - Provider Capability Integration

  • Update provider capability evaluation so exchange_powershell_invoke is Supported only when combined readiness passes.
  • Prove admin consent, client secret, missing credential, missing permission, stale permission, wrong-scope permission, unsupported provider, and unknown evidence do not produce Supported.
  • Keep capability status values within existing ProviderCapabilityStatus unless a new status has a direct behavioral need and proportionality review.
  • Record the expected rendered impact on existing provider capability/readiness surfaces and keep default output canonical/redacted.

Phase 6 - Runner Gate Integration

  • Wire Spec 432 runner gate to combined readiness before runtime/process execution.
  • Store only safe readiness/blocker state in OperationRun context.
  • Do not create a new OperationRun type unless explicitly justified; current expectation is reuse tenant_configuration.exchange_powershell_invocation.
  • Preserve disabled default and production-runner config gates from Spec 432.

Phase 7 - No-Promotion and Surface Guard

  • Add tests/guard scans proving no tenant configuration evidence rows, raw/normalized Exchange payloads, content-backed/comparable/renderable/certified/restore/customer states, new UI/routes/assets/global search, jobs/schedules/listeners, Exchange-specific tables, legacy shims, fallback readers, or tenant_id.
  • Add product-surface guard proof that existing provider readiness/capability surfaces do not show raw credential, permission, provider, OperationRun, stdout/stderr, or scope-diagnostic payloads by default.

Phase 8 - Validation and Report

  • Run focused Spec 433 tests.
  • Run Spec 432/431/430 and selected no-promotion/provider regressions.
  • Run migration/PostgreSQL lane if schema changes.
  • Run focused browser proof and Human Product Sanity for existing provider capability/readiness surfaces.
  • Run Pint and git diff --check.
  • Create implementation report with matrices for credential kinds, permission evidence, migration/no-migration, no-promotion, validation, deployment impact, Product Surface proof, browser/Human Product Sanity result, and no completed-spec rewrite proof.

Rollout and Deployment Considerations

  • No runtime enablement is planned by this spec. Existing production-runner feature flags remain disabled by default.
  • If a permission-currentness config key is added, default it fail-closed or preserve existing 30-day behavior with explicit tests.
  • If migration is added, it must be safe for staging validation and must not add secret material, raw payloads, Exchange-specific tables, or tenant_id.
  • No queue, scheduler, storage, asset, browser build, or filament:assets deployment impact is expected.
  • Dokploy staging must validate any migration/config change before production.

Risk Controls

  • Hard stop if client-secret credentials can pass Exchange PowerShell readiness.
  • Hard stop if admin consent alone makes exchange_powershell_invoke Supported.
  • Hard stop if stale, missing, unvalidated, or wrong-scope permission evidence passes.
  • Hard stop if credential material or raw permission/provider payloads enter context, logs, tests, or persisted metadata.
  • Hard stop if Exchange provider calls, PowerShell execution, evidence rows, new UI/routes/jobs/schedules/listeners, customer output, Exchange-specific tables, or tenant_id are introduced.
  • Hard stop if existing rendered provider capability/readiness surfaces are changed without the Product Surface proof, browser proof, and Human Product Sanity required by this plan.