/** * @deprecated Use the `superblocks.policy-gates.security-scans.enabled` LaunchDarkly flag instead. * Kept as `false` to match the fail-closed LD default; create and enable the * LD flag to turn built-in scans on. */ export const SECURITY_SCANS_ENABLED: boolean = false; export type PolicyGateReadinessAction = | 'contact_admin' | 'fix_with_clark' | 'request_approval' | 'request_suppression' | 'rerun_gate' | 'view_report' | 'wait'; export type PolicyGateReadinessFindingSummary = { advisory: number; // Non-blocking findings whose severity holds publish (excludes info). advisoryHold?: number; approvalRequired: number; blocking: number; suppressed: number; }; export type PolicyGateReadinessFinding = { blocking: boolean; humanSummary?: string | null; locationsJson?: unknown[]; remediationHintJson?: Record; severity: 'critical' | 'high' | 'info' | 'low' | 'medium'; technicalSummary?: string | null; title: string; }; export type PolicyGateScanPhaseName = 'built_asset' | 'dependency_audit' | 'source'; export type PolicyGateScanPhaseState = 'complete' | 'failed' | 'pending' | 'running' | 'skipped'; export type PolicyGateScanPhaseProgress = { completedAt?: string; durationMs?: number; startedAt?: string; state: PolicyGateScanPhaseState; }; export type PolicyGateScanProgress = { phases: Partial>; requiredPhases: PolicyGateScanPhaseName[]; }; export type PolicyGateReadinessItem = { actions: PolicyGateReadinessAction[]; displayName?: string; findings?: PolicyGateReadinessFinding[]; /** Optional provider/scanner logo (data URI or URL) shown next to the item. */ iconSrc?: string; findingSummary: PolicyGateReadinessFindingSummary; itemId: string; itemType: 'security_agent' | 'security_scan'; mode: 'advisory' | 'approval' | 'blocking' | 'report_only'; policyId: string; policyVersionId: string; progress?: PolicyGateScanProgress; reviewRunId?: string; runs?: PolicyGateReadinessRun[]; staleReason?: string; status: PolicyGateReadinessItemStatus; }; export type PolicyGateReadinessRun = { completedAt?: string; createdAt?: string; decision: 'advisory_allowed' | 'allowed' | 'blocked' | 'error_blocked' | 'not_applicable' | null; errorCode?: string; errorMessage?: string; findingSummary: PolicyGateReadinessFindingSummary; reviewRunId: string; startedAt?: string; staleReason?: string | null; status: PolicyGateReadinessItemStatus; }; export type PolicyGateReadinessItemStatus = | 'advisory_findings' | 'approval_required' | 'blocked' | 'failed' | 'missing' | 'passed' | 'running' | 'stale'; export type PolicyGateReadinessResponse = { items: PolicyGateReadinessItem[]; status: PolicyGateReadinessStatus; target: PolicyGateReadinessTarget; }; export type PolicyGateReadinessStatus = 'allowed' | 'approval_required' | 'blocked' | 'disabled' | 'failed' | 'running' | 'stale'; export type PolicyGateReadinessTarget = { applicationId: string; commitId: string; directoryContentsHash: string | null; }; /** * Stable error code used in BadRequestError messages when a deploy is rejected * due to unresolved policy gate findings. Both server and client reference this * constant so the contract doesn't rely on fragile string matching. */ export const POLICY_GATE_BLOCKED_ERROR = 'POLICY_GATE_BLOCKED'; /** * User-facing message returned when a deploy is rejected because a dev-server * policy gate has not yet run against the version being deployed and the * current live edit state no longer matches that version. The dev-server scan * evaluates the live edit working tree, so running it for the first time * against a divergent live edit would review the wrong code. Surfaced directly * to the user, and shared so server and client agree on the exact text. */ export const POLICY_GATE_STALE_LIVE_EDIT_ERROR = 'Policy gates can only run for the current app state. Deploy the current changes or restore to this commit and then deploy.';