/** * Repo merge-config posture assertion for the auto-close enforcement seam * (mmnto-ai/totem#1762, E-lever addendum — strategy-claude 2026-07-21T0235Z; the * squash-only extension — codex supplement 2026-07-21T0356Z). * * The operator flipped all four governed repos to * `squash_merge_commit_title: PR_TITLE` + `squash_merge_commit_message: BLANK` * (executed 2026-07-21T02:30Z). BLANK stops GitHub composing a squash body from * COMMIT_MESSAGES, so the server-composed close-keyword channel is gone; PR_TITLE * makes the squash subject deterministically the PR title (a surface D1 already * scans pre-merge). * * D1 also asserts SQUASH-ONLY (`allow_squash_merge` on, `allow_merge_commit` and * `allow_rebase_merge` off). This is what LICENSES D2's single-HEAD, `(#N)`-subject * assumption: a rebase merge pushes several commits (an earlier close-keyword * commit would never be scanned when only the final SHA is read), and a regular * merge commit need not carry the squash-subject form (breaking receipt * correlation). Enabling squash-only is an OPERATOR settings action (routed * separately, like the E lever); until flipped, D1 reds loudly by design. * * A repo setting is one careless settings-page click from silently reverting — so * D1 ASSERTS the whole posture at workflow start and fails loud on drift (Tenet 4 * parity-test rule applied to repo config; a "keep it set" intention is not a * coupling mechanism). Candidate standing row for the mmnto-ai/totem-strategy#482 * parity manifest. * * Pure evaluator — thin GraphQL glue lives in the D1 script. The source is * GraphQL (`squashMergeAllowed` / `mergeCommitAllowed` / `rebaseMergeAllowed` / * `squashMergeCommitTitle` / `squashMergeCommitMessage`), NOT the REST repos * endpoint: REST omits the merge-policy fields for callers without admin * visibility, and the Actions `GITHUB_TOKEN` is such a caller — discovered on * D1's first live run, where a healthy posture read as all-absent. That failure * class gets its own verdict (`unverifiable`) so a token-visibility problem is * never misreported as settings drift. */ /** The required squash-merge posture (the E lever). */ export declare const REQUIRED_SQUASH_MERGE_TITLE = "PR_TITLE"; export declare const REQUIRED_SQUASH_MERGE_MESSAGE = "BLANK"; /** The repo-config fields the posture assertion reads (absent/null = not visible). */ export interface MergeConfigPosture { squash_merge_commit_title?: string | null; squash_merge_commit_message?: string | null; allow_squash_merge?: boolean | null; allow_merge_commit?: boolean | null; allow_rebase_merge?: boolean | null; } /** * Verdict class: `drift` = a field is PRESENT and wrong (settings action needed); * `unverifiable` = no field is wrong but at least one is absent from the config * source (token-visibility failure — do NOT touch settings on this verdict). */ export type MergeConfigStatus = 'conforms' | 'drift' | 'unverifiable'; /** Verdict of {@link evaluateMergeConfigPosture}. */ export interface MergeConfigVerdict { /** True iff every field is present AND matches the required posture. */ conforms: boolean; status: MergeConfigStatus; /** Human-readable descriptions of each present-and-wrong field. */ drift: string[]; /** Field names the config source did not carry (token-visibility class). */ absent: string[]; /** Precise operator-facing message for the job log. */ message: string; } /** * Evaluate whether a repo's merge config matches the required posture: the * E-lever squash-body shape (`PR_TITLE` + `BLANK`) AND squash-only (`allow_squash_ * merge` on, merge-commit and rebase off). Returns the drift set (one entry per * off-posture field) and a precise message; the caller fails the check when * `!conforms`. */ export declare function evaluateMergeConfigPosture(config: MergeConfigPosture): MergeConfigVerdict; //# sourceMappingURL=merge-config.d.ts.map