Skip to content

Reviews: --sort reaches the store, and page 2 continues from page 1 - #7

Merged
jehrr merged 1 commit into
mainfrom
fix/reviews-sort-and-pagination
Oct 22, 2026
Merged

jehrr merged 1 commit into
mainfrom
fix/reviews-sort-and-pagination

Conversation

@jehrr

@jehrr jehrr commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

Problem

Two defects in --mode reviews, both reported by a manual test of v0.2.0 and both reproduced before fixing.

--sort newest did not sort. The sort key was sent in the first slot of the sort block. The store reads a constant there, so it answered "newest" in its relevance order and answered "relevant" and "rating" with nothing. The README described that as the store only offering one ordering. It was this repository's request. Same app, same moment, 20 asked for:

key old request [sort, null, …] corrected [2, sort, …]
1 relevant 0 rows 20 rows, relevance order
2 newest 20 rows, dates 08-28, 08-31, 09-18, 07-26 … 20 rows, strictly descending
3 rating 0 rows 20 rows, by score

Page 2 restarted the list. Page 1 came from the reviews embedded in the app page. They carry no continuation token, so page 2 was asked for without one, returned the start of the list, and dedupe removed most of it (20 / 1 / 19 rows over three pages in the report).

Behaviour after

  • Every page of a reviews run comes from the reviews endpoint, each page after the first asked for with the previous page's token. The app page is still fetched first, to confirm the app exists in that market. One request more than before.
  • --sort newest|relevant|rating, default newest; unknown values are refused.
  • --url <app page> --mode reviews runs reviews instead of exiting 2.
  • A reviews run with a proxy pool logs that it keeps one exit for the run.
  • README and CHANGELOG ([Unreleased], led by a correction notice) no longer claim the store offers one ordering. The score-filter sentence now says only that this repository does not implement one: the forms tried in the corrected request either changed nothing or returned no rows.

Evidence

  • newest across a token, live 2026-10-22: 40 + 40 reviews, no id shared, posted_at non-increasing over the page boundary.
  • Review fixtures re-taken through the corrected request by make_fixtures.py, scrubbed; a new check asserts newest-first across both pages.
  • Fake-driver run through engine_core.main: page 1 posts no token, page 2 posts page 1's token, 80 rows (40 per page), newest first end to end; --sort rating sends key 3; --url + --mode reviews runs.
  • The suite previously pinned the broken shape and "newest only"; those checks now pin the correct shape for all three keys.
  • Controls, each planted in a disposable copy and required to fail on the named check: sort key back in slot 0, page 2 without token, page 1 from embedded reviews, --url refused, --sort ignored on the wire, page 2 fixture out of order — 6 of 6 caught.
  • Canary reviews command run live through Playwright, Selenium and pyppeteer: [100, 100] rows per page, newest first, assertions exit 0. The same assertions on unfixed main: [20, 80], dates out of order, exit 1.
  • Offline suite green with core requirements only and in each engine venv; credential scan clean.

Not changed here

Grid stop_reason, the reCAPTCHA variant heuristic, CDP teardown and the remaining report items are separate PRs.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VrpkXSoXyZMGV5nqF9JV6P

`--sort newest` did not sort. The key went in the first slot of the sort
block, where the store reads a constant; it answered "newest" in relevance
order and answered "relevant" and "rating" with nothing at all. The README
reported that as the store offering only one ordering. It was this
repository's request. In the shape the store's front end sends —
`[2, <sort>, [count, null, token], null, []]` — all three work. Measured
2026-10-22 on com.whatsapp: newest comes back strictly descending and stays
in order across a continuation token (40 + 40, no id shared).

Page 2 restarted the list. Page 1 was taken from the reviews embedded in the
app page, which carry no continuation token, so page 2 was asked for without
one and came back as the start of the list; dedupe then removed most of it
(20 / 1 / 19 rows over three pages in one reported run). Every page now
comes from the reviews endpoint, each with the previous page's token. The app
page is still fetched first, to confirm the app exists in the market.

Also:
- `--sort` offers newest (default), relevant and rating; an unknown value is
  refused instead of silently replaced.
- `--url <app page> --mode reviews` runs a reviews run instead of being
  refused as a mode conflict.
- With a proxy pool, a reviews run logs that it keeps one exit for the run.
- The review fixtures are re-taken through the corrected request and
  scrubbed; a new check asserts they are newest first across both pages.
- The suite pinned the broken request shape and "newest only"; those checks
  now pin the correct shape for all three orderings. A fake-driver run checks
  that page 2's form carries page 1's token and that rows are newest first.
- The canary's reviews job asserts a full page on each page and date order.
  Its old floor of 100 rows over two pages passed by accident.

Verified: offline suite green with core requirements and in each engine's
venv; each new check confirmed to fail on its planted fault (six controls,
each caught by the named check); the canary's reviews command run live
through Playwright, Selenium and pyppeteer gives [100, 100] rows, newest
first end to end, and the same assertions fail on the unfixed code
([20, 80], dates out of order).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VrpkXSoXyZMGV5nqF9JV6P
@jehrr
jehrr merged commit b1a4e51 into main Oct 22, 2026
7 checks passed
@jehrr
jehrr deleted the fix/reviews-sort-and-pagination branch October 22, 2026 21:35
jehrr added a commit that referenced this pull request Oct 22, 2026
Version and changelog for the five fixes merged as #7-#11, from a manual
test of v0.2.0. The section opens with the behaviour changes an existing
caller will see — reviews order and paging, exit 2 for a --gl Play does not
serve, --url keeping its market, --out suffixes, the no_new_products
stop_reason, and the Scraper API's json default and sidecar — followed by
the correction of the README's earlier claim about the store's review
orderings.

The auditor's own reproduction steps were re-run against the merged code
before this commit: 13 of 13 runnable items now give the expected result.


Claude-Session: https://claude.ai/code/session_01VrpkXSoXyZMGV5nqF9JV6P

Co-authored-by: Petr <petr@2captcha.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant