# Policy, tasks and captures

## Captures

A capture is the result of processing one message in one bucket: the fields with value, confidence, raw text and source; the validation result; a status; and the routing reason.

| Status | Meaning |
|---|---|
| `applied` | Policy accepted it. Destinations were notified. |
| `task` | Someone needs to look: a field requires a human, validation failed, a required field is missing, or confidence is below the bucket's threshold. |
| `held` | Reserved for explicit holds. |

## Policy

Tenant-wide defaults (`set_tenant_policy`) and per-bucket overrides (`policy` on the bucket), merged key by key.

```json
{
  "auto_accept": { "min_confidence": 1, "require_complete": true, "require_valid": true },
  "requires_human": ["ship_to"],
  "no_schema": "accept",
  "task_on_unrouted": true,
  "on_flags": { "hidden_text": "task", "external_resource": "accept" },
  "require_passing_tests": true
}
```

- `on_flags` decides what a sanitization flag does to routing. The hidden-text flags (`hidden_text`, `zero_font`, `invisible_color`), `unexpected_sender` and `forwarding_verification` default to `task`; every other flag defaults to `accept`. A held message becomes a `flagged_message` task before anything else is weighed.
- `require_passing_tests` gates schema changes on the bucket's [test suite](/docs/test-suite).

- `requires_human` fields (here or on the schema) always create a task when they carry a value. Confidence never overrides that.
- `min_confidence` applies to every extracted field except constants. Confidence comes from the extractor kind (labelled 1, regex 0.8, mailbox or header 0.5, constant 0.3), halved on a failed transform or coercion. See [Extractors](/docs/extractors).
- `no_schema` decides what happens to messages in a bucket with no schema: accept them, or make a task.

## Tasks

| Kind | Created when |
|---|---|
| `unrouted` | No bucket matched. Subject is the message. |
| `review_capture` | Policy held a capture (validation, completeness, confidence). |
| `field_review` | A `requires_human` field has a value. |
| `flagged_message` | The message carried a sanitization flag the policy holds: hidden text, or `unexpected_sender` on an address with expected forwarders. |
| `forwarding_verification` | A mail provider is asking to confirm a forwarding rule; the code and link are in the payload. |
| `config_change` | A schema change was refused by the test suite. |

Resolve a task with `resolve_task`, or let `approve_capture` resolve the capture's tasks for you.

## Corrections and approval

`correct_field` sets a field on a capture and records a correction (old, new, actor, reason). The capture is re-validated but its status does not change. `approve_capture` (scope `approve`) applies it, resolves its tasks, and delivers. If validation issues other than missing required fields remain, approval fails unless `force` is passed.

Approving never sends email. Sending is a separate capability that unverified tenants do not have.
