fix(#4725): write normalization preserves tight paragraph-list shape (#4842)

* test(#4725): write normalization must not reflow untouched prose (failing first)

* fix(#4725): stop write normalization injecting a blank before a list after prose

* test(#4725): repair ordered-list fixture and list-spacing snapshot

* test(#4725): assert whole-file prose stability, fix heading-list comment

* chore(#4725): backfill changeset PR number (4842)

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-18 01:38:14 -04:00
committed by GitHub
parent c9a5cc3e12
commit 8d0b6868ae
6 changed files with 222 additions and 18 deletions

View File

@@ -969,6 +969,54 @@ describe('roadmap update-plan-progress command', () => {
assert.ok(roadmapContent.includes('1/2'), 'roadmap should contain updated plan count');
});
test('#4725: leaves surrounding prose byte-identical (bold paragraph above a tight list)', () => {
const fixture = [
'# Roadmap',
'',
'### Phase 654: Stream Consumer',
'',
'**Goal:** bind the evidence HMAC key in production',
'',
'**Scope narrowed 2026-09-14, round `663-DISPOSITION` Q7 (3/3)** (`.planning/decisions/663-disposition.md`):',
'- The "for retry" javadoc correction moved to Phase 663',
'- Per Q6 (3/3), crash and failed-XACK residue stay this phase\'s population',
'',
'**Plans:** 2 plans',
'',
'Plans:',
'',
'- [ ] 654-01-PLAN.md — (wave 1) the evidence HMAC key binds in production',
'- [ ] 654-02-PLAN.md — (wave 2) consumer hardening',
'',
].join('\n');
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), fixture);
const phaseDir = path.join(tmpDir, '.planning', 'phases', '654-stream');
fs.mkdirSync(phaseDir, { recursive: true });
fs.writeFileSync(path.join(phaseDir, '654-01-PLAN.md'), '# Plan 1');
fs.writeFileSync(path.join(phaseDir, '654-02-PLAN.md'), '# Plan 2');
fs.writeFileSync(path.join(phaseDir, '654-01-SUMMARY.md'), '# Summary 1');
const result = runGsdTools('roadmap update-plan-progress 654', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const output = JSON.parse(result.output);
assert.strictEqual(output.updated, true, 'should update');
// Whole-file assertion per the issue's Expected: ONLY the **Plans:**
// count line and the matching checkbox row change; every other byte —
// the bold paragraph and its tight list included — is untouched.
const expected = fixture
.replace('**Plans:** 2 plans', '**Plans:** 1/2 plans executed')
.replace('- [ ] 654-01-PLAN.md', '- [x] 654-01-PLAN.md');
const written = fs.readFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), 'utf-8');
assert.strictEqual(
written,
expected,
`the file must differ from the input by exactly the two intended edits; written:\n${written}`
);
});
test('counts plans and summaries from plans/ subdirectory layout (#3053)', () => {
fs.writeFileSync(
path.join(tmpDir, '.planning', 'ROADMAP.md'),