From 402307a88906e9fd090159e5ccf2d0036e6aec83 Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Mon, 20 Jul 2026 19:50:40 -0400 Subject: [PATCH] fix: require non-negative policy priority Align the governance create, update, and response schemas on the existing non-negative priority invariant, and carry the constraint into the standalone governance extension and generated admin artifact. --- README.md | 2 +- changelogs/cycles-governance-admin.md | 15 +++++++++++++++ changelogs/cycles-governance-extensions.md | 11 +++++++++++ cycles-governance-admin-v0.1.25.yaml | 13 ++++++++----- cycles-governance-extensions-v0.1.26.yaml | 3 ++- cycles-spec-index.yaml | 8 ++++---- merged/cycles-openapi-admin-merged.yaml | 13 ++++++++----- 7 files changed, 49 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3eb9450..b51d612 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Cycles is the protocol layer that ensures agents cannot authorize more spend or --- -**Spec suite:** v0.1.26 · **Current conformance target:** v0.1.25 · **Runtime base:** v0.1.25 · **Governance base:** v0.1.25.41 (semantic_base 0.1.25.9) · **API path:** `/v1` · **License:** Apache 2.0 +**Spec suite:** v0.1.26 · **Current conformance target:** v0.1.25 · **Runtime base:** v0.1.25 · **Governance base:** v0.1.25.42 (semantic_base 0.1.25.9) · **API path:** `/v1` · **License:** Apache 2.0 The Cycles spec suite is organized by conformance status. The **current conformance target is v0.1.25** — the version runcycles' own reference servers implement today. v0.1.26 specs are published in this repo but not yet required; they are the **upcoming** target and will be promoted to normative once the reference stack implements them. diff --git a/changelogs/cycles-governance-admin.md b/changelogs/cycles-governance-admin.md index 1b2c4b3..7318855 100644 --- a/changelogs/cycles-governance-admin.md +++ b/changelogs/cycles-governance-admin.md @@ -6,6 +6,21 @@ New entries are added directly to this file. See `scripts/validate_changelogs.py --- +## v0.1.25.42 — 2026-07-20 + +- **Policy priority contract aligned.** `Policy.priority` has always declared + `minimum: 0`, but `PolicyCreateRequest.priority` and the inline + `updatePolicy` PATCH body previously accepted any integer. A negative write + could therefore produce a persisted `Policy` that violated its own response + schema. Both write schemas now declare `minimum: 0`; omitted priority still + defaults to `0`, and zero or positive integers are unchanged. +- **Violation behavior.** The existing `400 INVALID_REQUEST` response covers a + negative priority on create or update. This is an intentional validation + tightening for values that could not produce a schema-conformant resource; + it adds no field, status code, or representation change. The governance + semantic base remains `0.1.25.9` because the correction enforces the + pre-existing `Policy.priority` domain invariant. + ## v0.1.25.41 — 2026-07-11 Corrects three issues in v0.1.25.40 (all reviewer findings against merged main). diff --git a/changelogs/cycles-governance-extensions.md b/changelogs/cycles-governance-extensions.md index 3515302..eb06df6 100644 --- a/changelogs/cycles-governance-extensions.md +++ b/changelogs/cycles-governance-extensions.md @@ -6,6 +6,17 @@ New entries are added directly to this file. See `scripts/validate_changelogs.py --- +## v0.1.28 — 2026-07-20 + +- Aligns the extension's portable restatement of the base `updatePolicy` + fields with governance base revision `0.1.25.42`: `priority` now carries + `minimum: 0`. The merged artifact already composes the base constraint via + `allOf`; this revision ensures tooling that reads the extension document in + isolation sees the same non-negative invariant. +- No extension field or runtime behavior changes. Zero and positive priorities + remain valid; negative priorities could not produce a base-schema-conformant + `Policy` response. + ## v0.1.27 — 2026-04-18 - Cross-surface correlation — adds `trace_id` (W3C Trace Context- diff --git a/cycles-governance-admin-v0.1.25.yaml b/cycles-governance-admin-v0.1.25.yaml index 05bf6b0..ad33813 100644 --- a/cycles-governance-admin-v0.1.25.yaml +++ b/cycles-governance-admin-v0.1.25.yaml @@ -1,12 +1,12 @@ openapi: 3.1.0 info: title: Complete Budget Governance Admin API - version: 0.1.25.41 + version: 0.1.25.42 license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 summary: >- - Stable governance base — document revision 0.1.25.41; semantic base + Stable governance base — document revision 0.1.25.42; semantic base frozen at 0.1.25.9. This file is self-sufficient for the current v0.1.25 conformance target (it adds a normative tenant-close cascade contract at @@ -48,7 +48,9 @@ info: halves into a single normative cross-plane WEBHOOK SUBSCRIPTION INVARIANT (tenant-owned subscriptions carry only tenant-accessible selectors, by any provisioning mechanism) on the conformance surface, - and fixes the #209 operator migration recipe to be submittable) + and fixes the #209 operator migration recipe to be submittable; + document revision 0.1.25.42 makes the non-negative Policy priority + invariant consistent across create, update, and response schemas) and also serves as the base for the upcoming v0.1.26 spec family. Covers tenant management, authentication, and runtime enforcement. NOTE: This file alone is NOT sufficient for the @@ -326,7 +328,7 @@ info: target. Reference-implementation status is tracked in CONFORMANCE.md and the changelog, not in this contract prose (see AUTHORING CONVENTION). Document revision - 0.1.25.41; semantic base frozen at 0.1.25.9 + 0.1.25.42; semantic base frozen at 0.1.25.9 (see cycles-spec-index.yaml for the versioning model). The upcoming v0.1.26 target adds new capabilities (action quotas, @@ -1179,6 +1181,7 @@ components: type: string priority: type: integer + minimum: 0 default: 0 caps: $ref: '#/components/schemas/Caps' @@ -5370,7 +5373,7 @@ paths: properties: name: {type: string} description: {type: string} - priority: {type: integer} + priority: {type: integer, minimum: 0} caps: {$ref: '#/components/schemas/Caps'} commit_overage_policy: {$ref: '#/components/schemas/CommitOveragePolicy'} reservation_ttl_override: {$ref: '#/components/schemas/ReservationTtlOverride'} diff --git a/cycles-governance-extensions-v0.1.26.yaml b/cycles-governance-extensions-v0.1.26.yaml index 096126d..2308c40 100644 --- a/cycles-governance-extensions-v0.1.26.yaml +++ b/cycles-governance-extensions-v0.1.26.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: Cycles Governance Extensions — Admin Plane - version: 0.1.27 + version: 0.1.28 license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0 @@ -685,6 +685,7 @@ paths: type: string priority: type: integer + minimum: 0 caps: type: object commit_overage_policy: diff --git a/cycles-spec-index.yaml b/cycles-spec-index.yaml index 7c5728d..ffad285 100644 --- a/cycles-spec-index.yaml +++ b/cycles-spec-index.yaml @@ -70,10 +70,10 @@ spec_family: current_versions: base_runtime: "0.1.25.15" # payment-rail terminology boundary clarification; no wire-format change base_runtime_semantic_base: "0.1.25" # frozen wire baseline — runtime 0.1.25.15 is documentation-only - base_governance: "0.1.25.41" # unify webhook selector boundary into a cross-plane conformance INVARIANT + conformance-status tracking + migration recipe fix + base_governance: "0.1.25.42" # align non-negative policy priority across create, update, and response schemas base_governance_semantic_base: "0.1.25.9" # frozen wire baseline extension_runtime: "0.1.27" # ErrorCodeExtension base-list refresh (+ LIMIT_EXCEEDED, TENANT_CLOSED) against runtime 0.1.25.13 - extension_governance: "0.1.27" # trace_id plus response correlation headers + extension_governance: "0.1.28" # retain the base policy priority minimum in the extended PATCH action_kinds: "0.1.27" # trace_id plus X-Cycles-Trace-Id response headers evidence_envelope: "0.2.1" # ErrorResponseMirror re-cut against canonical ErrorCode 0.1.25.13 (+ LIMIT_EXCEEDED, TENANT_CLOSED) spec_index: "0.1.43" # include evidence envelope in the canonical publication summary @@ -112,7 +112,7 @@ documents: - id: governance_base file: cycles-governance-admin-v0.1.25.yaml - version: "0.1.25.41" # webhook subscription cross-plane conformance invariant + conformance-status tracking (matches info.version) + version: "0.1.25.42" # non-negative policy priority request/response alignment (matches info.version) semantic_base: "0.1.25.9" # frozen wire baseline role: base conformance: mixed @@ -236,7 +236,7 @@ documents: - id: governance_extension file: cycles-governance-extensions-v0.1.26.yaml - version: "0.1.27" # trace_id plus response correlation headers + version: "0.1.28" # retain the base policy priority minimum in the extended PATCH role: extension extends: governance_base conformance: normative diff --git a/merged/cycles-openapi-admin-merged.yaml b/merged/cycles-openapi-admin-merged.yaml index 77094af..e4e9c6e 100644 --- a/merged/cycles-openapi-admin-merged.yaml +++ b/merged/cycles-openapi-admin-merged.yaml @@ -4,8 +4,8 @@ # This is the pre-built admin-plane merged artifact for Cycles v0.1.26. # To regenerate: python scripts/merge_specs.py # Sources: -# - cycles-governance-admin-v0.1.25.yaml (v0.1.25.41, governance base) -# - cycles-governance-extensions-v0.1.26.yaml (v0.1.27, governance extension) +# - cycles-governance-admin-v0.1.25.yaml (v0.1.25.42, governance base) +# - cycles-governance-extensions-v0.1.26.yaml (v0.1.28, governance extension) # - cycles-action-kinds-v0.1.26.yaml (v0.1.27, action kind registry) # - cycles-protocol-extensions-v0.1.26.yaml (v0.1.27, runtime extension — schemas only) # Canonical sources live at the paths above. Edit source files, regenerate. @@ -21,7 +21,7 @@ info: MERGED ARTIFACT — not canonical. Generated by scripts/merge_specs.py. Admin/governance plane for the Cycles Protocol v0.1.26 spec suite. Covers: - - Tenant / budget / policy / API key / webhook management (governance base v0.1.25.41) + - Tenant / budget / policy / API key / webhook management (governance base v0.1.25.42) - v0.1.26 policy extensions: action_quotas, risk_class_quotas, allow/deny lists - v0.1.26 tenant extension: observe_mode - v0.1.25.8 dashboard enrichments: AdminOverviewResponse optional fields, @@ -30,8 +30,8 @@ info: - action_quotas:read permission (enforced v0.1.26, balances:read fallback) Source specs: - - cycles-governance-admin-v0.1.25.yaml (governance base v0.1.25.41) - - cycles-governance-extensions-v0.1.26.yaml (governance extension v0.1.27) + - cycles-governance-admin-v0.1.25.yaml (governance base v0.1.25.42) + - cycles-governance-extensions-v0.1.26.yaml (governance extension v0.1.28) - cycles-action-kinds-v0.1.26.yaml (action kinds v0.1.27) - cycles-protocol-extensions-v0.1.26.yaml (runtime extension v0.1.27, schemas only) @@ -848,6 +848,7 @@ components: type: string priority: type: integer + minimum: 0 default: 0 caps: $ref: '#/components/schemas/Caps' @@ -6025,6 +6026,7 @@ paths: type: string priority: type: integer + minimum: 0 caps: $ref: '#/components/schemas/Caps' commit_overage_policy: @@ -6053,6 +6055,7 @@ paths: type: string priority: type: integer + minimum: 0 caps: type: object commit_overage_policy: