commandBatches
Destructive-command batches (v1.0 quorum). A batch fixes a set of (subject, kind) leaves, optionally bound to exact payloads, under one Merkle root when it is created (modules create them through `commands.createBatch`). When the deployment publishes approver keys (`pki.approvers`), the batch's commands wait until enough approvers, holding keys off the control plane, have signed its root for the trust domain. The gateway then sends each command with the approval and its leaf's proof, and the daemon verifies both. Without approver keys a batch is recorded for audit and its commands go out at once. See [Security](/docs/operations/security).
Destructive-command batches (v1.0 quorum). A batch fixes a set of (subject, kind) leaves, optionally bound to exact payloads, under one Merkle root when it is created (modules create them through commands.createBatch). When the deployment publishes approver keys (pki.approvers), the batch's commands wait until enough approvers, holding keys off the control plane, have signed its root for the trust domain. The gateway then sends each command with the approval and its leaf's proof, and the daemon verifies both. Without approver keys a batch is recorded for audit and its commands go out at once. See Security.
All 7 methods are served by this release.
| Method | Kind | Authorization | Phase | Status |
|---|---|---|---|---|
create | mutation | compute:batches:create @ compute-tenant | v1.0 | registered |
get | read | compute:batches:read @ compute-tenant | v1.0 | registered |
list | read | compute:batches:read @ compute-tenant | v1.0 | registered |
scope | read | compute:batches:read @ compute-tenant | v1.0 | registered |
members | read | compute:batches:read @ compute-tenant | v1.0 | registered |
approve | mutation | compute:batches:approve @ compute-tenant | v1.0 | registered |
cancel | mutation | compute:batches:approve @ compute-tenant | v1.0 | registered |
create
POST /api/compute/commandBatches/create
Creates a batch from its (subject, kind) leaves, each optionally bound to a payload's SHA-256, a reason and a lifetime; returns it pending, with the approvals its size needs.
- The tree is fixed now: its root, size and every leaf's proof are stored, so what approvers review is what the daemons check. Subjects are computed as the executing agent does (see pki
batchSubject): the node id,bmc:<site agent>/<address>for BMC kinds,node:<target>forsite.httpProxy. A leaf withoutpayloadSha256admits any payload of its kind, andscopeflags it to approvers. - Idempotency. The batch id derives from the tenant, the caller and
idempotencyKey. The same request again (the same leaves in any order, reason and lifetime) returns the stored batch without a new event; a different request under the key isCONFLICT. - The lifetime is
notAfterSeconds(default 24 hours): after it the batch admits no commands and can no longer be approved. At most 50,000 leaves.
Publishes command.batch.created with the scope size and the approvals required.
- Kind: mutation
- Authorization:
compute:batches:create@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
reason | string | yes | |
scope | list of object | yes | |
scope[].subject | string | yes | |
scope[].kind | string | yes | |
scope[].payloadSha256 | string | ||
scope[].payload | object | ||
scope[].payload.typeUrl | string | yes | |
scope[].payload.value | string | yes | |
notAfterSeconds | integer | ||
idempotencyKey | string | yes |
get
POST /api/compute/commandBatches/get
Returns one batch of the tenant: its reason, state, scope root and size, the approvals it needs and has, and how many of its commands are in each state.
The state is expired as soon as notAfter passes, even before the minute sweep writes it. A batch of another tenant is NOT_FOUND.
createdBy is the identity that created the batch. When an agent proposed it on that identity's behalf (MCP propose_command_batch), createdByAgent and delegationId say so, and the reason is the agent's text, not the person's.
- Kind: read
- Authorization:
compute:batches:read@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
batchId | string | yes |
list
POST /api/compute/commandBatches/list
Returns the tenant's batches, newest first, filtered by state.
limit is 1 to 200 (default 50); next, when present, is the cursor for the following page.
- Kind: read
- Authorization:
compute:batches:read@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
state | one of pending, approved, expired, cancelled | ||
limit | integer | ||
cursor | string |
scope
POST /api/compute/commandBatches/scope
Returns a batch's leaves in leaf order, for approvers to review before signing: each leaf's index, subject, kind and payloadSha256, plus the leaf's payload ({ typeUrl, value } base64) when its creator stored it. Decode it by the kind's payload type, after checking it against payloadSha256.
An empty payloadSha256 marks a leaf that admits any payload of its kind, which approvers should look at closely. Pages hold 1 to 5,000 leaves (1,000 by default); next is the leaf index to pass as cursor.
- Kind: read
- Authorization:
compute:batches:read@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
batchId | string | yes | |
cursor | integer | ||
limit | integer |
members
POST /api/compute/commandBatches/members
Returns the commands enqueued into a batch so far, in command-id order: each one's node, (subject, kind), state and reason, and awaitingApproval while it is held for the batch's approval.
state keeps one command state. Pages hold 1 to 500 commands (100 by default); next is the command id to pass as cursor. A batch of another tenant is NOT_FOUND.
- Kind: read
- Authorization:
compute:batches:read@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
batchId | string | yes | |
state | one of pending, dispatched, acked, running, succeeded, failed, rejected, expired, cancelled | ||
limit | integer | ||
cursor | string |
approve
POST /api/compute/commandBatches/approve
Adds one approver's signature over the batch's root; once the signatures meet the threshold for its size, the batch becomes approved and its held commands are released at once.
signatureis{ kid, sig }: the approver key id and a base64url P-256 signature over the batch (id, root, size, end, trust domain), made off the control plane. A signature by a key outside the published set, or over anything else, isACCESS_DENIED. The same approver twice counts once.- Decided as
compute:batches:approve, on top of the signature, never instead of it. INVALID_STATEfor a batch that is notpending, or one that needs no approvals (no approver keys, or a size the tiers exempt).INVALID_CONFIGwhen the deployment has no trust domain (nopki.join).
Publishes command.batch.approved with the approver key ids when the batch completes.
- Kind: mutation
- Authorization:
compute:batches:approve@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
batchId | string | yes | |
signature | object | yes | |
signature.kid | string | yes | |
signature.sig | string | yes |
cancel
POST /api/compute/commandBatches/cancel
Ends a pending batch: it becomes cancelled and its held commands are cancelled with it.
A batch that is not pending is INVALID_STATE. Decided as compute:batches:approve.
- Kind: mutation
- Authorization:
compute:batches:approve@compute-tenant - Module:
quorum - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | |
batchId | string | yes |
Better Compute is created by Sean Filimon
Last updated
capacity
The capacity methods report what the pools a tenant can see hold, book and have free, without booking anything. `summary` and `byPool` read the per-pool rollup, which the booking transactions update and a periodic rebuild corrects. `preview` asks the placer whether a request fits, and `timeline` counts booked GPUs over time. All four are decided as `compute:capacity:read`. See [Capacity](/docs/guides/capacity).
commands
One-shot actions on one node, queued as durable rows in the node's command queue and delivered in order over its session. Every method is decided on `compute-node/{nodeId}`: `run` and `cancel` with `compute:nodes:exec`, `get` and `list` with `compute:nodes:read`. See [Commands](/docs/guides/nodes/commands).