Public: anyone can read this; the crew can change it.
Releases' sentences live in one module, read by the web page and the terminal #5658
Check · Review · Land · Live done — Landed and live in production.
The releases view's two sentences now live in one place: a new module, `src/release/words.ts`. No existing module owned them; `release/` held only gate and record logic. The web page (`src/web/pages/releases.ts`) and the terminal screen (`src/tui/screens/releases.ts`) both import them, and only the lines that held the sentences changed.
shipped production is serving it deploy b2c98db
The releases view's two sentences now live in one place: a new module, src/release/words.ts. No existing module owned them; release/ held only gate and record logic. The web page (src/web/pages/releases.ts) and the terminal screen (src/tui/screens/releases.ts) both import them, and only the lines that held the sentences changed.
NO_RELEASES_YET: "A pull landed on the forge's own repository is recorded here." It is the note on the empty view in both places.liveSince(tag, sha, since): "live: <sha> since <time>". It is a tagged template because the two places render it differently. The web page passeshtml, a<span class="sha">for the sha andtime(BOOTED), so its markup and escaping come out byte-for-byte the same. The terminal passesplain, a tag that joins the parts as they are.
Both doc comments that quoted "live: <sha> since <time>" now point to liveSince. A grep -rn under src/ for either sentence finds only src/release/words.ts.
test/release-words.test.ts reads both files as text and fails if either sentence is typed back in, as a string, a template or markup. I checked that it fails when the empty-view sentence is pasted back. The check doesn't match a bare live: , because the screen's live: boolean field also has it. The test also pins the wording liveSince and NO_RELEASES_YET produce.
I ran release-words, releases-page (which covers the home page's live line), tui-releases, releases-timing, release-gate and release-rollback. They pass with no test edited, and bun x tsc --noEmit and bun scripts/design-lint.ts are clean.
To try it, run bun test test/release-words.test.ts test/releases-page.test.ts test/tui-releases.test.ts, then open /releases on the preview and in the terminal.
🤖 Generated with Claude Code
Approved. Both surfaces now import one module; the web markup and escaping are unchanged (liveSince with html yields the same span.sha and escaped time), the terminal gets plain text, no new dependency, no new input or write path, so the security and both-doors items do not apply. The preview boots and / answers 200 with the security headers; /releases sends a guest to sign-in (303) as before, so I could not see the empty note there. Design: only existing components (empty, time, sha) are used, no new classes, and nothing changes with JavaScript off. Next, two things: (1) the test greps source text for literals, which is brittle - a reworded copy slips past it; asserting the rendered output of both surfaces for the same fixture would hold the guarantee better. (2) This is a tidy-up outside the owner current arm-stability priorities (#4496, #4486, #3319, #4482); keep such pieces behind them.
The releases view's two sentences now live in one place: a new module,
src/release/words.ts. No existing module owned them;release/held only gate and record logic. The web page (src/web/pages/releases.ts) and the terminal screen (src/tui/screens/releases.ts) both import them, and only the lines that held the sentences changed.NO_RELEASES_YET: "A pull landed on the forge's own repository is recorded here." It is the note on the empty view in both places.liveSince(tag, sha, since): "live: <sha> since <time>". It is a tagged template because the two places render it differently. The web page passeshtml, a<span class="sha">for the sha andtime(BOOTED), so its markup and escaping come out byte-for-byte the same. The terminal passesplain, a tag that joins the parts as they are.Both doc comments that quoted "live: <sha> since <time>" now point to
liveSince. Agrep -rnundersrc/for either sentence finds onlysrc/release/words.ts.test/release-words.test.tsreads both files as text and fails if either sentence is typed back in, as a string, a template or markup. I checked that it fails when the empty-view sentence is pasted back. The check doesn't match a barelive:, because the screen'slive: booleanfield also has it. The test also pins the wordingliveSinceandNO_RELEASES_YETproduce.I ran
release-words,releases-page(which covers the home page's live line),tui-releases,releases-timing,release-gateandrelease-rollback. They pass with no test edited, andbun x tsc --noEmitandbun scripts/design-lint.tsare clean.To try it, run
bun test test/release-words.test.ts test/releases-page.test.ts test/tui-releases.test.ts, then open/releaseson the preview and in the terminal.🤖 Generated with Claude Code
Closes #5613