
# Approval governance

Ethen's approval framework provides **human-in-the-loop (HITL)** controls for sensitive actions, with configurable policies, risk classification, evidence collection, and audit trails.

## Risk classification

Every tool action is classified into a risk level. Each risk level maps to a user-facing label:

| Risk level | Label | Example actions |
|---|---|---|
| `read_only` | Read Only | Reading files, fetching data |
| `write` / `writes_user_content` | Writes Data | Creating or editing content |
| `external_side_effect` | External Effect | Sending API requests, posting to external services |
| `destructive` | Destructive | Deleting resources, modifying critical state |
| `privileged` | Privileged | Accessing credentials, modifying policies |

## Approval policies

An approval policy (`ApprovalPolicy`) governs when human approval is required:

| Policy field | Description |
|---|---|
| `name` | Human-readable policy name |
| `description` | Policy summary |
| `riskThreshold` | Actions at or above this risk level require approval |
| `requireApprovalFor` | Specific risk levels that always require approval |
| `blockActions` | Risk levels that are blocked outright |
| `autoExecuteRiskLevels` | Risk levels that may auto-execute without approval |
| `maxAutoExecuteCount` | Maximum auto-executions before approval is required |
| `requireJustification` | Whether a justification is required |
| `escalationContact` | Contact for escalation when approval is needed |

## Approval lifecycle

An approval request progresses through these states:

```text
draft → pending → approved → executed
         ↓          ↓
      rejected   cancelled
         ↓
      expired / stale / blocked
```

| Status | Description |
|---|---|
| `draft` | Proposal created but not yet submitted for review |
| `pending` | Awaiting human decision |
| `approved` | Human approved the action |
| `rejected` | Human rejected the action |
| `cancelled` | The request was cancelled before resolution |
| `expired` | The request's expiry time passed without a decision |
| `blocked` | Policy prohibits the action |
| `stale` | The request's payload hash no longer matches the current state |

## Decision types

A human reviewer can submit one of four decision types:

| Decision | Effect |
|---|---|
| `approve` | Approves the action for execution |
| `reject` | Rejects the action |
| `escalate` | Forwards the decision to the escalation contact |
| `defer` | Delays the decision |

Each decision is recorded with the actor's identity (ID, name, role), an optional comment, and a timestamp.

## Payload hash binding

When an approval request includes a `payloadHash` (SHA-256 of the approved content), the system can detect if the underlying payload has changed since approval. A status of `stale` indicates the payload no longer matches the hash — the request must be re-submitted.

## Evidence package

An approval request can carry an **evidence package** — a set of supporting materials for the reviewer:

| Evidence field | Description |
|---|---|
| `label` | Human-readable label |
| `contentUrl` | URL to full evidence content (nullable) |
| `summary` | Plain-English summary of what was observed |
| `confidence` | Confidence level (`high`, `medium`, `low`) |
| `sourceName` | Origin of the evidence |
| `freshness` | How current the evidence is (ISO timestamp, nullable) |
| `verified` | Whether the evidence has been independently verified |

## Audit trail

Every event in the approval lifecycle produces an `ApprovalAuditRecord`:

| Audit event | Description |
|---|---|
| `created` | Approval request was created |
| `submitted` | Request was submitted for review |
| `decided` | A decision was recorded |
| `escalated` | The request was escalated |
| `expired` | The request expired |
| `cancelled` | The request was cancelled |

Each audit record includes the actor identity (when applicable), a detail string, and references to evidence items.

## Review-required statements

The following aspects of the approval governance framework have not been independently verified:

- Policy enforcement boundaries: the actual enforcement of `blockActions` and `autoExecuteRiskLevels` depends on the runtime environment and has not undergone independent penetration testing.
- Evidence package confidence scoring: the `confidence` field reflects heuristic classification and is not a certified accuracy metric.

## See also

- [Enterprise controls](/docs/enterprise/enterprise-controls)
- [Security overview](/docs/security/overview)
- [Evidence and audit](/docs/security/evidence-and-audit)
