О проекте
Команда: 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 — устройство просмотрщика.
Для жюри: проверка за пять минут
- Положите три файла организаторов в
data/и выполните./run.sh. Первый запуск ставит зависимости; затем анализ за секунды создаёт вout/три CSV и запускает просмотрщик. Откройте в браузере http://127.0.0.1:8765 — адрес печатается в конце работы скрипта; остановить — Ctrl+C. - Откройте
out/nodes_roles.csv, выберите любые триgidи найдите их в просмотрщике (клавиша/). Карточка объясняет роль через метрику и порог правила, показывает альтернативу и связи. - Сверьте объяснение с порогами в таблице раздела 4 и строками кода в FEATURES.md. Как устроен весь код, за десять минут объясняет экскурсия по коду.
- Запустите проверки из раздела 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 разных плательщиков | 17 | 9 консолидаторов и 8 распределителей: при веере на 10 и более получателей основной становится роль распределителя |
| Узлы с веерной рассылкой на 60–116 получателей | 8 | все 8 — распределители |
| 72 узла с коэффициентом пропуска 0,8–1,2 | 72 | транзитом остаются 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.
Авторы коммитов
История коммитов
- 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 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.