Files
autoreg-skills-max/skills/ai-provider-autoreg/references/isadev-github-pr-domain-farm.md

11 KiB
Raw Blame History

is-a.dev (GitHub PR subdomain registry) — масс-фарм доменов через API

Класс: subdomain-реестры, где домен выдаётся через PR в публичный репозиторий (is-a-dev/register). Цель — получить домен, ЧИСТЫЙ в disposable/free-domain blocklist'ах, для таргетов с work-email валидацией (Daytona и подобные).

Почему is-a.dev

  • is-a.dev отсутствует в основных blocklist-базах (disposable-email-domains, ivolo) — в отличие от *.loc.cc, nl8.eu, t-online (режутся финальной валидацией) и disposable-доменов (режутся на signup).
  • Регистрация бесплатная и автоматизируется полностью через GitHub REST API (PAT), без браузера.
  • Узкое место — merge мейнтейнером (ревью волнами); закладывать часы/дни до живого домена.

Механика одного домена (API-only, на живой PAT)

  1. GET /user — проверить токен И получить РЕАЛЬНЫЙ login (пул-файлы могут содержать устаревшие login'ы).
  2. Имя домена = нормализованный login ([^a-z0-9-] → -, ≤25 символов, начинать с буквы).
  3. GET repos/is-a-dev/register/contents/domains/<name>.json — 200 = занято, пробовать <name>-dev.
  4. Создать сайт-репо <name>-site (auto_init) + PUT contents/index.html (любой валидный HTML про "personal developer blog") + POST /pages — PR-бот проверяет наличие website.
  5. POST repos/is-a-dev/register/forks → поллить GET repos/<login>/register до 200 (fork создаётся асинхронно, до 8×3с).
  6. Ветка от upstream main: GET repos/is-a-dev/register/branches/main → POST git/refs на форке.
  7. Commit domains/<name>.json — записи под forwardemail.net (DNS-only forward, безлимитный на free-плане; ImprovMX free = 1 домен на аккаунт и масс-фарм не масштабирует):
{"owner": {"username": "<login>", "email": "<login>@users.noreply.github.com"},
 "records": {"MX": ["mx1.forwardemail.net", "mx2.forwardemail.net"],
            "TXT": ["forward-email=<catchall-target>@gmail.com",
                    "v=spf1 include:spf.forwardemail.net ~all"]}}

Поле — ОБЯЗАТЕЛЬНО records (множественное): репозиторий сменил схему, PR со старым record CI молча закрывает без мержа (выглядит как человеческий реджект — причину видно только в job-логе GET repos/is-a-dev/register/actions/jobs/<id>/logs). Перед любым фармом сверь текущую схему по свежему merged-примеру: raw.githubusercontent.com/is-a-dev/register/main/domains/<name>.json. Старые PR с ImprovMX-записями чинятся пост-фактум: GET /pulls/<n> → head repo+branch → GET contents/domains/<name>.json?ref=<branch> (нужен sha) → PUT с новым record. 8. Тело PR ОБЯЗАНО пройти Template-check: скачать .github/PULL_REQUEST_TEMPLATE.md, заменить все - [ ] → - [x], вставить website-URL между WEBSITE_PREVIEW_START/END и purpose между WEBSITE_PURPOSE_START/END (regex — в шаблоне CRLF). Без этого PR висит непроверенным. 9. POST /pulls (head <login>:<branch>, base main). 422 имеет два разных смысла — читать message: «A pull request already exists» = дубль от предыдущего прогона (найти существующий через GET /search/issues?q=repo:is-a-dev/register is:pr is:open author:<login> и считать успехом, иначе retry-батч сжигает токены впустую); «sha wasn't supplied»/validation = ветка/коммит не подхватились, проверить шаги 6-7; 404 «Not Found» на валидном токене и существующей ветке = account-level GitHub spam-блок (см. питфолы), а не баг кода.

Масс-режим

  • Рабочий пул токенов: СВЕЖИЙ audit-файл (проверка ниже). Один токен = один домен.
  • ThreadPoolExecutor(3), done-set персистится после каждого результата (резюм), output — JSONL со stage-меткой. Конкурентность >3 упаривается в 429 на fork/repo-эндпоинтах (второй бёрст подряд даёт волну fork_fail:429 и yield падает с ~97% до ~70%).
  • Каждый пишащий шаг (git/refs создание ветки, contents PUT) оборачивать в retry-цикл 3-4× с sleep 8-20с: 429/409/«sha wasn't supplied» — транзиентные рейсы, а не перманентные отказы.
  • Yield на живых токенах: ~97% PR. На password+TOTP → браузерная генерация PAT yield низкий (~25%) — не масштабировать браузерный путь, если есть живые токены.
  • Мерж НЕ автоматический: мониторить GET repos/is-a-dev/register/pulls?state=open&head=<login>:<branch>; один мейнтейнер-бот может смержить PR сразу после Template-check, но рассчитывать на дни.
  • После мержа: домен живёт на DNS is-a.dev; при forwardemail-записях почта уже работает (forward — чисто DNS, настраивать нечего) — прогнать тест probe@<домен> → IMAP Gmail, затем ОДИН полный авторег-цикл до дашборда таргета, прежде чем включать bulk.
  • Прямой GitHub OAuth у таргетов с WorkOS (Daytona) — отдельная от домена проблема: idp_access_denied даже на GitHub-акках с НЕ-gmail почтой (outlook/hotmail/t-online проверены). Домен-путь (email+код на своём домене) — единственный рабочий; GH-пул тратить на PR-фарм, а не на OAuth-попытки.

Питфолы

  • Свежесть пула решает всё. Старые token-файлы (all_tokens_LIVE.json 1465 шт, pw_alive.json, PAT'ы внутри gh_union_accounts.json) дали 0 живых из 40-80 пробы; свежий audit gh_alive_FIXED_0810.json — 40/40 из 1135. Перед масс-фармом: прогнать 40-токенную пробу GET /user по КАЖДОМУ файлу-кандидату и брать самый свежий по mtime/имени.
  • Заголовок Authorization. Терминальный вывод и write_file маскируют литерал схемы авторизации → битый заголовок даёт 401 на ВАЛИДНОМ токене (pitfall 20d). Собирать конкатенацией.
  • 409/422 на PR чаще = fork/branch/commit не успели создаться, а не дубль PR; сначала перечитать состояние форка.
  • commit_fail «sha wasn't supplied» = POST git/refs не прошёл (429/рейс) и contents PUT ушёл в несуществующую ветку — ретраить создание refs, а не commit. Надёжный фолбэк вместо contents PUT: git data API цепочкой POST git/blobs → POST git/trees (base_tree=upstream sha) → POST git/commits → PATCH git/refs/heads/<branch> (force) — не зависит от того, успела ли ветка создаться.
  • done-set чинить только по PR-успехам: при рескрипте state-файла сохранять в done ТОЛЬКО login'ы со stage=PR; записанные туда fail'ы исключают аккаунт из ретрая навсегда, и батч молча теряет десятки токенов.
  • done-set и tokmap сравнивать case-insensitively (login.lower()): GitHub-логины регистрозависимы в API, но пул-файлы и done-сеты из разных прогонов расходятся регистром — без нормализации живые токены повторно уходят в dup-PR 422.
  • Не батчить несколько доменов в один PR «чтобы быстрее» — Template-check проходит, но один проблемный файл топит весь PR; per-domain PR изолирует отказы.
  • Масс-фарм провоцирует account-level GitHub spam-блок: POST /pulls отдаёт 404 «Not Found» (не 403) на ВСЕ акки пула сразу. Диагностика: тот же токен успешно создаёт issue/PR в СВОЁМ репо, а в is-a-dev — 404; мержи чужих PR у мейнтейнеров при этом продолжаются (блок на акках-авторах, не на репо). ~200+ однотипных PR за день — достаточный триггер; лок держится дни. Закрытые PR не reopen-ятся и force-push в их ветки запрещён. Новый PR требует УНИКАЛЬНОГО имени ветки (diverged старая ветка тоже даёт 404): всегда DELETE git/refs/heads/<branch> → создать заново от свежего upstream main sha → commit → PR. Темп фарма держать низким/разносить по дням, иначе пул токенов сгорает впустую.

Скрипты

  • tmp/_isadev_farm_api.py — рабочий API-only масс-фарм (token-файл → repo/pages → fork → branch → commit → PR; done-set + JSONL).
  • tmp/_gh_patgen.py — браузерная генерация PAT из password+TOTP (низкий yield, фолбэк).
  • tmp/isadev_gh_tokens.json — живой пул токенов (login+token).
  • Публичная репа всего пайплайна (scrubbed): github.com/ExaAutocratHunt65/daytona-isadev-autoreg — farm + fixold + daytona_reg2 + daytona_gh_reg + README с цепочкой и стенами. Копия локальных скриптов на случай чистки tmp; секретов не содержит.