Public: anyone can read this; the crew can change it.

/changelog reads like a story: same-shape landings of a day gather into one line, and titles drop lane and test-file jargon #10843

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The changelog now gathers landings of one UTC day whose titles share a shape into a single line. `bun x tsc --noEmit`, `bun scripts/gate.ts` and `bun scripts/design-lint.ts` are clean. `bun test test/story-gather.test.ts test/changelog*.test.ts test/keys-changelog.test.ts` passes, including the 500-entry timing test at about 11 ms median against the 50 ms budget. The phone-look test (`changelog-fi…

shipped production is serving it deploy c1c74c2

opened this

The changelog now gathers landings of one UTC day whose titles share a shape into a single line. bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts are clean. bun test test/story-gather.test.ts test/changelog*.test.ts test/keys-changelog.test.ts passes, including the 500-entry timing test at about 11 ms median against the 50 ms budget. The phone-look test (changelog-fit) was skipped here because no chromium starts in the sandbox.

I did not call keep_plan for this issue.

What changed

  • New module src/story/gather.ts:

- plainTitle drops a leading small: and any test/… or src/… path, along with the "with" or "in" that introduced it. - gather groups a day's landings whose titles differ in one slot of at most three words. They must share at least three words, and the shared words must outnumber the slot.

  • standsAlone: a title mentioning a revert or security (CVE, XSS, CSRF, injection and similar) is never gathered. It stays on its own line.
  • src/web/pages/changelog.ts:

- A gathered line shows the shared words with … for the slot, for example "J/k, enter, esc and ? on …". Its meta reads "9 pulls · Scout · with Claude Sonnet 5.5". - The line opens as a <details> (no script) to the individual pulls, each linking to its real pull page. - All rows show the plain title.

  • localDaysJs: it now moves only top-level rows, so the pulls inside a gathered line are not pulled out into the wrong day. It sums a data-count on each row for the day badge and the "shipped today" count.
  • Atom feed (src/web/feeds.ts): entry titles use plainTitle.
  • test/story-gather.test.ts:

- Title cleaning. - A fixture of the nine keys pulls gathering into one line credited once. - Reverts and security fixes staying single. - The page rendering a <details> with the author named once and no small:.

Not done

  • /api/v1/changelog still returns the raw titles; the issue only named the page and the feed.
  • A gathered line that spans two local days (once the browser regroups by time zone) sits in the day of its newest landing.
  • The pull's own page keeps its real title, as before.

Try it: open /changelog on the preview and open a gathered line. /changelog.atom shows the plain titles.

The push was first refused by the pre-push hook, which wants a Try: line in a commit message. I added an empty commit with one.

🤖 Generated with Claude Code

Closes #10837

commented

The changelog now gathers landings of one UTC day whose titles share a shape into a single line. bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts are clean. bun test test/story-gather.test.ts test/changelog*.test.ts test/keys-changelog.test.ts passes, including the 500-entry timing test at about 11 ms median against the 50 ms budget. The phone-look test (changelog-fit) was skipped here because no chromium starts in the sandbox.

I did not call keep_plan for this issue.

What changed

  • New module src/story/gather.ts:

- plainTitle drops a leading small: and any test/… or src/… path, along with the "with" or "in" that introduced it. - gather groups a day's landings whose titles differ in one slot of at most three words. They must share at least three words, and the shared words must outnumber the slot.

  • standsAlone: a title mentioning a revert or security (CVE, XSS, CSRF, injection and similar) is never gathered. It stays on its own line.
  • src/web/pages/changelog.ts:

- A gathered line shows the shared words with … for the slot, for example "J/k, enter, esc and ? on …". Its meta reads "9 pulls · Scout · with Claude Sonnet 5.5". - The line opens as a <details> (no script) to the individual pulls, each linking to its real pull page. - All rows show the plain title.

  • localDaysJs: it now moves only top-level rows, so the pulls inside a gathered line are not pulled out into the wrong day. It sums a data-count on each row for the day badge and the "shipped today" count.
  • Atom feed (src/web/feeds.ts): entry titles use plainTitle.
  • test/story-gather.test.ts:

- Title cleaning. - A fixture of the nine keys pulls gathering into one line credited once. - Reverts and security fixes staying single. - The page rendering a <details> with the author named once and no small:.

Not done

  • /api/v1/changelog still returns the raw titles; the issue only named the page and the feed.
  • A gathered line that spans two local days (once the browser regroups by time zone) sits in the day of its newest landing.
  • The pull's own page keeps its real title, as before.

Try it: open /changelog on the preview and open a gathered line. /changelog.atom shows the plain titles.

The push was first refused by the pre-push hook, which wants a Try: line in a commit message. I added an empty commit with one.

🤖 Generated with Claude Code

Changes requested — before the latest push

The gathering works in the preview (a <details> line opens in place, no script). Changes for one round:

  1. Both doors: src/tui/screens/changelog.ts still shows raw titles and ungathered landings. Use plainTitle/gather there too and add a TUI test.
  2. Box 4 has no test: nothing fails if changelogAtom stops using plainTitle. Add an Atom test.
  3. docs/features/changelog.md does not say landings gather or that titles are cleaned. Update it.
  4. plainTitle capitalises the first letter, so keys 'j/k' become 'J/k', which reads wrong. Capitalise only when the first word is a plain word, and say so in the test.
  5. Principle 8/1: the meta line 'N pulls · Scout · with Claude Sonnet 5.5' is fine, but the gathered row has no real title link; check it is reachable by keyboard (summary focus) and the fold has a label naming what it opens.
commented

I've addressed all five points and pushed to the same branch. bun x tsc --noEmit is clean and gate.ts printed nothing. Of the tests, I ran the story-gather, TUI changelog and changelog suites (56 pass); I did not run design-lint again.

  1. Terminal screen: src/tui/screens/changelog.ts now shows plain titles and gathers a release's pulls.

- A gathered line reads "j/k, enter, esc and ? on … · 3 pulls". - Enter on a gathered line lists its own pulls; Enter on a single pull opens it as before. - The release filter also matches against plain titles. - New test in test/tui-changelog.test.ts, written against pullLines rather than the rendered screen. - To let both doors share the code, gather in src/story/gather.ts is now generic over anything with a title.

  1. Atom test: test/changelog-atom.test.ts now has a live pull titled "small: j/k, … with test/keys-pulls.test.ts". The test expects the entry "Went live: j/k, enter, esc and ? on pulls" and fails if small: or test/keys appears anywhere in the feed. I dated the new fixture earlier than the existing ones, because a merge older than the newest live pull counts as live and the "Not shipped yet" fixture would otherwise leak into the feed.
  2. Docs: docs/features/changelog.md has a new "Reads like a story (#10837)" section. It covers cleaning, gathering, the revert and security exception, the terminal, the Atom feed, and that /api/v1/changelog keeps raw titles.
  3. Capitalisation: plainTitle capitalises only when the first word is all letters. "j/k, …" stays as written and "small: fold the copy" becomes "Fold the copy". The test says why.
  4. Keyboard and label: I did not change the markup for this. The gathered row is a native <summary>, so it is focusable and toggles with Enter or Space. Its visible text ("j/k, enter, esc and ? on …" plus "9 pulls · Scout · with Claude Sonnet 5.5") is the label naming what it opens. I did not test keyboard focus in a browser.

I did not change /api/v1/changelog to plain titles; the issue only named the page and the feed.

Changes requested — before the latest push

No high finding; the gathering, plain titles, Atom and terminal door are right. Fix in one round: (1) the localDaysJs change (top-level-only rows, data-count summing for the day badge and shipped-today count) is new behaviour with no test that fails without it; add one that runs the script against a gathered row and checks the count. (2) gather() recomputes plainTitle+split for every pair, quadratic on a busy day; compute each landing words once. (3) A mid-file import in test/tui-changelog.test.ts; move it to the top. Boxes 1-5 are met by the head, pending these.

commented

/changelog now tells a day's work as a story. Landings of the same day whose titles share a shape gather into one line, such as "j/k, enter, esc and ? on …". That line opens in place to each pull, and who built them is named once. Reverts and security fixes always stay on their own line. Titles drop the small: lane prefix and any test/… or src/… path, on the page, in the Atom feed and in the terminal's release view.

This round fixes the three review points:

  • Day count test: a new test in test/changelog.test.ts checks how the browser's local-day regrouping (localDaysJs) counts. It renders a day holding one gathered row of three pulls plus one single pull, then runs the script in a Chicago time zone. The day badge must read 4 and the top line "4 shipped today.". The three pulls must stay inside the gathered row and must not be pulled out as rows of their own. I put back the old script (every li counted, one per row) and the test failed (badge read 5).
  • Speed of gather(): src/story/gather.ts now cleans and splits each title once, and checks once whether it must stand alone, before the loop that compares pairs. That loop now only compares words already split.
  • Imports: creditWords and pullLines move into the import block at the top of test/tui-changelog.test.ts, joined with changelogScreen.

bun scripts/gate.ts and bun x tsc --noEmit are clean. The changelog, Atom, terminal-changelog and gather test files pass.

To try it: open /changelog on the preview on a day with several pulls of one shape, open a gathered line, and compare the day's count with the pulls listed.

🤖 Generated with Claude Code

Approved

Earlier asks, all met in the diff since 28a2cd9c9590: (1) the localDaysJs change now has a test that runs the script against a gathered row and checks the badge (4), the shipped-today line and that inner pulls stay inside the row; (2) gather() computes words and standsAlone once per landing; (3) the TUI test imports sit at the top. Gathering uses the existing row fold (native details/summary, works with JS off), plain titles show on the page, feed and terminal, and the how-to is in docs/features/changelog.md, not the README. Two things I would do next, non-blocking: Non-blocking: 1) test the rendered terminal screen (Enter on a gathered line) rather than only pullLines. 2) give the gathered summary an explicit accessible name such as "9 pulls: j/k, enter, esc and ? on …" and check it in a browser on a 360px phone.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs