> For AI agents: the documentation index is at https://docs.umbraprivacy.com/llms.txt, and every page is available as Markdown at its URL with .md appended.

# Versions (/docs/architecture/versions)

Every Umbra instruction carries a version, and every account records its layout version. A program refuses an instruction whose version it does not serve, so a change of format never silently means something else.

## Instructions

Every instruction starts with the same envelope: a one-byte tag that names the instruction, a two-byte version, then the payload. The chart below shows how a program handles one.

```mermaid
flowchart LR
I["Instruction"] --> K{"Tag and version"}
K -->|"both served"| H["Handler runs"]
K -->|"known tag, other version"| V["Refused: unsupported version"]
K -->|"unknown tag"| U["Refused: unknown instruction"]
```

*How a program dispatches an instruction on its tag and version together.*

A program matches the tag and the version as a pair. Only a pair it serves reaches a handler, and the handler then requires the payload to be exactly its expected length. A known tag at any other version is refused with an error of its own, distinct from an unknown tag, so a client can tell that it is out of date rather than wrong. When an instruction's payload or account list changes, its version goes up and the old version stops being served. The programs built for the mainnet addresses start every instruction at version 0, the value instruction included.

Every version an instruction has had at a program's address, current and retired, is recorded in the repository's ABI ledger. The indexer's decoder is built from that ledger, so it can still read transactions made under a version the program no longer accepts. A program at a new address starts a new ledger, and the indexer archives only the programs at the mainnet addresses.

## Accounts

Every account starts with the same five-byte header, which records the account's status, its layout version and the bump of its program-derived address. A reader checks the layout version before it trusts any of the account's other fields. A program reading another program's account does the same: the shielded pool, for instance, refuses a guardian cluster account whose version is not the one it was built against. When an account's layout changes, its version goes up, so a reader built for the old layout refuses the new one instead of misreading it. Every account of the programs built for the mainnet addresses starts at layout version 0.

## Generated, not hand-written

The instruction tables on this site are read at build time from the manifests the repository generates from each program's source, never typed by hand. The shielded pool's is in the [reference](#reference) below. Every other program's is in the reference section of [on-chain programs](https://docs.umbraprivacy.com/docs/architecture/programs).

## Reference

**Shielded pool instructions**

| Tag  | Instruction                           | Version | Payload bytes | Accounts |
| ---- | ------------------------------------- | ------- | ------------- | -------- |
| `0`  | `register`                            | v0      | 306           | 6        |
| `1`  | `vault_initialize`                    | v0      | 0             | 7        |
| `2`  | `initialize_submitter_tip_accrual`    | v0      | 32            | 5        |
| `3`  | `claim_submitter_tip`                 | v0      | 1             | 7        |
| `4`  | `process_policy_set`                  | v0      | 80            | 6        |
| `5`  | `initialize_commitment_tree`          | v0      | 2             | 3        |
| `6`  | `initialize_identity_tree`            | v0      | 2             | 3        |
| `7`  | `initialize_nullifier_turnstile`      | v0      | 2             | 3        |
| `8`  | `registration_turnstile_initialize`   | v0      | 2             | 3        |
| `9`  | `resize_turnstile`                    | v0      | 2             | 3        |
| `10` | `finalize_nullifier_turnstile`        | v0      | 2             | 2        |
| `11` | `finalize_registration_turnstile`     | v0      | 2             | 2        |
| `12` | `forester_commit`                     | v0      | 290           | 1        |
| `13` | `registration_forester_commit`        | v0      | 290           | 1        |
| `14` | `governance_initialize`               | v0      | 41            | 4        |
| `15` | `governance_propose`                  | v0      | 33            | 5        |
| `16` | `governance_cancel`                   | v0      | 0             | 4        |
| `17` | `initialize_fee_commitment_tree`      | v0      | 2             | 3        |
| `18` | `initialize_fee_turnstile`            | v0      | 2             | 3        |
| `19` | `finalize_fee_turnstile`              | v0      | 2             | 2        |
| `20` | `fee_forester_commit`                 | v0      | 290           | 1        |
| `21` | `execute_reassign_authority`          | v0      | 41            | 5        |
| `22` | `treasury_payout_address_set`         | v0      | 64            | 6        |
| `23` | `claim_fee_20`                        | v0      | 792           | 9        |
| `24` | `process_3x3x2x2`                     | v0      | 798           | 39       |
| `25` | `escape_hatch`                        | v0      | 329           | 15       |
| `26` | `initialize_escape_hatch_fee_accrual` | v0      | 2             | 5        |
| `27` | `claim_escape_hatch_fee`              | v0      | 3             | 8        |
| `28` | `mint_allowance_grant`                | v0      | 32            | 6        |
| `29` | `mint_allowance_revoke`               | v0      | 32            | 6        |
| `30` | `propose_reassign_authority`          | v0      | 41            | 6        |
| `31` | `committee_key_create`                | v0      | 12            | 7        |
| `32` | `committee_key_refresh`               | v0      | 0             | 5        |
| `33` | `insert_fee_commitments`              | v0      | 2             | 1        |
| `34` | `finalize_fee_commitment_tree`        | v0      | 2             | 2        |
| `35` | `lamport_vault_initialize`            | v0      | 0             | 3        |
| `36` | `release_escape_escrow`               | v0      | 0             | 6        |
| `37` | `finalize_commitment_tree`            | v0      | 2             | 2        |
| `38` | `finalize_identity_tree`              | v0      | 2             | 2        |

Read at build time from `contracts/solana/tools/umbra-manifest/manifest/shielded-pool.json`.

## Related

- [On-chain programs](https://docs.umbraprivacy.com/docs/architecture/programs): All eight programs and their instructions.
- [Changelog](https://docs.umbraprivacy.com/docs/resources/changelog): What has changed in the protocol.


Last updated 12 October 2026
