Files
autoreg-skills-max/skills/ai-provider-autoreg/references/gh-regkit-prime-camoufox-runner.md

5.3 KiB

gh-regkit-prime: Camoufox multi-stage GitHub runner — pitfalls & ops

Stack: Camoufox (Firefox anti-detect) + mail.cx (mailcx provider) + multi-stage runner (reg → email verify → auto-login → repo → 2FA TOTP → PAT → profile). Project: Desktop/_PROJECTS/gh-regkit-prime, repo gbonnet65923/gh-regkit-prime. Account line format: email----password----username----totp_secret----has_recovery----pat.

Batch operations (CRITICAL)

  • NEVER run two registration batches concurrently — they share the exit IP, GitHub DataDome bans it fast and accounts come out suspended. Before launching, enumerate and kill leftovers.
  • Filter processes by main.py substring ONLY, not by project path — the CommandLine of a batch started with a relative path (cd project && python main.py) does not contain the project directory, so a path in CommandLine filter silently misses it and duplicate batches keep running.
  • Enumerate/kill on Windows (wmic is unreliable here): powershell Get-CimInstance Win32_Process -Filter "Name='python.exe'" | ConvertTo-Json, parse JSON in Python, taskkill /F /T /PID.
  • Run batches with background=true + heartbeat; report OK/FAIL from the heartbeat log, verify saves by wc -l accounts/github_accounts_*.txt (a successful log line without a saved row means the crash happened before persistence — see salvage below).

Signup form

  • mail.cx issues short local-parts (4 chars) → derived usernames collide constantly. Pad any local-part shorter than ~10 chars with random alnum BEFORE the first attempt.
  • "Create account stayed disabled after validation wait" is AMBIGUOUS: it can mean octocaptcha pending OR username taken (a taken name keeps the button disabled forever). Probe the username-error element first and raise a distinct "username taken" error → caller retries with a fresh random suffix in-place. Treating it as transient and reloading the page WITH THE SAME DATA burns all page-reload attempts for nothing.

2FA (TOTP) stage

  • The wizard keeps hidden twin otp inputs in the DOM; locator(...).first resolves to an INVISIBLE one and fill() hangs "element is not visible" until timeout → stage fails. Iterate candidates checking is_visible() and is_editable(); last-resort fill via JS el.value=code + dispatch input/change on the offsetParent!==null element.
  • TOTP secret is frequently absent from innerText (dialog closed / rendered as QR). Parse it from page.content(): look for otpauth://totp/...secret=[REDACTED] in BOTH percent-encoded (secret%3D) and plain form, then fall back to a bare [A-Z2-7]{16,32}` scan.
  • Recovery codes: scrape from the DOM first. SKIP the file download entirely when the DOM scrape succeeded — Firefox/Camoufox download handling intermittently hangs the whole 2FA wizard (user-visible symptom: hang at the backup-download step).
  • GitHub regenerates the TOTP secret on every load of the setup page — read the secret only from the page you actually submit the code on.

PAT stage

  • The ghp_... token often lives in HTML attributes (<code>, clipboard-value), not in innerText. Search _page_text(page) first, then page.content(), then wait ~5s and retry both — a single innerText search reports "token not found" on success.
  • Any helper called from the PAT function needs its own local import (import re as _re inside the function) — module-level re may not be imported in this codebase shape; a NameError here kills the stage after the token was already generated.

Crash salvage (account-saving checkpoint)

  • The browser/driver can crash ("Connection closed while reading from the driver", WebGL out-of-memory) AFTER the account is verified and logged in. If credentials are only persisted at the very end, the account is lost. Set a checkpoint dict (pending["active"]=True, pending["username"], email) at the start of the finalize stage, and in the outer exception handler salvage a record line from it when the checkpoint is set. Thread the pending dict through the post-form flow function.

Proxies / DataDome

  • Free HTTP pool (~125 live) gives roughly 30-60% yield; failures are DataDome challenge pages and dead-proxy connect timeouts. When the home IP itself gets DataDome-banned ("email form did not appear (DataDome challenge page); IP is blocked"), only IP rotation helps — residential proxies.
  • 1024proxy.com residential: the marketing/pricing site is Cloudflare-blocked from a banned/flagged home IP — open it through Camoufox routed via one of the free pool proxies to read prices. Wallet balance alone does NOT enable the gateways: the white API (white.1024proxy.com/white/api?region=US&num=N&time=M&format=0&type=json, cookie zero_sid auth, navigate not fetch — CORS) returns "Insufficient traffic" until a traffic package is purchased; gateways answer raw CONNECT with 407. Purchase only via the dashboard UI (Buy button); raw api.1024proxy.com calls from Python return "re-login" errors — they need the browser session context.

Config knobs that silently disable stages

  • create_repo, set_profile_status, complete_profile can be False in config.json even when the dataclass defaults are True — a warmed-up account (profile + first repo) requires flipping them explicitly in config.json AND restarting the batch (a running process holds the old code/config in memory).