murmur set change-request, and you do not delete it with murmur rm. You read one with murmur get change-request.
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. |
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 withmurmur get change-request <id> 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 tomurmur set with --propose. This creates a PENDING change-request and prints its id instead of writing the target.
--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 can propose by default.
Read change-requests
List every change-request in your tenant: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 aPENDING 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.
unendorse:
change-request.endorse and read access to the target.
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, 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 withmurmur change-request (alias murmur cr).
Approve
Approving records the approval and writes the proposed value to the target in one step:{targetKind}.create if the target did not exist when the change was proposed, otherwise {targetKind}.edit. --note records an optional decision note.
Reject
Withdraw
The proposer removes their ownPENDING change-request:
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. |
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. |
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. |
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. |
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. |
Related
- Authorization — the permissions that gate proposing, endorsing, and approving
- Permission reference — every permission and its default grant
- Catalog resources — overview of all catalog resource kinds
murmur set— propose a change with--proposemurmur get— read and list change-requests- Agents — agents discover and endorse change-requests through MCP tools