| name | sift-route-debug |
| description | Diagnose Sift Mihomo routing decisions for RULE-SET and MetaCubeX GEOSITE/GEOIP templates under rules/, and run whole-tree domain route regression across all Full/Core/Nano templates. Use when investigating why a domain or IP is routed direct/proxy, checking first-match rule attribution, regression-testing after routing changes, or when asked to test all templates' 分流路径. |
sift-route-debug
Use this skill when a Sift domain or IP route needs attribution ("why did this go direct?", "which rule matched?"), or when validating all templates after routing / rule-provider / strategy-group changes.
Commands
Single domain / IP
.agents/skills/sift-route-debug/scripts/explain_route.py rules/DustinWin-full.yaml example.com
.agents/skills/sift-route-debug/scripts/explain_route.py rules/MetaCubeX-core.yaml play.googleapis.com
.agents/skills/sift-route-debug/scripts/update_cache.py rules/DustinWin-full.yaml
.agents/skills/sift-route-debug/scripts/update_cache.py rules/MetaCubeX-full.yaml
Whole-tree domain matrix (preferred after template edits)
bash .agents/skills/sift-route-debug/scripts/matrix_route.sh
python3 .agents/skills/sift-route-debug/scripts/matrix_route.py --update-cache
python3 .agents/skills/sift-route-debug/scripts/matrix_route.py --update-cache --no-assert
python3 .agents/skills/sift-route-debug/scripts/matrix_route.py --update-cache \
--templates DW-f MC-f AC-f \
--domain googleapis.cn --domain challenges.cloudflare.com
matrix_route.sh will try to put MetaCubeX geo on PATH (repo .cache/tools/geo, downloading v1.1 linux binary if missing).
Exit codes: 0 = all FAIL-level expectations passed (or --no-assert); 1 = at least one FAIL.
Workflow
Single diagnosis
- Run
explain_route.py <template> <domain-or-ip>.
- If it reports missing cached rules, run
update_cache.py <template> and retry.
- Treat the target YAML as the only source of truth:
- DustinWin and ACL4SSR templates read
rule-providers.*.url and behavior.
- MetaCubeX templates read
geox-url.geosite, geox-url.geoip, and geox-url.mmdb.
- do not hardcode MetaCubeX or any other upstream in scripts or reasoning.
- For domain input, MetaCubeX diagnosis defaults to GeoSite only and does not resolve DNS. Mention that runtime may later hit
GEOIP after DNS resolution.
- For IP input, diagnose IP providers or
GEOIP rules only.
- If a misroute is confirmed, update
matrix_route.py expectations when the product contract changes.
Whole-tree regression (after multi-template routing changes)
- Prefer
bash .agents/skills/sift-route-debug/scripts/matrix_route.sh from repo root.
- Read the printed matrix (columns
DW-f/c/n, MC-f/c/n, AC-f/c/n) and the ASSERTIONS section.
- FAIL = product contract broken (fix before commit). WARN = known design variance (report, usually do not block).
- Optionally run
bash .claude/skills/sift-check/check.sh (or .agents/skills/sift-check/check.sh) for structural invariants alongside the route matrix.
- Domain matrix is domain-first-match only:
- Any
GEOIP rules are skipped for domain probes.
- Providers with
behavior: ipcidr are skipped for domain probes (runtime may still match after DNS).
Matrix labels
| Label | Template |
|---|
DW-f / DW-c / DW-n | rules/DustinWin-{full,core,nano}.yaml |
MC-f / MC-c / MC-n | rules/MetaCubeX-{full,core,nano}.yaml |
AC-f / AC-c / AC-n | rules/ACL4SSR-{full,core,nano}.yaml |
Built-in probes (default)
Private, advertising (doubleclick / googlesyndication), Google / .cn Google APIs, YouTube, CF challenge, AI, Netflix/Disney+/Spotify/TikTok/Twitch/Hulu, Apple/Microsoft/OneDrive, GitHub/social, domestic CN sites. See DEFAULT_DOMAINS in scripts/matrix_route.py.
Built-in expectations (contract highlights)
Keep these aligned with AGENTS.md / README.md when routing design changes:
| Area | Contract (summary) |
|---|
| Advertising | ad.doubleclick.net / pagead2.googlesyndication.com → 广告拦截 on all nine templates |
| Full Google | www.google.com / googleapis.cn → 谷歌服务 on DW/MC/AC Full |
| Core/Nano Google | → 节点选择 (not broad CN direct for googleapis.cn) |
| CF challenge | challenges.cloudflare.com → 节点选择 or 漏网之鱼, never 流媒体 |
| Full AI | chatgpt.com → AI |
| Full streaming | MC/AC: YouTube/Netflix → 流媒体; AC brand packs (not ProxyMedia) |
| Full brands | icloud → 苹果服务, office → 微软服务 |
| Core brands | full Apple/Microsoft → 全球直连 |
| Domestic | baidu/qq/taobao/bilibili → 全球直连 on all nine |
| Private | localhost → DIRECT |
WARN-level examples (do not treat as hard failures unless design changes):
- DustinWin Full YouTube/Netflix often →
节点选择 (domain media light; mediaip is IP).
- ACL4SSR Nano may send some overseas hosts to
漏网之鱼 (narrow ProxyLite).
- DustinWin Core/Nano
gstatic.cn may → 全球直连 via cn-lite +.cn (no Google classical list).
Edit default_expectations() in matrix_route.py when the product contract changes.
Reading single explain_route results
explain_route.py prints the first matching template rule in Mihomo rule order. For DustinWin and ACL4SSR templates it includes the provider name, provider source, behavior, and matched provider entry. For MetaCubeX templates it includes matched GeoSite/GeoIP tags from the configured geo database and the first matching GEOSITE/GEOIP rule.
Common Sift cases to call out:
- DustinWin:
proxy is the explicit non-CN layer after service/brand rules and before cn-lite; Full also has blackmatrix7 google → 谷歌服务 before proxy.
- MetaCubeX Full:
GEOSITE,google → 谷歌服务 before geolocation-!cn / cn; Core/Nano: google → 节点选择 between geolocation-!cn and cn.
- ACL4SSR Full: streaming brand packs (YouTube/Netflix/NetflixIP/DisneyPlus/Spotify/TikTok) →
流媒体; do not re-add ProxyMedia (CF challenge pollution).
- Core intentionally routes full Apple and Microsoft rules to
全球直连.
- A domain that has no domain-rule match can still route by IP at runtime if DNS resolution produces an IP matched by an IP rule.
MetaCubeX geo CLI
Geodata diagnosis needs MetaCubeX/geo:
mkdir -p .cache/tools
curl -fsSL https://github.com/MetaCubeX/geo/releases/download/v1.1/geo-linux-amd64 -o .cache/tools/geo
chmod +x .cache/tools/geo
export PATH="$PWD/.cache/tools:$PATH"
matrix_route.sh attempts this automatically.