khive-gate 0.9.0

Pluggable authorization gate trait + default AllowAllGate impl for khive verb dispatch.
Documentation
# Gate audit events

`AuditEvent` is the stable record emitted once for each gate consultation, both to structured
tracing and, when configured, to the runtime event store.

## Stable JSON fields

| Field                        | Meaning                                                                  |
| ---------------------------- | ------------------------------------------------------------------------ |
| `timestamp`                  | UTC consultation time, RFC 3339 in JSON                                  |
| `actor`, `namespace`, `verb` | request identity and operation                                           |
| `decision`                   | lowercase `"allow"`, `"deny"`, or `"gate_unavailable"`                   |
| `deny_reason`                | present only for a denial                                                |
| `obligations`                | policy obligations on allow; always `[]` on deny or gate unavailability  |
| `gate_impl`                  | backend name from `Gate::impl_name`                                      |
| `session_id`                 | request-context correlation token when present                           |
| `op_index`                   | zero-based parser position within the request, or `null` when unknown    |
| `ref_resolution`             | `"literal"` or `"resolved"`, or `null` together with an unknown position |

Field names are a public wire contract. Adding a field is compatible; removing or renaming one
requires an architectural compatibility decision. `obligations` is always serialized so non-Rust
consumers never need to distinguish absence from an empty array.

## `AuditEvent::from_check`

The constructor copies actor, namespace, verb, backend name, and optional session ID from the
request, uses the request-context timestamp when supplied (stamping the current UTC time only when it is absent), and projects the decision. Allow carries its obligations and
no deny reason; deny carries its reason and an empty obligation array.

## `AuditEvent::gate_unavailable`

The constructor preserves the request identity, namespace, verb, timestamp, optional session ID,
and gate implementation while recording `decision="gate_unavailable"`, no deny reason, and an
empty obligation array. Runtime dispatch persists this envelope with `EventOutcome::Error` before
returning `RuntimeError::GateUnavailable` without invoking the operation.

## Operation provenance

The composed-request runner supplies both operation fields through a scoped context.
Single operations record index `0`. Batch operations keep their parser position even
when they finish or persist in a different order. A chain operation records `resolved`
only when an argument consumed a `$prev` reference; its first literal operation and
later operations without references record `literal`.

The same fields are persisted as event columns and exposed by event `list` and `get`.
They do not add a filter or change request-group correlation. Historical rows and
non-request producers have no proven parser position: both values are `null`, never
an invented `0`/`literal`. Deserializing an older audit envelope with absent fields
preserves that unknown state. The runtime attaches known provenance after constructing
the gate envelope; direct `from_check` and `gate_unavailable` calls default to unknown.

Events capture provenance before being queued for persistence. Nested awaited work
retains the originating operation; spawned background tasks do not inherit the scope.
Explicitly deferred transactional producers can carry an owned attribution snapshot.
Reusable token-scoped event stores do not retain an operation position between calls.
No argument values or argument digests are added by these fields.