МАТЕРИАЛЫ ПРОЕКТА · 20.09.2026
INUM — техническая архитектура
Версия 0.4 · 20 сентября 2026. Связанные документы: концепция, спецификация, сверка с книгой, протокол пилота.
1. Архитектурное решение
Основной сервер и рабочее приложение — Elixir / Phoenix / LiveView. Транзакции и доказательная история — PostgreSQL. Надёжная очередь — Oban. Вычислительные сервисы и обработка наборов — Python, DuckDB, Parquet. Языковая модель подключается как ограниченный аналитический помощник. Источники сохраняются в контурах их владельцев.
Elixir выбран ради конкурентной обработки, изоляции процессов и восстановления под надзором OTP. Он не является универсально более быстрым языком для математики, обработки таблиц или ИИ. Эти задачи выполняют специализированные движки. LiveView позволяет хранить авторитетное состояние и проверки на сервере, используя небольшой браузерный клиент. Основание выбора Elixir, LiveView.
Сайт и общедоступное учебное демо написаны на HTML/CSS/JavaScript без TypeScript. Они развёртываются отдельно от защищённого приложения. Демо не обладает доступом к серверным ключам, исходным данным организаций или локальному ИИ.
2. Что уже работает
| Компонент | Реализация первого выпуска | Граница |
|---|---|---|
| Сайт | Три аудитории, услуги, книга, концепция, бриф | Канал отправки заявок ещё не задан владельцем |
| Учебное демо | Три задачи, альтернативы, чувствительность, карточка, прогноз–факт, экспорт, профиль доступа | Вымышленные значения; память браузерной сессии |
| Phoenix / LiveView | Локальный вход, серверный пересчёт, сохранение карточек, реестр, утверждение, просмотр версий, помощник | Локальный стенд; корпоративный SSO ещё не подключён |
| PostgreSQL | Отдельная роль приложения, FORCE RLS, неизменяемые версии/наблюдения, транзакции | Один локальный кластер; промышленная отказоустойчивость не настроена |
| API | Карточки, пересмотры, утверждение, наблюдения, очередь, политика, аудит, помощь ИИ | Версия v1 первого выпуска; контракт в репозитории |
| Обработка | Python-сервис расчёта; ограниченный импорт локального CSV в Parquet; профиль качества без образцов строк | Федеративные коннекторы и промышленное объектное хранилище — следующий этап |
| Локальный ИИ | Адаптер Ollama, доступ только к разрешённой карточке, проверка структуры и идентификатора источника | Не валидирован как отраслевой эксперт; ответ требует проверки |
Успешный тест прототипа не является аттестацией безопасности или подтверждением готовности к государственному внедрению.
3. Разделение контуров
- Человек и полномочияPhoenix · LiveView · политика доступа
- Решение и историяPostgreSQL · версии · аудит
- Расчёт и помощьOban · Python · локальный ИИ
- Источники владельцевРазрешённые запросы · Parquet · целевая федерация
Публичный сайт, рабочее приложение, вычисления и источники имеют разные доверительные границы. Связи пунктиром обозначают целевую интеграцию. Браузер не обращается непосредственно к PostgreSQL, Python или модели. ИИ не получает инструменты изменения решений, произвольного SQL, файлового доступа или вызова URL.
Для малого пилота используется модульный сервер с понятными границами, без преждевременного дробления на десятки микросервисов. Тяжёлые расчёты уже вынесены в отдельный процесс. Сервисы выделяются дальше по измеренным ограничениям и требованиям изоляции.
4. Субъект и полномочия
Три вида пространства: public, business, personal. Они используют общий цикл решения, но отличаются владельцем целей и правилами утверждения.
- Государственный институт: мандат, публичная и закрытая части, распределительные последствия, независимая проверка и оспаривание.
- Бизнес: стратегия, обязательства, допустимые риски, разделение подготовки и утверждения.
- Человек: личные цели и ресурсы, приватность по умолчанию, самостоятельное утверждение собственного плана.
В текущем сервере роль, пространство и допуск извлекаются из записи проверенного ключа. Поля role, tenant_id, clearance из клиентского запроса не повышают полномочия. Чужой объект и объект вне допуска возвращают одинаковый ответ 404. Список также фильтруется по допуску.
Для организаций автор текущей версии не может утверждать её сам. Пересмотр добавляет новую версию, сбрасывает статус в черновик и требует нового утверждения. Предыдущая версия сохраняется. Конфликт ожидаемой версии возвращает 409.
5. Данные и воспроизводимость
Карточка связывает субъект, цель, сценарий, обоснование, модель, параметры, результат и автора. Версии, наблюдения и аудит допускают добавление записей; роль приложения не может их переписать или удалить. История утверждений хранится в отдельном неизменяемом реестре по точной версии: участник, время и номер версии; событие также записывается в аудит. Пересмотр не удаляет прежнее утверждение.
Каждый производственный набор в целевой модели должен иметь владельца, происхождение, версию, контрольную сумму, схему, единицы, период, часовой пояс, качество, чувствительность, допустимые цели использования и срок хранения. Отсутствующие значения отличаются от нуля; запас — от потока; корреляция — от причинной связи.
Реализованная учебная модель рассчитывает NPV дополнительного потока относительно базового сценария. В ней нет налогов, инфляции, графика ввода, остаточной стоимости и полной причинной модели. Нефинансовые показатели выведены отдельно. Языковая модель не вычисляет финансовые результаты.
Для реального расчёта сохраняются идентификаторы модели и набора, версии кода и окружения, параметры, случайное зерно при необходимости, результат, ограничения и диагностические сообщения. Реестр независимых моделей должен позволять сравнивать альтернативные интерпретации; текущая модель одна и учебная.
Очередь принимает не более 32 незавершённых запусков на организацию и не более 1000 за скользящие 24 часа. Допуск задания сериализован advisory-lock в PostgreSQL, поэтому лимит не зависит от числа узлов приложения. При исчерпании возвращается 429. Эти стартовые лимиты относятся к учебной модели; ресурсные бюджеты тяжёлых вычислений требуют отдельного профиля.
6. Большие данные и федерация
Согласно §16.1 книги, не требуется единая центральная копия всех данных. Владелец источника контролирует его хранение, качество и доступ. Федеративный шлюз должен передавать только разрешённый запрос или минимально необходимый результат с происхождением и ограничениями.
Внутри каждого разрешённого контура целевой поток: источник → карантин → проверка формата и вредоносного содержимого → классификация владельцем → версия набора → колонночный формат → расчёт → агрегированный артефакт. Прямая загрузка произвольных документов в LLM запрещена архитектурой. Автоматическая подсказка по названию столбца не заменяет классификацию.
Для первого локального обработчика реализованы последовательное хэширование CSV, DuckDB с лимитом памяти 512 МБ и двумя потоками, запись Parquet/ZSTD, подсчёт строк и пропусков. Манифест не содержит образцов строк. Автоматическая установка расширений отключена. CLI принимает локальный файл; публичной загрузки файлов или произвольного SQL нет.
Измерение 20.09.2026: 20 000 000 синтетических строк, 667 600 432 байта CSV → 22 745 010 байт Parquet; обработка и профиль — 3,288 с, генерация исходного файла — 14,237 с. Среда: Apple M1 Pro, 16 ГБ, локальный диск; установленный лимит DuckDB 512 МБ, а не измеренный пик памяти процесса. Данные сильно сжимаются. Это единичный тест, не TB-нагрузка и не гарантия для других схем/распределений. Исходный манифест сохранён вместе с результатами испытаний.
Для следующего этапа: S3-совместимое хранилище с отдельными ключами владельцев, версионированием и политиками хранения; партиционирование Parquet по времени/области; реестр схем; квоты; отмена; ограничение времени/объёма результата; идемпотентный импорт. Распределённый SQL, ClickHouse или Spark выбираются только после профилирования реальной нагрузки. PostgreSQL остаётся транзакционным реестром, а не складом сырых петабайтных массивов.
7. Профиль риска информации
Профиль характеризует операцию с данными. Он не присваивает человеку рейтинг благонадёжности и не определяет его права.
| Проверка | Текущее правило |
|---|---|
| Класс | public, internal, confidential, restricted; неизвестный класс запрещён |
| Допуск | Класс не выше серверного допуска пользователя |
| Роль | Отдельные права чтения, расчёта, ИИ и экспорта |
| Среда | Внешняя обработка непубличных данных запрещена |
| Публичные данные снаружи | Нужен отдельный флаг разрешения организации; внешний адаптер не реализован |
| Локальный ИИ | Нужен отдельный допуск организации; restricted не допускается |
| Результат | allow/deny, причина, версия политики |
В промышленную политику дополнительно входят основание и цель, срок разрешения, регион обработки, договорные ограничения, надёжность источника, ограничения объединения наборов, допустимая детализация результата и риск повторной идентификации. Риск не должен сводиться к произвольной единой цифре, снимающей жёсткие запреты.
8. ИИ и проверяемость
В кабинете доступны сохранение, просмотр версий, сверка с фактом и создание пересмотра. Запись факта проверяет ожидаемую версию. Поздний ответ ИИ повторно проверяет доступ и версию карточки перед показом.
Пайплайн: проверенный пользователь → проверка карточки и допуска → политика локального ИИ и разрешённая цель → проверка ожидаемой версии → ограниченный контекст из этой версии → локальная модель → проверка JSON и ссылок → ответ с отметкой обязательной проверки человеком → минимальный аудит события.
В стенде используется Qwen3 4B через Ollama. Модель загружается локально; приложению задан конкретный loopback-адрес. У неё нет инструментов изменения карточек. Источник и текст вопроса считаются недоверенными данными. Ответ с неизвестным идентификатором источника отклоняется. Вывод отображается как текст, а не исполняемый HTML. Ограничены длина вопроса, длина ответа, размер HTTP-ответа, время и частота обращения; одновременно допускается один вызов модели на узел.
Проверка ссылки доказывает лишь то, что модель сослалась на переданную карточку. Она не доказывает достоверность утверждений. Защита от prompt injection не достигается одним системным промптом: нужны минимальные полномочия, изоляция, фильтрация источников, проверка выхода и отсутствие опасных инструментов. Угрозы OWASP для LLM, контракт Ollama.
Полный поиск по документам с разграничением прав (RAG) ещё не реализован. При его добавлении ACL применяется до извлечения фрагментов; индексы и кеши разделяются по владельцу/политике; отозванный доступ удаляется из поискового контура; отравление корпуса и утечки через ответы проверяются отдельными испытаниями. Качество модели оценивается на предметном наборе вопросов с эталонными основаниями и проверкой воздержания от ответа.
9. Защита сервера
Реализованы: сильные случайные ключи; SHA-256 исходного ключа в БД; проверка срока и отзыва; ограничение тела запроса; параметризованный SQL; серверные полномочия; FORCE RLS; отдельные роли владельца схемы и приложения; транзакции; шифрованная и подписанная HttpOnly-сессия; CSRF-защита браузерных форм; SameSite; проверка origin; ограничения запросов; отсутствие подробных ошибок в клиентском ответе; фильтрация чувствительных параметров журналирования; локальные адреса сервисов.
RLS защищает от пропущенного фильтра организации в запросе. Общая роль приложения может устанавливать контекст организации; её компрометация — отдельная угроза. Для особо чувствительных владельцев предусматривается отдельное развёртывание/БД/ключ шифрования. Суперпользователь и BYPASSRLS обходят политики PostgreSQL; приложению они не выданы. Официальные границы RLS.
Аудит связывает события хэшами и не хранит исходный текст обоснований/вопросов. Роль приложения не может переписать журнал. Полный контроль над БД позволяет атакующему вмешаться в историю; промышленный вариант требует независимого подписания контрольных точек и внешнего хранилища с запретом перезаписи. Хэш-цепочка сама по себе не объявляется защитой от администратора БД.
Production-конфигурация требует секрет, адрес приложения, проверяемый TLS к PostgreSQL и доверенный корневой сертификат. Приложение слушает loopback за доверенным TLS-прокси; прокси обязан перезаписывать forwarded-заголовки. Требуются отдельные сетевые политики egress, управление секретами/KMS, резервирование, мониторинг, обновления и независимая проверка. Они не заменяются настройкой языка программирования.
10. Очереди, отказоустойчивость и эксплуатация
Oban записывает задания в PostgreSQL вместе с записью запуска. Результат связан с идентификатором запуска; повторная обработка завершённого задания не создаёт повторный результат. Не обещается «ровно один раз» для произвольных внешних эффектов. Для них необходимы собственные ключи идемпотентности и протокол подтверждения. Документация Oban.
Целевой промышленный контур: минимум два узла приложения за балансировщиком; резервируемый PostgreSQL; PITR; отдельные вычислительные узлы; квоты владельцев; наблюдаемость по идентификатору запроса; очереди и бюджеты; оповещения без содержимого защищённых данных. RPO/RTO и SLO согласуются и проверяются восстановлением, а не назначаются рекламной цифрой.
Перед реальными данными обязательны: OIDC/корпоративный вход и MFA; выдача/отзыв полномочий; проверка модели угроз; аудит зависимостей; проверка резервного восстановления; тесты изоляции и нагрузки; проверка логов; регламент инцидента и удаления данных; независимый аудит значимых моделей. Соответствие законодательству определяется конкретным владельцем, страной, типом данных и назначением.
11. Порядок развития
- Завершить согласование первого решения, источников и критерия успеха.
- Подключить корпоративный вход, эксплуатационный контур и реальный ограниченный источник.
- Валидировать предметную модель и сравнить её с простой базовой альтернативой.
- Провести полный цикл решения и независимый разбор результата.
- Добавлять новые владельцы, ресурсы, модели и масштабы после измеренной полезности и проверки границ доступа.
Принцип выпуска: для каждого утверждения о возможностях должно быть ясно, реализовано ли оно, испытано ли на конкретных данных или относится к целевой архитектуре.
12. Проверки выпуска
Сводка выполненных испытаний и их границ: TEST-REPORT.md. Для браузерного клиента разрешены только собственные ресурсы и явно названный WebSocket-адрес платформы; необходимость явного адреса подтверждена документацией CSP connect-src.
Уточнение 0.4.1: назначение и происхождение ответа
Политика inum-policy/1.1.0 разрешает ИИ только для проверки допущений (review_assumptions) и сравнения сценариев (compare_scenarios). Произвольный текст цели не подставляется в системную инструкцию: используется серверный перечень. Запрос assist требует целочисленную expected_revision; несовпадение до или после вычисления возвращает 409.
Сервер добавляет provenance: идентификатор карточки, номер версии, цель, идентификаторы модели и политики, источник, время UTC. Аудит содержит хэш метаданных операции без текста вопроса и ответа. Это не полный архив ответов ИИ; его политика хранения, шифрование и сроки удаления должны быть определены для конкретного внедрения. Ограничение цели не гарантирует семантической корректности вывода.
Реестр: ограничение объёма каждой выборки
В 0.4.2 реестр использует keyset-пагинацию по (created_at, id) с составным индексом (tenant_id, created_at DESC, id DESC). Запрос запрашивает не более limit + 1 строк для определения следующей страницы, без глубокого OFFSET и без общего COUNT. Фильтр допуска и PostgreSQL RLS действуют в каждой выборке. Полный объём просмотренных страниц не накапливается в серверном LiveView или клиентском DOM.
Позиция следующей/предыдущей страницы передаётся шифрованным токеном с проверкой целостности и сроком 15 минут; он связан с текущими серверными tenant/actor/role/clearance. Для обработки всё равно требуется действующая аутентификация. Реализация использует Phoenix.Token с отдельным назначением ключа для пагинации. Изменение прав требует нового обхода. Порядок по UUID разрешает совпадающие времена создания.
Это ограничивает размер ответа и памяти интерфейса; время запроса на миллионах карточек ещё не измерено. Фильтрация по допуску может потребовать просмотра большего числа индексных строк. Текущая история версий одной карточки остаётся отдельным ограничением и требует собственной пагинации перед массовой эксплуатацией.
12. Кабинет локального ИИ и подтверждённая память
В выпуске 0.7.0 /advisor принимает вопрос и необязательный контекст, затем вызывает Ollama /api/chat через существующий ограниченный HTTP-клиент. Выбрана установленная Qwen3 4B. Используются структурированный JSON-ответ, проверка обязательных полей, think: true, контекст 8192, предел генерации 4096 токенов и ожидание 180 секунд. Слишком длинный, незавершённый или невалидный ответ не сохраняется как успешный. Занятая модель возвращает предложение повторить запрос; устойчивой очереди ИИ и потоковой выдачи пока нет.
advisor_runs хранит неизменяемые входы и финальный ответ. advisor_memories хранит отдельно подтверждённую запись с автором, источником-ответом, классом и признаком активности. Перед генерацией отбирается только память текущего автора и организации не выше класса текущего запроса; после генерации актуальность ключа и допуск проверяются повторно. Отдельные проверки покрывают чужую организацию, другого автора той же организации, понижение класса, отсутствие подтверждения и исключение записи. Системные полномочия модели ограничены ответом: инструменты исполнения и изменение доступов ей не выдаются.
Бесплатный локальный режим не связан с планируемым коммерческим токенным балансом. Ограничения размера и конкурентности защищают оборудование; это технические пределы, а не платный пакет. Запросы не передаются облачному провайдеру. Для доступа с других устройств потребуется отдельно размещённый backend с согласованной инфраструктурой и аутентификацией; статический хостинг сайта этого не обеспечивает.
API и JSON schema: Ollama Chat, Structured outputs. Структурная корректность JSON не гарантирует истинность ответа. Память контекста не изменяет веса модели.