fix(markdown-renderer): collapse 3+ consecutive newlines in slice plan
Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions

Task descriptions in slice plans sometimes contained double-blanks
(model emits multi-paragraph content with its own paragraph padding,
which survives normalizeMarkdownBlockSpacing's heading-only padding
logic). The double blanks tripped MD012/no-multiple-blanks in
pre-execution checks and blocked the autonomous loop at the
execute-task phase.

Live observation today: SF iter2 completed research-slice and
plan-slice for M006/S01 cleanly, then pre-execution checks failed on
the generated S01-PLAN.md with two MD012 violations at lines 99-100
and 126-127 (both inside task description paragraphs). SF paused
"Autonomous mode paused (Escape)" awaiting user — autonomous loop
stalled.

auto_fix_check_failures: true in prefs should have handled this but
doesn't run for files under .sf/milestones/ (separate bug worth
filing). Fix at source: collapse runs of 3+ newlines to 2 in the
final rendered slice plan. Surgical, no semantic change, defensive
against future model-quirks too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikael Hugo 2026-05-16 21:40:52 +02:00
parent 6f4728bdbd
commit 767c499d9a

View file

@ -587,7 +587,14 @@ function renderSlicePlanMarkdown(slice, tasks, gates = []) {
}
}
lines.push("");
return `${lines.join("\n").trimEnd()}\n`;
// Collapse 3+ consecutive newlines down to 2. Task descriptions sometimes
// contain double blanks (model-emitted multi-paragraph content + paragraph
// padding) that survive normalizeMarkdownBlockSpacing's heading-only logic.
// Without this, the rendered S0?-PLAN.md trips MD012/no-multiple-blanks in
// pre-execution checks and blocks the autonomous loop at execute-task.
// auto_fix_check_failures was supposed to handle this but doesn't run for
// .sf/milestones/ files — quicker to emit clean markdown at the source.
return `${lines.join("\n").trimEnd()}\n`.replace(/\n{3,}/g, "\n\n");
}
export async function renderPlanFromDb(basePath, milestoneId, sliceId) {
const slice = getSlice(milestoneId, sliceId);