Repository navigation
Atomic output, CSV formula guard, one paid solve per page, typed --category wins over SLEEPNUMBER_URL - #7
Merged
Merged
Conversation
…tegory wins - JSON, CSV and the sidecar are written to a temp file in the target's directory, fsynced and renamed; a failed write no longer truncates the previous good file. New files take 0o666 & ~umask, existing ones keep their mode. - CSV string cells starting with = + - @ TAB CR LF get a leading apostrophe (CSV only); the sidecar records csv_cells_escaped, merged under the caller's extra. - page_flow.SolveBudget: one paid solve per page across every retry and exit rotation, claimed immediately before the purchase, in all three browser engines. - The credential scan tests repo-relative paths, fails on zero files, and reads .json/.csv/.toml/.cfg/.ini and renamed .env copies. - A typed --category wins over SLEEPNUMBER_URL; --url plus --category is a usage error. .env.example ships SLEEPNUMBER_URL commented out. - --pages/--concurrency >= 1, --delay/--retry-delay/--proxy-block-retries >= 0 in every entry point. - pyppeteer passes the goto status and headers to the classifier. - The canary fails with an error naming SLEEPNUMBER_PROXY instead of skipping green. - Comments describing other sites' measurements as this site's are corrected; references to private notes are replaced with the rule in the repo's own words, with a suite guard. - Docker image carries http_scraper.py; CI tests Python 3.13. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jehrr
marked this pull request as ready for review
October 15, 2026 22:20
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.
Works through the 2026-10-14 audit of
mainat1ded84e(v0.2.0). No open PRs overlapped.Problems and resulting behaviour
main)write_json/write_csv/write_run_metausedopen(path, "w"). A failure insidejson.dumpturned a 559-byteout.jsoninto 13 bytes of invalid JSON, and clobbered the sidecar too._atomic(): temp file in the target's dir, flush + fsync,os.replace, unlink on error,newline=""kept for CSV. New file0o666 & ~umask; an existing file keeps its mode.= + - @ TAB CR LFget'in CSV only. Numbers and JSON are untouched.csv_cells_escapedgoes in the sidecar, merged UNDER callerextra. Fires on 0 of 362 string cells in the committed sample and fixtures.page_flow.SolveBudget(SOLVES_PER_PAGE=1)is created once per page before the retry/rotation loop and passed to the only solve call site in each of the three browser engines.claim()happens immediately beforesolve_recaptcha, so detecting nothing or having no key spends nothing. A failed purchase still counts.path.parts: a clone undervenv/scanned 0 files and printed the clean line..env.bakand.jsonwere never read.path.relative_to(REPO).parts, and a scan of 0 files fails..json .csv .toml .cfg .iniand.env.*(renamed copies) are read;.envitself is not, since it is meant to hold the user's real key. Now 43 files are scanned, all clean.SLEEPNUMBER_URLsilently replaced a typed--categoryin every engine.typed_urlis captured beforeenv_config.apply, thenpage_flow.resolve_start_url: typed--url> typed--category> env URL > default.--url+--categoryis a usage error..env.exampleships the variable commented out.CLAUDE.mdand about 90§citations in shipped files.test_no_private_citations_in_shipped_files(tokens assembled from pieces). Release notes for v0.1.0 and v0.2.0 and the released CHANGELOG sections had none, so nothing was edited there.SLEEPNUMBER_PROXY).::error::namingSLEEPNUMBER_PROXY. Exit 3/4/5/6 were already red. The thresholds are row floors plus parser properties; the discount share stays informational..env.examplesaid "the block tracks geography"..env.exampleand the README said credentials "last about a day".gotoResponse.classify, as in Playwright.http_scraper.py.--pages/--concurrencymust be ≥1;--delay/--retry-delay/--proxy-block-retriesmust be ≥0. This applies to all five CLIs, and argparse names the flag in the error.Evidence
Suite,
PYTHONDONTWRITEBYTECODE=1, no browser download:handle_captcha_if_present3 times against one budget with the detector and solver stubbed. Result: 1 solver call per engine.Real argparse of http, playwright, selenium and puppeteer with
SLEEPNUMBER_URL=…/mattresses --category furnituregives…/categories/furniture.--url X --category Ygives exit 2, and--pages 0gives exit 2.ci_checks.py --help-check --sample-check --secret-check --published-checkpasses.Controls. 19 planted faults, each applied with an assert that the edit changed the file, with
__pycache__cleared, and then restored. Each turned the suite red on the named check:open()inwrite_json: atomic check;chmodremoved: atomic check (umask 002/077);budget=: source check;spent += 1removed (selenium venv): behavioural check;path.parts: scan check;.env.names dropped: scan check;.jsondropped: scan check;typed_urlcaptured after apply: precedence check;positive_intaccepting 0: numeric check;--delay type=float: numeric check;CLAUDE.mdin README: citation guard;§in tools/capture.py: citation guard;The tree is green after restore.
No paid calls, no proxies, no credentials, no requests to sleepnumber.com.
Not changed, and why
page_flow.should_solve/ thesolvepolicy column is still unread by the engines (F10). Owner decision: wire it or delete it.scraper_api_client.py --categoryis a row LABEL there, not a URL builder, so the env-URL precedence change does not apply to it.[Unreleased]with a behaviour-change blockquote.SLEEPNUMBER_PROXY(a residential exit) is set. This is intended: before, it was green without ever reaching the site.🤖 Generated with Claude Code