# 错误重试分层策略（步骤 4/8/9/自动运行）

本文档说明当前实现中的三层重试语义，避免把“当步重试 / 小循环重试 / 大循环重试”混在一起理解。

## 1. 第一层：当步重试（Step 内部）

定义：不离开当前步骤，在当前页面链路内恢复或替换资源。

典型位置：
- `background/steps/fetch-signup-code.js`（步骤 4 页面恢复）
- `background/steps/fetch-login-code.js` + `background/verification-flow.js`（步骤 8 邮箱轮询与重发）
- `background/phone-verification-flow.js`（步骤 9 号码轮换、重发、回到 add-phone）

常见动作：
- 点击 `Try again` 恢复 405/重试页；
- 同一步内重新拉验证码；
- 步骤 9 内直接换号（不立刻回步骤 7）；
- 同提供商/同国家内换价格档位或换号码。

## 2. 第二层：小循环重试（授权链路重开）

定义：当前轮次内回到授权链路起点（通常步骤 7），再走 7→8→9。

触发来源：
- `background.js` 的 `getPostStep6AutoRestartDecision(...)`；
- 步骤 8 检测到邮箱通信异常且当前链路连续重试超限；
- 步骤 9 触发 `PHONE_RESTART_STEP7` 类错误（例如回调窗口过期/链路不可恢复）。

特点：
- 还是同一“轮次”；
- 不进入线程间隔（20 分钟）；
- 优先用于“流程状态错位/页面链路失效”类问题。

## 3. 第三层：大循环重试（自动运行 attempt/round）

定义：由自动运行控制器决定是否进入下一次 attempt，或等待线程间隔后继续。

位置：
- `background/auto-run-controller.js`

关键点：
- `autoRunSkipFailures=true` 时，允许同轮多次 attempt；
- 某些错误会被视为“本轮直接失败并跳过剩余重试”；
- 若配置了线程间隔，会出现“等待 N 分钟后第 x 次尝试”日志。

## 4. 错误分类优先级（当前实现）

1) 先做当步恢复（能在步骤内闭环就不升级）
2) 当步失败后，再判断是否走小循环（回步骤 7）
3) 小循环仍失败，才交给大循环（attempt / round / 线程间隔）

## 5. 已落实的关键规则（与近期问题对应）

- `Failed to fetch / network error / fetch failed`：
  步骤 4/8/9 进入有上限的网络重试（当前默认 3 次，冷却 12 秒）。

- `Step 9: 5sim check activation failed: order not found`：
  归类为“号码失效”，在步骤 9 内立即换号（当步重试），不应直接触发线程间隔。

- `Route Error 405`（手机号验证码页）：
  优先当步恢复；若落入 route-405 循环，步骤 9 内换号。

- `add-phone / phone-verification` 页面状态：
  表示流程已进入手机链路，自动运行层默认不再盲目回步骤 7，避免破坏当前链路。

## 6. 关于“第几轮尝试 + 暂停”含义

- “第 x/y 轮第 n 次尝试”是自动运行控制器的外层 attempt 计数；
- “线程间隔：等待 20 分钟...”表示已经升级到第三层（大循环）；
- 用户手动停止会中断当前计划；恢复时是否回到步骤 7，取决于当前页面状态与回调是否过期：
  - 回调未过期且仍在可恢复链路：优先当前链路继续；
  - 回调已过期或链路断裂：回步骤 7 重拉授权。
