Skip to content

docs(spec): state list order as one rule - #474

Merged
cuibonobo merged 2 commits into
mainfrom
claude/history-read-order
Oct 29, 2026
Merged

cuibonobo merged 2 commits into
mainfrom
claude/history-read-order

Conversation

@cuibonobo

@cuibonobo cuibonobo commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Summary

Closes #472. getVersions() reads newest first and getJournal() oldest first, and the spec never said this was deliberate. This adds one rule that covers every list, not just those two: a list starts at the end its reader needs first, and a paged list's cursor walks away from that end.

The rule sits beside the order table in data-model.md, and each row now gives its reason:

  • query() with no sort reads newest first, the order a feed-style listing reads in. With a sort, the caller names the end itself.
  • getVersions() reads newest first, because a restore point is almost always a recent one.
  • getJournal() reads oldest first, because a log is tailed and replayed, and a backward cursor can't catch up.
  • getAttachmentRecords() reads oldest first, so records[0] is the record that establishes the mimeType.
  • listTypeGrants() reads newest first because it is a query() with no sort and inherits that default.

Tests: parseVersionsParams() now gets the same cases as parseJournalParams(). The zero case pins the existing split, where the parser checks the format and Stack checks the range. Also fixes a journal test name that said assertValidJournalQuery allows limit: 0.

Spec

No behavior change. Documents existing behavior:

  • New: docs/spec/data-model.md § List order (the rule and the table, moved to the end of § Sorting and pagination)
  • versioning.md § Version history and journal.md § Reading it each give a one-line reason for their own read and link to the table. wire-format.md § Versions links to it too.

Verification

pnpm run format:check, check:refs, lint, test, build, typecheck: all pass locally.

Notes for reviewers

We considered aligning both history reads on oldest first with afterVersion and decided against it. Nothing tails version history, and the common case (the last few restore points) would have needed arithmetic on record.version.

The wire parser accepts beforeVersion=0 and Stack refuses it with the same 400. Making the parser enforce the range would make it the only parser that does, so that's left as is. No changeset: docs and tests only.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XRRrTNc31HrcBZo1FnWDPd

…e orders

getVersions() reads newest first and getJournal() oldest first, and
nothing in the spec said this was a choice. State it as one rule: a
paged history read starts at the end its reader needs first. Version
history is browsed back from the present for a recent restore point;
the journal is tailed and replayed, which only a forward cursor can
do. Everything else about the two reads shares one shape.

Also covers parseVersionsParams() with tests mirroring
parseJournalParams().

Closes #472.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XRRrTNc31HrcBZo1FnWDPd
@changeset-bot

changeset-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f0d093f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Generalize the rule from history reads to every list: a list starts at
the end its reader needs first, and a paged list's cursor walks away
from it. It now sits in data-model.md § List order beside the table,
which gives each row its reason, including listTypeGrants(), which
inherits the unsorted query() default. Versioning and Journal each
keep a one-line reason for their own read, and the duplicated "one
shape" prose is gone.

parseVersionsParams() tests now mirror parseJournalParams(): repeated
params, malformed values, and zero, which the parser accepts and Stack
refuses. Also corrects a journal test name that claimed
assertValidJournalQuery allows limit 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XRRrTNc31HrcBZo1FnWDPd
@cuibonobo cuibonobo changed the title docs(spec): state why version history and the journal read in opposite orders docs(spec): state list order as one rule Oct 29, 2026
@cuibonobo
cuibonobo merged commit 3d7b5d0 into main Oct 29, 2026
9 checks passed
@cuibonobo
cuibonobo deleted the claude/history-read-order branch October 29, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decide whether version history and the journal read in one order

2 participants