---
url: https://hanria.ai/blogs/how-to-write-a-mandate/
canonical: https://hanria.ai/blogs/how-to-write-a-mandate/
site: HANRIA
---

# How to write an agent mandate: denials first, expiry, requires_human

This is not enforcement. A checked mandate does not stop an action. Only a runtime that exclusively controls the protected tool or credential could refuse it.

HANRIA is a coined name. No expansion, derivation, or translation is published or intended. A U.S. trademark application is pending; no registration or completed clearance is claimed.

## Three rules that actually restrict

1. **Denials first.** Clauses are first-match-wins. A denial written after a broader permit never runs. It reads as though it applies and does nothing. The checker refuses a mandate where a later denial is unreachable.

1. **Set `not_valid_after`.** An unbounded mandate lets delegated authority outlive the task it was granted for. After that timestamp every action is denied.

1. **List `requires_human`.** Typical kinds: `credential_use`, `transaction`, `administrative`. That list turns a permitting clause into an escalation. A ceiling narrows what may be asked for. It does not remove the person.

## What does not restrict

Prose in `purpose`, a clause `note`, or a request `justification` is for whoever reviews this later. Only structured `match` conditions decide. Writing "never touch payroll" in `purpose` and not as a clause restricts nothing.

The mandate `default` must be `deny` or `escalate`. `permit` by default cannot express a limit.

Prefix matching is literal. It does not resolve symlinks. Directory prefixes end in `/`. Write `/srv/tickets/`, not `/srv/tickets`.

## A worked shape

Deny secrets and home paths first. Then permit a narrow read. Then permit a narrow write or post. Keep `transaction` in `requires_human` even if you also write a refund ceiling.

The skill includes an example mandate that exercises permit, deny, escalate, and a shadowed-denial file that is supposed to be refused.

## Entry

Use the free hosted check, which runs the evaluator and keeps no request content: MCP `https://check.hanria.ai/v1/mcp` or HTTP `https://check.hanria.ai/v1/check`. Schemas and examples: [hanria.ai/developers](https://hanria.ai/developers/).

Developers: https://hanria.dev/ Boundaries: [https://hanria.ai/boundaries/](https://hanria.ai/boundaries/)

## Honest verdict

Write the grant as clauses, not as hopes in a paragraph. Do not treat the skill as a lock. It checks and records, but it never holds the tool or credential.
