Context
Defect-note 824539f4, found during #19166. buildScripts/docs/index/release.mjs dates each release by its note's publishedAt, and falls back to stats.birthtime. Before #19322, the Brain sync re-materialized each released note from its GitHub Release, frontmatter included. Since #19322, publish.mjs keeps the authored .github/RELEASE_NOTES/v<version>.md as the archive, and no step writes tagName or publishedAt. 168 of the 169 notes carry it. v13.2.0.md, the first note released under the new flow, does not.
The Problem
From 13.2 on, a release's date in the Portal is a file creation time:
- At the cut,
prepare.mjs indexes the note by its birthtime in the operator's checkout, which is whenever the file arrived there.
- Pages step 4.1 copies the notes on every deploy. Its index dates 13.2.0 by that copy, so the date moves with each redeploy, and the npm package's index carries a third date.
Measured: indexing .github/RELEASE_NOTES from a fresh worktree dated 13.2.0 at the second the worktree was created.
The Architectural Reality
publish.mjs:
- Step 2 runs
prepare.mjs, which rebuilds releases.json, and commits "Release v".
- Step 3 squashes to
main, and Step 4 appends the atomic-commit line to the note.
- Step 5 creates the GitHub Release from the note. It strips the frontmatter (
/^---[\s\S]+?---\s*/) and uses the first H1 as the title.
- The archived notes' frontmatter is the GitHub Release's:
tagName, name, publishedAt, isPrerelease, isDraft, for example in v13.1.0.md.
The Fix
- A new
buildScripts/release/releaseNoteFrontmatter.mjs exports stampReleaseNote(content, {publishedAt, version}). It prepends that frontmatter, with name taken from the first H1 (the title Step 5 uses), through gray-matter for YAML quoting. A note that already has frontmatter is returned unchanged, so a re-run keeps its date.
publish.mjs stamps the note at the start of Step 2, before prepare.mjs, so the release commit's index carries the date.
Acceptance Criteria
Out of Scope
- The 168 archived notes keep GitHub's dates.
- If the 13.2 cut runs before this merges, the block is added to
v13.2.0.md by hand before publish.
Related
#19166 · #19322 · #14800 · neomjs/pages#14
Sweeps at 12:34Z:
- Live latest-open: the latest 20 open neo issues; none equivalent.
- Org search (
publishedAt release note, release notes frontmatter): nothing open.
- MC: nothing contrary.
- A2A: no claim since the defect-note.
- Own assignments: #14800 is the 13.2 notes epic, which this ticket only relates to.
Retrieval Hint: "release note publishedAt frontmatter stamp publish.mjs release index date"
Origin Session ID: 90464c20-910b-4abd-ac1d-d86f8fbccb13
Authored by Grace (Claude Opus 5.5, Claude Code) 🖖
Context
Defect-note
824539f4, found during #19166.buildScripts/docs/index/release.mjsdates each release by its note'spublishedAt, and falls back tostats.birthtime. Before #19322, the Brain sync re-materialized each released note from its GitHub Release, frontmatter included. Since #19322,publish.mjskeeps the authored.github/RELEASE_NOTES/v<version>.mdas the archive, and no step writestagNameorpublishedAt. 168 of the 169 notes carry it.v13.2.0.md, the first note released under the new flow, does not.The Problem
From 13.2 on, a release's date in the Portal is a file creation time:
prepare.mjsindexes the note by its birthtime in the operator's checkout, which is whenever the file arrived there.Measured: indexing
.github/RELEASE_NOTESfrom a fresh worktree dated 13.2.0 at the second the worktree was created.The Architectural Reality
publish.mjs:prepare.mjs, which rebuildsreleases.json, and commits "Release vmain, and Step 4 appends the atomic-commit line to the note./^---[\s\S]+?---\s*/) and uses the first H1 as the title.tagName,name,publishedAt,isPrerelease,isDraft, for example inv13.1.0.md.The Fix
buildScripts/release/releaseNoteFrontmatter.mjsexportsstampReleaseNote(content, {publishedAt, version}). It prepends that frontmatter, withnametaken from the first H1 (the title Step 5 uses), through gray-matter for YAML quoting. A note that already has frontmatter is returned unchanged, so a re-run keeps its date.publish.mjsstamps the note at the start of Step 2, beforeprepare.mjs, so the release commit's index carries the date.Acceptance Criteria
tagName,name,publishedAt,isPrereleaseandisDraft, and a prerelease version setsisPrerelease: true.publish.mjsstamps the note beforeprepare.mjsruns. Step 5's release body still carries no frontmatter.Out of Scope
v13.2.0.mdby hand before publish.Related
#19166 · #19322 · #14800 · neomjs/pages#14
Sweeps at 12:34Z:
publishedAt release note,release notes frontmatter): nothing open.Retrieval Hint: "release note publishedAt frontmatter stamp publish.mjs release index date"
Origin Session ID: 90464c20-910b-4abd-ac1d-d86f8fbccb13
Authored by Grace (Claude Opus 5.5, Claude Code) 🖖