> ## 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.

# Publicar um pack

> Distribua suas próprias políticas como um release do GitHub que qualquer pessoa pode instalar.

Um pack é composto por três arquivos anexados a um release do GitHub. O comando `failproofai pack build` gera os três a partir de um arquivo de políticas que você já possui.

## 1. Escreva as políticas

Um único arquivo, usando a mesma API de qualquer política customizada. Dois campos extras são importantes para um pack:

```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** por padrão quando omitido. Um `failproofai pack add` simples ativa apenas o que você marcou — instalar todas as políticas de um desconhecido de forma automática não é uma decisão que o instalador deve tomar pelo usuário.

<Warning>
  O entry deve ser **um único arquivo autocontido**. Apenas o entry recebe o pin de digest, então um pack que importa arquivos locais não poderia honestamente afirmar que o digest cobre o que é executado. Faça o bundle primeiro (`esbuild`, `bun build`, `rollup`) e construa o pack a partir do bundle — o `pack build` recusa uma importação local em vez de fazer uma promessa que não pode cumprir.
</Warning>

## 2. Construa os assets do release

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

O comando gera três arquivos e valida cada política com as **próprias regras do loader** antes — assim, um pack que nunca poderia ser instalado falha aqui, onde você pode corrigir:

| Arquivo                 | O que é                                                    |
| ----------------------- | ---------------------------------------------------------- |
| `failproofai-pack.json` | O manifesto: id, versão, efeito e uma entrada por política |
| `failproofai-pack.mjs`  | Seu entry, literalmente                                    |
| `SHA256SUMS`            | `<sha256>  <filename>` para os outros dois                 |

São recusados em tempo de build: um id que não seja `publisher/name`, um nome de política contendo `/`, uma política declarando `alwaysOn`, uma `description`, `category` ou `match` ausentes, um entry que não registra nada, e um entry que importa arquivos locais.

## 3. Anexe ao release

Crie a tag do release com a mesma versão que você usou no build e anexe os três arquivos como assets do release:

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

Agora qualquer pessoa pode instalá-lo:

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

Os nomes dos assets são fixos — são eles que a CLI do consumidor usa para construir suas URLs, sem chamadas de API nem descoberta automática.

## Lançando uma nova versão

Faça o build com o novo `--version`, crie um novo release com a tag correspondente e anexe os três assets novamente. Os consumidores executam o mesmo `pack add` e mantêm o subconjunto de políticas que haviam escolhido; uma política que foi desativada permanece desativada após a atualização.

Alterar o **nome** de uma política é uma breaking change: uma máquina que havia desativado esse nome está desativando um nome que não existe mais, e o novo nome chega com o valor que `defaultEnabled` define.

## O que seus usuários estão confiando

O `SHA256SUMS` fica no mesmo release que o artefato, portanto prova que os bytes são os que você publicou — mas não quem você é. Quem pode escrever no repositório pode escrever ambos os arquivos. A proteção dos seus usuários está no fato de que o digest é fixado no momento da instalação, então o que você publicou não pode ser alterado depois.

Publique a partir de um repositório cujo acesso de escrita você controla e trate um release de pack como a publicação de um pacote.

## Observe antes de aplicar

Um manifesto pode declarar `"effect": "observe"`. Essas políticas são executadas e seus vereditos são **registrados e descartados** — nada é bloqueado. É a forma de medir uma nova regra com tráfego real antes que ela possa interromper o trabalho de alguém.

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