> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Публикация пакета

> Поставляйте свои собственные политики как GitHub-релиз, который может установить кто угодно.

Пакет — это три файла, прикреплённые к GitHub-релизу. `failproofai pack build` создаёт все три файла на основе уже имеющегося файла политики.

## 1. Напишите политики

Один файл, использующий тот же API, что и любая пользовательская политика. Для пакета важны два дополнительных поля:

```js theme={null}
import { customPolicies, deny, allow } from "failproofai";

customPolicies.add({
  name: "block-refunds",
  description: "Refunds above the approved limit need a human",
  category: "Billing",        // groups it, and is what --category selects on
  defaultEnabled: true,       // switched on by a plain `pack add`
  match: { events: ["PreToolUse"], tools: ["Bash"] },
  fn: async (ctx) =>
    String(ctx.toolInput?.command ?? "").includes("refund")
      ? deny("Refunds need a human. Ask before running this.")
      : allow(),
});
```

`defaultEnabled` по умолчанию имеет значение **false**, если вы его опустите. Простая команда `failproofai pack add` включает только то, что вы отметили — установка всех политик незнакомца без участия пользователя — это решение, которое установщик не должен принимать за своего пользователя.

<Warning>
  Точка входа должна быть **одним самостоятельным файлом**. Только точка входа закреплена по хешу, поэтому пакет, который импортирует локальные файлы, не может честно утверждать, что хеш покрывает то, что запустится. Сначала объедините файлы (`esbuild`, `bun build`, `rollup`), а затем создайте пакет из объединённого результата — `pack build` отказывает локальным импортам, чтобы не поставить обещание, которое оно не может выполнить.
</Warning>

## 2. Создайте релиз-артефакты

```bash theme={null}
failproofai pack build ./policies.mjs \
  --id acme/support-agent \
  --version 1.0.0 \
  --out ./dist-pack
```

Он создаёт три файла и проверяет каждую политику с использованием **собственных правил загрузчика** — так что пакет, который никогда не мог бы установиться, не пройдёт здесь, где вы сможете это исправить:

| Файл                    | Что это                                                           |
| ----------------------- | ----------------------------------------------------------------- |
| `failproofai-pack.json` | Манифест: id, версия, эффект и по одной записи на каждую политику |
| `failproofai-pack.mjs`  | Ваша точка входа в неизменённом виде                              |
| `SHA256SUMS`            | `<sha256>  <filename>` для остальных двух файлов                  |

Отклоняется на этапе сборки: id, который не соответствует формату `publisher/name`, имя политики, содержащее `/`, политика, объявляющая `alwaysOn`, отсутствие `description`, `category` или `match`, точка входа, которая ничего не регистрирует, и точка входа, которая импортирует локальные файлы.

## 3. Прикрепите их к релизу

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

```bash theme={null}
gh release create 1.0.0 \
  ./dist-pack/failproofai-pack.json \
  ./dist-pack/failproofai-pack.mjs \
  ./dist-pack/SHA256SUMS
```

Теперь кто угодно может установить его:

```bash theme={null}
failproofai pack add acme/support-agent
```

Имена артефактов фиксированы — это то, из чего CLI потребителя строит свои URL-адреса, без вызовов API и без обнаружения.

## Поставка новой версии

Создайте пакет с новым `--version`, создайте новый релиз, снова прикрепите три артефакта. Потребители запустят тот же `pack add` и сохранят любое подмножество, которое они выбрали; политика, которую они отключили, останется отключённой при обновлении.

Изменение **имени** политики — это критическое изменение: машина, которая его отключила, отключает имя, которое больше не существует, а новое имя приходит с тем, что говорит `defaultEnabled`.

## Чему доверяют ваши пользователи

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

Публикуйте из репозитория, доступ на запись в который вы контролируете, и относитесь к релизу пакета как к публикации пакета.

## Наблюдайте перед тем, как применять

Манифест может объявить `"effect": "observe"`. Эти политики запускаются, и их решения **записываются и отбрасываются** — ничего не блокируется. Это способ проверить новое правило на реальном трафике перед тем, как оно сможет помешать чьей-то работе.

```json theme={null}
{ "id": "acme/support-agent", "version": "1.1.0", "effect": "observe", "policies": [ ... ] }
```
