Skip to content

bug(state): a quoted STATE.md milestone gains an escape layer in state.json on every state.* write (split from #4998) #5246

Closed as not planned

Description

@behruznassre

Split out of #4998 at the maintainer's request in the #5234 review: this issue covers only the issue's first half, the milestone escaping. The record-session half (orphaned tail line of a wrapped value, stopped_at replacement, the added **Stopped at:** line) stays on #4998.

Pre-submission checklist

GSD Version

next @ 13d37238b (1.16.0); originally reported on 1.14.0 in #4998

Runtime

Claude Code

Operating System

macOS

Node.js Version

v24.19.0

Installation Method

Source checkout of next (npm run build:lib)

What happened?

A milestone: value that YAML has to double-quote (one containing a literal ") is read back from STATE.md as its on-disk YAML text, quotes and backslashes included, and that text is written into state.json as the value. Every state.* write adds one more escape layer.

Root cause: three readers in src/roadmap-parser.cts (extractCurrentMilestoneScoped, getMilestoneInfo, currentMilestoneRawRanges) match ^milestone:\s*(.+) against the raw file text instead of reading the frontmatter parser's decoded value.

What did you expect?

state.json carries the decoded milestone value ("v1.1 — Example milestone", including its literal quotes), unchanged across writes.

Steps to reproduce

  1. STATE.md frontmatter contains milestone: "\"v1.1 — Example milestone\"".
  2. Run gsd-tools query state.begin-phase --phase 3 --name Example --plans 2.
  3. state.json now has "milestone": "\"\\\"v1.1 — Example milestone\\\"\"". That is the YAML source text, not the value.

On next I could not reproduce STATE.md's own frontmatter growing (#4998 reported that on 1.14.0). begin-phase, add-decision, record-metric, record-session and state sync, three rounds each, left it byte-identical. The state.json symptom reproduces every time.

How often does this happen?

Every time (100% reproducible)

Impact

Minor — Cosmetic or edge case

Additional context

Fix in #5234: the three readers go through rawFrontmatterField (the frontmatter parser's decoded value, FAILSAFE schema).

Privacy Checklist

  • I have reviewed all pasted output for PII (usernames, paths, API keys) and redacted where necessary

Activity

  1. added 2 commits that reference this issue on Oct 7, 2026
  2. behruznassre commented on Oct 7, 2026

    @behruznassre
    ContributorAuthor

    Superseded: at review the maintainer asked for both halves of #4998 to be fixed in #5234, which is back to Fixes #4998. This split-out issue is no longer needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageNew issue awaiting maintainer review

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions