* fix(#4469): anchor beginPhaseCore's focusPattern regex to line start focusPattern (src/state-transition.cts, beginPhaseCore's first-time- execution branch) rewrites the **Current focus:** body line via a regex with no line anchor and \s* (crosses newlines) instead of a same-line whitespace class -- the same defect class already fixed for a different function, stateReplaceField, in #4243/PR #4453. A bold **Current focus:** quoted mid-sentence anywhere in the body (e.g. an Accumulated Context bullet documenting the field) matched first and had the rest of its line silently overwritten with the new focus label -- the #4010 data-loss class, applied to a different field. Anchored using the exact same idiom PR #4453 established: ^([ \t]*\*\*Current focus:\*\*[ \t]*)(.*)$ with the /m flag. [ \t]* (not \s*) avoids consuming the newlines before the label into the match; $ documents the match ends at end-of-line. Added a regression test to tests/state-transition.test.cjs: a body with NO real **Current focus:** field yet present, but a mid-sentence prose mention of the same bold text in an Accumulated Context bullet -- proving the unanchored pattern would corrupt the prose (empirically verified via direct node -e execution before wiring the test) while the anchored pattern's .test() correctly returns false and leaves it untouched. stateReplaceProgressPercent's bold branch (~line 51-71) is explicitly NOT touched -- the issue itself flags it as entangled with the recorded #2177 form-priority decision, needing a maintainer call. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(#4469): backfill changeset PR number Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: sim <sim@local> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1252,7 +1252,17 @@ function beginPhaseCore(
|
||||
const focusLabel = intent.phaseName
|
||||
? `Phase ${intent.phaseNumber} — ${intent.phaseName}`
|
||||
: `Phase ${intent.phaseNumber}`;
|
||||
const focusPattern = /(\*\*Current focus:\*\*\s*).*/i;
|
||||
// #4469: anchored to line start with same-line whitespace only, mirroring
|
||||
// #4243/PR #4453's fix to stateReplaceField's bold branch. The pre-fix
|
||||
// pattern carried no `^`/`m` and used `\s*` (crosses newlines), so a bold
|
||||
// `**Current focus:**` quoted mid-sentence elsewhere in the body (e.g. an
|
||||
// Accumulated Context bullet) matched first and had the rest of its line
|
||||
// silently overwritten with the new focus label -- the same #4010
|
||||
// data-loss class. `[ \t]*` (not `\s*`) avoids consuming the newlines
|
||||
// before the label into the match; `$` documents the match ends at
|
||||
// end-of-line (inert here since `.` never crosses line terminators
|
||||
// without `/s`, which is not set).
|
||||
const focusPattern = /^([ \t]*\*\*Current focus:\*\*[ \t]*)(.*)$/im;
|
||||
if (focusPattern.test(body)) {
|
||||
body = body.replace(focusPattern, (_match, prefix: string) => `${prefix}${focusLabel}`);
|
||||
updated.push('Current focus');
|
||||
|
||||
Reference in New Issue
Block a user