fix(#2736): write current_phase_name from the transition intent, not the lossy prose round-trip (#2821)
* fix(#2736): intent-first current_phase_name on transitions; dash-first prose precedence Primary: completePhase (adapter) and beginPhase (via readModifyWriteStateMd options) pass the intent-held display name to syncStateFrontmatter as an authoritative override, applied after every derive/preserve/carry-forward step — so the lossy prose round-trip can never destroy a name the transition just resolved. Names containing a parenthetical (`Closer-ruling measurement (D1a)`) now land in frontmatter verbatim instead of collapsing to the parenthetical (`D1a`). Secondary (#1695 AC #3 residual): parsePhaseFromProse prefers the em-dash name when it is a genuine name (not a status keyword, not a `Milestone:` tail), else falls back to the parenthetical — satisfying both first-party writer shapes (`N — Name (aside)` and `N (Name) — EXECUTING`). Still lossy for paren-containing names, which is why the intent-first override is the primary fix. plannedPhase carries no name in its intent, so it is naturally out of scope. Fixes #2736 * docs(changeset): backfill PR number for #2736 fragment * fix(#2736): drop an unnecessary type assertion on result.data StateTransitionResult.data is already `Record<string, unknown> | undefined`, so the cast was a no-op and tripped @typescript-eslint/no-unnecessary-type- assertion (CI lint-tests red on the first push; every test lane was green). --------- Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
@@ -2456,7 +2456,15 @@ function cmdPhaseComplete(cwd: string, phaseNum: string, raw: boolean): void {
|
||||
planCount,
|
||||
summaryCount,
|
||||
);
|
||||
stateContent = syncStateFrontmatter(stateContent, cwd);
|
||||
// #2736: the transition holds the next phase's exact display name in
|
||||
// the intent; pass it as authoritative so the sync's prose
|
||||
// re-derivation cannot rewrite current_phase_name to the name's own
|
||||
// parenthetical (`Closer-ruling measurement (D1a)` → `D1a`).
|
||||
stateContent = syncStateFrontmatter(
|
||||
stateContent,
|
||||
cwd,
|
||||
nextPhaseDisplayName ? { current_phase_name: nextPhaseDisplayName } : undefined,
|
||||
);
|
||||
|
||||
writes.push({ filePath: statePath, before: originalStateContent, after: stateContent });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user