> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trysinker.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Lifecycle

> How a Solana transaction moves from enqueue to finalized, and what Sinker tracks at each stage.

## The seven stages

A transaction submitted through Sinker passes through seven distinct stages. Each stage transition is detected from the live Yellowstone gRPC stream and written to the lifecycle log.

```
[enqueued]
    ↓  TPU ingestion at leader (via Jito block engine)
[submitted]
    ↓  Leader includes tx in block; shreds propagate via Turbine
[landed / processed]
    ↓  ≥ 2/3 stake weight votes confirm the block
[confirmed]
    ↓  31+ subsequent blocks are finalized on top of this one
[finalized]
```

<Warning>
  A bundle can receive HTTP 200 from the Jito block engine and still never land. This happens when no jito-solana validator is scheduled as leader in the next \~20 slots. Sinker's background status tracker detects this by polling `getInflightBundleStatuses` and stamps the entry `invalid`.
</Warning>

***

## Lifecycle entry

Every bundle submission produces a `LifecycleEntry` written to `lifecycle.jsonl`. You can read all entries with `sinker.getLifecycle()` or filter to a single transaction with `tx.lifecycle()`.

```ts theme={null}
const entries = await handle.lifecycle();

for (const entry of entries) {
  console.log(entry.bundle_id);
  console.log(entry.stage);            // 'finalized' | 'failed' | ...
  console.log(entry.tip_lamports);
  console.log(entry.confirmed_to_finalized_ms);  // latency delta
  console.log(entry.ai_decision_trace);           // agent's reasoning
}
```

### LifecycleEntry fields

<ResponseField name="bundle_id" type="string">
  Unique identifier assigned by the Jito block engine (or a synthetic ID for
  faulted/errored submissions).
</ResponseField>

<ResponseField name="slot_submitted" type="number">
  The slot at which the bundle was submitted.
</ResponseField>

<ResponseField name="leader" type="string | null">
  The validator identity pubkey scheduled to lead `slot_submitted`.
</ResponseField>

<ResponseField name="tip_lamports" type="number">
  The tip amount included in this bundle attempt, in lamports.
</ResponseField>

<ResponseField name="tip_floor" type="TipSnapshot | null">
  The live Jito floor snapshot captured at submit time (`p50` / `p75` / `p95` / `ema` / `stale`).
</ResponseField>

<ResponseField name="landed_slot" type="number | null">
  The slot the tip transaction was processed in — may drift from `slot_submitted`.
</ResponseField>

<ResponseField name="attempt" type="number">
  Submission attempt number for this bundle (1-based; increments on retry).
</ResponseField>

<ResponseField name="mode" type="string">
  Strategy that produced this bundle: `agent` | `bypass` | `naive`.
</ResponseField>

<ResponseField name="decision_mode" type="'reflex' | 'cortex' | ''">
  The decision tier the agent submitted under. Empty for script / bypass / naive submissions.
  See [AI Agent → Two-tier router](/concepts/agent).
</ResponseField>

<ResponseField name="escalated" type="boolean | null">
  Reflex-only: whether this submission was escalated to the LLM (Cortex). `null` when not in reflex mode.
</ResponseField>

<ResponseField name="submitted_at" type="string">
  ISO 8601 timestamp of submission.
</ResponseField>

<ResponseField name="stage" type="BundleStage">
  Current lifecycle stage: `submitted` | `landed` | `processed` | `confirmed` |
  `finalized` | `failed` | `invalid` | `unknown`
</ResponseField>

<ResponseField name="failure" type="FailureClass | null">
  Structured failure class when `stage` is `failed`. See [Fault Injection](/concepts/fault-injection)
  for the full taxonomy.
</ResponseField>

<ResponseField name="confirmed_to_finalized_ms" type="number | null">
  Wall-clock milliseconds from `confirmed` to `finalized`. Observed values on
  mainnet: \~11,700–13,000 ms (\~29–32 slots) — the protocol's finalization depth.
  (An earlier revision reported \~2.3 s here; that was an instrumentation artifact,
  since fixed — see the lifecycle log notes.)
</ResponseField>

<ResponseField name="ai_decision_trace" type="string | null">
  The AI agent's chain-of-thought for this bundle: tip selection rationale,
  failure pattern analysis, and escalation decisions.
</ResponseField>

<ResponseField name="queued_tx_ids" type="string[]">
  The `tx_id` values from `/tx/enqueue` that were included in this bundle.
</ResponseField>

***

## Commitment levels

| Level       | Slots from tip | Description                                       |
| ----------- | -------------- | ------------------------------------------------- |
| `processed` | 0              | Included in a block. Can reorg.                   |
| `confirmed` | \~2            | Supermajority vote. Reorg rate \<0.1% on mainnet. |
| `finalized` | \~32           | Irreversible under BFT assumption.                |

Sinker uses `confirmed` commitment when fetching blockhashes, giving 148 valid slots (\~59s) vs 118 slots (\~47s) for `finalized`. This is meaningful when targeting a specific 4-slot Jito leader window.

***

## Observed latencies (mainnet-beta)

From real bundle submissions during development:

| Bundle   | submitted → confirmed | confirmed → finalized |
| -------- | --------------------- | --------------------- |
| 160974fe | 11,875ms              | 2,480ms               |
| b9e8b294 | 13,354ms              | 2,355ms               |
| 4359b58d | 13,053ms              | —                     |

Variance in `submitted → confirmed` is primarily driven by leader window alignment at submission time.
