failproofai jev setup), every tool call is judged twice: by the policies you run, and by Jev, which asks what the call actually does and whether the person who typed the task asked for it. Each policy’s authority decides what happens when the two disagree.
Without Jev configured, authority has no effect. Every policy enforces exactly as it always has.
Hard and reviewable
- Hard is the default. A hard policy’s deny or instruction is final: Jev cannot clear it, and a hard deny stops the call without waiting for Jev.
- Reviewable means Jev may clear the policy’s verdict, but only through the semantic checks the policy names in
reviewedBy. The verdict is cleared only when every named check was asked about this call and each one either found nothing or recorded the user asking for this. A check that fired — found the concern — without the user asking keeps the block, even when its own verdict is only a warning. A check Jev was not asked, because it does not apply to that tool, never clears anything, whatever the others said. One softening counts as consent: when the call is a step of the task the user gave and reaches no further, Jev turns a deny into a warning, and that warning clears the policy’s block and is what the agent is told.
- It declares
authority: "reviewable". reviewedByis a non-empty list, and every entry is a semantic check this machine can ask: one of the built-in checks, or one an installed pack declares. A pack installed from a FailproofAI repository that declares checks of its own replaces the built-in ones, and then only the packs’ checks count.- It is not
alwaysOn. The guard that stops an agent from disabling Failproof AI is always hard.
reviewedBy, or a name that is not a check this machine can ask. An unknown name makes the whole declaration hard rather than being skipped, because reviewedBy means “all of these must be asked, and none of them may deny”, and skipping a name would let Jev clear the policy on fewer checks than you asked for.
Once Jev is configured, Failproof AI logs a warning when it refuses a reviewable declaration, once per process. Without Jev it says nothing, because authority then decides nothing. failproofai publish refuses to build a pack that carries such a declaration, so a pack author finds out before anyone installs it. It judges reviewedBy against the checks the pack declares when it declares any, and against the built-in checks otherwise.
Where authority is declared
Each way a policy reaches a machine has one place that decides its authority:
For a pack or a cloud-managed policy, fields set inside the policy code are ignored; the manifest or the assignment decides. A pack can only describe its own policies: its policy names cannot contain
/ and are registered under the pack’s own prefix, so no manifest can mark a built-in policy or another pack’s policy as reviewable. A policy a pack’s code registers without declaring it in the manifest is hard.
Two packs, or two cloud-managed policies, whose code is byte-identical share one artifact and load as one policy. That policy is reviewable only if every one of them declares it reviewable, and Jev must then clear every check any of them names. If any of them declares it hard, or does not declare it at all, it stays hard. The order the packs or policies are listed in never matters.
Most machines get the built-in policies from the FailproofAI/policies pack, and read their authority from that pack’s manifest. The reviewable entries below take effect once a release of the pack that carries them is installed; an older release carries none, so every policy in it stays hard.
Declare authority in your own policy
failproofai publish copies both fields into the pack manifest, so a policy published as a pack keeps the authority its author gave it. It refuses to build the pack if a declaration would not be honored: a value other than "hard" or "reviewable", a reviewedBy that is not a list of names, or a name that is not a check — one of the pack’s own Jev checks when it declares any, a built-in check otherwise.
Built-in policies
Reviewable only where a semantic policy genuinely covers the same concern. Every other built-in policy is hard. Covering the concern is necessary but not sufficient, and both ways of getting it wrong are quiet:- A check that is never asked makes the block permanent.
reviewedByis a conjunction and a check that was not asked never clears, so a policy paired with a check whose precondition does not fire for the shapes the policy matches can never be cleared at all. - A check that is asked but does not fire answers “no concern”, and no concern clears. So pairing with a check that does not model your policy’s shapes does not review the policy — it switches it off for exactly the inputs the check does not understand.
push-to-protected-branch, commit-on-protected-branch, read-outside-workspace, system-modification, env-secrets-dump and external-data-egress — and the table below gives every check’s mode. The question to ask is “is there anything left that can deny”: a clear must never leave the concern enforced by nothing. The engine applies that test per call. A warning nobody consented to is not a clear, because before tool calls a warning does not stop the agent. And when a check that can deny warns — its evidence fell short of its deny line — and the user did not ask for the call, nothing is cleared on that call and every regex deny stands.
Semantic policy names
These are the built-in checks, and the valuesreviewedBy accepts unless a pack installed from a FailproofAI repository declares Jev checks of its own. Each is a check Jev answers about the tool call in front of it. Mode is what a check can answer: a deny check blocks on strong evidence, while an instruct check only ever warns. Either keeps a policy’s deny standing when it fires and the user did not ask for the call. User can override says whether the human’s own explicit request clears it.
A pack’s Jev checks are added to this list, and their names join the ones reviewedBy accepts. A pack installed from a FailproofAI repository instead replaces this list: its checks are then the only ones Jev asks and the only names reviewedBy accepts, so a policy naming a check below that it does not declare stays hard. FailproofAI/jev-policies declares these same sixteen, so with it the table still applies. A name two packs declare differently is honoured for neither. One of these sixteen names declared by a pack not installed from a FailproofAI repository is ignored in that pack: its version is never asked and does not contest FailproofAI’s own, so a third-party pack can neither become the check that clears the core pack’s policies nor switch one of these checks off. A pack whose every check is unusable leaves this list in force.

