Commit graph

61 commits

Author SHA1 Message Date
Simbiot Harness
c396756eb6 Движок тика claude_code: тики исполняет Claude Code (claude -p) с моделью на уровень (min Haiku 5.5, hour Sonnet 5.5, day Opus 5.5; SIMBIOT_LLM_BACKEND[_<LEVEL>], SIMBIOT_CC_MODEL_<LEVEL>, SIMBIOT_CC_API_KEY); круги доверия — хук cc_guard → trust.check_tool, MCP портала с лимитом, трасса и BudgetSpent как у Strands; настройки уровней читаются из .env инстанса
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:23:24 +00:00
Simbiot Harness
578856081e Профиль агента: studio (Коди, мандаты без изменений) | client — агент клиента Shkor Labs Autopilot со своим именем, владельцем и инструментами тарифа (SIMBIOT_PROFILE, SIMBIOT_AGENT_DISPLAY_NAME, SIMBIOT_OWNER_NAME, SIMBIOT_COMPANY) + тест
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 20:14:26 +00:00
Simbiot Harness
f9354a5c36 member_remove: безопасное удаление члена портала (t-261018141319) — описания тула + тест ядра 2026-10-18 15:22:46 +00:00
Simbiot Harness
9badb02951 гейт кода в закрытии задачи: правка харнеса = коммит + тест + зелёный тест
Кейс 2026-10-18 (t-261018103940): Коди закрыл задачу итогом «x» до конца
правки tg_inbox, без теста и без коммита. Проверка — в complete (не в промпте):
- незакоммиченные правки harness/ cli.py tests/ scripts/, сделанные тиком
  задачи после её клейма → отказ со списком файлов. «Сделанные тиком» — по
  трассе: edit/write по пути, shell — путь + признак записи (sed -i, >, tee,
  cp/mv/rm, patch, git apply, open(…,'w')); чтение (grep, sed -n) и запуск
  (python cli.py …) — не правка; нет трассы — по времени изменения файла.
  Иначе чужая незакоммиченная правка того же времени блокировала бы задачу;
- коммиты после клейма (точно по %ct, не по секунде --since) меняют код без
  tests/test_*.py → отказ; исключение — complete --no-test «причина»
  (причина уходит Alex в итоге);
- изменённые тесты запускаются при закрытии, FAIL/падение → отказ;
- в итог Alex автоматически: «Код: <хеши> · тесты PASS: …»;
- правило — в постановке батча задач; SIMBIOT_CODE_GATE=off выключает.
Сухой прогон на задаче Коди: сейчас — «Код: 70a2015 · тесты PASS:
tests/test_tg_group_ux.py»; в 10:42 был бы отказ (tg_inbox.py не закоммичен).
Тест: test_code_gate 14 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:06:44 +00:00
Simbiot Harness
70a2015bae 👍 на отвеченные сообщения (правка Коди t-261018103940) + тест; мусорный итог задачи не принимается
Коди сам доработал tg_inbox (задача Alex 10:39): после ответа ставит
реакцию на каждое отвеченное сообщение (одиночный и сводный ответ),
нашёл, что ✅ Telegram не принимает (REACTION_EMPTY) — взял 👍. Правка
лежала незакоммиченной и без теста, а задачу он закрыл с итогом «x»
до того, как доделал (Alex пришло «✅ Готово … x»).
- коммит правки Коди как есть;
- тест (test_tg_group_ux +8): 👍 на сообщение, весь батч, портал без
  реакции, сбой реакции не ломает ответ;
- complete_task_with_delivery: итог короче 10 символов («x», «2»,
  «готово» — 3 из 338 закрытий с октября) отклоняется с подсказкой
  «опиши, что сделано и где результат».
Полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:55:02 +00:00
Simbiot Harness
1745e6c1c8 адресация: бот давно молчит в чате — строже порог и подсказка модели («тебе» — другому человеку)
Кейсы «Правления» 17.10: «Ща обновлю тебе до премиум» (Alex — Vlad'у,
18:40, P=0.68) и «Так проверь пока опен роутер» (Alex — Vlad'у, 14:56,
P=0.62) — бот молчал 2 и 6 часов, но «тебе/проверь» перевесило, и Коди
встрял («О, спасибо! 🙏…», «Проверил OpenRouter ✅…»).
- bot_idle_minutes: молчание бота в чате по журналу исходящих/ответам;
- бот писал ≤ 10 мин назад — порог 0.5 и прежний промпт (подсказка «люди
  ещё говорят с Коди» завышала P — пробовал, откатил);
- бот молчит дольше — порог 0.6 (SIMBIOT_ADDRESSING_MIN_P_IDLE) и в
  контексте модели: «Коди не участвует в текущем разговоре, «ты/тебе» без
  имени — скорее другому человеку».
Реплей 111 спорных решений правления за 17.10: оба встревания ушли
(P 0.68→0.18, 0.62→0.31), обращения к молчавшему боту сохранились
(«Можешь зайти на клоуд…» 0.77, «Чекни опен роутер генерацию…» 0.80).
Тест: test_addressing 35 PASS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 18:48:06 +00:00
Simbiot Harness
2da39af74d кэп tool-result'ов в истории тика: срез >8k симв (после 60k суммы — 4k), полный текст в трейсе; burn-аудит 14.10 рек.1 2026-10-17 14:09:00 +00:00
Simbiot Harness
4e57de63bd t-261017110430: подача событий EventStore в контекст тика (policy events_context)
- scheduler: _events_digest() — содержательные события стора за ~90 мин
  (Message/Reply/Tasks/Escalations/AUM/MCP), шум (CycleTicked/Tool*/) отсечён;
  секция «СОБЫТИЯ ХАРНЕСА» в build_context по policy.events_context=on
- commands/cli: policy --events-context on|off (переключатель, одобрен Alex)
- tests/test_events_context.py: 9 hermetic-проверок (on/off/дефолт/пустой стор)
2026-10-17 13:03:14 +00:00
Simbiot Harness
d06a4e45bc память: синк без записи в стор, круги из событий (не из проекции), калибровка порогов nomic
- бэкфилл индекса шёл 13 мин при 4 с CPU: _sync_once звал run_projections()
  (пишет в стор) и ждал блокировку живой лестницы — теперь только чтение;
- круги людей — из событий TrustSet, задачи — из своих событий: отставшая
  проекция дала бы дефолтный круг 4 — ошибка в сторону утечки;
- пороги релевантности по прод-индексу (nomic): релевантное 0.78–0.88,
  посторонний запрос ≤ 0.75 → MIN_SCORE 0.76 + окно 0.07 от лучшего;
  «рецепт борща» → пусто, «миграция Gennady» → нужная задача;
- прод: индекс 1650 разговоров (личка 1 / правление 2 / агенты 3),
  270 задач, 91 дайджест; поиск круга 2 не отдаёт записей круга 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:05:09 +00:00
Simbiot Harness
969d57f14a куб 4×4×4: 4 круга доверия, динамическая память D0–D3 с приватностью по кругу, голова depth
Куб Alex: круг доверия × тик (sec/min/hour/day) × глубина памяти —
одна таблица политик, не 64 программы.
- круги 4: 1 владелец (+система: тик без внешних входов), 2 правление,
  3 свои (портал, MCP-агенты, партнёры), 4 остальные; trust.norm для
  старых номеров (в сторе только 1/2 — смысл тот же); потолок памяти круга;
- harness/memory.py: индекс собственной истории (<home>/memory) — разговоры
  (сообщение + ответ; батч — ответ головы), свои рассылки (не ответы),
  итоги задач, дайджесты без заглушек; nomic search_document/query;
  КРУГ ПРИВАТНОСТИ записи = самый недоверенный участник чата (личка
  Alex — 1, «Правление» — 2, задача — её круг, дайджест — 1); поиск
  отдаёт только записи круга ≥ круга тика — тик с правлением не поднимет
  личку владельца; SIMBIOT_MEMORY=on|off (дефолт off — тесты герметичны);
- глубина: D0 односложные / D1 разговор / D2 + эпизоды (8) / D3 + архив
  (15): уровень (час D2, день D3), «помнишь/вчера/как договаривались» →
  D2, «за месяц/что делал/итоги» → D3, задачи → D2, reply на давнее (>48 ч)
  сообщение бота → D2; потолок круга (свои — D2, остальные — D1);
- DepthChosen по трассе (rag/копание в своём сторе/«не помню» = нехватка)
  → голова ядра depth (shadow; on — уверенный ученик поднимает до D2);
- выжимки нижних уровней: проекция не хранила stub — заглушки «LLM не
  запускался» забивали контекст; теперь отсеиваются;
- ядро: чтение чемпиона больше не создаёт каталоги, без чемпиона —
  без эмбеддингов (тесты создавали core/ в репо и ходили в Ollama).
Тесты: test_memory 30, test_trust 55 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 10:43:12 +00:00
Simbiot Harness
17a5befd86 память разговора: ответ на сообщение бота — с полным его текстом, свои рассылки в памяти тика
Кейс Alex 10:10: «Ок делай» реплаем на итог рефлексии. Telegram отдаёт в
reply начало, харнес хранил 300 символов — тик видел «✅ Готово: Рефлексия…»
без самого предложения; два мин-тика (10:11–10:17) искали по коду «что за
переключатель» и упирались в бюджет, ответ — через 8 минут «посмотрю».
- журнал исходящих: send_message пишет OutboundMessage (chat:message_id →
  полный текст до 4000) — любой ответ/доставка/уведомление;
- receive_message: reply на бота → reply_to_full по message_id; для
  старых сообщений — по началу текста среди DeliverySent/ReplySent;
- контекст тика: «↳ ЭТО ОТВЕТ НА ТВОЁ СООБЩЕНИЕ (полный текст)»;
- память тика: «ТВОИ НЕДАВНИЕ СООБЩЕНИЯ» — собственные рассылки бота
  (итоги задач, уведомления, предложения) за 48 ч, без дублей с ответами;
- kodi_core.status: прогноз rule-ветки без p_fit (коммит часа a163e88,
  проверен: precision 0.74 / recall 0.52 на 93 задачах) не валит статус.
Тест: test_reply_memory 9 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 10:24:29 +00:00
simbiot-harness
a163e88d7b task_fit: rule-ветка «внешние системы → не влезет в мин-тик» (рефлексия t-261017093718)
93 размеченных S-задачи: ext>=1 precision 0.74 / recall 0.52; ML-ученик
logloss 0.849 хуже базы 0.707 — чемпион не промоутится. Без чемпиона /
вне зоны уверенности ученика решает детерминированное правило: портал/
сервер/деплой/UI/git в тексте S-задачи → S→M до мин-клейма (route=rule:ext,
act только в SIMBIOT_CORE_TASK_FIT=on; дефолт shadow — прогноз пишется,
батч не трогается). Уверенный ученик (student) приоритетнее правила.
2026-10-17 10:06:40 +00:00
Simbiot Harness
fd6c4052d0 круги доверия: 8 кругов × лестница времени — политика вместо 64 программ
Вторая ось к тактам: время — как часто/глубоко думать, доверие — что
можно с этим человеком. Один код + таблица POLICY (уровни × инструменты).
harness/trust.py:
- круг — только по проверенной личности (tg user_id, MCP-агент, портал,
  tui), не по тексту; старт: Alex 1, Vlad/Yura 2 (правление); агенты 4,
  портал 3, прочие tg 6, чужие 7; менять — только человек
  (cli.py trust set вне тика; из тика — отказ и страж, и CLI);
- круг тика = самый недоверенный вход (входящие + задачи батча); задачи
  наследуют круг тика (SIMBIOT_TICK_CIRCLE → TaskSubmitted.circle) —
  просьба правления не исполняется позже часом с правами владельца;
- страж в воркере (BeforeToolCallEvent.cancel_tool, не промпт): shell
  в кругах ≥ 2 — одна команда cli.py из белого списка круга, без ; && |
  > $() ` ${; файлы — чтение docs/out/sites/artifacts/входящих, секреты
  и запись — нет; portal_mcp — список круга (правлению без казны и
  member_create); rag по кругу; отказ → TrustDenied;
- уровни × круги: партнёров/знакомых — только min; батч не смешивает
  круги; строка круга в контексте тика;
- задача правления упёрлась в права → владельцу кнопки «Разрешить/Нет»
  (только Alex; разрешение = круг 1).
Закрыта дыра: общий SIMBIOT_TG_ALLOWED давал правлению в личке shell
под root наравне с владельцем.
Тест: test_trust 53 PASS (обходы стража, наследование, батчи, одобрение);
фейковые раннеры трёх тестов приняли circle; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:48:39 +00:00
Simbiot Harness
f32c127c6b ядро Коди: чемпион/претендент без утечки + база как порог допуска, снятие чемпиона
Найдено на проде: чемпион, обученный на всём (включая холдаут), сравнивался
на этом же холдауте — видел ответы и выигрывал всегда (адресация: 0.745
против 0.81 у претендента), а task_fit на холдауте при выборе проигрывал
константе (0.849 против 0.707), но стал чемпионом, потому что чемпиона не было.
- чемпион помнит trained_upto; честное сравнение — только на свежих
  (≥ 10, не виденных чемпионом); мало свежих — чемпион остаётся;
- допуск: претендент обязан бить базовую линию (константа = доля класса
  в обучении); чемпион, на свежих хуже базы, снимается (CoreModelRetired),
  ученик молчит; cli.py core retire --head; откат возвращает снятого;
- прод: task_fit снят вручную (при выборе хуже базы).
Тест: test_kodi_core_tasks 20 PASS (свежие/честно/снятие/откат, шум не
промоутится); полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:36:44 +00:00
Simbiot Harness
ebcfe3b9be ядро Коди: эскалация недоделанных задач, голова task_fit, рефлексия, недельный отчёт
Разбор гейта (трассы с 15.10): hour — 0% пустых тиков, min — 6% (15%
токенов уровня) → модель-гейт не нужен. Пустые мин-тики — зацикливание:
«бюджет исчерпан» возвращал S как S, мин брал её снова с нуля (S-задача
33 захвата за 2 ч; 45 из 272 задач ≥ 2 мин-захватов).
- requeue_or_escalate: после 2 захватов на уровне (SIMBIOT_TASK_ATTEMPTS_
  PER_LEVEL) размер растёт выше классов уровня (S→M, к часу, 300 шагов) —
  и для guard «бюджет исчерпан», и для смерти воркера; счётчик попыток
  best effort (сбой → обычный requeue, не ломает путь падения воркера);
- kodi_core — несколько голов (общие: хранение/обучение/промоут/откат,
  nf в модели; SIMBIOT_CORE_<ГОЛОВА>). Голова task_fit: влезет ли S в
  мин-тик (метки — из истории задач); shadow — прогноз перед первым
  мин-захватом, on — уверенное «не влезет» сразу S→M. Честно: на 93
  задачах 5 фолдов 0.58–0.62 при базе 0.52, уверенных 0% — пока инертна;
- рефлексия (как reflexion.py): ≥ 3 расхождений вердикта адресации с
  меткой человека/чата или ≥ 3 S-задач, не влезших в мин → задача часу
  с автодоставкой: разобрать и предложить Alex правило (код не трогать);
- недельный отчёт ядра (понедельник, без LLM, идемпотентно по неделе);
  ночью: train_all → reflect → weekly_report; cli.py core reflect|report|--head.
Тесты: test_task_escalation 8, test_kodi_core_tasks 13, test_kodi_core_
reflect 10, test_kodi_core 28 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:32:41 +00:00
Simbiot Harness
c1d5a11bfb ядро Коди: обучаемый ученик адресации (цикл как в systemone-bench), теневой режим
harness/kodi_core.py — цикл engine42/router42 бенча на решениях Коди,
первая голова addressing (отвечать ли в группе):
- опыт — подписанные события core: CoreLabel (учитель по истории;
  человек — кнопки «Это было мне?» в личку, ≤5/сут), CoreFeedback
  (неявно из чата: ответил, а следом «не тебе/продолжает» → 0; промолчал,
  а автор тут же «@juno42bot»/«Коди?» → 1), живые вердикты учителя;
  веса: учитель 1, обратная связь 3, человек 5;
- признаки: nomic-embed-text сообщения (локально, кеш) + 8 флагов;
  контекстный эмбеддинг убран — шумел (5 фолдов 0.822 → 0.845 без него);
- ученик: логрегрессия (numpy, Adam, L2) — эмбеддинги без поразмерной
  стандартизации (раздувала шум на сотнях примеров); kNN-память новизны,
  пороги новизны калибруются на холдауте (у nomic она 0.03–0.09);
- роутер: знакомо и |p−0.5| ≥ 0.4 → ученик; незнакомо и учитель
  сомневается → вопрос Alex; иначе учитель. SIMBIOT_CORE_ADDRESSING=
  shadow (дефолт: решает учитель, ученик пишет CorePrediction) | on | off;
- тренировка в дневной тик: временной холдаут, претендент против
  чемпиона по log-loss, CoreModelPromoted с sha256; подмена файла →
  ученика нет; cli.py core status|train|backfill|feedback|rollback.
Репетиция на истории правления (259 примеров): холдаут — совпадение с
учителем 73%, уверенная доля 4% при 100% совпадения; 5 фолдов при
CONF 0.4 — покрытие 25%, совпадение 95%. До включения нужны метки.
Поллер: callback_query (allowed_updates явно). numpy — в requirements.
Тест: test_kodi_core 28 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 08:20:02 +00:00
Simbiot Harness
72727c6339 TG: 👀 реально ставится, ответы в группе — reply'ем, правка сообщения не дублирует входящее
Жалоба Alex: «реплаю на сообщения Коди — не реагирует». Триаж реплай на
бота распознавал (07:57, rule=reply_to_bot, ответ через 25 с), но:
- set_reaction слал reaction_type одиночным объектом вместо reaction —
  массива ReactionType: Telegram видел пустую реакцию — в личке молча
  «снимал реакции» (ok → MessageSeen, 596/нед, 👀 не было видно), в
  группе 400 REACTION_EMPTY. Тест test_seen_indication закреплял баг —
  исправлен под Bot API;
- ответ в группе уходил отдельным сообщением: теперь reply на сообщение
  (батч — на последнее, досылка --followup — на исходный вопрос) с
  allow_sending_without_reply; личка — как было;
- edited_message уже принятого сообщения писался новым входящим
  (m-516174914/915 — исправленная опечатка дала дубль в батче) — пропуск.
Тест: test_tg_group_ux 10 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 08:01:15 +00:00
Simbiot Harness
16d2b438bd адресация: имя бота — только звательное обращение; разговор О Коди — не повод отвечать
Кейс 2026-10-17 07:40: фильтр отсёк «Блять)»/«Продолжает)», но правило
«имя в тексте = обращение» ответило на «Так теперь Коди должен отвечать
когда его тегают…» и «Ещё и забыл что он Коди)» — люди обсуждали бота.
- детерминированно — только звательное: «Коди, …», «Коди!», «…, Коди»;
  имя посреди фразы — серая зона;
- промпт decision-модели: «Коди» = Cody, речь о нём в третьем лице —
  не обращение. Пробы: 8/8 (о боте ≤ 0.14, к боту ≥ 0.96); реплей
  истории правления — оба утренних ложных ответа ушли (0.40/0.13),
  разговор Alex с ботом без тега по-прежнему распознаётся;
- мандат мин-уровня: «Коди» в чате — это ты (бот писал о себе в
  третьем лице: «Коди … на вашей стороне»).
Тест: test_addressing 31 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:46:20 +00:00
Simbiot Harness
3ff504143a адресация: группы без chat_type по chat_id<0; облако decision — таймаут 30 с, кулдаун 60 с
- старые записи инбокса без chat_type (до t-261013113629) считались
  личкой и обходили фильтр адресации — группа теперь и по chat_id < 0;
- утренний холодный старт clef:27b в облаке (> 15 с) взводил
  предохранитель на 5 минут → ответы от CPU-nimble по 10 с: облако
  ждём до 30 с, его кулдаун 60 с (локальной — по-прежнему 5 минут).
Реплей реальной истории «Правления» (62 сообщения, бот отвечает только
на адресованное, облако ~0.66 с): приветствия и переписка людей между
собой отфильтрованы; разговор Alex с ботом без упоминания распознан
по контексту; спорные — 2–3 в каждую сторону, «Коди»/@/reply — всегда.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:13:35 +00:00
Simbiot Harness
9d13e59742 адресация в группах: Коди больше не встревает в чужие разговоры
Кейс «Правления»: бот отвечал на каждое сообщение группы — «Доброе
утро!», реплики Alex для Vlad, ответы Vlad на вопросы Alex: фильтра не
было, любое сообщение разрешённого человека будило минутный LLM.

harness/addressing.py — триаж ДО гейта, без LLM:
- личка/портал/агенты — как раньше;
- группа, детерминированно: @juno42bot, reply на бота, имя (Коди/Cody,
  SIMBIOT_BOT_NAMES) → боту; reply на человека → не боту;
- серая зона — decision-модель, choice «кому адресовано»: бот / человек /
  группа; P(бот) ≥ 0.5 (SIMBIOT_ADDRESSING_MIN_P). В истории — только
  ответы бота на адресованное: «встревания» сбивали модель. Замер на
  истории правления: адресованное 0.93, остальные 14 ≤ 0.22 (noul с
  полной историей давал 4 ошибки). Модель недоступна → молчим.
Вердикт: MessageTriaged{addressed} (+ 👀 только тогда) или
MessageIgnored{not_addressed}. Поллер пишет reply_to_user_id/is_bot и
mentions_bot; 👀 в группах ставит триаж, а не приём.
Тест: test_addressing 25 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 07:04:56 +00:00
Simbiot Harness
2b266caab5 сжатие стора с подписью + «сначала ответ, потом работа» на мин-уровне
harness/compact.py + cli.py compact [--dry-run|--vacuum|--verify-archives]:
шум сек-уровня (CycleTicked sec, ReflexObserved без алерта/команд/каналов)
старше часа → архив jsonl.gz (0600, строки целиком со sig) → мост цепочки
(подписи унесённых строк, на которые ссылаются остающиеся, + маркеры
boundary:<id> для legacy-границ) → подписанный StoreCompacted с sha256
архива/строк/моста → удаление пачками. audit.verify_events принимает мост
только при совпадении хеша с подписанным событием; проекции подгружают
мост лениво, если хвост перекрыл сжатый диапазон (rebuild с нуля).
Репетиция на копии прода: 1389 → 200 МБ, verify 484 с/3.4 ГБ → 29 с/420 МБ,
архив 246 МБ — все 2.47 млн подписей проверены; rebuild_projections OK.
Найдено репетицией: legacy-граница (id 466633) и коллизия id сжатия в
одну секунду — оба покрыты тестом. scripts/compact-store.sh — процедура
с VACUUM под остановленными писателями.

мин-уровень: если до ответа нужна работа >30 с — сначала короткий
tg-reply, итог — cli.py tg-reply <id> --followup (в чат входящего:
группа → группа; идемпотентно по тексту). p90 «старт LLM → ответ» был 223 с.

hour: лимит 300 вызовов оставлен — реальный пик 205 (p90 169), 100
оборвал бы 8 из 19 тиков.
Тесты: test_compact 25 PASS, test_followup 10 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 20:10:26 +00:00
Simbiot Harness
b257c32558 аудит @juno42bot 2026-10-16: медиа без подписи в триаже, мин-тик по входящему, тишина сек-уровня, изоляция тестов
- фото/документ/видео без подписи выпадали из триажа (_pending_inbox и
  build_context пускали только текст/голос): висели до 23 ч, все 4
  неотвеченных за неделю — такие. Один фильтр _is_pending, медиа с тегом
  и путём файла; окно свежести SIMBIOT_MEDIA_PENDING_H=6 — старые не
  будят LLM задним числом; стикер без текста — не повод.
- MinNudge: мин-тик через 3 с тишины после MessageReceived/Transcribed, не
  ждём границы минуты (было: медиана 36 с до старта LLM, p90 93 с при
  24 с самой модели). Слот следующего такта, граница его пропускает;
  SIMBIOT_MIN_NUDGE=0 — выключить.
- сек-уровень: CycleTicked+ReflexObserved каждую секунду = 1.35 млн
  подписанных событий/нед (98% стора 1.37 ГБ). Теперь heartbeat раз в
  60 с + такты с событием (алерт, команды, каналы); «reflex ok» не
  спамит журнал.
- 6 тестов писали в боевой стор под SIMBIOT_HOME тика (TTFTWatchdogRetry
  с бюджетом 0.5 с в проде — это они): изоляция SIMBIOT_DB.
Тест: tests/test_tick_latency_noise.py 20 PASS; полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 19:32:15 +00:00
Simbiot Harness
88bb2c0a95 decision-модель в тиках: Ollama Cloud clef:27b → локальная nimble (systemone-bench)
harness/decision.py — клиент /v1/systemone по схеме router42 бенча:
механика — быстрый путь, decision-модель — арбитр, недоступна → фолбэк.
- порядок батча задач: из 9 старейших первой — самая ценная для AUM (on);
- тема инициативной реплики: выбор вместо round-robin (on);
- серая зона гейта (только warn/info): P(нужен LLM) < 0.35 → тихий такт (shadow);
- cli.py decide: статус бэкендов, вопрос 2–9 вариантов / P(да), --stats.
Бэкенды: облако clef:27b (~0.7 с, SIMBIOT_DECISION_API_KEY) → nimble на
CPU (10–30 с); предохранитель на бэкенд, кеш детерминированных ответов,
DecisionMade (backend/model/ms/applied) — policy trace для GA-сшивки.
Дефолт SIMBIOT_DECISION=off — старые тесты герметичны.
Тест: tests/test_decision.py 34 PASS (фейковый эндпоинт); полный набор — без регрессий.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 19:21:29 +00:00
Simbiot Harness
0daf10135c e-261015222515: память разговора в контексте тика — секция НЕДАВНИЙ РАЗГОВОР (отвеченные реплики + наш ответ тех же чатов, cap 12) рядом с батчем неотвеченных; мин-уровень больше не теряет нить после ReplySent; тест +6 PASS 2026-10-15 23:02:41 +00:00
Simbiot Harness
9fa188bccb t-261015090129: канал агент↔агент через MCP — poll_messages (портал: очередь agent_message + курсор per-agent) → инбокс триажа (chat_id=portal:agent:<имя>, kind=agent_message), ответ ask_agent из send_reply/send_batch_reply; рефлекс демона раз в минуту; тест 24 PASS + регрессии чисто 2026-10-15 10:11:11 +00:00
Simbiot Harness
f667ab6d2c t-261015000631: атомарный клейм задач (claim_task_if_ready) — гонка двойного claim hour/day закрыта на уровне стора 2026-10-15 01:15:44 +00:00
Simbiot Harness
acfdf3e5b9 e-261014163808-4da3ec: TTFT-watchdog+ретрай висящего апстрим-вызова в LLM-воркере — зависание до первого токена больше не роняет весь тик (2 павших hour-тика 13:08/16:11, batch TaskFailed); тест test_ttft_retry 7 PASS 2026-10-14 17:08:27 +00:00
simbiot-hour
d850d4828a t-261013131228: резолв цели реплая без текста — reply_to_desc из инбокса (chat_id, reply_to_message_id); build_context показывает содержимое документа вместо «reply на сообщение без текста»; тест 8 PASS (документ/текст/вне инбокса/контекст) 2026-10-13 13:15:44 +00:00
Simbiot Harness
5b1d30a0ff t-261013113629: маршрутизация ответов TG в чат-источник — chat_type/chat_title в MessageReceived, дефолтный чат уведомлений = личка Alex (chat_id>0 фолбэк для старых записей); тест 11 PASS (группа→группа, личка→личка, смешанный батч, дефолт) 2026-10-13 11:44:43 +00:00
Simbiot Harness
5a889e42a4 merge origin/master (hour digests, systemone-bench skill) + конфликт skills/README.md разрешён объединением строк 2026-10-12 09:11:25 +00:00
Simbiot Harness
dfa3b2d8a8 t-261010093054: MCP портала кооператива как стандартный тул харнеса — portal_mcp (booking_slots/booking_create, реестры, казна, лента), guardrail на деньги-тулы, 4 вызова/тик, трейс PortalMcpCalled, cli mcp-call, тест 18 PASS 2026-10-10 10:19:09 +00:00
Simbiot Harness
57a0f97318 t-261010092931: typing «печатает…» весь тик LLM — без привязки к pending-инбоксу; чаты из всего TG-инбокса, фолбэк на чат харнеса; тест: всё seen/пустой инбокс/только портал/чат неизвестен (25 PASS) 2026-10-10 10:05:14 +00:00
Simbiot Harness
58cc3785c6 t-261009160906: анти-гонка уровней min/hour на входящих TG — привязка артефакта к сообщению (-m), guard в deliver_artifact, reply_artifact в read model, тест гонки (8 PASS) + концепт ИИШНИЦЫ 2026-10-09 16:16:09 +00:00
root
2e31249992 feat(scheduler): fetch origin + детектор дрейфа репо в дневном тике (t-261007082307-2e2294) — _repo_sync_check: git fetch + behind/ahead замер RepoSynced (1/день, дедуп), эскалация при behind>0 два дня ПОДРЯД (счётчик из истории стора — рестарт демона не сбрасывает); fetch-fail фиксируется честно (behind=unknown), тик не валит; порог SIMBIOT_REPO_SYNC_MAX_AGE_DAYS (default 2); тест 17 проверок hermetic (git-песочница), весь сюит 20/20 зелёный; живой прогон: behind=0 ahead=13, baseline записан 2026-10-08 10:32:05 +03:00
root
a964329fdb merge origin/master (32 коммита портального инстанса) + burn-fallback в смерженном aum.py
Разрешены конфликты: isolated_runner (тщательный upstream-вариант killpg-wait), cli.py task-диспетчеризация upstream + guard ValueError, aum.py paths-изоляция + STORE_DB fallback.
Тесты после мерджа: 5 устарели к новой реальности — починены по интентам:
- test_aum 9c: hermetic-мок OPENROUTER_KEY (ключ уехал со старого хоста)
- test_router_env_fallback: патчит paths.env_path (runtime больше не читает _HARNESS_DIR)
- test_submit_title_guard: контракт task list = показ доски (exit 0), а не ERROR
- test_tg_commands: доска задач от тестовой ready-задачи (в прод-копии ready пусто)
- test_instance_isolation: SKIP RAG-контура без вендора /root/rag (хост мигрировал)
Итог: 19/19 зелёные
2026-10-07 11:18:05 +03:00
Simbiot Harness
c5c3e8fbaa feat: входящие documents/photo на диск при приёме (t-261005135853-186b42) — гейтвей скачивает документ/фото (getFile→download, атомарно через .part) в inbox/files/<file_unique_id>.<ext> (paths.inbox_files_dir, SIMBIOT_INBOX_FILES_DIR), путь+имя+размер+mime в MessageReceived; идемпотентно по file_unique_id, сбой getFile (истёкший файл) не валит поллер — file_id остаётся; фото — максимальный размер; тест 22 PASS + регресс voice/seen/batch зелёный 2026-10-05 14:17:03 +00:00
Simbiot Harness
20e655e4ec test: служебный текст inbox не порождает задачу-клон (t-261004160532-0fb500) — регресс обоих фиксов (e-261003125707 'list'=доска, e-261004134613 task<ID>=чтение): парсер, CLI-гварды (счёт задач не растёт, несуществующий ID → exit 2), инбокс-уровень ('list'/ID в тексте → команда/речь, без клонов); 4 теста pytest+plain 2026-10-04 17:15:55 +00:00
Simbiot Harness
47352897ce test: видео→текст в voice-пайплайне (t-261004160531-ed25ed) — extract_audio_track на живых ffmpeg-фикстурах (ogg/opus, без дорожки→None), роутинг kind=video ≤60с сразу в large-v3-turbo, >60с через base-лестницу, audio_track_failed, e2e MessageReceived→транскрипт+идемпотентность; 6 тестов pytest+plain 2026-10-04 17:05:06 +00:00
root
bc59609d27 guard мусорных заголовков задач: 'list'/id без деталей → ValueError (e-261003094628, повтор e-261001082241); тест 14/14 2026-10-04 16:03:07 +03:00
Simbiot Harness
3dc6ca6ab9 t-261004113351: изоляция памяти инстанса — SIMBIOT_HOME (репо = чистый код)
- harness/paths.py: единая карта персистентных путей; SIMBIOT_HOME → db/ rag/
  env/ docs/ digests/ audit/ inbox/ run/ voice/; без него — legacy-пути без
  изменений; точечные env (SIMBIOT_DB и пр.) сильнее схемы
- es/tg_inbox/voice/portal_channel/aum/audit/runtime/rag_lookup/isolated_
  runner/cli: все записи-чтения памяти через paths
- scripts/init_instance.py: новый инстанс — чистая база + идентичность
  владельца + его доки (+RAG) + селективный импорт выжимок/доков
- tests/test_instance_isolation.py: копия с пустой памятью не вспоминает
  наши проекты (контекст тика/RAG/прод — 14 проверок ALL PASS, регресс 7/7)
- scripts/migrate_to_home.sh: перенос боевого инстанса в хом (тихое окно,
  идемпотентно, RAG-корпус коопа сохраняется точечным SIMBIOT_RAG_DB)
- install.sh/service/README: свежие установки сразу с ~/.simbiot-data
2026-10-04 12:34:45 +00:00
Simbiot Harness
f286f1b8ed AUM v1: метрика цели измерима (t-261004000834-ed84f5, day-20731): balances.json + авто-refresh из API (OpenRouter credits, Stripe live; livemode-only), AUM=26.7 (было None), aum --record обновил aum_target для всех тиков; тесты test_aum +4 (mock API, livemode=False→None) — ВСЕ ОК; hour-тик: task list без клонов-задач + tg_inbox env-fallback (e-261003125707); дневной отчёт day-2026-10-04 2026-10-04 00:16:09 +00:00
Simbiot Harness
d8a7c89ef9 auto-collapse stale failed (e-261003094432, просьба Alex): failed>24ч → closed архивом
- es: TaskClosed → статус closed (терминальный, обратимый через requeue; closed_by manual|archive)
- commands: close_task (ручной, только failed, идемпотентен), archive_stale_failed(max_age_hours=24, now=None) — демон-архиватор
- scheduler._delivery_and_orphans_loop: каждый проход (15с) архивирует failed>24ч
- requeue принимает closed → ready (доработка из архива)
- cli: simbiot close <id> [-r reason]
- dashboard: порядок ready→running→failed→done→архив, счётчик «архив» в статусбаре, схема закрытых фейлов под одной строкой-счётчиком (тумблер показывает полностью), pill.closed
- тест tests/test_close_stale_failed.py: 15 проверок (закрытие, порог через симуляцию +25ч, done не трогается, идемпотентность, полный цикл closed→ready→failed→closed)
2026-10-03 10:11:40 +00:00
Simbiot Harness
03d3dffeb8 fix isolated_runner: TimeoutExpired has no .pid (e-261003004801) — Popen start_new_session + killpg(proc.pid), group+children reaped; scheduler None-guard in r2 double-close guard (mocked es in tests); regression test test_timeout_kill 2026-10-03 01:17:34 +00:00
Simbiot Harness
b9d7fd9d23 tests: dash-chat hermetic suite (7/7) — лента БД портала, секрет команд, anchor-дедуп, коллапс повторов 2026-10-02 22:12:58 +00:00
Simbiot Harness
26edbb76c8 TG: входящее взято в работу — emoji-реакция 👀 + typing на время тика (e-261002202857, t-261002205233) 2026-10-02 21:15:48 +00:00
Simbiot Harness
e435289e55 hour берёт L-задачи (t-261002170836): classes S,M,L + мандат; тесты синхронизированы 2026-10-02 16:06:02 +00:00
Simbiot Harness
e65d205e0f feat(day): криптоаудит стор/команд (ed25519, genesis-граница), метрика AUM (замер+policy+пилот), правки для портал-развёртывания (t-260930083716, t-260929161138, t-260930110622) 2026-10-02 00:34:07 +00:00
Simbiot Harness
fa634ce526 fix(scheduler+bot): сироты-чистка не рвёт свежие клеймы (grace 90с); алиас «list» → без-LLM команда /задачи; авто-уведомление Alex при падении тика (e-261001124837-ab3fa7, e-261001124424-d9295f, e-261001134429-c68495) 2026-10-01 15:11:53 +00:00
Simbiot Harness
4fe412eac3 fix(runtime): ROUTER_BASE_URL и ключ читаются из .env (e-261001091912) + тест
systemd-юниты не экспортируют .env; на Hetzner-агентах base_url тихо
уходил в дефолт 127.0.0.1:20128 (живой 9router только на эталонном
хосте). _env_or_file(): env > .env > default. E2E на агенте 82:
venv без openai (в cloud-init добавлен отдельно в coop).
2026-10-01 10:09:13 +00:00
Simbiot Harness
053bab3e78 tests(task-batch): синхронизация с контекст-схемой 11a8ccc (min 256k / hour 512k / day 1M) — t-261001090908-18a4f5
Бюджет и размеры задач в секциях 5/6 выведены из LEVELS[].ctx_tokens,
константы уровня захардкожены отдельным check'ом. 30 checks ALL PASS.
2026-10-01 10:02:28 +00:00