From b7b6f89776ca91cda5efd31ca017fd767a0a2aea Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 26 Apr 2026 11:46:40 -0400 Subject: [PATCH] fix(phase-lifecycle): fast-path replaceInCurrentMilestone only when pattern matches after The previous guard `if (after.trim().length > 0)` incorrectly triggered when `after` contained only footer text (e.g. `---\n*Last updated*`). In that case `after.replace(pattern, replacement)` is a no-op and the function returned unchanged content instead of falling through to the slow path that searches inside the last `
` block. Fix: capture the replaced string first, then only take the fast path when the replacement actually changed `after`. Co-Authored-By: Claude Sonnet 4.6 --- sdk/src/query/phase-lifecycle.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/src/query/phase-lifecycle.ts b/sdk/src/query/phase-lifecycle.ts index 48620dbd1..dba30143f 100644 --- a/sdk/src/query/phase-lifecycle.ts +++ b/sdk/src/query/phase-lifecycle.ts @@ -111,8 +111,9 @@ export function replaceInCurrentMilestone( // Fast path: the current milestone is not inside a
block — the // pattern lives in the plain text after the last
. - if (after.trim().length > 0) { - return before + after.replace(pattern, replacement); + const replacedAfter = after.replace(pattern, replacement); + if (replacedAfter !== after) { + return before + replacedAfter; } // Slow path: the active milestone is inside the last
block.