Repository navigation
Mirror engines survive a block with no pool, solves stay within budget, canary is red unless it tested Etsy - #19
Merged
Merged
Conversation
… and the canary is red unless it tested Etsy - pyppeteer/Selenium: a t=bv block or a dead exit with no proxy pool (the --cdp-endpoint case) re-fetches instead of crashing on pool=None. - One per-page solve allowance covers the reCAPTCHA and DataDome call sites in all three engines, checked before each purchase. - A served page that states listings and parses to none is parser_found_nothing (exit 5/6, not 4 or a complete run); an HTTP 404/410 reaches the classifier as not_found (Playwright, pyppeteer). - New outputs follow the umask; existing files keep their mode. - Credential scan: exclusions relative to the repo, an empty scan fails, data files and .env.* backups are read (ignored ones warn). - .gitignore covers top-level and multi-page dumps and live/. - tests.yml runs ci_checks.py instead of inline copies. - Private-note citations removed from public files, with a guard. - Canary: weekly + on demand; exit 3/5/6 and a missing ETSY_CDP_ENDPOINT secret fail the job instead of going green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jehrr
marked this pull request as ready for review
October 15, 2026 21:14
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.
Fixes from the 2026-10-14 audit of
mainat8bc19c7, plus the owner's request that the canary only goes green when it actually tested etsy.com.Problem → behaviour now
1. Mirror engines crashed with no proxy pool (high). With no pool (the normal case over
--cdp-endpoint), Etsy's usual DataDomet=bvrefusal made pyppeteer and Selenium callpool.current/pool.advanceonNone. The run ended with a traceback and exit 1 instead of exit 3. pyppeteer did the same on a repeated load failure.Now: both re-fetch through the same access path without relaunching, as Playwright already did, and they rotate only when a pool exists. pyppeteer now rotates only for an unusable exit, matching its twins. A timeout has already had its
--retries.2. Paid solves exceeded the per-page limit. The reCAPTCHA check runs on every block-retry and was never counted. With the solver stubbed and no pool, one page bought 4 solves against
SOLVES_PER_PAGE = 1.Now:
page_flow.SolveBudgetis one object per page, shared by the reCAPTCHA and DataDome call sites in all three engines. It is checked immediately before each purchase and never reset by a retry or a rotation.3. A served page that parses to nothing was reported as an empty catalogue.
Now: a listing or shop page that Etsy itself says holds listings but yields 0 rows ends with
stop_reason: parser_found_nothing. "Says holds listings" means:numberOfItems> 0;initial_total_pages.That gives exit 5, or 6 after earlier pages. Before, the same page gave exit 4, or on page 2+ a
completerun with exit 0 holding page 1 only.4. The HTTP status never reached the classifier.
Now: Playwright and pyppeteer pass the navigation status to the classifier. The status is dropped once the document is replaced (by a solve or a DataDome interstitial resolving), so a stale 403 cannot mislabel the page. A 404 or 410 is a new
not_foundstate: final, not blocked, not parsed. On page 1 it gives exit 5; past page 1 it ends the listing. Selenium has no status and is unchanged.5. New output files ignored the umask. They were always 0644, including under umask 077.
Now: a new file gets
0o666 & ~umask, and an existing file keeps its mode. Tested under umask 022, 002 and 077 for JSON, CSV and the sidecar.6. The credential scan could pass over nothing. Exclusions were tested against absolute path parts, so a clone under any
venv/or.git/directory scanned 0 files and reported clean.Now:
.json,.html,.csv,.toml,Dockerfileand.env.*backups. A hit in a git-ignored file is a warning; anywhere else it fails.7. Housekeeping
.gitignorenow covers/*.html,*.page[0-9]*andlive/. A check confirms that shipped files and fixtures are not ignored.tests.ymlrunsci_checks.py --help-check --sample-checkinstead of inline copies that had drifted.diff_runs.pywas added to the CLI list, and a guard rejects inline local imports in workflows.captcha_solver.pycomment that described another site's hosts as Etsy's.8. Canary (owner request). Before: dispatch-only, skipped green with a notice when no secret was set, and treated exit 3, 5 and 6 as green warnings. The only run so far (2026-09-10) was a green skip.
Now:
ETSY_CDP_ENDPOINTsecret fails the job, and the error names the secret.This secret is required:
ETSY_CDP_ENDPOINT(a Scraping Browser API endpoint with a pid reserved for CI). It is not set today, so the canary is red until it is.Evidence
pip checkwas clean._fetch_one_pagethrough five cases:t=bvwith no pool;PYTHONDONTWRITEBYTECODE=1. Each one turned the suite red on the expected check, with no crash:/*.htmlremoved from.gitignore;Not changed
[Unreleased]): owner decision.--fingerprint,--proxyor--concurrencywith--cdp-endpoint: a behaviour change that needs owner agreement.--fingerprintand--localeare Playwright-only), unusedpage_bound,counts_as_blockedandpagination_is_addressable, and recounting thecf-turnstile/Akamai markers: low severity, left for a separate pass.not_found: no status, and there is no captured Etsy 404 body to key on..env.exampleETSY_URL:--categoryhere is a label, not a URL builder, so nothing is hijacked.🤖 Generated with Claude Code