chore(changelog): announce the changelog, and make entries a convention

The changelog's own entry names the commit before this one, since a
commit cannot contain its own hash. AGENTS.md now asks every
reader-visible change for an entry, and every multi-commit feature for a
note, so the record keeps up. PRD F18 and the storage and design records
describe what shipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Winther
2026-10-13 14:27:25 +02:00
co-authored by Claude Opus 5.5
parent 65505e17b5
commit 1fc47e2864
6 changed files with 43 additions and 1 deletions
+7
View File
@@ -1049,6 +1049,13 @@ to an open page). Four things hold it up:
that says *why* — the reasoning a diff cannot show — rather than listing the files it touched.
Never reformat code the change did not touch; a formatter the project does not run buries a
100-line change in a 550-line diff.
- **A change a reader can see adds a changelog entry** (`src/shared/changelog.ts`, PRD F18): one
reader-facing line, its kind, its date and the commit it shipped in. A commit cannot contain its
own hash, so the entry lands in a follow-up `chore(changelog)` commit naming the one before it. A
feature spanning several commits also gets a release note when it lands — a few paragraphs from
its spec, with its `from..to` range and spec paths. Run `bun run scripts/check-changelog.ts`
after: tests check a ref's shape only, because CI's checkout is shallow. Data refreshes and
changes invisible to readers get no entry.
- **Zod schemas are the single source of truth for types.** Derive with `z.infer<>`; never
hand-write an interface that duplicates a schema.
- Every adapter ships a fixture in `fixtures/<game>/` and a test asserting parsed output. This is
+4
View File
@@ -227,6 +227,10 @@ Namespaced, versioned, and small. Nothing here ever goes to the server.
// the reader turned on; routinesAsked the games already
// asked about. Both absent means none — built-ins are
// opt-in for every install. PRD F17.
// changelogSeen is the newest changelog entry id the
// reader dismissed. Absent means unrecorded: first-run
// setup sets it, so absent is an install from before the
// changelog, shown the last 14 days once. PRD F18.
// timelineDayWidth is px per day on the board, stored as the
// measurement rather than a step number and read through
// snapDayWidth — so a value from an older ladder still opens
+7
View File
@@ -415,6 +415,13 @@ selected tab fills with `raised` and turns ink; unselected tabs are faint and go
label, a small numeric field on `ground`, `/ 2,100 points`, and a near-pill Save. Weekly and
monthly counts sit on their own faint line under the strip's heading, so the reset countdown
never wraps.
- **What's new card** (top of the main column, never the rail): the eyebrow, up to five lines of
kind (faint, fixed width) · title (muted) · date (faint, hidden on phones), then a near-pill
**Got it** and a faint **See all**. Shown once per batch of changes; never modal.
- **Changelog sheet** (from the footer's *Changelog*, beside *Source code*): the detail sheet's
frame. Each release note is a section — date eyebrow, title, summary paragraphs in muted ink, the
short entries it covers with commit links, then a faint line of `commits from…to` and spec links.
Entries with no note follow under *Other changes*, by month.
- **Built-in question** (top of the dailies strip, once per game): one line of muted text —
`Track Zenless Zone Zero's built-in weekly tasks?` — with a near-coloured **Yes** and a faint **No
thanks** as plain text buttons. Never a card, never a modal; the strip renders for it alone.
+15
View File
@@ -571,6 +571,21 @@ once, in one line, about a game on screen that has them, and a switch per game i
governs them after. Built-ins are not edited in place; **Make it mine** copies one into the reader's
own tasks with its ticks and numbers, and hides the original while the copy exists.
**F18 — What changed.**
The app now says what changed, in two tiers, both tied to git. **Short entries** — one line each,
tagged New, Fixed, or Games & sources — appear once as *What's new*, above the lists, after a new
version loads; *Got it* dismisses them. **Release notes** — a few paragraphs per feature or
milestone, summarised from the history and the design specs — are in the footer's *Changelog*, each
linked to the commits it covers and the specs it draws on. Data refreshes are not changes in this
sense; the footer already states the data's age.
- **After the reload, not before.** The update notice (F14) is the old app, which cannot know what
the new one brings, so the news waits for the version that carries it. Nothing is fetched.
- **A new reader is not shown a history.** First-run setup marks them up to date. A reader from
before the changelog existed is shown the last two weeks once, so its arrival is announced.
- **Written for readers, by a person or an agent, at development time** — never generated at
runtime (AGENTS.md constraint 2).
## Out of scope for v1
Accounts and sync; push notifications; in-game resource or pull tracking; native mobile apps (the
@@ -2,7 +2,8 @@
**Date:** 2026-10-13
**Status:** approved; spec 3. Independent of specs 1 and 2, and announces them.
**Status:** implemented 2026-10-13; spec 3. The card and sheet landed together; three same-day
fix entries for bugs no reader ever saw were left out of the backfill. Independent of specs 1 and 2, and announces them.
## Request and intended outcome
+8
View File
@@ -50,6 +50,14 @@ export const KIND_LABEL: Record<Entry["kind"], string> = {
};
export const ENTRIES: Entry[] = [
{
id: "changelog",
date: "2026-10-13",
kind: "feature",
title: "What's new after an update, and a changelog in the footer",
body: "A short list of changes appears once after a new version loads. The footer's Changelog has the fuller story: notes summarised from the project's history, each linked to its commits.",
ref: "65505e1",
},
{
id: "check-for-new-data",
date: "2026-10-13",