# `Capstan.Xa.Id`
[🔗](https://github.com/baselabs/capstan/blob/v1.3.1/lib/capstan/xa/id.ex#L1)

The value-free identity of an XA transaction (ADR-0006, Rule 1).

`gtrid`/`bqual` are application-chosen bytes — row-value class — so the pool keys on
a **sha256 digest** of the canonical XID frame, and the raw bytes are never stored,
logged, or emitted. Even the digest is never emitted (a digest of a low-entropy
application XID is dictionary-reversible); it exists as the in-memory pool key ONLY.
Telemetry and errors correlate on server-assigned GTIDs, never on anything
XID-derived.

Both XID encodings capstan sees produce the same digest:

  * the `XA_prepare_log_event` (type 38) body — `one_phase` byte, `format_id` /
    `gtrid_length` / `bqual_length` as little-endian u32s, then the raw bytes
    (layout read from the MySQL server source, `control_events.cpp`);
  * the resolution `QUERY` text — `XA COMMIT X'<hex gtrid>',X'<hex bqual>',<format_id>`
    (and `XA ROLLBACK`), the canonical hex-literal form the server writes (captured
    live; `test/fixtures/binlog/xa/`).

# `resolution`

```elixir
@type resolution() :: {:commit | :rollback, t()}
```

A parsed resolution statement: the verb and its XID digest.

# `t`

```elixir
@type t() :: &lt;&lt;_::256&gt;&gt;
```

A parsed XID's value-free identity: the sha256 digest of the canonical frame.

# `xid`

```elixir
@type xid() :: %{
  one_phase: boolean(),
  format_id: non_neg_integer(),
  gtrid: binary(),
  bqual: binary()
}
```

# `digest`

```elixir
@spec digest(xid()) :: t()
```

The digest of a canonical XID. The frame is namespaced and length-prefixed so no
two distinct `{format_id, gtrid, bqual}` triples collide.

# `parse_resolution`

```elixir
@spec parse_resolution(String.t()) :: {:ok, resolution()} | :error
```

Parses an `XA COMMIT`/`XA ROLLBACK` resolution `QUERY` text into its verb + digest.

Accepts exactly the canonical hex-literal form the server writes
(`XA COMMIT X'…',X'…',<format_id>`); a bare `XA COMMIT`-shaped text with no XID
(or any other shape) returns `:error` — the caller treats an unparseable
resolution as unmatched and fails closed, never guesses.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
