# R2.2.12 任务报告

## 结果

已为 runtime-manual 账号 `https://sub.yjxm1221.top plus 0.025`（ID 27）下发精确 `Input must be a list` 临时不可调度规则：

- statusCode：400
- keyword：`input must be a list`
- duration：1分钟
- 行为：命中后当前账号短时冷却，当前请求返回 `UpstreamFailoverError` 进入切号。

未使用通用400匹配，避免把真实客户参数错误错误切号。

## 所有权与配置

- owning YAML：`config/platform-infra/sub2api-codex-pool.yaml`
- 模板：`codex-upstream-failover`
- 账号管理类型：`runtime-manual`
- 下发方式：精准 `runtime apply --account 27 --template codex-upstream-failover --confirm`
- 未把账号27加入 YAML managed profiles，也未运行全量 `sync`。

为避免模板覆盖账号27既有运行规则，YAML模板同时对齐了其已有：

- 429 `upstream rate limit exceeded`
- 504 `concurrency limit exceeded` / `upstream service temporarily unavailable`

最终规则从6条增至7条，保留429、500、502、503、504、524，仅新增精确400。

## 源码确认

Sub2API v0.1.153 普通400进入 `handleErrorResponse` 后会调用 `handleOpenAIAccountUpstreamError`；`RateLimitService.HandleUpstreamError` 在默认400处理前执行 `tryTempUnschedulable`。规则命中返回 `shouldDisable=true`，OpenAI gateway 构造 `UpstreamFailoverError`，因此既冷却后续调度，也会为当前请求触发切号。

## 执行证据

Dry-run：

- account：`https://sub.yjxm1221.top plus 0.025` / 27
- change：update
- beforeRules：6
- afterRules：7
- beforeCodes：429,500,502,503,504,524
- afterCodes：400,429,500,502,503,504,524

确认下发：`mutation=true`。最终 `runtime get`：

- management：runtime-manual
- schedulable：true
- matching rule count：7
- status codes：400,429,500,502,503,504,524
- pool mode：false

## 短窗口

下发后5分钟只读窗口：

- `unidesk-codex-pool`：43请求、0客户错误、客户错误率0%。
- 账号27：7次尝试、7次成功、0失败。
- 窗口内没有自然出现新的 `Input must be a list`，因此尚未观察到真实 `account_temp_unschedulable` 命中；不能把“零命中”解释为规则无效。

## 验证

- 精准 runtime apply dry-run通过。
- 精准 runtime apply confirm通过。
- 逐账号 runtime get对账通过。
- `git diff --check`通过。
- 未发送错误探针，未修改proxy、账号凭据、priority、capacity、membership或其他调度配置。
