Fix reviewed Discogs pagination, comparison tasks, and grading (#109) - #142
Merged
Merged
Conversation
Adds the 16th WebHarbor mirror at https://discogs.com — the world's largest music release database and marketplace. Real catalogue of 7,042 releases / 5,031 artists / 3,938 labels / 6,825 master records pulled from the Discogs public API + MusicBrainz, plus 323 real album covers from Wikipedia. Backed by a benchmark community of 29 users with seeded ratings, reviews, collections, wantlists, lists, marketplace listings, and forum threads. Registered as the 16th site at port 40015. Image bumps to 16 mirrors total; EXPOSE 40000-40015. ## Site features - Release / master / artist / label / genre / style / format pages - Token-overlap scored search across releases, artists, labels with genre / style / format / year / country facets - Marketplace with media-condition + genre filters, per-listing comments, grades, currencies, sellers - User collection (5 folders: Uncategorized / All / Vinyl / CD / Wishlist Bought) with media + sleeve grades per item - Wantlist with min-grade preferences - User-curated public lists (CRUD) - Forums (10 topical boards) with threaded replies - Rating (1-5) + Review submission with helpful counts - Auth (Flask-Login + bcrypt + CSRF), register / settings / logout - 20 WebVoyager-format tasks in sites/discogs/tasks.jsonl ## Data scale - releases: 7,042 (3,522 from Discogs API + 3,520 from MusicBrainz) - artists: 5,031, labels: 3,938, masters: 6,825 - ratings: 86,714, reviews: 3,253 - collection_items: 4,207, wantlist_items: 1,374 - lists: 40, listings: 2,640, threads: 43, posts: 333 - benchmark users: alice_crate, bob_vinyl, carol_jazz, dave_techno (passwords: alice12345 / bob123456 / carol12345 / dave12345) - + 25 collector-style users with realistic locations & seller status ## Determinism work - MIRROR_REFERENCE_DATE = datetime(2026,5,26) pins all date fields so re-seeding from scraped_data/ is bit-for-bit reproducible - random.Random(42) seed for the community generator - Idempotent gates on every seed_*() function (count() > 0 → early return); byte-identical reset verified ## Verification - Docker build green; all 16 sites return 200 - POST /reset/discogs keeps DB byte-identical to seed - All 20 tasks pass when walked via Playwright (Chromium) ## Paired Hugging Face assets - Heavy assets shipped via the ChilleD/WebHarbor HF dataset: - sites/discogs/instance_seed/discogs.db (13 MB) - sites/discogs/static/images/release/*.jpg (323 covers, 32 MB) - .assets-revision is left at `revision: main` so the HF merge will roll in automatically (same approach as TED / Phys.org PRs).
The Owner compared the mirror with discogs.com side by side and rejected the homepage: the top menu was completely different, the release rows used a scrollbar instead of the live prev/next arrows, the footer differed substantially, and the pages behind the benchmark tasks did not follow the original site closely enough. Measured the live site as a guest at 1440px (full-page captures, shadow-DOM markup for the header and footer components, computed styles for ~90 elements) and rebuilt against those measurements: - Header: the live two-row structure, the search component with its category panel, the cart and Sign Up / Log In controls, and the five dropdown menus with all 33 destinations. Menus are native <details>, so they work with or without JavaScript; narrow widths collapse to the live drawer. - Homepage: hero, three release carousels and the app promo in the live order. Carousels page with prev/next buttons and bullets instead of a scrollbar, and the cards carry the live field set. The homepage community block, which the live site does not have, is gone. - Footer: the live three-column plus social layout, labels, social icons, newsletter form, app badges, language selector, legal links and the keyboard shortcuts dialog. - Task-path pages: search results with entity tabs and in-result facet counts, release detail with the live two-column layout and right rail, marketplace with the You Selected chips and seven facet groups, List Explorer, list detail, forum index, board, thread, login and register. - Twelve routes added so every menu and footer destination resolves locally, plus marketplace format/ships-from/year/price filters and label, catalog number and barcode filters behind an advanced search form. Ranking carousels are computed from the benchmark's own marketplace and collection state and labelled as such; no source ranking is fabricated. Route paths and query parameter names used by verifiers are unchanged, the seed database is untouched and reset stays byte-identical. 48/48 application tests and 23/23 verifier-contract tests pass.
The footer newsletter input carried name="email", which collided with the register form's own email field on /register, so a form-filling agent saw two elements named "email" on that page. The live Discogs footer input has no name attribute; match it. Found while re-walking the 15 task paths on the repaired UI. 48/48 application tests pass.
Matching the live search card meant showing the full format description, which put "Album, Dolby System" and "Album, Repress" on the results page. Task 3 asked for exactly that descriptor plus each release ID, so two of its three facts became readable without opening either detail page, while the verifier still demanded both detail visits. That is a task-versus-verifier contradiction: a completion the question allows was rejected by a navigation condition the question never stated. Re-anchor the task on identifier facts that only the detail pages carry. One of the two Spanish 1978 cassettes lists an extra "Impuesto de lujo" entry (Num. 6649) that the other does not, and both share a "Deposito Legal" value; neither appears on a search card. The question now asks for both release IDs, which edition carries the extra entry and its value, and the shared value. Replace the generic nearest-token association for this task with an explicit attribution check: the nearest release ID preceding the fact decides the binding, so a swapped answer fails even though every requested token is present. Proximity alone did not do this, because sentence order could place the correct ID closer than the wrong one. Tests: swapped-binding and results-page-only answers now fail, a second natural paraphrase passes, and the full verifier suite plus 48 application tests pass.
The verifiers accepted a step URL only when its port was exactly 40024. That pinned grading to one operator choice while implementing no control: the adversarial test that justified it rewrites the origin to https://attacker.invalid, which differs in scheme and host, so the port never took part in rejecting it. It also made the workflow AGENTS.md prescribes ungradeable, since that guide runs the image on 41000+ when the default range is busy. Replace it with checks on what actually matters, asserted explicitly on every task rather than used as a silent filter: no_foreign_origins any non-loopback step fails single_origin a trajectory spanning two origins fails origin_matches_expected optional exact pin via WHR_EXPECTED_ORIGIN single_origin rejects a trajectory stitched together from two local services, which the port pin could not detect at all. Tests: all 15 tasks grade identically when re-hosted on 127.0.0.1:41024; the foreign-origin spoof still fails all 15; a mixed-origin trajectory fails all 15 with reason single_origin; the optional pin accepts its origin and rejects another. Suite 24/24. Also make the fixture's subprocess cap WHR_VERIFIER_TIMEOUT (default 180s). A verifier takes ~19s on a host running many environments at once, and the old 30s cap failed runs for lack of CPU rather than for verifier behaviour.
main added two sites since this branch's base, so the three registration
places conflicted and discogs no longer fits at index 24 -- FedEx holds that
index, and therefore port 40024, on main. Appending discogs after webmd_doctor
puts it at index 26, port 40026, with 27 sites in the image.
Resolved by appending discogs last in websyn_start.sh, control_server.py and
the Dockerfile EXPOSE range, then following the consequences:
tasks.jsonl web -> http://localhost:40026/ in all 15 rows
test_environment_quality.py asserts that value; would have failed
test_verifiers.py fixture origins moved off 40024 (now FedEx), which
changes nothing about what is tested
docs port range and site count in README, CONTRIBUTING,
AGENTS, CLAUDE, agent_demo/README and the skills;
README's site list now names Discogs
The site itself is untouched by the merge: app.py, templates, seed database and
verifier logic are identical, so the questions, answers and acceptable paths do
not change. Grading is origin-agnostic -- it requires only that every recorded
step share one loopback origin -- so the frozen task executions remain valid
across this port move.
Verified on the merged tree: discogs application suite 48/48, verifier and
environment-quality suites 27/27. The 27-site integration build is not re-run
here; assets for twelve sites are absent locally and the host lacks the space.
…se relative times Two defects found while walking the authenticated task paths against the live site. "All" is the unfiltered view, not a folder, but it sat in COLLECTION_FOLDERS. So it was offered in the folder select, accepted by the write path, and then unreachable: the collection list treats folder == "All" as "do not filter", so a row stored with that folder could never be viewed as a folder again. Confirmed by posting one and finding it in the database. The template also rendered the tab row as ["All"] + COLLECTION_FOLDERS, which duplicated the tab. The sentinel now has its own name, UNFILTERED_FOLDER, and the template takes it from the route instead of hard-coding the literal a second time -- that duplication is what allowed the two meanings to drift apart. Relative timestamps had no singular form, so the forum showed "1 years ago", and the minute unit was abbreviated. Live Discogs writes "1 day ago" and "12 minutes ago", per the captured reference pages. Tests: three regressions covering the enum, a rejected folder writing no row, the tab row listing "All" exactly once, and eight relative-time cases. Application suite 51/51, verifier and environment-quality suites 27/27.
…ex 28
main added two more sites since the last merge, and Healthline took index 26 --
the slot discogs held. Appending discogs after Kaggle puts it at index 28, port
40028, giving 29 sites in the image.
Conflicts were the same three registration places plus the port range and site
count in the docs, all resolved by taking main's text and then adding the 29th
site on top of it. Nothing in sites/discogs/ conflicted.
Followed through, as before:
tasks.jsonl web -> http://localhost:40028/ in all 15 rows
test_environment_quality.py asserts that value
test_verifiers.py fixture origins moved off 40026 (now Healthline)
docs range and count in README, CONTRIBUTING, AGENTS,
CLAUDE, agent_demo/README and the skills; README's
site list now names Discogs
The site is untouched by the merge: app.py, templates, seed and verifier logic
are identical, so the questions, answers and acceptable paths do not change.
Grading requires only that every recorded step share one loopback origin, so the
frozen executions remain valid across this second port move.
Application suite 51/51 on the merged tree.
Merge upstream main at 7ace1c7, preserve NVIDIA at index 28, and append Discogs at index 29 (port 40029). Update registry declarations, task URLs, verifier fixtures, and active documentation to the 30-site range.
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.
Discogs Search and Marketplace pagination now retain filters, narrow-screen Marketplace layout no longer overflows, and task grading rejects swapped facts and contradictory answers. Tasks 4 and 6 require meaningful two-release comparisons; all 15 tasks retain natural answer formats.
Based on original contribution #34 by @hqhq1025 and reviewer continuation #109 by @jackjin1997. Merge order is #34 → #109 → this follow-up, using regular merge commits. Discogs is registered at port 40046; all previous site ports are preserved.
Required assets are integrated: HF #24 and HF #76 are merged. The code pins immutable merged revision
ebe2e47a2ce53196ab8a4b18f22b56c7082b5004; all 50 pre-existing dataset files remain unchanged.Validation: fresh 47-site asset fetch and manifest verification; full Docker build; 47 healthy sites and 47 HTTP-200 homepages; 83 tests and 398 subtests; 15/15 preserved browser runs regraded by the official deterministic evaluator; fresh Chromium pagination/mobile checks; real UI mutation followed by byte-identical reset and restart. See
review-reports/discogs-pr109-integration.mdfor evidence and infrastructure workarounds. No image publication or deployment.