AAYMA
RU
Войти

Neverlose

Локальное рабочее место AML-аналитика: из трёх parquet строит направленный граф переводов, очередь приоритетной проверки, гипотезы шести ролей…

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

О проекте

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

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

Суть

Локальное рабочее место AML-аналитика: из трёх parquet строит направленный граф переводов, очередь приоритетной проверки, гипотезы шести ролей участников и три обязательных CSV (nodes_roles, clusters, top_nodes).

Как устроено

nodes/edges/transactions.parquet проверяются по схемам, деньги считаются в целых тиынах. NetworkX/SciPy строят направленный граф, считают PageRank, betweenness и seed-достижимость, выделяют сообщества Louvain. Роли и priority score задаются опубликованными правилами в config/rules.json. Для каждого узла показываются «Основания» и «Альтернатива» со ссылками на исходные переводы. FastAPI отдаёт snapshot в React/Cytoscape-интерфейс. Опциональный AI-аналитик на OpenAI Responses API выбирает инструменты и опирается только на проверенные основания; основной расчёт от модели не зависит.

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

  • NetworkX
  • PageRank
  • betweenness centrality
  • Louvain
  • seed reachability
  • rule-based role scoring
  • structural removal simulation
  • OpenAI tool selection

Особенности

Сильная объяснимость: у каждой роли есть условия правила, альтернативная гипотеза и ссылки на исходные строки transactions.parquet, а score прямо назван эвристикой, а не вероятностью вины. Режим --verify-only сверяет результат с хешами исходных данных, CSV из браузера, API и файлов совпадают побайтово. Всё работает офлайн без ключа и GPU, есть симуляция удаления узлов из структуры. Воспроизводимость подтверждена на втором ноутбуке.

Стек

Python 3.12 · pandas · NumPy · PyArrow · NetworkX · SciPy · FastAPI · Pydantic · Uvicorn · React 19 · TypeScript · Vite · Cytoscape.js · pytest · Vitest · Playwright

Модели

OpenAI Responses API


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

README

README.md
banner

Neverlose · Граф денег

Кого из 2 248 участников финансовой сети проверить первым — и почему?

Neverlose — локальное рабочее место AML-аналитика для кейса Finance / Freedom, HackAlem AI 2026. Приложение превращает три исходных parquet в очередь проверки, направленный граф, гипотезы шести ролей и три обязательных CSV. Аналитик может оспорить каждую гипотезу: открыть исходные переводы, сравнить альтернативу и увидеть, каких данных не хватает. Роли не устанавливают виновность, score не является вероятностью преступления.

Настоящий интерфейс Neverlose: очередь проверки слева, направленный граф в центре, карточка с основаниями справа

Скриншот реального расчёта: легенда ролей и кнопка AI-аналитика справа снизу. Слева — кого проверить; в центре — связи; справа — почему выбран узел. Суммы ведут к исходным переводам. Поиск принимает любой полный gid, включая изолированный seed. Полезный результат работы — объяснимый приоритет, исходные основания и следующий запрос данных, а не только изображение графа.

Для жюри: быстрый старт → проверка за пять минут → технологии → алгоритмы → проверенная версия.

Основной сценарий работает локально после установки: без ключа, платного API, GPU и Node.js. Готовая сборка интерфейса включена в репозиторий; Node нужен только разработчику для её пересборки и тестов. Необязательный AI-аналитик включается отдельно.

Быстрый старт

Официальный приватный репозиторий: BAITC-Hacks/hack-1eeed6ff-s-ztech. Для получения исходников нужен предоставленный организатором доступ; работа приложения не требует аккаунта участника.

git clone https://github.com/BAITC-Hacks/hack-1eeed6ff-s-ztech.git
cd hack-1eeed6ff-s-ztech
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.lock
python -m pip check
python run.py

Откройте http://127.0.0.1:8000 и нажмите «Открыть платформу». В рабочем окне: 2 248 узлов, 3 119 связей, 4 840 переводов. В терминале — status=ready, run_id и время пересчёта; в results/ — три CSV. Остановка — Ctrl+C. Если порт занят: python run.py --port 8001, затем откройте порт 8001.

Предварительно нужны установленный Python 3.12, Git и доступ организатора к приватному репозиторию. Интернет нужен для получения исходников и зависимостей; после установки основной сценарий автономен. .env создавать не нужно. Команды выше предназначены для macOS/Linux shell; проверенные платформы и Windows-вариант указаны ниже.

При настроенном SSH вместо HTTPS можно получить тот же репозиторий командой git clone [email protected]:BAITC-Hacks/hack-1eeed6ff-s-ztech.git. SSH-вариант проверен Алишером. Аккаунт или ключ не передаётся приложению.

Системные требования

Проверено: Python 3.12.14, macOS 26.6.2 arm64, Apple M4, 16 GiB RAM. Для обычного запуска нужны Python 3.12, зависимости из lock, исходные parquet, свободный локальный порт. Второй clean/offline запуск: Apple M2, 8 CPU, 8 GiB, macOS 27.0 arm64, Python 3.12.14. Точный целевой профиль 4 CPU / 8 GB RAM отдельно не измерен. Windows/Linux отдельно не проверены. На Windows эквивалент: py -3.12 -m venv .venv, затем .venv\Scripts\python.exe -m pip install -r requirements.lock; использовать этот интерпретатор для всех команд без активации.

Python-зависимости: pandas 2.2.3, NumPy 2.3.5, PyArrow 25.0.1, NetworkX 3.7, SciPy 1.18.1, FastAPI 0.141.1, Pydantic 2.13.5, Uvicorn 0.53.0. Транзитивные зависимости зафиксированы в requirements.lock. При запуске пакеты не устанавливаются автоматически.

Запуск и остановка

Обычный запуск из корня с активированным окружением:

python run.py

Он проверяет raw, пересчитывает результат, сохраняет CSV/snapshot и обслуживает web/dist тем же процессом. Откройте http://127.0.0.1:8000. Проверка готовности — /health, метаданные — /api/v1/meta; остановка — Ctrl+C.

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

В отдельном терминале с тем же активным окружением проверьте созданные файлы:

python run.py --verify-only

Ожидается JSON с status: "valid", nodes: 2248, clusters: 89, top_nodes: 50. run_id должен совпасть с сервером. Проверка сопоставляет результат с исходными данными; роли и суммы не подменяются примером.

Дополнительные режимы для разработки и автоматической проверки:

# Только raw → CSV, без сервера
python run.py --pipeline-only
# Только API, без интерфейса
python run.py --api-only --port 8001
# Отдельный каталог результата
python run.py --pipeline-only --data data --out work/check-results

В --api-only корневая страница сообщает об отсутствии подключённого UI; для просмотра графа используйте обычный запуск.

Все параметры:

ПараметрЗначение по умолчаниюНазначение
--datadata рядом с run.pyТри исходных parquet
--outresults рядом с run.pyОтдельный каталог результата
--rulesconfig/rules.jsonОпубликованные формулы и пороги
--assistantвыключенВключить OpenAI-аналитика на сервере; нужен локальный ключ
--askнетВопрос аналитику в CLI; вывод одного JSON, progress в stderr
--gidнетНеобязательный точный gid для --ask
--profileofficialПроверка точных hashes организатора; generic допускает иные графы с теми же схемой, периодом и порогом
--host127.0.0.1Только loopback: 127.0.0.1, localhost или ::1
--port8000Свободный порт 1…65535
--pipeline-onlyвыключенПересчёт и завершение
--verify-onlyвыключенПроверка существующего результата, raw/config/hashes; центральности не пересчитываются
--api-onlyвыключенРазработка API без web/dist

--pipeline-only, --verify-only, --api-only и --ask взаимоисключающие. Для основного сценария переменные окружения, .env, API-ключи, платные сервисы, GPU и внешняя модель не требуются. Каталог вывода не может перекрывать raw или содержать посторонние файлы.

Проверка за пять минут

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

ДействиеОжидаемый результат
Сверьте шапку с /api/v1/meta2248 узлов, 3119 связей, 4840 переводов; июль 2026; один run_id
Найдите 100000008346837100Гипотеза «Консолидация», кластер 13. Вход 254359.00 KZT, выход 1258643.00 KZT; это наблюдаемые потоки, не полный баланс
Откройте «Основания», затем «Альтернатива»Условия правила и альтернативная гипотеза распределения; score обозначен как эвристика
Нажмите сумму входа/выходаИсходные переводы соответствующего направления; у строк есть source_ref и позиция в transactions.parquet. Итог относится ко всей выборке, а не странице
Найдите 100000001053894100Предупреждение «Граница выборки», роль peripheral; отсутствие выхода не объявляется накоплением денег
Найдите 100000000456947100Изолированный seed: 1 узел / 0 связей, роль peripheral, role_score и priority_score равны 0; карточка непустая
Выберите три разных произвольных gid из raw командой нижеДля каждого откройте карточку, условия роли, приоритет и связи; поиск работает независимо от фильтров очереди, точные цифры сохраняются
Откройте кластер, затем «На главный экран»Статистика кластера и возврат к обзору; поиск/фильтры очищены
По очереди скачайте три CSV2248/89/50 строк данных соответственно, схемы перечислены ниже; gid импортируйте в Excel как текст
Выполните python run.py --verify-onlyvalid, те же counts и run_id; после установки повторите маршрут без внешней сети

Три разных произвольных gid непосредственно из исходного файла. Для каждого проверьте, что роль объясняется метриками и порогами в «Основаниях», а вывод учитывает ограничения данных. По ТЗ жюри выбирает три gid, и команда за минуту объясняет их роли; команда ниже помогает подготовить такой разбор:

python -c 'import random, pyarrow.parquet as pq; print(*random.SystemRandom().sample(pq.read_table("data/nodes.parquet", columns=["gid"]).column("gid").to_pylist(), 3), sep="\n")'

Автоматические проверки подтверждают также побайтовое равенство CSV из браузера, API и файлов расчёта. Сценарий выступления отделён от самостоятельной проверки жюри.

Технологии и их назначение

ТехнологияЗачем используется
Python 3.12, PyArrow, pandas, NumPyЧтение parquet, проверка схем и исходных агрегатов; расчёт денег в целых тиынах
NetworkX, SciPyНаправленный граф, PageRank/betweenness, seed-достижимость, Louvain и структурная симуляция
FastAPI, Pydantic, UvicornТипизированный локальный API и раздача интерфейса из одного snapshot
React 19, TypeScript, ViteИнтерфейс, проверка контрактов и воспроизводимая сборка
Cytoscape.jsНаправленный граф, выбор узла, масштабирование и доступная таблица связей
pytest, Vitest, PlaywrightИнварианты данных, отказы, unit и настоящий browser/API/CSV сценарий
OpenAI Responses API — опциональноВыбор инструментов и проверенных оснований для ответа; основной расчёт от модели не зависит

Точные версии: requirements.lock, requirements-dev.lock, web/package-lock.json. Происхождение и лицензии: THIRD_PARTY.md, тексты notices готового bundle.

Интерфейс и сборка

Готовый интерфейс включён в репозиторий: для обычного запуска Node и пересборка не нужны. Для разработки доступны контракт API, синтетический пример для тестов и настоящий ответ API. Синтетические данные не подставляются при ошибке рабочего API.

Для пересборки нужен Node >=22.12 и npm. Полный цикл ниже проверен с Node 24.19.0; дополнительные результаты и ограничения окружений приведены в отчёте проверок.

cd web
npm ci
npm test -- --run
npm run build
npx playwright install chromium
npm run test:e2e
# При работающем python run.py на localhost:8000:
npm run test:integration

Не заменять npm ci обновлением до latest. Contract E2E используют явно synthetic HTTP-ответы; integration тесты обращаются к настоящему серверу и сверяют скачанные CSV с API и файлами. При другом порте задайте NEVERLOSE_BASE_URL=http://127.0.0.1:8001; при другом каталоге результатов — NEVERLOSE_RESULTS=/полный/путь/к/results. Это настройки тестов, не обязательные переменные приложения. Фактические проверки — в validation.

Данные и результаты

ФайлСтрокПоля
data/nodes.parquet2 248gid:int64, depth:int64, is_seed:bool
data/edges.parquet3 119src:int64, dst:int64, sum_kzt:float64, n_tx:int64, depth:int8
data/transactions.parquet4 840src:int64, dst:int64, date:day, sum_kzt:float64

81 seed, июль 2026, порог 5 000 KZT, только внутрибанковские исходящие пути до четырёх колен. Сумма наблюдаемых переводов 365 890 012,01 KZT — не объём уникальных денег. Hashes/схемы: официальный manifest, выполненный loader audit.

97 повторяющихся транзакций сохраняются: банковского ID нет, исходные агрегаты учитывают все строки. 19 изолированных seed остаются в графе, отдельных кластерах и выгрузках. Всего 35 слабых компонент со всеми узлами.

results/nodes_roles.csv  gid,role,role_score,cluster_id,priority_score,evidence
results/clusters.csv     cluster_id,n_nodes,n_seed,sum_kzt_internal,top_gids,hypothesis
results/top_nodes.csv    rank,gid,role,priority_score,why
results/snapshot.json    Полные признаки, правила, переводы, ограничения, config и run_id
results/manifest.json    Hashes входов/выходов, версии, размеры и длительность

CSV — UTF-8, точные десятичные gid, score с 6 знаками. Evidence непустой и не длиннее 200 Unicode-символов. top_gids в CSV разделены ;, в JSON это массив строк. Все исходные узлы присутствуют ровно один раз. Топ — первые min(50,N); на официальных данных 50. Ранжирование использует полный score до округления и затем меньший gid.

Фактический первый расчёт: 89 кластеров; consolidator 113, distributor 102, coordinator 8, transit 63, peripheral 884, terminal 1078. Это результат опубликованных эвристик v1, а не разметка истинных ролей.

Алгоритмы и объяснимость

Версия вычислительного кода 1.0.2: поле why объясняет приоритет через число плательщиков/получателей и наблюдаемые суммы. Роли, скоры, порядок приоритетов и кластеры сохранены; изменился текст top_nodes.csv и идентификатор расчёта. Подробные формулы: 02_DATA_ALGORITHMS.md. Действующие параметры: config/rules.json, версия v1.

Деньги проверяются на точность до тиына: abs(100*x-round(100*x))<=1e-6. Масштабирование целых (включая точно целые float) выполняется без промежуточного float; дробные исходные значения проверяются через Decimal. После проверки все суммы агрегируются целыми Python int. Пары/число операций/суммы tx сверяются с edges; допустимое различие до 1 тиына фиксируется, каноническая сумма берётся из tx. Неизвестный endpoint, null, inf, self-loop, неверный период, тип или точность останавливают расчёт.

Граф включает все nodes. PageRank: alpha=.85, tol=1e-8, max_iter=500, денежный вес. Betweenness: directed, normalized, без весов расстояния, выборка k=min(128,N), seed=42. Seed-reach — число разных seed с направленным путём длиной 1…4, исключая сам seed. Louvain: неориентированная проекция со суммой обоих направлений, resolution=1, threshold=1e-7, seed=42. Несвязные части сообществ разделяются; изоляты — singleton. ID кластеров: размер desc, минимальный gid asc.

Обозначения: I/O — наблюдаемый вход/выход, a/b — число разных отправителей/получателей, s — seed-reach, r=O/I при I>0, C — разнообразие кластеров соседей по обороту, B — betweenness. P(x) — ранг среди положительных значений, ties включаются полностью, для нуля P=0. clip ограничивает 0…1.

РольУсловиеRaw score
consolidatora≥3.45·clip(a/8)+.25·P(I)+.30·clip(s/3)
distributorb≥5.60·clip(b/20)+.40·P(O)
transitне seed/boundary, a,b≥1, I>0, .8≤r≤1.2.60·clip(1−abs(1−r)/.2)+.20·clip(min(a,b)/3)+.20·P(min(I,O))
terminalне seed, depth<4, a≥1, b=0, I>0.50+.25·P(I)+.25·clip(a/3)
coordinatordepth<4, a,b≥2, s≥2, C≥.30, P(B)≥.90.35·P(B)+.25·C+.20·clip(s/5)+.20·P(PageRank)
peripheralнет допустимого кандидата / изолят.20 / 0

Выбор по наибольшему raw score. Ties: coordinator → consolidator → distributor → transit → terminal. Затем применяются caps: coordinator .55; terminal/boundary/seed .65; одна операция или меньше .45. Это консервативные соглашения, не статистическая калибровка. Все кандидаты, условия pass/fail, raw/capped score и действующие caps доступны в карточке API. Альтернатива — следующая допустимая роль, иначе null с объяснением недостаточности данных.

Приоритет: .30·P(I+O)+.25·P(B)+.20·clip(s/5)+.15·max(P(a),P(b))+.10·C. Для изолята ноль. Пять вкладов публикуются отдельно; сумма сверяется с итогом до 1e-12. Seed не даёт прямого бонуса, низкий role_score не скрывает важный узел.

Диагностика чувствительности: в восьми вариантах порогов состав top-20 сохранился, роли изменились у 0–4.98% узлов. Louvain resolution 0.8/1.2 даёт 83/98 кластеров. Это не измерение accuracy; исходные параметры сохранены. Фактические результаты.

Перевод имеет source_ref=tx:<12 символов SHA-256>:<source_row>; source_row — 0-based физическая строка parquet, не банковский transaction_id. Совпадающие платежи имеют разные ссылки. Переводы сортируются по date, затем source_row. Суммы API transfers относятся ко всей выбранной direction, а не текущей странице. Краткая Markdown-справка доступна в /api/v1/nodes/{gid}/brief.

Структурная симуляция E1: POST /api/v1/experiments/removal принимает 1–3 разные строки gid. Она сравнивает число связанных неупорядоченных пар среди оставшихся вершин до и после удаления. Исходные слабые компоненты ещё допускают пути через выбранные узлы; после удаления эти пути исчезают. При нулевом знаменателе доля равна null. Возвращаются также число компонент, крупнейшая компонента и удалённые направленные рёбра. Это проверка топологии всей наблюдаемой сети, не прогноз денежных потерь; CSV, роли и приоритеты не меняются. Контракт и пример. UI-панель пока не включена.

Куда сходятся переводы выбранной группы

Это практический вопрос из кейса Freedom: найти получателей, которым переводит каждый из выбранных счетов. Откройте AI Аналитик → Общие получатели · без API-ключа, вставьте от 2 до 5 полных gid и нажмите «Найти общих получателей». Можно также добавлять текущий выбранный узел по одному: закрытие панели сохраняет группу.

Для воспроизводимого примера вставьте:

100000008748914100
100000008304139100
100000003880331100
100000004358004100
100000003528285100

Ожидаемый результат на приложенной выгрузке: 1 получатель — 100000003684369100, 2 874 700.00 KZT, 31 операция от всех 5 отправителей. Раскройте вклад каждого и идентификаторы исходных строк; полные переводы доступны в карточке получателя. Это сумма переводов выбранной группы, а не полный входящий оборот получателя и не доказательство координации.

Расчёт выполняется локально по всем исходным строкам, с точными суммами и сохранением повторов. При отсутствии совпадений показан честный пустой результат. «Подготовить вопрос AI» переносит точную группу в вопрос; модель вызывается только после «Задать вопрос». При успешном вызове инструмента сервер проверяет полный набор распознанных gid и условие «от всех», затем обязательно показывает каждого выданного получателя, число всех совпадений и ограничения. Выбор инструмента и понимание вопроса остаются задачей модели. Контракт и ограничения.

Необязательный OpenAI-аналитик (F13)

Панель помогает разобрать роль и альтернативу, проверить исходные переводы и выбрать следующий запрос данных. Поддерживаются вопросы по текущему графу; добавлен поиск общих прямых получателей 2–5 явно указанных счетов. Произвольные вычисления и трассировка маршрутов не реализованы. Обзор содержит пять лидеров, список соседей ограничен 20 связями.

Для проверки жюри со своим ключом:

  1. В корне проекта выполните cp .env.example .env (Windows PowerShell: Copy-Item .env.example .env).
  2. Откройте локальный .env в редакторе и заполните строку OPENAI_API_KEY=ваш_собственный_ключ. Поле в опубликованном .env.example намеренно пустое. OPENAI_MODEL можно оставить без изменения.
  3. Если обычный сервер уже работает, остановите его через Ctrl+C. В активном Python-окружении выполните python run.py --assistant.
  4. Откройте http://127.0.0.1:8000, нажмите «Открыть платформу», выберите узел и кнопку AI Аналитик справа снизу. Например: «Покажи исходные переводы и ограничения вывода». Нажмите «Задать вопрос»; проверьте ссылки и «Сохранить ответ».

Для этого дополнительного режима нужны интернет и действующий OpenAI API-ключ с доступом к указанной модели и оплатой запросов. Ключ хранится только на сервере; браузер его не получает. При изменении .env перезапустите сервер. Не загружайте .env в GitHub.

Основному сценарию этот раздел не нужен. После cp .env.example .env укажите свой ключ в OPENAI_API_KEY через локальный редактор. .env исключён из Git; не помещайте ключ в командную строку, browser/VITE переменные или коммиты. По умолчанию модель gpt-6-astra, проверенная настоящими запросами 23.09.2026. Более экономный вариант OPENAI_MODEL=gpt-5.4-mini-2026-03-17 также прошёл проверку. Astra использует reasoning low с ограничением времени и токенов. Это выбор модели для MVP, не доказательство превосходства на любых вопросах. OPENAI_MODEL позволяет указать доступную вашему аккаунту Responses-модель. Переменные окружения имеют приоритет над .env.

# Отдельный вопрос: JSON ответа, citations и tool_trace в stdout
python run.py --ask "Покажи приоритетные узлы и ограничения анализа"
# Точный gid можно передать без потери цифр:
python run.py --ask "Объясни роль и следующий запрос данных" --gid 100000000456947100
# Включённый серверный endpoint для интерфейса или HTTP-клиента:
python run.py --assistant

POST /api/v1/agent/query принимает {"question":"вопрос","gid":null} или точную строку gid. Непустой вопрос до 2000 символов. Полный контракт, настоящий ответ с исходным переводом. Нажмите AI Аналитик справа снизу: выберите контекст узла, напишите вопрос и нажмите «Задать вопрос». Ответ содержит основания, ссылки на текущий API, переход к узлу, фактические вызовы инструментов и кнопку «Сохранить ответ». Само открытие панели не отправляет запрос. На обычном python run.py ключ не читается, features.agent=false, endpoint возвращает 503 AGENT_DISABLED.

Это реальный цикл модели: выбор read-only инструментов → карточка/соседи/переводы/кластер/гипотезы/справка/общие получатели → оценка достаточности → выбор и порядок проверенных утверждений. Чтобы модель не сочиняла суммы и ссылки, финальная строгая схема содержит только status и ID утверждений, реально возвращённых инструментами. Сервер проверяет выбранный gid, ссылки и наличие ограничений и формирует Markdown. Свободного текста финансовых фактов, произвольного кода, веб-поиска и банковских действий нет. Выбор релевантных оснований моделью всё равно требует оценки аналитика; отсутствие вымышленных чисел не доказывает полноту ответа.

Одновременно один вопрос, не более 6 обращений к модели и 8 инструментов, 1800 output tokens на обращение и 7200 суммарно; общий бюджет времени 120 s, сетевой timeout до 35 s. На границе времени/токенов, при refusal/incomplete или неизвестных ссылках — явная ошибка, без подставного успешного ответа. tool_trace не содержит API-ключа или скрытых рассуждений. Роли/CSV/snapshot не меняются. Другие запросы основного API обслуживаются независимо.

При запросе помощнику вопрос и выбранные обезличенные факты передаются OpenAI; нужны интернет и оплачиваемый API. Используется store:false, что не означает безусловного zero retention: данные провайдера. При недоступном API используйте тот же граф/карточки/CSV локально. Проверка жюри не зависит от ключа участника.

Реально проверены: исходный перевод с source_ref, сопоставление основной/альтернативной ролей, отказ от установления личности/виновности/полного баланса по boundary и CLI для изолята. Provider mocks проверяют только протокол и отказы; отдельно выполнены 4 настоящих вопроса (12 Responses-вызовов). Фактические ответы и токены — в проверках API/CLI. Затем выполнены ещё два настоящих вопроса из браузера (5 Responses-вызовов, 12168 входных / 539 выходных токенов): роль/альтернатива и исходные переводы со ссылками. Проверены сохранение ответа, доступность источников и неизменность CSV: проверки панели.

Архитектура

flowchart LR
    RAW[Raw parquet] --> CHECK[Валидация и точные тиыны]
    CHECK --> GRAPH[Directed graph + Louvain]
    GRAPH --> RULES[Признаки / роли / приоритет]
    RULES --> SNAP[Единый snapshot и run_id]
    SNAP --> CSV[Три CSV]
    SNAP --> API[FastAPI на localhost]
    API --> UI[React / Cytoscape Алишера]

run_id — SHA-256 от source hashes, полного config, algorithm_version и точных версий вычислительных библиотек. Время записывается отдельно. GET не запускает пересчёт. API держит snapshot и байты CSV в памяти одного запуска, поэтому параллельный последующий CLI-пересчёт не смешивает данные сервера.

Новый результат готовится в соседнем временном каталоге и проверяется до активации. Замена каталога имеет rollback при ошибке переименования; это не универсальная атомарная замена директорий при аварийном выключении ОС. Если восстановление также не удалось, прежние результаты сохраняются в соседнем .<out>-recovery-<id>; точный путь выводится в ошибке. Один output защищён lock-файлом от двух писателей. Проверка сопоставляет snapshot с каждой исходной строкой перевода и ребром, а не только с общим количеством. Исходные данные не изменяются. БД отсутствует; внешний OpenAI используется только явно включённым необязательным помощником.

КаталогНазначение
app/loader, graph/features, clusters, roles, ranking, explanations, pipeline, schemas, API
config/Версионированные пороги и веса
tests/Искусственные графы, raw-инварианты, API/CSV и отказоустойчивость
contracts/Договор A/B, synthetic и реальные примеры
data/, starter/Оригинальные материалы организатора, без изменений
results/Генерируемый проверяемый результат
web/Интерфейс Алишера, production dist, unit/browser/integration tests
docs/hackalem/, docs/progress/ТЗ, источники, критерии, фактическая история

API: /api/v1/meta, /nodes, /nodes/{gid}, /nodes/{gid}/transfers, /graph, /clusters, /clusters/{id}, /exports/{name}, /nodes/{gid}/brief. Оболочки/фильтры/ошибки описаны в contracts/README.md, схема OpenAPI доступна локально в /openapi.json. Gid/src/dst — строки; денежные поля *_kzt — строки с двумя знаками. Пагинация 1…200, граф 1…1000 вершин; укороченный граф сообщает matched/shown counts.

Проверка результата

python -m pip install -r requirements-dev.lock
python -m pytest tests -q
python -m ruff check app tests run.py
python -m compileall -q app run.py
python run.py --pipeline-only
python run.py --verify-only

Проверены соседние 18-значные gid, все исходные узлы, денежные агрегаты, дубли, self-loop/ошибки, boundary, seed, нулевой вход, шесть ролей, caps/ties, кластеры, приоритет, повторный и перемешанный вход, raw↔CSV, API-пагинация и ограничения графа. Актуальные числа тестов и ограничения проверки — docs/validation.md.

Для самостоятельной проверки интерфейса:

  1. Открыть локальное рабочее место, сверить counts/period/run_id с /api/v1/meta.
  2. Выбрать любой узел очереди, сверить gid/роль/score с nodes_roles.csv.
  3. Проверить исходные переводы и сумму всей выборки; открыть следующую страницу.
  4. Ввести любой полный gid из data/nodes.parquet, независимо от фильтров очереди.
  5. Открыть boundary и изолированный seed; проверить предупреждения и отсутствие ложного terminal.
  6. Проверить кластер, кандидатов/альтернативу, следующий запрос данных и скачать три CSV.
  7. После установки отключить сеть и повторить основной сценарий.

Последовательность выполнена на двух ноутбуках, включая новый clone и запрет внешней сети для проверяемых процессов. Команды, версии, screenshots и точные границы проверки записаны в validation и повторе R1 на втором ноутбуке.

Производительность и offline

На Apple M4 / 16 GiB / macOS 26.6.2 полный Python-вызов raw→CSV с проверкой занял 0,808 с; CLI --pipeline-only — 0,883 с (импорты/установка пакетов вне этого таймера). Первый HTTP smoke: карточка 2,398 мс, ego 2,185 мс локально; это единичные измерения, не нагрузочный SLA. 2 248/3 119/4 840 входных строк; 2 248/89/50 строк в трёх CSV.

Сеть нужна для первоначального получения исходников и пакетов. Runtime ядра/API/UI не требует внешних сервисов. На A три сквозных браузерных сценария прошли с OS-запретом внешних исходящих соединений для сервера и тестового браузера; loopback разрешён. Поиск, граф, переводы и три CSV работали. Это проверка изоляции процессов, а не заявление об отключении всего ноутбука от сети. Универсальная установка без сети на неизвестной ОС не обещается: для неё нужен заранее проверенный wheelhouse для конкретной платформы. Личные .venv/.env не являются частью результата.

Ограничения выводов

  • 444 depth=4/out=0 — граница выгрузки; ни один не получает terminal только из-за отсутствующего выхода.
  • Входящие и начальные остатки неполны. 354 узла имеют O>I при I>0, ещё 23 — нулевой вход при положительном выходе. Это не доказательство аномалии баланса.
  • Конец наблюдаемого маршрута до depth=4 также не доказывает удержание денег. Координация — структурная гипотеза.
  • Нет ФИО, ИИН, атрибутов клиента, других банков, точного времени суток и ground truth. Внешнее обогащение и вымышленные личности не используются.
  • Louvain/центральности и пороги — эвристики. Число кластеров не подгоняется под замечания постановщика; accuracy/F1 не заявляются.
  • Главный сценарий локальный, loopback-only, без банковской авторизации. Публичный production deployment не реализован.
  • E1 доступен через API; UI-панель ещё не включена. E2 не реализован. AI-аналитик доступен в панели, API и CLI; по умолчанию выключен. Детерминированные объяснения ядра работают независимо от него.

Масштабирование до миллиона узлов

Текущая реализация проверена только на предоставленном объёме. Для ~1 млн узлов нужны колоночное/порционное чтение parquet, компактный графовый движок и adjacency, пересмотр стоимости Louvain/центральностей, предрасчёт ограниченных соседств и агрегаций, offline-расчёт дорогих метрик. UI должен получать ограниченные срезы и уровни детализации, а не весь граф. Сначала профиль памяти/времени, затем выбор распределённой инфраструктуры; это направление развития, не реализованный benchmark.

Устранение ошибок

СимптомДействие
Нет Python 3.12Проверить python --version; создать .venv именно интерпретатором 3.12
ModuleNotFoundErrorАктивировать .venv, выполнить установку из lock и python -m pip check
Ошибка precision/aggregate/hashНе ремонтировать суммы вручную; повторно получить оригинальные файлы и сверить source manifest
Нет web/distПолучить интегрированный commit или выполнить npm ci / npm run build в web
Порт занятОстановить свой предыдущий сервер Ctrl+C или использовать --port 8001
Gid округляется в ExcelИмпортировать колонку как текст; CSV сохраняет точные цифры
Узел не найденИспользовать полный gid; поиск относится ко всему набору, фильтры очереди не меняют данные
Pipeline lockУбедиться, что другой пересчёт не выполняется; только затем удалить указанный в ошибке stale lock
Нет сети после installИспользовать установленные зависимости; не требуется API-key или облачный сервис

Не скрываем повреждение данных заменой на fixture. При ошибке предыдущий успешный output сохраняется, но новый запуск не объявляется успешным.

Команда, источники и сдача

Мейрам (A) — данные, алгоритмы, API, CSV, README и интеграция; Алишер (B) — интерфейс, граф, карточки, браузерные проверки и демо. Ветки: codex/analysis-core, codex/workspace-ui; merge сохраняет историю. Codex помогал в проектировании, реализации и тестировании зоны A. Фактические компоненты и происхождение starter/data раскрыты в THIRD_PARTY.md. Данные разрешены только в рамках хакатона; не переиздаются как open data.

Оригинальный starter не является готовым решением команды. Основная функциональность создана в соревновательном окне. Официальное ТЗ, положение, матрица сдачи, полное ТЗ.

Проверенная версия и границы приёмки

Приложение строит граф, роли, кластеры и три CSV; поиск, исходные переводы, альтернативные гипотезы, обе темы и AI-панель проверены в браузере. Перед публикацией финального кода 8e9de4d прошли 217 backend-тестов, 43 frontend-теста, 64 браузерные contract-проверки и 5 сквозных сценариев на настоящих данных с запрещённой внешней сетью. Время проверки, SHA и результаты записаны в финальном отчёте интеграции.

Чистый clone более ранней версии f45632f с новым venv прошёл offline-проверку: расчёт за 1.10 s и побайтовое совпадение трёх CSV. Чистая установка финального SHA повторно не выполнялась. Общие получатели проверены отдельно в offline-браузере и настоящим вопросом Astra: отчёт этого этапа.

Основной сценарий работает без ключа. Структурная симуляция доступна через API; её интерфейс и временные паттерны не реализованы. Точный SHA вашей копии: git rev-parse HEAD. Дополнительно: проверки и ограничения, текущее состояние, порядок подачи.

Итоговая сверка ТЗ и замечаний внешнего ревью содержит покрытие требований, ограничения агента и приоритетные направления развития.

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

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

mikonyaa 38CyberPersonality 21

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

  • 2026-09-23 17:52Clarify jury README verification and final evidencemikonyaa
  • 2026-09-23 17:50Fix WebKit modal focus and verify final joint MVP releaseCyberPersonality
  • 2026-09-23 17:44Record final joint release acceptance and end-of-work handoffmikonyaa
  • 2026-09-23 17:44Merge Alisher final verifier and keyboard fixes after release checksmikonyaa
  • 2026-09-23 17:41Document jury workflow, common-recipient evidence and final B7 acceptancemikonyaa
  • 2026-09-23 17:39Harden evidence verification and keyboard navigation after independent reviewCyberPersonality
  • 2026-09-23 17:39Bind explicit investigation groups independently of the open node cardmikonyaa
  • 2026-09-23 17:37Merge reviewed B7 audit fixes with common-recipient workflowmikonyaa
Все коммиты (59)
  • 2026-09-23 17:34Add exact common-recipient investigation and verified Astra agentmikonyaa
  • 2026-09-23 17:28Fix MVP audit findings in local API, verifier and analyst workflowCyberPersonality
  • 2026-09-23 17:17Record final clean-clone acceptance, hour five and jury API-key setupmikonyaa
  • 2026-09-23 17:06Merge reviewed B6 visual update with grounded AI panelmikonyaa
  • 2026-09-23 17:02Add grounded AI analyst panel and explain priorities with observed flowsmikonyaa
  • 2026-09-23 16:58Polish entry transitions and make dense graph exploration readableCyberPersonality
  • 2026-09-23 16:45Merge main banner while preserving jury launch and verification guidemikonyaa
  • 2026-09-23 16:43docs: make jury verification self-contained and ship bundle license noticesmikonyaa
  • 2026-09-23 16:41Update README with banner and project detailsmrxfs0ciety
  • 2026-09-23 16:30docs: verify B5 themes and overview integration on real offline datamikonyaa
  • 2026-09-23 16:20feat(ui): add Freedom-inspired themes and return to overviewCyberPersonality
  • 2026-09-23 16:13docs: verify optional agent release from a keyless clean clonemikonyaa
  • 2026-09-23 16:10feat: add optional OpenAI analyst with verified evidence and bounded toolsmikonyaa
  • 2026-09-23 15:52docs: verify B4 integration against hardened backendmikonyaa
  • 2026-09-23 15:51docs: publish optional evidence-grounded OpenAI agent contractmikonyaa
  • 2026-09-23 15:50merge: integrate Alisher graph focus and workspace hierarchymikonyaa
  • 2026-09-23 15:50fix: preserve exact money and validate configured snapshots before publicationmikonyaa
  • 2026-09-23 15:41feat(ui): refine analyst workspace with clear hierarchy and graph focusCyberPersonality
  • 2026-09-23 15:36Merge remote-tracking branch 'origin/main' into codex/workspace-uiCyberPersonality
  • 2026-09-23 15:33docs: prepare verified submission handoff and explicit release limitsmikonyaa
  • 2026-09-23 15:28release: verify fresh main clone and offline end-to-end deliverablesmikonyaa
  • 2026-09-23 15:25docs: reconcile final readiness with verified second laptop evidencemikonyaa
  • 2026-09-23 15:24Merge remote-tracking branch 'origin/codex/analysis-core' into codex/workspace-uiCyberPersonality
  • 2026-09-23 15:23docs: record second laptop reproducibility and third hour evidencemikonyaa
  • 2026-09-23 15:23merge: include Alisher timed demo and repeated main README verificationmikonyaa
  • 2026-09-23 15:20merge: preserve Alisher independent clean launch offline proof and demo guidemikonyaa
  • 2026-09-23 15:20feat: simulate bounded structural removals without changing analysis resultsmikonyaa
  • 2026-09-23 15:19docs: confirm corrected main README on second clean cloneCyberPersonality
  • 2026-09-23 15:16Merge remote-tracking branch 'origin/main' into codex/workspace-uiCyberPersonality
  • 2026-09-23 15:14docs: record timed live demo and verified CSV handoffCyberPersonality
  • 2026-09-23 15:14docs: verify integrated offline workflow and publish bounded removal contractmikonyaa
  • 2026-09-23 15:13docs: verify clean clone and isolated offline workflowCyberPersonality
  • 2026-09-23 15:08merge: connect real transfers cluster summaries and verified CSV downloadsmikonyaa
  • 2026-09-23 15:07Merge remote-tracking branch 'origin/codex/analysis-core' into codex/workspace-uiCyberPersonality
  • 2026-09-23 15:04merge: integrate Alisher directed graph and rule evidence workspacemikonyaa
  • 2026-09-23 15:04merge: preserve updated Neverlose project title from mainmikonyaa
  • 2026-09-23 15:04fix: keep API exports coherent and verify every source-backed resultmikonyaa
  • 2026-09-23 14:59feat: finish source-backed node investigation workflowCyberPersonality
  • 2026-09-23 14:53Merge remote-tracking branch 'origin/codex/analysis-core' into codex/workspace-uiCyberPersonality
  • 2026-09-23 14:51merge: integrate Alisher workspace shell with shared analysis contractmikonyaa
  • 2026-09-23 14:51feat: serve verified analysis CSVs and source-backed investigation APImikonyaa
  • 2026-09-23 14:50Update project title in README.mdmrxfs0ciety
  • 2026-09-23 14:46feat: connect directed network and evidence panelCyberPersonality
  • 2026-09-23 14:46Merge remote-tracking branch 'origin/codex/analysis-core' into codex/workspace-uiCyberPersonality
  • 2026-09-23 14:39feat: build analyst workspace shell with exact identifiersCyberPersonality
  • 2026-09-23 14:38feat: compute explainable roles communities and reproducible CSVsmikonyaa
  • 2026-09-23 14:29feat: validate source transfers and preserve every graph nodemikonyaa
  • 2026-09-23 14:26chore: establish Python runtime and synthetic API contractmikonyaa
  • 2026-09-23 14:11docs: define Neverlose finance MVP and named parallel work plansmikonyaa
  • 2026-09-23 13:49docs: preserve official finance inputs and audit datasetmikonyaa
  • 2026-09-23 13:31just update name from SozTech to Neverlosemrxfs0ciety
Структура репозитория (340 файлов)
.env.example
.gitignore
AGENTS.md
CLAUDE.md
README.md
THIRD_PARTY.md
THIRD_PARTY_NOTICES.txt
app/__init__.py
app/api.py
app/assistant.py
app/clusters.py
app/common_recipients.py
app/experiments.py
app/explain.py
app/features.py
app/loader.py
app/pipeline.py
app/ranking.py
app/roles.py
app/schemas.py
config/rules.json
contracts/README.md
contracts/agent-v1.md
contracts/common-recipients-v1.md
contracts/removal-v1.md
contracts/v1.actual.json
contracts/v1.agent.actual.json
contracts/v1.example.json
contracts/v1.removal.actual.json
data/README.md
data/edges.parquet
data/nodes.parquet
data/transactions.parquet
docs/SUBMISSION.md
docs/architecture.md
docs/demo.md
docs/hackalem/01_PRODUCT_SPEC.md
docs/hackalem/02_DATA_ALGORITHMS.md
docs/hackalem/03_ARCHITECTURE_CONTRACTS.md
docs/hackalem/04_INTERFACE.md
docs/hackalem/05_IMPLEMENTATION_PLAN.md
docs/hackalem/06_QUALITY_GATES.md
docs/hackalem/07_RULES_DELIVERY.md
docs/hackalem/08_SESSION_CONTEXT.md
docs/hackalem/09_PROMPTS.md
docs/hackalem/10_SOURCE_AUDIT.md
docs/hackalem/11_README_REQUIREMENTS.md
docs/hackalem/ALISHER.md
docs/hackalem/DECISIONS.md
docs/hackalem/FINAL_AUDIT.md
docs/hackalem/MEIRAM.md
docs/hackalem/PACKAGE_REVIEW.md
docs/hackalem/README.md
docs/hackalem/STATUS.md
docs/hackalem/evidence/a1-loader.json
docs/hackalem/evidence/a2-sensitivity.json
docs/hackalem/evidence/agent-ui-a/final-answer-dark.png
docs/hackalem/evidence/agent-ui-a/final-answer.md
docs/hackalem/evidence/agent-ui-a/final-floating-button-dark.png
docs/hackalem/evidence/agent-ui-a/final-report.json
docs/hackalem/evidence/agent-ui-a/initial-answer-dark.png
docs/hackalem/evidence/agent-ui-a/initial-answer.md
docs/hackalem/evidence/agent-ui-a/initial-floating-button-dark.png
docs/hackalem/evidence/agent-ui-a/initial-report.json
docs/hackalem/evidence/agent-ui-a/report.json
docs/hackalem/evidence/b5-a/download-hashes.json
docs/hackalem/evidence/b5-a/real-card-dark-1440.png
docs/hackalem/evidence/b5-a/real-network-light-1024.png
docs/hackalem/evidence/b5-a/report.json
docs/hackalem/evidence/b5-a/run.json
docs/hackalem/evidence/b6-agent-a/download-hashes.json
docs/hackalem/evidence/b6-agent-a/panel-dark.png
docs/hackalem/evidence/b6-agent-a/panel-light.png
docs/hackalem/evidence/b6-agent-a/real-card-dark-1440.png
docs/hackalem/evidence/b6-agent-a/real-card-light-1024.png
docs/hackalem/evidence/b6-agent-a/report.json
docs/hackalem/evidence/b6-agent-a/run.json
docs/hackalem/evidence/b6-agent-a/workspace-dark.png
docs/hackalem/evidence/b6-agent-a/workspace-light.png
docs/hackalem/evidence/baseline-audit.json
docs/hackalem/evidence/common-a/astra-answer.md
docs/hackalem/evidence/common-a/browser-check.mjs
docs/hackalem/evidence/common-a/browser-live.json
docs/hackalem/evidence/common-a/browser-offline.json
docs/hackalem/evidence/common-a/common-dark-1440.png
docs/hackalem/evidence/common-a/common-light-1024.png
docs/hackalem/evidence/common-a/final-browser-offline.json
docs/hackalem/evidence/common-a/final-integration.json
docs/hackalem/evidence/common-a/final-secret-audit.json
docs/hackalem/evidence/common-a/live-astra-answer.png
docs/hackalem/evidence/common-a/model-evaluation.json
docs/hackalem/evidence/common-a/report.json
docs/hackalem/evidence/common-a/secret-audit.json
docs/hackalem/evidence/data-audit.json
docs/hackalem/evidence/e1-api.json
docs/hackalem/evidence/f13-a/cli-isolate.json
docs/hackalem/evidence/f13-a/csv-sha256.json
docs/hackalem/evidence/f13-a/first-loop.json
docs/hackalem/evidence/f13-a/http-boundary.json
docs/hackalem/evidence/f13-a/http-node.json
docs/hackalem/evidence/f13-a/report.json
docs/hackalem/evidence/g3-a/download-hashes.json
docs/hackalem/evidence/g3-a/real-card-1440.png
docs/hackalem/evidence/g3-a/real-transfers-1024.png
docs/hackalem/evidence/g3-a/run.json
docs/hackalem/evidence/g3-a/verification.json
docs/hackalem/evidence/hour-5-a/download-hashes.json
docs/hackalem/evidence/hour-5-a/report.json
docs/hackalem/evidence/hour-5-a/run.json
docs/hackalem/evidence/hour-5-a/secret-audit.json
docs/hackalem/evidence/release-a/download-hashes.json
docs/hackalem/evidence/release-a/run.json
docs/hackalem/evidence/release-a/verification.json
docs/hackalem/evidence/runtime-a/probe.py
docs/hackalem/evidence/runtime-a/run.json
docs/hackalem/sources/manifest.json
docs/hackalem/sources/official-case.ru.txt
docs/hackalem/sources/official-case.txt
docs/hackalem/sources/rules-extracted.txt
docs/hackalem/sources/user-master-context.md
docs/progress/A.md
docs/progress/B.md
docs/progress/hour-1.md
docs/progress/hour-2.md
docs/progress/hour-3.md
docs/progress/hour-4.md
docs/progress/hour-5.md
docs/validation.md
pyproject.toml
requirements-dev.in
requirements-dev.lock
requirements.in
requirements.lock
results/clusters.csv
results/manifest.json
results/nodes_roles.csv
results/snapshot.json
results/top_nodes.csv
run.py
starter/README.md
starter/requirements.txt
starter/starter.py
tests/conftest.py
tests/test_analysis.py
tests/test_api.py
tests/test_assistant.py
tests/test_common_recipients.py
tests/test_data.py
tests/test_experiments.py
tests/test_explain_plain.py
tests/test_exports.py
web/README.md
web/THIRD_PARTY.md
web/e2e/agent.spec.ts
web/e2e/fixture.ts
web/e2e/welcome.spec.ts
web/e2e/workspace.spec.ts
web/evidence/b1/b1-1024.png
web/evidence/b1/b1-1280.png
web/evidence/b1/b1-1440.png
web/evidence/b2/b2-directed.png
web/evidence/b2/b2-isolate.png
web/evidence/b3/download-hashes.json
web/evidence/b3/real-boundary.png
web/evidence/b3/real-card-1024.png
web/evidence/b3/real-card-1280.png
web/evidence/b3/real-card-1440.png
web/evidence/b3/real-isolate.png
web/evidence/b3/real-network-1024.png
web/evidence/b3/real-network-1280.png
web/evidence/b3/real-network-1440.png
web/evidence/b3/real-transfers-1024.png
web/evidence/b3/real-transfers-1280.png
web/evidence/b3/real-transfers-1440.png
web/evidence/b3/run.json
web/evidence/b4/download-hashes.json
web/evidence/b4/real-boundary.png
web/evidence/b4/real-card-1024.png
web/evidence/b4/real-card-1280.png
web/evidence/b4/real-card-1440.png
web/evidence/b4/real-isolate.png
web/evidence/b4/real-network-1024.png
web/evidence/b4/real-transfers-1280.png
web/evidence/b4/run.json
web/evidence/b4/verification.json
web/evidence/b5/download-hashes.json
web/evidence/b5/real-boundary-dark.png
web/evidence/b5/real-boundary-light.png
web/evidence/b5/real-card-dark-1024.png
web/evidence/b5/real-card-dark-1280.png
web/evidence/b5/real-card-dark-1440.png
web/evidence/b5/real-card-light-1024.png
web/evidence/b5/real-card-light-1280.png
web/evidence/b5/real-card-light-1440.png
web/evidence/b5/real-isolate-dark.png
web/evidence/b5/real-isolate-light.png
web/evidence/b5/real-network-dark-1024.png
web/evidence/b5/real-network-dark-1280.png
web/evidence/b5/real-network-dark-1440.png
web/evidence/b5/real-network-light-1024.png
web/evidence/b5/real-network-light-1280.png
web/evidence/b5/real-network-light-1440.png
web/evidence/b5/real-transfers-dark-1024.png
web/evidence/b5/real-transfers-dark-1280.png
web/evidence/b5/real-transfers-dark-1440.png
web/evidence/b5/real-transfers-light-1024.png
web/evidence/b5/real-transfers-light-1280.png
web/evidence/b5/real-transfers-light-1440.png
web/evidence/b5/run.json
web/evidence/b5/verification.json
web/evidence/b6/download-hashes.json
web/evidence/b6/overview-dark.png
web/evidence/b6/overview-expanded.png
web/evidence/b6/overview-focused.png
web/evidence/b6/overview-light.png
web/evidence/b6/overview-network.png
web/evidence/b6/real-boundary-dark.png
web/evidence/b6/real-boundary-light.png
web/evidence/b6/real-card-dark-1024.png
web/evidence/b6/real-card-dark-1280.png
web/evidence/b6/real-card-dark-1440.png
web/evidence/b6/real-card-light-1024.png
web/evidence/b6/real-card-light-1280.png
web/evidence/b6/real-card-light-1440.png
web/evidence/b6/real-isolate-dark.png
web/evidence/b6/real-isolate-light.png
web/evidence/b6/real-network-dark-1024.png
web/evidence/b6/real-network-dark-1280.png
web/evidence/b6/real-network-dark-1440.png
web/evidence/b6/real-network-light-1024.png
web/evidence/b6/real-network-light-1280.png
web/evidence/b6/real-network-light-1440.png
web/evidence/b6/real-transfers-dark-1024.png
web/evidence/b6/real-transfers-dark-1280.png
web/evidence/b6/real-transfers-dark-1440.png
web/evidence/b6/real-transfers-light-1024.png
web/evidence/b6/real-transfers-light-1280.png
web/evidence/b6/real-transfers-light-1440.png
web/evidence/b6/run.json
web/evidence/b6/verification.json
web/evidence/b6/welcome-dark.png
web/evidence/b6/welcome-light.png
web/evidence/b7/audit-controls.json
web/evidence/b7/audit-controls.png
web/evidence/b7/clean-clone/README-AUDIT.md
web/evidence/b7/clean-clone/http-report-0b6a20e.json
web/evidence/b7/clean-clone/http-report.json
web/evidence/b7/clean-clone/packages.json
web/evidence/b7/clean-clone/verify.json
web/evidence/b7/demo-timer.json
web/evidence/b7/dependencies/npm-audit.json
web/evidence/b7/dependencies/python-dev-osv-querybatch.json
web/evidence/b7/dependencies/python-dev-package-versions.json
web/evidence/b7/dependencies/python-osv-querybatch.json
web/evidence/b7/dependencies/python-package-versions.json
web/evidence/b7/dependencies/summary.json
web/evidence/b7/download-hashes.json
web/evidence/b7/keyboard-card-1024.png
web/evidence/b7/overview-dark.png
web/evidence/b7/overview-expanded.png
web/evidence/b7/overview-focused.png
web/evidence/b7/overview-light.png
web/evidence/b7/overview-network.png
web/evidence/b7/real-boundary-dark.png
web/evidence/b7/real-boundary-light.png
web/evidence/b7/real-card-dark-1024.png
web/evidence/b7/real-card-dark-1280.png
web/evidence/b7/real-card-dark-1440.png
web/evidence/b7/real-card-light-1024.png
web/evidence/b7/real-card-light-1280.png
web/evidence/b7/real-card-light-1440.png
web/evidence/b7/real-isolate-dark.png
web/evidence/b7/real-isolate-light.png
web/evidence/b7/real-network-dark-1024.png
web/evidence/b7/real-network-dark-1280.png
web/evidence/b7/real-network-dark-1440.png
web/evidence/b7/real-network-light-1024.png
web/evidence/b7/real-network-light-1280.png
web/evidence/b7/real-network-light-1440.png
web/evidence/b7/real-transfers-dark-1024.png
web/evidence/b7/real-transfers-dark-1280.png
web/evidence/b7/real-transfers-dark-1440.png
web/evidence/b7/real-transfers-light-1024.png
web/evidence/b7/real-transfers-light-1280.png
web/evidence/b7/real-transfers-light-1440.png
web/evidence/b7/run.json
web/evidence/b7/ux-review-before.json
web/evidence/b7/ux-review.json
web/evidence/b7/verification.json
web/evidence/b7/welcome-dark.png
web/evidence/b7/welcome-light.png
web/evidence/r1/clean-launch.json
web/evidence/r1/download-hashes.json
web/evidence/r1/network-proof.json
web/evidence/r1/offline-used.sb
web/evidence/r1/release-retest.json
web/evidence/r2/download-hashes.json
web/evidence/r2/timer.json
web/index.html
web/integration/audit-controls.spec.ts
web/integration/real-api.spec.ts
web/package-lock.json
web/package.json
web/playwright.config.ts
web/playwright.integration.config.ts
web/scripts/offline-macos.sb
web/src/App.tsx
web/src/agent/AgentPanel.tsx
web/src/agent/CommonRecipients.tsx
web/src/agent/agent.css
web/src/agent/client.test.ts
web/src/agent/client.ts
web/src/agent/common.test.ts
web/src/agent/common.ts
web/src/analysis/role-legend.css
web/src/api.test.ts
web/src/api.ts
web/src/assets/freedom.svg
web/src/components/ClusterPanel.tsx
web/src/components/Exports.tsx
web/src/components/FreedomLogo.tsx
web/src/components/Icon.tsx
web/src/components/Network.tsx
web/src/components/NodePanel.tsx
web/src/components/Queue.tsx
web/src/components/RuleChecks.tsx
web/src/components/States.tsx
web/src/components/ThemeSwitch.tsx
web/src/components/Transfers.tsx
web/src/components/Welcome.tsx
web/src/contract.ts
web/src/domain.ts
web/src/main.tsx
web/src/network.test.ts
web/src/network.ts
web/src/styles.css
web/src/theme.ts
web/test-support/workspace.ts
web/tsconfig.json
web/vite.config.ts
Ветки (3)

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

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

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