История до 1.7.5 — в git log (сообщения коммитов вида v1.7.5: …). Здесь ведём план и состав следующего релиза.
Статус: состав накапливается. Сборка не запускается — Олег добавляет нововведения, релиз собирается после закрытия состава.
Тема: правило периметра данных доводится до работающего механизма, а не остаётся декларацией в промпте.
Основание — аудит профиля ai-si 05.11.2026. Проверенное состояние:
| Что | Факт |
|---|---|
skills/productivity/docx/references/anonymization.md |
процедура полная: тело, таблицы, все headerN/footerN.xml, docProps/core.xml, app.xml, картинки; замена подчёркиваниями; верификация из 3 шагов. Лежит только в профиле ai-si — в сборке файла нет |
skills/productivity/docx/scripts/scan_open_pii.py |
работает (--summary, --header, --json, --fail-on-open). Лежит только в профиле ai-si — в сборке файла нет |
skills/ailab/anonymization-check |
лежит в сборке, в профиль не ставится — категории ailab в установленном профиле нет |
skills/engineering/ai-data-perimeter |
есть только в профиле ai-si, в сборке отсутствует → получателям не приедет |
profiles/<p>/hooks/ |
пусто — принуждения нет |
SOUL.md сборки |
про обезличивание, периметр и заказчика — ни слова |
Отсюда формулировка «у нас обезличивание до отправки в модель» сегодня не подтверждается: правило записано в скилле, но срабатывает по триггеру и зависит от того, вспомнит ли модель его применить.
Проблема: одна и та же процедура описана в трёх местах — docx/references/anonymization.md, ailab/anonymization-check, engineering/ai-data-perimeter. Три редакции разъедутся.
Иерархия, которую фиксируем:
| Место | Роль |
|---|---|
engineering/ai-data-perimeter |
канон: правила периметра, проверка «соблюдается ли», порядок работы с документом заказчика, чек-лист и нормы (references/perimeter-rules.md) |
docx/references/anonymization.md |
техника правки DOCX-пакета + scripts/scan_open_pii.py — исполнение под каноном |
ailab/anonymization-check |
свести к тонкой ссылке на канон либо убрать; сейчас это третья редакция того же правила |
engineering/ai-data-perimeter в сборку (dist/vasily/skills/engineering/) — в сборке этой категории нет вообще, поэтому переносится каталог целиком, вместе с references/perimeter-rules.md и templates/soul-perimeter-block.md.skills/productivity/docx/references/anonymization.md и skills/productivity/docx/scripts/scan_open_pii.py. Оба сейчас есть только в профиле ai-si; в dist/vasily/skills/productivity/docx/ их нет. Копировать без __pycache__.skills/engineering/ai-data-perimeter/ (SKILL.md, references/perimeter-rules.md, references/hermes-intercept.md, templates/soul-perimeter-block.md), skills/productivity/docx/references/anonymization.md, skills/productivity/docx/scripts/scan_open_pii.py. md5 совпадают с профилем ai-si, __pycache__ не попал, синтаксис скрипта проверен.engineering и ailab доезжают до установленного профиля при установке и обновлении (ailab сейчас не доезжает — см. таблицу выше).skills/engineering/ai-data-perimeter/SKILL.md + references/perimeter-rules.md; третьей редакции правила в профиле нет.SOUL.md — сведено с ai-data-perimeterСверено с каноном. SOUL не переписывает светофор и контуры (они в references/perimeter-rules.md), а закрывает то, что действует до первого чтения файла, и не противоречит трём правилам скилла: аудит вместо согласия (Правило 0), декларация ≠ контроль (Правило 1), агент сам канал (Правило 2).
Расхождения первой редакции, исправленные при сверке:
| Было в первой редакции | Что говорит скилл | Исправлено |
|---|---|---|
| не покрывала запрос «подтверди, что соблюдается» | Правило 0: это аудит по двум слоям, а не согласие | добавлены оба слоя и запрет ответа по одному |
| «не открывается, пока не решено» — без статуса данных | документ до классификации считается красным | добавлен статус «считается красным» |
| правило жило само по себе | процедура — в скилле, SOUL задаёт только порядок | добавлена ссылка на канон, дублирование убрано |
| не было стоп-сигнала | «маркеров нет» = скорее всего оригинал; ноль находок ≠ чисто | добавлено |
| не сказано, кто обезличивает | обезличивание — работа человека, спорное агент не решает | добавлено |
Формулировка для вставки в SOUL.md (в сборку и в рабочий профиль):
## Периметр данных Правила, светофор и процедура — скилл `ai-data-perimeter`. Здесь — то, что действует до первого чтения файла. - Документ заказчика (ТЗ, договор, переписка, форма, ИД) до классификации считается красным. Инструментами чтения он не открывается, пока не решено, откуда берётся обезличенная копия: её даёт владелец или агент делает копию и читает только её. - Оригинал не открывать «чтобы посмотреть объект». Таблица соответствия токенов и реальных значений не читается никогда — она и есть закрываемые данные. - Обезличивание — работа человека по его таблице соответствий. Агент делает копию по технике `docx/anonymization.md`, только если об этом попросили, и не решает за человека, что закрывать в спорных случаях. - Проверка полноты: `python scripts/scan_open_pii.py "<файл>" --summary`. Агент читает счётчики; полный отчёт со значениями — человеку, потому что находки и есть закрываемые данные. - «Маркеров нет» — единственный стоп-сигнал: скорее всего, это оригинал. Ноль находок ≠ «документ чист». Формулировка: «шаблоны нашли N, открыто: …». - «Документ обезличен» и «у нас это соблюдается» без проверки файлов — запрещены. На просьбу подтвердить меру проверяются два слоя: организационный (приказ, регламент, журнал) и технический (SOUL, установленные скиллы, hooks). Ответ по одному слою — ошибка в обе стороны. - Если механизма принуждения нет — говорить это прямо: правило в промпте срабатывает по триггеру, а не по факту.
SOUL.md в сборке (приезжает всем получателям) + profiles/<p>/SOUL.md в рабочем профиле (иначе правило не действует у того, кто уже установлен).Проверено 05.11.2026 по установленной сборке: точка перехвата в Hermes существует и врезана в путь запроса.
ctx.register_middleware("llm_request", fn) — hermes_cli/plugins.py:939.agent/turn_api_request.py:156 → apply_llm_request_middleware(...), и api_kwargs заменяются тем, что вернул плагин (hermes_cli/middleware.py:88).request, включая messages/input, и может переписать их или прервать вызов исключением.tool_request (аргументы инструмента до выполнения) и llm_execution (обёртка самого вызова провайдера).Решение Олега 05.11.2026: режим — маскировать и логировать. Блокировка — только там, где маскирование бессмысленно. Причина: шаблоны ПДн дают ложные срабатывания на техническом тексте (номера СП и ГОСТ, ИНН поставщика в спецификации, кадастровые в выписке), а жёсткая блокировка валит нормальную работу и толкает её на личный телефон.
Категория — не по шаблону, а по типу документа и роли. Классификатор угадывает и ошибается; поэтому тип документа определяется до чтения, а подтверждает человек одним вопросом, и ответ живёт в метке сессии.
Три точки в одном плагине:
| Точка | Что делает |
|---|---|
tool_request (read_file, DOCX/PDF-парсер, OCR) |
определяет тип документа по имени файла, титулу и штампу; сверяет с ролью пользователя; ставит метку категории в сессии; при запрете — отказ до чтения файла, содержимое в модель не попадает |
llm_request |
маскирует по правилам категории из метки; пишет строку в журнал |
llm_execution |
возвращает реальные значения в ответе (демаскировка) |
Плагин работает только с содержимым запроса к модели. Ключи доступа, учётные данные и личные файлы он не читает и не меняет — это отдельный контур, к политике доступа к документам отношения не имеет.
Политика — файл в профиле (policy.yaml), правится без пересборки:
| Категория | Кому | Что входит | Режим |
|---|---|---|---|
| 🟢 зелёный | всем | открытые нормативы, методики, обезличенные тексты | без маски |
| 🟡 жёлтый | всем | ТЗ, реестры замечаний, переписка, локальные сметы, ВОР | маска + журнал |
| 🔴 красный | только роль «договорной пул» (несколько человек) | договоры, сводные сметы, акты, ИД, кадры, финансы | остальным — отказ с подсказкой, к кому идти |
Маскировать красное и отправлять нельзя: у договора маска убивает предмет — стороны, суммы, особые условия. Поэтому для красного единственный корректный ответ — не пускать.
Два ограничения по доступу — согласованы с Олегом 05.11.2026:
Источник ролей — Единый докер USER.xlsx (лист USERS, колонка «роль», добавлена 05.11.2026), 11 учёток:
| Роль (как записана) | Кто | Категории | Отправка в облако |
|---|---|---|---|
| инженер ОВиК, ТЗ, ТУ, СТУ, проекты — 7 | Гришкевич, Воробей, Фролагина, Воронцов, Анушов, Кашина, Нечаев | 🟢🟡, ТЗ — всем | да, с маской |
| гл. бухгалтер (договоры, контракты, сметы, тендеры) — 1 | Хундадзе | 🟢🟡 + открытие красного | нет |
| совладелец директор (договоры, контракты, сметы, тендеры) — 2 | Швецов, Дуда | 🟢🟡 + открытие красного | нет |
Требования к колонке, без которых policy.yaml не собрать:
engineer / contracts / admin), а не перечисление задач: «инженер ОВиК, ТЗ, ТУ, СТУ, проекты» не парсится и меняется от задачи к задаче. Описание оставить отдельной колонкой для человека.policy.yaml генерируется из этой таблицы скриптом, а не правится руками: два источника правды разъедутся на первой же кадровой замене.root (TESTOFF) политику не обходят — иначе одна учётка отменяет контроль. Для них отдельная запись в журнале с пометкой admin.engineer — 7, contracts — 3, admin — 1), столбец H «роль — что делает» — исходное описание задач для человека. Дуда В. заведён (ключ выдан сотруднику, хэш в таблицу не сохранялся) — прежний пункт снят.Единый докер USER.xlsx — личная таблица Олега (OneDrive). Источник ролей, но не рабочий файл сборки: агент её читает, не изменяет и не переписывает. policy.yaml генерируется из копии, снятой на момент подготовки релиза, — чтобы правка личной таблицы не ломала политику, а политика не правила личную таблицу.
Критерий приёмки:
Порядок работ: сначала tool_request + политика + журнал в режиме «только запись» (ничего не маскируем, смотрим поток), затем включаем маску на жёлтом, и только после настройки правил — демаскировку ответа.
Единый источник UI- и функциональных требований — C:\Users\Admin\OneDrive\Документы\OM LAB\OM_Lab — требования к следующей сборке.md (§0 — сводка, §1–§4 — тексты). Здесь только состав и статусы; требования не дублируются, при расхождении верен документ.
| № в документе | Пункт | Раздел | Статус на 05.11.2026 |
|---|---|---|---|
| 1 | Только разрешённые модели, персональный ключ, бренд агрегатора скрыт | §1 | готово к реализации |
| 2 | Один провайдер (шлюз), прямой polza.ai удалён, discover_models выключен + миграция для установленных |
§3a | готово к реализации |
| 3 | Прогресс-бар лимита — по ключу в рублях, через шлюз | §1a | блокер: нужен /v1/wallet на шлюзе |
| 4 | Vision через шлюз тем же ключом | §1b | готово к реализации |
| 5 | Резерв proxyapi.ru, только автопереключение, пользователю не виден | §2 | в объёме 1.7.6, делается при сборке (работа шлюза, не клиента): ключ есть (797 моделей), группы и fallbacks заведены, но LiteLLM отклоняет переход по правам ключа → переделать на второй деплоймент в группе + cooldown_time: 300 |
| 6 | Настройки: пять вкладок, «О программе» скрыть | §3 | готово к реализации |
| 6a | Вкладка «Боты» скрыта, Bot Mode остаётся в коде | §3b | решено 04.11.2026: только вкладка |
| 6b | Первое открытие после установки — тёмная тема | §3c | записано 04.11.2026 |
| 7 | Бот на звонок в Телемост | §4 | блокер: отдельная учётка Яндекс |
| 8 | Ключ привязан к машине: зачисление + key_cmd, статического ключа в .env нет |
§1c | сделано 05.11.2026 (см. ниже) |
Пункт 8 (привязка доступа к машине) — сделано 05.11.2026. Шлюз: gw-issuer v2 — /enrol (обмен старого sk-… на зачисление), /app-key (сессия as-… на 300 с по X-Install-Token), /resolve (подмена сессии на ключ человека для nginx), /revoke, /list. nginx на gw.ailabscrume.ru получил auth_request: в LiteLLM уходит тот же ключ, что и раньше, поэтому лимиты и учёт не меняются (короткие ключи через /key/generate отвергнуты — каждый ключ это отдельная строка расхода и прогресс-бар §1a показывал бы ноль). Клиент: gw-key.ps1 (DPAPI-конверты, коды 0/1/2/3/4, кэш при недоступном хабе), установщик зачисляет машину по почте и коду, пишет key_cmd вместо key_env, чистит .env, файл зачисления кладёт в %LOCALAPPDATA%\AILabSCRUME (вне дома агента). Проверено живьём: агент на временном профиле ответил моделью через key_cmd при пустом .env; отзыв зачисления → helper выходит с кодом 3. ISSUER_STRICT=0 — статические ключи пока проходят насквозь; включать 1 после обновления всех машин.
Брендинг 1.7.6 (решение Олега 05.11.2026). Название агента — OM_Lab_Agent (видимые строки: установщик, ярлык, описание задачи Планировщика, README/INSTALL/CHANGELOG, проверка самоназвания $NamePat). Лого на пустом чате — assets/scrum-engineering.svg заменён на логотип OM Lab (PNG 3032×1376 → 640 px внутри SVG, alt OM_Lab_Agent, ширина 280 px, прозрачность 0.85); рендерер пересобран. Иконка — dist/setup/assets/om-lab.ico (256 px). Display-имя Electron НЕ меняем (product-identity.cjs: display: 'Hermes'): оно задаёт %APPDATA%\Hermes, где лежат список чатов и настройки окна — переименование «потеряло» бы их у всех. Триггер автообновления не трогаем (остаётся Daily 03:00 + 0…44 мин с -StartWhenAvailable); поведение при выключенном ПК: обновление выполняется при первом включении/входе, но если в этот момент открыто окно Hermes.exe → «отложено» до следующего окна.
Что реально войдёт в 1.7.6: пункты без внешних блокеров — 1, 2, 4, 6, 6a, 6b, 8 (плюс безопасность п.1–3 выше) и пункт 5 (резерв, работа шлюза — по решению Олега 05.11.2026 переделка делается при сборке 1.7.6, а не сейчас).
proxyapi.ru живой, GET /v1/models → 200, 797 моделей, ограничений на ключе нет (подтверждено Олегом). Группы proxy/<vendor>/<model> и router_settings.fallbacks для всех алиасов уже заведены, но переход не выполняется: в логе gw-llm — Fallback to proxy/google/gemini-4-argon was skipped because the caller is not authorized to call it. Причина: у ключа сотрудника в models только его 9 моделей, proxy/* в них нет. Отсюда решение: не отдельная группа, а второй деплоймент внутри той же группы <alias>/<vendor>/<model> (список моделей у ключа не меняется — резерв остаётся невидимым), плюс явный cooldown_time: 300 (сейчас «5 минут» держатся на дефолте роутера, в router_settings его нет).anthropic/claude-sonnet-5.5 → резерв anthropic/claude-sonnet-5-5 (у proxyapi дефис вместо точки);openai/gpt-6.1-sol-pro → на proxyapi отсутствует, резерв = деградация на openai/gpt-6.1-sol (подтверждено Олегом). Технически это второй деплоймент в той же группе: model_name = <alias>/<vendor>/<model> (то, что видит ключ), litellm_params.model = фактическая модель proxyapi, api_base = https://api.proxyapi.ru/v1. Группа и список моделей у ключа не меняются.testoff/… в названиях моделей, точный перечень вкладок настроек, маппинг моделей proxy.Мероприятия по этапам. Галочка ставится по факту проверки, а не по факту «сделали».
policy.yaml: общий файл на диске (план) или политика на шлюзе; шлюз остаётся вторым рубежом для тех, кто ходит мимо агента.engineering/ai-data-perimeter в сборке и в установленном профиле (п.1). В сборке лежит с 05.11.2026; осталась проверка установленного профиля после чистой установки.SOUL.md сборки и профиля (п.2).tool_request + policy.yaml + журнал в режиме «только запись», без маски (п.4).llm_execution.CHANGELOG.md: перенести 1.7.6 из «план» в «выпущено», поставить дату и номер сборки.README.md: раздел безопасности — новые правила и роли.distribution.yaml → version: 1.7.6; README.md → «Текущая версия: 1.7.6».v1.7.6: <главное изменение> + тег.config.yaml) — маска не должна требовать релиза, чтобы её отключить при массовых ложных срабатываниях.