# Contracts — Verification Surfaces Unification (Spec 084) This document describes the user action surfaces and canonical linking rules. ## Canonical run link - Canonical run viewer route: `/admin/operations/{runId}` - Helper: `OperationRunLinks::tenantlessView($runId)` Rule: - All verification surfaces MUST link to the canonical tenantless viewer. - Tenantless run viewing MUST still enforce: - workspace membership AND - tenant entitlement (when the run is tenant-associated) Missing either MUST be deny-as-not-found (404). ## Start surfaces ### Tenant detail — “Verify configuration” - Trigger: Filament action on tenant view page. - Behavior: - Authorize capability. - Start/dedupe `OperationRun` with `type = provider.connection.check`. - Dispatch `ProviderConnectionHealthCheckJob` when newly created. - Notify with “View run” (canonical URL). ### Onboarding — “Verify access” - Trigger: Filament wizard action. - Behavior: - Authorize onboarding capability. - Start/dedupe the same run type. - Notify with “View run” (canonical URL). ## Viewer surfaces (DB-only) ### Tenant embedded viewer - Select latest `provider.connection.check` run attempt for the tenant. - States: - Empty (no run yet): shows “Start verification” CTA. - In progress (active run; no report yet): shows DB-only in-progress UI. - Completed: shows stored `verification_report`. ### Operations run viewer - Uses `OperationRun` as the source of truth. - Verification report rendered from `context.verification_report` only. ## Blocked completion invariant For `provider.connection.check` runs: - If the run is completed with outcome `blocked`, `context.verification_report` MUST exist and be schema-valid. - Viewers MUST NOT fabricate a report at render time.