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

# change-request

> Catalog resource that proposes a change to another catalog resource and holds it behind an approval — so anyone who can read a resource can propose a change, while applying it still requires permission to write the target.

A change-request proposes a new value for another catalog resource and holds that value until someone with write access approves it. It is how a person — or an [agent](/concepts/agents) — who can read a resource but not write it suggests a change: [propose](#propose-a-change) the new value, others [endorse](#endorse-a-change-request) it, and a reviewer with [permission](/security/authorization) to write the target [approves](#approve-reject-or-withdraw) it. Approving applies the proposed value to the target in one step.

A change-request is created and updated entirely through its own commands — proposing, approving, rejecting, withdrawing, and endorsing. You do not author it with [`murmur set change-request`](/cli/set), and you do not delete it with [`murmur rm`](/cli/rm). You read one with [`murmur get change-request`](/cli/get).

## Lifecycle

A change-request moves through these states:

| State      | Meaning                                                                                                                                                            |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PENDING`  | Proposed and awaiting review. Can be endorsed, approved, rejected, or withdrawn.                                                                                   |
| `APPROVED` | A reviewer approved it. The proposed value is being applied to the target; if the apply has not yet completed, it remains here and is retried on the next approve. |
| `APPLIED`  | The proposed value is written to the target. Terminal — the endorser list is frozen as a record of who wanted the change.                                          |
| `REJECTED` | A reviewer declined it. Terminal.                                                                                                                                  |

A `PENDING` change-request the proposer no longer wants is **withdrawn** — removed entirely. Withdrawal works only while `PENDING`; once a change-request is `APPROVED` or later, the proposer cannot cancel it and must ask a reviewer to reject it.

The proposed value applies only if the target has not changed since the change-request was proposed. If the target changed in the meantime, approval fails with a conflict and the change-request stays `APPROVED` so the conflict can be resolved or the change rejected. Nothing is merged silently.

## Fields

Change-requests are managed by the API, not authored by hand. Reading one with [`murmur get change-request <id>`](/cli/get) shows these fields:

| Name                | Type      | Description                                                                                                                                                                  |
| ------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                | string    | Server-generated identifier, e.g. `cr-a1b2c3`. Also the change-request's catalog name.                                                                                       |
| `targetKind`        | string    | The catalog kind the change-request proposes to change, e.g. `recipe`.                                                                                                       |
| `targetName`        | string    | The name of the target resource within `targetKind`.                                                                                                                         |
| `proposedPayload`   | object    | The full proposed value of the target resource — a complete replacement, not a diff. Redacted on read exactly as a direct read of the target would be.                       |
| `baseVersion`       | integer   | The target resource's version when the change was proposed. Approval applies only if the target still matches this version. `0` if the target did not exist at propose time. |
| `status`            | enum      | Lifecycle state: `PENDING`, `APPROVED`, `APPLIED`, or `REJECTED`.                                                                                                            |
| `proposer`          | object    | Who proposed the change. Stamped from the authenticated caller.                                                                                                              |
| `approver`          | object    | Who approved or rejected the change. Unset while `PENDING`.                                                                                                                  |
| `rationale`         | string    | Optional justification supplied by the proposer.                                                                                                                             |
| `decisionNote`      | string    | Optional note supplied by the approver or rejecter.                                                                                                                          |
| `createdAt`         | timestamp | When the change-request was proposed.                                                                                                                                        |
| `decidedAt`         | timestamp | When the change-request was approved or rejected.                                                                                                                            |
| `appliedAt`         | timestamp | When the proposed value was written to the target.                                                                                                                           |
| `appliedGeneration` | integer   | The target version produced by the apply. Recorded once the change-request is `APPLIED`.                                                                                     |
| `endorsers`         | array     | Thumbs-up signals from members, service profiles, or agents. Each endorser appears at most once. Frozen once the change-request is terminal.                                 |
| `source`            | enum      | What generated the change-request. Unset for changes you propose; set for changes the platform generates automatically.                                                      |

## Propose a change

To suggest a change to a catalog resource without writing it directly, read the resource, edit the value, and pipe it to [`murmur set`](/cli/set) with `--propose`. This creates a `PENDING` change-request and prints its id instead of writing the target.

```bash theme={null}
murmur get recipe default | yq '.script_ref = "v2"' | murmur set recipe default --propose --rationale "bump build script to v2"
```

```
cr-a1b2c3
```

`--propose` takes the full resource value as the proposed replacement and validates it against the target's schema immediately — an invalid proposal is rejected at propose time, not at approval. `--rationale` is optional and records why you are proposing the change.

Proposing requires `change-request.create` and read access to the target (`{targetKind}.read`). Every org member and every [service profile](/concepts/service-profiles) can propose by default.

## Read change-requests

List every change-request in your tenant:

```bash theme={null}
murmur get change-request
```

```
ID         TARGET           STATUS   ENDORSE  PROPOSER  CREATED
cr-a1b2c3  recipe/default   PENDING  4        alice     2026-06-24T18:02:11Z
cr-9f8e7d  role/developer   APPLIED  1        bob       2026-06-23T09:14:55Z
```

Read one change-request in full, including its proposed value and rationale:

```bash theme={null}
murmur get change-request cr-a1b2c3
```

Reading a change-request requires `change-request.read` (or `change-request.list` to list) and read access to the target. A caller who cannot read recipes cannot read recipe change-requests, and list results omit change-requests whose target the caller cannot read.

## Endorse a change-request

Endorsing adds your thumbs-up to a `PENDING` or `APPROVED` change-request — an advisory signal of demand that aggregates onto one proposal. It never approves or applies the change, and approval never depends on the endorsement count.

```bash theme={null}
murmur cr endorse cr-a1b2c3
```

```
Endorsed change-request cr-a1b2c3 (5 endorsements)
```

Remove your endorsement with `unendorse`:

```bash theme={null}
murmur cr unendorse cr-a1b2c3
```

Endorsing is idempotent: endorsing twice leaves one endorsement, and un-endorsing when you have not endorsed does nothing. Endorsing requires `change-request.endorse` and read access to the target.

[Agents](/concepts/agents) can participate in the same signal through MCP tools — `find_change_requests` discovers open proposals so an agent endorses an equivalent one instead of filing a duplicate, and `endorse_change_request` / `unendorse_change_request` toggle its thumbs-up. Unlike org members and [service profiles](/concepts/service-profiles), agent runtimes hold no change-request permissions by default; an agent uses these tools only where the tenant grants `change-request.read`, `change-request.list`, and `change-request.endorse` to its agent runtimes.

## Approve, reject, or withdraw

A reviewer with permission to write the target drives the change-request to a terminal state with `murmur change-request` (alias `murmur cr`).

```text theme={null}
murmur change-request approve <id> [--note TEXT]    Approve and apply a change-request
murmur change-request reject  <id> [--note TEXT]    Reject a change-request
murmur change-request withdraw <id>                 Withdraw your own pending change-request
murmur change-request endorse  <id>                 Add your thumbs-up
murmur change-request unendorse <id>                Remove your thumbs-up
```

### Approve

Approving records the approval and writes the proposed value to the target in one step:

```bash theme={null}
murmur cr approve cr-a1b2c3 --note "looks good, rolling out"
```

```
Approved change-request cr-a1b2c3 (APPLIED); applied generation 7
```

Approval requires the same permission as writing the target directly: `{targetKind}.create` if the target did not exist when the change was proposed, otherwise `{targetKind}.edit`. `--note` records an optional decision note.

### Reject

```bash theme={null}
murmur cr reject cr-a1b2c3 --note "superseded by cr-9f8e7d"
```

Rejecting requires the same target-write permission as approving.

### Withdraw

The proposer removes their own `PENDING` change-request:

```bash theme={null}
murmur cr withdraw cr-a1b2c3
```

Only the proposer can withdraw, and only while the change-request is `PENDING`.

## Targets you cannot propose against

A change-request carries the full proposed value of its target, so kinds whose value cannot be meaningfully reviewed cannot be targets:

| Kind                                           | Reason                                                                                             |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `secret`, `user-secret`, `token`, `share-link` | Their values are write-only and suppressed on read — a proposed value could never be reviewed.     |
| `integration`                                  | Mints a one-time signing key when written; routing it through a change-request would drop the key. |
| `change-request`                               | A change-request cannot target another change-request.                                             |

Platform builtins (resources whose name begins with `murmur-`) also cannot be the target of a change-request.

## Errors

| Code                  | Meaning                                                            | What to do                                                                                                                                                                                |
| --------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_ARGUMENT`    | `{kind} resources cannot be the target of a change-request`        | Choose a target kind that supports change-requests. See [Targets you cannot propose against](#targets-you-cannot-propose-against).                                                        |
| `INVALID_ARGUMENT`    | `{kind} "{name}" is a platform resource and cannot be changed`     | Platform builtins (`murmur-*`) are immutable. Propose against a resource you own.                                                                                                         |
| `INVALID_ARGUMENT`    | `unknown resource kind "{kind}"`                                   | Use a valid catalog kind. See [Catalog resources](/catalog/overview).                                                                                                                     |
| `INVALID_ARGUMENT`    | `target_name is required`                                          | Provide the name of the resource you are proposing to change.                                                                                                                             |
| `INVALID_ARGUMENT`    | `target_name "{name}" does not match payload name "{name}"`        | Make the `name` field in the proposed value match the target name.                                                                                                                        |
| `INVALID_ARGUMENT`    | `unmarshal proposed {kind}: …`                                     | Fix the proposed value so it parses as a valid `{kind}` resource.                                                                                                                         |
| `NOT_FOUND`           | `change-request "{id}" not found`                                  | Check the id with [`murmur get change-request`](/cli/get).                                                                                                                                |
| `FAILED_PRECONDITION` | `target {kind} "{name}" changed since base version {n}`            | The target changed after the proposal. Re-propose against the current value, or reject the change-request.                                                                                |
| `FAILED_PRECONDITION` | `change-request is already applied` / `change-request is rejected` | The change-request is terminal — it cannot be approved, rejected, endorsed, or withdrawn.                                                                                                 |
| `FAILED_PRECONDITION` | `only a pending change-request can be withdrawn`                   | Reject the change-request instead of withdrawing it.                                                                                                                                      |
| `PERMISSION_DENIED`   | (proposer-only withdraw)                                           | Only the proposer may withdraw a change-request.                                                                                                                                          |
| `PERMISSION_DENIED`   | (missing permission)                                               | Proposing needs `change-request.create`; endorsing needs `change-request.endorse`; approving and rejecting need write access to the target. See [Authorization](/security/authorization). |

## Related

* [Authorization](/security/authorization) — the permissions that gate proposing, endorsing, and approving
* [Permission reference](/security/permission-reference) — every permission and its default grant
* [Catalog resources](/catalog/overview) — overview of all catalog resource kinds
* [`murmur set`](/cli/set) — propose a change with `--propose`
* [`murmur get`](/cli/get) — read and list change-requests
* [Agents](/concepts/agents) — agents discover and endorse change-requests through MCP tools
