// A branch's protection (novox/hq ADR 0237): what makes a pull request wait for the mesh's merge check — // `mesh/merge-gate`, the module graph's gate, and `mesh/repo-check`, the repository's own tests — before it // may merge. Pure, so it is tested without a forge; the client does the asking (client.ts). /** A branch protection rule, as the forge keeps it — the fields the mesh reads; the forge sends more. */ export interface BranchProtection { rule_name?: string; branch_name?: string; enable_push?: boolean; enable_status_check?: boolean; status_check_contexts?: string[] | null; required_approvals?: number; block_admin_merge_override?: boolean; [field: string]: unknown; } /** What a branch's protection is set to. A field not given is left as the rule has it (or the forge's * default on a new rule), except pushes, which a new rule refuses unless `push` says otherwise. */ export interface ProtectionWanted { /** The statuses a pull request must have succeeded before it merges, e.g. mesh/merge-gate. Empty: none. */ statusChecks: string[]; /** Whether a person may push to the branch directly. */ push?: boolean; /** Whether an administrator is stopped from merging past a status that has not succeeded. */ blockAdminOverride?: boolean; } /** The forge's body for a wanted protection. */ export function protectionBody(want: ProtectionWanted, creating: boolean): Record { const checks = [...new Set(want.statusChecks.map((c) => c.trim()).filter(Boolean))]; const body: Record = { enable_status_check: checks.length > 0, status_check_contexts: checks }; if (want.push !== undefined) body.enable_push = want.push; else if (creating) body.enable_push = false; if (want.blockAdminOverride !== undefined) body.block_admin_merge_override = want.blockAdminOverride; return body; }