Found by the #1021 comment-preservation proof (PR #1067). Blocks Y-2 (yq for writing) in 3-practice/YAML-POLICY.adoc.
Repro — bd9313a6, yq v4.53.3
cp .github/workflows/tag-ruleset-canon.yml /tmp/t.yml
yq -i . /tmp/t.yml; cp /tmp/t.yml /tmp/p1.yml
yq -i . /tmp/t.yml; diff /tmp/p1.yml /tmp/t.yml # non-empty
What moves
Original (lines 46–63): two comment paragraphs separated by a blank line, both before the Mint… step:
- uses: actions/checkout@3d3c42e5… # v7.0.1
# WHICH App's credentials belong in vars.APP_ID / secrets.APP_PRIVATE_KEY:
# … (10 lines, the R-14 App-identity rationale)
# An App installation token is scoped to ONE owner …
- name: Mint an App installation token for hyperpolymath
id: tok-user
Pass 1 keeps both before the step (comment-clean). Pass 2 moves the R-14 block inside the step, between name: and id::
oracle: jobs/converge/steps/1/name (before) → jobs/converge/steps/1/id (before) — 10 comments.
The same drift occurs under a realistic edit (yq -i pin bump). yq -o kyaml does not drift on this file (56/56 idempotent).
Candidate cause, not investigated: go-yaml v3 head/foot comment reattribution around blank lines.
Acceptance criteria
🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo
Found by the #1021 comment-preservation proof (PR #1067). Blocks Y-2 (yq for writing) in
3-practice/YAML-POLICY.adoc.Repro —
bd9313a6, yq v4.53.3What moves
Original (lines 46–63): two comment paragraphs separated by a blank line, both before the
Mint…step:Pass 1 keeps both before the step (comment-clean). Pass 2 moves the R-14 block inside the step, between
name:andid::oracle:
jobs/converge/steps/1/name (before)→jobs/converge/steps/1/id (before)— 10 comments.The same drift occurs under a realistic edit (
yq -ipin bump).yq -o kyamldoes not drift on this file (56/56 idempotent).Candidate cause, not investigated: go-yaml v3 head/foot comment reattribution around blank lines.
Acceptance criteria
bun prove.js .github/workflows/*.yml(tools/yaml-comment-proof) reports pass-2 drift 0 and idempotent 56/56 for theidentityandpin-bumparms — by a yq version, flag, or wrapper that achieves it; or🤖 Generated with Claude Code
https://claude.ai/code/session_01WPSJ7fBhVAMcpSffCBWUDo