Files
codex-oauth-plus-onboarding…/skill/codex-oauth-plus-onboarding/references/luban-one-by-one-runner-review-and-fixes-2026-05-11.md
T

151 lines
5.8 KiB
Markdown

# 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:
```json
{"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-verification` and reaches `about-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-you` fields 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:
```javascript
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:
```text
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-phone` URL, country `select`, 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:
```text
停用失败,该供应商需要在:118 秒 后停止.
停用失败,该供应商需要在:43 秒 后停止.
```
The runner stopped retrying, requiring manual cleanup. Later manual check showed `该号码已释放`.
Fix: `reject_after_min_wait()` now loops until:
- `success`, or
- `已释放`, or
- `wrong_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:
```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:
```text
scripts/luban_one_by_one_phone_verify.py
```
Key behavior:
1. Buys only one Luban request at a time.
2. Validates OpenAI `add-phone` readiness before each country and before buying.
3. Stops instead of buying when the page is in Bad Request/error state.
4. Holds unused Luban orders for at least 3 minutes before reject.
5. Retries reject until success/already-released/wrong_status or hard deadline.
6. Polls provider for strict 6-digit code.
7. On SMS received, writes the code only to a local file and logs `sms_received` without printing it.
8. Submits code with the proven 5sim InputEvent method.
9. If submit fails, keeps page and provider order for retry and exits with `sms_submit_failed_hold_for_retry`.
10. Does not set success unless OpenAI leaves `/phone-verification`.
Run example:
```bash
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:
```bash
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.