Skip to main content
Glama

AIRLOCK

Ничто не попадает в продакшн, не пройдя через шлюз.

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

Построена на TrueForge для Agent Harness Hackathon, 24–30 августа 2026 года.


Идея в одном правиле

Заключительная фраза TrueFoundry на странице хакатона: «создай агента, которому можно доверить root». AIRLOCK — это буквальный ответ: агент, который ведёт себя так, будто ему не доверен root, и каждый раз доказывает это, прежде чем попросить.

Любой другой шлюз утверждения — это «агент говорит, что собирается сделать X — нажми “да”». Это просьба к человеку довериться плану. Шлюз AIRLOCK не может быть открыт, пока агент не создаст сертификат, а сертификаты бывают двух видов:

Сертификат Undo — для обратимых изменений. Агент применяет изменение к теневой ветке, применяет собственный откат, затем в третий раз сверяет контрольные суммы таблиц и доказывает, что данные вернулись байт-в-байт в то состояние, с которого всё началось. Он уже сделал это, потом отменил, и вот совпадающие контрольные суммы. Теперь он может спросить.

Сертификат Scope — для по-настоящему необратимых изменений. Удаление нельзя доказать обратимым, поэтому агент доказывает противоположное: что именно будет уничтожено во всех системах, к ничего больше. И плюс явный список исключений: что намеренно не трогается и почему. Он не может пообещать, что вы сможете это откатить. Он может пообещать, что знает точно, что такое «это».

certificate.status !== "PROVEN"  →  the approval gate is never offered.

Не приглушено. Не предупреждается. Вообще не отрисовывается.

Это правило — тип, а не if

Элемент управления Approve принимает ApprovalGrant. ApprovalGrant содержит приватный на уровне модуля символ, который может выпустить только openGate(). Поэтому не существует такого значения, которое разработчик мог бы передать, чтобы получить одобрение непроверенного изменения — ни случайно, ни намеренно, не редактируя сам шлюз.

// packages/contract/src/gate.ts
const GATE_WITNESS: unique symbol = Symbol('airlock.gate.witness');

export interface ApprovalGrant {
  readonly [GATE_WITNESS]: true;   // unforgeable outside this module
  readonly irreversible: boolean;
  readonly seals_required: number;
  readonly final: boolean;
  // …
}

Шесть попыток подделать его зафиксировано как ошибки компиляции в gate.typetest.ts. Если кто-то ослабит тип, ожидаемые ошибки исчезнут, tsc сообщит о неиспользуемом @ts-expect-error — и сборка падёт.

То же правило работает и на стороне сервера. Утверждение через HTTP API без участия браузера отклоняется точно так же:

$ curl -XPOST localhost:3000/api/dossiers/dos_currency_fix/decision -d '{"decision":"approved"}'
{"error":"CERTIFICATE_FAILED","message":"Verification ran and failed. This change cannot be approved from this dossier."}
403

$ # …and a dossier that lies, claiming match:true with checksums that differ:
{"error":"CHECKSUM_MISMATCH","message":"The data did not return to its starting state after rollback."}
403

AIRLOCK никогда не доверяет собственному флагу match верификатора. Он сам пересчитывает pre === post_rollback, поэтому ошибка движка или подделанная нагрузка не могут открыть дверь.

Попробуйте без установки чего-либо. На лендинге есть живой шлюз: он строит настоящий Change Dossier из набора контролов и передаёт его настоящему openGate(). Каждая комбинация — это настоящее вычисление. Попробуйте найти ту, что откроет дверь, которая не должна открываться.


Related MCP server: mcp-nixreview

Как это запустить

git clone https://github.com/Rohit-ATS/Airlock && cd Airlock
npm install
npm run build --workspace @airlock/contract
npm run dev --workspace @airlock/console

Route

What it is

/

Парадная дверь — аргумент, в нём два живых демо

/console

Консоль оператора: DOING / WAITING / DID

/control

Пульт управления: состояние, отказы, целостность журнала

Консоль сама наполняет себя из contracts/examples/ при первом запуске, поэтому вы попадаете в живая очередь согласования с одиннадцатью настоящими изменениями — два готовых к одобрению, шесть запечатаны по шести разным причинам и три решённых записи запечатаны в хэш-цепочку. Без базы данных, API-ключа и регистрации.

Эти одиннадцать — фикстуры консоли. Они прогоняют карточку сертификата, очередь, движок политик и журнал. Это не доказательства чего-либо о чьей-либо базе, а нерешённые записи при посадке привязываются к текущему времени, потому что у сертификата есть окно свежести, а вечно устаревшее демо не доказывает ничего. Запуск AIRLOCK_NO_SEED=1 стартует без данных.

Чтобы управлять агентом, а не фикстурами, направьте его на сервер TrueForge:

npx @truefoundry/trueforge@latest              # http://localhost:8790
NEXT_PUBLIC_TRUEFORGE_BASE_URL=http://localhost:8790 npm run dev --workspace @airlock/console

В Windows используйте Docker. TrueForge 0.1.4 не запускается нативно в Windows (Only URLs with a scheme in: file, data, and node are supported… Received protocol 'c:'); а локальный режим песочницы там — только macOS/Linux. См. docs/TRUEFORGE-NOTES.md.


На что смотрит судья

У агента ровно один вход

AIRLOCK поставляется как MCP-сервер (packages/mcp). Подключение его — это то, что делает наименьшие привилегии структурным фактом, а не пожеланием:

{ "name": "airlock",
  "command": "npx", "args": ["-y", "@airlock/mcp"],
  "enable_tools": ["@all"],
  "require_approval_for_tools": ["airlock_request_approval"] }

Агент может прочитать политику, открыть изменение, прикрепить доказательство и спросить человека. Это весь набор его возможностей. Нет инструмента, который применяет изменение к продакшн, и единственный инструмент, который продвигает изменение дальше, удерживается harness, пока человек не ответит.

Коннекторы к продакшну примонтированы в режиме @read-only, и так как субагенты TrueForge наследуют MCP-область корневого агента, эта гарантия автоматически распространяется на каждого субагента: никакой субъект в запущенном run не сможет попасть в продакшен без участия человека. Это проверяется в scripts/check-agents.mjs в CI — поэтому свойство не разъезжается.

Семь классов изменений

Тест на допуск — не “является ли это записью в базу”, а “если это пойдёт не так, сможете ли вы это откатить?”. Отправить сорок тысяч писем так же необратимо, как удалить столбец, и при этом извиняться за это заметно труднее.

Класс

Сертификат

Одобряющие

Потолок

Миграция схемы

UNDO

1

тогда

Операция с данными

UNDO

1

5 000 000 записей

Стирание данных

SCOPE

2

1 000 человек

Раздача доступа

SCOPE

2

каждый доступ требует срок действия

Движение денег

SCOPE

2

25 000 £

Массовая рассылка

SCOPE

2

50 000 человек, режим тихого соблюдается

Изменение инфраструктуры

либо

2

запрет imökning с пятницы по понедельник

Политика: второй вопрос

Сертификат отвечает на вопрос «соответствует ли это изменение нашему заявлению?». Политика отвечает на другой: «разрешено ли это изменение в принципе, кому и именно сейчас?» Доказательство не может ответить на этот вопрос, потому что это свойство не изменения, а организации.

Оба вопроса оцениваются одним и тем же openGate, поэтому изменение, которое честно доказано и честно не разрешено, запечатывается по второй причине и получается типичное пояснение. Полная детализация — в додuments/POLICY.md, сгенерированном из самой политики, поэтому они не пустят.

Четыре правила, которые стоит выделить:

  • Паспортт — дело недолговечное. За пределами окна свежести сертификат описывает систему, которую уже не существует. Десять минут для выдачи доступа, тридцать — для миграции.

  • Дрейф продажи. Перед открытием шлюза AIRLOCK заново сверяет контрольные суммы продакшона с состоянием, из которого было взято доказательство. Если тем временем прилетела чужая миграция, изменение печатается — это, даже если сам dalаsea-он- is drift- complaint доложил, что всё в порядке. Заявлению об опасности верят; заявление о безопасности проверяется заново.

  • Кворум считает людей, а не кликов. Подписи хранятся по личности, поэтому дважды подписавшийся одноименный подтверждающий — это один подтверждающий человек, а тот, кто давал изменение, никогда не может оказаться среди них.

  • Нет постоянного доступа в продакшен. Каждый грант должен иметь срок действия, поэтому состояние системы по умолчанию — ни у кого нет ключей.

Журнал устойчиво виден при попытке подчинки

Система контроля изменений, в которой аудиторойдетую log можно отредактировать, — это контроль-изменение-театр. Каждое решённое изменение запечатывается хэшем отчёта Sobытия, поэтому правка любой исторической записи ломает все линии после неё:

$ npm run verify:ledger
  ok  #000  dos_orders_index         a41f9c02be7d8e5f31c4…
  FAIL #001  dos_gdpr_batch          9e02cc71a4bb0d3f2871…
         fault      : content-modified
FAIL — the chain breaks at record 1. Every record after that point is no longer trustworthy.

Это не делает журнал выпутаемым неправмым — те, кто может переписать файл, могут пересемей вычислить всю цепочку. Это делает видимым вмешательство для любого, у кого есть старый экземпляр одной единственной хэша; именно это свойство и важует, потому что человек, который аудирует вас, — не тот, кто его изменял.

Отдельные меточки вынимаются и проверяются сами, без доступа к консоли: GET /api/dossiers/{id}/receiptnode scripts/verify-ledger.mjs receipt.json.

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

Трёхзонная консоль

Оценка Savile Row требует интерфейс, который показывает, что агент сделает, что он ждёт и что он сделал, и спрашивает подтверждения перед следующим irreversible step шагом. Вот и указаны эти три зоны, названо ровно так.

  • DOING — live: параллельные потоки субагентов, каждый со своей моделью и расчитанной ценстой, под ними падаёт журнал песочницы, по времениются водовые вызовы действий.

  • WAITING — очередь согласований: каждое изменение щитирувает Какого человека, на что блокировано, сколько подписей ещё нужно и как долго уже повисло.

  • DID — журнал завершённых изменений: кто запросил, кто одобрил, какой именно сертификат, какие контрольные суммы и какие квитант, которые его печатают.

Комната управления

/control — другая аудитория. Не «должен ли я это одобрить», а «что эта система удерживает, что она отклонила и можно ли доверять записи о том, что она сделала».

Защитным числом является то, что шлюз отклонил, а не то, что одобрil — очередь, в которой ничего нет, не является доказаorium безопасности; число остановленных изменений с причинами — да. Также он перепроверяет journal прямо в браузере, а не полагается на серый слово «всё нормально» от сервера.

Панель харнисса

Постоянная узла с полным списком из 22 возможностей TrueForge. Каждая лампа приглушена, пока реальное событие харнеса не подтвердит true, после чего она загорается с временной подписью и ссылкой на высобей, который её доказал ровно.

Лампу нельзя зажечь из кода приложения. Единственный «шляфир» — detectors.ts, а питается она проходит через изменяемый обстукивател, обёрнутый вокруг настоящего потока событий TrueForge в observedServer.ts. События наблюдаются и соответствующие в исходном виде — никогда не синтезируются, не переносят в_state_order и не выбрасываются. Запуска, который не посетил этоt capability, закончается результатом ниже 22 — и это правильный результат.

Неопознанные строки намеренно остаются определимыми. Статит скрывать того, чего не было, — и счётчик теряет смысл; показано именно человеке lit=True. На лендинге все лампы тусклые, потому что там нет предположения.

См. docs/CAPABILITIES.md — построено из реестра, поэтому невозможно расхождение между утверждением и доказуемостью панели.

Карточка сертификата

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

Трос контрольных суммитов — это и есть видимый ответ: первая и третья строки сгруппированы вместе, вторая строка намеренно выделена меньше, потому что по ожиданиям должна отличаться, а при несоответствии подсвечивается именно тот знак, где расхождения, а не просто красный крест.

"### Break-glass (аварийный доступ)" "### Принудительный доступ (break-glass)" "### Противоаварийный режим (break-glass)"

Управляется политикой, по умолчанию выключено, и шлюз не открывает — BreakGlassOverride несёт другой приватный символ, нежели ApprovalGrant, и ни одна функция не принимает оба. Что оно делает — фиксирует, что поименованный человек обошёл запечатанную дверь, с письменным обоснованием не короче 40 символов, навсегда, в той же хеш-цепочке, что и всё остальное.

Аргумент в пользу его существования: люди так делают в любом случае. В каждой организации наступает момент, когда безопасный путь недоступен, и кто-то вместо этого открывает сессию psql. Плоскость управления, которая делает вид, что такого не бывает, не предотвращает обход — она лишь гарантирует, что о нём не останется записи. Чтобы включить его, требуются два переключателя, а ERASURE, MONEY_MOVEMENT и COMMS_BLAST прямо запрещают его полностью они outright.


Архитектура

contracts/dossier.schema.json     the Change Dossier — the one contract everything shares
packages/contract/                types, the gate, policy, receipts, capabilities, detectors
  src/gate.ts                     the invariant, as an unforgeable type
  src/policy.ts                   quorum, ceilings, freshness, freezes, no standing access
  src/receipt.ts                  the tamper-evident hash chain, isomorphic
  src/detectors.ts                the ONLY thing that can light a lamp
  src/capabilities.ts             the 22, each with its load-bearing use and its evidence
packages/mcp/                     AIRLOCK as an MCP server — the agent's one doorway
apps/console/                     Next.js 15, React 19, Tailwind v4
  app/page.tsx                    the landing page
  app/console/                    the three-zone operator console
  app/control/                    the control room
  src/server/observedServer.ts    the passthrough tap on the real TrueForge stream
agents/                           four agent specs: least privilege, model routing
skills/                           seven skill packs, one per domain the agent must not improvise

Консоль — и есть SDK. TrueForgeUI принимает кастомный layout-компонент, который рендерится внутри её собственного стека провайдеров, поэтому AIRLOCK передаётся как layout={AirlockConsole} — транскрипт, composer, список тредов, карточки подтверждения инструментов, карточки «спросить пользователя» и экран MCP OAuth — это всё собственные компоненты @truefoundry/trueforge-ui, просто переоформленные. Это не похожая подделка, собранная рядом с ним.


Честные примечания

Три пункта из исходного плана, как выяснилось, опирались на несуществующий API, и они построены иначе, а не зафакированы. Подробности — в docs/TRUEFORGE-NOTES.md §4.

  1. Субагенты динамичны, а не объявлены. TrueForge создаёт их в рантайме через create_sub_agent; в спецификации нет отдельного блока для каждого субагента. Поэтому «четыре поименованных субагента, каждый со своей областью инструментов» — нереализуемо.

  2. Посубагентного разграничения инструментов не существует. Документация это утверждает прямо: «субагенты имеют доступ к тем же MCP-инструментам и песочной среде, что и корневой агент». AIRLOCK вместо этого обеспечивает наименьшие привилегии на границе агента — продакшн-коннекторы смонтированы в режиме @read-only, а единственный прямой путь — это инструмент на нашем собственном MCP-сервере, который удерживает обвязка. Поскольку субагенты наследуют эту область видимости, ни один субъект в прогоне не сможет коснуться продакшена без участия человека. Это более сильное утверждение, чем просто уменьшенный набор инструментов, и оно реально.

  3. Посубагентной маршрутизации моделей тоже не существует. Маршрутизация реальна на границе агента — см. airlock-scout, airlock-privacy и airlock-treasury — а модель и стоимость, показанные для каждой полосы, берутся из реальных thread.created.agentInfo.model и turn.done.state.metrics.total_cost_in_usd.

Три детектора возможностей зависят от сигналов, которые мы не смогли подтвердить по документации — имя инструмента Code Mode, маркер выгрузки больших результатов и наличие события компакции. Они помечены как непроверенные. Если реальный прогон их не подтвердит, эти лампы останутся тёмными, а знаменатель уменьшится. Честные 19/19 лучше подогнанных 22/22, которые судья опровергнет, кликнув по одной лампе.

Два найденных апстрим-бага

  • @truefoundry/trueforge-ui@0.2.4 содержит конфликт зависимостей: @assistant-ui/core объявляет peer-зависимость от zustand@^5, тогда как рендереры OpenUI тянут zustand@^4, который npm поднимает в корень. Сборка падает с ошибкой 'useShallow' is not exported from 'zustand/shallow'. Обойдено блоком overrides в корневом package.json.

  • Его styles.css поставляет полный набор Tailwind-утилит в @layer tfy-agent-ui-utilities. При подключении после tailwindcss этот слой регистрируется позже, поэтому обычный .hidden от SDK побеждает ваш .xl\:flex независимо от медиавыражения — молча ломая каждый адаптивный вариант в хост-приложении. Исправлено явным объявлением порядка @layer в globals.css.


Тесты

npm test        # 92 tests, 11 fixtures, 4 agent specs

Четыре набора тестов, и каждый фиксирует свойство, а не реализацию:

Suite

Что закрепляется

gate.test.mjs

Ни один сертификат, не являющийся PROVEN, не открывает шлюз ни при какой комбинации класса, статуса и наблюдателя

policy.test.mjs

Кворум считает людей; заморозки вычисляются по лондонскому времени; заявление о безопасности пересчитывается; аварийный доступ никогда не становится подтверждением

receipt.test.mjs

Редактирование, переупорядочение или удаление опечатанной записи обнаруживается на самой записи, где это произошло

harness.test.mjs

Ничего, кроме реального события обвязки, не зажигает лампу — шум, повторные коннекторы и проза, которая просто упоминает доступен, ничего не зажигают

mcp/server.test.mjs

Ровно один инструмент является разрушительным, и это тот, который удерживается для подтверждения; инструмента, который вносит изменения, не существует

Плюс две структурные проверки, которые выполняются в CI:

  • check-fixtures.mjs — каждая фикстура парсится против контракта и даёт тот вердикт шлюза, который подразумевает её имя, так что фикстура .standing.json действительно отклоняется за отсутствие срока действия, а не по какой-то несвязанной причине, которой никто не заметил.

  • check-agents.mjs — ни один продакшн-коннектор не доступен на запись, а любой агент, который может писать куда-либо, подключает AIRFLOCK и удерживает ровно один инструмент для подтверждения.

Генерируемые артефакты (contracts/dossier.schema.json, docs/CAPABILITIES.md, docs/POLICY.md, фикстуры) создаются через npm run gen и идемпотенты, так что заявленное в документации и реальное поведение кода не может разойтись.


Команда

Рохит Марури — консоль, лендинг, диспетчерская, панель обвязки, карточка сертификата, шлюз, движок политик, журнал, защищённый от подделки, MCP-сервер, наборы правил и навыки агентов, контракт, webhookс и роли. Дамир — верификационный движок, жизненный цикл теневых веток, вычисление области доступа, эталонные данные.

Лицензия MIT.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Pauses AI agent execution and routes approval requests to humans via Slack or email, with cryptographically signed proof of the human's decision.
    197
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A safety gate for agent-proposed NixOS configuration changes, grading security-relevant option deltas, attesting closures for vulnerabilities, and requiring human approval with a tamper-evident audit ledger.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A human-in-the-loop governance interlock for AI agents. Agents propose changes, a human countersigns the exact plan, and then it executes stage by stage with precondition checks, verification, and auditing.
    Apache 2.0

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Rohit-ATS/Airlock'

If you have feedback or need assistance with the MCP directory API, please join our Discord server