This document is the authoritative statement of what a Cycles implementation MUST, SHOULD, and MAY do to claim conformance with the Cycles Protocol.
Current conformance target: v0.1.25 (runtime base + governance-admin cross-plane surface). This is the version runcycles' own reference servers implement today and the version against which a second implementation can be validated.
Upcoming conformance target: v0.1.26 (action-kind registry, runtime extensions, governance extensions). These specs are published in this repo but are not yet required for conformance; implementations SHOULD plan for them. They will be promoted to MUST in a future revision of this document once the reference stack implements them.
Authoritative sources (v0.1.25):
- all files enumerated in
cycles-spec-index.yamlunderconformance: normativeat or below v0.1.25 (currentlycycles-protocol-v0.yaml), and - any schemas or operations inside
conformance: mixeddocuments (currentlycycles-governance-admin-v0.1.25.yaml) that are individually labeledx-conformance: normative.
Language follows RFC 2119: MUST / MUST NOT / SHOULD / SHOULD NOT / MAY.
Cycles is a minimum protocol. A conformant v0.1.25 server MUST implement 12 operations (4 core runtime reserve/commit/release/extend + 8 cross-plane event / webhook / auth-introspection; getBalances is cross-plane MUST because the admin spec re-declares the runtime's "nice-to-have" path as normative) and SHOULD implement an additional 4 runtime operations (decide, listReservations, getReservation, createEvent) that the spec marks OPTIONAL but that well-rounded servers expose. Total v0.1.25 protocol surface is 16 distinct operations. The server is otherwise free to implement tenant management, budget provisioning, key rotation, and audit UX however it likes.
| File | Target | Conformance | What it defines |
|---|---|---|---|
cycles-protocol-v0.yaml |
v0.1.25 | normative | Runtime base: reserve / commit / release / decide / balances / events |
cycles-governance-admin-v0.1.25.yaml |
v0.1.25 | mixed | Mostly reference admin API (runcycles' management plane; implementers MAY diverge). Eight cross-plane operations and a set of schemas inside this file are normative — see §MUST below. |
cycles-action-kinds-v0.1.26.yaml |
v0.1.26 | upcoming | Action-kind registry + quota primitives. SHOULD today; MUST once v0.1.26 is the active target. |
cycles-protocol-extensions-v0.1.26.yaml |
v0.1.26 | upcoming | DenyDetail, ObserveMode, v0.1.26 evaluation order, v0.1.26 schemas. SHOULD today. |
cycles-governance-extensions-v0.1.26.yaml |
v0.1.26 | upcoming | Policy fields for action quotas / access control; tenant observe_mode. SHOULD today. |
Operations inside v0.1.26 files still carry x-conformance: normative — that label describes each operation's contract within its own spec. Whether the spec is currently required for conformance is a separate question, answered by "current conformance target" above.
A conformant implementation MUST:
Implement and honor the semantics of the 4 core runtime operations:
POST /v1/reservations— createReservationPOST /v1/reservations/{reservation_id}/commit— commitReservationPOST /v1/reservations/{reservation_id}/release— releaseReservationPOST /v1/reservations/{reservation_id}/extend— extendReservation (TTL heartbeat for long-running operations)
The other runtime endpoints marked OPTIONAL / nice-to-have in cycles-protocol-v0.yaml (decide, listReservations, getReservation, createEvent) are listed under §SHOULD below. GET /v1/balances is also marked "nice-to-have" in the runtime spec but is re-declared as a normative cross-plane op in cycles-governance-admin-v0.1.25.yaml — it therefore appears under §MUST / Cross-plane operations, not §SHOULD. Where implemented, all these endpoints MUST follow the spec contract (paths, schemas, error codes) per their x-conformance: normative labels.
- Atomic reservation — budget is locked across all affected scopes in one step; no partial locks.
- Concurrency-safe enforcement — shared budgets MUST NOT be oversubscribed under concurrent reserve calls.
- Idempotent commit and release — retries MUST be safe; the same action MUST NOT settle twice.
- Unit consistency — every reserve / commit / release / event operation MUST validate and preserve unit denomination.
Return the exact HTTP status + error code pairs defined in cycles-protocol-v0.yaml §ERROR SEMANTICS — including BUDGET_EXCEEDED (409), OVERDRAFT_LIMIT_EXCEEDED (409), IDEMPOTENCY_MISMATCH (409), RESERVATION_FINALIZED (409), RESERVATION_EXPIRED (410), UNIT_MISMATCH (400), NOT_FOUND (404), and DEBT_OUTSTANDING (409). The v0.1.26 action-governance error codes (ACTION_QUOTA_EXCEEDED, ACTION_KIND_NOT_ALLOWED, ACTION_KIND_DENIED) are upcoming and listed under §Upcoming below.
Authenticate via X-Cycles-API-Key header and enforce tenant isolation per cycles-protocol-v0.yaml §AUTH & TENANCY. How API keys are provisioned, rotated, or scoped to permissions is implementation-specific.
Although cycles-governance-admin-v0.1.25.yaml is mostly reference (the tenant / budget / policy / API-key / audit CRUD is runcycles' own shape), eight operations and a set of schemas in that file are normative because they expose the protocol's event stream, webhook delivery contract, and balance / auth introspection surface across planes. Each carries an explicit x-conformance: normative label.
Normative operations (8):
GET /v1/admin/events— listEventsGET /v1/admin/events/{event_id}— getEventPOST /v1/admin/webhooks/{subscription_id}/replay— replayEventsGET /v1/events— listTenantEvents (tenant-scoped)GET /v1/admin/webhooks/{subscription_id}/deliveries— listWebhookDeliveriesGET /v1/webhooks/{subscription_id}/deliveries— listTenantWebhookDeliveries (tenant-scoped)GET /v1/balances— getBalances (admin-plane view of the same path served by the runtime base)GET /v1/auth/introspect— introspectAuth
Normative schemas:
Event,EventType, and allEventData*payload variantsWebhookDeliveryenvelope, signature header rules, and retry semantics (WebhookRetryPolicy)Permissionenum- shared
Amount,Subject,Balance(originate incycles-protocol-v0.yaml; re-referenced here)
Any events emitted MUST conform to the EventType enum and EventData* payload schemas; any webhooks delivered MUST match the WebhookDelivery envelope shape, signature header rules, and retry semantics.
Transitional: these operations and schemas currently live inside
cycles-governance-admin-v0.1.25.yaml. A future revision will extract the event and webhook content into dedicatedcycles-events-v0.yamlandcycles-webhooks-v0.yamlfiles. The contract is normative regardless of file location.
A conformant implementation SHOULD:
- Emit events for budget-state changes (reservation., budget., quota.*) matching the
EventTypeenum. Implementations MAY sample or filter which events they emit, but emitted events MUST follow the schema. - Propagate
X-Cycles-Trace-Idand W3Ctraceparentheaders percycles-protocol-v0.yaml§CORRELATION AND TRACING. Trace correlation is central to multi-service debugging. - Implement
POST /v1/decide— marked OPTIONAL in the v0 spec, but agent frameworks need soft-landing signals for graceful degradation. - Implement
GET /v1/reservations(listReservations) — marked OPTIONAL in v0; useful for reservation recovery (re-discover a lostreservation_idviaidempotency_key) and for identifying stuckACTIVEreservations. - Implement
GET /v1/reservations/{reservation_id}(getReservation) — marked "optional, for debugging" in v0; valuable for support / monitoring of long-running reservations. - Implement
POST /v1/events(createEvent) — marked OPTIONAL in v0; the post-only accounting path for cases where pre-estimation is unavailable (bills-later providers, receipt ingestion).
Note on
GET /v1/balances: the runtime spec summary calls it "nice-to-have", but the admin spec (cycles-governance-admin-v0.1.25.yaml) re-declares the same path + operationId as a normative cross-plane op. The more-restrictive declaration wins:getBalancesis therefore listed under §MUST (cross-plane operations), not here.
- Publish metrics / logs when scopes enter
is_over_limit: truestate so operators can reconcile.
These specs are published in this repo but are not yet required for conformance. runcycles' reference servers do not implement them yet. A conformant implementation SHOULD plan for them; they will become MUST in a future revision of this document once the reference stack ships support.
- Action-kind registry (
cycles-action-kinds-v0.1.26.yaml) — 4 operations:GET /v1/action-kinds— listActionKindsGET /v1/action-kinds/{kind}— getActionKindGET /v1/admin/action-quota-counters— listActionQuotaCountersPOST /v1/admin/action-quota-counters/reset— resetActionQuotaCounter
- Runtime extensions (
cycles-protocol-extensions-v0.1.26.yaml) — no new paths; addsDenyDetail,ObserveMode, the full reservation evaluation order (access control → risk-class quotas → per-kind quotas → budget), and the new error codesACTION_QUOTA_EXCEEDED,ACTION_KIND_NOT_ALLOWED,ACTION_KIND_DENIED. - Governance extensions (
cycles-governance-extensions-v0.1.26.yaml) — 2 PATCH operations (updateTenantObserveMode,updatePolicyActionQuotas) and the policy field contracts (action_quotas,risk_class_quotas,allowed_action_kinds,denied_action_kinds, tenantobserve_mode). The PATCH endpoints MAY be replaced by an equivalent mechanism (config file, direct DB write), but once v0.1.26 is the active target the field contracts MUST be evaluated at reserve time percycles-protocol-extensions-v0.1.26.yaml§RESERVATION EVALUATION ORDER.
A conformant implementation MAY:
- Adopt the shape of
cycles-governance-admin-v0.1.25.yaml(tenants, budgets, policies, API keys, audit, webhook subscriptions, bulk operations) wholesale, as runcycles does. - Replace any or all of those reference portions with an alternative provisioning mechanism: OAuth/OIDC for auth, GitOps YAML for policies, internal admin console for tenants, direct DB writes for budget allocation, etc. (The reference portions only — the eight normative cross-plane operations listed under §MUST still apply.)
- Skip
audit_logentirely. Not required by the protocol. - Expose additional endpoints beyond those specified, as long as they use a non-
/v1path prefix or a vendor-namespaced extension path (e.g.,/v1/x-runcycles/...).
A Cycles conformance test kit (a set of black-box curl/pytest probes any server can be pointed at) is planned but not yet published. Until it exists, conformance is asserted by:
- Validating your OpenAPI descriptor against
merged/cycles-openapi-protocol-merged.yamlusing any OpenAPI 3.1.0 validator. - Passing the Spectral ruleset in
.spectral.yamlon your own spec. - Running the runcycles reference Python/TypeScript/Rust clients against your server's
/v1/reservationsendpoints and verifying expected ALLOW / DENY / error behavior.
A dedicated conformance kit is tracked for a future release. Contributions welcome.
Open an issue or discussion in runcycles/cycles-protocol.