Client and platform compatibility¶
What is compatible with what, what an agent does when the platform has moved on without it, and how to upgrade.
An agent runs a client: the policy engine (kyvvu-engine), usually through
the Python client (kyvvu) or an integration built on it (kyvvu-langchain,
kyvvu-crewai), or through the Claude Code plugin (kyvvu-claude). The platform serves that client its
policies and stores what it reports. The two are released separately, and you
upgrade your agents on your own schedule, so at any moment some agents run an
older client than the platform was built with.
What the platform serves¶
The platform declares the oldest client it can serve, as two numbers:
| Floor | Today | What it means |
|---|---|---|
| Minimum engine version | 0.13.0 |
The oldest kyvvu-engine the platform serves policies to. |
| Minimum policy schema | 1 |
The oldest policy schema — the shape of the policies the engine can load — the platform serves. |
A client meets the floor when both its engine version and its policy schema are
at or above it. A development build of a release (0.13.0.dev4) meets that
release's floor.
The floor rises only when the platform starts serving something an older engine cannot load: a new rule, a renamed rule parameter, a change in the shape of a policy. Between such releases, an older client keeps working.
From kyvvu-engine 1.0 a renamed rule or rule parameter is a breaking change
that needs a major version; within 1.x, the floor rises for additions only
(a new rule, a new optional parameter). The
policy rule contract
lists exactly what is frozen.
Release compatibility¶
Which releases work together. Each row is a platform release and the client releases published with it.
| Platform (API and dashboard) | kyvvu |
kyvvu-engine |
kyvvu-cli |
kyvvu-baseline |
kyvvu-templates |
kyvvu-claude |
kyvvu-langchain |
kyvvu-crewai |
|---|---|---|---|---|---|---|---|---|
| 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
| 0.22 | 0.23 | 0.13 | — | — | — | 0.7 | 0.1 | 0.1 |
Across releases, two rules decide what works:
- The Python client uses the platform's registration response. A successful
register_agentcall is accepted regardless of the API version header. Individual requests may still be refused if an older platform does not support their wire format; for example, platform 0.22 refuses batches containing the step hash sent bykyvvu1.0 with422. - The platform serves every client at or above its floor. Platform 1.0
still serves
kyvvu-engine0.13.0 or newer, so 0.x agents (kyvvu0.23,kyvvu-claude0.7) keep working against it unchanged; they send no hash, and the platform computes the chain for them as before. Clients older than 0.13 are served aslegacy(see below).
The 1.0 packages depend on each other within the major version: kyvvu
and kyvvu-claude require kyvvu-engine>=1.0,<2.0, and kyvvu-langchain
and kyvvu-crewai require kyvvu>=1.0,<2.0, so pip install -U of any of
them brings a matching set.
The client announces itself¶
From kyvvu 0.23, kyvvu-engine 0.13, kyvvu-claude 0.7, kyvvu-langchain
0.1 and kyvvu-crewai 0.1, every request a client makes to the platform —
registration, policy fetch, log batch, incident — carries four headers:
| Header | Example | Sent |
|---|---|---|
X-Kyvvu-Engine-Version |
1.0.0 |
always |
X-Kyvvu-Policy-Schema |
1 |
always |
X-Kyvvu-Client |
kyvvu-claude/1.0.0 |
always: the integration package, or kyvvu/<version> for the plain Python client |
X-Kyvvu-SDK-Version |
1.0.0 |
when the Python client is installed |
If you call the REST API directly you have no engine to report, and need send none of them. See REST integrations below.
What happens to an agent below the floor¶
It keeps enforcing the policies it already has, and tells you to upgrade. It is never left ungoverned.
- The platform answers the agent's policy fetch (and its registration) with
426 Upgrade Required:
{
"detail": "This platform serves kyvvu-engine 0.14.0 or later and policy schema 2 or later; this client announced kyvvu-engine 0.13.0, policy schema 1. Upgrade the client.",
"code": "client_upgrade_required",
"min_engine_version": "0.14.0",
"min_policy_schema": 2,
"upgrade": "pip install -U kyvvu 'kyvvu-engine>=0.14.0'"
}
- An agent that already holds a policy set — in memory, or in its on-disk
policy cache (
KV_POLICY_CACHE_PATH) — keeps enforcing that set. Its load state isstale_cachewith the causeclient_upgrade_required, and it logs one warning, at most once an hour:
kyvvu 0.23.0 (kyvvu-engine 0.13.0) is too old for this platform (needs kyvvu-engine>=0.14.0); still enforcing the policies fetched at 2026-11-02T09:14:03+00:00; pip install -U kyvvu 'kyvvu-engine>=0.14.0'
It will not receive policy changes until it is upgraded.
- An agent with nothing to fall back on — a fresh start with no policy
cache, or one whose cache is empty — refuses to start, with one line. On a
fresh start only a non-empty set you configured counts: the policy cache,
or a
policies=set passed by name. The Python client's bundled baseline floor does not, so a too-old agent never looks governed by a set it did not ask for.
kyvvu_engine.errors.KyvvuClientUpgradeRequired: kyvvu 0.23.0 (kyvvu-engine 0.13.0) is too old for this platform (needs kyvvu-engine>=0.14.0); no policies are cached, so nothing can be enforced; pip install -U kyvvu 'kyvvu-engine>=0.14.0'
Set KV_POLICY_CACHE_PATH on long-running agents so that a restart after
the platform moves on keeps enforcing rather than stopping.
- Log batches and incidents the platform refuses for a version reason
(
426, or400 unsupported_wire_version) are logged with the same warning and are not retried; a too-old client's next attempt would be refused the same way.
kyvvu-claude maps the same refusal onto its enforce setting: with a cached
policy set the session stays governed and its banner leads with
UPGRADE REQUIRED; with nothing cached the session is unavailable, so under
enforce every tool call is denied with the upgrade as the remedy, and in
monitor mode calls are logged as unchecked.
Seeing it¶
kv.policy_status()reportsload_state="stale_cache",stale_cause="client_upgrade_required"and, underclient_upgrade, what the platform said.kyvvu doctorreports the Policies check as a warning (cached set) or a failure (nothing cached), with thepip installcommand as the remedy.- The
KYVVU:line the engine prints on stderr when policy enforcement degrades names the state and the cause.
Clients that predate the headers¶
A client older than the releases above sends no version headers. The platform
cannot tell it anything it would understand, so it serves it exactly as
before. Its policy fetch without the headers is what identifies it — every
engine since these releases announces itself when it fetches — and it is
recorded as legacy. Such a client still breaks the old way
when the platform serves a policy its engine cannot load: it raises
PolicyLoadError at its next cold start. Upgrade legacy clients first.
REST integrations¶
A client that calls the REST API directly — registration and
POST /api/v1/logs/batch — runs no engine, so it has no version to be too old.
| It sends | Recorded as | needs_update |
|---|---|---|
no X-Kyvvu-* header |
rest, shown as REST integration |
never |
X-Kyvvu-Client: support-bot/1.4, and no engine version |
support-bot/1.4 |
never |
a policy fetch (GET /api/v1/policies?agent_key=...) with no header |
legacy |
yes |
A header-less registration or batch never replaces a client already recorded
by name, and never a legacy one with a policy fetch on record. So a later
header-less policy fetch turns rest into legacy, but a header-less batch
does not turn it back — an old engine posts its batches without the headers
too. (An agent recorded legacy with no policy fetch on record — what a
header-less registration or batch alone was recorded as before
— reads rest from its
next request.) A REST integration that fetches policies should send
X-Kyvvu-Client.
See REST API, "What the dashboard shows".
Which agents need updating¶
The platform records what each agent's client last announced. It is on every
agent in GET /api/v1/agents and GET /api/v1/agents/{agent_id}:
"client": {
"name": "kyvvu-claude/1.0.0",
"engine_version": "1.0.0",
"sdk_version": null,
"policy_schema": 1,
"legacy": false,
"needs_update": false,
"needs_update_by": null,
"seen_at": "2026-10-16T09:14:03Z",
"refused_at": null
}
needs_update is true for a client below the floor and for a legacy one;
never for rest or a client named without an engine version.
needs_update_by is the date of an announced upcoming floor (below) that the
client does not meet, or null.
refused_at is when the platform last refused the agent's client, cleared by
its next accepted request. client is null for an agent not heard from
since the platform began recording.
The dashboard's Agents page shows the client beside each agent and tags the ones that need it Needs update. An agent that has gone silent after being refused reads stopped reporting: client too old rather than just silent.
Before the floor rises¶
A raise is announced at least one release ahead, as an upcoming floor and the date it takes effect. From then:
- each agent whose client is below the upcoming floor (or
legacy) carriesclient.needs_update_by: "<date>", and the Agents page tags it Needs update by <date>; - the Workspace page (General tab) says N agents need updating before <date>, linking to the Agents page;
GET /api/v1/agents/upgrade-noticereturns the same thing for the current workspace:
{
"min_engine_version": "0.13.0",
"next_min_engine_version": "0.14.0",
"effective": "2027-01-15",
"count": 2,
"agents": [
{"agent_id": "agent_6442dabc", "agent_key": "support-bot", "org_id": 12,
"client": {"name": "legacy", "legacy": true, "needs_update": true,
"needs_update_by": "2027-01-15", "...": "..."}}
]
}
Agents are listed by identifier only, oldest client first. With nothing
announced, next_min_engine_version and effective are null and the list
is empty. Platform staff may add ?all_workspaces=true.
Nothing is refused because of an announcement; it only warns.
How to upgrade¶
Upgrade the package the agent installs; it brings a compatible engine with it.
pip install -U kyvvu # the Python client, and agents built on it
uv tool upgrade kyvvu-cli # the kyvvu command, kyvvu serve and Claude Code
pip install -U kyvvu-langchain # LangChain and LangGraph
pip install -U kyvvu-crewai # CrewAI
Then restart the agent (or run kyvvu claude refresh) and check with
kyvvu doctor that the policies report as enforcing.
Python versions¶
From 1.0, every client package (kyvvu-engine, kyvvu, kyvvu-cli,
kyvvu-baseline, kyvvu-templates, kyvvu-claude, kyvvu-langchain and
kyvvu-crewai) requires Python 3.11 or newer.
kyvvu-crewai also stops at 3.13, because CrewAI does not support 3.14 yet.
Python 3.10 reaches end of life in October 2026, and the 0.x releases are the
last to install on it: on 3.10, pip install -U keeps the newest 0.x release
rather than failing, so move the agent to 3.11 or newer before you expect 1.0.
kyvvu doctor reports the interpreter and the minimum on its first line.
Safe upgrade order¶
For a change to the client/server wire contract, upgrade the platform before installing clients that require it. Kyvvu's hosted platform is upgraded before those clients are published.
For a new policy rule or parameter, upgrade the agents' engine and Python client before the platform starts assigning policies that use it. An older engine refuses a rule or parameter it cannot load. Check the announced floor, test the new set, and upgrade affected agents before enabling it. See How to upgrade.