Skip to content

docs: add budget override API reference and OpenAPI spec - #5736

Merged
akshaydeo merged 1 commit into
mainfrom
07-31-docs_added_budget_override_docs_for_virtual_keys
Jul 31, 2026
Merged

akshaydeo merged 1 commit into
mainfrom
07-31-docs_added_budget_override_docs_for_virtual_keys

Conversation

@impoiler

@impoiler impoiler commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an override_amount on top of the base max_limit, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed via PUT/DELETE on /api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override.

Changes

  • Added a Budget overrides section to budget-and-limits.mdx explaining the effective_max_limit = max_limit + override_amount enforcement model and linking to the virtual keys walkthrough.
  • Expanded the override section in virtual-keys.mdx with full API usage examples for PUT (both cycles and forever modes) and DELETE, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.
  • Registered PUT and DELETE endpoints for /api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override in the OpenAPI spec (both JSON and YAML), including request/response schemas (BudgetOverrideRequest, BudgetOverrideResponse) and new override fields on the Budget schema (override_amount, override_mode, override_cycles_remaining, override_cycles_total, override_anchor_reset).

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

  1. Navigate to the Budget overrides section in budget-and-limits.mdx and confirm the formula and cross-link render correctly.
  2. Navigate to the override API section in virtual-keys.mdx and verify all code blocks, the sample response, and the behavioral notes display as expected.
  3. Load the OpenAPI spec and confirm the two new endpoints appear under the Governance tag with correct request/response schemas and that the Budget schema includes the five new override fields.

Breaking changes

  • Yes
  • No

Related issues

Security considerations

The new endpoints require ManagementBearerAuth, consistent with all other governance management endpoints. No new auth surface is introduced.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@mintlify

mintlify Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
bifrost 🟢 Ready View Preview Jul 31, 2026, 8:14 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@impoiler impoiler changed the title docs: added budget override docs for virtual keys docs: add budget override API reference and OpenAPI spec Jul 31, 2026
@impoiler impoiler self-assigned this Jul 31, 2026
@impoiler
impoiler marked this pull request as ready for review July 31, 2026 08:15
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for temporary or permanent spending-limit overrides for virtual-key budgets.
    • Overrides can be created, replaced, or removed through the management API and budget information interface.
    • Finite overrides may expire after a configured number of reset cycles.
    • Added budget details showing override amounts, remaining cycles, and effective spending limits.
  • Documentation

    • Added setup guidance, validation rules, persistence behavior, API examples, and schema references for budget overrides.

Walkthrough

The documentation adds virtual-key budget override concepts, API contracts, authenticated PUT and DELETE operations, lifecycle rules, validation behavior, reset-cycle handling, and governance UI guidance.

Changes

Virtual-key budget overrides

Layer / File(s) Summary
Budget override schemas
docs/openapi/schemas/management/governance.yaml, docs/openapi/openapi.json
The Budget schema now exposes override amount, mode, cycle counters, and reset anchor fields. BudgetOverrideRequest and BudgetOverrideResponse define override inputs and persisted results.
Governance API operations
docs/openapi/paths/management/governance.yaml, docs/openapi/openapi.yaml, docs/openapi/openapi.json
The OpenAPI contract adds authenticated operations for setting, replacing, and deleting virtual-key budget overrides, with success and error responses.
Governance documentation
docs/features/governance/budget-and-limits.mdx, docs/features/governance/virtual-keys.mdx
The feature documentation describes effective limits, finite and perpetual overrides, validation, persistence, expiry, reset behavior, UI management, and API usage.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • maximhq/bifrost#5434: Implements the related budget override fields and database migration.
  • maximhq/bifrost#5435: Implements the corresponding virtual-key budget override APIs and schemas.
  • maximhq/bifrost#5436: Implements override lifecycle, persistence, reset-cycle consumption, and limit enforcement.

Suggested reviewers: akshaydeo, pratham-mishra04

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the documentation and OpenAPI changes for budget overrides.
Description check ✅ Passed The description covers the purpose, changes, testing steps, affected areas, security, and breaking-change status; optional issue links and checklist items remain incomplete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 07-31-docs_added_budget_override_docs_for_virtual_keys

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 oasdiff (1.26.0)
docs/openapi/openapi.yaml

Error: failed to load base spec from "/tmp/coderabbit-oasdiff-base.Nh7U21": encountered disallowed external reference: "./paths/inference/async.yaml#/components/parameters/AsyncJobId"


Comment @coderabbitai help to get the list of available commands.

akshaydeo commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Jul 31, 8:18 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 31, 8:19 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit a7742dd into main Jul 31, 2026
14 of 15 checks passed
@akshaydeo
akshaydeo deleted the 07-31-docs_added_budget_override_docs_for_virtual_keys branch July 31, 2026 08:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
docs/features/governance/virtual-keys.mdx (1)

529-565: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a cycles-mode response example.

The response example (Lines 552-565) reflects only the forever-mode call. It omits the cycle-tracking fields a cycles-mode grant would return, such as override_cycles_remaining and override_cycles_total. Add a short response example for the cycles call (Lines 532-539) so readers see those fields without needing to open the API Reference.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/features/governance/virtual-keys.mdx` around lines 529 - 565, Add a
concise JSON response example immediately after the cycles-mode curl request,
showing the cycle grant response fields including override_mode set to cycles,
override_cycles_remaining, and override_cycles_total. Keep the existing
forever-mode request and response example unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/openapi/openapi.json`:
- Around line 82481-82505: Update BudgetOverrideRequest in
docs/openapi/schemas/management/governance.yaml with exclusiveMinimum: 0 for
amount and OpenAPI 3.1 conditional schemas requiring positive cycles for mode
"cycles" and omitted-or-zero cycles for mode "forever"; regenerate
docs/openapi/openapi.json at both listed ranges. Update Budget to represent
inactive mode as override_mode: "", require zero inactive override values while
omitting only override_anchor_reset, and enforce positive active amounts plus
valid finite-cycle fields; remove omitempty from inactive response fields when
needed to serialize their zero values.
- Around line 45035-45186: Update the bundled OpenAPI schemas
`BudgetOverrideRequest` and `Budget` to match the governance contract: require
`amount` to be strictly positive, enforce `cycles` validation conditionally when
the override mode is `cycles`, and include the inactive empty-string mode plus
the zero-value lifecycle state in `Budget`. Preserve the existing operation
definitions and references.

In `@docs/openapi/paths/management/governance.yaml`:
- Around line 268-320: Update BudgetOverrideRequest in both OpenAPI schema
sources to require a positive finite amount and enforce mode-dependent cycles:
cycles mode must use a positive count, while forever permits cycles 0; remove
the unconditional minimum that rejects this case. Update Budget to require
inactive override fields to be zero, omit the anchor when inactive, and enforce
override_cycles_total >= override_cycles_remaining, keeping the JSON definition
synchronized with the YAML schema.

In `@docs/openapi/schemas/management/governance.yaml`:
- Around line 33-55: The governance schema must document inactive overrides as
zero-valued rather than omitted, with an empty override mode and only
override_anchor_reset omitted. Update the property descriptions and enum/model
definitions around override_amount, override_mode, override_cycles_remaining,
and override_cycles_total, ensuring the inactive empty mode is accepted
consistently with config.schema.json while retaining the existing active-mode
values.
- Around line 167-183: Update BudgetOverrideRequest so amount uses
exclusiveMinimum: 0, and replace the global cycles minimum with mode-dependent
oneOf or if/then constraints: require cycles with minimum 1 for mode cycles,
while omitting cycles for mode forever. Apply the same schema changes to
docs/openapi/openapi.json.

---

Nitpick comments:
In `@docs/features/governance/virtual-keys.mdx`:
- Around line 529-565: Add a concise JSON response example immediately after the
cycles-mode curl request, showing the cycle grant response fields including
override_mode set to cycles, override_cycles_remaining, and
override_cycles_total. Keep the existing forever-mode request and response
example unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 722bf00a-35bb-4a89-9203-90d60645ca34

📥 Commits

Reviewing files that changed from the base of the PR and between 22f98fc and 3569e41.

📒 Files selected for processing (6)
  • docs/features/governance/budget-and-limits.mdx
  • docs/features/governance/virtual-keys.mdx
  • docs/openapi/openapi.json
  • docs/openapi/openapi.yaml
  • docs/openapi/paths/management/governance.yaml
  • docs/openapi/schemas/management/governance.yaml

Comment thread docs/openapi/openapi.json
Comment on lines +45035 to +45186
"/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override": {
"put": {
"operationId": "updateVirtualKeyBudgetOverride",
"summary": "Set virtual key budget override",
"description": "Sets or replaces the spending override on one of a virtual key's budgets. The override is additive —\nwhile it is active the budget is enforced against `max_limit + override_amount` — and it leaves the\nbudget's base limit, current usage, and reset schedule untouched.\n\nUse `mode: cycles` with a `cycles` count to grant extra spend for a finite number of reset windows\n(the current window counts as the first), or `mode: forever` to keep the override until it is deleted.\nA finite grant is anchored to the budget's current reset window, so every node in a cluster derives the\nsame number of remaining cycles and a config reload cannot resurrect a spent one.\n",
"tags": [
"Governance"
],
"parameters": [
{
"name": "vk_id",
"in": "path",
"required": true,
"description": "Virtual key ID",
"schema": {
"type": "string"
}
},
{
"name": "budget_id",
"in": "path",
"required": true,
"description": "ID of a budget owned by the virtual key",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BudgetOverrideRequest"
}
}
}
},
"security": [
{
"ManagementBearerAuth": []
}
],
"responses": {
"200": {
"description": "Budget override applied successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BudgetOverrideResponse"
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BifrostError"
}
}
}
},
"404": {
"description": "Virtual key or budget not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BifrostError"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BifrostError"
}
}
}
}
}
},
"delete": {
"operationId": "deleteVirtualKeyBudgetOverride",
"summary": "Remove virtual key budget override",
"description": "Removes any active override from the budget, so it is enforced against its base `max_limit` again.\nThe budget's current usage and reset schedule are unchanged, and the removal is permanent — a cleared\ngrant cannot be re-derived. Safe to call on a budget that has no override.\n",
"tags": [
"Governance"
],
"parameters": [
{
"name": "vk_id",
"in": "path",
"required": true,
"description": "Virtual key ID",
"schema": {
"type": "string"
}
},
{
"name": "budget_id",
"in": "path",
"required": true,
"description": "ID of a budget owned by the virtual key",
"schema": {
"type": "string"
}
}
],
"security": [
{
"ManagementBearerAuth": []
}
],
"responses": {
"200": {
"description": "Budget override removed successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BudgetOverrideResponse"
}
}
}
},
"404": {
"description": "Virtual key or budget not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BifrostError"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BifrostError"
}
}
}
}
}
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

jq -e '
  .paths["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]
  | {put, delete}
' docs/openapi/openapi.json

jq -e '
  .components.schemas
  | {Budget, BudgetOverrideRequest, BudgetOverrideResponse}
' docs/openapi/openapi.json

rg -n -C 16 \
  'virtual-keys/\{vk_id\}/budgets/\{budget_id\}/override|BudgetOverride(Request|Response)|override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)' \
  docs/openapi/openapi.yaml \
  docs/openapi/paths/management/governance.yaml \
  docs/openapi/schemas/management/governance.yaml

Repository: maximhq/bifrost

Length of output: 33738


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- OpenAPI version ---'
sed -n '1,35p' docs/openapi/openapi.yaml
jq -r '.openapi // .swagger' docs/openapi/openapi.json

printf '%s\n' '--- Source path definition ---'
sed -n '268,362p' docs/openapi/paths/management/governance.yaml

printf '%s\n' '--- Source schema definitions ---'
sed -n '1,75p' docs/openapi/schemas/management/governance.yaml
sed -n '157,197p' docs/openapi/schemas/management/governance.yaml

printf '%s\n' '--- Bundled path and schemas ---'
jq '.paths["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]' docs/openapi/openapi.json
jq '.components.schemas.Budget, .components.schemas.BudgetOverrideRequest, .components.schemas.BudgetOverrideResponse' docs/openapi/openapi.json

Repository: maximhq/bifrost

Length of output: 17692


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Governance budget override contract ---'
rg -n -C 12 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride|budget override|mode.*empty|empty.*mode' \
  transports/config.schema.json \
  --glob '!docs/openapi/openapi.json'

printf '%s\n' '--- Implementation references ---'
rg -n -C 10 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
  --glob '!node_modules' \
  --glob '!dist' \
  --glob '!build' \
  --glob '!docs/openapi/openapi.json' \
  .

printf '%s\n' '--- Governance documentation navigation ---'
rg -n -C 8 \
  'governance|openapi/openapi.json|API Reference' \
  docs/docs.json docs \
  --glob '!docs/openapi/openapi.json'

Repository: maximhq/bifrost

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Config schema matches ---'
rg -n -C 18 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride|budget override|mode.*empty|empty.*mode' \
  transports/config.schema.json

printf '%s\n' '--- Matching implementation files ---'
rg -l \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
  . \
  --glob '!docs/**' \
  --glob '!node_modules/**' \
  --glob '!dist/**' \
  --glob '!build/**' \
  --glob '!*.sum' \
  | head -80

printf '%s\n' '--- Navigation and API reference entries ---'
rg -n -C 10 \
  'OSS Governance|governance|openapi/openapi.json|API Reference' \
  docs/docs.json

Repository: maximhq/bifrost

Length of output: 22082


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Handler override logic ---'
rg -n -C 16 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
  transports/bifrost-http/handlers/governance.go

printf '%s\n' '--- Budget persistence and model logic ---'
rg -n -C 12 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)' \
  framework/configstore/tables/budget.go \
  framework/configstore/rdb.go \
  framework/configstore/migrations.go \
  plugins/governance/store.go

printf '%s\n' '--- Tests for override state and validation ---'
rg -n -C 12 \
  'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|mode.*empty|empty.*mode|amount.*0|cycles' \
  transports/bifrost-http/handlers/governance_test.go \
  framework/configstore/migrations_test.go

Repository: maximhq/bifrost

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json

with open("docs/openapi/openapi.json", encoding="utf-8") as f:
    api = json.load(f)
with open("transports/config.schema.json", encoding="utf-8") as f:
    config = json.load(f)

path = api["paths"]["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]
request = api["components"]["schemas"]["BudgetOverrideRequest"]
budget = api["components"]["schemas"]["Budget"]
config_budget = config["$defs"]["budget_line"]

print("openapi:", api["openapi"])
print("put.operationId:", path["put"]["operationId"])
print("delete.operationId:", path["delete"]["operationId"])
print("put.security:", path["put"]["security"])
print("delete.security:", path["delete"]["security"])
print("request.amount.constraints:",
      {k: request["properties"]["amount"].get(k)
       for k in ("minimum", "exclusiveMinimum", "maximum", "exclusiveMaximum")})
print("request.cycles.minimum:", request["properties"]["cycles"].get("minimum"))
print("request.has_conditional_keywords:",
      any(k in request for k in ("if", "then", "else", "oneOf", "anyOf", "allOf")))
print("budget.override_mode.enum:", budget["properties"]["override_mode"].get("enum"))
print("config.override_mode.enum:", config_budget["properties"]["override_mode"].get("enum"))
print("config.inactive_rules:", config_budget["allOf"][0])
print("config.cycles_rules:", config_budget["allOf"][1])
print("config.forever_rules:", config_budget["allOf"][2])
PY

Repository: maximhq/bifrost

Length of output: 690


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json

with open("transports/config.schema.json", encoding="utf-8") as f:
    config = json.load(f)

def walk(value, path=()):
    if isinstance(value, dict):
        if "override_mode" in value:
            print("definition:", ".".join(path))
            print(json.dumps(value, indent=2))
        for key, child in value.items():
            walk(child, path + (str(key),))
    elif isinstance(value, list):
        for index, child in enumerate(value):
            walk(child, path + (str(index),))

walk(config)
PY

Repository: maximhq/bifrost

Length of output: 3490


Align the bundled budget override schemas with the governance contract.

BudgetOverrideRequest lacks a positive amount constraint and conditional cycles validation. Budget omits the inactive "" mode and zero-value lifecycle state. Add the OpenAPI 3.1 constraints and lifecycle states. The bundled operations match the source specifications.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openapi/openapi.json` around lines 45035 - 45186, Update the bundled
OpenAPI schemas `BudgetOverrideRequest` and `Budget` to match the governance
contract: require `amount` to be strictly positive, enforce `cycles` validation
conditionally when the override mode is `cycles`, and include the inactive
empty-string mode plus the zero-value lifecycle state in `Budget`. Preserve the
existing operation definitions and references.

Source: Learnings

Comment thread docs/openapi/openapi.json
Comment on lines +82481 to +82505
"BudgetOverrideRequest": {
"type": "object",
"description": "Replaces the active override on one budget. The override is additive: it does not change the\nbudget's `max_limit`, `current_usage`, or reset schedule. Sending this request against a budget\nthat already has an override replaces that override entirely.\n",
"required": [
"amount",
"mode"
],
"properties": {
"amount": {
"type": "number",
"description": "Additional spend in dollars added on top of `max_limit` while the override is active. Must be greater than 0 and finite."
},
"mode": {
"type": "string",
"description": "`cycles` keeps the override active for `cycles` reset windows starting with the current one.\n`forever` keeps it active until it is removed with a DELETE.\n",
"enum": [
"cycles",
"forever"
]
},
"cycles": {
"type": "integer",
"description": "Number of reset windows the override stays active for, counting the current window as the first.\nRequired and must be greater than 0 when `mode` is `cycles`; must be omitted or 0 when `mode` is `forever`.\n",
"minimum": 1
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- repository status and changed-file summary ---'
git status --short
git diff --stat
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(openapi\.json|config\.schema\.json|docs\.json)$|governance|budget'
printf '%s\n' '--- OpenAPI version and target schemas ---'
rg -n -C 3 '"openapi"|"BudgetOverrideRequest"|"override_amount"|"override_mode"|"override_cycles_remaining"|"override_cycles_total"|"override_anchor_reset"' docs/openapi/openapi.json
printf '%s\n' '--- source/schema references ---'
rg -n -C 3 'BudgetOverrideRequest|override_cycles_remaining|override_cycles_total|override_anchor_reset|override_mode|override_amount|mode.*empty|empty.*mode' . -g '!docs/openapi/openapi.json' -g '!node_modules' -g '!dist' -g '!build'

Repository: maximhq/bifrost

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -e
log=/tmp/coderabbit-shell-logs/shell-output-4qMj78
printf '%s\n' '--- status and diff summary ---'
sed -n '1,80p' "$log"
printf '%s\n' '--- exact budget override references outside generated OpenAPI ---'
rg -n -C 4 'BudgetOverride|override_cycles_remaining|override_cycles_total|override_anchor_reset|override_mode|override_amount' \
  --glob '!docs/openapi/openapi.json' \
  --glob '!ui/**' \
  --glob '!core/providers/**' \
  --glob '!vendor/**' \
  .
printf '%s\n' '--- OpenAPI header and target schema ranges ---'
sed -n '1,25p' docs/openapi/openapi.json
sed -n '82250,82335p' docs/openapi/openapi.json
sed -n '82455,82535p' docs/openapi/openapi.json

Repository: maximhq/bifrost

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- OpenAPI document version ---'
sed -n '1,18p' docs/openapi/openapi.json
printf '%s\n' '--- source OpenAPI Budget schema ---'
sed -n '1,125p' docs/openapi/schemas/management/governance.yaml
printf '%s\n' '--- source OpenAPI override request schema ---'
sed -n '125,205p' docs/openapi/schemas/management/governance.yaml
printf '%s\n' '--- budget model and lifecycle methods ---'
rg -n -C 8 'type BudgetOverrideMode|BudgetOverrideMode|func \(.*\) SetOverride|func \(.*\) ClearOverride|HasActiveOverride|OverrideCycles' framework/configstore/tables/budget.go
printf '%s\n' '--- handler validation and request flow ---'
sed -n '1569,1638p' transports/bifrost-http/handlers/governance.go
printf '%s\n' '--- relevant docs navigation entry ---'
rg -n -C 4 'OSS Governance|governance|openapi/openapi.json' docs/docs.json

Repository: maximhq/bifrost

Length of output: 25592


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import json
from pathlib import Path

doc = json.loads(Path("docs/openapi/openapi.json").read_text())
schemas = doc["components"]["schemas"]
for name in ("Budget", "BudgetOverrideRequest"):
    schema = schemas[name]
    print(f"--- {name} ---")
    print("required:", schema.get("required"))
    for key, value in schema.get("properties", {}).items():
        if key.startswith("override") or key in ("amount", "mode", "cycles"):
            print(key, json.dumps(value, sort_keys=True))
    print("allOf:", json.dumps(schema.get("allOf"), sort_keys=True))

print("--- exact JSON schema checks ---")
budget = schemas["Budget"]
request = schemas["BudgetOverrideRequest"]
checks = {
    "request.amount.exclusiveMinimum": request["properties"]["amount"].get("exclusiveMinimum"),
    "request.amount.minimum": request["properties"]["amount"].get("minimum"),
    "request.cycles.minimum": request["properties"]["cycles"].get("minimum"),
    "request.anyOf": request.get("anyOf"),
    "request.oneOf": request.get("oneOf"),
    "request.allOf": request.get("allOf"),
    "budget.override_mode.enum": budget["properties"]["override_mode"].get("enum"),
    "budget.allOf": budget.get("allOf"),
}
for key, value in checks.items():
    print(f"{key}: {json.dumps(value, sort_keys=True)}")
PY
printf '%s\n' '--- serialization tags for the Budget response fields ---'
sed -n '23,70p' framework/configstore/tables/budget.go
printf '%s\n' '--- all governance OpenAPI source references ---'
rg -n 'Budget:|BudgetOverrideRequest:|override_amount:|override_mode:|override_cycles_remaining:|override_cycles_total:|override_anchor_reset:' \
  docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.yaml docs/openapi/openapi.json

Repository: maximhq/bifrost

Length of output: 6301


Align budget override schemas with the runtime lifecycle.

  • Add exclusiveMinimum: 0 to BudgetOverrideRequest.amount.
  • Add OpenAPI 3.1 conditional rules: cycles is required and positive for mode: cycles; it is omitted or 0 for mode: forever.
  • In Budget, model the empty mode as override_mode: "". Require zero inactive override values and omit only override_anchor_reset. Require positive active amounts and valid finite-cycle fields.
  • Update docs/openapi/schemas/management/governance.yaml and regenerate docs/openapi/openapi.json. Remove omitempty from inactive response fields if the API must serialize their zero values.
📍 Affects 1 file
  • docs/openapi/openapi.json#L82481-L82505 (this comment)
  • docs/openapi/openapi.json#L82289-L82312
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openapi/openapi.json` around lines 82481 - 82505, Update
BudgetOverrideRequest in docs/openapi/schemas/management/governance.yaml with
exclusiveMinimum: 0 for amount and OpenAPI 3.1 conditional schemas requiring
positive cycles for mode "cycles" and omitted-or-zero cycles for mode "forever";
regenerate docs/openapi/openapi.json at both listed ranges. Update Budget to
represent inactive mode as override_mode: "", require zero inactive override
values while omitting only override_anchor_reset, and enforce positive active
amounts plus valid finite-cycle fields; remove omitempty from inactive response
fields when needed to serialize their zero values.

Source: Path instructions

Comment on lines +268 to +320
virtual-keys-budget-override:
put:
operationId: updateVirtualKeyBudgetOverride
summary: Set virtual key budget override
description: |
Sets or replaces the spending override on one of a virtual key's budgets. The override is additive —
while it is active the budget is enforced against `max_limit + override_amount` — and it leaves the
budget's base limit, current usage, and reset schedule untouched.

Use `mode: cycles` with a `cycles` count to grant extra spend for a finite number of reset windows
(the current window counts as the first), or `mode: forever` to keep the override until it is deleted.
A finite grant is anchored to the budget's current reset window, so every node in a cluster derives the
same number of remaining cycles and a config reload cannot resurrect a spent one.
tags:
- Governance
parameters:
- name: vk_id
in: path
required: true
description: Virtual key ID
schema:
type: string
- name: budget_id
in: path
required: true
description: ID of a budget owned by the virtual key
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/management/governance.yaml#/BudgetOverrideRequest'
security:
- ManagementBearerAuth: []
responses:
'200':
description: Budget override applied successfully
content:
application/json:
schema:
$ref: '../../schemas/management/governance.yaml#/BudgetOverrideResponse'
'400':
$ref: '../../openapi.yaml#/components/responses/BadRequest'
'404':
description: Virtual key or budget not found
content:
application/json:
schema:
$ref: '../../schemas/inference/common.yaml#/BifrostError'
'500':
$ref: '../../openapi.yaml#/components/responses/InternalError'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== BudgetOverrideRequest / BudgetOverrideResponse schema =="
fd -t f 'governance.yaml' docs/openapi/schemas | xargs -I{} rg -n -A 25 'BudgetOverrideRequest:|BudgetOverrideResponse:|OverrideMode|override_mode|override_amount|override_cycles|override_anchor' {}

echo "== openapi.json parity check =="
fd -t f 'openapi.json' docs/openapi | xargs -I{} rg -n 'virtual-keys-budget-override|BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles|override_anchor' {}

Repository: maximhq/bifrost

Length of output: 5690


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Stack and changed-file context =="
git status --short
git branch --show-current
git diff --stat

echo "== YAML schema definitions =="
cat -n docs/openapi/schemas/management/governance.yaml | sed -n '1,75p;150,200p'

echo "== OpenAPI JSON operation and schemas =="
python3 - <<'PY'
import json
from pathlib import Path

p = Path("docs/openapi/openapi.json")
doc = json.loads(p.read_text())
path = doc["paths"].get("/v1/management/virtual-keys/{vk_id}/budgets/{budget_id}/override")
print("operation:")
print(json.dumps(path, indent=2, sort_keys=True) if path else "NOT FOUND")

schemas = doc.get("components", {}).get("schemas", {})
for name in ("BudgetOverrideRequest", "BudgetOverrideResponse", "Budget"):
    print(f"\n{name}:")
    print(json.dumps(schemas.get(name, "NOT FOUND"), indent=2, sort_keys=True))
PY

echo "== Documentation navigation references =="
rg -n -C 3 'API Reference|openapi\.json|Governance|governance' docs/docs.json docs -g 'docs.json' -g '*.mdx' -g '*.md' | head -200

Repository: maximhq/bifrost

Length of output: 24688


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Existing budget-override conventions =="
rg -n -C 8 'override|budget.*mode|cycles|anchor|remaining|total' transports/config.schema.json | head -240

echo "== OpenAPI paths containing the override operation =="
python3 - <<'PY'
import json
from pathlib import Path

doc = json.loads(Path("docs/openapi/openapi.json").read_text())
for path, item in doc.get("paths", {}).items():
    if "override" in path.lower():
        print(path)
        for method, operation in item.items():
            if isinstance(operation, dict):
                print(" ", method, operation.get("operationId"))
PY

echo "== Schema constraint keywords =="
rg -n -C 5 'BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset|oneOf|allOf|anyOf|minimum|exclusiveMinimum|finite' docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.json | head -320

Repository: maximhq/bifrost

Length of output: 13266


🏁 Script executed:

#!/bin/bash
set -u

echo "== OpenAPI paths containing the override operation =="
python3 - <<'PY'
import json
from pathlib import Path

doc = json.loads(Path("docs/openapi/openapi.json").read_text())
found = False
for path, item in doc.get("paths", {}).items():
    if "override" in path.lower():
        found = True
        print(path)
        for method, operation in item.items():
            if isinstance(operation, dict):
                print(" ", method, operation.get("operationId"))
if not found:
    print("NO OVERRIDE PATH FOUND")
PY

echo "== OpenAPI override schema constraints =="
rg -n -C 6 'BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset|oneOf|allOf|anyOf|minimum|exclusiveMinimum|finite' \
  docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.json || true

echo "== YAML operation identity =="
rg -n -C 4 'virtual-keys-budget-override|updateVirtualKeyBudgetOverride|BudgetOverrideRequest|BudgetOverrideResponse' docs/openapi/paths/management/governance.yaml

Repository: maximhq/bifrost

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -u

echo "== Generated JSON operation =="
python3 - <<'PY'
import json
from pathlib import Path

doc = json.loads(Path("docs/openapi/openapi.json").read_text())
op = doc["paths"]["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]["put"]
print(json.dumps({
    "operationId": op.get("operationId"),
    "summary": op.get("summary"),
    "request_schema": op["requestBody"]["content"]["application/json"]["schema"],
    "response_schema": op["responses"]["200"]["content"]["application/json"]["schema"],
}, indent=2))
PY

echo "== Runtime budget override symbols =="
rg -n -l 'BudgetOverrideRequest|override_cycles_total|override_anchor_reset|override_mode|override_amount' --glob '!docs/openapi/openapi.json' --glob '!docs/openapi/schemas/management/governance.yaml' . | head -80

echo "== Runtime validation and mode handling =="
rg -n -C 5 'BudgetOverrideRequest|override_cycles_total|override_anchor_reset|override_mode|override_amount|cycles.*forever|forever.*cycles' --glob '*.go' . | head -320

Repository: maximhq/bifrost

Length of output: 25923


Add the missing budget override constraints to both OpenAPI sources.

BudgetOverrideRequest does not enforce a positive finite amount or mode-dependent cycles rules. Its unconditional minimum: 1 conflicts with the documented forever case where cycles may be 0. Budget does not enforce inactive zero values, the absent anchor, or override_cycles_total >= override_cycles_remaining. The JSON file mirrors these incomplete definitions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openapi/paths/management/governance.yaml` around lines 268 - 320, Update
BudgetOverrideRequest in both OpenAPI schema sources to require a positive
finite amount and enforce mode-dependent cycles: cycles mode must use a positive
count, while forever permits cycles 0; remove the unconditional minimum that
rejects this case. Update Budget to require inactive override fields to be zero,
omit the anchor when inactive, and enforce override_cycles_total >=
override_cycles_remaining, keeping the JSON definition synchronized with the
YAML schema.

Comment on lines +33 to +55
override_amount:
type: number
description: Additional spend added on top of `max_limit` while the override is active. Omitted when no override is set.
override_mode:
type: string
description: |
How long the override stays active. `cycles` keeps it active for a finite number of
reset windows; `forever` keeps it active until it is removed. Omitted when no override is set.
enum:
- cycles
- forever
override_cycles_remaining:
type: integer
description: |
Reset windows the override is still valid for, including the current one. Positive only
for `cycles` mode; recomputed from the original grant on every reset, never decremented in place.
override_cycles_total:
type: integer
description: Number of reset windows the current `cycles` override was granted for. Immutable for the life of the grant.
override_anchor_reset:
type: string
format: date-time
description: Reset-window boundary at which the current `cycles` override was granted. Immutable for the life of the grant.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make the inactive override state match the governance schema.

Lines 35 and 40 state that inactive override_amount and override_mode are omitted. The governance convention requires inactive override values to reset to zero, use the empty mode, and omit only override_anchor_reset.

A response that serializes the empty mode does not validate against the current enum. Document and model the zero-value inactive fields consistently.

As per path instructions, check parity with config.schema.json; it requires zero-valued inactive overrides and an omitted anchor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openapi/schemas/management/governance.yaml` around lines 33 - 55, The
governance schema must document inactive overrides as zero-valued rather than
omitted, with an empty override mode and only override_anchor_reset omitted.
Update the property descriptions and enum/model definitions around
override_amount, override_mode, override_cycles_remaining, and
override_cycles_total, ensuring the inactive empty mode is accepted consistently
with config.schema.json while retaining the existing active-mode values.

Source: Path instructions

Comment on lines +167 to +183
amount:
type: number
description: Additional spend in dollars added on top of `max_limit` while the override is active. Must be greater than 0 and finite.
mode:
type: string
description: |
`cycles` keeps the override active for `cycles` reset windows starting with the current one.
`forever` keeps it active until it is removed with a DELETE.
enum:
- cycles
- forever
cycles:
type: integer
description: |
Number of reset windows the override stays active for, counting the current window as the first.
Required and must be greater than 0 when `mode` is `cycles`; must be omitted or 0 when `mode` is `forever`.
minimum: 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect the OpenAPI version before choosing conditional-schema syntax.
rg -n -C2 '^openapi:' docs/openapi/openapi.yaml

# Compare the YAML source, published JSON bundle, and transport schema contract.
rg -n -C8 \
  'BudgetOverrideRequest|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset' \
  docs/openapi/schemas/management/governance.yaml \
  docs/openapi/openapi.json \
  transports/config.schema.json

Repository: maximhq/bifrost

Length of output: 21858


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

sed -n '157,187p' docs/openapi/schemas/management/governance.yaml
sed -n '82481,82512p' docs/openapi/openapi.json

rg -n -C6 \
  'BudgetOverrideRequest|override.*cycles|override.*amount|mode.*forever|cycles.*mode' \
  --glob '!docs/openapi/openapi.json' \
  --glob '!docs/openapi/schemas/management/governance.yaml' .

Repository: maximhq/bifrost

Length of output: 50373


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

sed -n '41,86p' ui/components/budgetOverrideDialog.tsx
sed -n '1268,1282p' ui/lib/types/schemas.ts

rg -n -C10 \
  'func .*SetOverride|SetOverride\(|BudgetOverrideMode|override amount|cycles must' \
  --glob '*.go' \
  --glob '!**/*_test.go' \
  transports plugins configstore

Repository: maximhq/bifrost

Length of output: 7165


Encode the mode-dependent constraints in BudgetOverrideRequest.

Set amount.exclusiveMinimum: 0. Use oneOf or if/then so cycles is required with minimum: 1 only for mode: cycles. Omit cycles for mode: forever, matching the UI, Go request type, and documentation examples. Update docs/openapi/openapi.json to match.

The current global minimum: 1 rejects the documented cycles: 0 form for forever, and the schema does not enforce a positive amount.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openapi/schemas/management/governance.yaml` around lines 167 - 183,
Update BudgetOverrideRequest so amount uses exclusiveMinimum: 0, and replace the
global cycles minimum with mode-dependent oneOf or if/then constraints: require
cycles with minimum 1 for mode cycles, while omitting cycles for mode forever.
Apply the same schema changes to docs/openapi/openapi.json.

Source: Path instructions

@mintlify

mintlify Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
bifrost 🟡 Building Jul 31, 2026, 8:12 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
## Summary

Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an `override_amount` on top of the base `max_limit`, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed via `PUT`/`DELETE` on `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override`.

## Changes

- Added a **Budget overrides** section to `budget-and-limits.mdx` explaining the `effective_max_limit = max_limit + override_amount` enforcement model and linking to the virtual keys walkthrough.
- Expanded the override section in `virtual-keys.mdx` with full API usage examples for `PUT` (both `cycles` and `forever` modes) and `DELETE`, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.
- Registered `PUT` and `DELETE` endpoints for `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override` in the OpenAPI spec (both JSON and YAML), including request/response schemas (`BudgetOverrideRequest`, `BudgetOverrideResponse`) and new override fields on the `Budget` schema (`override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, `override_anchor_reset`).

## Type of change

- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [x] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [x] Docs

## How to test

1. Navigate to the **Budget overrides** section in `budget-and-limits.mdx` and confirm the formula and cross-link render correctly.
2. Navigate to the override API section in `virtual-keys.mdx` and verify all code blocks, the sample response, and the behavioral notes display as expected.
3. Load the OpenAPI spec and confirm the two new endpoints appear under the **Governance** tag with correct request/response schemas and that the `Budget` schema includes the five new override fields.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

The new endpoints require `ManagementBearerAuth`, consistent with all other governance management endpoints. No new auth surface is introduced.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
## Summary

Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an `override_amount` on top of the base `max_limit`, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed via `PUT`/`DELETE` on `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override`.

## Changes

- Added a **Budget overrides** section to `budget-and-limits.mdx` explaining the `effective_max_limit = max_limit + override_amount` enforcement model and linking to the virtual keys walkthrough.
- Expanded the override section in `virtual-keys.mdx` with full API usage examples for `PUT` (both `cycles` and `forever` modes) and `DELETE`, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.
- Registered `PUT` and `DELETE` endpoints for `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override` in the OpenAPI spec (both JSON and YAML), including request/response schemas (`BudgetOverrideRequest`, `BudgetOverrideResponse`) and new override fields on the `Budget` schema (`override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, `override_anchor_reset`).

## Type of change

- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [x] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [x] Docs

## How to test

1. Navigate to the **Budget overrides** section in `budget-and-limits.mdx` and confirm the formula and cross-link render correctly.
2. Navigate to the override API section in `virtual-keys.mdx` and verify all code blocks, the sample response, and the behavioral notes display as expected.
3. Load the OpenAPI spec and confirm the two new endpoints appear under the **Governance** tag with correct request/response schemas and that the `Budget` schema includes the five new override fields.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

The new endpoints require `ManagementBearerAuth`, consistent with all other governance management endpoints. No new auth surface is introduced.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants