---
name: cebers-pulse-v0-10-x-sprint-g1-g20-picks-quality-hardening
description: "Sport (Fonbet) + Polymarket scanners, 6-layer post-validation, grounding cascade research-gateway→deepseek-search→search→gemini→DDG. Obsidian docs created 2026-05-30 (Projects/cebers-pulse/, 5 файлов канон)."
metadata: 
  node_type: memory
  originSessionId: 6620ea3d-79ed-46e4-b5ea-65828f0cc0b8
---

# cebers-pulse v0.10.x — Sprint G1-G20 picks-quality hardening (2026-05-30)

**Status**: production на mac mini, бот @cebers_pulse_bot (PID меняется при kickstart). Obsidian: [[cebers-pulse]] (Overview/Architecture/Scenarios/Changelog/Decisions, 5 файлов канон, создан 2026-05-30).

## Sprint G1-G20 — что сделано

Закрыли **20 категорий брака** в Sport + Polymarket picks. Каждый G-fix родился от реального бракованного pick'а в проде, найденного через side-by-side audit vs независимые источники (`/v1/search` через research-gateway).

**Headline-баги что нашли и закрыли**:
- **G15**: bot предлагал France YES @ 0.166 при est=0.125 = negative edge. Фикс — `_direction_matches_edge`.
- **G16**: Setka Cup pick «при коэф 1.5 = low-risk» прошёл из-за утечки regex `\b\d+\.\d+\b` в FACT_MARKERS (матчил сам коэф). Фикс — убрать bare-decimal + `_COEF_FOLLOWING_PATTERNS`.
- **G18 (catastrophic)**: UCL Final PSG vs Arsenal — bot заявил «финал уже состоялся, est=1.0, conf=5/5». Реально матч ИДЁТ сейчас 30 мая 2026. Фикс — `_extreme_certainty_check` reject est ∈ [0,0.05] ∪ [0.95,1.0].
- **G20**: Pick на «Россия. Лига Про А4» low+conf=4 несмотря на amateur cap — markers содержал только латиницу `"liga pro"`. Фикс — добавили «лига про» кириллицей.
- **G20 (cache dedup)**: 4 дубля одного market_id 2340843 в cache (Iran ceasefire). Фикс — `cache_polymarket_analysis` теперь DELETE прежние verdicts по same event_id перед INSERT.

## 6-layer post-validation pipeline

После LLM ответа Python пробегает по picks через 6 фильтров:
1. **Anti-hallucination**: outcome_id/market_id должен быть в БД.
2. **Quality filter** (G2+G16+G19): длина ≥40, нет hedge, нет coef_following, есть concrete fact, есть named subject (`_ENTITY_TRANSLATIONS` 25 En↔Ru для polymarket).
3. **Amateur cap** (G16+G20): TT Cup, Setka, **Лига Про** (кириллица), U-21 → max mid + conf≤2.
4. **Math direction** (G15, poly only): sign(est-yes_price) == side, min edge 3%.
5. **Extreme certainty** (G18, poly only): reject est ≤0.05 / ≥0.95.
6. **Correlation**: `_drop_correlated_picks` (исход+фора одной стороны), `_drop_nested_totals`, same-event dedup внутри analyze_event + cache-level dedup по event_id (G20).

## Grounding cascade (G14+G17)

```
1. /v1/research (planner + ddgs + synthesis, ~16-20s) [PRIMARY]
2. research/deepseek-search (grounded LLM, ~12s)
3. /v1/search (raw SERP, ~0.6s)
4. Gemini grounded (4-key rotation, SOCKS5 :2080)
5. DDG (ddgs, last resort)
```

После каждого успешного tier — `_enrich_with_pdf_arxiv` (G17): для PDF/arxiv URL в snippets подтягивает full text (≤2 URL × 3000 chars) через `/v1/fetch`.

## Side-by-side audit results (2026-05-30 ~10:00 AM)

После G20 ожидаемое согласие моих выводов с picks бота ≥80% (нужна верификация на свежих picks в 10:20 wake-up). До G20 согласие было ~50% из-за двух багов (Cyrillic amateur + cache dupes).

## Текущие модели

- `sport_llm_primary = "cerebras/zai-glm-4.7"` (Phase 0 winner, см. Decisions D2)
- `sport_llm_live = "cerebras/gpt-oss-120b"` (on-demand для live матчей)
- `sport_llm_fallback = "nvidia/mistral-small"`
- Polymarket: `gemini/gemini-flash-lite-latest` (paid, надёжный)
- Self-audit cron (G5): противоположная модель к primary

## Открытый бэклог (G21+)

1. **WTI moonshot guard**: reject pick если yes_price < 0.05 + deadline < 7 days (lottery-ticket picks).
2. **OmniRoute timeout robustness**: примерно треть тиков пустые из-за `Advisor L3 raised TimeoutError`. Bump timeout / add 3-й fallback tier.
3. **Unit-тесты для G16-G20 guards** (сейчас покрыты только REPL smoke в tests/sport/).
4. **est_prob calibration**: bot склонен к `est = price + 5-10%`. Нужна Brier-калибровка после месяца наблюдений.
5. **qwen-search**: auto_search не сработал в тестах, может починиться после CebersResearch обновлений.

## Architecture pointers

- [[OmniRoute]] :20127 — primary LLM bus (cerebras / nvidia / gemini / siliconflow).
- [[CebersResearch]] :20130 — web grounding с /v1/research, /v1/search, /v1/fetch, /v1/chat (7 моделей + RAG).
- [[gemini-web2api]] :1717 — Gemini Web прокси, fallback grounding.
- Sport collector через REST `line-lbN-w.bk6bba-resources.com` + SOCKS5 :2080.
- Polymarket collector через gamma-api.polymarket.com (public, без auth).

## Команды для admin

См. [[cebers-pulse/Scenarios]] — S1 топ picks UI, S4 аудит SQL, S5 filter logs, S8 force-rebuild cache, S9 self-audit.

## Точки входа

- TG: `@cebers_pulse_bot` (только admin id 1005954706)
- SSH: `ssh -i ~/.ssh/id_ed25519 cebers_mini@192.168.0.107`
- launchd: `com.cebers.cebers-pulse`
- Code: `/Users/cebers_mini/Services/cebers-pulse`
- venv: `~/Services/cebers-pulse/.venv`
- Logs: `~/Services/cebers-pulse/logs/cebers_pulse.log`
- DB (Fernet-encrypted): `~/Services/cebers-pulse/data/advisor/advisor.db`
- master-key: `~/Services/cebers-pulse/data/.master_key` (persistent с v0.8.7, см. Decisions D10)

## Sprint G21-G24 (2026-05-30..31) — citation + уведомления + поиск + on-demand

- **G21a/b + G22** (e04e89f, 3b58e7d): обязательная цитация snippet'ов в reasoning + fake-citation guard + reasoning truncation 140→320/400→800.
- **G23** (e584b3b): **аудит** показал tick 770s при interval 600s, 0% deep у MMA/boxing. Фиксы: web_search timeouts срезаны (45→15/25→12/15→8), skip LLM при empty grounding, top_n 20→50, Semaphore 3→5, **per-sport round-robin в `pick_stalest_matches`** (cap=4, чтобы редкие виды не задвигались футболом). **Уведомления**: таблицы `notify_subscriptions`+`notify_sent`, кнопка «🔔 Уведомления» в sport-меню (toggle low/mid/high), `sport_notify_push_loop` каждые 15мин top-5 свежих (дедуп по cache_key+outcome_id).
- **G24** (7559e7a): **поиск** `/sport_search <запрос>` (`search_sport_matches_by_team`, кириллица через кастомную `pylower()` SQLite-func — встроенный lower() ASCII-only). **On-demand анализ**: кнопка «⚡ Проанализировать сейчас» → `sport:analyze:{id}` → `run_deep_one` (если нет markets) + `analyze_match(force=True)`. `AdvisorDeps` расширен sport_llm/collector (collector общий с deep-loop).
- **Skill `~/.claude/skills/tg-web-e2e/`**: TG-web e2e тестирование ботов (Playwright + сессия `~/.gaechkin/tg_test_session.json`, proxy `127.0.0.1:2081`, web.telegram.org/k/). Канон из Gaechkin tests/e2e/tg_client.py. Боты: @cebers_pulse_bot / @gaechkin_bot / @avtero_bot.
- Тесты: **862 passed**. Бот @cebers_pulse_bot жив на mini.
- Backlog: cleanup_notify_sent (7д) ещё не вызывается из sport_cleanup_loop; e2e через TG-сессию для advisor-бота требует чтобы тестовый id 8688355181 был в super_admin (сейчас только 1005954706).

## v0.14 — 1С-модуль /onec (2026-06-10, commit e2d4718)

Бот делает внешние отчёты/обработки 1С: загрузка «Отчёта по конфигурации» (терпимый парсер) → задача+скрины (vision) → вопросы gpt-5.5 → исходники формата «выгрузка в файлы» (отчёт=СКД, обработка=программная управляемая форма; ClassId из эталонов в `templates/ref/`) → bsl-language-server гейт → ZIP+инструкция. Доработка .epf → ГОТОВЫЙ файл через v8unpack(pip)+обязательный round-trip (чистый на реальной обработке юзера). «Удалить мою конфигурацию» — полное стирание. Маркеры //+ из скилла 1c-epf (`onec_marker_author`). bsl-ls arm64 в `~/Services/tools/bsl-ls/`. 985 тестов. НЕ проверено: загрузка XML в реальный Конфигуратор (образец на рабочем столе юзера); v8unpack-формы с нуля и build-агент — отложены.

## v0.13.1 LABEL-AUDIT — 2026-06-10 (commit 20f2370)

Юзер заметил «неточность в названиях ставок периодически». Корень: статичный `section_map` в `_fonbet_hint` переписывал РЕАЛЬНЫЕ имена таблиц каталога на выдуманные для большинства видов («Тотал очков» в футболе не существует). Убран; подсказка = имя таблицы каталога + category из БД (колонка ХОЗЯЕВ/ГОСТЕЙ для категорий «1»/«2»). Плюс %P в `_clean_label` подставлял сырые сотые (250 вместо 2.5) — нормализовано. Урок: лейблы/категории Fonbet НЕ переименовывать статикой — каталог и есть то, что рендерит сайт. fon.bet в headless Playwright не рендерит матчи (проверка только через каталог/API). 969 тестов.

## v0.13 — 2026-06-10 (самообучение + полный пул маркетов)

Коммит `41ff61c`. **Самообучение по журналу** (D17: контекст-фидбек, НЕ fine-tuning): `pick_insights.py` — срезы спорт×семейство с Уилсоном (MIN_N=10 анти-шум), блок `self_stats_ru` в промпт воркеров, авто-гейт консенсус+1 для убыточных срезов (Уилсон-верх<0.55), few-shot из reasoning (колонка добавлена ALTER-миграцией). Флаг `sport_feedback_learning=True`, всё fail-soft, кэш 1ч сбрасывается при settle. **Пул маркетов**: round-robin по семействам вместо «Основные+дешёвый кэф» — реальный матч теперь 7 семейств в LLM; категории «1»/«2» (командные) допущены. **Сверка расширена**: 924/925/926 по id (все виды), форы/ИТ/обе-забьют/чёт/точный-счёт по ТОЧНОМУ лейблу для игровых видов (у фор id на каждую линию). 963 теста. Первый органический пик в журнале: тен. фора @ 1.68 pending. Грабля: import `tests.sport.*` между тест-модулями падает под `.venv/bin/pytest` (pre-commit) — хелперы дублировать локально.

## v0.12 — 2026-06-10 (рекомендации аудита внедрены)

Коммиты `a16f7ec` (v0.11.x + аудит-фиксы + 24 линт-чистки для pre-commit хука) и `7491320` (v0.12). **Журнал результатов пиков**: `sport_pick_results` (без FK — переживает CASCADE), запись из analyze_match_consensus, счёт live из `eventMiscs` (119 матчей со счётом за тик), сверка в cleanup-тике ДО удаления (D15: только 921/922/923 все виды + 930/931 тоталы игровых видов; экзотика=unsettled, 48ч без счёта=void), UI «📊 Результаты» (hit-rate/ROI flat-stake/по рискам 7-30 дней). Семафор 4→6 (тик 336с vs 566с, реальных 429=0). Банк-кнопки УЖЕ были (sport:bk пресеты) — только хинт поправлен. 930 тестов. Интеграционно проверено на копии прод-БД: П1@0:2→loss. E2E реальным TG: 📊 экран + назад работают. D15/D16 в Obsidian Decisions.

## v0.16–v0.16.1 — кнопочный UI + RAG доков 1С + бенч моделей + миграция агента (2026-06-11, 43da7f2+a69123a)

**UI-разделы вместо команд**: нижняя клавиатура = 📊 Финансы/⚽ Спорт/🛠 1С/💰 Кэшбэк/📝 Ассистент/⚙️ Настройки, разделы открывают inline-меню; обычный юзер при /start получает Ассистент/Настройки(+Спорт грант); пункты Ассистент/Настройки делегируют cmd_* через model_copy-прокси (e2e реальным TG прошёл). Команды = скрытые алиасы. **RAG документации 1С (D24)**: `scripts/build_onec_docs_index.py` — shcntx_ru.hbk→контейнер→FileStorage(zip)→21900 страниц→FTS5 на Ext (46МБ, 14524 имени API); `docs_rag.OnecDocs.context_for` в промпты + `unknown_calls` пост-проверка (один мягкий ретрай; БСП-методы не блок). **1С-флоу**: бриф-подтверждение перед генерацией («✏️ Дополнить»), скрины в rework (с подписью — сразу в работу), итерации без перезагрузки (собранный файл = живая rework-сессия). **onec_llm → agy/claude-opus-4-6-thinking** (бенч: всё проходит, 3-4× быстрее gpt-5.5; sonnet валит fake-API ловушку; gemini-3.1-pro галлюцинирует таблицы; vision остаётся gemini-3.1-flash-lite 6/6). **Миграция сборок на мини (D26)**: платформа в `~/opt/1cv8` мини (Rosetta ок), agent.py параметризован env (V8_DIR/DATA/PORT), plist мини порт 8789, базы→Ext; **блокеры юзера: `sudo ln -s /Users/cebers_mini/opt/1cv8 /opt/1cv8` (дилибы зашиты на /opt) + активация лицензии пин-кодом (тек. .lic привязан к MacBook)**. 1002 теста.

## v0.15.4 — чистка мёртвых кнопок + фикс клавиатуры (2026-06-11, ae79025)

Аудит всей TG-поверхности. **Баг**: `build_advisor_reply_keyboard()` возвращал `ReplyKeyboardRemove` (шим v0.7.5c) — каждый /today (кнопка «Где растёт»)/crypto/moex/earn/advisor сносил персистентную клавиатуру → теперь `build_main_reply_keyboard()` + регресс-тест. Удалено: EARN_BUTTON_TEXT-фильтр, GROW/WHERE_GROW/WHATS_MINE-константы, ADVISOR_REPLY_LAYOUT+legacy-клавиатура, ADVISOR_COMMANDS+register_advisor_commands (вызов был закомментирован), алиас /coins. /help (обе локали) дополнен /onboard /prefs /integrations + /admin /onec; advisor_help_text актуализирован. `earn:cancel` ЖИВОЙ (кнопка «❌ Отмена» /earn) — не удалять. ChekPilot-кнопка живая (229 чеков). 999 тестов, e2e /help реальным TG.

## v0.15.3 — rework = JSON-патч (2026-06-11, 849dd01)

**Критика из e2e на реальном .epf**: gpt-5.5 НЕ может вернуть большой модуль целиком (терял 384–592 строки, upstream режет вывод; на длинных промптах 500 fetch failed) → бот отдал бы выпотрошенную обработку. **Решение (D23)**: LLM отдаёт JSON-патч `edits[{module, op: append|replace_procedure, procedure?, code}]`, `_apply_patch` применяет детерминированно (regex-границы процедур, маркер //+ принудительно, старое байт-в-байт), ошибка → 1 ретрай с жалобой. 1С-LLM на своём OmniRoute-клиенте timeout 600с (дефолт 60с рвал). Vision скринов проверен: PIL-макеты рисовать ТОЛЬКО truetype (дефолт-шрифт без кириллицы → «[Название поля]»); gemini-3.1-flash-lite распознал поля+типы/таблицу/кнопки полностью. 998 тестов.

## v0.15.1–0.15.2 — изоляция юзеров + канон хранения на Ext (2026-06-10, f086735+84a91a5)

**Изоляция (D21)**: персональные сборочные базы `ib_u<uid>` на агенте (uid ставит бот, валидация ^\d{1,15}$, traversal отбит), `/drop-user` при «Удалить конфигурацию», chmod 700 хранилища. **Канон хранения (D22)**: ВСЁ на `/Volumes/Ext/.../onec/<uid>/` (metadata.json + оригинал config.cf|cfe), rclone→gdrive ежедневно 04:30; базы на MacBook = КЭШ, бот сам восстанавливает из канона (`user_ib_ready` + стрим Path aiohttp). Гигабайтные .cf: агент спулит тела >32МБ на диск (MAX_BODY 4ГБ), в RAM не бывает. **UpdateDBCfg промоуту не нужен** (типы сверяются с конфигурацией; на крупных конфах файловая БД падает «длина ключа индекса»). **Проверено боевым прогоном**: .cf Бухгалтерии юзера 1.63 ГБ → канон Ext → стрим → ib_u1005954706 за 338с → 9110 объектов → сборка реальной ПерепроведениеДокументов с uid за 13с → готовый .epf. 14/14 юзерских .epf распакованы rework-путём. Правленные внешним тулингом XML-выгрузки (аСверкаРеестровыхКомпаний, DEVACC-723) платформа отвергает XDTO — дефект исходника. 995 тестов.

## v0.15 — 1С build-агент (2026-06-10, commit bc168c6)

Лицензия 1С 8.3.27 на MacBook задействована: **HTTP build-агент** `~/Services/onec-build-agent/agent.py` (launchd `com.cebers.onec-build-agent`, :8788, Bearer в `.token`, batch-Конфигуратор) — `/build` zip-исходники→готовый .epf/.erf (~7с), `/dump-config` .cf/.cfe→XML-дескрипторы (~16с). Бот теперь отдаёт **готовый файл** (fail-open: MacBook спит → исходники+инструкция; одна авто-починка спеки по логу платформы). **Фикс СКД**: LLM больше НЕ пишет XML — `build_dcs_xml(query/fields/params)` детерминирован (D18; LLM-XML ломал XDTO → крэши Конфигуратора юзера). Грабли: BOM не whitespace для lstrip (двойная XML-декларация), 1cv8-лаунчер детачится (ждать pgrep по tmp-пути), CLI zip = cp437 кириллица (только python-zipfile), kickstart НЕ перечитывает env плиста (bootout+bootstrap). Конфигурацию принимает: отчёт txt/zip, **zip XML-выгрузки**, **.cf/.cfe** (через агент; >20МБ не пролезет в Bot API). Данные 1С только на `/Volumes/Ext/Services/cebers-pulse/onec` (guard + `OnecStorageUnavailableError`), бэкап `com.cebers.onec-backup` 04:30 rclone→gdrive (D20). На Desktop юзера готовый `ПродажиПоКонтрагентам.erf`. TG-прогон /onec — за юзером (гейт супер-админ). 993 теста.

## Аудит 2026-06-10 (до/после)

4 фикса на проде (бэкапы `.bak-audit-*`, 908 тестов зелёные, kickstart, e2e реальным TG): (1) NameError `cmd_grow` — кнопки «💸 Приумножить»/«⚡ Заработать сегодня» были мертвы, теперь `register_grow_handlers` возвращает `cmd_grow`, проверено байткодом LOAD_DEREF; (2) второй `callback.answer()` после долгого on-demand анализа («query is too old») — в suppress; (3) FK-гонка `cache_analysis` vs cleanup — IntegrityError молча скипается; (4) окно релевантности `start_ts < now+8h` (=TTL) в analyze_top_n — кандидаты 806→605, бюджет не тратится на матчи, чей кэш умрёт до старта (линия выросла до 2810 матчей). Известный шум (не баги, fail-soft): self_audit TimeoutError, pinnacle 403, Unclosed client session (ddgs/primp). **16 файлов в git мини НЕ закоммичены** (вся работа v0.11.x). Предложенные киллер-фичи (не делал): results-ledger (трекинг исходов отданных пиков → hit-rate/ROI юзеру), кнопка-визард банка вместо /sport_bankroll.

## Старая версия

До v0.10.x: см. [[cebers-pulse/Changelog]] (v0.8.x master-key fix + doc parsing; v0.9.x image generate/edit + video tools; v0.10.0-alpha sport scaffold).
