Skip to content

Publish a gate policy

View as Markdown
POST
/v1/gate-policies
curl --request POST \
--url https://example.com/v1/gate-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "id": "example", "version": "example", "agentId": "example", "scope": { "kind": "tenant" }, "spec": { "comparison": { "maxAgeHours": 1, "suite": { "id": "example", "version": "example" } }, "evidence": { "minCases": 1, "minWeight": 1 }, "metrics": [ { "name": "weightedYesShare", "k": 1, "minCandidate": 1, "maxDrop": 1 } ], "replay": { "maxDiverged": 1, "maxErrors": 1, "maxRefusedWrites": 1, "maxStopped": 1 }, "approvals": { "role": "standard", "separateApprover": true }, "onlyRestrictedClasses": true }, "description": "example" }'

Registers a gate policy, or a new version of one: what a promotion of agentId for scope must show. One policy per agent and scope: another policy id for a scope that has one is refused with 409 gate-policy-scope-taken (details.heldBy names it; publish a new version of that one instead), and a new version can’t change the agent or scope (409 gate-policy-scope-changed). The spec is checked strictly: an unknown key is refused (400 validation-failed, details.issues). Needs admin on the tenant: whoever may promote can’t loosen their own gate.

Idempotency-Key
string
>= 1 characters

Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per docs/API-ROUTE-CONVENTIONS.md §3.1). A retry sent while the first request still runs is answered 409 idempotency-key-in-flight with Retry-After, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets 409 idempotency-key-replay-withheld, with the first request’s status and when it succeeded (from 0.1.5). A request whose key store can’t be read before it runs is answered 503 idempotency-store-unavailable with Retry-After: nothing ran, so retry with the same key (from 0.3.0).

Media typeapplication/json
object
id
required

Yours to choose, e.g. acme.drafting-prod.

string
/^[a-z0-9][a-z0-9._-]{0,127}$/
version
required
string
/^\d+\.\d+\.\d+$/
agentId
required
string
scope
required
One of: discriminator: kind

The agent’s default for the whole tenant.

object
kind
required
string
Allowed values: tenant
spec
required

What a promotion must show. Every part is optional; an empty spec checks nothing. A promotion must name a comparison (evalRunId) exactly when the spec has comparison, evidence, metrics, replay or onlyRestrictedClasses. Unknown keys are refused.

object
comparison
object
maxAgeHours
number
> 0
suite
object
id
required
string
version
string
evidence

The judged evidence behind each gated metric; for a metric with maxDrop, the baseline’s too.

object
minCases
integer
minWeight
number
metrics
Array<object>
object
name
required
string
Allowed values: weightedYesShare judgedCoverage weightedPrecisionAtK
k

weightedPrecisionAtK only: the summary’s k must be this.

integer
>= 1 <= 100
minCandidate
number
<= 1
maxDrop

How far the candidate may fall below the baseline (the live version).

number
<= 1
replay

Each knob left out of the block is 0. No block: no replay checks.

object
maxDiverged
integer
maxErrors
integer
maxRefusedWrites

At most this many tool calls the replay refused (the comparison summary’s refusedWrites). Reads count too, despite the name.

integer
maxStopped
integer
approvals

A passing promotion waits for a reviewer.

object
role

Default senior.

string
Allowed values: standard senior admin
separateApprover

Default true.

boolean
onlyRestrictedClasses

Only restricted judge classes count: the comparison must be weighted restricted-only, so a class anyone may assert can’t move the gate.

boolean
description
string

Gate policy published.

Media typeapplication/json
object
id
required
string
version
required
string
agentId
required
string
scope
required
One of: discriminator: kind

The agent’s default for the whole tenant.

object
kind
required
string
Allowed values: tenant
spec
required

What a promotion must show. Every part is optional; an empty spec checks nothing. A promotion must name a comparison (evalRunId) exactly when the spec has comparison, evidence, metrics, replay or onlyRestrictedClasses. Unknown keys are refused.

object
comparison
object
maxAgeHours
number
> 0
suite
object
id
required
string
version
string
evidence

The judged evidence behind each gated metric; for a metric with maxDrop, the baseline’s too.

object
minCases
integer
minWeight
number
metrics
Array<object>
object
name
required
string
Allowed values: weightedYesShare judgedCoverage weightedPrecisionAtK
k

weightedPrecisionAtK only: the summary’s k must be this.

integer
>= 1 <= 100
minCandidate
number
<= 1
maxDrop

How far the candidate may fall below the baseline (the live version).

number
<= 1
replay

Each knob left out of the block is 0. No block: no replay checks.

object
maxDiverged
integer
maxErrors
integer
maxRefusedWrites

At most this many tool calls the replay refused (the comparison summary’s refusedWrites). Reads count too, despite the name.

integer
maxStopped
integer
approvals

A passing promotion waits for a reviewer.

object
role

Default senior.

string
Allowed values: standard senior admin
separateApprover

Default true.

boolean
onlyRestrictedClasses

Only restricted judge classes count: the comparison must be weighted restricted-only, so a class anyone may assert can’t move the gate.

boolean
description
string
createdAt
required
string format: date-time
unregisteredAt
string format: date-time
Example
{
"scope": {
"kind": "tenant"
},
"spec": {
"metrics": [
{
"name": "weightedYesShare"
}
],
"approvals": {
"role": "standard"
}
}
}

Validation failed (see details.issues).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Missing / malformed / expired / revoked bearer token.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

gate-policy-already-registered: that (id, version) exists. gate-policy-scope-taken: another policy gates the agent for the scope (details.heldBy). gate-policy-scope-changed: the version would change the agent or scope. gate-policy-scope-unpinned: the scope has no live version of its own; a gated scope holds its own pin (a pin above it is not enough, since a promotion there would change this scope ungated), so pin a version for the scope first.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

The request body is over the API’s limit (request-too-large; details.maxBytes says how much).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

Server error (unmapped domain code or framework crash).

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

The Idempotency-Key store couldn’t be read before the request ran (idempotency-store-unavailable), so nothing was changed; Retry-After (whole seconds) says when to try again with the same key.

Media typeapplication/json
object
error
required
object
code
required

Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).

string
message
required
string
details

Optional, kind-specific.

object
key
additional properties
any
requestId
required

Server-assigned request id; also echoed via X-Request-Id header.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": {},
"requestId": "example"
}
}

See also