/* * ⟨q-fee7239f⟩ — A CLOSING LINE STATES AN ARTEFACT IT HAS NOT READ. * * Measured 2026-09-14 in one clock: #318 merged 18:12:42Z · "Remote branch * deleted" posted 18:12:53.626Z · head_ref_deleted 18:13:27Z — the claim * preceded its artefact by 33.4s; #319 by 61.7s. Then qa re-read * `git ls-remote --heads origin` after #321 and withdrew the same line for * FIVE merges (#309 #311 #315 #317 #321) where the remote was NEVER deleted: * `gh --delete-branch` had not deleted the remote when the local delete * errored, and the closing line reported THE FLAG IT PASSED rather than the * remote it never read. A closing line already verifies the squash by content; * the ref gets the same rule. The grammar admits exactly two forms for a * deletion: a post-delete observation — `remote ref read: 0 refs at ` — * or the weaker `delete requested`, which claims no state. A closing that * asserts deletion in any other wording is refused at the send, by the same * check that requires a DONE to cite its PR, naming both forms. * * Dated adoption floor: qa's 18:36:30.939Z message — "From here every closing * line reads the remote before claiming a delete". Closings at or before it * are LISTED, never raised. */ export const CLOSING_GRAMMAR_ADOPTED_MS = 1789410990939; // 2026-09-14T18:36:30.939Z /** A merge-closing line: a `done` whose text says MERGED. */ export const isMergeClosing = (text: string): boolean => /\bMERGED\b/.test(text); /** * A deletion CLAIM is a statement, read by POSITION: the wording at the start * of a sentence. The same words quoted mid-sentence — qa's own correction says * `My "remote branch deleted" lines … were wrong` — are a mention, not a claim. */ export const DELETE_CLAIM = /(?:^|[.;!]\s+|\n\s*)(?:(?:Remote|Local and remote|Remote and local) (?:branch|ref) deleted|Deleted the remote (?:branch|ref))\b/; /** The observation form: what `git ls-remote --heads origin ` returned, and when. */ export const REMOTE_READ = /remote ref read:\s*(\d+)\s*refs?\s+at\s+(\S+?)(?=[.;,)]?(?:\s|$))/i; /** The weaker form: a command was issued; the state is left unclaimed. */ export const DELETE_REQUESTED = /\bdelete requested\b/i; export const ACCEPTED_FORMS = "`remote ref read: 0 refs at ` (an `ls-remote` observation taken AFTER the delete) or `delete requested` (a command issued; state unclaimed)"; export type ClosingLine = { merged: boolean; claimsDelete: boolean; form: "read" | "requested" | null; read?: { refs: number; at: string }; }; export function closingLineOf(text: string): ClosingLine { const merged = isMergeClosing(text); const claimsDelete = DELETE_CLAIM.test(text); const r = REMOTE_READ.exec(text); const form: ClosingLine["form"] = r ? "read" : DELETE_REQUESTED.test(text) ? "requested" : null; return { merged, claimsDelete, form, ...(r ? { read: { refs: Number(r[1]), at: r[2]! } } : {}) }; } /** The refusal: a merge closing that asserts deletion without either accepted form. */ export function checkClosingLine(text: string): { ok: true; closing: ClosingLine } | { ok: false; error: string; closing: ClosingLine } { const closing = closingLineOf(text); if (closing.merged && closing.claimsDelete && closing.form === null) { return { ok: false, closing, error: `a merge-closing line asserts a branch deletion it has not shown it read — "Remote branch deleted" reports a flag passed, not a remote observed (2 of 2 measured were premature, 5 of 7 were false). ` + `State the deletion in one of the two accepted forms: ${ACCEPTED_FORMS}.`, }; } return { ok: true, closing }; } export type Closing = { pr: number | null; from: string; ts: number; claimsDelete: boolean; form: ClosingLine["form"]; beforeAdoption: boolean }; /** Every merge closing in a log, judged; `beforeAdoption` for those at or before the floor. */ export function closingsIn(logText: string, floorMs: number = CLOSING_GRAMMAR_ADOPTED_MS): Closing[] { const out: Closing[] = []; for (const l of logText.split("\n")) { if (!l.trim()) continue; let o: { ts?: number; from?: string; text?: string; record?: { type?: string; cites?: { ref?: string }[] } }; try { o = JSON.parse(l); } catch { continue; } if (o.record?.type !== "done") continue; const text = String(o.text ?? ""); const c = closingLineOf(text); if (!c.merged) continue; const cited = (o.record.cites ?? []).map((x) => (String(x?.ref ?? "").match(/#(\d+)/) ?? [])[1]).find(Boolean); const inText = (text.match(/MERGED[^\n]*?#(\d+)/) ?? [])[1]; const pr = cited ?? inText; const ts = Number(o.ts ?? 0); out.push({ pr: pr ? Number(pr) : null, from: String(o.from ?? ""), ts, claimsDelete: c.claimsDelete, form: c.form, beforeAdoption: ts <= floorMs }); } return out.sort((a, b) => a.ts - b.ts); }