The finding
Observation, not a defect — filing it for triage rather than acting on it.
Two scripts now open blog MDX files and pull the YAML frontmatter out by hand, with the same fence-splitting logic written twice:
scripts/content-lint.mjs — splitFrontmatter(source, file)
scripts/lib/post-dates.mjs — frontmatter(source, file) (added by the sitemap lastmod work)
Both assert the file opens with a --- fence, find the closing fence with indexOf('\n---', 4), and hand the slice to js-yaml. Neither knows about the other.
Why it was not consolidated in the PR that created it
The obvious move — extract the split into scripts/lib/ and have content-lint.mjs import it — would have edited scripts/content-lint.mjs, which was claimed by other in-flight work at the time. Touching it would have created a conflict for no functional gain, so the new reader got its own copy, documented as such.
That was the right call for one PR and is the wrong shape to leave permanently: the two copies can drift, and the frontmatter fence is exactly the kind of parsing detail where a divergence is silent (one script accepting a file the other rejects).
Scope sketch
- Move the fence split into a shared helper (
scripts/lib/frontmatter.mjs, or export it from post-dates.mjs), and have both callers use it.
- Keep the error messages each caller produces —
content-lint.mjs reports against its own file list and its wording is part of its output contract.
- Worth checking whether
scripts/gen-zh-hant.mjs, scripts/new-post.mjs and scripts/to-wechat.mjs have their own copies too; this issue only confirmed the two above.
Not urgent
Nothing is broken today: both copies behave identically on the current content tree (pnpm content:lint passes on 334 files, and the sitemap map reads the same 334). This is a consolidation to do once the files involved are free, not a fix to rush.
Found while implementing #104.
Generated by Claude Code
The finding
Observation, not a defect — filing it for triage rather than acting on it.
Two scripts now open blog MDX files and pull the YAML frontmatter out by hand, with the same fence-splitting logic written twice:
scripts/content-lint.mjs—splitFrontmatter(source, file)scripts/lib/post-dates.mjs—frontmatter(source, file)(added by the sitemaplastmodwork)Both assert the file opens with a
---fence, find the closing fence withindexOf('\n---', 4), and hand the slice tojs-yaml. Neither knows about the other.Why it was not consolidated in the PR that created it
The obvious move — extract the split into
scripts/lib/and havecontent-lint.mjsimport it — would have editedscripts/content-lint.mjs, which was claimed by other in-flight work at the time. Touching it would have created a conflict for no functional gain, so the new reader got its own copy, documented as such.That was the right call for one PR and is the wrong shape to leave permanently: the two copies can drift, and the frontmatter fence is exactly the kind of parsing detail where a divergence is silent (one script accepting a file the other rejects).
Scope sketch
scripts/lib/frontmatter.mjs, or export it frompost-dates.mjs), and have both callers use it.content-lint.mjsreports against its own file list and its wording is part of its output contract.scripts/gen-zh-hant.mjs,scripts/new-post.mjsandscripts/to-wechat.mjshave their own copies too; this issue only confirmed the two above.Not urgent
Nothing is broken today: both copies behave identically on the current content tree (
pnpm content:lintpasses on 334 files, and the sitemap map reads the same 334). This is a consolidation to do once the files involved are free, not a fix to rush.Found while implementing #104.
Generated by Claude Code