Skip to content

Serve a job's journal from its newest entries (#51) - #63

Merged
kikashy merged 1 commit into
mainfrom
feat/51-journal-newest-first
Oct 11, 2026
Merged

kikashy merged 1 commit into
mainfrom
feat/51-journal-newest-first

Conversation

@kikashy

@kikashy kikashy commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Closes #51

What changes for a reader

GET /v1/jobs/{job}/events and GET /v1/events take two new query parameters. tail=true answers the newest page (the last up to 50 entries). before=<sequence> answers the up to 50 entries immediately before that sequence. Entries stay in the journal's order within a page, journalBegan is answered as always, and GET /v1/status lists the capability journal-backward to test first. A reader that wants the latest activity no longer reads the whole journal.

Design

  • A backward answer has more (older entries exist before the page), a new member before (the sequence of the page's first entry: the cursor for the next older page) and next as today (the page's last entry, to turn around and follow the journal forward). An empty backward page has more false, before as given (0 for tail) and next 0.
  • tail=true with before, either with after, a repeated parameter, or a tail other than true/false is 400 (invalid_paging, invalid_tail or invalid_cursor) with one sentence. tail=false is the same as no tail. before=0 answers an empty page; a before beyond the end answers the newest page.
  • A request with neither parameter takes the old path unchanged and its answer has no before member.
  • Words: openapi.json (parameters, before member, more/next descriptions, the capability on /status), docs/design/activity-journal.md (a paragraph on reading from the end), docs/releases/v0.8.0.md (one section).

Tests

internal/runner/events_backward_test.go, on a journal of 2,100 entries written through the journal's own writer:

  • the golden test: ten forward requests, answered by the code before this change, recorded as SHA-256 of their bytes (TestOlderClientsGetTheAnswersTheyAlwaysGot);
  • the newest page in one request, checked against openapi.json (TestTheNewestPageIsOneRequest);
  • walking back reaches the first entry, each entry once, in order, more false exactly on the last page, on both routes (TestWalkingBackReachesTheFirstEntryOnceEach);
  • forward paging from a backward page's next reaches the end without a gap (TestForwardPagingContinuesFromABackwardPage);
  • bounds and conflicts (TestBackwardPagingBounds); whole-page journals (TestAJournalOfWholePagesEndsOnTheLastPage); the capability (TestTheStatusListsTheBackwardCapability).

Mutation tally

Seven mutants in a scratch copy, all compiled, all caught: overlap at the page boundary (<=) by the walk and bounds tests; a skipped entry and an overlapping cursor by the walk and newest-page tests; a short page by the newest-page and bounds tests; a wrong next by the newest-page and forward-continuation tests; more true on a whole last page by TestAJournalOfWholePagesEndsOnTheLastPage (the first version of the tests missed it, so that test was added); the dropped before+after and tail+after conflicts by the bounds test.

Checks

  • gofmt -l .: clean. go vet ./...: clean.
  • CI at 414f3d8: Runner (ubuntu-latest), Runner (macos-latest) and Release contents pass.

Not in this PR

Desk's side (desk #235), and any change to the journal's contents, order or storage.

Review

A read-only paging change with a golden test for the old answers; no review round.

🤖 Generated with Claude Code

GET /v1/jobs/{job}/events and GET /v1/events accept tail=true (the newest
page) and before=<sequence> (the page immediately before it), answering
the entries in the journal's order with more for older entries and a
before cursor for the next older page. Requests that send neither
parameter are answered byte for byte as before. GET /v1/status lists the
capability journal-backward.

Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: kikashy <35789537+kikashy@users.noreply.github.com>
@kikashy
kikashy merged commit c85d5af into main Oct 11, 2026
3 checks passed
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.

Serve a job's journal from its newest entries, so a reader need not page through all of it

1 participant