# Better Compute > An embeddable TypeScript control plane for GPU, CPU and sandbox capacity: nodes, reservations, bare-metal provisioning, and isolated VMs, authorized by Better IAM. Created by Sean Filimon. # Docs - Guides: Nodes, GPU and CPU capacity, bare metal, VPS and sandboxes - **Getting started** - [Introduction](/docs/guides): Better Compute is an embeddable TypeScript control plane for GPU, CPU and sandbox capacity that uses Better IAM for identity, policy and billing. - [Quickstart](/docs/guides/quickstart): Install Better Compute from npm, run the development server with simulated GPU machines, reserve GPUs, watch capacity change and release them. - [Installation](/docs/guides/installation): Requirements, installing better-compute and Better IAM from npm, the umbrella package's subpaths, packages outside it, optional peers, and building from a clone. - [Tutorial: a GPU cluster end to end](/docs/guides/tutorial-gpu-cluster): A step-by-step walkthrough with the real CLI commands - create a site and a pool, mint a join token, join a GPU server with bcd, watch it get adopted, reserve GPUs, use the CDI device names on the node, release them and follow the events. - **Foundations** - Concepts - [Concepts](/docs/guides/concepts): The ideas Better Compute is built on, from one Postgres truth and desired state to one IAM decision per mutation, and its fifteen design principles. - [Architecture](/docs/guides/concepts/architecture): The planes and components of Better Compute, the api, gateway and worker process modes, and how joins, reservations, bare metal and VPS flow through them. - [Domain model](/docs/guides/concepts/domain-model): Every entity Better Compute tracks, from regions and pools to atoms, bookings and commands, how they relate, and how each maps to a Better IAM resource type. - [Desired state and commands](/docs/guides/concepts/desired-state-and-commands): How Better Compute tells a node what to do, with generation-numbered NodeSpecs, level-triggered reconcilers and durable commands for one-shot actions. - [Consistency](/docs/guides/concepts/consistency): Why double-booking cannot happen in Better Compute, and how one clock, exclusion constraints, the outbox, the work queue and fencing keep the fleet consistent. - IAM integration - [IAM integration](/docs/guides/iam): How Better Compute uses Better IAM as its only identity provider, policy engine, billing ledger and flag store, and how the IAM bridge wires the two. - [Actions and resources](/docs/guides/iam/actions-and-resources): The compute:* actions and compute-* resource types Better Compute adds to Better IAM, the method-to-action table, list filtering and cross-tenant refusal. - [Policies](/docs/guides/iam/policies): Write Better IAM policies for Better Compute, from the gpu-user and agent-guardrails examples to pool relations, resource attributes and conditions. - [Tenancy](/docs/guides/iam/tenancy): How Better Compute maps onto Better IAM tenants, with the root tenant as the platform, pools offered to organizations, and projects inside a tenant. - [Billing and usage](/docs/guides/iam/billing-and-usage): How the root tenant bills its sub-tenants for compute. Better Compute meters every resource it issues (hosted and node capacity, provider VMs, reservation grants, networks, disks, snapshots and provider pass-through costs) into hourly usage windows; Better IAM prices them, applies budgets and closes the invoices. - [Delegated confirmation](/docs/guides/iam/delegated-confirmation): How an AI agent acting for a person gets CONFIRMATION_REQUIRED instead of a denial, how the draft waits for approval, and how the retry completes. - **Fleet** - Nodes - [Nodes](/docs/guides/nodes): The node model in Better Compute, with its independent state axes, role, trust, hardware key and generations, and how a server goes from join to schedulable. - [Joining](/docs/guides/nodes/joining): Join tokens, the join flow, node certificates and renewal, adopting a brownfield server with the install script, and the join request approval queue. - [Attestation](/docs/guides/nodes/attestation): The attestors that admit machines (join-token, x509pop, provisioned, discovery, cloud-iid, tpm), what each proves, single-use evidence and two-round joins. - [Inventory and health](/docs/guides/nodes/inventory-and-health): NodeInventory v1 and its section hashes, snapshots and diffs, GPU naming, devices and atoms, conditions, XID handling, remediation and acceptance. - [Operating nodes](/docs/guides/nodes/operating-nodes): Cordon, drain, taint and label nodes, understand maintenance, liveness and connectivity, revoke a node's identity, and delete nodes, with the nodes API. - [Commands](/docs/guides/nodes/commands): The durable command queue from an operator's view, with commands.run, kinds and lanes, deadlines, safety flags, signing, cancellation and results. - [Fleet configuration](/docs/guides/fleet-config): Keep sites, provider accounts, pools, quotas, offers, flavors and sandbox templates in one reviewed FleetConfig document; plan, apply, catch drift. - [Kubernetes fleet pools](/docs/guides/kubernetes-fleet-pools): Back a GPU pool with a managed Kubernetes cluster on GKE, EKS or DOKS. The same FleetConfig document works on each; swap the provider account and keep the rest. - [Rollouts](/docs/guides/rollouts): Register offline-signed bcd releases and roll a daemon version out in waves within each pool's disruption budget, with a failure gate, pause and abort. - Access - [Access](/docs/guides/access): How people reach nodes and instances through tunnels with daemon-verified exec tickets, break-glass SSH certificates and allowlisted commands. - [Tunnels](/docs/guides/access/tunnels): Open exec, console, SSH and TCP tunnels with tunnels.open, single-use 60-second exec tickets and a WebSocket relayed through the node's gateway. - [Break-glass SSH](/docs/guides/access/ssh): Issue short-lived OpenSSH user certificates from the compute SSH CA with nodes.issueSshCert, only for MFA sessions that hold compute:nodes:ssh-root on the node. - **Compute** - Capacity - [Capacity](/docs/guides/capacity): How Better Compute counts GPUs, books them as atoms over time, keeps every booking exclusive, and reports free capacity per pool. - [Pools](/docs/guides/capacity/pools): Pools group the nodes of one site under one GPU model, sharing mode and policy, and offerings make a pool visible to other tenants with a quota. - [Placement](/docs/guides/capacity/placement): How the placer picks a node and its atoms for a request, the filters and scorers it runs, and how a guarded commit makes lost races harmless. - [Reservations](/docs/guides/capacity/reservations): Reserve GPUs from a pool with an idempotent request that Better IAM decides on, follow it from draft to released, and extend, renew or release it. - [Quotas and usage](/docs/guides/capacity/quotas-and-usage): Per-pool quotas that cap what a tenant holds at once, hourly usage windows metered from active reservations, and how both reach Better IAM billing. - [Gang and calendar reservations](/docs/guides/capacity/gang-and-calendar): Book several nodes at once on one fabric, book a window that starts later, and let BookingRepair move a future booking off hardware that went bad. - [Spot and preemption](/docs/guides/capacity/spot-and-preemption): Spot reservations fill idle GPUs at the spot meter, and a regular request that would otherwise wait takes their atoms after a notice. - [Fractional GPUs](/docs/guides/capacity/fractional-gpus): Share GPUs as MIG instances, time-slice slots or MPS slots, each booked as its own atom, and what of it runs today versus in v0.5. - [Kubernetes workers](/docs/guides/capacity/kubernetes): Join a pool's machines to a Kubernetes cluster and hand a reservation's GPUs to their kubelets with binding kubernetes, through bcd's device plugin or DRA driver. - VPS and sandboxes - [VPS](/docs/guides/vps): Virtual machines on your own hosts or on a provider's cloud, with desired state, flavors, provider accounts and pool IPAM from the vps() module. - [Instances](/docs/guides/vps/instances): Create, start, stop, resize and delete VPS instances, and how the vps.instances reconciler converges them from host reports or provider polls. - [Sandboxes](/docs/guides/vps/sandboxes): Short-lived isolated VMs from per-tenant templates, with a time-to-live, warm pools, snapshots, exec over SSH certificates and one IAM decision per sandbox. - [Flavors](/docs/guides/vps/flavors): Named instance shapes per VPS pool, and how each becomes scalar claims, GPU atoms and quota on a host, or a provider offer. - [Providers](/docs/guides/vps/providers): Provider accounts, the defineProvider contract, the Hetzner Cloud, Proxmox VE, Google Compute Engine, DigitalOcean and Amazon EC2 providers, discovery and attach, provider reservations, platform-issued compute and its tenant isolation, billing (modes, attach billing, reservation grants, provider costs and pass-through), conformance cases, and secret references for credentials. - [Networking](/docs/guides/vps/networking): How VPS instances get addresses, from one IPv4 range per hosted pool to what runtimes and providers report, and tenant networks (VPCs, subnets, firewall rules) on provider accounts. - [Volumes and addresses](/docs/guides/vps/provider-volumes): Block volumes, shared (NFS) volumes, their snapshots and reserved public addresses on a provider account, as typed resources next to instances, and what happens to them when an instance is deleted. - [AI platform](/docs/guides/vps/ai-platform): DigitalOcean's AI platform as cloud resources. Dedicated Inference endpoints booked against the GPU quota, sealed model access keys and a token-counting inference proxy, knowledge bases and guardrails, the Managed Agents previews (harness agents on containers or MicroVMs, action gateways), and their read-only signals for an attention list. - Bare metal - [Bare metal](/docs/guides/bare-metal): Enroll machines by their BMCs, commission them over PXE, deploy signed images and wipe them on release, all driven by one provision state machine. - [Sites and site agents](/docs/guides/bare-metal/sites): Sites are boot and failure domains. A bcd site agent in each one runs proxy DHCP, iPXE, the image cache and BMC access, with one active boot server per site. - [BMC drivers and credentials](/docs/guides/bare-metal/bmc): The driver concerns metal adds, how BMC operations reach the site agent, enrolling with sealed BMC credentials, power control and two-phase BMC password rotation. - [Profiles and images](/docs/guides/bare-metal/profiles-and-images): Versioned metal profiles that name steps, drivers, an image and user data; the profiles metal ships for each provision state; and the signed image catalog. - [Provisioning workflows](/docs/guides/bare-metal/workflows): The workflow engine expands a profile into persisted steps that run on the control plane, a site agent, the node or its ramdisk, and resume after any crash. - [Deploying machines](/docs/guides/bare-metal/deploying): Walkthroughs that deploy machines on an emulated QEMU/KVM site, install Ubuntu over virtual media, and run Talos on an agentless pool. - [Dedicated-root metal](/docs/guides/bare-metal/dedicated-root): Lease whole machines to tenants with root, under tenant-controlled trust and node-tenant certificates, and take them back with a BMC-driven teardown. - **Integrate** - Clients - [Clients](/docs/guides/clients): Every way to call Better Compute, from raw HTTP to the typed client, the CLI, MCP tools and the console, and the credentials each one carries. - [TypeScript client](/docs/guides/clients/typescript-client): createComputeClient infers every group and method from your server's type, sends bearer tokens or the IAM cookie, and raises ComputeClientError with stable codes. - [CLI](/docs/guides/clients/cli): Use the better-compute command line as a client - authenticate with a token, run a command for every API group, reserve GPUs, run sandboxes, plan the fleet. - [MCP](/docs/guides/clients/mcp): The Better Compute MCP server gives AI agents tools to find capacity, reserve GPUs and check nodes, as the agent, behind Better IAM's gate with delegated confirmation. - [Console](/docs/guides/clients/console): The Next.js console runs Better IAM and Better Compute on one origin, built on console-kit, framework-free stores with live updates and permission-aware actions. - [Admin panel](/docs/guides/clients/admin-panel): The operator panel in apps/admin, a keyboard-first workspace over capacity, the fleet and the control plane that runs on a simulated fleet or, through a loopback-only proxy, on a real compute API as the signed-in operator. - Events and audit - [Events](/docs/guides/events): Every change writes a CloudEvents-style event to the outbox in its own transaction. Read it with events.list, stream it over SSE, or receive it by webhook. - [Webhooks](/docs/guides/events/webhooks): Subscribe a tenant's HTTPS endpoint to event types, verify the HMAC signature on each delivery, and handle retries, dead letters, redelivery and secret rotation. - [Watch](/docs/guides/events/watch): Stream a tenant's events live over Server-Sent Events with handleWatch, resume from any cursor with Last-Event-ID, filter by type, and authorize every stream. - [Audit](/docs/guides/events/audit): Every allowed mutation lands in audit_events with its admission context, sealed hourly by signed per-tenant RFC 6962 Merkle checkpoints you can verify and prove. - Extending: Modules, drivers, providers, plugins and steps - [Overview](/docs/extending): Every seam of Better Compute is a typed contract you register through options. What each extension point is for, where it runs and how stable it is. - **Server** - [Modules](/docs/extending/modules): A ComputeModule bundles API groups, migrations, reconcilers, command kinds and NodeSpec sections. How to write one, what its context offers, and how the host runs it. - [Methods](/docs/extending/methods): defineMethod declares an API method with its IAM action, the resource it is decided on, validation, and optional admission or composite behaviour. The envelope does the rest. - [Sinks](/docs/extending/sinks): Event and audit sinks receive every committed row at least once, each with its own durable cursor. How dispatch works, the cursor pitfalls, poison events, and usage. - **Hardware** - [Drivers](/docs/extending/drivers): Declare a driver with defineDriver, bind drivers to machines through hardware profiles, and run one out of process with the bcx driver SDK. - [Attestors](/docs/extending/attestors): Write an AttestorVerifier that admits machines on your own evidence, defer a join for a second round, use evidence once, and register it with JoinService. - [Providers](/docs/extending/providers): Build a provider adapter with defineProvider, make create idempotent against an API that has no idempotency keys, map errors, and test it against an emulator. - **Scheduling and provisioning** - [Scheduler plugins](/docs/extending/scheduler-plugins): Add filters, scorers, atom pickers and admission hooks to the capacity placer with defineSchedulerPlugin, and tune the built-in scorer weights. - [Steps and profiles](/docs/extending/steps-and-profiles): Write workflow steps with defineStep, ship profiles, use the step context's PKI and secret ports, and keep steps idempotent across crashes and wake-ups. - **Examples** - [Walkthroughs](/docs/extending/walkthroughs): The acceptance walkthroughs of PLAN.md 5.6 and the emulated-site example, what each one proves about extending Better Compute, and how to run them. - Daemon and protocol: bcd, the gateway, and the session protocol between them - [Overview](/docs/daemon): bcd is one Go binary for servers, site agents and the PXE ramdisk. It dials out to a gateway, runs typed commands and converges desired state. - **Run bcd** - [Installing bcd](/docs/daemon/install): The install script that puts bcd on a server, the files and hardened systemd unit it writes, joining with BCD_JOIN_TOKEN, and upgrades. - [bcd commands](/docs/daemon/commands): Every bcd subcommand with its flags, what it does and its exit codes, plus the full list of bcd doctor checks with their statuses and fixes. - [config.toml reference](/docs/daemon/configuration): Every key and section of bcd's /etc/bcd/config.toml with its type, default, validation and the modes that read it, plus the files bcd keeps under data_dir and elsewhere. - [Running bcd on real hardware](/docs/daemon/real-hardware): A bring-up checklist for bcd on a real machine, what bcd hardware and bcd doctor check before a join, what changes between root, bcd helper and an unprivileged node, WSL 2 specifics, and exactly what has and has not run on real hardware. - [Host configuration](/docs/daemon/host-config): The config units bcd converges from NodeSpec.host, in order, with their settings, files, refusals and reboot cases, and how bcd helper applies them as root. - [On Kubernetes](/docs/daemon/kubernetes): Run bcd as a privileged DaemonSet on the GPU nodes of a cluster you already operate, so the control plane adopts them without owning their host configuration. - [Delivery](/docs/daemon/delivery): How NodeSpec generations and one-shot commands reach bcd, the acceptance checks, lanes and credits, cancellation, signatures, and the journal that makes delivery safe. - [Failure modes](/docs/daemon/failure-modes): What happens when a gateway, a node, the network, the journal, PostgreSQL, the api or a worker fails, or clocks and certificates go wrong, and which invariants hold. - [Troubleshooting bcd](/docs/daemon/troubleshooting): Symptom, cause and fix for the ways bcd fails on real hosts - joins, pins and TLS, the clock, renewals, revocation, sections stuck progressing, GPU holds, nvidia-smi, KVM and the helper socket - with the doctor check that detects each. - **Node agent** - [bcd helper](/docs/daemon/helper): How bcd helper runs as root beside an unprivileged bcd node, which callers it serves, the versioned request format, every operation family and what root checks before it acts. - [Devices and holds](/docs/daemon/devices-and-holds): The devices converger in bcd, which turns NodeSpec.devices into CDI holds. Covers the bindings and atoms it takes, conflicts, hold slices and host admission, the CDI spec and env file it writes, the AllocationBound, Released and Failed events and their reasons, unprivileged nodes, and Kubernetes releases. - [GPUs on a node](/docs/daemon/gpus): How bcd reads a node's NVIDIA GPUs through nvidia-smi, merges them into the inventory, keeps passed-through GPUs, builds CDI specs from NVIDIA's, handles persistence mode, XIDs, diag.nvml and gpu.reset, what works on WSL 2, and what bcd doctor checks. - [Instance runtimes](/docs/daemon/runtimes): The runtimes bcd runs VPS and sandbox instances on, what each one does for disks, NICs, GPUs, volumes, snapshots, consoles and seeds, how placement and admission apply, and how they run under bcd helper. - [Node identity](/docs/daemon/identity): What makes up a bcd node's identity on disk, how bcd join creates it with each attestor, how renewal replaces the key every day, what revocation does on the node, how bcd join --reset recovers, and how node keys live in the TPM. - [Self-update](/docs/daemon/self-update): The node side of daemon upgrades, from the signed release manifest and its checks to the A/B slots, the release floor, confirmation, rollback, the crash-loop unit, the helper's half and the bcd update command. - [Telemetry and status](/docs/daemon/telemetry): How bcd exports its own GPU, host and instance metrics over OTLP/HTTP to the collector NodeSpec.telemetry names, every metric with its unit, type and attributes, how failures behave, and what bcd status reads from the agent's local socket. - [Site agent and ramdisk](/docs/daemon/site-and-ramdisk): How bcd site runs the boot server, proxy DHCP, TFTP, the image cache and BMC drivers for a site, and how bcd ramdisk joins from its kernel command line, wipes disks, writes and verifies images and kexecs. - **Protocol** - [Gateway](/docs/daemon/gateway): The gateway holds daemon sessions in memory and writes what matters to PostgreSQL. Its loops, dispatch by join, group commit, lease, control API, tunnels and metrics. - [Protocol](/docs/daemon/protocol): Transport, the proto packages, the AgentGateway service and its frames, signed envelopes, message size bounds and the version-skew rules. - [Sessions](/docs/daemon/sessions): How a bcd session opens with Hello and Welcome, how epochs fence a stale gateway, the resume rules, heartbeats, liveness batching and reconnect back-off. - Operations: Deploy, secure, observe and scale - [Overview](/docs/operations): The processes of a Better Compute deployment, the roles each one runs, what talks to what, and what you need before the first node joins. - **Deploy** - [Deployment](/docs/operations/deployment): Lay out the api, gateway and worker processes, put the right load balancers in front, run the better-compute serve host or embed the handler in your own app. - [Deploying on AWS](/docs/operations/deploy-aws): The reference deployment of the control plane on AWS, as three CloudFormation stacks rendered by aws deploy-templates, from the VPC to the ECS Fargate services. - [Configuration](/docs/operations/configuration): The better-compute.config file, every betterCompute() option with its default, the host export that serve runs, environment variables and the deployment secret. - [Database](/docs/operations/database): PostgreSQL requirements, connecting and pooling through PgBouncer, how migrations run, PGlite for development, the runtime tables and the lock order. - [Scaling](/docs/operations/scaling): The PLAN.md section 16 performance gates, what the benchmarks measured so far, how each tier scales, which placer to run, and what breaks first. - [High availability](/docs/operations/high-availability): How worker processes share 256 shards and the singleton jobs through table leases, how a dead worker's or gateway's work moves and how fast, what fences a process that lost its lease, and why it all needs PostgreSQL. - [Upgrades](/docs/operations/upgrades): The order an upgrade runs in, how migrations behave, the version skew allowed between the server, gateways and bcd, rolling bcd out with signed releases, and the API surface freeze that keeps clients working. - [Backup and recovery](/docs/operations/backup-and-recovery): What state lives where (PostgreSQL, the PKI bundle and deployment secret, operator-held keys, bcd's data directory on each node), what to back up, the order to restore in, what a restore cannot bring back, and how nodes rejoin after a loss. - [Requirements and sizing](/docs/operations/hardware-requirements): What the control plane needs and how far the measured numbers go in sizing it, the PostgreSQL version, what a node must have before bcd can run (Linux, systemd, cgroup v2, the NVIDIA driver, KVM and IOMMU for VPS hosts), the GPUs the inventory knows, and the network ports. - [DigitalOcean](/docs/operations/digitalocean): Running compute on DigitalOcean accounts - token scopes, the per-token rate budget, an OAuth app and its redirect URI, provider costs and leaks, findings, Droplet metrics, and the opt-in live suite. - **Secure** - [Security](/docs/operations/security): The trust boundaries and threat model of Better Compute, the controls that enforce them, and a checklist for hardening a deployment. - [PKI](/docs/operations/pki): The local CAs, JoinService keys and signing keys a deployment owns, the pki CLI and bundle, SPIFFE IDs, node certificate lifetimes, revocation and rotation. - **Observe** - [Observability](/docs/operations/observability): Prometheus metrics with bounded labels, a bearer-protected /metrics route, ComputeSpan observers, trace context, health endpoints and doctor. - [Operating on AWS](/docs/operations/aws): CloudWatch metrics through EMF, bcd telemetry through an ADOT collector, Amazon Managed Service for Prometheus, and control-plane spans to X-Ray. - [Retention](/docs/operations/retention): What the retention passes prune from PostgreSQL and when, how cursors hold them back, how history partitions work, and what is kept on purpose. - **Develop** - [Local development](/docs/operations/local-development): Run a whole control plane on your laptop with better-compute dev, join simulated GPU machines with --sim, and run the deterministic fleet simulator. - [Testing](/docs/operations/testing): The testing kit - a control plane on PGlite, the FakeDaemon, faulty links, the fleet simulator and its invariants, real-time harnesses and benchmarks. - Reference: Server API, CLI, protocol, errors, and changelog - [Reference](/docs/reference): Generated reference for the API, the CLI, command kinds, error codes, the daemon protocol, events, modules and packages, from a live control plane and the .proto files. - **Interfaces** - API - [API](/docs/reference/api): Every method of the compute API, by group: 291 registered, 289 in PLAN.md §9.2. - [billing](/docs/reference/api/billing): The platform's billing setup for compute: the meters and prices root keeps on the IAM root tenant, so root can bill its sub-tenants for what they use. Every method is decided as a `compute:billing:*` action on `compute-fleet`, which resolves only in the root tenant, so a tenant administrator is turned away before any IAM decision, however broad the tenant's own grants. A root member needs `compute:billing:read` or `compute:billing:manage` on `compute-fleet`. - [capacity](/docs/reference/api/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). - [certificates](/docs/reference/api/certificates): TLS certificates on a provider account (DigitalOcean first), for the tenant's [load balancers](/docs/reference/api/load-balancers). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.certificates`. Reading takes `compute:certificates:read`, everything else `compute:certificates:manage`, on `provider-certificate/{id}`. Certificates book no quota (at most 100 per tenant) and do not bill. - [cloudResources](/docs/reference/api/cloud-resources): Cloud resources are a provider's managed data and platform services (managed databases and what lives in them, App Platform apps, Functions, Marketplace add-ons, partner attachments), served by the `@better-compute/cloud-resources` module through the provider-neutral `ProviderResources` contract. One table, one reconciler and these calls serve every kind a provider lists: DigitalOcean today (`do.database.pg`, `do.app`, …), AWS and GCP kinds later under their own prefixes. A resource belongs to one provider pool, so to that pool's account. Two hosting models use the same calls: a platform account's pool offered to the tenant (the resource lives on the platform's account, which other tenants share), or a pool on the tenant's own account. The calls record what the tenant wants and return at once; the `cloud.resources` reconciler then creates the resource at the provider, applies changes in place and deletes what the tenant deleted. `state` shows where it is: `pending`, `provisioning`, `ready`, `updating`, `deleting`, `deleted`, `released` or `error` (with a `message`). Resources still converging are looked at every 30 seconds; ready and failed ones are refreshed every five minutes, which retries an error and picks up what changed at the provider. - [commandBatches](/docs/reference/api/command-batches): 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). - [commands](/docs/reference/api/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). - [dnsRecords](/docs/reference/api/dns-records): The records of a tenant's [DNS zone](/docs/reference/api/dns-zones). Every method names the zone and is decided on it: reading takes `compute:dns:read`, everything else `compute:dns:manage`, on `provider-dns-zone/{zoneId}`. Records book no quota (at most 500 per zone) and do not bill. The provider's ownership marker (`_better-compute`) and its apex NS and SOA records are never touched. - [dnsZones](/docs/reference/api/dns-zones): DNS zones on a provider account (DigitalOcean Domains first), with their [records](/docs/reference/api/dns-records). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.dns`. Reading takes `compute:dns:read`, everything else `compute:dns:manage`, on `provider-dns-zone/{id}`. Zones book no quota (at most 50 per tenant) and do not bill. - [drivers](/docs/reference/api/drivers): The drivers this deployment registered through its options, modules and plugins, so `metal.enroll` callers and the console can offer valid choices. The group returns declarations only, never a driver's configuration or credentials. See [Drivers](/docs/extending/drivers). - [events](/docs/reference/api/events): A tenant's CloudEvents-style events, read from the transactional outbox that every change writes to in its own transaction. Pages follow the outbox's `txid:seq` position, so no event ever appears behind a cursor already handed out. See [Events](/docs/guides/events). - [filesystems](/docs/reference/api/filesystems): Filesystems are shared filesystems on a tenant [network](/docs/reference/api/networks) that the network's instances mount at boot: `nfs`, an elastic NFS filesystem across every zone of the network (Amazon EFS on AWS), or `lustre`, a Lustre filesystem in one zone for training scratch and checkpoints (Amazon FSx for Lustre). Like [firewall rules](/docs/reference/api/firewall-rules) they belong to a network and are decided on it: reading them takes `compute:networks:read`, changing them `compute:networks:update`. The provider must support filesystems (AWS does; another provider is `UNSUPPORTED`). The calls record what the tenant wants and return at once. The `vps.filesystems` reconciler then makes the filesystem at the provider once its network has been ready, behind its own security group that admits only the network's machines, and always encrypted at rest. `state` shows where it is: `pending`, `ready`, `deleting`, `deleted` or `error` (with a `message`); an `error` is retried every five minutes. Once ready, `mount` says how a machine mounts it (`fstype`, `source`, `options`): DNS names and mount names, never a secret. - [firewallRules](/docs/reference/api/firewall-rules): Firewall rules belong to a [network](/docs/reference/api/networks) and are decided on it: reading them takes `compute:networks:read`, changing them `compute:networks:update`. A rule says which traffic is allowed or denied, from where and to which instances, and the `vps.networks` reconciler applies it at the provider as a firewall named `bc-` and the rule's id. A rule that names instances applies to the machines carrying those instances' network tags (`bc-` and 16 hex digits of the sha256 of the instance id), which the reconciler sets on each instance that owns its machine (applying rules first: a tag set later still matches); a rule that names none applies to every instance on the network. A network has at most 100 rules that are not deleted. - [flavors](/docs/reference/api/flavors): Flavors are the named instance shapes of a VPS pool: vCPU, memory, disk and GPU count, plus the provider offer a provider pool creates. The pool's owner manages them, and tenants the pool is offered to can list them. An instance keeps the shape it was admitted with, so changing or deleting a flavor never changes a live instance. See [Flavors](/docs/guides/vps/flavors). - [fleet](/docs/reference/api/fleet): The fleet group manages a tenant's platform objects as one FleetConfig document: sites, provider accounts, pools, owner quotas, offers and flavors. `plan` diffs a document against what exists, `apply` runs the plan through the owning modules' own methods, and the applied document is kept so that drift from it is reported. Every method decides `compute:fleet:admin` on the fleet scope. See [Fleet configuration](/docs/guides/fleet-config). - [images](/docs/reference/api/images): The images group is the catalog of OS images and ramdisks that deploys write to disk. An image is registered by its digest and source URL, never uploaded, and a signature from a signer on the tenant's or the platform's allowlist marks it verified. Unsigned images stay private to their tenant; only verified images can be made public. See [Profiles and images](/docs/guides/bare-metal/profiles-and-images). - [instances](/docs/reference/api/instances): Instances are VMs in a VPS pool: hosted pools place them on a host through capacity, and provider pools create them through the pool's provider account. After `create`, every call only changes `desiredState`; the `vps.instances` reconciler converges the instance and publishes `instance.*` events as its `state` moves. Instances are also the sandbox primitive today. See [Instances](/docs/guides/vps/instances). - [inventory](/docs/reference/api/inventory): A node's hardware and software inventory as the daemon reports it, kept as an append-only history of snapshots: a new snapshot is stored each time the node's reported section set changes. Every method decides `compute:nodes:read` on `compute-node/{nodeId}` and only answers for nodes the calling tenant owns. See [Inventory and health](/docs/guides/nodes/inventory-and-health). - [joinRequests](/docs/reference/api/join-requests): Join requests are the approval queue for joins an attestor deferred: a machine with placeholder hardware identifiers, a machine the `discovery` attestor did not know, or a TPM whose endorsement key is on no allow-list. An approval admits exactly one join, which the machine's retry with the same CSR consumes. The group is decided on `compute-pool/{poolId}` with the join-token actions. See [Joining nodes](/docs/guides/nodes/joining). - [joinTokens](/docs/reference/api/join-tokens): Join tokens are single-purpose credentials that let a limited number of daemons join one pool for a limited time. The bearer form `bcjt_.` is returned once, when the token is created; the control plane stores only the SHA-256 of the secret. Every method is decided on `compute-pool/{poolId}`. See [Joining nodes](/docs/guides/nodes/joining). - [kubernetesClusters](/docs/reference/api/kubernetes-clusters): Kubernetes clusters are managed Kubernetes clusters (Google Kubernetes Engine, Standard and Autopilot) on a provider account, served by the `@better-compute/kubernetes` module. The provider runs the control plane; better-compute never runs one itself. A cluster belongs to one provider pool, so to that pool's account, and the account's provider must provide managed Kubernetes (a provider that does not is `UNSUPPORTED`). Two hosting models use the same calls: a platform account's pool offered to the tenant (the cluster lives in the platform's cloud project), or a pool on the tenant's own account (the cluster lives in the tenant's project). The calls record what the tenant wants and return at once; the `kubernetes.clusters` reconciler then creates the cluster at the provider, its node pools once the control plane is up, applies changes in place and deletes what the tenant deleted. `state` shows where it is: `pending`, `provisioning`, `ready` (the control plane and every node pool are ready), `updating`, `deleting`, `deleted` or `error` (with a `message`). The reconciler publishes `kubernetes.cluster.ready` the first time, `kubernetes.cluster.updated` when it is ready again after a change or the provider moved it to another version (a release-channel upgrade), `kubernetes.cluster.error` and `kubernetes.cluster.deleted`. Clusters still converging are looked at every 30 seconds; ready and failed ones are refreshed every five minutes, which retries an error and picks up what changed at the provider. - [kubernetesNodePools](/docs/reference/api/kubernetes-node-pools): Node pools are the groups of worker nodes of a `standard` Kubernetes cluster ([kubernetesClusters](/docs/reference/api/kubernetes-clusters)); an `autopilot` cluster has none, because the provider runs its nodes. A cluster's first node pools are created with it; these calls add, resize and remove pools later. Every call records what the tenant wants and returns at once: the node pool shows `pending`, `ready`, `updating`, `deleting`, `deleted` or `error` (with a `message`), and its cluster goes `updating` until the reconciler has converged the change, then `ready` again. A node pool the provider refuses is `error`, and so is its cluster, with the pool named in its `message`, until the pool is changed or deleted. The reconciler publishes `kubernetes.nodepool.ready`, `kubernetes.nodepool.error` and `kubernetes.nodepool.deleted` on the cluster's subject. A node pool's name is also its provider-side name. - [kubernetesSubstrates](/docs/reference/api/kubernetes-substrates): A pool substrate is the managed Kubernetes cluster behind a pool whose policy has a `substrate` (`kind: 'kubernetes'`, an `account`, and `cluster: { create }` or `cluster: { adopt }`). The `kubernetes.substrates` reconciler records it here: it creates the cluster with one node pool per flavor (or adopts an existing cluster and adds the flavors' node pools to it, named `bc--` so they never collide with the tenant's own pools), server-side applies bcd's DaemonSet with a hosted join token, and the cluster's Nodes join the pool. Every object it applies carries the label `better-compute.dev/substrate-pool=`; on an adopted cluster an object of the same name it did not create is never taken over or deleted. There is nothing to call to create or delete a substrate: change the pool's policy, or archive the pool to tear it down. - [loadBalancers](/docs/reference/api/load-balancers): Load balancers on a provider account (DigitalOcean regional and global first). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.loadBalancers`. Reading takes `compute:load-balancers:read`, everything else `compute:load-balancers:manage`, on `provider-load-balancer/{id}`. A load balancer books one `loadBalancers` quota on the pool (no quota row grants none) and bills `vps.load-balancer.hours` from `ready` until deleted. - [metal](/docs/reference/api/metal): The metal group enrolls machines by their BMCs and moves them through the provision state machine: inspect, commission, deploy, rescue, release and retire. Each verb checks the move against the provision state table, records it in one transaction and queues the metal reconciler, which runs the workflow of the new state; no verb touches the machine itself. Every method returns the node's metal view, which reports whether BMC credentials are set but never returns them. See [Bare metal](/docs/guides/bare-metal) and [BMC drivers and credentials](/docs/guides/bare-metal/bmc). - [networks](/docs/reference/api/networks): Networks are a tenant's private networks (VPCs) on a provider account, with their subnets and firewall rules ([firewallRules](/docs/reference/api/firewall-rules)). A network belongs to one provider pool, so to that pool's account, and the provider must support tenant networks (Google Cloud does; a provider that does not is `UNSUPPORTED`). The calls record what the tenant wants and return at once. The `vps.networks` reconciler then converges the provider: it creates the VPC, then the subnets and the firewall rules, then tags the network's instances, and removes what the tenant deleted, rules first, then subnets, then the network. `state` shows where it is: `pending`, `ready`, `deleting`, `deleted` or `error` (with a `message`). The network's `state` covers the VPC and its subnets (`ready` when all are; `error` with the failing resource in `message`); each subnet and each rule also has its own `state`, and a rule the provider refuses is `error` on the rule without taking the network out of `ready`. The reconciler publishes `network.ready`, `network.error`, `network.subnet.ready`, `network.rule.ready`, `network.rule.error` and `network.deleted`. An `error` is retried by the periodic pass, which runs every five minutes and also re-applies what drifted at the provider (a firewall deleted by hand). - [nodes](/docs/reference/api/nodes): Nodes are machines that joined the control plane, as their tenant sees them: a tenant sees the nodes the authorization projection holds for it. Every method except `list` is decided on `compute-node/{nodeId}`. Mutations take an optional `version`; when the node has moved past it, the call is `CONFLICT`. See [Operating nodes](/docs/guides/nodes/operating-nodes). - [pools](/docs/reference/api/pools): A pool groups the nodes of one site under one GPU model, one sharing mode and one policy, and every reservation and quota belongs to exactly one pool. The tenant that creates a pool owns it; other tenants see it only once the owner offers it to them with a quota. Only the owner can offer, unoffer, update or archive a pool; anyone else gets `NOT_FOUND`. See [Pools](/docs/guides/capacity/pools). - [profiles](/docs/reference/api/profiles): The profiles group stores and checks the versioned recipes that provisioning workflows run: steps, drivers, an image, user data and host config. A version becomes immutable the first time a workflow uses it. Lookups see the tenant's own profiles, public ones, and the read-only profiles that modules ship under the tenant `builtin`. See [Profiles and images](/docs/guides/bare-metal/profiles-and-images). - [projects](/docs/reference/api/projects): Projects group a tenant's work without creating more tenants. A project is app-owned, lives in one tenant, and its creator becomes its owner in the authorization projection; membership is a Better IAM relationship on `compute-project/{id}`. See [Tenancy](/docs/guides/iam/tenancy). - [providerAccounts](/docs/reference/api/provider-accounts): Provider accounts connect a tenant to an external provider registered with `vps({ providers })`, such as a cloud or a dedicated-server host. Each account's `config` is validated by its provider's manifest and holds secret references, never secret values. Provider pools create instances through an account, and `bootstrap` turns one of its machines into a bcd host. See [Providers](/docs/guides/vps/providers). - [providerAddresses](/docs/reference/api/provider-addresses): Reserved public addresses on a provider account (DigitalOcean reserved IPv4 and IPv6 first), assigned to the account's [instances](/docs/reference/api/instances). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.addresses`. Reading takes `compute:addresses:read`, everything else `compute:addresses:manage`, on `provider-address/{id}`. An address books one `addresses` quota on the pool and bills `vps.address.hours` from `ready` until deleted. A DigitalOcean reserved IP carries no name or tag, so the row is the ownership record: one address is recorded by at most one live row, and it keeps the provider's fingerprint from the reserve where there is one (a reserved IPv6's reservation time; a reserved IPv4 has none). An address released at the provider outside better-compute (gone, mismatched, or handed to a later reserve) goes to `error` for good: never re-adopted, assigned or released, and its delete makes no provider call. - [providerSnapshots](/docs/reference/api/provider-snapshots): Snapshots of [provider volumes](/docs/reference/api/provider-volumes), made with `providerVolumes.snapshot` and converged by the `vps.provider-resources` reconciler. Reading takes `compute:volumes:read`, deleting and restoring `compute:volumes:manage`, on `provider-snapshot/{id}`. A snapshot books no quota and bills `vps.snapshot.gib.hours` (the GiB the provider reports) from `ready` until deleted. - [providerVolumes](/docs/reference/api/provider-volumes): Block volumes and shared volumes (network file shares) on a provider account (DigitalOcean Block Storage and Network File Storage first), next to the account's [instances](/docs/reference/api/instances). Every call records what the tenant wants and returns at once, usually `pending`; the `vps.provider-resources` reconciler then converges the provider through `ProviderImpl.volumes` without blocking on provider actions, and writes back what it saw (`state` is `pending`, `ready`, `updating`, `deleting`, `deleted` or `error`, with the provider's `message`). Reading takes `compute:volumes:read`, everything else `compute:volumes:manage`, on `provider-volume/{id}`. A volume books its `sizeGiB` on the tenant's `diskGiB` quota for the pool and bills from `ready` until deleted: a block volume `vps.volume.gib.hours`, a shared volume `vps.share.gib.hours`. Once created, a volume is only read: one deleted at the provider outside better-compute goes to `error` and is never created again (its data is gone; delete it). See the [provider volumes guide](/docs/guides/vps/provider-volumes). - [quotas](/docs/reference/api/quotas): A quota caps how much of one resource a tenant may hold in one pool at the same time, as a `max` and a `used` counter per tenant, pool and resource. A missing row grants 0; `pools.create` and `pools.offer` create the rows, and admissions charge them with `QUOTA_EXCEEDED` when a request does not fit. - [releases](/docs/reference/api/releases): Releases are signed bcd builds the platform may roll out to its nodes. A release is registered from a signed manifest, which must verify under the release key pins given to `rolloutModule`, and rollouts can then target its version. Both methods decide `compute:fleet:admin` on the fleet scope. See [Rollouts](/docs/guides/rollouts). - [reservationGrants](/docs/reference/api/reservation-grants): Reservation grants commit slots of a provider capacity reservation to one tenant for a term. Root makes them: the reservation is the platform's (a GCE reservation on a root provider account, bound to a pool with `providerAccounts.bindReservation`), and a grant hands some of its slots to a tenant the pool is offered to, from `startsAt` to `endsAt`. Times are epoch milliseconds. - [reservations](/docs/reference/api/reservations): A reservation is a tenant's claim on devices of one pool for a time window. `create` first writes the request as a draft, Better IAM decides once on that draft with the request as attributes, and only an allowed draft is charged against quota and placed. A reservation holds its quota charge until it reaches a terminal state, and the `capacity.reservations` reconciler drives it through `placed`, `binding` and `active` to `released`. See [Reservations](/docs/guides/capacity/reservations). - [rollouts](/docs/reference/api/rollouts): Rollouts take a registered bcd release to the nodes of the tenant's pools in waves, within each pool's disruption budget. A controller settles nodes as they report the new version, pauses the rollout when a wave's failure ratio exceeds its limit, and soaks between waves. Every method decides `compute:fleet:admin` on the fleet scope. See [Rollouts](/docs/guides/rollouts). - [sandboxSnapshots](/docs/reference/api/sandbox-snapshots): Sandbox snapshots are their own resource, so a snapshot kept with `keep: true` outlives the sandbox it came from. `sandboxes.snapshot` takes them and `sandboxes.create` restores from them with `fromSnapshot`. These methods list, read and delete them. Snapshots stay private to their tenant and are never promoted to shared images. See [Sandboxes](/docs/guides/vps/sandboxes). - [sandboxTemplates](/docs/reference/api/sandbox-templates): A sandbox template belongs to one tenant and fixes what its sandboxes run: a hosted pool, a flavor, an image, the pool's runtime, optional user data, TTL bounds and a warm pool. For each live template the `vps.sandboxes` reconciler keeps `warm.min` instances with `desiredState` `paused`, or `stopped` when the runtime cannot pause, creating at most 4 per template in one pass and deleting those beyond `warm.max`, newest first. Warm instances are owned by the template's author, placed and charged to quota when they are created, and a refill that fails is logged and tried again on a later pass. See [Sandboxes](/docs/guides/vps/sandboxes). - [sandboxVolumes](/docs/reference/api/sandbox-volumes): Sandbox volumes are persistent disks on one host that a tenant's sandboxes attach across runs, so an agent keeps its memory, caches and checkouts. A volume is placed when it is created: its size is booked as `diskGiB` on one host of the pool, charged to the tenant's quota, and the host keeps it as a sparse raw file. A sandbox template names volumes with a mount path. Sandboxes of that template then run on the volume's host only, attach it as an extra virtio disk, and mount it by serial (`/dev/disk/by-id/virtio-`) from their user data. The first mount formats it as ext4, and no later one ever does. A volume takes any number of read-only attachments or one read-write attachment, never both. Volumes are metered as `vps.volume.gib.hours` from creation until the disk is released. See [Sandboxes](/docs/guides/vps/sandboxes). - [sandboxes](/docs/reference/api/sandboxes): A sandbox is a hosted VPS instance with a template and a lifetime: `create` admits it after one IAM decision, then claims a warm instance of its template or creates one through the instance lifecycle, and the `vps.sandboxes` reconciler, which runs every 15 seconds, deletes it once `expiresAt` passes. A sandbox's `state` follows its instance: `starting`, `ready` while the instance runs, `failed` when it is in `error` or `lost`, `deleting` once deletion was asked, and `deleted` when the instance is gone. The instance belongs to the sandbox: `instances.start`, `stop`, `resize` and `delete` refuse it with `INVALID_STATE`, and `instances.get` still returns it. See [Sandboxes](/docs/guides/vps/sandboxes). - [secrets](/docs/reference/api/secrets): Secrets are write-only: `put` hands a value to the configured secret store and returns its `secret://` reference and version, and no method ever reads a value back. Events and audit rows carry only the reference, name and version; values reach agents through the secret broker, never through the API. Methods are decided on `compute-tenant/{tenantId}`, or on `compute-fleet/global` for platform secrets with `scope: 'fleet'` in the root tenant. See [Security](/docs/operations/security) and [BMC credentials](/docs/guides/bare-metal/bmc). - [siteTokens](/docs/reference/api/site-tokens): Site tokens are join tokens with the role `site`: they enroll `bcd site` agents on one site, which then contend for the site's boot lease. They share the join-token bearer format `bcjt_.` and storage, so the secret is shown once and only its hash is kept. Both methods are decided as `compute:sites:manage` on `compute-site/{siteId}`. See [Sites](/docs/guides/bare-metal/sites). - [sites](/docs/reference/api/sites): Sites are boot and failure domains: every pool and node belongs to one site. Platform sites (`shared`, `dedicated`) belong to the root tenant; a tenant's own hardware lives on its `custom` sites. A tenant sees the sites the authorization projection holds for it. See [Sites](/docs/guides/bare-metal/sites). - [system](/docs/reference/api/system): The `system` group answers questions about the deployment itself. `whoami` and `version` are public and answer without a credential, which makes them a quick connectivity and credential check; `selfCheck` is a fleet administrator's health report and `workQueue` the work queue's backlog. See [Observability](/docs/operations/observability). - [tunnels](/docs/reference/api/tunnels): Interactive access to an instance or a node through its gateway and daemon: exec, SSH, TCP or the serial console of an instance, or the console of a node. The server's tunnels module hosts this group when the deployment configures `tunnels` with an exec ticket issuer. See [Tunnels](/docs/guides/access/tunnels). - [usage](/docs/reference/api/usage): The hourly usage windows compute meters and hands to Better IAM billing, as the tenant can read them: one per hour and meter of every source (allocations of hosted capacity, provider instances, reservation grants, networks, snapshots, and pass-through provider costs). `list` and `export` decide `compute:usage:read` on `compute-tenant/{tenantId}`, or on `compute-project/{projectId}` when the call names a project, since windows carry their project as a tag. `platform`, `deadLetters`, `retry` and `void` are the root tenant's: the cross-tenant view and the corrections to what the usage sink sent. They decide `compute:usage:read` (`compute:usage:manage` for `retry` and `void`) on `compute-fleet/global`, so only root can call them. A voided window is not usage: `list` and `export` leave it out of rows and totals, and `platform` counts it apart. See [Billing and usage](/docs/guides/iam/billing-and-usage). - [webhooks](/docs/reference/api/webhooks): Per-tenant subscriptions that POST every matching committed event to an HTTPS endpoint, signed with a secret only the tenant and Better Compute know, with at-least-once delivery, retries with backoff, dead letters and redelivery. The events module hosts this group, and every method decides `compute:webhooks:manage` on `compute-tenant/{tenantId}`. See [Webhooks](/docs/guides/events/webhooks). - [workflows](/docs/reference/api/workflows): The workflows group reads the provisioning workflows of a node and lets an operator abort, retry, pause or resume one. Workflows are started by other modules, such as metal for each workflow-driven provision state, not through this group. Every method is decided on the node (`compute-node`): reads as `compute:workflows:read`, the others as `compute:workflows:manage`. See [Provisioning workflows](/docs/guides/bare-metal/workflows). - [CLI](/docs/reference/cli): The better-compute command line 0.3.0: 193 commands. - [Protocol](/docs/reference/protocol): Every service, message and enum of the daemon protocol, from the .proto sources, with field numbers and types. - **Catalogs** - [Command kinds](/docs/reference/command-kinds): The 21 command kinds daemons run, with lane, safety flags, timeout and payload. - [Errors](/docs/reference/errors): Every stable error code the API, the SDK and the CLI surface, with its HTTP status. - [Events](/docs/reference/events): The 52 event families the control plane publishes to webhooks, the SSE watch stream and sinks. - [Host config units](/docs/reference/host-units): The 12 config units a node's spec may set, their settings and what bcd does with them. - [Metrics](/docs/reference/metrics): The 57 Prometheus metric families better-compute exposes on /metrics, with their labels. - [Modules](/docs/reference/modules): What each module registers in a full deployment: API groups, migrations, and the jobs the runtime runs. - [Packages](/docs/reference/packages): Every package of the repository, its version, whether a release publishes it, what it is for and its entry points. - **Project** - [Glossary](/docs/reference/glossary): Every term the Better Compute docs use, from atoms and bookings to leases, NodeSpecs and exec tickets, with a link to the page that explains it. - [Use the docs with AI](/docs/reference/ai): Connect AI coding assistants to these docs through their MCP endpoint, or hand them the site as Markdown with llms.txt and per-page Markdown. - [Roadmap](/docs/reference/roadmap): The version plan from P0 to v1.0 with each phase's deliverables and exit gates, and the honest state of every item in the repository today. - [Changelog](/docs/reference/changelog): Release notes for the better-compute packages and the documentation site, every notable change, newest first.