fix(messages): confirm a short history page before calling it the start - #402
Merged
Merged
Conversation
messages.list answered hasMore only for a full page back, so a page MAX returned short in the middle of a chat read as its first message: messages list dropped the older-page hint and store fetch marked the chat complete. MAX's CHAT_HISTORY answer carries messages and nothing else (the spec, and the web-tab captures record no answer body), so there is no paging signal to follow. A short, nonempty page is now confirmed with one more CHAT_HISTORY for a single message older than its oldest, sent straight to the wire with web.max.ru's fields, so it costs no reactions or name lookup. chats.list also reports hasMore on its last nonempty page when the login's chat list was cut (#chatsCut was set and never read), so inbox, review and chats list can say the list was incomplete. The test mocks now page history by from/backward as MAX does (pagedHistory), and the download fixture's time matches its id. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
leemour
force-pushed
the
fix/unread-and-short-pages
branch
from
October 4, 2026 21:38
e6a0a4a to
0b0f641
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task
TASK-370:
client.messages.list, the backward branch) usedmessages.length >= limit, so a short page counted as the start of the chat.Why
chats.historyspec (src/spec/operations/chats.ts) lists onlymessagesin the answer. The 2026-09-25 web-tab captures record the requests, but no answer bodies. That is an absence of evidence, not proof. Nothing we hold says whether older messages exist.store fetchmarks the chat complete andmessages listdrops the hint for older messages.#chatsCutwas set and never read (#readRestOfChats). When the oneCHATS_LISTafter the login was refused, or came back with 26 or more chats, the chat list still saidhasMore: false.What
CHAT_HISTORY:{ chatId, from: oldest - 1, forward: 0, backward: 1, getMessages: true }. These are exactly web.max.ru's fields, with nointeractive, so it marks nothing read.hasMore: true; none means the start of the chat. A full page still counts as more, and an empty page as the end.inboxandinbox --newfor a chat with fewer messages than--limit.after) branch is unchanged. It already asks for one more than the page.chats.listreportshasMore: trueon its last nonempty page when the list was cut. An empty page past the end still saysfalse, so a script that pages ends.CHATS_LISTpage). On a bigger account, the rest is now reported (partial), but still not read. Reading the rest means following theCHATS_LISTmarker. That is new protocol behaviour on the real account, so it needs its own plan, and it is not built here.inboxon a cut account prints the old "only the 100 newest chats were looked at". The number is wrong, but it does say the list was incomplete.from/backwardas MAX does (pagedHistoryinsrc/testing/mock-max.ts), and the download fixture'stimenow matches its id. Counts that now include the confirming request are updated: inbox, review, store.docs/usage.md(a user page) is rewritten.docs/dev/ARCHITECTURE.mdis corrected in place, with a correction mark.Testing
pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm docs:check && pnpm parity:checkall pass, on mainb5d3691.New tests in
src/client.test.ts:hasMore: true, with the exact confirming request and no extra reactions request;false;hasMoreon its last nonempty page only.All three fail on main.
The adapter contract was run against fix(inbox): look at every chat for unread, new and review cli-messaging#548's kit: 22 passed, 2 skipped, the same as on main.
Noticed, not fixed: on main,
src/store.test.ts"asks MAX for --page-size messages a page" fails when run alone (-t) and passes in a full-file run, so it depends on test order.Not verified: anything against live MAX. Fakes only.
🤖 Generated with Claude Code