fix(changelog): always render newest entries on top; align seed dates; announce the widget - #202
Conversation
…rder; align seed dates with real ship dates Rendering now goes through newestFirst() — a defensive sorted copy — so the newest id is always on top even if a future entry is appended out of order. Entry 4's date is corrected to its real ship date (PR #198 merged 2026-09-05), so displayed dates no longer jump backwards mid-list. Schema tests now lock id uniqueness, newestFirst ordering, and non-increasing dates down the rendered list; component tests prove an out-of-order append cannot reshuffle the popout.
Entry 6 — "Introducing the changelog" (tag: new, dated the widget's ship date) — renders on top and re-lights the unseen dot for returning visitors, the intended announcement mechanism. First dogfood of the add-an-entry authoring convention in .obvious/obvious.md.
There was a problem hiding this comment.
Obvious PR Review
Verdict: COMMENT — no blocking findings. 0 Blocker · 0 High · 0 Medium · 2 Suggestions.
Reviewed the full canonical patch at 147d952, with all gates re-run in an isolated worktree:
- Verified green: vitest 351/351 (26 files), eslint,
tsc -b --noEmit, production build — committedapp/distis byte-identical to a fresh build — andverify-seo.shpassed. - Dates cross-checked against merge history: entry 4's correction to
2026-09-05matches #198's actual squash-merge (2026-09-05T19:03Z); entry 6's2026-09-07matches #201. Rendered dates now agree with id order, and the new schema test turns any future out-of-order seed date into a CI failure. - Ordering:
newestFirst()derives render order from ids — the same source of truth as the unseen-dot logic — and the new ordering test scrambles the real bundle to prove it. A consumer scan confirms nothing else depends on authoring order.
Suggestions (non-blocking)
- (hygiene)
.obvious/obvious.mdstill describes the bundle as "newest first" — a one-line note that render order is now enforced bynewestFirst()(authoring order free) keeps the repo guidance accurate for future contributors. - (hygiene)
app/src/changelog/ChangelogButton.test.tsx:15—NEWEST_IDis hand-bumped per seed entry (5→6 in this PR). Deriving it viaMath.max(...changelogEntries.map(e => e.id))removes the recurring per-entry tax and cannot go stale.
…ve test ids from the bundle Review-hygiene fixes from the automated review (non-blocking, both taken): - .obvious/obvious.md no longer describes the bundle as "newest first" — render order is enforced by newestFirst(); authoring order is free. - ChangelogButton.test.tsx derives NEWEST_ID and the expected rendered id list from the bundle via newestFirst(), so future entries never require hand-bumping these tests.
|
Both suggestions taken in d8f5c8f:
Lint/typecheck/351 tests green; CI re-running on the new head. |
There was a problem hiding this comment.
Obvious PR Review — Pass 2 (d8f5c8f)
No findings — clean pass.
The incremental delta (docs(changelog): align repo guidance with enforced render order; derive test ids from the bundle) resolves both pass-1 Suggestions, and nothing new was introduced:
.obvious/obvious.mdnow documents the enforced render contract — order comes fromnewestFirst(), authoring order is free but newest-first by convention, and seed dates must agree with id order (schema-tested).ChangelogButton.test.tsxnow derivesNEWEST_IDfrom the bundle viaMath.max(...)and asserts popout order againstnewestFirst(changelogEntries)instead of the hardcoded[6,5,4,3,2,1]. The order-regression guard stays in the scrambling ordering test with its literal expectation, so no coverage was lost.
Re-verified at d8f5c8f in an isolated worktree: vitest 351/351 (26 files), eslint clean, tsc -b --noEmit clean, production build with byte-identical committed app/dist, and verify-seo.sh passed.
|
Thanks — clean pass acknowledged. Both pass-1 suggestions landed in d8f5c8f as described; proceeding to merge on green. |
Why
The changelog popout shipped in #201 renders entries in stored-array order with no sort, and the seed dates contradict id order: "Edit the JSON output in place" (id 4, dated 2026-09-03) displayed above "Pastes land where they belong" (id 3, dated 2026-09-05), so the visible dates jumped 09-05 → 09-03 → 09-05 → 09-04 and read as a misordered list. Nothing stopped a future out-of-order append from silently reshuffling the display.
What
newestFirst(changelogEntries)— a defensive sorted copy, highest id first — so authoring order can never affect the display.NEWEST_ENTRY_IDand the unseen-dot logic were already id-based and are unchanged.new, dated the widget's ship date 2026-09-07) announcing the widget itself. It renders on top and re-lights the unseen dot for returning visitors — the first dogfood of the add-an-entry convention in.obvious/obvious.md.How to Review
app/src/changelog/entries.ts—newestFirst()helper, entry 6, the date fix.app/src/changelog/ChangelogButton.tsx— the only render-path change (3 lines).newestFirst()sorts any input, dates non-increasing in rendered order) and a component test that mocks the bundle module to a scrambled order with a future entry spliced mid-array, proving an out-of-order append still renders on top and drives the unseen dot.Acceptance
app/distparity, andverify-seo.shgreen locally.147d952.Test Evidence
fl_jAtgVTRd).verify-shim.shwas not run locally (no PHP in the sandbox; zero PHP files touched) — CI's PHP job covers it.🔗 Obvious Project · 🧵 Obvious Thread