# Julia-DID Chialisp Code Reference

This document is a reference for the shipped Chialisp source. For the protocol-level design, see **[did:julia Technical Specification (Doc #15)](http://doc_15_did_julia_specification.md)**.

The Chialisp tree contains 27 production/build puzzle files (`.clsp`), 9 shared library files (`.clib`), two precompiled Chia singleton hex files, and a Makefile.

All source paths below are relative to the public Chialisp repository root.

---

## 1. Codebase Organization

### 1.1 Build Order

The repository includes a Makefile that builds the puzzles in the correct order. This matters because many puzzles embed compiled hashes of other puzzles with `embed-file`; a parent puzzle cannot be compiled until the child puzzle hashes it embeds already exist.

That is the only build rule this reference relies on: use the Makefile rather than compiling files by hand in arbitrary order.

### 1.2 How DID Spends Route

The main DID singleton puzzle, `julia_did.clsp`, is the first puzzle run for a DID spend. After checking the DID state hash and lineage, it routes to one of seven top-level entrypoints:

| Entrypoint | Route type | What it does |
|------------|------------|--------------|
| `singlesig.clsp` | Normal authentication | Authenticates one key, then calls an allowed operation |
| `multisig.clsp` | Normal authentication | Authenticates a multi-class signer set, then calls an allowed operation |
| `custody_minion.clsp` | Normal authentication by custodian DID | Requires a custodian DID command, then calls an allowed operation |
| `recovery_initiate.clsp` | Direct recovery entrypoint | Starts a pending assisted recovery |
| `recovery_cancel.clsp` | Direct recovery entrypoint | Cancels a pending assisted recovery |
| `recovery_complete.clsp` | Direct recovery entrypoint | Completes an assisted recovery |
| `recovery_prerotation.clsp` | Direct recovery entrypoint | Switches to pre-rotated keys |

Normal authentication entrypoints can call two kinds of child operations:

- combineable operations, which can continue to another child puzzle
- standalone operations, which perform one action and stop

### 1.3 Combineable Operations

The combineable operations have a required invocation order:

```text
sign_message
  -> coin_control
    -> invalidate
      -> DIDdoc_announce
        -> pass_thru
          -> present_delegated
            -> present_claims
```

Any combineable operation can be skipped. For example, authenticated callers can call `present_claims` directly; `sign_message` can call `present_claims` directly; `DIDdoc_announce` can call `present_delegated` directly. The chain above shows the order when all combineable operations are used together.

Each wrapper prepends its own conditions before passing through child conditions:

| Puzzle | Adds |
|--------|------|
| `sign_message.clsp` | signed-message, timestamp, and nonce announcements |
| `coin_control.clsp` | `JDIDP` command messages to other coins |
| `invalidate.clsp` | impossible spend condition and optional time bounds |
| `DIDdoc_announce.clsp` | DID document pointer announcement |
| `pass_thru.clsp` | guarded arbitrary caller-supplied conditions |
| `present_delegated.clsp` | delegated-claim assertions and presentation announcement |
| `present_claims.clsp` | direct credential presentation announcements and claim validation conditions |

### 1.4 Standalone DID Operations

These operations are called individually by an authentication entrypoint and do not continue into the wrapper chain.

| Puzzle | Allowed caller | Purpose |
|--------|----------------|---------|
| `custodian.clsp` | `singlesig`, `multisig` | Sends a command from a custodian DID to a minion DID |
| `DIDdoc_set.clsp` | `singlesig`, `multisig`, `custody_minion` | Updates the DID Document pointer |
| `issuer_key_control.clsp` | `singlesig`, `multisig`, `custody_minion` | Sends revocation-update or melt commands to issuer key singletons |
| `launch_issuer_key.clsp` | `singlesig`, `multisig`, `custody_minion` | Launches issuer key singletons |
| `rekey.clsp` | `singlesig`, `multisig` | Replaces the DID authentication configuration |
| `recovery_authorize.clsp` | `singlesig`, `multisig` | Sends a recovery initiation or cancellation authorization message from a recovery-agent DID |

### 1.5 Recovery Paths

Recovery has two distinct call patterns. Four recovery puzzles are direct entrypoints selected by `julia_did.clsp`, bypassing normal authentication. `recovery_authorize.clsp` is different: it is a standalone operation called by the recovery-agent DID through `singlesig` or `multisig`.

| Recovery puzzle | Called by | Requires | Effect |
|-----------------|-----------|----------|--------|
| `recovery_initiate.clsp` | `julia_did` directly | Recovery-agent quorum messages and no active recovery | Starts pending recovery and records replacement state |
| `recovery_cancel.clsp` | `julia_did` directly | Recovery-agent quorum messages and active recovery | Clears pending recovery |
| `recovery_complete.clsp` | `julia_did` directly | Active recovery and elapsed relative height | Applies replacement state; anyone can complete once mature |
| `recovery_prerotation.clsp` | `julia_did` directly | Signatures from pre-rotated keys | Switches to pre-rotated keys and commits the next prerotation |
| `recovery_authorize.clsp` | `singlesig` or `multisig` | Current control of a recovery-agent DID | Sends an initiation or cancellation authorization message to another DID |

### 1.6 Issuer Key and Companion Coin Interactions

Issuer key singletons are separate from the DID singleton:

- `launch_issuer_key.clsp` is a DID operation that creates issuer key singleton launchers.
- `issuer_key.clsp` is the issuer key singleton puzzle.
- `issuer_key_functions.clsp` implements issuer key management modes for revocation updates and melt.
- `issuer_key_control.clsp` is the DID-side operation that sends commands to issuer key singletons.

Companion coin puzzles are not DID sub-puzzles:

- `p2_JDID.clsp` is used as an inner puzzle for coins controlled by a DID. It spends only when it receives a `JDIDP` command from the owning DID.
- `p2_claim.clsp` is used as an inner puzzle for coins controlled by a qualifying credential presentation and a DID command.
- `faucet_coin.clsp` is an independent faucet puzzle and is not part of the DID call graph.

### 1.7 Common Return Convention

Most sub-puzzles are called with:

```clojure
(curried-args solution)
```

They return:

```clojure
(updated-curried-args conditions)
```

The top-level `julia_did.clsp` consumes that return value, creates the next singleton generation with the updated curried-args hash, and emits the returned conditions. Leaf operations that do not change DID state return the original `curried-args`.

### 1.8 DID Curried Arguments

The DID singleton state is passed through the codebase as `curried-args`:

| Position | Field | Purpose |
|---:|------|---------|
| 1 | `julia-DID-puzzlehash` | Hash of the raw `julia_did.clsp` puzzle |
| 2 | `my-launcher-id` | Permanent DID identifier |
| 3 | `recovery-timeout-block` / `recovery-delay` | `0` when no recovery is pending; nonzero during recovery |
| 4 | `multisig-info` | Authentication tree and class quorum configuration |
| 5 | `valid-custodian-DIDs` | DID launcher IDs authorized as custodians |
| 6 | `recovery-info` | Recovery agent and prerotation configuration |
| 7 | `DID-doc` | DataLayer singleton launcher ID for the DID Document |
| 8 | pending recovery parameters | Present only while recovery is active or where a token-consuming puzzle appends a marker |

`julia_did.clsp` and `issuer_key.clsp` are curried with `CURRIED-ARGS-HASH`, not the full state. The full state is revealed in the solution and checked with `sha256tree`.

### 1.9 Chialisp Conventions

- Most files include `*standard-cl-26*`.
- Uppercase names in a `mod` signature are curried parameters; lowercase names are solution parameters.
- `embed-file` imports compiled puzzle hashes, not source.
- Bare `(x <code>)` expressions raise integer errors.
- `AGG_SIG_PUZZLE` and `ASSERT_MY_PUZZLEHASH` are used in normal singleton spends for fast-forward-compatible authorization.
- `ASSERT_MY_PARENT_ID` appears in eve spends, where the launcher relationship is being established.

---

## 2. Puzzle Reference

### 2.1 Top-Level and Companion Puzzles

#### `julia_did.clsp`

Main DID singleton puzzle.

**Mod signature:** `(CURRIED-ARGS-HASH curried-args parent-info solution)`

**State input:** Verifies `CURRIED-ARGS-HASH == sha256tree(curried-args)`.

**Regular spend behavior:**

- Destructures the DID curried args.
- Confirms `launcher-coin-id == my-launcher-id`.
- Computes valid entrypoint hashes for `singlesig`, `multisig`, `custody_minion`, `recovery_initiate`, `recovery_cancel`, `recovery_complete`, and `recovery_prerotation`.
- Runs the selected entrypoint through `puzzle-selector`.
- Emits `ASSERT_MY_PUZZLEHASH`.
- Creates the next DID singleton child with `julia-DID-curried-puzzlehash(julia-DID-puzzlehash, sha256tree(new-curried-args))`.
- Emits `REMARK new-curried-args`.
- Appends child conditions returned by the entrypoint.

**Eve spend behavior:**

- Asserts the singleton launcher as parent with `ASSERT_MY_PARENT_ID`.
- Creates the first DID singleton child.
- Emits `REMARK curried-args`.
- Sends `JDIDL` to the prelauncher coin.

**Errors:** `15` failed lineage proof; `16` invalid curried args hash.

#### `prelauncher.clsp`

Prelauncher for Julia DID coins and root of the fast-forward lineage proof.

**Mod signature:** `(PUBKEY julia-did-puzzlehash my-coin-id did-coin-curried-args-hash)`

**Conditions emitted:**

- `ASSERT_MY_COIN_ID my-coin-id`
- `CREATE_COIN singleton_launcher 1`
- `RECEIVE_MESSAGE 0x3F "JDIDL" did-coin-id`

The puzzle is curried with `PUBKEY`; the remaining values are solution parameters.

#### `p2_JDID.clsp`

Inner puzzle for coins owned by a Julia DID.

**Mod signature:** `(JDID_LAUNCHER_ID JDID-curried-args-hash conditions)`

**Behavior:**

- Computes the owning DID coin puzzle hash from `julia_did.clsp.hash.bin`, the DID launcher ID, and the DID curried-args hash.
- Requires `RECEIVE_MESSAGE 0x17 (concat "JDIDP" (sha256tree conditions)) <owning-DID-puzzlehash>`.
- Emits the supplied `conditions`.

This puzzle does not validate the business meaning of the emitted conditions; it trusts the owning DID's authenticated `coin_control` path.

#### `p2_claim.clsp`

Inner puzzle for coins controlled by possession of a valid credential claim.

**Mod signature:** `(JDID_LAUNCHER_ID my-coin-id spender-launcher-id spender-curried-args-hash conditions)`

**Behavior:**

- Asserts its own coin ID.
- Computes the spender DID puzzle hash.
- Requires an asserted puzzle announcement from the spender DID proving a `JDIDV` claim for the hardcoded payment property `sha256("cleartext://./.julia-payment")`, this coin ID, and the payee DID launcher ID.
- Requires `RECEIVE_MESSAGE 0x17 (concat "JDIDP" (sha256tree conditions)) <spender-DID-puzzlehash>`.
- Emits the supplied `conditions`.

#### `faucet_coin.clsp`

Simple faucet coin puzzle used by the Julia Social faucet.

**Mod signature:** `(PUBKEY SERIAL conditions)`

`SERIAL` allows multiple otherwise-identical faucet coins to be created. The puzzle emits the supplied `conditions` only when authorized by:

```clojure
(AGG_SIG_ME PUBKEY (sha256tree conditions))
```

Unlike the DID puzzles, this puzzle uses `AGG_SIG_ME`, binding authorization to the specific coin spend.

---

### 2.2 Authentication Entry Points

#### `singlesig.clsp`

Single-key authentication entrypoint.

**Mod signature:** `(curried-args solution)`

**Solution shape:** `fee-coin`, one pubkey Merkle path, sides, and child puzzle input.

**Validation:**

- DID must require exactly one class.
- Exactly one pubkey path must be supplied.
- The path must validate against `multisig-info`.
- The selected class must require exactly one member.
- Recovery must not be active.

**Conditions added:**

- `AGG_SIG_PUZZLE <pubkey> (sha256tree solution)`
- Optional `ASSERT_CONCURRENT_SPEND fee-coin`

**Allowed children:** `sign_message`, `coin_control`, `custodian`, `DIDdoc_announce`, `DIDdoc_set`, `invalidate`, `issuer_key_control`, `launch_issuer_key`, `pass_thru`, `present_claims`, `present_delegated`, `rekey`, `recovery_authorize`.

**Errors:** `30`, `31`, `32`, `33`, `34`, plus `110` from `puzzle-selector`.

#### `multisig.clsp`

Multi-signer, multi-class authentication entrypoint.

**Mod signature:** `(curried-args solution)`

**Solution shape:** `fee-coin`, participant Merkle paths, path sides, and child puzzle input.

**Validation:**

- Uses `multiclass` to validate participants against `multisig-info`.
- Recovery must not be active.
- Child puzzle hash must be in the allowlist.

**Conditions added:**

- One `AGG_SIG_PUZZLE <pubkey> (sha256tree solution)` per validated participant.
- Optional `ASSERT_CONCURRENT_SPEND fee-coin`.

**Allowed children:** Same as `singlesig.clsp`.

**Errors:** `17`, plus `103`-`106` from `multiclass` and `110` from `puzzle-selector`.

#### `custody_minion.clsp`

Authentication entrypoint for DIDs controlled by an external custodian DID.

**Mod signature:** `(curried-args solution)`

**Solution shape:** custodian DID launcher ID, custodian curried-args hash, and child puzzle input.

**Validation:**

- The custodian DID must appear in `valid-custodian-DIDs`.
- Recovery must not be active.
- Requires `RECEIVE_MESSAGE 0x12 (concat "JDIDC" child-solution-hash) <custodian-DID-puzzlehash>`.
- Asserts this minion DID's current puzzle hash.

**Allowed children:** `sign_message`, `coin_control`, `DIDdoc_announce`, `DIDdoc_set`, `invalidate`, `issuer_key_control`, `launch_issuer_key`, `pass_thru`, `present_claims`, `present_delegated`.

**Errors:** `5`, `6`, plus `110` from `puzzle-selector`.

---

### 2.3 DID Operation Puzzles

#### `sign_message.clsp`

Adds DID-signed message announcements, timestamps, and nonces, then optionally delegates.

**Mod signature:** `(curried-args solution)`

**Solution shape:** messages list, datetime, nonce, optional child puzzle input.

**Conditions added:**

- One `CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDM" message)` per message.
- Optional `CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDT" datetime)`.
- Optional `CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDN" nonce)`.

**Allowed children:** `coin_control`, `DIDdoc_announce`, `invalidate`, `pass_thru`, `present_claims`, `present_delegated`.

**Errors:** `110` for invalid child.

#### `coin_control.clsp`

Sends DID-authorized command messages to other coins.

**Mod signature:** `(curried-args solution)`

**Solution shape:** count, `count` pairs of message and coin ID, then optional child puzzle input.

For each pair, emits:

```clojure
(SEND_MESSAGE 0x17 (concat "JDIDP" message) coin-id)
```

The code does not check whether the receiving coin uses `p2_JDID` or `p2_claim`; it only emits the command message.

**Allowed children:** `DIDdoc_announce`, `invalidate`, `pass_thru`, `present_claims`, `present_delegated`.

**Errors:** `110` for invalid child.

#### `invalidate.clsp`

Adds conditions that make a spend bundle unusable on-chain while preserving verifiability.

**Mod signature:** `(curried-args solution)`

**Solution shape:** `invalidate-flag`, `valid-from-seconds`, `valid-to-seconds`, optional child puzzle input.

**Conditions added:**

- If `invalidate-flag` is truthy: `ASSERT_CONCURRENT_SPEND` on the all-zero coin ID.
- If `valid-from-seconds` is set: `ASSERT_SECONDS_ABSOLUTE`.
- If `valid-to-seconds` is set: `ASSERT_BEFORE_SECONDS_ABSOLUTE`.

**Allowed children:** `DIDdoc_announce`, `pass_thru`, `present_claims`, `present_delegated`.

**Errors:** `110` for invalid child.

#### `DIDdoc_announce.clsp`

Announces the DataLayer singleton ID associated with the DID Document.

**Mod signature:** `(curried-args solution)`

**Condition added:**

```clojure
(CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDD" DID-doc))
```

**Allowed children:** `pass_thru`, `present_claims`, `present_delegated`.

**Errors:** `110` for invalid child.

#### `DIDdoc_set.clsp`

Updates the DID Document pointer.

**Mod signature:** `(curried-args solution)`

**Solution shape:** `new-DID-doc`.

**State change:** Replaces the `DID-doc` field in `curried-args`.

**Conditions added:** none.

#### `pass_thru.clsp`

Allows arbitrary caller-supplied conditions after guarding the `JDID` namespace.

**Mod signature:** `(curried-args solution)`

**Solution shape:** count, `count` conditions, optional child puzzle input.

**Validation:**

- Rejects structured coin/puzzle announcements.
- Rejects coin/puzzle announcements whose byte content starts with `JDID`.
- Rejects structured `SEND_MESSAGE` payloads.
- Rejects `SEND_MESSAGE` payloads whose byte content starts with `JDID`.

**Allowed children:** `present_claims`, `present_delegated`.

**Errors:** `18`, `19`, `20`, `21`, `36`.

#### `custodian.clsp`

Allows a custodian DID to command a custodied DID that uses `custody_minion.clsp`.

**Mod signature:** `(curried-args solution)`

**Solution shape:** minion DID launcher ID, minion curried-args hash, child solution hash.

**Conditions added:**

- `SEND_MESSAGE 0x12 (concat "JDIDC" child-solution-hash) <minion-DID-puzzlehash>`
- `ASSERT_MY_PUZZLEHASH <this-DID-puzzlehash>`

**State change:** none.

#### `rekey.clsp`

Routine key update using current authentication.

**Mod signature:** `(curried-args solution)`

**Solution shape:** `new-multisig-info`.

**State change:** Replaces the `multisig-info` field.

**Conditions added:** none.

---

### 2.4 Recovery Puzzles

#### `recovery_initiate.clsp`

Starts a time-locked recovery by committing pending replacement state.

**Mod signature:** `(curried-args solution)`

**Solution shape:** participant Merkle paths, participant curried-arg hashes, new multisig info, new custodian DID list, new recovery info.

**Validation:**

- Recovery must not already be active.
- Participants must satisfy `recovery-info` via `multiclass`.
- Participant and curried-arg-hash lists must balance.

**State change:**

- Sets `recovery-timeout-block` to the configured recovery delay.
- Appends pending replacement values: new multisig info, new custodian DIDs, and new recovery info.

**Conditions added:** One `RECEIVE_MESSAGE 22 (concat "JDIDR" new-params-hash) <participant-DID-puzzlehash>` per required recovery participant.

**Errors:** `27`, `28`, `29`, plus `multiclass` and Merkle-path errors.

#### `recovery_authorize.clsp`

Run by a recovery participant DID to authorize initiation or cancellation on another DID.

**Mod signature:** `(curried-args solution)`

**Solution shape:** target DID launcher ID, target curried-args hash, `initiate-or-cancel`, `new-params-hash`, `expiration-block`.

**State change:** Appends a trailing `0` marker to its own curried args.

**Conditions added:**

- `SEND_MESSAGE 22 (concat "JDID" initiate-or-cancel new-params-hash) <target-DID-puzzlehash>`
- `ASSERT_BEFORE_HEIGHT_ABSOLUTE expiration-block`

`initiate-or-cancel` must be `"R"` or `"X"`.

**Errors:** `22`.

#### `recovery_cancel.clsp`

Cancels an active recovery.

**Mod signature:** `(curried-args solution)`

**Solution shape:** participant Merkle paths and participant curried-arg hashes.

**Validation:**

- Recovery must be active.
- Participants must satisfy `recovery-info`.
- Participant and curried-arg-hash lists must balance.

**State change:** Resets `recovery-timeout-block` to `0` and removes pending recovery state.

**Conditions added:** One `RECEIVE_MESSAGE 22 "JDIDX" <participant-DID-puzzlehash>` per required recovery participant.

**Errors:** `23`, `24`, `25`, plus `multiclass` and Merkle-path errors.

#### `recovery_complete.clsp`

Completes an active recovery after the delay.

**Mod signature:** `(curried-args solution)`

**Validation:** Recovery must be active.

**State change:** Applies pending `new-multisig-info`, `new-custodian-DIDs`, and `new-recovery-info`; resets recovery delay to `0`.

**Conditions added:** `ASSERT_HEIGHT_RELATIVE recovery-delay`.

Anyone can spend this puzzle once the relative height condition can be satisfied.

**Errors:** `26`.

#### `recovery_prerotation.clsp`

Switches immediately to a pre-committed key configuration and commits the next prerotation.

**Mod signature:** `(curried-args solution)`

**Solution shape:** fee coin, participant Merkle paths, path sides, new prerotation multisig info.

**Validation:** Participants must satisfy the prerotation multisig info stored inside `recovery-info`.

**State change:**

- Replaces `multisig-info` with the previous prerotation multisig info.
- Stores the supplied next prerotation info inside `recovery-info`.
- Cancels any active recovery by setting recovery delay to `0`.

**Conditions added:**

- One `AGG_SIG_PUZZLE <pubkey> (sha256tree solution)` per prerotation signer.
- Optional `ASSERT_CONCURRENT_SPEND fee-coin`.

---

### 2.5 Issuer Key Puzzles

#### `launch_issuer_key.clsp`

Creates issuer key singleton launchers from the owning DID.

**Mod signature:** `(curried-args solution)`

**Solution shape:** DID parent, DID launcher ID, raw issuer-key puzzle hash, followed by one or more issuer key definitions: public key, `valid-from`, `valid-to`, maximum credential expiration, allowed property root, mode-1 payment puzzle hash, mode-1 payment mojos.

**Conditions added per key:**

- `CREATE_COIN singleton_launcher amount`
- `RECEIVE_MESSAGE 0x3F "JDIDI" <issuer-key-coin-id>`

**Additional condition:** `ASSERT_MY_COIN_ID my-coin-id`.

**Implementation note:** Launcher coin amounts increase across multiple launches while issuer key singleton children use amount `1`.

**Error:** `41` if `mode-1-payment-mojos > 1`, blocking free anyone-can-spend payment coins.

#### `issuer_key.clsp`

Issuer key singleton puzzle.

**Mod signature:** `(CURRIED-ARGS-HASH curried-args parent-info spend-mode spend-mode-args)`

**Issuer key curried args:**

1. `issuer-did-launcher-id`
2. `issuer-key-puzzlehash`
3. `julia-did-puzzlehash`
4. `my-launcher-id`
5. `public-key`
6. `revocation-bitfield-root`
7. `valid-from`
8. `valid-to`
9. `max-expiration`
10. `cred-property-hash-root`
11. `mode-1-payment-puzzlehash`
12. `mode-1-payment-mojos`

**Eve spend behavior:**

- `ASSERT_MY_PARENT_ID launcher-coin-id`
- Creates the first issuer key singleton child.
- Emits `REMARK curried-args`.
- Sends `JDIDI` to the issuer DID coin.

**Regular spend behavior:**

- Checks `CURRIED-ARGS-HASH`.
- Verifies launcher lineage.
- Emits `ASSERT_MY_PUZZLEHASH`.
- Mode `1`: recreates the singleton unchanged, emits `REMARK curried-args`, emits `CREATE_PUZZLE_ANNOUNCEMENT "JDIDA"`, and optionally creates the configured payment coin.
- Other modes: require `issuer_key_functions.clsp` as the spend-mode puzzle and delegate to it.

**Errors:** `9`, `10`, `11`, `42`.

#### `issuer_key_functions.clsp`

Management functions for an issuer key singleton.

**Mod signature:** `(curried-args spend-mode spend-mode-args)`

**Mode 2: update revocation by key**

- Verifies current bitfield proof.
- Replaces one bitfield leaf and computes the new root.
- Requires `AGG_SIG_PUZZLE public-key (sha256tree spend-mode-args)`.
- Creates the next issuer key singleton child and emits `REMARK new-curried-args`.
- Optionally asserts a concurrent fee coin.

**Mode 3: update revocation by DID**

- Verifies current bitfield proof.
- Replaces one bitfield leaf and computes the new root.
- Requires `RECEIVE_MESSAGE 0x16 (concat "JDIDK" (sha256tree (list index new-leaf))) <issuer-DID-puzzlehash>`.
- Creates the next issuer key singleton child and emits `REMARK new-curried-args`.

**Mode 5: melt**

- Requires `RECEIVE_MESSAGE 0x12 "JDIDZ" <issuer-DID-puzzlehash>`.
- Emits the Chia singleton melt `CREATE_COIN 0 -113`.

**Errors:** `12`, `13`, `14`.

#### `issuer_key_control.clsp`

DID-side issuer key management operation.

**Mod signature:** `(curried-args solution)`

**Solution shape:** mode plus mode-specific target issuer key values.

**Mode 3:** Emits `SEND_MESSAGE 0x16 (concat "JDIDK" (sha256tree (list index new-leaf))) <issuer-key-puzzlehash>`.

**Mode 5:** Emits `SEND_MESSAGE 0x12 "JDIDZ" <issuer-key-puzzlehash>`.

**State change:** none.

**Error:** `35` for invalid mode.

---

### 2.6 Credential Presentation Puzzles

#### `present_claims.clsp`

Validates and presents credential claims.

**Mod signature:** `(curried-args solution)`

**Solution shape:** nonce plus claims-with-proofs.

**Behavior:**

- Emits `CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDN" nonce)`.
- Calls `validate-claims` with this DID launcher ID, the raw `julia_did` puzzle hash, the raw `issuer_key` puzzle hash, and the supplied claims-with-proofs.
- Returns unchanged `curried-args`.

See `include/validate_claims.clib` for per-claim validation details.

#### `present_delegated.clsp`

Presents claims delegated through one or more DID holders.

**Mod signature:** `(curried-args solution)`

**Solution shape:** count, delegation paths, optional `present_claims` child input.

**Behavior:**

- Asserts the original claim's holder/delegation announcement.
- Walks each delegation path.
- Requires the terminal delegatee to be this DID.
- Emits `CREATE_PUZZLE_ANNOUNCEMENT (concat "JDIDV" claim-property-hash claim-value-hash issuer-did-launcher-id)` for delegated presentation as subject.
- Optionally runs `present_claims.clsp` as a child to present original claims in the same spend.

**Errors:** `37`, `38`, `39`.

---

## 3. Library Reference

### `include/sha256tree.clib`

Recursive CLVM tree hash implementation:

- Atom: `sha256(1, atom)`
- Pair: `sha256(2, sha256tree(left), sha256tree(right))`

### `include/condition_codes.clib`

Defines Chia condition constants used throughout the codebase, including signature, coin creation, announcements, messaging, self-inspection, relative/absolute time assertions, and `REMARK`.

### `include/curry_and_treehash.clib`

Computes the puzzle hash of a curried function without performing the curry. Used by `did_puzzles.clib` to reconstruct expected DID and issuer key puzzle hashes inside other puzzles.

### `include/did_puzzles.clib`

Puzzle hash helpers:

- `prelauncher-coin-puzzlehash`
- `issuer-key-curried-puzzlehash`
- `issuer-key-coin-puzzlehash`
- `julia-DID-curried-puzzlehash`
- `julia-DID-coin-puzzlehash`

Embeds the standard singleton top layer and singleton launcher hashes.

### `include/puzzle_selector.clib`

Generic allowlist router. It compares a supplied puzzle hash against valid hashes and executes the puzzle if matched. Raises `110` when no match is found.

### `include/parse_merkle_path.clib`

Validates a Merkle path and extracts `(class . leaf)`. Raises `107` for class depth beyond leaf depth, `108` for invalid class depth, and `109` for root mismatch.

### `include/multiclass.clib`

Validates multi-class quorum requirements. It parses participant Merkle paths, verifies class membership, enforces unique participant leaves, and checks that enough classes are satisfied.

Errors: `103`, `104`, `105`, `106`.

### `include/bitfield.clib`

Revocation bitfield utilities:

- `verify-tree`
- `check-bit`
- `set-leaf`

Errors: `100` offset too large, `101` negative offset, `102` invalid tree proof.

### `include/validate_claims.clib`

Credential claim validation logic. For each claim, validates subject/holder mode, issuer DID consistency, public-key consistency, expiration bounds, issuer-key validity period, revocation status, property authorization, and antecedent requirements.

Per valid claim it emits claim/holder announcements, asserts issuer-key liveness via `JDIDA`, adds time-window assertions, and requires `AGG_SIG_UNSAFE` from the issuer key over the claim tree hash.

Error: `112` claim validation failed.

---

## 4. Error Codes

| Code | Source | Meaning |
|------|--------|---------|
| 5 | `custody_minion.clsp` | Custodian DID is not authorized |
| 6 | `custody_minion.clsp` | Recovery is active |
| 9 | `issuer_key.clsp` | Invalid issuer key functions puzzle |
| 10 | `issuer_key.clsp` | Invalid issuer key lineage |
| 11 | `issuer_key.clsp` | Invalid issuer key curried args hash |
| 12 | `issuer_key_functions.clsp` | Invalid bitfield proof in mode 2 |
| 13 | `issuer_key_functions.clsp` | Invalid bitfield proof in mode 3 |
| 14 | `issuer_key_functions.clsp` | Invalid issuer key spend mode |
| 15 | `julia_did.clsp` | Invalid DID lineage |
| 16 | `julia_did.clsp` | Invalid DID curried args hash |
| 17 | `multisig.clsp` | Recovery is active |
| 18 | `pass_thru.clsp` | Structured announcement rejected |
| 19 | `pass_thru.clsp` | `JDID`-prefixed announcement rejected |
| 20 | `pass_thru.clsp` | Structured message rejected |
| 21 | `pass_thru.clsp` | `JDID`-prefixed message rejected |
| 22 | `recovery_authorize.clsp` | Invalid recovery authorize flag |
| 23 | `recovery_cancel.clsp` | Participant/hash list mismatch |
| 24 | `recovery_cancel.clsp` | Participant/hash list mismatch |
| 25 | `recovery_cancel.clsp` | Recovery is not active |
| 26 | `recovery_complete.clsp` | Recovery is not active |
| 27 | `recovery_initiate.clsp` | Participant/hash list mismatch |
| 28 | `recovery_initiate.clsp` | Participant/hash list mismatch |
| 29 | `recovery_initiate.clsp` | Recovery is already active |
| 30 | `singlesig.clsp` | Selected class requires more than one member |
| 31 | `singlesig.clsp` | Selected key class is not valid |
| 32 | `singlesig.clsp` | DID requires more than one class |
| 33 | `singlesig.clsp` | More than one pubkey path supplied |
| 34 | `singlesig.clsp` | Recovery is active |
| 35 | `issuer_key_control.clsp` | Invalid issuer key control mode |
| 36 | `pass_thru.clsp` | Invalid child puzzle |
| 37 | `present_delegated.clsp` | Invalid child puzzle |
| 38 | `present_delegated.clsp` | Terminal delegatee is not this DID |
| 39 | `present_delegated.clsp` | Claim not found in delegation list |
| 41 | `launch_issuer_key.clsp` | Free anyone-can-spend payment coin rejected |
| 42 | `issuer_key.clsp` | Odd singleton child amount rejected |
| 100 | `bitfield.clib` | Bit offset exceeds `0x01FF` |
| 101 | `bitfield.clib` | Negative bit offset |
| 102 | `bitfield.clib` | Invalid bitfield tree proof |
| 103 | `multiclass.clib` | Participant class is not valid |
| 104 | `multiclass.clib` | Class quorum requirements not met |
| 105 | `multiclass.clib` | Duplicate participant leaf |
| 106 | `multiclass.clib` | Duplicate leaf across classes |
| 107 | `parse_merkle_path.clib` | Class depth exceeds leaf depth |
| 108 | `parse_merkle_path.clib` | Invalid class depth |
| 109 | `parse_merkle_path.clib` | Merkle root mismatch |
| 110 | Routing helpers | Puzzle hash not in allowed set |
| 112 | `validate_claims.clib` | Claim validation failed |

---

## 5. File Inventory

### 5.1 Production/Build Puzzles

| File | Lines | Category | Summary |
|------|------:|----------|---------|
| `DIDdoc_announce.clsp` | 44 | DID Document | Announces DID Document DataLayer singleton ID |
| `DIDdoc_set.clsp` | 50 | DID Document | Updates DID Document pointer |
| `coin_control.clsp` | 60 | Operations | Sends `JDIDP` commands to controlled coins |
| `custodian.clsp` | 59 | Custody | Sends `JDIDC` commands to minion DIDs |
| `custody_minion.clsp` | 110 | Authentication | Authenticates by custodian DID command |
| `faucet_coin.clsp` | 19 | Faucet | Faucet spend puzzle authorized by `AGG_SIG_ME` |
| `invalidate.clsp` | 76 | Operations | Adds unsatisfiable or time-window conditions |
| `issuer_key.clsp` | 93 | Issuer key | Issuer key singleton |
| `issuer_key_control.clsp` | 73 | Issuer key | DID-side issuer key commands |
| `issuer_key_functions.clsp` | 178 | Issuer key | Issuer key management modes |
| `julia_did.clsp` | 95 | Top-level | Main DID singleton |
| `launch_issuer_key.clsp` | 75 | Issuer key | Launches issuer key singletons |
| `multisig.clsp` | 96 | Authentication | Multi-class multisig authentication |
| `p2_JDID.clsp` | 23 | Companion | Inner puzzle for DID-owned coins |
| `p2_claim.clsp` | 31 | Companion | Inner puzzle for credential-controlled coins |
| `pass_thru.clsp` | 90 | Operations | Guarded arbitrary condition passthrough |
| `prelauncher.clsp` | 26 | Top-level | DID prelauncher |
| `present_claims.clsp` | 29 | Credentials | Direct claim presentation |
| `present_delegated.clsp` | 158 | Credentials | Delegated claim presentation |
| `recovery_authorize.clsp` | 46 | Recovery | Recovery participant authorization token |
| `recovery_cancel.clsp` | 108 | Recovery | Cancels pending recovery |
| `recovery_complete.clsp` | 57 | Recovery | Completes pending recovery |
| `recovery_initiate.clsp` | 117 | Recovery | Starts pending recovery |
| `recovery_prerotation.clsp` | 73 | Recovery | Switches to pre-rotated keys |
| `rekey.clsp` | 43 | Operations | Routine key rotation |
| `sign_message.clsp` | 82 | Operations | DID message/timestamp/nonce announcements |
| `singlesig.clsp` | 117 | Authentication | Single-signer authentication |

### 5.2 Libraries

| File | Lines | Summary |
|------|------:|---------|
| `include/bitfield.clib` | 92 | Revocation bitfield Merkle utilities |
| `include/condition_codes.clib` | 77 | Chia condition constants |
| `include/curry_and_treehash.clib` | 68 | Curried puzzle hash computation |
| `include/did_puzzles.clib` | 46 | DID and issuer key puzzle hash helpers |
| `include/multiclass.clib` | 135 | Multi-class quorum validation |
| `include/parse_merkle_path.clib` | 66 | Merkle path parsing and class extraction |
| `include/puzzle_selector.clib` | 28 | Hash allowlist router |
| `include/sha256tree.clib` | 10 | CLVM tree hash |
| `include/validate_claims.clib` | 184 | Claim validation |

### 5.3 Other Build Files

| File | Summary |
|------|---------|
| `singleton_launcher.clsp.hex` | Precompiled Chia singleton launcher |
| `singleton_top_layer_v1_1.clsp.hex` | Precompiled Chia singleton top layer |
| `Makefile` | Build and test orchestration |
