Leadaxe:sing-box-lx DNS 竞速失败项应标记为 lost_race 而非 FAILED

在 sing-box-lx issue #59 中,Leadaxe 重新打开一个诊断缺口:`fastest`、rescue 和 parallel DNS group 中,UDP 成功后被取消的 DoT/DoH TLS 阶段会显示 `FAILED`,而连接竞速路径已有 `SKIPPED + lost_race` 语义。他给出 `dns_ru` 复现配置和预期状态,并建议在诊断树中显示每个子树所属成员;这是待修复的诊断语义问题,未宣称已修复。

作者原文

Reopening for one gap found on v1.14.4-lx.24 (LxBox v2.25.18-rc.3, emulator, https://ya.ru, Full, From scratch).

The losers of a DNS group race are recorded as FAILED, not as SKIPPED with lost_race. The result is still right (they are never the root cause), but in the tree they look like a broken DoT/DoH server.

Repro: group dns_ru = yandex_udp (detour vpn-1), yandex_dot, yandex_doh, mode: fastest, win_ttl: 5m. Wait for the win to expire, then run. The election fans out to all three members:

app_dns A ya.ru                                455 ms  OK
  dns group ru-direct:dns_ru                   454 ms  OK
    detour vpn-1 → udp 77.88.8.8:53                    OK   (winner)
    tcp_connect 77.88.8.88:853                 453 ms  OK
    tcp_connect 77.88.8.88:443                 451 ms  OK
    tls safe.dot.dns.yandex.net                  2 ms  FAILED  context canceled  (alpn h2,http/1.1 — DoH)
    tls safe.dot.dns.yandex.net                  1 ms  FAILED  context canceled  (DoT)

Both tls stages fail 1–2 ms after their TCP connect, when UDP has already answered and the request context of the fan is cancelled (dns/transport/group/fan.go). §5.13 marks the losers of a parallel dial as SKIPPED + lost_race=<winner>, but that is only done in common/dialer/conntest_lx.go. The group fan (fastest election, rescue fan, parallel mode) has no such marking.

Expected: the stages of a fan participant cancelled after the winner answered end SKIPPED with lost_race=<winner stage id>. It would also help to tell which member each subtree belongs to: today the TCP/TLS stages of DoT and DoH sit side by side under the group with only the server address, so 853 vs 443 is the only hint.