5.8 KiB
Success-record review and Luban one-by-one runner fixes (2026-05-11)
Why this review was needed
BOSS asked to deeply revisit the known phone-verification success records and compare them with the current Luban flow.
The immediate trigger was a Luban France event where a code was received but OpenAI stayed on phone-verification, followed by a one-by-one test that ended with:
{"bought":4,"sms_received":0,"sms_timeout":2,"submit_no_sms_page":2}
The current OpenAI page then showed 糟糕,出错了! on https://auth.openai.com/add-phone.
Success records reviewed
1. 5sim Vietnam success, 2026-05-10
Reference: openai-phone-free-country-vietnam-sms-success-codex2api-region-block-2026-05-10.md.
Key success properties:
- Strict country/area-code gate before buying and again before submit.
- Count only actual provider activations.
- If OpenAI reaches
phone-verification, poll provider. - Submit a strict 6-digit code.
- Consider phone success only when OpenAI leaves
phone-verificationand reachesabout-you/ profile.
2. 5sim Indonesia success at 335 activations, 2026-05-11
Reference: openai-phone-335-success-cpa-oauth-login-session-pitfalls-2026-05-11.md.
Key success properties:
- OpenAI phone codes should prefer strict 6-digit extraction.
- Do not mark provider activation as finished until browser leaves
phone-verification. - A wrong parser selected a 4-digit candidate from a provider blob; rechecking the finished activation and extracting a 6-digit code fixed it.
- After phone success, fill
about-youfields explicitly (name,age,birthday).
Defects found in the current Luban one-by-one flow
Defect 1 — submit-code method not identical to successful 5sim method
The current Luban runner used a generic setVal with plain Event('input') in one path. The successful 5sim submit used:
const input=document.querySelector('input[autocomplete=one-time-code], input[name=code], input');
const setter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;
input.focus();
setter.call(input, code);
input.dispatchEvent(new InputEvent('input', {bubbles:true, inputType:'insertText', data:code}));
input.dispatchEvent(new Event('change', {bubbles:true}));
click exact '继续';
Fix: use this exact method for OpenAI phone-code submit.
Defect 2 — Bad Request / OpenAI error state was not fatal enough
The one-by-one run continued country gates after OpenAI became:
title: 糟糕,出错了! - OpenAI
url: https://auth.openai.com/add-phone
The page had no usable country selector/tel input for later countries, producing repeated false country-gate failures.
Fix: add ensure_add_phone_ready():
- require
add-phoneURL, countryselect, and tel input; - reject pages whose title/body match
糟糕|出错|Bad request|unknown_error|HTTP ERROR; - try reload/direct navigate a few times;
- if still not ready, stop the runner before buying another number.
Defect 3 — Luban release retry was too shallow
France 34133707 initially returned:
停用失败,该供应商需要在:118 秒 后停止.
停用失败,该供应商需要在:43 秒 后停止.
The runner stopped retrying, requiring manual cleanup. Later manual check showed 该号码已释放.
Fix: reject_after_min_wait() now loops until:
success, or已释放, orwrong_status, or- hard retry deadline.
It parses provider messages such as N 秒 后停止 and sleeps accordingly.
Defect 4 — provider/channel ambiguity was under-logged
The current OpenAI phone page can show WhatsApp delivery text:
重新发送 WhatsApp 消息
The runner must log page channel (whatsapp, sms, unknown). If provider reports a code while page says WhatsApp, classify failures as ambiguous until provider raw fields and OpenAI error text are inspected.
Defect 5 — submit_no_sms_page must not be treated as SMS delivery evidence
If OpenAI stays on add-phone after submit but does not show an explicit phone reject, classify as submit_no_sms_page, hold for the minimum Luban release window, release, then recover page. Do not count it as phone-verification SMS timeout.
Implemented optimized runner
New script:
scripts/luban_one_by_one_phone_verify.py
Key behavior:
- Buys only one Luban request at a time.
- Validates OpenAI
add-phonereadiness before each country and before buying. - Stops instead of buying when the page is in Bad Request/error state.
- Holds unused Luban orders for at least 3 minutes before reject.
- Retries reject until success/already-released/wrong_status or hard deadline.
- Polls provider for strict 6-digit code.
- On SMS received, writes the code only to a local file and logs
sms_receivedwithout printing it. - Submits code with the proven 5sim InputEvent method.
- If submit fails, keeps page and provider order for retry and exits with
sms_submit_failed_hold_for_retry. - Does not set success unless OpenAI leaves
/phone-verification.
Run example:
PYTHONUNBUFFERED=1 MAX_BUYS=10 PHONE_POLL_SECONDS=220 MIN_HOLD_SECONDS=180 \
/Users/chick/homebrew/opt/python@3.11/bin/python3.11 \
/Users/chick/.hermes/skills/software-development/codex-oauth-plus-onboarding/scripts/luban_one_by_one_phone_verify.py \
| tee /tmp/luban_one_by_one_phone_verify.log
Optional priority override:
LUBAN_COUNTRY_PRIORITY='France,Vietnam,Portugal,Romania,Germany,Netherlands,Argentina'
Operational rule going forward
For Luban/OpenAI tests, use the optimized script above instead of ad-hoc /tmp/luban_one_by_one_stop_on_sms.py.
If the runner exits with sms_submit_failed_hold_for_retry, do not release the order and do not navigate away. Retry from the preserved page using the local code file and corrected submit helper.