Live versions reference
This page lists everything about live agent versions: how a run gets its version, what conversations and flows keep, what promotions, rollbacks and unpins refuse, the history, gate policies, and what the console shows. To release a version, follow Release an agent version.
How a run gets its version
Section titled “How a run gets its version”A run's agent.via says how it got its version:
via |
The version is |
|---|---|
live |
the live version of the scope in liveScope |
latest |
the latest, because nothing is live for this run |
explicit |
the one the run named, with --agent-version or agentVersion |
flow-pin |
the one its flow version holds, as Flows keep their versions describes |
conversation |
the one its conversation started with, as Conversations keep their version describes |
The most specific live version wins: a segment path in a project, then
the project, the project's org, the tenant, and then the latest
version. Without --project, a run is in its agent's own project, which is
Default for what kindgi deploy registers.
A version only goes live by a promotion: publishing a newer version doesn't change what a scope with a live version runs.
Conversations keep their version
Section titled “Conversations keep their version”A follow-up turn in a conversation keeps the version the conversation started with, even after a promotion, so the conversation stays consistent. Here a conversation started on 1.2.0. Then 1.0.0 went live for the tenant, and the conversation's next turn still ran 1.2.0:
"agent": { "id": "acme.order-desk", "version": "1.2.0", "conversationId": "9fce3360-5426-4578-b387-361afa9f2156", "via": "conversation" },A new conversation gets the live version.
Flows keep their versions
Section titled “Flows keep their versions”A published flow version holds the agent versions it was published with.
Each agent step runs the version its node names, config.version. Otherwise
it runs the one a run in the flow's project would get when the flow version
is published: the live version, from the project, then the org, then the
tenant, or the latest when none is live. Its turns say "via": "flow-pin",
and a promotion doesn't change them.
Here acme.order-flow 1.0.0 was published while 1.3.0 was live. After the
tenant went back to 1.0.0, its step still ran 1.3.0:
"agent": { "id": "acme.order-desk", "version": "1.3.0", "conversationId": "5547f2a1-88b2-4b34-8d63-294f21fa5642", "via": "flow-pin" },To run a new agent version in a flow, publish a new version of the flow.
Rollbacks and unpins
Section titled “Rollbacks and unpins”- A rollback puts a scope back on the version that was live there
before, or on
--to=<version>, at once. It isn't gated. - An unpin removes a scope's own live version. Its runs then use a wider scope's live version, or the latest version when none is live.
What each refuses:
- a version that isn't registered:
Version 9.9.9 is not registered (or was unregistered); - a rollback where nothing was live before:
The scope had no live version before this one: unpin it to fall back to the scope above; - an unpin where the scope has no live version of its own:
The scope has no live version of its own; - an unpin of a gated scope, since a gated scope keeps its own live version:
segment company:acme in project <project-id> has a gate policy for acme.order-desk, and a gated scope keeps its own live version: unregister the gate policy first, or roll back instead.
To retire a version that's live somewhere, roll back, unpin or promote
another version in each of those scopes first. Until then,
kindgi agents unregister refuses it with 409 agent-version-live.
The history
Section titled “The history”Every promotion, rollback and unpin is kept, with who asked and why, newest first:
pnpm exec kindgi agents promotions list acme.order-desk --table--table prints a table. STATUS says how each ended, done for a
rollback or an unpin:
ID ACTION STATUS SCOPE FROM TO BY AT──────────────────────────────────── ──────── ──────── ───────────────────────────────────────────────────────── ───── ───── ───────────────────────────────────────── ────────────────────────d6db591b-8afc-4413-81c8-a794d9f848a5 unpin done tenant 1.0.0 - user 5c0a7e11-0000-4000-8000-0000000000aa 2026-10-06T18:48:59.665Z7da674c5-c835-42c0-8cde-59571afd0915 rollback done tenant 1.2.0 1.0.0 user 5c0a7e11-0000-4000-8000-0000000000aa 2026-10-06T18:48:47.871Z70ea0024-ec7e-4122-abc4-04df1eb7b9eb promote promoted tenant 1.0.0 1.2.0 user 5c0a7e11-0000-4000-8000-0000000000aa 2026-10-06T18:48:43.578Z912e10e7-18fb-4228-92b9-33b3f2a4d45b promote promoted project 367e1657-8067-4a1d-8ec4-bfa3c5fc5865 company=acme - 1.1.0 user 5c0a7e11-0000-4000-8000-0000000000aa 2026-10-06T18:48:23.207Zea4e7c15-7990-41b6-b153-0847a83f2e9d promote promoted tenant - 1.0.0 user 5c0a7e11-0000-4000-8000-0000000000aa 2026-10-06T18:46:15.125Z--tenant,--org,--projectand--segmentnarrow it to one scope's history.- A promotion's
statusispromoted,pending-approval,refusedorsuperseded. A waiting request issupersededwhen another promotion of the same scope goes live first. --eval-run=<eval-run-id>onpromotekeeps the comparison behind the decision on its record.
Gate policies
Section titled “Gate policies”A gate policy's parts, and what each asks of a promotion:
| Part | A promotion must show |
|---|---|
comparison.maxAgeHours |
a comparison of the version, finished at most this many hours ago |
evidence.minCases |
each figure resting on at least this many judged cases, for the version and for the live one |
metrics |
each named figure at least minCandidate, and lower than the live version's by at most maxDrop. The figures are weightedYesShare, judgedCoverage, or weightedPrecisionAtK with its k |
replay |
at most this many diverged cases, errors, refused calls and stopped cases: maxDiverged, maxErrors, maxRefusedWrites, maxStopped. maxRefusedWrites counts every call the replay refuses, a read that reaches outside included. Those left out are 0. A version with other settings runs read-only tools live, which counts as diverged, so maxDiverged: 0 refuses it |
approvals |
then a reviewer with this role approves it, senior if left out. It's someone other than whoever asked, unless separateApprover: false lets the one who asked approve it |
onlyRestrictedClasses: true |
a comparison that counted only restricted judges |
- A promotion must name its comparison when the policy has
comparison,evidence,metrics,replayoronlyRestrictedClasses. The comparison must be of the version you promote, with the same pins, and its recorded runs must be from the version live for the scope now. - With
onlyRestrictedClasses, a comparison that counted every class is refused withThe policy counts only restricted judge classes; the comparison counted every class. Re-run it with `classWeights: 'restricted-only'`.. So only the judges you restricted can release a version. - To change a gate, publish a new version of the policy.
kindgi gate-policies unregister acme.order-desk-release <version>goes back to the one before. kindgi agents gate-policy acme.order-desk --tenantshows the policy that applies to a scope.- With authorization on, publishing a
gate policy takes
adminon the tenant. Reading one takesreadon its scope: its project, a segment's too, its org, or the tenant for a tenant-wide one. A policy you can't read is left out of lists, and answers404 gate-policy-not-found, as if it weren't there.
A gated scope needs a live version of its own
Section titled “A gated scope needs a live version of its own”Otherwise, the next published version, or a promotion for a wider scope, would reach its runs without its gate. A policy for a scope without one is refused:
The tenant has no live version of acme.order-desk of its own, so publishing a version would make it live here ungated: pin a version for this scope first (1.2.0 serves it now)A scope whose runs get their version from a wider scope's pin, such as a segment that runs its project's version, is refused the same way, naming that pin:
Segment company:globex has no live version of acme.order-desk of its own, so a promotion for project <project-id> would change it without this gate: pin a version for this scope first (1.0.0 serves it now)Pin it in place: promote the version it serves now. That changes nothing for its runs, so it needs no comparison and no approval, even when a gate already applies:
pnpm exec kindgi agents promote acme.order-desk 1.0.0 --project=<project-id> --segment=company:globex --reason="Pin globex before its gate"<project-id>is the segment's project.--segment=company:globexis the segment,key:value. A deeper segment repeats--segment, coarse to fine.--reasonsays why, and is kept with the promotion.
Under a gate, the promotion's one check says why it went through, and its
reason starts with pin-in-place:
acme.order-desk 1.0.0 already serves this scope (from a pin above it), so pinning it here changes nothing for runs: the gate's checks and approval don't apply.
--check answers would-promote with that same check.
A gated scope that still follows a wider scope's pin, such as one set up by
an older runtime, refuses a promotion, rollback or unpin in that wider scope
with
409 gate-policy-descendant-unpinned, naming the scope and its version:
Promoting acme.order-desk for project <project-id> would also change segment company:acme, which a gate policy applies to and which has no live version of its own, without its gate. Pin it at its current version first: segment company:acme at 1.0.0Pin that scope in place, and promote again.
In the console
Section titled “In the console”- An agent's page says which version a run in this project gets, such as "Runs here use 1.0.0", and why: "It's live for every project (the tenant-wide default)." It links to its Live versions page.
- Live versions has the same headline, and Check a segment path, a key and a value, to see what a run on a path would get. It lists every pin that reaches this project with its part, each with Roll back and Unpin: "Runs here take it", or "Runs on this path take it" for a segment. Then it has the history, with who and why.
- Promote a version picks the version and the scope: this project, every project in its org when it's in one, every project, or a segment path in this project. It says what will happen before you promote, such as "Runs in this project (Support) will use 1.3.0."
- A run's page says why it ran its version, such as "Live for company = acme in this project (Default)".
- Gate policies, on the Live versions page, has each policy in sentences, with its versions, New version and Add a gate policy. The sentences read like "Judged yes: at least 60%, and no more than 2 points below the live version" and "Then a senior reviewer approves it, someone other than whoever asked".
- Add a gate policy has Only restricted judge classes count: "The comparison must count only judgments in classes restricted to some judges (start it with "Count only restricted judge classes"), so a class anyone may assert can't move the gate."
- Promote a version has Judged on, a finished comparison of the version. One that counted only restricted classes says "restricted classes only". It runs the gate's check before anything is recorded: "The gate passes (gate policy acme.order-desk-release 1.0.0) Then a senior reviewer approves it, someone other than you, and it goes live.", with each check. Its button follows: Ask to promote 1.3.0, or "The gate refuses it".
- A request waiting for approval shows on Live versions, with Open the approval. Its approval page shows the promotion, who asked and why, the comparison and the policy, and each check. Once approved, it says "Promoted 1.3.0, replacing 1.0.0".