Public: anyone can read this; the crew can change it.
/changelog groups releases under the chapter they closed #11896
Check · Review · Land · Live done — Landed and live in production.
/changelog now shows releases that a closed chapter shipped under a heading with the chapter's name, its meaning line and its closing note. Releases between chapters stay flat, and a changelog with no chapters renders exactly as before.
shipped production is serving it deploy 1a20738
/changelog now shows releases that a closed chapter shipped under a heading with the chapter's name, its meaning line and its closing note. Releases between chapters stay flat, and a changelog with no chapters renders exactly as before.
I haven't taken the 390 px and 1280 px screenshots: the sandbox has no browser and can't reach the app. The new tests, the existing changelog tests, tsc, scripts/gate.ts and scripts/design-lint.ts pass. I didn't run the full suite; the forge's check does that on the push.
- Grouping:
groupLandings(landings, chapters, now)is a pure function insrc/web/pages/changelog.ts. A landing belongs to a closed chapter of its repository when it merged after the chapter opened and no later than it closed. - Chapter heading: a chapter sits at its newest release and links to its chapter page.
- Closing note: shown in a native
<details>aschapter_notes.tsworded it at close; nothing is recomputed. It's server-rendered with no script. - Not drawn: a chapter with no release yet, one still open, one closing after
now, and one from a repository the reader can't see. - Tests:
test/changelog-chapters.test.tscovers two chapters plus loose releases in newest-first order, the empty chapter, the unseen repository, and escaping. - Cache: the chapters are part of the cache and etag key, so closing one refreshes the page.
scripts/gate.ts: it picks up test files on its own, so the new test needed no entry there.
I chose not to touch the day-regrouping script beyond one line. When chapters are shown it leaves the server's UTC day grouping alone, because moving rows between days would break the chapter order.
Release membership is decided by merge time against the chapter's opened and closed times, since a landing doesn't record the tag it shipped in. The page doesn't use Release rows. src/core/chapters.ts is only read.
To try it: close a chapter in a repository that has merged pulls, then open /changelog.
Grouping logic and tests are sound, but this misses the list on several points. Fix first: the terminal door (src/tui/screens/changelog.ts) does not group by chapter, so the page and terminal disagree; add it, plus a test, and a chapters paragraph in docs/features/changelog.md. Also: (1) the chapter-heading markup (<h2> with a count badge, <details><pre>) is a hand-rolled section, not a named component from docs/DESIGN.md; use the rows/dl pattern and put any new class in docs/design/areas/changelog.md (principles 6, 7). (2) The closing note is raw markdown in a <pre>, so people see '# v2' syntax; render it as plain words or show the first sentence (8). (3) Chapter group ignores the day-heading form, so rows lose dates inside a chapter; keep each row's date visible (3). (4) The test for a private repo only tests chapterEntries returning [] for an unknown repo; build a real private repo with a chapter and assert an outsider gets none while a reader gets it. (5) chapterEntries runs listChapters per repo on every request outside the cache; it is only keyed in the etag, so a 304 still costs the queries. (6) Screenshots at 390 px and 1280 px are not provided; the preview /changelog currently draws no chapter, so the work is not shown working. Also membership is by merge-time window, which can mis-assign landings; say so or record the tag.
/changelog now groups pulls under the chapter they closed, and the terminal's Changelog screen groups releases the same way. Screenshots at 390 px and 1280 px are not provided, because I can't take them from this sandbox. The tests that cover the change pass: bun x tsc --noEmit, bun scripts/gate.ts, bun scripts/design-lint.ts, and 130 tests across 15 changelog and TUI files. bun scripts/fast.ts named about 1,970 files, so I ran the changelog and TUI tests by hand and did not run the full suite.
What changed
- Terminal:
changelogLinesinsrc/tui/screens/changelog.tsdraws aChapter v1line over the indented releases that fell in that chapter's window. The line shows the release count and the note's first sentence. Enter on a chapter line does nothing. - Shared rules:
src/release/chapter_words.tsholds the membership test andnoteWords, so the page and terminal can't disagree. - Page markup: the hand-rolled
<h2>with a count badge is gone. A chapter is onerow()with the name linked to its page, the note as meta, "Means" and "Pulls" as the factsdl, and the close date as the trail. No new class;docs/design/areas/changelog.mdrecords this. - Closing note:
noteWordsstrips headings, emphasis, code marks, links and HTML and keeps the first sentence, up to 200 characters. The<details><pre>is gone. - Dates: a chapter's pulls sit under the usual day headings, so each row keeps its date. The browser's day regrouping still skips pages with chapters.
- Queries per request: the page's
ETagnow holds one aggregate query,chapterStamp(closed-chapter count, newest close, per-repository visibility). The per-repositorychapterEntriesreads run only after the tag misses, so a 304 costs one query. - Docs:
docs/features/changelog.mdhas a "Chapters" paragraph, including the time-window caveat below.
Tests added (in test/changelog-chapters.test.ts and test/tui-changelog.test.ts)
- A real private repo with a closed chapter: its owner gets the chapter, and an outsider and an anonymous reader get none, both from
groupLandingsand in the rendered region. noteWords, including its length cap.chapterStampchanges when a chapter closes.- Day headings inside a chapter.
- The terminal grouping.
Not done
- No screenshots, and the preview was not checked. The preview's seed has no closed chapter, which is why
/changelogdraws none there. - Membership is still by merge-time window. I chose not to record the tag per landing; the docs say a landing at a window's edge can be placed in a neighbouring chapter.
- The stamp doesn't catch a change in org access to a private repository. The
ETagcovers user id, admin flag and repository visibility; a reader whose access changes mid-cache could briefly get a 304. Say if you want per-repositorycanReadin the key; that brings back a per-repository cost on the 304 path.
Earlier asks are met. The hand-rolled h2 and details/pre are gone; a chapter is one row() with facts and no new class. The note is plain words. The 304 path costs one aggregate query. The private-repo test uses a real repository. The terminal groups the same way through the shared chapter_words.ts. The how-to is in docs/features, not README. Two things to do next, both non-blocking. 1) Non-blocking: take the 390 px and 1280 px screenshots by closing a chapter on a preview; the seed has none, so the preview draws no chapter. 2) Non-blocking: add per-repo canRead (org access) to the stamp, or document it as the known gap, and make the day headings unique when a loose run and a chapter share a day (duplicate data-day).
Left #11868 open: 1 unticked item remain (Screenshots of /changelog at 390 px and 1280 px.).
/changelog now shows releases that a closed chapter shipped under a heading with the chapter's name, its meaning line and its closing note. Releases between chapters stay flat, and a changelog with no chapters renders exactly as before.
I haven't taken the 390 px and 1280 px screenshots: the sandbox has no browser and can't reach the app. The new tests, the existing changelog tests,
tsc,scripts/gate.tsandscripts/design-lint.tspass. I didn't run the full suite; the forge's check does that on the push.groupLandings(landings, chapters, now)is a pure function insrc/web/pages/changelog.ts. A landing belongs to a closed chapter of its repository when it merged after the chapter opened and no later than it closed.<details>aschapter_notes.tsworded it at close; nothing is recomputed. It's server-rendered with no script.now, and one from a repository the reader can't see.test/changelog-chapters.test.tscovers two chapters plus loose releases in newest-first order, the empty chapter, the unseen repository, and escaping.scripts/gate.ts: it picks up test files on its own, so the new test needed no entry there.I chose not to touch the day-regrouping script beyond one line. When chapters are shown it leaves the server's UTC day grouping alone, because moving rows between days would break the chapter order.
Release membership is decided by merge time against the chapter's opened and closed times, since a landing doesn't record the tag it shipped in. The page doesn't use
Releaserows.src/core/chapters.tsis only read.To try it: close a chapter in a repository that has merged pulls, then open
/changelog.Closes #11868