> **Delta Spec**：本文件仅描述对 `openspec/specs/polling-stop-resume-logic/spec.md` 的变更部分。未提及的需求保持不变。

---

### 变更：not_realname 停机范围——从设备维度缩小为单卡维度

**原行为**：`EvaluateAndAct` 在非独立卡（`is_standalone=false`）触发停机时，无论停机原因如何，均调用 `stopDeviceCards` 停机整个设备的所有在线卡。

**新行为**：仅当停机原因为 `no_package` 或 `traffic_exhausted`（设备共享资源）时，才调用 `stopDeviceCards`；当停机原因为 `not_realname` 时，调用 `stopCardWithRetry` 只停被评估的单卡。

#### Scenario: not_realname 只停单卡，不连坐已实名卡
- **GIVEN** 设备 D 下有卡 A（`real_name_status=0`，在线）和卡 B（`real_name_status=1`，在线）
- **WHEN** `EvaluateAndAct` 对卡 A 执行，`checkStopReasons` 返回 `["not_realname"]`
- **THEN** 调用 `stopCardWithRetry(cardA, "not_realname")`；卡 A 停机；卡 B 保持在线，`network_status` 不变

#### Scenario: no_package 仍走设备维度停机
- **GIVEN** 设备 D 下有卡 A 和卡 B 均在线，设备无有效套餐
- **WHEN** `EvaluateAndAct` 对卡 A 执行，`checkStopReasons` 返回 `["no_package"]`
- **THEN** 调用 `stopDeviceCards(deviceID, "no_package")`；卡 A 和卡 B 均被停机（设备维度停机保持不变）

#### Scenario: 优先级 no_package > not_realname 时仍走设备维度
- **GIVEN** 卡 A（未实名 + 无套餐），卡 B（已实名）均在线
- **WHEN** 卡 A 的 `checkStopReasons` 返回 `["no_package", "not_realname"]`，`primaryReason = "no_package"`
- **THEN** `isDeviceScopeReason("no_package") = true`；调用 `stopDeviceCards`；卡 A 和卡 B 均停机

---

### 新增：carrier_stopped——运营商侧停机原因

新增常量 `StopReasonCarrierStopped = "carrier_stopped"`，表示由运营商/Gateway 侧主动停机（非本系统发起）。

**与现有停机原因的区别**：
| 原因 | 触发方 | 自动复机 |
|------|--------|----------|
| `no_package` | 本系统轮询 | ✅ 是 |
| `traffic_exhausted` | 本系统轮询 | ✅ 是 |
| `not_realname` | 本系统轮询 | ✅ 是（实名完成后） |
| `manual` | 管理员手动 | ❌ 否 |
| `carrier_stopped` | 运营商/Gateway | ❌ 否（需人工确认） |

#### Scenario: carrier_stopped 不触发自动复机
- **GIVEN** 卡停机，`stop_reason='carrier_stopped'`
- **WHEN** 下次轮询调用 `EvaluateAndAct`
- **THEN** `isPollingStopReason("carrier_stopped") = false`；跳过复机逻辑；卡保持停机状态直到管理员手动处理
