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

# Ein Pack veröffentlichen

> Eigene Policies als GitHub-Release bereitstellen, das jeder installieren kann.

Ein Pack besteht aus drei Dateien, die einem GitHub-Release beigefügt werden. `failproofai pack build` erzeugt alle drei aus einer Policy-Datei, die bereits vorhanden ist.

## 1. Die Policies schreiben

Eine einzelne Datei, die dieselbe API wie jede benutzerdefinierte Policy verwendet. Zwei zusätzliche Felder sind für ein Pack relevant:

```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` ist standardmäßig **false**, wenn es weggelassen wird. Ein einfaches `failproofai pack add` aktiviert nur das, was explizit markiert wurde — ob alle Policies eines Fremden unbeaufsichtigt installiert werden, sollte nicht stillschweigend für den Nutzer entschieden werden.

<Warning>
  Der Eintrag muss eine **in sich geschlossene Datei** sein. Nur der Eintrag wird mit einem Digest verknüpft. Ein Pack, das lokale Dateien importiert, kann nicht ernsthaft behaupten, der Digest decke ab, was tatsächlich ausgeführt wird. Daher zunächst bündeln (`esbuild`, `bun build`, `rollup`) und das Pack aus dem Bundle erstellen — `pack build` lehnt einen lokalen Import ab, anstatt ein Versprechen zu machen, das es nicht halten kann.
</Warning>

## 2. Die Release-Assets erstellen

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

Es werden drei Dateien geschrieben, und jede Policy wird zuerst mit den **eigenen Regeln des Loaders** validiert — so schlägt ein Pack, das niemals installiert werden könnte, bereits hier fehl, wo es noch behoben werden kann:

| Datei                   | Beschreibung                                                 |
| ----------------------- | ------------------------------------------------------------ |
| `failproofai-pack.json` | Das Manifest: ID, Version, Effekt und ein Eintrag pro Policy |
| `failproofai-pack.mjs`  | Der Eintrag, unverändert                                     |
| `SHA256SUMS`            | `<sha256>  <dateiname>` für die anderen beiden Dateien       |

Zur Build-Zeit abgelehnt werden: eine ID, die nicht dem Format `publisher/name` entspricht; ein Policy-Name, der `/` enthält; eine Policy, die `alwaysOn` deklariert; eine fehlende `description`, `category` oder `match`; ein Eintrag, der nichts registriert; sowie ein Eintrag, der lokale Dateien importiert.

## 3. Dem Release beifügen

Das Release mit derselben Version taggen, die beim Build angegeben wurde, und alle drei Dateien als Release-Assets anhängen:

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

Nun kann es jeder installieren:

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

Die Asset-Namen sind festgelegt — sie sind das, woraus die CLI des Consumers ihre URLs konstruiert, ohne API-Aufruf und ohne Erkennung.

## Eine neue Version veröffentlichen

Mit dem neuen `--version` bauen, ein neues Release taggen und die drei Assets erneut anhängen. Consumer führen dasselbe `pack add` aus und behalten die Teilmenge, die sie ausgewählt hatten; eine deaktivierte Policy bleibt auch nach dem Upgrade deaktiviert.

Das **Umbenennen** einer Policy ist eine breaking change: Ein System, das sie deaktiviert hatte, deaktiviert jetzt einen Namen, der nicht mehr existiert, und der neue Name wird mit dem Standardwert von `defaultEnabled` aktiviert.

## Was Nutzer vertrauen

`SHA256SUMS` liegt im selben Release wie das Artefakt und beweist daher, dass die Bytes mit dem übereinstimmen, was veröffentlicht wurde — nicht jedoch, wer der Urheber ist. Wer Schreibzugriff auf das Repository hat, kann beide Dateien schreiben. Der Schutz für die Nutzer besteht darin, dass der Digest bei der Installation eingefroren wird — was veröffentlicht wurde, kann nachträglich nicht mehr verändert werden.

Aus einem Repository veröffentlichen, dessen Schreibzugriff kontrolliert wird, und ein Pack-Release wie die Veröffentlichung eines Packages behandeln.

## Beobachten vor dem Durchsetzen

Ein Manifest kann `"effect": "observe"` deklarieren. Diese Policies werden ausgeführt und ihre Urteile werden **aufgezeichnet und verworfen** — nichts wird blockiert. So lässt sich eine neue Regel gegen echten Traffic messen, bevor sie die Arbeit von jemandem unterbrechen kann.

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