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

# Custom policies

> Write a policy for a failure mode unique to your agent workflow.

Create a file ending in `policies.js`, `policies.mjs`, or `policies.ts` under `.failproofai/policies/`. Convention files load automatically at project and user scope.

## Test the policy before Cloud publication

<Tabs>
  <Tab title="Dashboard">
    1. Install the custom policy on one test machine and trigger both a matching action and a legitimate non-match.
    2. Go to **Observe → policy** and compare the two decisions.
    3. Open each linked session and verify the event payload contains enough evidence for the rule.
    4. When the behavior is correct, move the reviewed source into **Admin → policy editor** and publish a version.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    failproofai policies --install --custom ./security.policies.ts \
      --cli claude --scope project
    failproofai policies
    ```

    Convention files under `.failproofai/policies/` load without `--custom`. Keep an explicit install command in CI when validation should fail on a broken module.
  </Tab>
</Tabs>

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

customPolicies.add({
  name: "protect-production-paths",
  description: "Block writes to production configuration",
  match: { events: ["PreToolUse"] },
  fn: async (ctx) => {
    if (ctx.toolName !== "Write" && ctx.toolName !== "Edit") return allow();
    const path = String(ctx.toolInput?.file_path ?? "").replaceAll("\\", "/");
    if (path.split("/").includes("production")) {
      return deny("Writes to production configuration require approval.");
    }
    return allow();
  },
});
```

This matches `production/config.yml`, `/srv/production/config.yml`, `/srv/production`, and `C:\\production\\config.yml` for both `Write` and `Edit`. It does not match names such as `production-backup` because `production` must be a complete path segment.

Validate and install an explicit file:

```bash theme={null}
failproofai policies --install --custom ./security.policies.ts
```

The policy context includes the event type, normalized payload, tool name and input, session metadata, parameters, and source CLI when available.

## Test failure paths

Run validation after changing the entry file or any local module it imports:

```bash theme={null}
failproofai policies --install --custom ./security.policies.ts --scope project
```

The strict CLI path fails for missing files, syntax errors, unresolved imports, top-level exceptions, and module-load timeouts. At enforcement time, a broken custom file is logged and skipped so builtin policies can continue. Treat any load warning as a loss of expected enforcement and alert on it in production logs.

Use globally unique names across explicit, convention, and Cloud-managed policies. Keep policy functions deterministic, bound external calls with short timeouts, and return an intentional `allow`, `instruct`, or `deny` on every path.

<Warning>
  A custom policy is enforcement code. Test missing fields, alternate tool names, and malformed input—not only the expected match.
</Warning>
