AAYMA
RU
Войти

Tyuin

Рабочее место аналитика финмониторинга: направленный граф переводов, список клиентов и досье с гипотезами ролей и объяснённым приоритетом проверки.

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

О проекте

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

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

Суть

Рабочее место аналитика финмониторинга: направленный граф переводов, список клиентов и досье с гипотезами ролей и объяснённым приоритетом проверки. Можно загрузить свои Parquet, есть онлайн-деплой.

Как устроено

Python-пакет moneygraph читает три Parquet (nodes, edges, transactions) и строит направленный граф в NetworkX. Модуль clusters.py выделяет кластеры, затем пайплайн присваивает роли с указанием границ наблюдения и неопределённости (например, «недостаточно данных для роли» на 4-м колене) и считает приоритет проверки с объяснением. Результаты: три CSV и manifest, команда verify их проверяет. React-интерфейс связывает граф и досье. OpenAI-ассистент подключается из браузера и только объясняет рассчитанные факты.

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

  • NetworkX
  • направленный граф транзакций
  • кластеризация сообществ
  • гипотезы ролей
  • приоритизация с объяснением
  • гипотезы назначения кластера
  • CLI verify

Особенности

Процесс agentic SDD для Codex и Claude Code: спецификации, контракты, ревью и backlog в docs. Продукт явно показывает, где кончаются наблюдаемые данные. Результат воспроизводим (canonical output, verify), на Brev пройдено 127 тестов.

Стек

Python · NetworkX · React · TypeScript · Vite · Docker Compose · Caddy · NVIDIA Brev

Модели

OpenAI (browser assistant)


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

README

README.md

Tyuin · Скрытые финансовые связи

Открыть приложение — hackalemai.uniqore.dev

Tyuin — рысь-сыщик

От потока переводов — к понятной картине связей и обоснованному плану проверки.

Tyuin — рабочее пространство для исследования финансовых связей. Оно помогает аналитику увидеть движение средств между участниками, разобраться в структуре групп и определить, кого проверить первым. Можно исследовать демонстрационный набор или загрузить свои три Parquet в поддерживаемом формате.

Направленный граф, список клиентов и досье связаны между собой. От общей картины можно перейти к отдельному участнику, основаниям его роли и конкретным операциям. Приоритет проверки сопровождается объяснением.

Понимать, где заканчиваются данные, так же важно, как видеть связи. Tyuin учитывает границы наблюдения, показывает неопределённость и помогает определить следующий шаг проверки.

Основная аналитика работает локально, без GPU и внешнего AI. Ассистент дополняет её объяснениями рассчитанных фактов. Основной пользователь — аналитик финансового мониторинга; текущий набор демонстрирует подход на задаче исследования транзакционной сети.

Запуск и деплой · Свои данные · Сценарий аналитика · Как работает · Результаты · Ограничения и развитие

Рабочее пространство Tyuin: клиенты, направленный граф и досье связаны выбором участника

Запустить и проверить

Онлайн-приложение доступно по https://hackalemai.uniqore.dev без аккаунта Brev. Ниже — самостоятельный запуск и полный путь развёртывания на своём сервере. Основной сценарий, API и три CSV не требуют ключа AI.

23.09.2026 приложение обновлено до main f4077ff: алгоритм 1.2.0, импорт собственных Parquet, новый интерфейс и подключение AI из браузера. На Brev прошли 127 тестов, проверки API, трёх CSV и импорта через HTTPS. Отчёт передеплоя и откат.

Имя продукта — Tyuin; внутренний Python-пакет и CLI называются moneygraph. «Граф денег» — название демонстрационного кейса организатора.

Подготовка

Выберите один способ запуска:

СпособЧто установитьЧто входит в репозиторий
DockerGit, работающий Docker Engine / Docker Desktop и Compose v2 с поддержкой --waitPython, зависимости, frontend и данные собираются в образ
PythonGit и Python 3.12+; версия 3.14.1 исключена NetworkX 3.7Готовый frontend, requirements.lock, исходные Parquet
Brev VMBrev CLI, доступ к своей VM; на VM — Docker и ComposeТот же Dockerfile и Compose, конфигурация HTTPS

Для воспроизведения полного исторического Windows-прогона используйте Python 3.12.14. Node нужен только для разработки интерфейса. Первичная установка Python-зависимостей требует PyPI, сборка Docker — также Docker Hub. После установки основной локальный сценарий работает без сети.

Склонируйте репозиторий и перейдите в его корень:

git clone https://github.com/BAITC-Hacks/hack-9fee8947-uniqore-ai.git
cd hack-9fee8947-uniqore-ai

В checkout должны быть requirements.lock, moneygraph/web/ и три файла data/nodes.parquet, data/edges.parquet, data/transactions.parquet. Вручную готовить CSV или собирать frontend для просмотра не нужно. Если репозиторий закрыт, используйте свою разрешённую Git-авторизацию без токена в URL.

Docker: сборка и запуск

Команды выполняются из корня репозитория в PowerShell или Bash:

docker compose version
docker compose --env-file .env.example config --quiet
docker compose --env-file .env.example up -d --build --wait --wait-timeout 360
docker compose --env-file .env.example ps
docker compose --env-file .env.example exec -T app python -m moneygraph verify --data /app/data --out /app/out

Ожидаемый результат: сервис app имеет статус healthy, verify возвращает status: "ok". Откройте http://127.0.0.1:8765 и проверьте клиентов, граф и досье. Адрес 0.0.0.0 в логе относится к контейнеру; в браузере используйте 127.0.0.1.

Порт по умолчанию открыт только на loopback. Если 8765 занят, задайте TYUIN_PORT=8766 перед запуском: в Bash — export TYUIN_PORT=8766, в PowerShell — $env:TYUIN_PORT = '8766'. Тогда адрес приложения — http://127.0.0.1:8766.

Логи, перезапуск и остановка:

docker compose --env-file .env.example logs --tail=100 app
docker compose --env-file .env.example restart app
docker compose --env-file .env.example up -d --wait --wait-timeout 360
docker compose --env-file .env.example down

Каждый старт пересчитывает данные. Результаты находятся в именованном томе analysis-output; down сохраняет его, down --volumes удаляет. Контейнер работает от UID/GID 10001: произвольный bind mount вместо /app/out требует соответствующих прав. Лимит 360 секунд относится к ожиданию готовности после сборки, а не к общей длительности установки.

Windows: PowerShell и Python

Установите Python 3.12 и проверьте выбранный интерпретатор. Выполните из корня репозитория:

py --list
py -3.12 --version
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.lock
.\.venv\Scripts\python.exe -m pip check
.\.venv\Scripts\python.exe scripts/check_environment.py --profile runtime
.\.venv\Scripts\python.exe -m moneygraph demo --data data --out out

Ожидаются No broken requirements found, PASS, затем JSON status: "ok" и адрес сервера. Активация окружения и изменение ExecutionPolicy не нужны. Без launcher используйте полный путь к Python: например, & 'C:\Python312\python.exe' -m venv .venv, заменив путь своим. Для другого поддерживаемого интерпретатора укажите его версию явно, например py -3.14, исключая 3.14.1. Существующее окружение другой версии сохраните и создайте новое.

macOS / Linux: Python

Проверьте python3 --version. Если он старше 3.12 или равен 3.14.1, выберите поддерживаемый интерпретатор, например python3.12, в первой команде:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.lock
python -m pip check
python scripts/check_environment.py --profile runtime
python -m moneygraph demo --data data --out out

Для обоих Python-маршрутов откройте http://127.0.0.1:8765 после появления адреса в терминале. Сервер слушает только локальный адрес; терминал должен оставаться открытым. Остановить — Ctrl+C. При занятом порте добавьте --port 8766 и откройте адрес с этим портом. Повторный расчёт перезаписывает выбранный --out; не используйте results/ как выходной каталог.

Проверить успешный запуск

В другом терминале проверьте API. Bash:

curl --fail --max-time 10 http://127.0.0.1:8765/api/health

PowerShell:

Invoke-RestMethod http://127.0.0.1:8765/api/health

Ответ должен содержать status: ok и тот же analysis_id, что out/manifest.json (для Docker — /app/out/manifest.json). При изменении порта подставьте свой. Проверка API не заменяет проверку интерфейса:

  1. Откройте приложение: видны клиенты, направленный граф и досье.
  2. Найдите 100000000018102100: досье показывает четвёртое колено и недостаточность данных для роли.
  3. Выберите связь на графе и проверьте список её операций.
  4. Через «Выгрузить» скачайте три CSV; выполните verify для выходного каталога.

NVIDIA Brev: развёртывание на VM

Создайте свою VM в Brev Console в VM Mode, без Jupyter. Для приложения достаточно CPU; GPU не используется. На VM должны работать Docker и Compose. На своём компьютере установите Brev CLI; на Windows используйте Bash внутри WSL с Ubuntu 20.04+.

В локальном терминале Bash/WSL:

brev --version
brev login
brev refresh
brev ls --json
brev shell tyuin

Здесь tyuin — имя вашего инстанса; замените его при необходимости. Перед подключением дождитесь BUILD COMPLETED, SHELL READY, HEALTH HEALTHY. Для VM используется обычный SSH-шлюз Brev. В контейнерном режиме для Docker хоста может потребоваться --host; для проверенной VM обычное подключение работает, а --host получало тайм-аут.

На VM клонируйте репозиторий командами из раздела «Подготовка» и выберите проверенный commit: git checkout <SHA_проверенной_версии>. Он должен содержать Dockerfile, готовый frontend и deploy/brev/domain-web.compose.yml. Затем выполните:

docker compose version
docker compose --env-file .env.example config --quiet
docker compose --env-file .env.example up -d --build --wait --wait-timeout 360
docker compose --env-file .env.example ps
curl --fail --max-time 10 http://127.0.0.1:8765/api/health
docker compose --env-file .env.example exec -T app python -m moneygraph verify --data /app/data --out /app/out

Для закрытого репозитория можно доставить архив проверенного commit без GitHub-токена на VM. На своём компьютере из чистого checkout выбранной версии:

git archive --format=tar.gz --output=../tyuin-release.tar.gz HEAD \
  Dockerfile docker-compose.yml .dockerignore .env.example requirements.lock \
  moneygraph data deploy scripts tests results
shasum -a 256 ../tyuin-release.tar.gz
scp ../tyuin-release.tar.gz tyuin:~/tyuin-release.tar.gz

На VM выполните sha256sum ~/tyuin-release.tar.gz и сравните с локальной суммой. При несовпадении остановитесь. Распакуйте архив в новый каталог выбранного выпуска и выполните команды Compose выше:

mkdir -p ~/workspace/tyuin-release
cd ~/workspace/tyuin-release
tar -xzf ~/tyuin-release.tar.gz

Для повторного выпуска задайте новое имя каталога. Архив содержит демонстрационные данные: передавайте его только на разрешённую VM. Рабочий .env, .git и персональные ключи в архив не входят. При первоначальном облачном прогоне использована именно доставка архива; подробный отчёт.

Для доступа без публичного домена на своём компьютере откройте туннель и оставьте его работающим:

brev refresh
brev port-forward tyuin --port 18765:8765

Откройте http://127.0.0.1:18765. Эквивалент через настроенный SSH-шлюз: ssh -N -T -o ExitOnForwardFailure=yes -L 127.0.0.1:18765:127.0.0.1:8765 tyuin. После закрытия терминала или перезагрузки компьютера туннель нужно открыть снова.

Собственный домен и HTTPS

Этот вариант рассчитан на Linux VM с уже работающим приложением на 127.0.0.1:8765. Посетителям публичного домена не нужен аккаунт Brev. Собственной авторизации у Tyuin нет: публикуйте только разрешённые для такого доступа данные. Демонстрационный адрес проекта — hackalemai.uniqore.dev.

  1. В DNS своего домена создайте A-запись на текущий публичный IPv4 вашей VM. Проверьте, что она разрешается; не оставляйте AAAA на другой сервер. При наличии ограничивающих CAA разрешите выпуск сертификата Let's Encrypt.
  2. Убедитесь, что входящие TCP 80/443 доступны в настройках провайдера и firewall VM, а сами порты свободны. Не открывайте наружу 8765 или административный API Caddy 2019.
  3. Из корня выбранного выпуска на VM задайте свой домен без схемы и пути и проверьте конфигурацию:
export TYUIN_DOMAIN=tyuin.example.com

docker compose --env-file .env.example \
  -f docker-compose.yml -f deploy/brev/domain-web.compose.yml config --quiet
docker compose --env-file .env.example \
  -f docker-compose.yml -f deploy/brev/domain-web.compose.yml \
  run --rm --no-deps domain-web caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile

tyuin.example.com — пример, замените его своим DNS-именем. Если на Ubuntu включён UFW, разрешите HTTP/HTTPS (SSH-доступ должен оставаться разрешённым):

sudo ufw allow proto tcp from any to any port 80 comment tyuin-domain-http
sudo ufw allow proto tcp from any to any port 443 comment tyuin-domain-https

Запустите Caddy и проверьте внешний доступ. Первоначальный выпуск сертификата может занять время: если первый запрос ещё не проходит, дождитесь успешного выпуска по logs --tail=100 domain-web с теми же Compose-файлами и повторите проверку. При устойчивой ошибке проверьте DNS и входящие порты:

docker compose --env-file .env.example \
  -f docker-compose.yml -f deploy/brev/domain-web.compose.yml up -d --no-deps domain-web
curl --fail --max-time 10 "https://${TYUIN_DOMAIN}/api/health"
curl --head --max-time 10 "http://${TYUIN_DOMAIN}/"

Ожидаются status: ok, доверенный HTTPS-сертификат и перенаправление HTTP на HTTPS (308). Затем в браузере откройте https:// со своим доменом и повторите поиск клиента и выгрузку трёх CSV. Не используйте --insecure: доверие сертификату — часть проверки.

Caddy получает и продлевает сертификат автоматически; тома caddy-data и caddy-config нужно сохранять. --no-deps выше запускает только прокси и предполагает уже здоровый app. При изменении порта приложения задайте тот же TYUIN_PORT для прокси. Переменные TYUIN_DOMAIN и TYUIN_PORT нужно задавать снова при пересоздании контейнеров. Linux host networking из этого Compose не предназначен для обычного локального Docker-запуска на macOS/Windows.

Обновление, откат и обслуживание

Сохраняйте предыдущий каталог и образ, а каждому новому выпуску задавайте отдельный тег по проверенному commit. В командах ниже замените COMMIT_SHA на SHA нового выпуска; он известен и при доставке архива без .git.

Сначала в каталоге работающего выпуска на VM сохраните образ действующего контейнера, независимо от того, какой тег использовался раньше:

export TYUIN_RELEASE=COMMIT_SHA
TYUIN_OLD_CONTAINER=$(docker compose -p tyuin --env-file .env.example ps -q app)
TYUIN_OLD_IMAGE=$(docker inspect --format '{{.Image}}' "$TYUIN_OLD_CONTAINER")
docker tag "$TYUIN_OLD_IMAGE" "tyuin:rollback-${TYUIN_RELEASE}"

Если контейнер не найден или команда завершилась ошибкой, остановитесь. Не перезаписывайте существующий rollback-тег: для повторной попытки используйте отдельную метку. Перейдите в новый каталог выбранного выпуска и явно задайте новый тег, даже если в этом терминале раньше выполнялся откат:

export TYUIN_IMAGE="tyuin:${TYUIN_RELEASE}"
docker compose -p tyuin --env-file .env.example build app
docker compose -p tyuin --env-file .env.example \
  up -d --no-deps --no-build --wait --wait-timeout 360 app
docker compose -p tyuin --env-file .env.example exec -T app \
  python -m moneygraph verify --data /app/data --out /app/out

Затем проверьте публичный health, поиск, подпись интерфейса и три CSV. Команда заменяет только app; Caddy и его тома сохраняются. При запуске выполняется пересчёт, поэтому возможен короткий перерыв до готовности API. Для обновления не используйте down, --remove-orphans или --volumes.

Если проверка не прошла, перейдите в сохранённый предыдущий каталог и верните закреплённый образ:

export TYUIN_IMAGE="tyuin:rollback-${TYUIN_RELEASE}"
docker compose -p tyuin --env-file .env.example \
  up -d --no-deps --no-build --wait --wait-timeout 360 app

Повторите health и verify. Предыдущий код пересчитает результаты в том же томе. Не удаляйте старый каталог: он нужен для отката, а его deploy/brev/caddy может оставаться источником конфигурации работающего прокси.

Для конфигурации домена все команды выполняйте с теми же TYUIN_DOMAIN, TYUIN_PORT и двумя Compose-файлами. Логи прокси:

docker compose --env-file .env.example \
  -f docker-compose.yml -f deploy/brev/domain-web.compose.yml logs --tail=100 domain-web

После изменения Caddyfile примените его без остановки приложения:

docker compose --env-file .env.example \
  -f docker-compose.yml -f deploy/brev/domain-web.compose.yml \
  exec -T domain-web caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile

Чтобы остановить только HTTPS, используйте ту же команду Compose с stop domain-web; возобновить — up -d --no-deps domain-web. Не удаляйте тома сертификатов при обновлении. Если меняете каталог выпуска, пересоздайте прокси из нового каталога после проверки приложения, сохранив имя Compose-проекта tyuin и его тома.

Остановка контейнеров не останавливает VM. Для завершения работы VM используйте brev stop tyuin или Brev Console; сайт станет недоступен. После повторного запуска проверьте публичный IP и DNS. Docker restart policy не включает остановленную VM. История проверок и нюансы эксплуатации — в инструкции Brev.

Альтернативный запуск готового образа в Brev

Для режима Docker Compose / Launchable используйте deploy/brev/docker-compose.yml. Нужен опубликованный образ для Linux amd64, доступный вашей VM; готовый публичный образ проекта не предоставляется.

На машине с Docker Buildx в Bash, после авторизации в разрешённом реестре:

export TYUIN_IMAGE="ghcr.io/YOUR_ORG/tyuin:$(git rev-parse --short=12 HEAD)"
docker buildx build --platform linux/amd64 --tag "$TYUIN_IMAGE" --push .
docker compose -f deploy/brev/docker-compose.yml config --quiet

Замените YOUR_ORG на свой namespace в нижнем регистре. --push публикует образ вместе с данными кейса: реестр и доступ должны соответствовать разрешённому использованию данных. Для закрытого реестра предварительно настройте pull-доступ на VM.

В Brev выберите Docker Compose, загрузите указанный файл, задайте Source «My code files are embedded in my container(s)», выключите Jupyter и добавьте обязательный Text-параметр TYUIN_IMAGE с опубликованным тегом или digest. Для доступа используйте Secure Link на порт 8765 и View access «Only my organization». Прямые API-проверки выполняйте через SSH-туннель. Не открывайте сырой порт приложения всему интернету. Реальная публикация образа в реестр и Secure Link этим проектом пока не проверены; основной проверенный маршрут — VM с Docker и собственным HTTPS-доменом.

Пересчёт, CSV и автоматическая проверка

Для Python-запуска в PowerShell замените python на .\.venv\Scripts\python.exe; в macOS/Linux используйте активированное окружение:

python -m moneygraph run --data data --out out
python -m moneygraph verify --data data --out out
python -m moneygraph verify --data data --out results
python -m pytest -q

run пересчитывает и проверяет результат без HTTP-сервера. В out/ появляются три CSV, manifest.json и analysis.json; results/ хранит проверенные примеры и не используется как выходной каталог. Успешный verify возвращает status: ok и код 0. В PowerShell код последней команды — $LASTEXITCODE.

Роли всех узлов · Сообщества · Топ-20 · Manifest и SHA-256.

Автоматическая проверка CLI, API, локальных assets и CSV без Node и AI-ключа:

python scripts/smoke_local_launch.py --data data --out out/readme-check --port 8876

Нужны чистый Git checkout и новый каталог out/readme-check. Для повтора выберите другое имя. Успех — status: pass, код 0 и отчёт out/readme-check/smoke-report.json. Скрипт завершает только свой сервер. Preflight проверяет окружение, smoke — расчёт и HTTP; граф, поиск и остановку через Ctrl+C дополнительно проверьте в браузере и терминале.

Если запуск не удался

СимптомДействие
Python не найден или версия не подходитПроверьте выбранный интерпретатор: нужен 3.12+, кроме 3.14.1. Создайте новый venv нужной версией.
VENV_REQUIRED / VENV_ISOLATIONИспользуйте Python из нового venv без --system-site-packages.
Ошибка зависимости или pip checkУстановите requirements.lock тем же Python из venv; проверьте доступ к PyPI. Не меняйте lock ради обхода ошибки.
INPUT_MISSING_OR_INVALIDПроверьте три Parquet в data/ и целостность checkout. CSV не заменяют входные данные.
FRONTEND_MISSING, пустая страницаПроверьте moneygraph/web/ из той же версии, сетевые запросы и консоль браузера.
Порт занятВыберите другой порт; не завершайте чужой процесс.
Docker недоступен или не знает --waitЗапустите Docker Engine / Desktop, проверьте версию Compose. Проверялся Compose 2.24.5 и новее.
Контейнер не стал healthyПосмотрите logs --tail=100 app, проверьте данные и права тома. Статус unhealthy сам по себе не вызывает restart.
verify --out results сообщает несовпадение hashИспользуйте свежий checkout с .gitattributes; не пересохраняйте эталонные CSV и manifest.
Smoke сообщает, что output существуетВыберите новый каталог внутри out/, сохранив предыдущий результат.
brev ... --host получает тайм-аутДля VM Mode попробуйте обычный SSH-шлюз: brev refresh, затем brev shell tyuin.
Домен не открывается или сертификат не выданПроверьте текущий IP, A/AAAA/CAA, доступность 80/443, занятость портов и логи domain-web.
После остановки VM сайт недоступенЗапустите VM, проверьте IP и DNS, затем состояние приложения и Caddy.
Русский текст искажается в терминалеИспользуйте UTF-8; не пересохраняйте CSV ради отображения.

Дополнительная диагностика Windows · Подробности Brev и сохранённые проверки.

AI подключается отдельно в интерфейсе и не является условием запуска. Настройка и границы AI.

Загрузить собственные данные

После запуска откройте «Загрузить данные», выберите nodes.parquet, edges.parquet и transactions.parquet, затем запустите обработку. Имена, поля и типы должны соответствовать схеме входа; дополнительные колонки не принимаются. Нужны обезличенные данные с той же семантикой, что у кейса: seed и исходящие связи до четвёртого колена, KZT, операции от 5 000 ₸. Период берётся из дат операций и может отличаться от июля 2026; максимум 366 календарных дней включительно.

ФайлПоля
nodes.parquetgid int64, depth целое 0–4, is_seed bool
edges.parquetsrc, dst int64; sum_kzt число; n_tx положительное целое; depth целое 1–4
transactions.parquetsrc, dst int64; date календарная дата без часового пояса; sum_kzt число

Нужны непустой набор клиентов и хотя бы одна операция. gid уникален в nodes, is_seed соответствует depth=0. Пары в edges уникальны; их суммы в тиынах и число операций должны точно совпадать с transactions. Глубина 4 остаётся границей наблюдения, а не параметром, вычисляемым из максимальной глубины загруженного графа.

Лимиты браузерного импорта: 10 MiB на файл, 30 MiB на весь запрос вместе со служебными полями, 5 000 клиентов, 20 000 связей и 100 000 операций; распакованный объём каждого Parquet ограничен 64 MiB. Сервер проверяет формат, типы, ссылки на клиентов, уникальность пар, суммы и количество операций; затем считает анализ и проверяет три CSV. Граф, досье, группы и скачиваемые CSV относятся к одному набору. При ошибке текущий анализ сохраняется. При успешном переключении старые фильтры, перечень проверки, чат и ключ AI сбрасываются. Для набора меньше 20 клиентов top содержит всех клиентов.

Импорт передаётся серверу Tyuin: при локальном запуске — вашему компьютеру, при удалённом — тому серверу, где работает приложение. Временные исходные файлы удаляются после обработки. Результат доступен до часа, очищается из памяти с интервалом до 30 секунд и теряется при перезапуске сервера; это не постоянное хранилище. Токен результата сохраняется в sessionStorage текущей вкладки и не включается в URL; перезагрузка вкладки сохраняет импорт до истечения срока. «Вернуться к исходному набору» освобождает текущий импорт; другие вкладки с собственными наборами не переключаются. Набор, указанный при запуске через --data, остаётся доступен. В одном серверном процессе одновременно разрешены один импортный расчёт и четыре временных набора; чужой действующий набор не вытесняется. При истёкшем или неизвестном токене интерфейс предлагает восстановление, а не подставляет другой набор.

Основной анализ не требует AI. Для отдельного AI-чата действуют настройки ключа и согласие на передачу фактов, описанные в разделе AI: пояснения и чат; загрузка сама по себе не вызывает внешний LLM. Браузерный импорт не заменяет CLI: собственный комплект можно также передать командой python -m moneygraph demo --data путь-к-набору --out out/custom.

Спецификация и критерии приёмки. Доступ к импорту ограничен случайным токеном вкладки; аккаунтов, постоянной истории и полноценного разграничения прав в этой версии нет.

Проверить сценарий аналитика

  1. В сводке набора видны три исходных файла, период, число seed и результат обработки; у демонстрационного набора 81 seed. Статус «3 CSV проверены» появляется только после успешной встроенной проверки команды запуска. Время обработки с записью и проверкой отделено от расчёта; импорты Python до запуска таймера, установка и браузер в него не входят.
  2. В «Клиенты» фильтры идут в порядке «Все клиенты», «На проверку N», «Топ-20». По умолчанию открыты все клиенты и вся сеть. Последний фильтр показывает тот же состав и порядок, что top_nodes.csv; при его выборе остальные фильтры сбрасываются. В каждой строке доступны основание, роль, глобальный ранг, приоритет и кнопка добавления на проверку; в досье на вкладке «Приоритет» — четыре численных вклада.
  3. Введите полный gid и нажмите Enter: поиск идёт по всему набору, сбрасывает мешающие фильтры и открывает роль с порогами и окружением клиента. При включённой подсветке клиент выделяется на всей сети. Фильтры списка остаются доступны во время поиска; переключение фильтра очищает поисковый запрос. Неизвестный gid явно отличается от клиента вне текущей выборки. Изолированный клиент показывается без вымышленных связей.
  4. Галочка «Подсвечивать на всей сети» сохраняет все узлы и связи, выделяет совпадения с фильтрами и приглушает остальное. Смена фильтра в этом режиме сохраняет положение узлов и масштаб. Тёмный контур отдельно обозначает выбранного клиента. При выключенной галочке фильтры скрывают несовпадения; можно выбрать окружение в 1–2 перехода, входящие/исходящие цепочки или всю выборку. Фильтры применяются до обхода. В направленном режиме показаны рёбра, пройденные по выбранному направлению; при всех направлениях — также связи между найденными соседями. Цвет переключается между ролями и группами, seed — ромб, граница — пунктир.
  5. Нажмите ребро, чтобы увидеть операции именно этой пары. hash:row указывает нулевой номер строки оригинального transactions.parquet и префикс его SHA-256. Выбранные даты ограничивают операции и активность связей; роли, приоритеты, суммы досье и три CSV остаются за весь период набора.
  6. Откройте сообщество клиента: карточка показывает состав, внутренний и межгрупповые потоки, гипотезу назначения, правила и ограничения. Остальные группы доступны в списке, возврат восстанавливает клиента и очередь.
  7. «Добавить на проверку» доступно в каждой строке и в досье. Фильтр «Клиенты» → «На проверку N» сохраняет обычные данные строки и дополнительно показывает полный gid, полное основание и следующий шаг. Общие фильтры могут сузить этот список; кнопки копирования явно охватывают весь перечень, включая скрытых клиентов. Можно убрать клиента или вернуться к его досье. Перечень сохраняется при переходах в текущем анализе; перезагрузка его очищает. Он не меняет рассчитанный top-20.
  8. «Выгрузить» отдаёт три обязательных CSV целого набора за весь период, независимо от фильтров и перечня аналитика. «Ассистент» остаётся дополнительным объяснением рассчитанных фактов.

На широком экране три панели прокручиваются независимо. Сводка набора компактна; подробности запуска и ограничения доступны отдельно. На узком экране панели расположены вертикально. План и критерии сценария, проверка текущей версии.

Примеры для живого разбора на исходном демонстрационном наборе, полученные из результата, а не заданные классификатору:

gidЧто показать
100000003684369100Первый в очереди: разные компоненты приоритета, неполный вход seed
100000000031787100Транзитная гипотеза: вход и выход по 90 000 KZT, временная совместимость
100000000456947100Изолированный seed: находится поиском, роль неизвестна, приоритет 0
100000000018102100Четвёртое колено: отсутствие выхода объясняется границей наблюдения

Сценарий пятиминутной демонстрации, исходная локальная проверка и проверка UX-итерации.

Контрольный пример: граница наблюдения

  1. Если открыт свой импорт, вернитесь к исходному набору. Сбросьте фильтры, найдите 100000000018102100 и выберите строку очереди. В досье ожидаются «Не установлена», «4-е колено», вход 7 000 KZT и нулевой наблюдаемый выход.
  2. В «Ассистенте» закройте окно подключения и раскройте «Локальные пояснения · без API». Объяснение «Почему эта роль?» указывает на глубину 4 и ненаблюдаемые дальнейшие переводы. Следующий шаг в обзоре — запросить исходящие переводы следующего колена. Нулевой выход не объявляется доказательством удержания средств.
  3. Найдите 100000000456947100: этот изолированный seed остаётся в очереди и графе с неизвестной ролью и приоритетом 0. Отсутствие узла или назначение ему роли получателя — расхождение с ожидаемым результатом.
  4. Скачайте «Все узлы и роли»: оба gid должны присутствовать в CSV. Для проверки границы и изолятов на всём наборе выполните python -m pytest tests/test_analysis.py::test_censored_nodes_seeds_isolates -q.

Для включённого внешнего AI формулировка может отличаться. Проверяются согласованность с числами и ограничениями досье и ссылки на факты; роль, приоритет и CSV от текста ответа не меняются.

Как получается результат

flowchart LR
    A["3 Parquet"] --> B["Валидация сумм и количества"]
    B --> C["Направленный граф и метрики"]
    C --> D["Правила ролей · Louvain и гипотезы групп · приоритет"]
    D --> E["Снимок анализа + manifest"]
    E --> F["3 CSV"]
    E --> G["FastAPI → React + Cytoscape"]
    G --> I["Перечень проверки аналитика"]
    E -. "минимальные факты без gid" .-> H["Опциональное AI-пояснение"]
    H -.-> G

Ядро — moneygraph/analysis.py, API — server.py, интерфейс — frontend/src. API и экспорты привязаны к одному analysis_id; сервер держит неизменяемый результат в памяти. Даже перезапись каталога out другим запуском не подменяет CSV открытого сервера.

  • Деньги суммируются в целых тиынах. Сумма и число операций каждой пары проверяются по edges.parquet.
  • Все узлы добавляются из nodes.parquet, включая изоляты. 97 совпадающих строк операций сохранены: без transaction ID нет основания удалять их как повторы.
  • Метрики: степени, суммы и количества, взвешенный PageRank, направленная невзвешенная betweenness, достижимость от других seed до четырёх переходов.
  • Louvain: ненаправленная проекция с суммой весов обоих направлений, seed=42, resolution=1; номера сообществ упорядочены по минимальному gid, изоляты получают отдельные сообщества. Оборот кластера включает только внутренние направленные рёбра, каждое один раз.
  • FIFO учитывает совместимый вход и последующий выход через 1–2 дня, без повторного использования объёма. Переводы одного дня не сопоставляются: порядок внутри дня неизвестен. Это совместимость, не доказанная трассировка денег.
  • gid остаётся целым десятичным идентификатором в CSV и строкой в API/браузере. При открытии CSV в Excel импортируйте этот столбец как текст: значения превышают точность чисел JavaScript и Excel.

Роли и поддержка гипотезы

Правила применяются сверху вниз. Пороги рассчитываются на входном наборе и записываются в manifest. P75 — квантиль положительных степеней; Q — средний процентиль среди активных узлов, при нулевой метрике 0.

РольУсловиеrole_score
unknownНет наблюдаемых связей0
coordinatorЕсть вход/выход; betweenness ≥ P90 положительных значений; соседи в ≥2 сообществах; достижим от ≥2 других seedСреднее Q посредничества и достижимости
consolidatorВходящая степень ≥ max(3, ceil(P75)) и ≥2 × исходящая; на границе достаточно подтверждённой входящей степениСреднее Q входящей степени и числа переводов; на границе максимум 0,5
distributorИсходящая степень ≥ max(10, ceil(P75)); для не-seed также ≥2 × входящаяСреднее Q исходящей степени и числа переводов
transitНе seed; глубина <4; есть вход и выход; отношение сумм 0,8–1,20,6 × min(вход, выход)/max + 0,4 × сопоставленный объём/max
terminalЕсть вход, нет наблюдаемого выхода, глубина <4Среднее Q входящей суммы и числа переводов
unknownГраница без достаточных признаков другой роли0
peripheralОстальные наблюдаемые узлы1 − max(Q степени, Q объёма, Q посредничества)

В этой выборке пороги степеней — 3 и 10. terminal в интерфейсе называется «Получатель»: даже внутри границы это наблюдаемая структура, а не подтверждение удержания денег. unknown — документированное расширение словаря, разрешённое ТЗ.

role_score — некалиброванная поддержка структурной гипотезы, не вероятность и не измеренная точность. В интерфейсе это баллы из 100, отдельно от приоритета; баллы разных ролей не сравниваются. Досье показывает наблюдаемые значения, условия выбранного правила, причины отклонения предыдущих правил и формулу поддержки. Правило peripheral — остаточное; у высокоактивного узла поддержка этой роли может быть низкой. Роль не исключает его из очереди.

Приоритет проверки

0,35 × Q(max(входящая сумма, исходящая сумма))
+ 0,25 × Q(betweenness)
+ 0,25 × Q(достижимость от других seed)
+ 0,15 × Q(число участий в переводах)

Изоляты имеют 0. Равные приоритеты после округления до 6 знаков упорядочиваются по gid. Коэффициенты — прозрачные начальные настройки без обучения на разметке. В досье и why в top-20 раскрываются четыре слагаемых с наблюдаемыми значениями и вкладом в балл. Человекочитаемое объяснение использует ту же формулу; локальный ассистент возвращает тот же why. role_score и priority_score независимы: отсутствие уверенной роли не означает низкий приоритет проверки.

Назначение группы

Начиная с алгоритма 1.1.0, каждое сообщество объясняется по внутренним направленным потокам, независимо от присвоенных узлам ролей. В 1.2.0 эти правила сохранены; расширена обработка периода и входная валидация. Стартовые пороги заданы явно, не обучены на разметке:

ГипотезаНаблюдаемое условие
Возможный сборУ узла ≥3 внутренних отправителей, их число ≥2 × числа внутренних получателей, вход ≥25% внутреннего оборота
Возможное распределениеЗеркальное правило: ≥3 получателей, ≥2 × числа отправителей, выход ≥25% оборота
Смешанная структураВ группе есть признаки и сбора, и распределения
Возможное промежуточное прохождениеЕсть не-seed вне границы с внутренними входом и выходом, min/max ≥0,8; сумма min по подходящим участникам ≥25% внутреннего оборота
Назначение не установленоНи один из предыдущих наборов признаков не подтверждён; указана конкретная причина

Проверяются смешанная структура, сбор, распределение, затем промежуточное прохождение. Переводы самому себе учитываются в обороте, но не подтверждают связь разных участников. Сумма min не является объёмом уникальных средств: одна последовательность переводов может учитываться у нескольких участников. Сходство сумм за период не доказывает передачу тех же денег.

В карточке доступны конкретные узлы, значения, правило и ограничения seed/четвёртого колена. Вход/выход через границу группы означает переводы между сообществами внутри предоставленного набора, а не данные других банков. hypothesis в CSV и API одинаков; схема clusters.csv сохранена. Правила ролей, состав кластеров и формула/порядок приоритета этой итерацией не меняются.

AI: пояснения и чат по выбранному клиенту

Обязательные результаты вычисляются локальными алгоритмами. Во вкладке «Ассистент» раскройте «Локальные пояснения · без API», чтобы прочитать три объяснения рассчитанных фактов без ключа и внешнего AI. Кнопки быстрых вопросов отправляют запросы OpenAI. Дополнительно доступен свободный чат с OpenAI по выбранному клиенту; ответ не меняет роли, приоритеты, граф или CSV и не выполняет автономных действий.

  1. Откройте «Ассистент». Если ключа нет, появится окно ввода OpenAI API key с пояснением передачи данных. Окно можно закрыть и продолжить с локальными объяснениями.
  2. Введите свой ключ. Статус «Ключ задан» означает только ввод; доступ проверяется при первом вопросе. Запросы выполняются напрямую из браузера в OpenAI Responses API с gpt-4.1-mini и store: false.
  3. Задайте вопрос. OpenAI получает текст вопроса, ограниченную историю диалога и агрегированные факты выбранного клиента. Автоматический контекст не включает исходный gid, операции или полный граф; сведения, введённые в вопрос вручную, передаются как часть текста.
  4. Удалите ключ через действие рядом со статусом. Это отменит текущий запрос и очистит чат. Перезагрузка страницы и смена набора также удаляют ключ и историю; смена клиента или уход со вкладки очищает диалог.

Ключ хранится только в памяти frontend: Tyuin не отправляет его на свой сервер и не записывает в браузерные хранилища. Для авторизации запроса ключ передаётся OpenAI. После перезагрузки его нужно ввести заново. store: false отключает сохранение ответа для последующего получения через API, но не обещает отсутствие всех журналов у провайдера; действуют правила обработки данных OpenAI.

Новый чат не требует серверных переменных LLM_*. Прежний POST /api/nodes/{gid}/explain оставлен для внешних API-клиентов: его необязательная конфигурация LLM_BASE_URL, LLM_MODEL, LLM_API_KEY описана в .env.example; файл .env автоматически не загружается. Интерфейс локальных объяснений этот endpoint не вызывает.

Живой запрос нового чата пока не проверен; доступ конкретного ключа, квоты и качество реальных ответов не подтверждены. Сценарии автоматической и браузерной проверки с имитацией OpenAI описаны в спецификации. Ответ AI необходимо сверять с числами и ограничениями досье.

Демонстрация на данных хакатона

Кейс «Граф денег» показывает применение Tyuin к предоставленной транзакционной сети. Все числа ниже относятся к этому набору, а не к гарантированным характеристикам любых данных.

Реальный результатЗначение
Клиенты / направленные связи / операции2 248 / 3 119 / 4 840
Изолированные seed сохранены19 из 19
Сообщества / приоритетные узлы88 / 20
Оборот без потери копеек365 890 012,01 KZT

Числа относятся к предоставленной выборке. При проверке алгоритма 1.2.0 получен снимок c138a62d811d6c39 с теми же объёмами; отчёт загрузки собственных данных. Сохранённые примеры в results/ относятся к историческому снимку 0a1216eed5476f02 (алгоритм 1.1.0) и сохранены без изменений. Время и условия прогонов указаны в результатах проверок.

Замер 1.1.0 на 22ec2b8: свежий процесс в существующем окружении macOS — 4,28 с, обработка с записью и проверкой — 3,23 с, пиковая память — 312,23 MiB. Установка исключена, файловый кэш ОС не очищался. Benchmark, контекст проверки.

Главное отличие — явный учёт границы наблюдения. Правило «есть вход, нет выхода → конечный получатель» отнесло бы к terminal все 444 узла четвёртого колена. Tyuin сохраняет 441 как unknown, ещё 3 получают частичную гипотезу консолидации с поддержкой не выше 0,5. Аналитик видит, где требуется запросить продолжение цепочки, вместо вывода об удержании денег по неполной выборке.

Доказательство: сравнение правил на исходном наборе, роли всех узлов и контрольный gid=100000000018102100 — глубина 4, наблюдаемый вход 7 000 KZT, роль «Не установлена». Это сравнение структурных правил, не измерение accuracy: эталонных ролей нет.

Требования кейса и проверка

Нумерация соответствует пяти обязательным пунктам ТЗ кейса; первичный источник — PDF организатора. Таблица показывает реализацию и способ проверки, а не оценку жюри или подтверждение допуска.

Требование ТЗРеализация и границаКак проверить
1. Один запуск от Parquet до трёх CSV менее чем за 5 минутrun рассчитывает и проверяет результаты без ручной разметки; измерения относятся к данному наборуpython -m moneygraph run --data data --out out; затем verify; полный замер — smoke и отчёт Windows
2. Роль, скор и объяснение каждого из 2 248 узловВсе узлы, включая 19 изолятов, входят в nodes_roles.csv; role_score — поддержка правилаCSV, verify; контракт полей проверяется в тестах
3. Документированные, объяснимые критерии ролейПравила и формулы, пороги в manifest, признаки в досьеНайти три произвольных gid и разобрать условия роли; автоматические тесты не заменяют устный разбор команды за минуту
4. Кластеры, состав, оборот и гипотеза назначения88 сообществ, cluster_id у каждого узла; гипотеза сбора, распределения, смешанной структуры, промежуточного прохождения либо обоснованная неопределённостьclusters.csv, вкладка «Группы», карточка с численными основаниями и порогами; гипотеза не является доказательством назначения
5. Не менее 20 приоритетных узлов с основаниями и направленный графTop-20 с полным why, включающим четыре компонента приоритета; граф показывает роли и сообществаtop_nodes.csv, поиск gid, выбор узла/ребра и переключение цвета графа

Что проверено

Среда и версияРеально выполненоДоказательство
Linux amd64, чистый контейнер python:3.12-slim-bookworm, Python 3.12.14, commit 6620aa1Команды README «macOS / Linux» на свежем клоне: venv, установка lock, pip check, preflight, demo, API, 3 CSV, Ctrl+C, verify для out и results, 89 тестов, smoke pass. Новый процесс run: 7,36 сПроверка на чистой машине
Docker, Linux amd64, свежий клон 78590c9 (код и конфигурация как в 6620aa1)Сборка --no-cache --pull, healthy, API, 3 CSV, verify, браузер, 89 тестов в образе без сетиПроверка на чистой машине
macOS arm64, Python 3.12.1, Node 25.8.1, загрузка данных 2269362127 Python-тестов, 39 frontend-тестов, build, импорт/ошибки/переключение/AI-контекст в браузере; свежий запуск CLI/API/CSV/assets — 4,641 с на b65fd8fПроверка загрузки собственных данных
macOS arm64, Python 3.12.1, Node 25.8.1, commit a91e3de89 backend-тестов, 8 тестов графа, build, браузерная проверка текущего frontend; свежий smoke CLI/API/CSV/assets и остановка сервера прошлиТекущая проверка и машинный отчёт
Windows 11 x64, Python 3.12.14, commit 60276af71 тест; preflight и pip check; CLI/API, 3 CSV, все assets, браузер, Ctrl+C и занятый порт. Новый процесс run: 6,7669 с; весь smoke: 20,1606 сОтчёт с SHA, командами и ограничениями
Windows 11 x64, Python 3.14.5, commit bb0c5d0Новый venv, установка lock, preflight, pip check, 14 тестов окружения. Полный smoke под 3.14 этим прогоном не подтверждёнОтчёт Python 3.14
macOS arm64, Python 3.12.1, исходная версия анализаНовый процесс: 27,0019 с, пиковая память 197,16 MiB; отдельный повтор 7,59 сИсходное измерение, повтор, контекст версии
Brev CPU VM, приложение 3c6b1cd, первоначальный облачный прогон 23.09.2026Сборка, 29 тестов, API и CSV с проверкой SHA-256, браузер, повторный запуск; затем HTTPS через Caddy, HTTP→HTTPS и сохранение сертификата при перезапускеОблачная проверка, HTTPS
Brev CPU VM, передеплой f4077ff, 23.09.2026127 тестов в новом образе, healthy, verify, публичные API и CSV, изолированный импорт, поиск и форма загрузки в браузереПередеплой и откат
Docker, Linux amd64, версия конфигурации BrevСборка, запуск, API, CSV, браузер, перезапуск и 29 тестов той версииОтчёт и проверенный commit

Измерения run включают новый Python-процесс, импорты, анализ, запись CSV и verify; установка исключена, кэш ОС не очищался. Это результаты отдельных машин, не сравнение производительности платформ. Память на Windows не измерялась. Таблица фиксирует конкретные исторические версии и объём каждого прогона. Новая веб-сборка требует отдельной проверки; прежние результаты не являются повторным запуском на новом commit. Проверка браузерного ассистента приведена в отчёте AI-интерфейса.

Техническая проверка Windows выполнена агентами. Повторение инструкции вторым участником и подтверждение локальной приёмки остаются открыты по спецификации. Реальный CPU-инстанс Brev, SSH-доступ и собственный HTTPS-домен проверены 23.09.2026: отчёт облачного запуска, проверка HTTPS. Живой внешний LLM этими прогонами не проверялся.

Данные, технологии и разработка

Три исходных Parquet предоставлены для этого кейса; SHA-256 зафиксированы в manifest. Данные обезличены и предназначены исключительно для хакатона. Никакого внешнего обогащения или вымышленных атрибутов нет. ТЗ и исходное описание.

Python-среды и объём их проверки перечислены выше. Зависимости: FastAPI 0.141.1, pandas 2.3.3, PyArrow 24.0.0, NumPy 2.5.3, NetworkX 3.7. Полный Python-набор — requirements.lock, frontend — frontend/package-lock.json. React + TypeScript + Vite + Cytoscape; системные шрифты и локальные ассеты, без CDN.

Изменение интерфейса (Node 22.12+; фактически проверен Node 25.8.1):

cd frontend
npm ci
npm run dev
# в другом терминале запускается Python demo на 8765;
# Vite выводит адрес разработки и перенаправляет /api на backend
npm run format:check
npm test
npm run build

Сборка сохраняется в moneygraph/web/ и коммитится вместе с исходниками. Рабочие изменения выполняются в отдельной ветке каждой задачи → локальная проверка → PR в main. Постоянной ветки dev нет. Слияние требует подтверждения локальной приёмки; правила.

Ограничения и следующий масштаб

Исходный кейс — внутрибанковские переводы за июль 2026. Собственный набор загружается из трёх Parquet с той же схемой и семантикой: KZT, операции от 5 000 ₸, seed на глубине 0 и исходящий обход до четвёртого колена. Период определяется из операций и может быть любым в пределах 366 календарных дней включительно; граница наблюдения по-прежнему фиксирована на глубине 4. Произвольные таблицы, сопоставление колонок, Excel/CSV и другие валюты не поддерживаются. Внешние входы, остатки и продолжение границы неизвестны. Нет эталонных ролей, поэтому accuracy, recall и доказанная эффективность расследования не заявляются. Сообщества не равны преступным группам; все назначения — гипотезы.

Сейчас реализованы загрузка собственных данных в поддерживаемом формате, динамический период, роли, кластеры, приоритет, временная совместимость, досье, фильтры и объяснения; дополнительный AI-чат работает с фактами выбранного клиента. Отдельные детекторы циклов, дробления и стресс-тест удаления top-N отложены. Интерфейс предназначен прежде всего для ноутбука; на узком экране панели идут вертикально.

Гипотезы назначения групп следуют из документированных начальных правил и не проверены на размеченных примерах. Полные основания всех четырёх факторов включены в why. Спецификация гипотез, спецификация объяснений приоритета.

Следующий шаг применения: другие валюты и настраиваемая глубина наблюдения, адаптеры новых источников, постоянная история и полноценное разграничение доступа, проверка правил на размеченных примерах. Работа с небольшими собственными наборами проверена; производительность на максимальных лимитах импорта и качество гипотез на новых наборах ещё не измерены.

При росте до миллиона узлов: агрегировать Parquet пакетами через DuckDB/Polars; заменить Python-объекты компактным графом и вынести расчёт в отдельный процесс; считать приближённую betweenness на выборке и ограниченные локальные признаки; использовать Leiden/Louvain в igraph; хранить снимки и индексировать gid; выдавать в браузер только окружение, серверные фильтры и агрегаты. Сохранить версионирование правил и контроль сумм. Проверять время, память, стабильность top и роль границы на отдельном нагрузочном наборе. Такой масштаб не реализован и не измерен.

Архитектурный план · Фактическая реализация · Проверка по критериям.

Документация проекта · Agentic SDD pipeline: план разработки через Codex и Claude Code.

Бренд, логотип и исходные скетчи · Проверка ребрендинга.

Решение создано командой uniqore.ai на хакатоне hackalem.ai 23.09.2026.

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

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

rbaranov 55Ivan Antonov 16Ivan Antonov 8

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

  • 2026-09-23 17:58Merge pull request #25 from BAITC-Hacks/fix/mobile-headerrbaranov
  • 2026-09-23 17:57docs: record header and footer acceptanceR
  • 2026-09-23 17:57fix: place team credit in the footer status rowR
  • 2026-09-23 17:57Merge remote-tracking branch 'origin/main' into fix/mobile-headerR
  • 2026-09-23 17:55fix: group mobile header tools with consistent spacingR
  • 2026-09-23 17:54docs: record Brev redeploy of f4077ff and verified rollback path (#26)Ivan Antonov
  • 2026-09-23 17:52fix: align mobile header actionsR
  • 2026-09-23 17:41Merge pull request #24 from BAITC-Hacks/docs/tyuin-readme-and-creditrbaranov
Все коммиты (79)
  • 2026-09-23 17:40docs: refresh README screenshot with hidden financial connections titleR
  • 2026-09-23 17:35Merge latest main and rename product caption to hidden financial connectionsR
  • 2026-09-23 17:33docs: present Tyuin as a product with complete deployment guideR
  • 2026-09-23 17:31Merge pull request #23 from BAITC-Hacks/feat/custom-data-uploadrbaranov
  • 2026-09-23 17:30docs: record accepted custom import and sync main publication notesR
  • 2026-09-23 17:25docs: record custom import validation and AI reset behaviorR
  • 2026-09-23 17:22feat: import isolated custom Parquet datasets from workbenchR
  • 2026-09-23 17:21feat: publish Brev demo on custom HTTPS domain (#22)Ivan Antonov
  • 2026-09-23 17:17Merge pull request #21 from BAITC-Hacks/feat/openai-browser-assistantrbaranov
  • 2026-09-23 17:16docs: record local acceptance of OpenAI assistantR
  • 2026-09-23 17:16docs: record clean-machine check in Docker and Linux (#20)Ivan Antonov
  • 2026-09-23 17:10feat: connect assistant to OpenAI with ephemeral browser keyR
  • 2026-09-23 17:05docs: let README launch steps use any supported Python (#19)Ivan Antonov
  • 2026-09-23 16:53Merge pull request #18 from BAITC-Hacks/feat/finance-demo-scenariorbaranov
  • 2026-09-23 16:53docs: record local acceptance of finance demo UXR
  • 2026-09-23 16:48docs: record verified integration and local smoke evidenceR
  • 2026-09-23 16:47fix: distinguish closed TCP connections in local smoke cleanupR
  • 2026-09-23 16:43Merge main preserving demo UX and local runtime checksR
  • 2026-09-23 16:41docs: save live demo script and verify client filter workflowR
  • 2026-09-23 16:38feat: highlight graph selections and unify client review filtersR
  • 2026-09-23 16:30Merge pull request #17 from BAITC-Hacks/codex/local-launch-runtimeIvan Antonov
  • 2026-09-23 16:27docs: connect README claims to reproducible evidenceIvan Antonov
  • 2026-09-23 16:14Merge main preserving demo workflow and Brev deployment documentationR
  • 2026-09-23 16:13docs: record finance demo workflow and local verificationR
  • 2026-09-23 16:07feat: implement finance demo investigation workflowR
  • 2026-09-23 16:04merge: retain Brev deployment and local launch documentationIvan Antonov
  • 2026-09-23 15:59Merge pull request #16 from BAITC-Hacks/codex/brev-deployIvan Antonov
  • 2026-09-23 15:57Merge main into codex/brev-deploy preserving Windows and Docker run guidesIvan Antonov
  • 2026-09-23 15:55merge: preserve current main Windows support and launch checksIvan Antonov
  • 2026-09-23 15:50Merge pull request #14 from BAITC-Hacks/fix/windows-reproducibilityIvan Antonov
  • 2026-09-23 15:43Merge pull request #15 from BAITC-Hacks/docs/demo-ux-priorityrbaranov
  • 2026-09-23 15:42Merge commit '1d70aec152482031cbdddfc189981020466dbd5d' into codex/local-launch-runtimeIvan Antonov
  • 2026-09-23 15:41feat: add isolated local launch smoke verificationIvan Antonov
  • 2026-09-23 15:39docs: prioritize case demo UX and require merged branch cleanupR
  • 2026-09-23 15:36Merge pull request #10 from BAITC-Hacks/docs/additional-roles-backlogrbaranov
  • 2026-09-23 15:35docs: explain additional roles and sync backlog with mainR
  • 2026-09-23 15:35Merge pull request #11 from BAITC-Hacks/docs/finance-case-audit-backlogrbaranov
  • 2026-09-23 15:34docs: normalize audit spec endingsR
  • 2026-09-23 15:34Merge remote-tracking branch 'origin/main' into docs/finance-case-audit-backlogR
  • 2026-09-23 15:33fix: preserve canonical output bytes and validate launch portsIvan Antonov
  • 2026-09-23 15:33Merge branch 'codex/local-launch-docs' into codex/local-launch-runtimeIvan Antonov
  • 2026-09-23 15:32docs: document isolated PowerShell launch and acceptanceIvan Antonov
  • 2026-09-23 15:32Merge pull request #13 from BAITC-Hacks/docs/backlog-analysis-queuerbaranov
  • 2026-09-23 15:32docs: record Brev deployment checks against latest mainIvan Antonov
  • 2026-09-23 15:28feat: add Docker deployment configuration for NVIDIA BrevIvan Antonov
  • 2026-09-23 15:28fix: make README verification reproducible on WindowsIvan Antonov
  • 2026-09-23 15:26feat: add reproducible Windows runtime preflightIvan Antonov
  • 2026-09-23 15:17docs: add investigation priority workflow and optional LLM chatR
  • 2026-09-23 15:17Merge pull request #12 from BAITC-Hacks/feat/finance-ux-workspacerbaranov
  • 2026-09-23 15:16Merge main Tyuin branding and record UX acceptanceR
  • 2026-09-23 15:11Merge pull request #5 from BAITC-Hacks/feat/tyuin-brandrbaranov
  • 2026-09-23 15:10Merge main backlog docs and record Tyuin acceptanceR
  • 2026-09-23 15:07feat: simplify investigation workspace and explain role hypothesesR
  • 2026-09-23 15:06fix: add breathing room to Tyuin horizontal logoR
  • 2026-09-23 15:06docs: add finance case audit findings to backlogR
  • 2026-09-23 15:05docs: add backlog task for justified additional rolesR
  • 2026-09-23 15:01Merge pull request #6 from BAITC-Hacks/docs/backlog-trackingrbaranov
  • 2026-09-23 14:58fix: center Tyuin wordmark in horizontal logoR
  • 2026-09-23 14:57docs: add custom data upload to backlogR
  • 2026-09-23 14:55docs: add prioritized backlog and completed task historyR
  • 2026-09-23 14:50feat: rebrand finance workbench as TyuinR
  • 2026-09-23 14:39Merge pull request #4 from BAITC-Hacks/feat/finance-workbenchrbaranov
  • 2026-09-23 14:37Merge main documentation and preserve both project entry pointsR
  • 2026-09-23 14:35feat: implement local finance graph investigation workbenchR
  • 2026-09-23 14:22Merge pull request #3 from BAITC-Hacks/agentic-sdd-pipelineIvan Antonov
  • 2026-09-23 14:19Merge main and preserve both documentation entry pointsIvan Antonov
  • 2026-09-23 14:14docs: complete SDD reviews and add bootstrap guideIvan Antonov
  • 2026-09-23 13:58docs: plan agentic SDD workflow for Codex and Claude CodeIvan Antonov
  • 2026-09-23 13:57Merge verified finance documentation from devrbaranov
  • 2026-09-23 13:56Merge finance documentation into devrbaranov
  • 2026-09-23 13:54docs: add finance case specification and architecture planR
Структура репозитория (174 файлов)
.dockerignore
.env.example
.gitattributes
.gitignore
.python-version
AGENTS.md
Dockerfile
README.md
data/README.md
data/edges.parquet
data/nodes.parquet
data/transactions.parquet
deploy/brev/caddy/Caddyfile
deploy/brev/docker-compose.yml
deploy/brev/domain-web.compose.yml
deploy/brev/public-web.compose.yml
docker-compose.yml
docs/README.md
docs/agentic-sdd-pipeline/README.md
docs/agentic-sdd-pipeline/acceptance.md
docs/agentic-sdd-pipeline/contracts.md
docs/agentic-sdd-pipeline/examples.md
docs/agentic-sdd-pipeline/implementation-plan.md
docs/agentic-sdd-pipeline/process-spec.md
docs/agentic-sdd-pipeline/prompts.md
docs/agentic-sdd-pipeline/quickstart.md
docs/agentic-sdd-pipeline/review.md
docs/agentic-sdd-pipeline/templates/evidence.json
docs/agentic-sdd-pipeline/templates/inputs.json
docs/agentic-sdd-pipeline/templates/review.json
docs/agentic-sdd-pipeline/templates/run.json
docs/agentic-sdd-pipeline/templates/spec.md
docs/agentic-sdd-pipeline/templates/task.json
docs/backlog.md
docs/brand/README.md
docs/brand/tyuin/v1.0.0/README.md
docs/brand/tyuin/v1.0.0/SHA256SUMS
docs/brand/tyuin/v1.0.0/assets/tyuin-icon.png
docs/brand/tyuin/v1.0.0/assets/tyuin-logo.png
docs/brand/tyuin/v1.0.0/design-brief.md
docs/brand/tyuin/v1.0.0/originals/01-knot-logo-concept.png
docs/brand/tyuin/v1.0.0/originals/02-inspector-sketch.png
docs/brand/tyuin/v1.0.0/originals/03-lynx-sketch-selected.png
docs/brand/tyuin/v1.0.0/originals/04-raven-sketch.png
docs/brand/tyuin/v1.0.0/originals/05-knot-detective-sketch.png
docs/brand/tyuin/v1.0.0/originals/06-lynx-logo-approved.png
docs/brand/tyuin/v1.0.0/originals/07-lynx-icon-derived.png
docs/brand/tyuin/v1.0.0/previews/mobile-390.png
docs/brand/tyuin/v1.0.0/previews/workbench.png
docs/brand/tyuin/v1.0.0/validation.md
docs/brand/tyuin/v1.0.1/README.md
docs/brand/tyuin/v1.0.1/SHA256SUMS
docs/brand/tyuin/v1.0.1/assets/tyuin-logo.png
docs/brand/tyuin/v1.0.1/originals/01-horizontal-alignment.png
docs/brand/tyuin/v1.0.1/previews/mobile-390.png
docs/brand/tyuin/v1.0.1/previews/workbench.png
docs/brand/tyuin/v1.0.1/validation.md
docs/brand/tyuin/v1.0.2/README.md
docs/brand/tyuin/v1.0.2/SHA256SUMS
docs/brand/tyuin/v1.0.2/assets/tyuin-logo.png
docs/brand/tyuin/v1.0.2/originals/01-horizontal-spacing.png
docs/brand/tyuin/v1.0.2/previews/mobile-390.png
docs/brand/tyuin/v1.0.2/previews/workbench.png
docs/brand/tyuin/v1.0.2/validation.md
docs/clean-machine-check.md
docs/deployment/brev-redeploy-f4077ff.md
docs/deployment/brev.md
docs/development-workflow.md
docs/done.md
docs/finance/README.md
docs/finance/architecture.md
docs/finance/custom-upload-validation.md
docs/finance/demo-filter-validation.md
docs/finance/demo-ux-validation.md
docs/finance/demo.md
docs/finance/evidence/custom-upload-smoke.json
docs/finance/evidence/demo-filter-smoke.json
docs/finance/implementation.md
docs/finance/mobile-header-validation.md
docs/finance/openai-assistant-validation.md
docs/finance/requirements.md
docs/finance/screenshots/brev-redeploy-f4077ff.png
docs/finance/screenshots/custom-upload-390.png
docs/finance/screenshots/custom-upload-result.png
docs/finance/screenshots/demo-client-filters-1280.png
docs/finance/screenshots/demo-filter-highlight-1280.png
docs/finance/screenshots/demo-review-filter-1280.png
docs/finance/screenshots/demo-review-filter-390.png
docs/finance/screenshots/demo-scenario-1280.png
docs/finance/screenshots/demo-scenario-cluster-1280.png
docs/finance/screenshots/demo-scenario-mobile-390.png
docs/finance/screenshots/desktop-1920.png
docs/finance/screenshots/laptop-1366.png
docs/finance/screenshots/readme-hidden-financial-connections-1280.jpg
docs/finance/screenshots/ux-help-mobile.png
docs/finance/screenshots/ux-tyuin-help-mobile.png
docs/finance/screenshots/ux-tyuin-workbench-1280.png
docs/finance/screenshots/ux-workbench-1280.png
docs/finance/screenshots/ux-workbench-1440.png
docs/finance/screenshots/workbench.png
docs/finance/sources/SHA256SUMS
docs/finance/sources/case.pdf
docs/finance/sources/data-description.md
docs/finance/ux-validation.md
docs/finance/validation.md
docs/local-launch.md
docs/specs/additional-roles.md
docs/specs/brev-deploy.md
docs/specs/cluster-purpose-hypotheses.md
docs/specs/custom-data-upload.md
docs/specs/finance-demo-rehearsal.md
docs/specs/finance-workspace-ux.md
docs/specs/local-launch.md
docs/specs/openai-browser-assistant.md
docs/specs/priority-explanations.md
docs/specs/product-readme-and-credit.md
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/public/tyuin-icon.png
frontend/public/tyuin-logo.png
frontend/src/App.tsx
frontend/src/Assistant.tsx
frontend/src/ClientRow.tsx
frontend/src/DatasetUpload.tsx
frontend/src/Graph.tsx
frontend/src/RoleExplanation.tsx
frontend/src/ScenarioPanels.tsx
frontend/src/dataset.ts
frontend/src/dateRange.ts
frontend/src/graphScope.ts
frontend/src/main.tsx
frontend/src/openaiAssistant.ts
frontend/src/style.css
frontend/src/types.ts
frontend/tests/assistant-browser-harness.mjs
frontend/tests/dataset.test.mjs
frontend/tests/graph-scope.test.mjs
frontend/tests/openai-assistant.test.mjs
frontend/tsconfig.json
frontend/vite.config.ts
moneygraph/__init__.py
moneygraph/__main__.py
moneygraph/analysis.py
moneygraph/clusters.py
moneygraph/datasets.py
moneygraph/server.py
moneygraph/web/assets/graph-BB4DxJjf.js
moneygraph/web/assets/index-D-MRXflO.js
moneygraph/web/assets/index-DyoOpy-2.css
moneygraph/web/index.html
moneygraph/web/tyuin-icon.png
moneygraph/web/tyuin-logo.png
pyproject.toml
requirements.lock
results/README.md
results/benchmark.json
results/clusters.csv
results/demo-scenario-benchmark.json
results/manifest.json
results/nodes_roles.csv
results/repeat-benchmark.json
results/top_nodes.csv
scripts/benchmark.py
scripts/check_environment.py
scripts/smoke_local_launch.py
tests/conftest.py
tests/test_analysis.py
tests/test_api.py
tests/test_custom_analysis.py
tests/test_environment.py
tests/test_local_launch.py
tests/test_smoke_runner.py
tests/test_upload_api.py

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

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

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