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

# Jev through FailproofAI Cloud

> Let Jev judge your agents' tool calls through FailproofAI Cloud, on your organization's plan, with no TypeSafe account or key of your own.

[Jev](/policies/jev-byok), TypeSafe's classifier, reads each tool call against what you actually asked for and answers alongside your policies, never instead of them. Through **FailproofAI Cloud**, a connected machine uses Jev with the same key it already connects with: no TypeSafe account, no second key, no endpoint to configure. Each call is charged to your organization's existing plan allowance.

Everything Jev does is unchanged from the [bring-your-own-key setup](/policies/jev-byok): hard policies stay final, a reviewable policy's deny is cleared only when Jev was asked about exactly that concern, and any failure falls back to the regex result for that call.

<Note>
  Requires **failproofai 1.0.8-beta.0** or later. 1.0.7 has no Jev, even though it sorts above the 1.0.7 betas. Without a Jev config nothing changes: hooks run the regex policies exactly as they always have.
</Note>

## Turn it on

1. **Create a key with Jev.** In the FailproofAI Cloud dashboard, open **Keys → Create key** and pick the **machine** preset. It grants the three permissions a machine needs: `events:add` (send activity), `policies:pull` (receive policies) and `jev:evaluate` (Jev, charged to your organization's plan). A key cannot carry `jev:evaluate` without the other two.
2. **Connect the machine** with that key:

   ```bash theme={null}
   failproofai config --token <key>
   ```

   If your organization runs its own FailproofAI Cloud rather than the hosted one, add its address: `--url https://<your dashboard host>` (or export `FAILPROOFAI_CLOUD_URL`). Without it the key is checked against the hosted service and the connection fails. If that host's certificate comes from a private CA, install the CA in the machine's system trust store (for example with `update-ca-certificates`), not only in `NODE_EXTRA_CA_CERTS`: the daemon that sends events and pulls policies reads the system store. See [Troubleshooting](/reference/troubleshooting).

That is all. Connecting stores the key and, when the machine has **no** Jev config yet, turns Jev on through FailproofAI Cloud in **shadow** mode: Jev is asked about every gated tool call and its verdicts are recorded, but your policies' result is what is enforced. The output says so:

```text theme={null}
  Jev       on through FailproofAI Cloud, in shadow mode: logged, not enforced (~/.failproofai/jev.json).
```

**With `--no-transcripts`, connecting does not turn Jev on.** Jev sends each checked tool call and the recent prompt to FailproofAI Cloud, which is more than a decisions-only connection asked to send. The key is still stored, and the output says Jev is available and how to switch it on:

```bash theme={null}
failproofai jev setup --provider failproofai
```

It does not turn Jev **off** either. If the machine's `jev.json` already runs Jev through FailproofAI Cloud, it is left as it is, and the output says that Jev still sends each checked tool call and the recent prompt, and that `failproofai jev setup --mode off` switches it off.

<Warning>
  Connecting **never overwrites** an existing `~/.failproofai/jev.json`. If you already use your own Jev endpoint, it keeps being used, and the output says the file was left as configured — and, when that file leaves Jev off (refused, or switched off), says so and how to fix it. To switch that machine to FailproofAI Cloud, run `failproofai jev setup --provider failproofai`.
</Warning>

## Shadow, enforce or off

Start in shadow, watch what Jev would have done on the policy page, then let it act:

```bash theme={null}
failproofai jev setup --mode enforce   # Jev's verdicts apply: it may clear a reviewable deny and add its own
failproofai jev setup --mode shadow    # Jev is asked and logged; your policies' result is enforced
failproofai jev setup --mode off       # keep the config, stop asking Jev
```

The same switch is in the local dashboard: **Settings → Jev** has an on/off switch and shadow/enforce. It rewrites the mode and nothing else. Hooks read the config on every tool call, so a change applies from the next one, with no restart.

## Check what it is doing

```bash theme={null}
failproofai jev status
failproofai jev test
```

`status` shows the provider as **FailproofAI Cloud**, the Cloud host the machine connected to, the mode, and the key source as **FailproofAI Cloud connection**, never the key. When a FailproofAI Cloud `jev.json` is in place but Jev cannot run, it says why:

| `status` says                                                                  | `status --json` | Meaning                                                                                                                                                                                                                                          |
| ------------------------------------------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **off — no Jev key is stored for this machine's FailproofAI Cloud connection** | `key-lacks-jev` | The machine is connected, but no Jev key is stored for it: the key lacks `jev:evaluate`, or the connect could not confirm it. Run `failproofai config --token <key>` again with the same key; if it lacks the permission, use a **machine** key. |
| **off — this machine is not connected to FailproofAI Cloud**                   | `not-connected` | There is no FailproofAI Cloud connection on this machine for the Jev key to belong to.                                                                                                                                                           |

After `failproofai config --disconnect` there is no FailproofAI Cloud `jev.json` any more (unless it was switched off, which is kept), so `status` simply reports Jev as off. `status --json` carries the same facts (`provider: "failproofai"`, `keySource: "cloud"`, `cloudConnected`, `keyCarriesJev`), also when the config is absent or refused. `permissions` is always `jev.json`'s; a refusal about `credentials.json` adds `credentialsPermissions`, and `fix` when one command fixes it. `test` sends one live request and reports its latency and the Jev version that answered. It exits 1, and says so in its title, when the answer arrives after the hook timeout (hooks would record `timeout`) or answers its check question wrongly.

The dashboard's **Settings → Jev** panel also shows the **FailproofAI Cloud connection**: which organization the machine reports into and whether its key carries Jev. It is read from the machine's own files, with no network call.

## What reaches the policy page

The machine already sends its hook activity to FailproofAI Cloud (`events:add`). With Jev on, each gated call's record also says which evaluator ran, what Jev decided, which policies it cleared, why it fell back when it did, its latency and the model that answered — decisions, codes and names, never the command or your prompt. On your organization's **Policies** page:

* a call Jev's own verdict decided (enforce mode) is attributed to **Jev**, and when the deciding check came from a pack, the record also names that pack and its version;
* in shadow mode, Jev's deny or warning appears as a **would-have**, next to the rollouts you are observing;
* the policies Jev cleared, or would have cleared in shadow mode, are counted per policy.

## When Jev cannot answer

Every one of these falls back to your policies' result for that call, and is recorded with its reason:

| Reason                   | Cause                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `out-of-credits`         | Your organization has used its plan allowance.                                                                                                                                                                                                                                                                                                                                                  |
| `http-401`, `http-403`   | The key was revoked, or does not carry `jev:evaluate`. Reconnect with a key that does.                                                                                                                                                                                                                                                                                                          |
| `http-429`               | FailproofAI Cloud is rate-limiting Jev for your organization. Until the wait it asks for is over (its `Retry-After`, at most 60 seconds), the machine sends it nothing and every call falls back straight away. Calls held back that way are recorded as `http-429`, or as `rate-limited` when the machine's own rate limit holds them first.                                                   |
| `http-429` (daily limit) | Your organization has used its daily Jev calls: **10,000 per UTC day**, unless whoever operates your FailproofAI Cloud has set another limit. Every call falls back until the count resets at 00:00 UTC; the machine still asks again at most once a minute, so it picks the reset up within a minute. `failproofai jev test` says "Daily Jev limit for this org reached; resets at 00:00 UTC." |
| `http-422`               | Jev refused this call's request, usually because the tool call held dense text (base64, hex, minified code) over Jev's token budget. That call falls back every time; it is not an outage.                                                                                                                                                                                                      |
| `http-502`               | Jev is unavailable right now.                                                                                                                                                                                                                                                                                                                                                                   |
| `http-503`               | This Cloud cannot serve Jev for your org: no model gateway, an org not provisioned yet, or the gateway is down. Ask your admin; hooks ask again at most once a minute.                                                                                                                                                                                                                          |
| `http-404`               | This FailproofAI Cloud does not serve Jev yet.                                                                                                                                                                                                                                                                                                                                                  |
| `timeout`                | No answer within `timeoutMs` (default 3000).                                                                                                                                                                                                                                                                                                                                                    |
| `model-mismatch`         | A Jev version other than 1.13 answered.                                                                                                                                                                                                                                                                                                                                                         |

## Where the key lives, and where it goes

* The key is stored once, in `~/.failproofai/credentials.json` (`0600`, in an owner-only directory), beside the other FailproofAI Cloud credentials. `jev.json` holds no key for this route; one written there makes the config invalid.
* If `credentials.json` carries **any** permission for anyone but you (group or other, read or write), or its directory can be **written** by anyone but you, it is **refused**, not read, and Jev is off until you fix it: `chmod 600` on the file, `chmod 700` on the directory (or reconnect, which rewrites the file at `0600` and makes the directory owner-only). A directory others can only read is fine; one they can write lets them swap the file.
* The key counts only while the connection it came with is on the machine: a policy or reporting credential for the same FailproofAI Cloud **with the same key**, in the same file. A Jev key left behind without one is ignored, and Jev stays off. That happens when an older failproofai's `config --disconnect` leaves the Jev key in place (it does not know to remove it), or when an older failproofai's `config --token` connects with another key, which on FailproofAI Cloud may belong to another organization. To switch Jev back on, connect again with a **machine** key.
* The key is only ever sent to the Cloud origin it was verified against. A `jev.json` pointing anywhere else is refused.
* **An agent on the machine can read it.** `credentials.json` is owner-only, and the agent runs as that owner. Reading failproofai's own files is allowed on purpose (only changing them is blocked, by `block-failproofai-commands`), so the only thing between an agent and this file is `block-read-outside-cwd` — a *reviewable* policy — and from a session started in your home directory, nothing. A key with `jev:evaluate` spends your organization's Jev allowance (up to the daily cap) from wherever it is used, so treat a machine key like any other spending credential: if an agent may have read it, disable it on the Keys page and reconnect with a new one.
* Only your global files decide this. A repository cannot turn Cloud Jev on, point it elsewhere or supply its key, and `FAILPROOFAI_JEV_API_KEY` is ignored for this route.
* For each call Jev evaluates, one request goes to FailproofAI Cloud, carrying what the [bring-your-own-key page](/policies/jev-byok#what-leaves-the-machine) lists (secrets redacted). FailproofAI Cloud forwards it to TypeSafe and does not log or keep it.

## Turn it off

| Command                            | Outcome                                                                                                                                                                                                                                                                        |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `failproofai jev setup --mode off` | Keep the config; Jev is not asked. **This is the switch that lasts:** connecting again never rewrites an existing `jev.json`, so Jev stays off until you switch it back with `--mode shadow`.                                                                                  |
| `failproofai jev remove`           | Delete `~/.failproofai/jev.json`; Jev is off — until the next `failproofai config --token` with a key that carries `jev:evaluate`, which finds no `jev.json` and turns Jev on again in shadow mode (unless it runs with `--no-transcripts`). To keep it off, use `--mode off`. |
| `failproofai config --disconnect`  | Disconnect the machine: the key is removed, and so is `jev.json` when it names FailproofAI Cloud and is not switched off. A `jev.json` for your own endpoint stays, and so does one switched off, so Jev stays off when you connect again.                                     |

From the next tool call, hooks run the regex policies exactly as before.
