# VMess Domain / IP Rotator > 🚀 **Cloudflare 优选 IP / 域名全自动轮换系统** > 支持多源选优评分、双频自适应调度、Git 孤儿分支状态总线与路由器嵌入式闪存防擦写设计。 --- ## ⚡️ 核心模式总览 本项目针对不同运行环境提供三大解耦运行模式: | 运行模式 | 数据源 | 配置文件 | 运行时落盘路径 | 状态同步与发布 | 典型适用环境 | | :--- | :--- | :--- | :--- | :--- | :--- | | **服务器模式** | 远程监控 API | `configs/config.server.json` | `runtime/` | 自动提交并推送至 `runtime-state` 孤儿分支 | Linux VPS / 云服务器 (systemd) | | **本地 Python 模式** | 本机 `cfst` 测速 | `configs/config.local.json` | `runtime/` | 纯本地文件落盘,供本地工具/脚本直接读取 | 本地开发机 / 具备 Python 环境的 PC | | **BusyBox 路由器模式**| 路由器 `cfst` 测速 | `configs/config_router.conf` | `cfip_runtime/` 或 `/tmp` | 启动微型 HTTP 服务供局域网直接拉取 | 华硕梅林 / OpenWrt / 嵌入式路由器 | --- ## 📑 快速导航 - [1. 目录架构与输出约定](#1-目录架构与输出约定) - [2. 服务器模式(API -> 域名)](#2-服务器模式api---域名) - [2.1 快速执行](#21-快速执行) - [2.2 一键部署与服务管理 (systemd)](#22-一键部署与服务管理-systemd) - [2.3 Git 自动推送(Push)与凭据认证](#23-git-自动推送push与凭据认证) - [2.4 高峰/非高峰双频自适应调度](#24-高峰非高峰双频自适应调度) - [2.5 核心规则:筛选与评分策略](#25-核心规则筛选与评分策略) - [2.6 日志格式与日常维护速查](#26-日志格式与日常维护速查) - [3. 本地 Python 模式(本机 cfst -> IP)](#3-本地-python-模式本机-cfst---ip) - [4. BusyBox 路由器模式(路由器 cfst + HTTP)](#4-busybox-路由器模式路由器-cfst--http) - [4.1 目录拓扑与关键配置](#41-目录拓扑与关键配置) - [4.2 [最佳实践] 延长路由器闪存寿命(动静分离防擦写)](#42-最佳实践-延长路由器闪存寿命动静分离防擦写) - [4.3 自启动与看门狗脚本](#43-自启动与看门狗脚本) - [4.4 路由器部署包一键打包](#44-路由器部署包一键打包) - [5. Sub-Store 算子对接](#5-sub-store-算子对接) - [6. 自动化测试与质量门禁](#6-自动化测试与质量门禁) --- ## 1. 目录架构与输出约定 ### 1.1 物理目录分层 ```text vmess-domain-rotator/ ├── configs/ # 统一配置仓 (SSOT) │ ├── config.server.json # 服务器 API 模式配置 │ ├── config.local.json # 本地 Python cfst 模式配置 │ └── config_router.conf # 路由器 BusyBox shell 模式配置 ├── scripts/ │ ├── domain_updater.py # 顶层外观门面 (Facade CLI) │ ├── rotator/ # 核心领域解耦子包 (Python) │ │ ├── config.py / filter.py / sources.py / scoring.py / storage.py / notify.py / main.py │ ├── server/ # Linux 服务端运维脚本 │ │ ├── run_update_and_commit.sh # 调度器入口 + Git 提交与修剪 │ │ ├── install_debian.sh # 一键部署与 systemd 注册 │ │ └── uninstall_debian.sh # 一键安全卸载 │ └── router/ # 路由器 BusyBox 运行时 │ ├── router_local_update.sh # 测速调度与原子落盘 │ └── router_local_http.sh # 微型 HTTP 服务 ├── substore/ │ └── operator_template.js # Sub-Store 脚本操作符 ├── build_router_package.sh # 路由器一键打包脚本 └── tests/ # 32 项自动化测试套件 ``` ### 1.2 运行时输出文件契约 所有运行模式均产生统一结构的标准输出,保障下游消费一致性: | 产物文件名 | 文件说明 | 典型消费场景 | | :--- | :--- | :--- | | `current_domain.txt` / `current_ip.txt` | 纯文本格式的当前优选值 | 极简脚本、命令行直接读取 | | `current_domain.json` / `current_ip.json` | 完整 JSON 状态报告与候选池列表 | 详细分析面板、具备完整解析能力的客户端 | | `substore_vars.json` | 轻量键值对(`AUTO_DOMAIN` 或 `AUTO_CFIP`、`STATUS`、`UPDATED_AT`) | **Sub-Store 算子专用**(免去完整 JSON 解析开销) | | `state.json` | 持久化状态沉淀(记录 `last_good_domain` / `last_good_ip`) | **双轨容灾 Fallback**(异常或断网时平滑回退) | > [!NOTE] > **候选信息稀疏语义**:JSON 输出中的 `top_candidates` 仅在字段非空时输出真实键值(如 `avg_latency`、`loss_rate`、`download_speed`、`region`),彻底消除空字符串/空数组/`null` 占位污染。 --- ## 2. 服务器模式(API -> 域名) ### 2.1 快速执行 ```bash # 1. 仅执行 Python 选优并落盘(不执行 Git 提交) python3 scripts/domain_updater.py --config configs/config.server.json # 2. 执行完整调度(自适应时间检查 -> 选优落盘 -> 差异对比 -> Git 提交与推送) bash scripts/server/run_update_and_commit.sh configs/config.server.json # 3. 强制提交(忽略自适应时间拦截与内容未变防抖,强制生成 Commit 并推送) bash scripts/server/run_update_and_commit.sh --force-commit configs/config.server.json ``` --- ### 2.2 一键部署与服务管理 (systemd) 在 Debian / Ubuntu 等发行版上,通过 [`scripts/server/install_debian.sh`](file:///Users/aurora/Project/vmess-domain-rotator/scripts/server/install_debian.sh) 一键安装为 `systemd` 服务与定时器: ```bash sudo bash scripts/server/install_debian.sh [options] ``` #### 安装脚本参数详解 | 参数选项 | 默认值 | 参数说明 | | :--- | :--- | :--- | | `--config ` | `configs/config.server.json` | 配置文件路径(支持相对于仓库根目录的相对路径) | | `--interval ` | `30min` | 定时任务基础轮询间隔(`--offpeak-interval` 别名) | | `--peak-start ` | `19` | 晚高峰起始小时(`0-23`,如 19 代表 19:00) | | `--peak-end ` | `24` | 晚高峰截止小时(`1-24`,如 24 代表 24:00) | | `--peak-tz `| `Asia/Shanghai` | 高峰期时钟判定的参考时区 | | `--peak-interval `| `10min` | 高峰期域名更新间隔(如 `5min`、`10m`) | | `--offpeak-interval `| `30min` | 非高峰期域名更新间隔(如 `30min`、`1h`) | | `--user ` | 当前 `sudo` 用户 | 运行 systemd 服务的非 root 系统用户 | | `--group ` | 当前 `sudo` 用户组 | 运行 systemd 服务的系统用户组 | | `--git-push <0\|1>` | `1` | 选出新域名后是否自动推送到远端 Git 仓库 | | `--git-push-remote `| `origin` | 推送的 Git 远程分支仓库名 | | `--git-http-username `| `git` | HTTPS 认证用户名 | | `--git-http-token ` | 空 | HTTPS 访问令牌(用于非交互式免密推送) | | `--git-http-token-file `| 空 | 从安全文件中读取访问令牌(权限限定 `600`,推荐) | | `--git-use-credential-store <0\|1>`| `1` | 是否使用 `git credential.helper store` 持久化凭据 | | `--git-credentials-file `| 空 | 自定义凭据存储文件路径(隔离多项目凭据) | | `--no-install-deps` | 否 | 跳过 `apt-get` 依赖检测与自动安装 | | `-h, --help` | - | 显示帮助信息 | #### 快速安装命令示例 ```bash # 场景 1:最简安装(默认晚高峰 10min、非高峰 30min,自动推送) sudo bash scripts/server/install_debian.sh # 场景 2:安全凭据安装(从指定文件读取 Token,自定义高峰时段) sudo bash scripts/server/install_debian.sh \ --peak-start 18 --peak-end 23 \ --git-http-username aurora \ --git-http-token-file /home/aurora/.git_token # 场景 3:纯本地运行(禁用 Git 远程推送) sudo bash scripts/server/install_debian.sh --git-push 0 ``` #### 卸载服务 ```bash # 彻底卸载(移除服务与定时器,清理凭据与配置文件,保留项目代码) sudo bash scripts/server/uninstall_debian.sh # 卸载服务但保留认证凭据(适合临时调整后重装) sudo bash scripts/server/uninstall_debian.sh --keep-auth-files ``` --- ### 2.3 Git 自动推送(Push)与凭据认证 在服务器模式下,`run_update_and_commit.sh` 会在完成选优落盘后,通过独立 Worktree 检出 `runtime-state` 孤儿分支,提交变更并自动推送至远端。 #### 2.3.1 认证决策拓扑图 ```mermaid flowchart TD Push["run_update_and_commit.sh 执行 push"] CheckRemote{"Remote 协议类型"} ModeDisabled["模式 5: 禁用推送
纯本地维护 runtime-state"] Push --> CheckRemote Push -. "GIT_PUSH_ENABLED=0" .-> ModeDisabled CheckRemote -->|"HTTPS 协议"| Mode1["方式 1: 动态 Header 注入
GIT_CONFIG_* 环境变量"] CheckRemote -->|"HTTPS 协议"| Mode2["方式 2: Git 凭据助手
credential.helper store"] CheckRemote -->|"SSH 协议"| Mode3["方式 3: SSH Deploy Key
~/.ssh 私钥免密"] CheckRemote -->|"URL 内联"| Mode4["方式 4: Remote URL 内嵌 Token
https://user:token@host"] ``` #### 2.3.2 5 大认证模式详解 1. **方式 1:Git 原生动态 Header 注入(安全首选,argv 零泄露)** - **机制**:通过 Git 原生环境变量 `GIT_CONFIG_COUNT=1`、`GIT_CONFIG_KEY_0=http.extraHeader`、`GIT_CONFIG_VALUE_0="Authorization: Basic "` 注入,**`ps aux` 与命令行参数中完全不含 Token**。 - **形态**: - 文件形式(推荐):`GIT_HTTP_TOKEN_FILE=/path/to/token`(文件权限设为 `chmod 600`)。 - 变量形式:`GIT_HTTP_TOKEN=ghp_xxx` 与 `GIT_HTTP_USERNAME=git`(CI/CD 流水线适用)。 2. **方式 2:Git 凭据助手持久化存储(`credential.helper store`)** - **机制**:安装脚本默认启用,通过 `git credential approve` 将凭据写入存储文件。 - **免交互配置命令(终端实操)**: ```bash # 开启 store 助手 git config --global credential.helper store # 零交互录入凭据 printf 'url=%s\nusername=%s\npassword=%s\n\n' \ "$(git remote get-url origin)" "你的用户名" "你的Token" | git credential approve # 只读验证(零提交测试,不提示输入密码即代表成功) git ls-remote origin ``` 3. **方式 3:SSH 部署公钥免密认证(SSH Deploy Key)** - **机制**:Remote URL 配置为 SSH 协议(如 `git@git.dewofaurora.de:user/repo.git`),在服务用户的 `~/.ssh/` 下配置具备写权限的 Deploy Key 即可。 4. **方式 4:Remote URL 内嵌凭据(兼容支持)** - **机制**:Remote URL 形如 `https://user:token@host/repo.git`(仅作兼容,Token 会留存在本地 `.git/config`,安全性较低)。 5. **模式 5:禁用远程推送模式(Local-Only)** - **机制**:设置 `GIT_PUSH_ENABLED=0`,仅在本地维护 `runtime-state` 分支并通过局域网暴露 HTTP 服务,完全不需要配置外网推送凭据。 #### 2.3.3 高频常见疑问(FAQ) > **Q1:配置凭据前需要先在项目中产生提交吗?** > > **完全不需要。** Git 凭据存储是网络传输层(HTTP/SSH)的配置,与本地是否存在未提交的修改或历史 Commit 完全解耦。只要仓库具备有效 remote 且能连通网络,随时可以录入凭据。 > **Q2:如果之前已经在分支上产生过历史提交,会有影响吗?** > > **完全不影响,且这正是脚本的标准工作模式。** > 1. **代码分支隔离**:开发人员在 `main` 上的提交与 `runtime-state` 分支物理隔离,互不干扰。 > 2. **智能状态防抖**:脚本每次运行都会比对 `runtime-state` 最新 HEAD。若优选值未变且状态为 `ok`,自动触发**静默跳过**,杜绝无效提交刷屏。 > 3. **模式 A 历史滚动修剪**:当提交累积达到阈值(默认 50 次)时,脚本会自动通过 `commit-tree` 创建 Baseline Snapshot 并执行 Squashed Rebase,始终将孤儿分支历史锁定在轻量窗口。 --- ### 2.4 高峰/非高峰双频自适应调度 为了平衡晚高峰的网络实时性与低谷期的系统资源开销,系统内置了**双频自适应调度引擎**: #### 调度算法原理 1. **定时器最小周期唤醒**: `install_debian.sh` 提取高峰与非高峰周期的最小值作为底层的唤醒基频(通常为 10 分钟): $$\text{TIMER\_INTERVAL} = \min(\text{Peak Interval}, \text{Off-Peak Interval})$$ 2. **时区强制对齐**: 通过 `TZ="Asia/Shanghai" date` 强制指定时区,机房位于 UTC 时区也能精准捕捉北京时间晚高峰(默认 19:00 - 24:00,支持跨午夜配置)。 3. **高峰期直接放行**:处于晚高峰时,每次定时器唤醒均执行全量更新(10 分钟更新一次)。 4. **非高峰期容差判定**: 在低谷期,脚本只在长周期边界(如 30 分钟边界:0 分或 30 分)执行。为防止定时器调度产生微小时间漂移(如 29m 58s 或 30m 02s 唤醒),内置**容差窗口**算法: $$\text{Tolerance} = \frac{\text{Peak Interval} + 1}{2}$$ $$\text{Remainder} = \text{Current Minute} \pmod{\text{Off-Peak Interval}}$$ - 若 $\text{Remainder} \le \text{Tolerance}$ 或 $\text{Remainder} \ge (\text{Off-Peak} - \text{Tolerance})$:判定为边界唤醒,**放行执行**。 - 否则:判定为中间冗余唤醒,记录 `off-peak run skipped` 并**安全退出 0**,零多余开销。 --- ### 2.5 核心规则:筛选与评分策略 #### 1. 字段映射与多维过滤 - **字段映射 (`record_mapping`)**:将第三方 API 字段标准映射为 `domain`、`created_at`、`yd_latency`、`yd_pkg_lost_rate`、`yd_score` 等标准键。 - **记录过滤 (`record_filter`)**:在解析前剔除黑名单语义(如排除 `host_provider == "CF优选IP"`)。 - **域名正则过滤 (`domain_filter`)**:通过正则表达式剔除纯 IPv4 记录,仅保留物理域名。 #### 2. 加权算分与平局决胜 - **加权评分公式**: $$\text{Score} = \frac{\sum (\text{Field Value} \times \text{Weight})}{\sum \text{Weights}}$$ 默认针对中国移动线路加权:`yd_latency`(权重 1.0,越小越优)+ `yd_pkg_lost_rate`(权重 10.0,越小越优)。 - **健康度极性避坑**:`yd_score`(健康得分,通常 75~110)为正向指标(越大越优)。在负向算分模式(`prefer_lower: true`)下,**禁止直接赋予正权重**(否则会导致健康分暴跌的劣化节点被优先选出)。 - **时效性避坑**:针对 `vps789` API 数据源,接口返回的 `createdTime` 实际为「域名纳入监控池的建档时间」而非当次拨测时间。在服务器模式下默认设置 `within_hours: 0`(禁用时效过滤),防止误杀老牌稳定域名。 - **平局决胜 (`tie_breakers`)**:得分相同时,依次以 `yd_score`(降序) $\to$ `avg_latency`(升序) $\to$ `created_at`(降序) $\to$ `domain`(升序)决胜。 #### 3. 双轨容灾机制 (Fallback) - **触发条件**:API 请求超时(`error_use_last_good`)或所有候选均被过滤(`fallback_last_good`)。 - **回退流程**:自动从 `state.json` 中读取 `last_good_domain`,**并对其再次执行黑名单与合法性复检**(杜绝故障节点复活);提交信息自动标注 `chore(fallback):`,且在值未变时抑制重复提交。 --- ### 2.6 日志格式与日常维护速查 #### 统一日志格式与 journald tee 所有服务端脚本统一输出标准日志格式: ```text [YYYY-MM-DD HH:MM:SS] [vmess-domain-rotator] ``` > [!TIP] > 手动在终端执行 `run_update_and_commit.sh` 时,脚本内置的 **`journald tee`** 技术会同时向终端(stdout/stderr)以及系统守护进程(`systemd-cat`)输出双流,确保手动调试信息与定时任务日志完整融合在同一系统时间线中。 #### 常用维护命令速查 ```bash # 1. 查看定时器运行状态与下一次触发时间 sudo systemctl status vmess-domain-rotator.timer # 2. 手动立即触发一次更新(无需等待定时器) sudo systemctl start vmess-domain-rotator.service # 3. 实时追踪查看运行日志(包含定时任务与手动调试日志) sudo journalctl -t vmess-domain-rotator -f --no-pager # 4. 查看当前配置解析出的绝对输出路径(不执行更新) python3 scripts/domain_updater.py --config configs/config.server.json --print-output-settings # 5. 手动强制提交当前域名(强制产生 commit 并推送到 remote) sudo -u aurora bash scripts/server/run_update_and_commit.sh --force-commit configs/config.server.json ``` --- ## 3. 本地 Python 模式(本机 cfst -> IP) 适用于有完整 Python 3 环境、并在本地机器上直接运行 `cfst` 测速程序的场景。 ```bash # 单次执行更新并查看落盘结果 python3 scripts/domain_updater.py --config configs/config.local.json # 维护与产物检查 cat runtime/current_ip.txt cat runtime/current_ip.json cat runtime/substore_vars.json cat runtime/state.json ``` - **配置关键**(`configs/config.local.json`): - `cfst_local.work_dir`:测速工作目录(如 `./cfst_darwin_arm64`) - `cfst_local.binary`:测速程序路径(如 `./cfst`) - `cfst_local.skip_run`:设为 `true` 时仅解析现有 `result.csv`,设为 `false` 时每次调用二进制执行测速。 - **下载测速保护**:系统自动剔除 `download_speed == 0.00` 的失效死节点;当在 `run_args` 中显式指定 `-dd`(禁用下载测速)时,自动转为按平均延迟排序。 --- ## 4. BusyBox 路由器模式(路由器 cfst + HTTP) 适用于运行在嵌入式路由器(如华硕梅林固件、OpenWrt)上,设备无 Python 环境,通过纯 POSIX Shell + BusyBox 驱动的场景。 ### 4.1 目录拓扑与关键配置 推荐在路由器物理持久分区(如 `/jffs/vmess/`)建立以下布局: ```text /jffs/vmess/ ├── busybox_armv7l # 具备完整 httpd applet 的 BusyBox 二进制 ├── config_router.conf # 路由器端专用配置文件 ├── scripts/ │ ├── router_local_update.sh # 本地更新脚本 │ └── router_local_http.sh # 微型 HTTP 守护进程 └── cfst/ ├── cfst / ip.txt / result.csv # 测速二进制与网段文件 ``` --- ### 4.2 [最佳实践] 延长路由器闪存寿命(动静分离防擦写) > [!WARNING] > **闪存寿命保护警示** > 路由器的 `/jffs` 分区位于 NAND/NOR 物理 Flash 闪存介质上。如果将高频定时生成的测速结果 `result.csv` 和运行时临时文件直接写入闪存,**长期高频擦写将严重缩短路由器硬件寿命**! 本项目全面支持**动静分离与绝对路径重定向**,通过将高频临时读写重定向至 RAM 内存文件系统(`/tmp`),实现硬件零磨损: ```bash # === config_router.conf 推荐优化配置 === # 1. 测速工作区与输入文件(只读性质,放在 Flash 物理存储上) CFST_WORK_DIR="/jffs/vmess/cfst" CFST_BIN="./cfst" CFST_IP_FILE="ip.txt" # 2. 【核心优化】测速输出 CSV 重定向到 RAM 内存系统(/tmp),彻底杜绝闪存磨损! CFST_RESULT_FILE="/tmp/vmess_result.csv" # 3. 【核心优化】高频运行期数据全部落盘在 RAM 内存,极速读写且零磨损 RUNTIME_DIR="/tmp/vmess_runtime" VALUE_TEXT_FILE="current_ip.txt" VALUE_JSON_FILE="current_ip.json" EXPORT_VARS_FILE="substore_vars.json" # 4. 【容灾持久化】仅将极低频写入的备用状态 state.json 保留在物理闪存中(断电不丢失) STATE_FILE="/jffs/vmess/state.json" ``` - **零闪存磨损**:高频临时测速与运行产物全部位于 RAM,闪存不再承受周期性擦写压力。 - **微秒级响应**:BusyBox `httpd` 直接挂载 `/tmp/vmess_runtime`,内存直读提供极速响应。 - **断电容灾存留**:设备意外断电时,物理闪存上的 `state.json` 依然完好,开机即能从 Fallback 状态迅速恢复。 --- ### 4.3 自启动与看门狗脚本 在路由器的开机自启脚本(如 `/jffs/scripts/services-start`)中加入守护与保活: ```sh VMESS_DIR="/jffs/vmess" CONFIG="./config_router.conf" UPDATE_LOG="/tmp/router_local_update.log" HTTP_LOG="/tmp/router_http.log" HTTP_PROCESS_PATTERN='[r]outer_local_http.sh' start_vmess_http() { if ps | grep -q "$HTTP_PROCESS_PATTERN"; then return 0 fi cd "$VMESS_DIR" || exit 1 nohup sh scripts/router_local_http.sh "$CONFIG" >> "$HTTP_LOG" 2>&1 & } cd "$VMESS_DIR" || exit 1 # 开机防抖:等待网络就绪后执行初次测速 sleep 60 i=1 while [ "$i" -le 5 ]; do if sh scripts/router_local_update.sh "$CONFIG" >> "$UPDATE_LOG" 2>&1; then break fi sleep 20 i=$((i + 1)) done # 注册 Cron 定时更新(每 12 小时一次) cru d vmess_rotate cru a vmess_rotate "0 */12 * * * cd $VMESS_DIR && sh scripts/router_local_update.sh $CONFIG >> $UPDATE_LOG 2>&1" # 启动微型 HTTP 服务并设置看门狗(每 5 分钟保活) sleep 10 start_vmess_http cru d vmess_watchdog cru a vmess_watchdog "*/5 * * * * if ! ps | grep -q '$HTTP_PROCESS_PATTERN'; then cd $VMESS_DIR && nohup sh scripts/router_local_http.sh $CONFIG >> $HTTP_LOG 2>&1 & fi" ``` --- ### 4.4 路由器部署包一键打包 本地直接执行打包工具,一键生成开箱即用的部署压缩包: ```bash # 默认打包当前配置与组件 -> 输出 vmess.tar.gz ./build_router_package.sh # 支持通过 SSOT 从 JSON 配置自动同步测速参数至路由器配置文件 ./build_router_package.sh --sync-from-config configs/config.local.json ``` --- ## 5. Sub-Store 算子对接 [`substore/operator_template.js`](file:///Users/aurora/Project/vmess-domain-rotator/substore/operator_template.js) 提供了高度灵活的动态节点注入能力: ### 5.1 工作模式与速度切换 - `VALUE_SOURCE_MODE = "default"`:路由器优先;当路由器实测下载速度低于阈值(`ROUTER_MIN_SPEED_MB_PER_S = 5`)时,自动无缝切换至服务器模式。 - `VALUE_SOURCE_MODE = "server_only"`:仅从服务器远端分支拉取。 - `VALUE_SOURCE_MODE = "router_only"`:仅从局域网路由器 HTTP 拉取。 ### 5.2 URL 参数强制覆盖 在 Sub-Store 订阅链接参数中传入参数即可实现强行注入(拥有最高优先级,绕过测速与模式判断): - `domain=my.preferred.com`:强制覆盖所有节点的地址为此域名或 IP。 - `domain_override=false`:临时关闭覆盖,恢复自动选优逻辑。 --- ## 6. 自动化测试与质量门禁 仓库配备了完善的零依赖自动化测试套件(执行时间 < 6 秒): ```bash # 1. 运行全套 32 项自动化测试 python3 -m unittest discover tests -v # 2. 全链路静态语法校验 bash -n scripts/server/*.sh scripts/router/*.sh build_router_package.sh python3 -m py_compile scripts/domain_updater.py scripts/rotator/*.py tests/*.py node -c substore/operator_template.js ``` ### 测试套件覆盖范围 | 测试套件文件 | 核心覆盖断言与安全边界 | | :--- | :--- | | **`tests/test_server_mode_lifecycle.py`** | Server 模式全生命周期(API 选优、孤儿分支 Worktree 提交、自适应时间拦截、静默抑制、模式 A 历史滚动修剪) | | **`tests/test_cfst_local_lifecycle.py`** | 本地 `cfst` 模式全生命周期(CSV 解析、零速节点过滤、`-dd` 延迟免测排序、Fallback 容灾与路径防漂移契约) | | **`tests/test_domain_updater.py`** | Python 选优核心算法(`yd_score` 正向极性修复、平局决胜顺序、迟滞防抖 Hysteresis、黑名单复检) | | **`tests/test_shell_lifecycle.py`** | Shell 脚本生命周期安全(`uninstall_debian.sh` 防空服务名误删库、Token 动态环境零泄露、`ls-remote` 退出码精细判定) | | **`tests/test_router_scripts.py`** | 路由器脚本原子性(`.tmp.$$` 替换写入、测速过滤、SSOT 打包配置同步) | | **`tests/test_substore_operator.py`** | Sub-Store 脚本算子(XSS/非法 HTML 过滤、数据源超时降级、类型安全断言) |