# Authority contract

The single question this answers: **when the agent acts, what is it allowed to
touch, and how would you know if it crossed the line?**

Fill one of these per deployment. It is a working file, not documentation —
`hermes-agent-os validate` reads it, and the gates in `04-gates/` refuse a
release when it is missing or incoherent.

---

## Why written-down authority beats configured authority

Configuration says what the agent *can* reach. The contract says what it *may*
reach. The two drift apart the moment someone widens a scope to unblock a
release, and the config alone cannot tell you which widenings were deliberate.

The failure this prevents is not the agent going rogue. It is far more ordinary:
a credential scoped wider than the task, kept because narrowing it would have
meant another hour, and then inherited by every later task.

---

## The contract

```yaml
deployment: <name>            # one Hermes deployment, not a fleet
owner: <human>                # the person who answers for it
reviewed: <YYYY-MM-DD>        # re-read this when it goes stale

filesystem:
  may_read:   []              # explicit paths. no bare "/" or "~"
  may_write:  []              # narrower than may_read, always
  never:      []              # credential stores, key material, other repos

network:
  egress: deny                # deny | allowlist
  allowlist: []               # exact hosts. no wildcards on a first pass

credentials:
  scope: <task | session | standing>
  # standing credentials are the thing you are trying to avoid.
  # if scope is standing, state why on the next line.
  justification: ""

tools:
  enabled:  []                # least privilege beats convenience here
  requires_human: []          # tools that may be invoked but not completed

data:
  may_process: []             # classes, not examples
  never_process: []           # PII, customer data, secrets, production dumps

escalation:
  on_boundary_hit: <halt | prompt | log_and_continue>
  # halt is the default. log_and_continue means you find out later, in a log
  # nobody reads, which is the same as not finding out.
```

---

## Filling it in

**Start from `never`, not from `may`.** Listing what the agent must never touch
is faster and less negotiable than enumerating what it may. The allow-list then
falls out of the task instead of out of ambition.

**`may_write` is always narrower than `may_read`.** If they are equal, the
contract has not been thought about. Reading a config to decide something is a
different act from rewriting it.

**A standing credential needs a sentence.** Not a policy exception — a sentence
naming who decided and what it unblocked. Most standing credentials cannot
survive being written down next to their reason.

**`log_and_continue` is a decision to find out later.** Occasionally correct, for
a low-stakes deployment where halting costs more than the boundary protects. Say
so in the contract rather than choosing it by default.

---

## Reviewing it

Re-read the contract when any of these happen, not on a calendar:

- a boundary was hit, whatever the escalation did
- a tool was added or a scope widened
- a Hermes minor version landed that changed defaults
- the owner changed

A contract nobody has re-read since the deployment was built describes the
deployment as it was imagined, not as it runs.
