
halo-record v0.2.42
Защищённые от несанкционированного вмешательства журналы аудита для ИИ-агентов: связанные хэш-цепочкой записи Runtime Records, без зависимостей, проверяемые кем угодно.
halo-record
Доказательство несанкционированного изменения аудиторских журналов для AI-агентов — хеш-цепочки Runtime Records, отображаемые в виде Runtime Report, который ваши клиенты могут проверить самостоятельно.
Каждое действие вашего агента (вызовы инструментов, вызовы моделей, доступ к данным, подтверждения) становится одной Runtime Record в журнале, доступном только для добавления и связанном хеш-цепочкой; Runtime Report — это та же цепочка, отображённая в виде самопроверяемой HTML-страницы. Любая сторона, владеющая контрольной точкой цепочки, может убедиться, что записи за ней никогда не изменялись, не доверяя тому, кто их создал — эта контрольная точка является несущим элементом: одна лишь цепочка обеспечивает защиту от несанкционированного изменения для всех, кроме стороны, управляющей регистратором (LIMITS.md §1). Когда служба безопасности клиента спрашивает: «Что ваш агент делал с нашими данными?», вы даёте им ссылку вместо абзаца текста. Проверки безопасности уже задают вопросы об AI рядом с чек-листом SOC 2 — и всё чаще эти вопросы исходят из ISO 42001, статей EU AI Act о ведении документации и собственных опросников клиентов. Сегодня письменное заверение всё ещё проходит. Ставка этого проекта в том, что так будет недолго.
Отмечено в Help Net Security (август 2026).
Формат записей открыт и свободен для реализации. Этот пакет — эталонная реализация: регистратор, верификатор, клиент-свидетель и сервер отчётов.
Используете halo-record или думаете об этом? Расскажите, кто вы и для чего → Кто использует halo-record?
Проверьте сами
Вас просят внедрить регистратор внутрь вашего агента. Вы не должны принимать это на веру:
- Ноль зависимостей времени выполнения. Только стандартная библиотека.
pip install halo-recordустанавливает ровно один пакет. - Никаких сетевых вызовов, кроме трёх опциональных — привязка к свидетелю (отправляет id субъекта, количество записей и два отпечатка цепочки — голову и корень цепочки), чтение контрольных точек свидетеля обратно (отправляет id субъекта) и метка времени RFC 3161 (отправляет только хеш состояния контрольной точки в Timestamp Authority). Все они отключены, пока вы их не вызовете; содержимое записей никогда не покидает вашу инфраструктуру.
- Необработанные аргументы инструментов хешируются, с рядом редактированное резюме. Аргументы хранятся в виде канонического хеша плюс резюме: текст аргументов с маскированием известных шаблонов секретов и PII, ограниченный 200 символами. Короткий ввод, не совпадающий ни с одним шаблоном, отображается в резюме полностью; режим только хеша (
summaries=False) не сохраняет резюме вовсе. Редактирование выполняется по мере возможности (регулярные выражения по распространённым форматам секретов и PII плюс энтропийный перехватчик): рассматривайте это как эшелонированную защиту, а не гарантию. Поля результатов, которые вы предоставляете помимоsummary, запечатываются как есть (LIMITS §13). - Достаточно мал для аудита. ~5 300 строк Python (строки кода, без учёта пустых строк и комментариев). Прочитать всё можно за один день.
- Apache-2.0.
- Документация первостепенна. LIMITS.md (что цепочка не может доказать), PRIVACY.md (что содержат записи и что покидает вашу машину), RETENTION.md (работа в условиях политики хранения) и REVIEWERS.md — независимая проверка из четырёх команд плюс формат цитирования для результатов проверки.
Что доказывает каждый уровень — несущее различие в этом проекте (LIMITS.md §1): цепочка, которую вы храните сами, доказывает, что записи не были отредактированы, относительно головы, которая уже есть у кого-то; только контрольные точки, хранящиеся вне оператора, доказывают, что ни одна не была удалена; и никакой хеш не доказывает, что каждое действие было захвачено.
| Утверждение | Собственная цепочка | + Внешние контрольные точки | + Доверенный захват |
|---|---|---|---|
| Обнаружение правок в установленном артефакте | ✔ | ✔ | ✔ |
| Обнаружение перезаписи зафиксированной истории | — | ✔ | ✔ |
| Обнаружение отсутствующих/запоздалых контрольных точек | — | ✔ (согласованная периодичность) | ✔ |
| Доказательство, что каждое действие было записано | — | — | зависит от границы захвата |
Посмотрите перед установкой: образец Runtime Report — вымышленные данные, настоящая цепочка, и он сам себя перепроверяет в вашем браузере, пока вы смотрите.
Демо за 60 секунд
Агент не требуется. С uv устанавливать ничего не нужно:``` uvx --from halo-record halo demo --serve
или классическим способом:```
pip install halo-record
halo demo --serve
Либо создаёт вымышленного поставщика support-агента с двумя клиентами, фиксирует цепочки (с локальным файлом-свидетелем, заменяющим внешнего по отношению к оператору — см. LIMITS.md §1), выдаёт их защищённые Runtime Reports и открывает консоль оператора в вашем браузере. Затем попробуйте тест на подмену: удалите строку из одного из файлов .jsonl и перезагрузите. Отчёт это обнаружит.
Запишите собственного агента
Одна строка на границе:```python from halo_record import trace
agent = trace(run_my_agent, profile="my-agent", log="audit.jsonl") # wraps your entrypoint; records the run boundary to ./audit.jsonl — add record_call() or a framework adapter at each tool boundary to capture individual calls
Удобный шим `from halo import ...` также поставляется — но имя `halo` на PyPI принадлежит несвязанному пакету терминального спиннера, и если этот пакет установлен, он выигрывает импорт. `halo_record` однозначен, поэтому в примерах используется он.
Без `log=` записи попадают в `~/.halo/my-agent.jsonl` (одна цепочка на агента). Обёртка фиксирует границу запуска; доказательства содержатся в записях отдельных вызовов. Захватывайте их с помощью адаптера фреймворка (матрица ниже) — или явно, что также показывает, как связываются делегирования:```python
from halo_record import Recorder, record_call
rec = Recorder("audit.jsonl")
with record_call(rec, "crm.lookup", {"account": "acct-9"}) as call: # one sealed record per tool call
call.result = crm.lookup("acct-9")
with record_call(rec, "payments.refund", {"amount": 120},
parent_id=rec.last_record_id()) as call: # child links to the action that spawned it
call.result = payments.refund(120)
Затем сформируйте отчёт:``` halo report audit.jsonl -o report.html # one chain -> self-verifying HTML halo serve ./records --port 8721 # all tenants, gated per customer
Quickstart заканчивается, когда вы смотрите на Runtime Report вашего собственного агента в браузере. Если вы получили файл JSONL и никакого отчёта, что-то не так: откройте issue.
### Блок верификации
Если guardrail или слой политик проверил действие, его вердикт может быть прикреплён к записи — необязательный блок, фиксирующий, что решил шлюз, запечатанный в цепочку хешей, как и любое другое поле:```python
from halo_record import build