---
name: delor-sport-cli
description: >-
  Диагностика спорт-советника Делора (@DelorCodoCeh_bot, sport_analyzer /
  results_ledger / notify-пайплайн) без ручного написания python -c снипетов
  по SSH каждый раз. Брать когда: «посмотри распределение риска/рынков у
  спорт-пиков», «проверь уведомления/подписки», «сколько пиков реально
  сеттлится и получает урок», «прогони живой пик на этом матче», «что модель
  реально предлагает vs что доходит до пользователя», «какие категории в
  bad_slices», нужен быстрый read-only SQL по advisor.db. Это CLI-скилл по
  методу «CLI вместо MCP» (как avtero-tecdoc) — обёртка над уже существующим
  кодом sport_analyzer/pick_insights/advisor_db, ничего не дублирует. НЕ для
  изменения логики/гейтов (это правки в самом репо ~/Services/delor) и не
  для других ботов.
---

# delor-sport-cli — диагностический CLI для Делор-спорт

Шесть команд вместо одноразовых `python3 -c "..."` по SSH — то, что за
сессию писалось руками по 2-3 раза (распределение risk_tier/рынков,
здоровье notify-конвейера, живой прогон модели на матче для разбора,
почему пик не прошёл гейты).

## Запуск

Скрипт живёт на mac mini в самом проекте: `~/Services/delor/scripts/sport_cli.py`
(venv и `advisor.db` там же). Вызывать по SSH:

```bash
ssh -p 2222 cebers_mini@100.84.177.25 \
  "cd ~/Services/delor && source .venv/bin/activate 2>/dev/null || source \$(find ~/.venvs -maxdepth 1 -iname '*delor*' -print -quit)/bin/activate; python3 scripts/sport_cli.py <команда> [аргументы]"
```

Копия — в `tools/sport_cli.py` этого скилла (источник истины). Правишь
логику — правь тут, потом передеплой:

```bash
scp -P 2222 tools/sport_cli.py cebers_mini@100.84.177.25:~/Services/delor/scripts/sport_cli.py
```

## Команды

- **`stats [--days N]`** (default 7) — распределение `risk_tier`/`result`/
  `market_family` по `sport_pick_results` за период. То, чем разбирали
  «перекос в низкий риск».

- **`notify [--days N]`** — текущие подписки (`notify_subscriptions`),
  объём push-уведомлений (`notify_sent`), и конверсия win/loss →
  `outcome_note` (урок сгенерирован) → `notified_ts` (доставлено). Показывает
  и общую (все-время-в-окне) и позволяет руками сверить с датой последнего
  фикса — если конверсия < 100% только на старых строках, это не баг.

- **`matches [--status live|prematch|finished] [--sport X] [--limit N]`**
  (default limit 20) — список текущих `sport_matches`, ближайшие по старту
  первыми, с числом активных маркетов. Для выбора кандидата под `probe`.

- **`probe <match_id>`** — **делает РЕАЛЬНЫЙ вызов боевой модели** (DashScope,
  тратит квоту): собирает точно тот же payload, что продовый
  `analyze_match_consensus`, зовёт модель напрямую, показывает пул
  кандидатов по семьям рынков, сырой ответ модели (`raw_picks_from_model`),
  что выжило после anti-hallucination (`validated_picks`), и для каждого
  отброшенного пика — ТОЧНУЮ причину (`reject_reason`, тот же порядок
  проверок, что в `_validate_model_picks`: `market_not_found` →
  `no_team_name`/`hedge_phrase`/`no_concrete_fact`/... → `amateur_league_cap`
  → `fake_citation` → `confidence_below_4`). Так поймали баг с русскими
  падежами (commit b101915) — не гадали по промпту, а посмотрели на реальный
  отказ. `OMNIROUTE_API_KEY` подхватывается из `~/.codex/omniroute.env`
  автоматически (не нужно `source` перед вызовом).

- **`insights`** — `pick_insights.compute_insights`/`bad_slices` целиком:
  срезы hit-rate/ROI по (sport, market_family) + список категорий,
  заблокированных как доказанно убыточные.

- **`db "<SQL>"`** — сырой read-only запрос к `advisor.db`. Разрешён только
  `SELECT` (проверка по префиксу) — escape hatch для всего, что не покрыто
  готовыми командами.

## Пример

```bash
ssh -p 2222 cebers_mini@100.84.177.25 \
  "cd ~/Services/delor && source .venv/bin/activate; python3 scripts/sport_cli.py notify --days 30"
```

## Формат вывода

Всегда JSON в stdout (`json.dumps(..., ensure_ascii=False, indent=2, default=str)`).

## Известные ограничения

- `stats`/`notify`/`matches`/`insights`/`db` не требуют Keychain — читают
  `advisor.db` напрямую (спорт-таблицы не Fernet-зашифрованы). Только
  `probe` нуждается в мастер-ключе (`get_master_key()`) и живой сети —
  дороже и медленнее остальных на порядок.
- `probe` тратит реальную LLM-квоту DashScope + делает live web-search —
  не гонять в цикле/на много матчей подряд без нужды.
