AAYMA
RU
Войти

Граф денег

Инструмент для финмониторинга восстанавливает сеть из 2 248 счетов по переводам 81 клиента, присваивает объяснимые роли и приоритет, строит 92…

Доведённый продукт
Команда «Masterart Netizens» 10💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Masterart Netizens
Кейс HackAlem.ai: Финансы — Freedom
Стадия: Доведённый продукт

Задача кейса: «Граф денег»: восстановить структуру организованной группы по сети транзакций (AML)

Суть

Инструмент для финмониторинга восстанавливает сеть из 2 248 счетов по переводам 81 клиента, присваивает объяснимые роли и приоритет, строит 92 кластера, ищет временные паттерны и аномалии. Есть рабочее место на React, AI-ассистент и PDF-справки.

Как устроено

Команда ./run.sh: 3 parquet → проверка консистентности транзакций и рёбер → направленный граф и метрики → роли по правилам finance-policy/2 с порогами насыщения (role_score 0.5 на пороге) → priority и кластеры → 3 CSV и analysis.json → просмотрщик. Дополнительно: датированные цепочки от seed-клиентов, быстрый транзит, повторяющиеся маршруты A→B→C, циклы со строго возрастающими датами, серии переводов, устойчивость сети при удалении топ-узлов. Ассистент отвечает через проверенные операции чтения графа (tool calling OpenAI), без ключа работает локальный разбор по правилам.

Ключевые решения

  • rule-based role scoring
  • temporal reachability
  • cycle enumeration
  • anomaly detection
  • network robustness vs random removal
  • tool calling
  • PDF reports
  • sensitivity analysis

Метрики

Удаление топ-10 по приоритету → 117 фрагментов против 42 в среднем у 50 случайных наборов; 155 счетов с быстрым транзитом, 227 циклов с возрастающими датами; 220+177 тестов

Особенности

Каждое требование связано со строками кода и тестами (FEATURES.md), есть экскурсия по коду и валидация без эталона с проверкой устойчивости к порогам. Рядом с ролью показывается ближайшая альтернатива. Повторный запуск даёт побайтно одинаковые выгрузки.

Стек

Python · React · TypeScript · Vite · Vitest

Модели

OpenAI (Astra, Sol, Luna)


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-9913a3c9-masterart-netizens.

README

README.md

Граф денег

Аналитический инструмент для специалиста финансового мониторинга банка. По выгрузке исходящих переводов 81 известного клиента он восстанавливает сеть из 2 248 счетов, присваивает каждому счёту объяснимую роль и отвечает на вопрос кейса: кого проверять первым и почему. Каждый вывод — гипотеза для проверки аналитиком, а не утверждение о виновности.

Навигация: 1. Название · 2. Описание · 3. Что реализовано · 4. Как работает · 5. Технологии · 6. Архитектура · 7. Запуск · 8. Как проверить · 9. Данные и интеграции · 10. Ограничения и масштаб · 11. Развёрнутая версия

Документы: docs/code-tour.md — экскурсия по коду простыми словами: путь одного настоящего счёта через все модули, с формулами и ссылками на строки · docs/validation.md — обоснованность без эталона: подсказки организаторов, ловушки данных, устойчивость к порогам и весам · FEATURES.md — каждое требование задания со ссылками на строки кода и тесты · docs/architecture.md — модули и границы достоверности · docs/demo.md — сценарий демо и ответы на вопросы · web/README.md — устройство просмотрщика.

Для жюри: проверка за пять минут

  1. Положите три файла организаторов в data/ и выполните ./run.sh. Первый запуск ставит зависимости; затем анализ за секунды создаёт в out/ три CSV и запускает просмотрщик. Откройте в браузере http://127.0.0.1:8765 — адрес печатается в конце работы скрипта; остановить — Ctrl+C.
  2. Откройте out/nodes_roles.csv, выберите любые три gid и найдите их в просмотрщике (клавиша /). Карточка объясняет роль через метрику и порог правила, показывает альтернативу и связи.
  3. Сверьте объяснение с порогами в таблице раздела 4 и строками кода в FEATURES.md. Как устроен весь код, за десять минут объясняет экскурсия по коду.
  4. Запустите проверки из раздела 8: 220 проверок анализа, сервера, ассистента, импорта и PDF и 177 проверок интерфейса.

Где смотреть по критериям оценки

Критерий (баллы)Что подтверждает
Соответствие задаче и работоспособность (25)Пять обязательных требований в разделе 3 и FEATURES.md; одна команда ./run.sh
Техническая реализация (25)Модули и границы достоверности в docs/architecture.md; обоснованность правил, измеренная на данных, в docs/validation.md; правила ролей со ссылками на код в FEATURES.md; AI-ассистент, который отвечает только проверенными операциями чтения графа
README и воспроизводимость (25)Разделы 7–8; повторный запуск даёт побайтно те же выгрузки; каждая функция связана с тестом
Ценность и применимость (15)Очередь проверки с обоснованием, справка по счёту, дополнительные наблюдения на данных организаторов (раздел 3)
Потенциал и оригинальность (10)Датированные цепочки как проверяемое свидетельство, альтернатива роли рядом с выводом, раздел 10 о миллионе узлов

1. Название проекта

«Граф денег» — решение кейса 02 «Финансы» хакатона HackAlem AI. Команда Masterart Netizens.

2. Краткое описание

Аналитику известен только нижний уровень цепочки — 81 клиент из оперативной информации. Кто собирает деньги, через кого их прогоняют и где они оседают, приходится восстанавливать вручную. Инструмент одной командой проходит путь от трёх исходных файлов parquet до трёх выгрузок фиксированной схемы, а локальное рабочее место проверки показывает очередь приоритетов, кластеры, направленные связи выбранного счёта, основания роли и её ближайшую альтернативу, датированные цепочки и справку по счёту. Анализ на данных организаторов занимает секунды.

3. Что реализовано

Обязательное требованиеКак выполненоСостояние
1. Воспроизводимый конвейер./run.sh: parquet → проверка данных → три CSV → просмотрщик; анализ не зависит от Node.jsГотово
2. Роль и скор у каждого узлаВсе 2 248 счетов: роль из словаря, role_score, priority_score, cluster_id и основание до 200 символовГотово
3. Объяснимые критерии ролейФормальное правило с порогом для каждой роли; все пороги с единицами и обоснованием — в backend/policy.pyГотово
4. Кластеризация92 кластера покрывают все счета: размер, число исходных клиентов, внутренний оборот, ключевые счета, гипотезаГотово
5. Топ-лист и визуализацияtop_nodes.csv — 30 счетов с обоснованием за пределами списка исходных клиентов; просмотрщик: поиск по точному gid, направление потоков, роли, кластерыГотово

Все восемь дополнительных пунктов задания реализованы. Числа ниже получены на данных организаторов:

ПунктЧто сделано и что найдено
Учёт обрыва на 4-м колене444 счёта глубины 4 без исходящих не получают роль «конечный получатель»
Временные паттерныЦепочки от исходных клиентов в трёх режимах дат с примером из исходных транзакций. Быстрый транзит за 0–2 дня (без возврата тому же плательщику) — у 155 счетов; 66 случаев, когда 3–7 плательщиков сходятся на счёте в один день; всплески активности — у 41 счёта
Повторяющиеся маршруты и возвраты129 маршрутов A→B→C повторяются в разные дни; 387 коротких циклов, из них 227 можно пройти по переводам со строго возрастающими датами
Детекция аномалий105 пар с сериями из 3 и более переводов за 2 дня (у 36 — одинаковые суммы); 72 счёта с профилем, необычным для своей глубины
Устойчивость сетиЕсли убрать из наблюдаемого графа 10 счетов с наибольшим приоритетом среди всех 2 248 (включая исходных клиентов), он распадается на 117 фрагментов против 42 в среднем по 50 случайным наборам; сценарии для 1–20 счетов. Это расчёт на графе выгрузки, а не оценка реального эффекта блокировки
AI-ассистент аналитикаВопрос словами → ответ по проверенным операциям чтения графа со ссылками на счета. Вызов инструментов проверен на моделях OpenAI Astra, Sol и Luna; без ключа API работает локальный разбор по правилам
Карточка счётаРоль, два-три факта с порогом правила, альтернатива, потоки, пробелы данных; кнопки «Сохранить» и «Справка PDF»; вкладка «Сохранённые» собирает счета для проверки и выгружает PDF-справку по отмеченным
Оценка полнотыДля каждого наблюдения указано, каких данных не хватает; счета сгруппированы по трём видам запросов
Вкладка «Наблюдения»Все дополнительные наблюдения с методом, параметрами и примерами из исходных транзакций; у каждого счёта в карточке — строки наблюдений, в которых он участвует

Кроме пунктов задания: загрузка своих данных прямо в интерфейсе — окно «О данных» или вкладка «Данные» принимают три файла той же схемы в формате parquet или CSV, проверяют их тем же загрузчиком и строят новый анализ без командной строки; рабочая область ассистента в шапке хранит разговоры, которые можно продолжить позже.

4. Как работает

3 файла parquet → проверка данных → направленный граф и метрики → роли, приоритет, кластеры, даты
                → nodes_roles.csv · clusters.csv · top_nodes.csv · analysis.json → просмотрщик

Проверка данных. Сверяются схемы, уникальность счетов, признак исходного клиента и согласованность транзакций с рёбрами: для каждой пары совпадают и сумма, и число операций (стартовый код организаторов проверяет только наличие пар). Идентификаторы не округляются: все 2 248 gid больше предела точных целых чисел JavaScript, поэтому в JSON и браузере они хранятся строками, а в CSV — десятичной записью int64.

Роли. Опора правила (role_score) равна 0,5 ровно на пороге и растёт до 1,0 к уровню насыщения. Это эвристическая мера того, насколько уверенно выполнено правило, а не вероятность. Основная роль выбирается сначала среди признаков веера (координатор, распределитель, консолидатор), затем среди признаков баланса (транзит, конечный получатель). Остальные сработавшие правила показываются как альтернативы — в карточке и в тексте основания. Строки кода каждого правила и его тесты — в FEATURES.md.

РольПравило (версия finance-policy/2)Порог (насыщение)Счетов
coordinator — координаторПрямые переводы с разными исходными клиентами: счёт на стыке их потоков3 (8) исходных клиента8
distributor — распределительПереводы многим разным получателям при наблюдаемых исходящих10 (40) получателей63
consolidator — консолидаторПереводы от многих разных плательщиков7 (20) плательщиков12
transit — транзитНе исходный клиент; переводы другим счетам, отправленные не раньше поступления от иного плательщика, составляют 80–120% полученногокоридор 0,8–1,2; полная опора от 3 операций с каждой стороны37
terminal — конечный получательИсходящие наблюдаются и составляют не больше 20% наблюдаемых входящих; с дня, когда набралось 90% входящей суммы, прошло не меньше 7 дней; не меньше 2 плательщиков или 500 000 ₸7 (21) дней; 500 000 (2 000 000) ₸150
peripheral — периферийныйНи одно правило не достигло 0,5. Если исходящие не собирались или окно наблюдения короткое, опора снижена вдвое; у счёта без переводов она равна 0—1 978

Числа плательщиков и получателей — нижние оценки: переводы извне выборки и суммы меньше 5 000 ₸ в данные не попали.

Почему периферийных счетов так много — 1 978: у 444 счетов 4-го колена исходящие не собирались, 19 исходных клиентов не имеют переводов, ещё 1 135 счетов имеют не больше одного плательщика и одного получателя, и только у 380 признаки есть, но ни один не дотягивает до порога. Карточка каждого такого счёта показывает ближайшую роль и сколько не хватило до порога.

Приоритет считается отдельно от роли — как взвешенная сумма пяти раскрытых семейств признаков: опора основной роли (30%), перцентиль оборота (25%), прямые связи с исходными клиентами (20%), число исходных клиентов с цепочками возрастающих дат (15%), перцентиль числа контрагентов (10%). Строка why в top_nodes.csv называет вклад каждого семейства.

Очередь проверки не включает 81 исходного клиента. Их банк уже знает; задача кейса — сместить фокус «с 81 курьера на реальные точки консолидации». Поэтому top_nodes.csv — 30 счетов с наибольшим приоритетом среди остальных, а приоритет самих исходных клиентов виден в nodes_roles.csv. Первые в очереди — два консолидатора (9 и 8 разных плательщиков) и координатор.

Схема сети показывается по частям, потому что 2 248 счетов на одном экране нечитаемы: карта окрестности выбранного счёта (плательщики сверху, получатели снизу, стрелки — направление денег) и карта каждого из 92 кластеров по шагам от исходных клиентов, с цветом и значком роли у каждого счёта.

Кластеры — метод Louvain с фиксированным зерном 20260923 на неориентированной проекции, где вес пары — сумма переводов в обе стороны. Направления сохраняются в исходном графе, в выгрузках и на карте. Гипотеза кластера описывает состав ролей и оборот и прямо оговаривает, что это наблюдаемая структура переводов, а не вывод о связи владельцев.

Сверка с подсказками организаторов. В задании перечислены выраженные кандидаты на роли. Мы воспроизводим каждое число на тех же данных и показываем, где наши правила строже:

Подсказка организаторовВоспроизведеноКак это отражено в ролях
Узлы с входящими от 8–24 разных плательщиков179 консолидаторов и 8 распределителей: при веере на 10 и более получателей основной становится роль распределителя
Узлы с веерной рассылкой на 60–116 получателей8все 8 — распределители
72 узла с коэффициентом пропуска 0,8–1,272транзитом остаются 37: правило исключает исходных клиентов и учитывает только деньги, ушедшие после поступления
8 устойчивых сообществ Louvain с несколькими исходными клиентами8ровно 8 кластеров содержат больше одного исходного клиента

Устойчивость. Мы сдвинули каждый порог на шаг вниз и вверх и заново запустили анализ: число счетов с ролью меняется, а из 30 счетов очереди остаются 27–30. В четырёх проверенных вариантах весов приоритета остаются 21–28 из 30, и лишь порядок в самом верху зависит от весов. С 30 крупнейшими по обороту счетами очередь совпадает только в 8 случаях. Таблицы и команда для повторения — в docs/validation.md.

Учёт объявленных ограничений данных.

ОграничениеРешение
444 счёта глубины 4 без исходящих — обрыв обходаРоль «конечный получатель» им не присваивается; опора «сигналов нет» снижена; карточка просит данные об исходящих
Входящие извне выборки не видны, у исходных клиентов заниженыТранзит не присваивается исходным клиентам; доли считаются только по наблюдаемым суммам и названы наблюдаемыми
19 исходных клиентов без рёбер, ещё 12 — только получателиВсе 2 248 счетов сохранены; у счёта без переводов роль не оценивается, и это сказано прямо
Порог 5 000 ₸Дробление ниже порога не заявляется; серии переводов выше порога показаны отдельно
Даты без времениПорядок внутри дня не выдумывается: для него есть отдельный режим «тот же день возможен»
Нет размеченных ролейТочность не заявляется; оценивается обоснованность правил

5. Технологии

  • Анализ: Python 3.12+, pyarrow 25.0.0, NetworkX 3.6.1.
  • Просмотрщик: React 19, TypeScript 5.9, Vite 7; сторонних графических библиотек и внешних шрифтов нет.
  • AI-ассистент: OpenAI Responses API со строгими схемами инструментов; модель вызывает только операции чтения графа, а текст ответа собирается из их результатов.
  • PDF-справки: ReportLab 4.4.9; шрифты Noto Sans распространяются по SIL Open Font License 1.1.
  • Проверки: unittest для анализа, сервера, ассистента и PDF; Vitest для интерфейса.
  • Облачный кластер, GPU и платные сервисы не нужны. Без ключа API всё, кроме разбора вопроса языковой моделью, работает без сети.

Часть кода карты (камера, полноэкранный режим, форма связей), 17 значков и кнопка копирования gid перенесены из собственного проекта автора, написанного до хакатона. Источник, ревизия и список изменений — в web/README.md. Остальной код написан на хакатоне.

6. Архитектура

flowchart LR
    A["3 файла parquet"] --> B["Проверка схемы, идентификаторов и сумм"]
    B --> C["Направленный граф и метрики"]
    C --> D["Роли с альтернативами и приоритет"]
    C --> E["Кластеры Louvain"]
    C --> F["Даты и границы наблюдения"]
    C --> N["Дополнительные наблюдения"]
    D --> G["Единая модель фактов и оснований"]
    E --> G
    F --> G
    N --> G
    G --> H["nodes_roles.csv · clusters.csv · top_nodes.csv"]
    G --> I["analysis.json"]
    I --> K["Просмотрщик: очередь, поиск gid, связи, карточка, справка"]
    I --> Q["AI-ассистент: операции чтения графа"]
    Q --> K

Выгрузки, просмотрщик и ассистент читают одни и те же вычисленные факты. Роли, приоритеты и кластеры считает только конвейер анализа; просмотрщик выводит из общей модели представление — окрестность счёта, факты роли, справку, — а ассистент не может создать новый факт. Состав модулей и границы компонентов — в docs/architecture.md.

7. Установка и запуск

Нужен Python 3.12 или новее; для просмотрщика дополнительно Node.js 20.19+ или 22.12+ и npm. Проверьте версию: python3 --version. Встроенный в macOS python3 — версии 3.9, его недостаточно: установите Python 3.12 с python.org или командой brew install [email protected]. Скрипт сам найдёт python3.12, а другой интерпретатор можно указать переменной WORKBENCH_PYTHON. Положите три файла организаторов (nodes.parquet, edges.parquet, transactions.parquet) в каталог data/ и выполните одну команду:

./run.sh

Скрипт создаёт среду Python и ставит зависимости, сначала выполняет анализ и записывает выгрузки в out/, затем собирает интерфейс и запускает локальный сервер просмотрщика. Когда в терминале появится строка «Просмотрщик: http://127.0.0.1:8765», откройте этот адрес в браузере; остановить сервер — Ctrl+C. Без Node.js анализ всё равно выполняется и три CSV появляются в out/; скрипт объясняет, чего не хватает для просмотрщика. Первая установка зависимостей требует сети.

ПараметрНазначение
--data каталогКаталог с тремя файлами parquet (по умолчанию data/)
--out каталогКаталог результатов (по умолчанию out/)
--no-serveТолько анализ и сборка, без сервера
--port портПорт просмотрщика (по умолчанию 8765)

В out/ появятся nodes_roles.csv, clusters.csv, top_nodes.csv, analysis.json для просмотрщика, run_receipt.json с хешем входных файлов и временем расчёта, runtime-receipt.json со временем установки, анализа и сборки и last_attempt.json с итогом последней попытки. Если запуск завершится ошибкой, прежние выгрузки сохранятся.

Только анализ, без скрипта: python -m backend --data data --out out после pip install -r requirements.txt.

AI-ассистент (необязательно). Задайте переменную окружения OPENAI_API_KEY перед ./run.sh; модель выбирается переменной OPENAI_MODEL. Без ключа ассистент отвечает локальным разбором по правилам и прямо сообщает об этом.

PDF-справка. Из командной строки после анализа:

.venv/bin/python -m reports --analysis out/analysis.json --gid 100000004015047100

Флаг --gid можно повторить, чтобы собрать справку по нескольким счетам; --mode выбирает режим путей. В просмотрщике та же справка открывается кнопкой «Справка PDF» в карточке счёта.

Свои данные через интерфейс. Откройте окно «О данных» (сводка справа вверху) или вкладку «Данные» и выберите три файла: nodes, edges, transactions в формате .parquet или .csv с именами столбцов в первой строке. Сервер проверяет их теми же правилами, что и командная строка, строит новый анализ и заменяет выгрузки только после полного успеха; при ошибке прежние результаты сохраняются, а причина показывается по-русски. CSV-файлы организаторов дают тот же отпечаток содержимого и побайтно те же выгрузки, что и parquet.

8. Как проверить

./run.sh --no-serve
.venv/bin/python -m pip install pypdf==6.19.0      # только для проверки текста PDF-справок
FINANCE_DATA=data FINANCE_DATA_DIR=data FINANCE_ANALYSIS=out/analysis.json \
  ASSISTANT_ANALYSIS_PATH=out/analysis.json WORKBENCH_VERIFY_BOOTSTRAP=1 \
  .venv/bin/python -m unittest discover -s tests -v
cd web && WORKBENCH_REAL=../out/analysis.json npm test
for part in assistant shortlist import; do npx vitest run --config src/features/$part/vitest.config.ts; done
INSIGHTS_REAL=../out/analysis.json npx vitest run --config src/features/insights/vitest.config.ts
npx vitest run --config src/features/assistant/chat.vitest.config.ts

В чистой копии этой версии прошли все проверки: 220 — анализа, сервера, ассистента, импорта и PDF-справок, 177 — интерфейса (просмотрщик — 48, сохранённые разговоры — 41, ассистент — 29, сохранённые счета — 34, импорт — 15, наблюдения — 10), включая прогон на данных организаторов. Переменные окружения включают проверки на официальных данных и полную установку из копии исходников; без них эти проверки явно пропускаются, и это не считается подтверждением.

Каждое требование задания связано со строками кода и тестом в FEATURES.md. Три счёта, на которых удобно проверить объяснения (жюри может назвать любые другие):

  • 100000004015047100 — первый в очереди проверки, консолидатор: 9 разных плательщиков при пороге 7. У роли «конечный получатель» почти такая же опора, поэтому она показана как альтернатива.
  • 100000003037476100 — счёт на 4-м колене: исходящие не собирались, поэтому роль «конечный получатель» не присвоена, а карточка называет недостающие данные.
  • 100000000456947100 — исходный клиент без переводов в выгрузке: сохранён, роль не оценивается.

9. Данные и интеграции

Используются только обезличенные данные организаторов: 2 248 счетов, 3 119 агрегированных пар, 4 840 транзакций за 1–31 июля 2026 года, 81 исходный клиент, оборот 365 890 012,01 ₸. Данные не хранятся в репозитории. Внешнее обогащение и персональные атрибуты не используются.

Выходы: три CSV по схеме задания, analysis.json (единая модель фактов, включая дополнительные наблюдения) и квитанции запуска. Выгрузки последнего проверенного запуска на данных организаторов лежат в results/: ./run.sh создаёт в out/ побайтно такие же файлы. Единственная внешняя интеграция — необязательный OpenAI API для ассистента. Если ключ задан, модель получает вопрос и факты графа, выбранные проверенными операциями чтения; без ключа данные не покидают машину. Сервер просмотрщика слушает только 127.0.0.1 и отдаёт лишь интерфейс, четыре файла результатов и запросы к ассистенту, PDF-справкам и импорту.

10. Ограничения

Выгрузка содержит только исходящие внутрибанковские переводы от исходных клиентов на глубину четыре перехода с порогом 5 000 ₸. Полный баланс счёта, происхождение денег, личность клиента и порядок операций внутри дня из этих данных не определяются. Цепочка с возрастающими датами не доказывает движение тех же самых денег. Размеченных ролей нет, поэтому точность не заявляется: роли и приоритеты — обоснованные гипотезы для проверки аналитиком. Пороги подобраны под структуру этой выгрузки и при других данных требуют пересмотра.

Что изменится при росте до 1 млн узлов

Измерено сейчас (Apple M4 Max, Python 3.14): полный запуск ./run.sh --no-serve из чистой копии — около 13 с, из них анализ — около 5 с при первом запуске в новой среде и меньше секунды при повторном; пиковая память анализа — около 140 МБ; analysis.json весит 6,7 МБ. Эти числа относятся к 2 248 счетам и не переносятся на миллион линейно.

Что придётся изменить (проект, не проверенный результат). При пропорциях текущих данных миллион счетов даёт порядка 1,4 млн пар и 2,2 млн транзакций.

  • Загрузка и метрики. Словари Python заменяются колоночной обработкой (Arrow, DuckDB или Polars): степени, суммы и доли — группировки за один проход по рёбрам.
  • Кластеры. Louvain в NetworkX выполняется в одном потоке. Кандидат на замену — Leiden (igraph) с фиксированным зерном: он гарантирует связность сообществ, а выигрыш во времени и устойчивость кластеров нужно измерить на тех же данных до перехода.
  • Даты и цепочки. Сейчас поиск от исходных клиентов проходит по всем наблюдаемым переходам; глубина 4 — это граница сбора выгрузки, а не ограничение алгоритма. На большом графе поиск отсекает ветви по монотонности дат, а транзакции индексируются по отправителю и дате.
  • Циклы и маршруты. Перечисление циклов уже ограничено длиной 4 и пределом числа циклов; на большом графе оно выполняется по компонентам параллельно.
  • Просмотрщик и ассистент. Один файл фактов перестаёт помещаться в браузер. Факты переносятся в локальную базу с индексом по gid, а интерфейс и ассистент запрашивают только окрестность выбранного счёта, очередь приоритетов и верх кластера.
  • Обновления. При ежедневных выгрузках пересчитываются только затронутые окрестности.

11. Ссылка на развёрнутую версию

Развёрнутой версии нет намеренно. Задание требует локальной работы с банковскими данными, поэтому весь сценарий запускается на машине аналитика командой ./run.sh.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
137
Авторы
1
Файлы
179
Ветки
1

Авторы коммитов

kensai 137

История коммитов

  • 2026-09-23 17:45README: как открыть просмотрщик в браузере и остановить серверkensai
  • 2026-09-23 17:42Число проверок анализа — 220; ссылки на строки для финальной сборкиkensai
  • 2026-09-23 17:41README: как получить Python 3.12 на macOS и как показана схема сетиkensai
  • 2026-09-23 17:41Уточнить сценарий удаления: все 2 248 счетов, среднее по 50 случайным наборам, расчёт на графе выгрузкиkensai
  • 2026-09-23 17:41Итоговые числа проверок и ссылки на строки для финальной сборкиkensai
  • 2026-09-23 17:41Убрать несуществующую команду проверки и уточнить вывод о весахkensai
  • 2026-09-23 17:37Отдавать worker PDF.js (.mjs) как JavaScript: просмотр справки работает в собранной версииkensai
  • 2026-09-23 17:30Показывать аналитику понятные основания ответаkensai
Все коммиты (137)
  • 2026-09-23 17:28Показывать понятные основания вместо сырого JSONkensai
  • 2026-09-23 17:26Объединить финальную проверенную сборку и материалы для жюриkensai
  • 2026-09-23 17:25Сделать PDF-справку понятнее аналитикуkensai
  • 2026-09-23 17:25Настроить выбранные автором модели помощникаkensai
  • 2026-09-23 17:25Добавить отдельную загрузку каждого файла данныхkensai
  • 2026-09-23 17:24Объединить с основной веткой: итоговая документация, выгрузки и FEATURES.mdkensai
  • 2026-09-23 17:23Исправить просмотр PDF и связать команды помощника с интерфейсомkensai
  • 2026-09-23 17:21Объединить с веткой интеграции: новые команды навигации помощникаkensai
  • 2026-09-23 17:21README и FEATURES.md: наблюдения, сохранённые разговоры, почему так много периферийных счетовkensai
  • 2026-09-23 17:20Объединить PDF-справку без машинных кодов оснований и с одной короткой оговоркойkensai
  • 2026-09-23 17:20Показывать Astra 6 и Sol с Luna семейства 5.6kensai
  • 2026-09-23 17:20Объяснить факторы приоритета в ответах помощникаkensai
  • 2026-09-23 17:20Выполнять новые команды навигации и убрать лишнюю подпись вводаkensai
  • 2026-09-23 17:20PDF-справка: без машинных кодов оснований, одна короткая оговорка, запрос данных на первой страницеkensai
  • 2026-09-23 17:19Импорт: кнопка «Загрузить / Заменить» в каждой строке таблицыkensai
  • 2026-09-23 17:17Переходы из ответа помощника: счёт, карта, кластер, очередь и сохранённые; один помощник в шапкеkensai
  • 2026-09-23 17:17Объединить с веткой переходов помощника: модель, усилие, наглядные ответы и переходы по рабочему местуkensai
  • 2026-09-23 17:15Показывать справку PDF на canvas через PDF.js, без встроенного модуля браузераkensai
  • 2026-09-23 17:14Подключить переходы помощника и убрать подсказку под полемkensai
  • 2026-09-23 17:13Итоговая документация на основной ветке: выгрузки, ссылки на строки и числа пересобраныkensai
  • 2026-09-23 17:11Объединить итоговую документацию, выгрузки и проверку обоснованности с основной веткойkensai
  • 2026-09-23 17:10Выровнять действия карточки, закрепить gid в одну строку и смягчить стрелки картыkensai
  • 2026-09-23 17:10Объяснить приоритет пятью понятными факторамиkensai
  • 2026-09-23 17:09Подключить выбор модели, историю диалога и наглядные ответыkensai
  • 2026-09-23 17:06Обоснованность без эталона: подсказки, ловушки данных, устойчивость к порогам и весамkensai
  • 2026-09-23 17:04Помощник: описание рабочей области — модель, усилие, контекст, таблицы и ограниченияkensai
  • 2026-09-23 17:04Добавить проверяемые команды перехода по рабочему местуkensai
  • 2026-09-23 17:04Ответы помощника: таблицы и схема пути из проверенного результатаkensai
  • 2026-09-23 17:03Согласовать очередь и альтернативы в ответах помощникаkensai
  • 2026-09-23 17:03Открыть помощника из шапки и упростить пояснение приоритетаkensai
  • 2026-09-23 17:01Разрешить проверенные переходы по интерфейсу из диалогаkensai
  • 2026-09-23 17:00Сохранённые счета: круглые отметки выбора и текст сервера для неизвестного счётаkensai
  • 2026-09-23 16:59Экскурсия по коду: путь одного счёта через все модули простыми словамиkensai
  • 2026-09-23 16:59Помощник: модель, ступенчатое усилие и контекст разговора в рабочей областиkensai
  • 2026-09-23 16:58Подключить помощника в верхней панели и показать приоритет пятью признаками с весамиkensai
  • 2026-09-23 16:57Показать наблюдения и исправить выявленные ошибки интерфейса и расчётовkensai
  • 2026-09-23 16:57Добавить рабочую область сохранённых разговоровkensai
  • 2026-09-23 16:55Показать дополнительные наблюдения: вкладка «Наблюдения» и строки наблюдений в карточке счётаkensai
  • 2026-09-23 16:55Согласовать очередь и альтернативы помощника с правилами расчётаkensai
  • 2026-09-23 16:54Исправить найденное независимой проверкой: двойная точка, возвраты в быстром транзите, формулировки и действия карточкиkensai
  • 2026-09-23 16:52Уточнить сценарий удаления: 10 счетов с наибольшим приоритетомkensai
  • 2026-09-23 16:50Документация и выгрузки для очереди без исходных клиентовkensai
  • 2026-09-23 16:50Поддержать CSV и начать очередь с новых счетов для проверкиkensai
  • 2026-09-23 16:49Объединить документацию и выгрузки с версией без исходных клиентов в очередиkensai
  • 2026-09-23 16:49Объединить с веткой интеграции: помощник с историей, моделями и усилиемkensai
  • 2026-09-23 16:48Подготовить проверяемые таблицы и схемы в ответах помощникаkensai
  • 2026-09-23 16:48Очередь проверки — счета за пределами списка исходных клиентовkensai
  • 2026-09-23 16:48Выгрузки на данных организаторов в results/ и документация итоговой версииkensai
  • 2026-09-23 16:45Добавить проверяемые таблицы и схемы в ответы помощникаkensai
  • 2026-09-23 16:45Объединить документацию для жюри с итоговой интеграциейkensai
  • 2026-09-23 16:45Импорт CSV той же схемы и загрузка данных из окна «О данных»kensai
  • 2026-09-23 16:44Обновить документацию и карту требований для жюриkensai
  • 2026-09-23 16:39Открыть дополнительные наблюдения через инструменты помощникаkensai
  • 2026-09-23 16:39Подключить сохранённые счета, просмотр PDF и загрузку данныхkensai
  • 2026-09-23 16:35Основание: при одинаковом округлении опоры альтернатива «не слабее», а не «сильнее»kensai
  • 2026-09-23 16:35Подключить сохранённые счета, просмотр PDF и загрузку данных; сервер отвечает по одному снимкуkensai
  • 2026-09-23 16:34Помощник: карта состояний рабочей области для проверки в браузереkensai
  • 2026-09-23 16:34Связать помощника с рассчитанными паттернами графаkensai
  • 2026-09-23 16:33Документация: PDF-справки, проверенные модели ассистента и точные формулировки плана масштабаkensai
  • 2026-09-23 16:32Помощник: рабочая область разговоров со значком в шапкеkensai
  • 2026-09-23 16:31Добавить сравнение счетов, контекст диалога и выбор моделейkensai
  • 2026-09-23 16:31Объединить документацию для жюри с интеграцией b7abab5kensai
  • 2026-09-23 16:29Merge commit '5f2bd88' into worktree-runtime-integrationkensai
  • 2026-09-23 16:29Merge commit '23cdc44' into worktree-runtime-integrationkensai
  • 2026-09-23 16:29Добавить сравнение счетов и проверяемый контекст диалогаkensai
  • 2026-09-23 16:25Уточнить раскрытие переводов и закрепление переключателяkensai
  • 2026-09-23 16:24Документация для жюри: навигация, карта задания со ссылками на строки кода, итоговая версияkensai
  • 2026-09-23 16:22Сделать ссылки на счета в ответах помощника читаемымиkensai
  • 2026-09-23 16:21Объединить с main: встроенный помощник для рабочей области чатаkensai
  • 2026-09-23 16:20Исправить ссылки на счета и экранирование в ответах помощникаkensai
  • 2026-09-23 16:20Сохранённые счета: номер в очереди обычным шрифтом, цифры табличныеkensai
  • 2026-09-23 16:19Объединить документацию для жюри с рабочей средой и помощникомkensai
  • 2026-09-23 16:18Добавить PDF-справки и уточнить ограничения наблюденияkensai
  • 2026-09-23 16:16Просмотрщик: полоса переключателя без щели и со стеклом, переводы пары по одному в строкеkensai
  • 2026-09-23 16:16Merge remote-tracking branch 'origin/main' into worktree-runtime-integrationkensai
  • 2026-09-23 16:15Уточнить формулировки: «90% суммы набралось за N дн.» и «исходящие — X% наблюдаемых входящих»kensai
  • 2026-09-23 16:15Просмотр PDF: отчёт по сохранённым и справка по открытому счёту в окнеkensai
  • 2026-09-23 16:13Подключить PDF-справки к серверу: POST /api/report возвращает файл или понятную ошибкуkensai
  • 2026-09-23 16:11Merge branch 'wt/finance-pdf-cli' into worktree-runtime-integrationkensai
  • 2026-09-23 16:10Подключить помощника, локальный запуск и дополнительные наблюденияkensai
  • 2026-09-23 16:10PDF-справка по одному или нескольким счетам: render_pdf и командная строкаkensai
  • 2026-09-23 16:09Сохранённые счета: список по набору данных и PDF-отчёт по выбраннымkensai
  • 2026-09-23 16:07Уточнить время запуска и служебные файлы в документацииkensai
  • 2026-09-23 16:07Merge remote-tracking branch 'origin/main' into worktree-runtime-integrationkensai
  • 2026-09-23 16:07Собрать рабочую среду: сначала анализ, затем просмотрщик, помощник на сервере и наблюдения в analysis.jsonkensai
  • 2026-09-23 16:06Импорт нового набора данных: три parquet-файла по схеме кейсаkensai
  • 2026-09-23 16:06Обновить документацию для жюри: README, реестр функций, схема и сценарий демоkensai
  • 2026-09-23 16:06Обновить факты правил и устойчивость интерфейсаkensai
  • 2026-09-23 16:05Просмотрщик: липкий переключатель очереди, строки переводов без сдвига колонок, факты правил второй версииkensai
  • 2026-09-23 15:59Исправить копирование и высоту страницы просмотрщикаkensai
  • 2026-09-23 15:59Merge branch 'wt/wave-2a9c373a' into worktree-runtime-integrationkensai
  • 2026-09-23 15:59Merge branch 'wt/wave-fb868a9d' into worktree-runtime-integrationkensai
  • 2026-09-23 15:58Merge branch 'worktree-roles-repair' into worktree-runtime-integrationkensai
  • 2026-09-23 15:58Merge branch 'wt/wave-5521f889' into worktree-runtime-integrationkensai
  • 2026-09-23 15:58Merge branch 'wt/wave-f3962f1b' into worktree-runtime-integrationkensai
  • 2026-09-23 15:58Добавить панель помощника с проверяемыми ответами и ссылками на счетаkensai
  • 2026-09-23 15:58Добавить помощника по графу с проверяемыми операциями и локальным разбором без ключаkensai
  • 2026-09-23 15:57Добавить запуск одной командой, локальный сервер и приёмочные проверкиkensai
  • 2026-09-23 15:57Сохранить полные объяснения ролей без обрезкиkensai
  • 2026-09-23 15:54Не обрезать объяснения ролей: короче формулировки, пометка о пробеле только если помещаетсяkensai
  • 2026-09-23 15:49Объединить просмотрщик с исправленными правилами ролейkensai
  • 2026-09-23 15:49Просмотрщик: прежняя кнопка копирования, скрытые подписи не удлиняют страницуkensai
  • 2026-09-23 15:46Исправить правила ролей по независимой проверке: даты, пробелы наблюдения, контрагентыkensai
  • 2026-09-23 15:43Merge branch 'wt/wave-55ca2080' into wt/finance-integrationkensai
  • 2026-09-23 15:37Просмотрщик: шапка кластера кратко, условие «или» у конечного получателя, приоритет на карточкахkensai
  • 2026-09-23 15:35Merge branch 'wt/wave-55ca2080' into wt/finance-integrationkensai
  • 2026-09-23 15:35Сохранить родство уже перенесённого коммита аналитического ядраkensai
  • 2026-09-23 15:35Сохранить родство уже перенесённого коммита временного анализаkensai
  • 2026-09-23 15:26Просмотрщик: суммы не делятся, контекст кластера назван явноkensai
  • 2026-09-23 15:24Просмотрщик: длинные суммы в фактах роли занимают строку целикомkensai
  • 2026-09-23 15:23Просмотрщик: основания читаются с одного взглядаkensai
  • 2026-09-23 15:19Просмотрщик: клавиша «/» ставит курсор в поиск gidkensai
  • 2026-09-23 15:19Ускорить поиск быстрого транзита, ограничить перечисление циклов и уточнить тексты наблюденийkensai
  • 2026-09-23 15:18Просмотрщик: фильтр ролей и карта кластераkensai
  • 2026-09-23 15:17Просмотрщик: кнопка копирования gid из Command Center, 44 px на телефонеkensai
  • 2026-09-23 15:15Добавить дополнительные наблюдения по графу: временные шаблоны, маршруты, циклы, аномалии и устойчивостьkensai
  • 2026-09-23 15:14Просмотрщик: число возвратных потоков открывает их списокkensai
  • 2026-09-23 15:13Просмотрщик: карта шире на ноутбуке, реестр проверок в READMEkensai
  • 2026-09-23 15:12Просмотрщик: стрелки «Назад» и «Вперёд» по счетам, доступностьkensai
  • 2026-09-23 15:10Просмотрщик: ширина страницы на телефоне и режим после «Назад»kensai
  • 2026-09-23 15:07Просмотрщик: спокойная компоновка с раскрытием подробностейkensai
  • 2026-09-23 15:01Просмотрщик: рабочее место проверки на React и TypeScriptkensai
  • 2026-09-23 14:54Объединить ядро и временной анализ: 51 проверка и запуск на исходных данныхkensai
  • 2026-09-23 14:46Добавить аналитическое ядро: роли, приоритет, кластеры и выгрузкиkensai
  • 2026-09-23 14:46Добавить временную достижимость от исходных клиентов со свидетелями цепочекkensai
  • 2026-09-23 14:42Добавить временную достижимость от исходных клиентов со свидетелями цепочекkensai
  • 2026-09-23 14:41Добавить аналитическое ядро: роли, приоритет, кластеры и выгрузкиkensai
  • 2026-09-23 14:12Зафиксировать контракт финансового кейса и проектную архитектуруkensai
  • 2026-09-23 12:50Исключить локальные файлы агентов из репозиторияkensai
Структура репозитория (179 файлов)
.env.example
.gitignore
FEATURES.md
README.md
assistant/README.md
assistant/__init__.py
assistant/config.py
assistant/conversation.py
assistant/openai.py
assistant/presentation.py
assistant/queries.py
assistant/render.py
assistant/service.py
backend/__init__.py
backend/__main__.py
backend/analysis.py
backend/clusters.py
backend/exports.py
backend/fmt.py
backend/insight_policy.py
backend/insights.py
backend/io.py
backend/metrics.py
backend/policy.py
backend/priority.py
backend/roles.py
backend/temporal.py
docs/architecture.md
docs/case-contract.md
docs/code-tour.md
docs/demo.md
docs/validation.md
imports/README.md
imports/__init__.py
imports/ingest.py
reports/__init__.py
reports/__main__.py
reports/facts.py
reports/fonts/NotoSans-Bold.ttf
reports/fonts/NotoSans-Regular.ttf
reports/fonts/OFL.txt
reports/pdf.py
requirements.txt
results/README.md
results/clusters.csv
results/nodes_roles.csv
results/run_receipt.json
results/top_nodes.csv
run.sh
serve.py
tests/test_acceptance.py
tests/test_assistant.py
tests/test_core.py
tests/test_imports.py
tests/test_insights.py
tests/test_reports.py
tests/test_roles_repair.py
tests/test_server.py
tests/test_temporal.py
tools/sensitivity.py
web/.npmrc
web/README.md
web/fixtures/analysis.json
web/fixtures/build-fixture.mjs
web/index.html
web/package-lock.json
web/package.json
web/src/app/App.tsx
web/src/app/AssistantSlot.tsx
web/src/app/Workbench.tsx
web/src/app/hash.ts
web/src/app/useAccountHistory.ts
web/src/app/useAnalysis.ts
web/src/data/brief.ts
web/src/data/format.ts
web/src/data/graph.ts
web/src/data/neighborhood.ts
web/src/data/roleFacts.ts
web/src/data/schema.ts
web/src/data/search.ts
web/src/features/assistant/AnswerCard.tsx
web/src/features/assistant/AssistantPanel.tsx
web/src/features/assistant/AssistantWorkspace.tsx
web/src/features/assistant/ModelEffortMenu.tsx
web/src/features/assistant/NodeLink.tsx
web/src/features/assistant/README.md
web/src/features/assistant/SafeAnswer.tsx
web/src/features/assistant/WORKSPACE.md
web/src/features/assistant/api-context.test.ts
web/src/features/assistant/api.ts
web/src/features/assistant/assistant.css
web/src/features/assistant/assistant.test.tsx
web/src/features/assistant/chat.vitest.config.ts
web/src/features/assistant/conversationStore.ts
web/src/features/assistant/conversations.test.tsx
web/src/features/assistant/index.tsx
web/src/features/assistant/model.test.tsx
web/src/features/assistant/modelSettings.ts
web/src/features/assistant/navigation.ts
web/src/features/assistant/rich.test.tsx
web/src/features/assistant/surface.manifest.json
web/src/features/assistant/types.ts
web/src/features/assistant/useConversations.ts
web/src/features/assistant/vitest.config.ts
web/src/features/assistant/workspace.css
web/src/features/assistant/workspace.surface.manifest.json
web/src/features/assistant/workspace.test.tsx
web/src/features/import/ImportPanel.tsx
web/src/features/import/README.md
web/src/features/import/api.ts
web/src/features/import/import.css
web/src/features/import/import.test.ts
web/src/features/import/index.tsx
web/src/features/import/vitest.config.ts
web/src/features/insights/AccountInsights.tsx
web/src/features/insights/InsightsPanel.tsx
web/src/features/insights/index.ts
web/src/features/insights/insights.css
web/src/features/insights/insights.test.tsx
web/src/features/insights/model.ts
web/src/features/insights/vitest.config.ts
web/src/features/shortlist/PdfCanvasViewer.tsx
web/src/features/shortlist/README.md
web/src/features/shortlist/ReportDialog.tsx
web/src/features/shortlist/SaveAccountButton.tsx
web/src/features/shortlist/ShortlistPanel.tsx
web/src/features/shortlist/index.ts
web/src/features/shortlist/pdfEngine.ts
web/src/features/shortlist/report.ts
web/src/features/shortlist/reportSession.ts
web/src/features/shortlist/shortlist.css
web/src/features/shortlist/shortlist.test.tsx
web/src/features/shortlist/store.ts
web/src/features/shortlist/useShortlist.tsx
web/src/features/shortlist/vitest.config.ts
web/src/main.tsx
web/src/map/MapFrame.tsx
web/src/map/clusterLayout.ts
web/src/map/egoLayout.ts
web/src/map/icons.tsx
web/src/map/useMapCamera.ts
web/src/map/useMapFullscreen.ts
web/src/styles/components/controls.css
web/src/styles/components/identity.css
web/src/styles/core/base.css
web/src/styles/core/tokens.css
web/src/styles/index.css
web/src/styles/responsive/mobile.css
web/src/styles/views/inspector.css
web/src/styles/views/lists.css
web/src/styles/views/map.css
web/src/styles/views/workbench.css
web/src/ui/Amount.tsx
web/src/ui/ClusterPanel.tsx
web/src/ui/CopyGid.tsx
web/src/ui/EvidencePanel.tsx
web/src/ui/Gid.tsx
web/src/ui/LeadsRail.tsx
web/src/ui/MapPanel.tsx
web/src/ui/Outline.tsx
web/src/ui/RoleGlyph.tsx
web/src/ui/SearchBox.tsx
web/src/ui/StatusScreen.tsx
web/src/ui/TopBar.tsx
web/surface.manifest.json
web/tests/brief.test.ts
web/tests/cluster.test.ts
web/tests/format.test.ts
web/tests/hash.test.ts
web/tests/helpers.ts
web/tests/neighborhood.test.ts
web/tests/outline.test.ts
web/tests/real-data.test.ts
web/tests/roleFacts.test.ts
web/tests/schema.test.ts
web/tests/search.test.ts
web/tsconfig.json
web/vite.config.ts
web/vitest.config.ts

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.