Zhivra Privacy Policy
Last updated: 2026-05-18 (J-B / routing-improvement opt-in added)
This is the privacy policy for Zhivra in its current state (pre-launch / early access). It describes what the extension does today. Before a public marketplace release we will revise this document — in particular, a future managed-cloud tier will introduce optional server-side features (covered below) that do not exist yet.
Zhivra is a VS Code extension that routes each of your requests to the best-suited “agent persona” (a model + system prompt + tool set) and runs an AI coding agent on your behalf. Here’s where your data goes — and, more importantly, where it doesn’t.
Where your data goes (and where it doesn’t)
-
Your code, files, prompts, and commands. When you use Zhivra’s AI features, the relevant files, your prompts, and the conversation context are sent to the AI model provider you have configured (e.g. OpenRouter, Anthropic, or whichever provider the routed persona’s model lives on) so the model can respond. Zhivra has no cloud proxy — your code and prompts go directly from your machine to that provider. We (the Zhivra developers) do not receive, store, or process your code, prompts, or commands. The AI provider you chose handles that data under their privacy policy.
-
API keys and credentials. Any API key you enter is stored locally on your device (in VS Code’s secret storage / settings) and is sent only to the provider it belongs to. It is never sent to us or any third party.
-
Telemetry / usage analytics — gated by consent, no data leaves until you acknowledge the prompt. Zhivra is forked from Roo Code, which shipped a PostHog analytics client; that has been removed (no analytics key is bundled, no PostHog sink is registered). Zhivra has its own, narrower telemetry: on first activation you see a one-time consent dialog. No data leaves your machine until you click “Yes” on that dialog. If you opt in, Zhivra uploads anonymous routing decisions and accept/reject signals to help the auto-router learn. Decline and nothing is uploaded — ever. No prompts, no code, no API responses are uploaded under any setting. Full detail in “Contributing anonymous telemetry (opt-in)” below.
-
Routing-improvement uploads — separate opt-in, off by default. A second, distinct channel (
zhivra.routingImprovement.enabled) opts you into uploading your full prompt + the agent’s full response so a third-party judge LLM can grade routing quality. This is a meaningful privacy step beyond anonymous telemetry, which is why it is its own setting and starts off. Full detail in “Routing-improvement uploads (opt-in, off by default)” below. -
Marketplace / model-list requests. Zhivra may make network requests to fetch the list of available models from your configured provider’s public catalog (e.g. OpenRouter’s
/modelsendpoint). These requests carry only what’s needed to fulfill them (extension version, the catalog query) — never your code, prompts, or any identifying information beyond what the provider’s public API requires.
Codebase indexing (off by default): if you turn on the optional “codebase indexing” feature, snippets of your code are sent to whichever embedding provider you configure (OpenAI, Ollama, Gemini, Mistral, Bedrock, OpenRouter, Vercel) and stored in whichever vector database you point it at (a local Qdrant by default). Nothing is indexed or sent until you enable it and supply that configuration.
Files Zhivra writes on your machine
Zhivra keeps some data locally on your own device — nothing here is uploaded anywhere unless you explicitly choose to share it (see the next section):
-
Error log —
~/.zhivra/errors-YYYY-MM-DD.log. A structured record of errors the extension hits, kept so that you (or we, if you choose to share a diagnostic bundle) can debug a problem. It contains the error type, the error message, a few lines of stack trace with file paths scrubbed (your home directory and workspace path are replaced with~/and<workspace>/so your username doesn’t leak), and a small set of scalar values (task id, persona id, token counts) — never your prompts, never your code, never file contents. Files older than 7 days are deleted automatically. On by default; disable with thezhivra.errorLog.enabledsetting. -
Routing & outcome logs (opt-in, off by default) —
~/.zhivra/dogfood/. When you turn on thezhivra.dogfoodLogger.enabledsetting, Zhivra writes per-turn routing decisions (which persona was picked and why) and behavioral signals (did you accept/reject a tool action, did you edit the agent’s code, did you abandon the task) to local CSV files. The routing log includes the first ~200 characters of your prompt (so the routing decision is interpretable); the outcome log contains no prompt or code content — only behavioral signals (tool names, persona ids, edit-distance buckets). This is off unless you explicitly enable it. A subset of this data — minus the prompt prefix and the reasoning text — is uploaded only if you also opt in to “Contributing anonymous telemetry”. -
Task history — VS Code’s extension storage (
globalStorage). Zhivra stores your conversation history per task so you can resume a task later and so the agent has its context. This includes your prompts and the files the agent read or wrote during that task. It stays on your machine; it is deleted if you uninstall the extension. (You can also delete individual tasks from the history view.)
When the agent runs a shell command whose output is large, the full output is
written to a file under your VS Code global-storage task directory
(tasks/<id>/command-output/cmd-*.txt) so it can be referenced later. That file
is removed when the task is reset and does not survive uninstalling the extension.
If a command you run prints a secret (e.g. cat .env), that secret will be in that
file until the task is cleared.
Contributing anonymous telemetry (opt-in)
To make the auto-router better, Zhivra can upload a small, anonymous stream
of behavioral data. This is off by default. The first time the routing/outcome
logging is enabled, Zhivra shows a one-time prompt asking whether you want to
contribute; you can also flip it any time via the zhivra.telemetry.uploadEnabled
setting. Until you say yes, nothing is uploaded.
What is uploaded, if you opt in:
- Routing decisions — for each turn: which category the request was classified as, which persona and model were chosen, which personas were candidates, whether it was an exploration pick, whether you overrode the choice (and to what), the turn index, and the length of your prompt (a number — not the text). The raw ~200-character prompt prefix that’s kept in the local log is stripped before upload, and so is the router’s free-text “reasoning” string.
- Behavioral signals — whether you accepted or rejected a tool action, reverted a file, redid or abandoned a turn, the edit-distance “bucket” of the agent’s output, and which tool a signal relates to. When the auto-router escalates because you re-asked (“redo this” / repeated frustration), we also record which tier the ladder moved to (alt model → adjacent persona → premium model) and which persona ids the escalation moved between — persona ids only, no prompt content. For task-anchored routing, we also record the task’s anchor persona id, whether the turn was held to that anchor, and the effective routing category — persona ids and category tags only, no prompt content. These are tags and small numbers — no prompt or code content.
- Attached to each event: an anonymous install id (a random UUID generated
on your machine — not your name, email, or any device identifier; a reinstall
gets a fresh one), the extension version, and — if a maintainer asked you to set
one — a coarse cohort tag like
"colleagues"or"beta". Nothing identifies you.
What is never uploaded: your prompts, your code, file contents, API requests or responses, file paths, your username, IP-derived data, or anything we could use to identify you. The uploaded payload is the same anonymous, scalar-only schema as the local CSV logs — minus the prompt prefix and the reasoning text.
Where it goes: a Supabase Postgres database hosted in the United States
(us-east-1). The write key the extension carries can only append events of
the allowed types — it cannot read anything back. Self-hosters can point the
extension at their own Supabase via zhivra.telemetry.uploadEndpoint.
Turning it off: set zhivra.telemetry.uploadEnabled to false. Already-uploaded
events stay where they are; nothing further is sent.
Routing-improvement uploads (opt-in, off by default)
This is a separate channel from anonymous telemetry above. Anonymous telemetry tells our auto-router what happened (which persona was picked, did you accept it). Routing-improvement uploads add the request and the answer so a third-party judge LLM can grade quality. We split it out as its own setting because it’s a meaningfully larger privacy surface — and because plenty of users will reasonably want the first channel but not the second.
It is controlled by the zhivra.routingImprovement.enabled setting and is
off by default. You can also flip it via the Zhivra: Configure Routing Improvement Consent command. We may also ask you once, via a one-click
prompt, if you already have anonymous telemetry on. If you say “Not now,” we
re-ask at most once, 30 days later, and then never again — no dark patterns.
What is uploaded, if you opt in (per routed turn):
- Everything the anonymous-telemetry channel uploads (routing decision, persona id, model id, accept/reject signals, edit-distance bucket).
- The full text of your prompt for that turn, up to 32 KB.
- The full text of the agent’s response for that turn, up to 64 KB.
- The list of tools the persona had access to (tool names only — e.g.
read_file,apply_diff,execute_command). - The size in characters of each tool’s output — not the output content.
If the agent reads a 50,000-character file, we upload “
read_file, 50000”; the file contents stay on your machine. - The same anonymous install id, extension version, and cohort tag the anonymous-telemetry channel uses.
What is still not uploaded: file contents the agent read or wrote, the text of diffs the agent applied, command output, API keys, your name, email, IP, or any device identifier. The boundary on tool output content is the same in both channels — only the metadata changes.
Where it goes: the same Zhivra-operated Supabase Postgres database in the
United States (us-east-1). From there, every routed turn is forwarded to
a third-party LLM provider so a judge can score it. Which provider depends on
which persona ran — we apply a family-separation rule (a Claude judge never
scores a Claude persona’s output, and so on):
- Anthropic Claude (Haiku 4.5 for the bulk judge; Sonnet 4.6 for a 5% calibration sample). Retention: 7 days for commercial API traffic; up to 2 years for abuse-flagged content; classifier scores up to 7 years. Anthropic moved from 30-day to 7-day retention on September 14, 2025. Source: https://privacy.claude.com/en/articles/10023548-how-long-do-you-store-my-data. Zhivra does not currently have a Zero Data Retention contract with Anthropic; we will pursue one before the public beta.
- Google Gemini Flash on a paid API key. Retention: none at rest —
prompts and responses to
generateContentare not stored after the response and are not used for training on paid keys. (Free-tier Gemini behaves differently; Zhivra does not use a free-tier key.) - OpenAI gpt-4o-mini for a 5% calibration sample on non-Anthropic-persona turns (family separation blocks Claude from grading itself, so we need a third provider). Retention: 30 days for abuse monitoring; data not used for training by default on API calls. Zhivra does not currently have an OpenAI ZDR contract.
These are the providers’ policies, not promises we can enforce. If a provider
changes posture, we will update this section and docs/contributing-routing-data.md.
How to opt out: set zhivra.routingImprovement.enabled to false. From
the next turn onward, no prompt or response content is uploaded. Already-uploaded
data stays unless you also run Zhivra: Delete My Telemetry (next paragraph).
How to delete what you’ve already contributed: the Zhivra: Delete My Telemetry command cascades a deletion of your anonymous install id’s rows
across the Zhivra-controlled tables. Specifically, in this order:
- Storage objects — zip blobs from any diagnostic reports you’ve sent are removed from our Supabase Storage bucket.
diagnostic_reports— metadata rows for those diagnostic reports.judge_scores— every quality / routing-fit / tool-fit score the judge LLM produced for your turns.telemetry_events— every dogfood routing decision + every behavioral signal (accept / reject / re-ask / frustration / etc.) we have for you.upload_attempts— the rate-limit log for your diagnostic uploads.consent_grants— your consent row is marked withdrawn (granted = false) rather than deleted immediately. A daily reaper job sweeps withdrawn rows after 30 days, at which point the row itself is gone. The 30-day delay exists so we can prove to ourselves (in an audit) that the withdrawal was processed, not lost.
After the cascade completes, your local install id and consent token are rotated; future turns from this machine are treated as a fresh install.
The delete cascade covers everything we store. It does not reach into the third-party LLM provider’s abuse-monitoring window described above — that data is held by Anthropic (7-day window), Google, or OpenAI under their own retention policies (the windows listed above) and we have no API to delete it. This is the documented gap; we’d rather state it honestly than imply we can wipe data we can’t.
Long version: see docs/contributing-routing-data.md
for the plain-English explainer, the trade-off in one paragraph, and pointers
into the source.
Verify Install command
Zhivra: Verify Install is a self-diagnostic command added in the pre-beta
build. Run it from the Command Palette to see a quick report on whether your
extension is configured correctly and whether your install id is registered
with Zhivra’s telemetry server. It also runs automatically once 30 seconds
after the first activation — only after you’ve already answered the routing-
improvement consent dialog — with Yes / Not now / Don’t ask again choices.
“Not now” suppresses the prompt for 7 days; “Don’t ask again” turns it off
permanently. You can always invoke the command yourself afterwards.
What the command sends to Zhivra’s server: your anonymous install_id
(the same UUID the rest of Channel-D uses) and the extension version. That is
the entire request body. No prompts, no code, no settings, no behavioral data
are sent — and the request is authenticated by the same publishable key any
client carries, not by a per-install secret.
What comes back: aggregate counts only, for your install id —
how many telemetry_events rows are recorded (today and all-time), whether
a consent_grants row exists and its granted state, the shape of the
consent token hash (sha256 / grandfather sentinel / null — never the hash
itself), aggregate counts for judge_scores and diagnostic_reports, and
the latest scored-at / received-at timestamps. The hash of your consent token
never leaves the server.
What the rendered report shows: the response above + your local settings
(telemetry.uploadEnabled, routingImprovement.enabled), the dogfood CSV
path (rendered with your home dir as ~/ so screenshots don’t leak your
username), the timestamp of the latest CSV write, and the count of
pending-retention.json entries. Your install id is truncated to the first
8 characters before display.
Where it goes: the same Zhivra-operated Supabase project in us-east-1
that hosts the rest of Channel-D, at the new
/functions/v1/verify-install Edge Function. Self-hosters can override via
the zhivra.verifyInstall.endpoint setting. The endpoint is rate-limited to
10 calls per install id per hour (it reuses the upload_attempts table); a
single rate-limit log row is inserted per call, no other writes happen.
How to opt out: don’t run the command, and pick “Don’t ask again” if the one-time prompt appears. The command never auto-fires after the first run.
Diagnostic reports — only if you choose to send one
If you hit a bug and want us to help, Zhivra has a Zhivra: Send Diagnostic Report command (Command Palette). Nothing uploads in the background. An
upload only happens when you run that command and pick “Send to Zhivra” in the
second dialog. This is one of three paths by which your data can reach Zhivra:
the other two are the opt-in anonymous routing telemetry
channel and the opt-in routing-improvement uploads
channel — both off by default. Diagnostic reports aren’t on/off; they just
run when you ask them to.
What the bundle contains:
dogfood/dogfood-*.csvandoutcomes-*.csv— routing decisions and behavioral signals (which persona was picked, accept/reject, edit-distance buckets). Scalar metadata only, anonymous. Only present if you had the local routing/outcome logs enabled.errors/recent.jsonl— the last 200 lines of the local error log (scrubbed stacks, file paths replaced with~/and<workspace>/). No prompt or code content.output-channel-tail.txt— the last 500 lines of the Zhivra Output panel.tasks/<taskId>/for the last 10 task directories —history_item.json,task_metadata.json,ui_messages.json,api_conversation_history.json. These conversation files are redacted by default (see below).versions.json— extension, VS Code, OS, and Node versions.manifest.json— a listing of every file in the bundle and the redaction level you picked.
What’s NOT in the bundle by default: your prompts, your code, the model’s
completions, and the contents of any files the agent read or wrote — all
replaced with [REDACTED — len=N] placeholders, keeping only structural
metadata (timestamps, roles, tool names, token counts). The first dialog gives
you three task-history options:
- Redacted (recommended) — the default; placeholders only.
- FULL (sensitive) — includes raw prompts and code. Explicit opt-in, with a clear warning in the dialog. Pick this only when the bug needs the actual prompt or file to reproduce, and only if you trust where it’s going.
- Skip task history — omit the
tasks/directory entirely.
The second dialog then asks where to send it: Send to Zhivra (recommended),
Save locally instead (you get a .zip you can email yourself), or
Cancel.
Where it goes if you choose “Send to Zhivra”: a Zhivra-operated Supabase
project hosted in the United States (us-east-1). Stored privately in
Supabase Storage; access is restricted to Zhivra maintainers debugging the
report.
How long it’s kept: 30 days, then auto-deleted by a scheduled job. We don’t keep copies elsewhere.
Reference code: after a successful upload you’ll see a code like
ZD-XXXX-XXXX. Include it when you email us at support@zhivra.com — that’s
how we find your bundle on the server. Without it we have no way to match a
report to a person, by design.
How to opt out: don’t run the command. If you’ve already started it and
changed your mind, pick Cancel in the second dialog (nothing is uploaded
until you confirm). If you want the bundle for your own records but don’t want
us to have it, pick Save locally instead — you can then email the zip to
support@zhivra.com yourself, or attach it to a GitHub issue, on your terms.
What we do not do
- We do not train any AI models on your data. (The judge LLM that scores routing-improvement uploads grades them; the providers we send those uploads to — Anthropic, Google paid Gemini, OpenAI — do not use API content for training by default. We don’t run our own training pipeline.)
- We do not sell or share your data with third parties — outside the two explicit, opt-in upload channels described above (anonymous telemetry and routing-improvement uploads), and the diagnostic-report path you trigger by hand. Routing-improvement uploads pass through a third-party judge LLM by design; that’s disclosed in its own section above.
- We do not upload your code, prompts, conversations, or diagnostics
anywhere automatically without an opt-in. A diagnostic report is only sent
when you run
Zhivra: Send Diagnostic Reportand pick “Send to Zhivra”; there is no automatic crash-report upload in the free fork. Background uploads happen only on the two opt-in channels above — both off by default. (So the network traffic Zhivra originates is: your configured AI provider and its public model catalog; — only if you opted in — the anonymous-telemetry endpoint; — only if you separately opted in to routing improvement — the routing-improvement upload endpoint plus the third-party judge LLM call it triggers; and — only when you explicitly send one — a diagnostic report.)
Your controls
- Configure a local model provider to keep everything on your machine.
zhivra.errorLog.enabled— turn off the local error log.zhivra.dogfoodLogger.enabled— turn on (or leave off) the local routing/outcome logs.zhivra.telemetry.uploadEnabled— turn off (the default) or on the anonymous telemetry upload.zhivra.telemetry.uploadEndpoint— point it at your own Supabase if self-hosting.zhivra.routingImprovement.enabled— turn off (the default) or on the routing-improvement uploads (full prompt + agent response to a third-party judge LLM).Zhivra: Configure Routing Improvement Consentre-opens the prompt at any time.Zhivra: Delete My Telemetry— cascade-delete everything Zhivra holds about your install id (telemetry events, judge scores, consent record, diagnostic reports) and reset your install id locally.Zhivra: Send Diagnostic Report— a no-op until you run it. You upload only if you choose to; the same command has a “Save locally instead” option that never touches the network.zhivra.diagnostics.endpoint— point it at your own Supabase deployment if self-hosting.- Delete tasks from the history view, or
~/.zhivra/directly, at any time. - Uninstall the extension to stop all local data collection.
Security & changes
We take reasonable measures to protect data on your machine, but no system is perfectly secure. If this policy changes materially, we will surface a notice in the extension.
Contact
For privacy questions, open an issue on the Zhivra project repository.
By using Zhivra, you agree to this Privacy Policy.