// The CHANGELOG section of the plan_version 1.9 / converging critic loop // delivery, found by its title. Before the release its heading is // `## Unreleased — `; the release commit makes it // `## vX.Y.Z — <date> — <title>` (docs/release-runbook.md § 1.4). The section // is found wherever it stands, so a later delivery's section above it does not // move the pins, and it must stand exactly once. import assert from 'node:assert/strict'; export const SECTION_TITLE = 'plan_version 1.9, the trial-4 findings, session-clean tests, the converging critic loop'; const escaped = SECTION_TITLE.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); export const SECTION_HEADING = new RegExp(`^## (?:Unreleased|v\\d+\\.\\d+\\.\\d+ — \\d{4}-\\d{2}-\\d{2}) — ${escaped}$`); // A heading line as written, without a trailing `\r` or trailing spaces. const bare = line => line.replace(/\s+$/, ''); // { heading, body } of the delivery's section in CHANGELOG text, up to the // next `## ` heading. Fails unless exactly one heading matches. export function deliverySection(text) { const lines = text.split('\n'); const at = []; lines.forEach((l, i) => { if (SECTION_HEADING.test(bare(l))) at.push(i); }); assert.equal(at.length, 1, `CHANGELOG.md has the "${SECTION_TITLE}" section exactly once (found ${at.length})`); const start = at[0]; let end = lines.length; for (let i = start + 1; i < lines.length; i++) { if (/^## /.test(lines[i])) { end = i; break; } } return { heading: bare(lines[start]), body: lines.slice(start + 1, end).join('\n') }; }