Changelog

What shipped, and when.

Including the things we got wrong and fixed. A changelog that only lists features is a marketing page with dates on it.

What actually shipped, newest first. Dates are when it went live on the box.

2026-08-24 (later)

The console is an application now. A persistent left sidebar with a tenant

switcher at the top, grouped sections, and identity at the bottom — the shape

Slack and Discord use, and for the same reason: you are always working inside a

tenant, and the tenant used to be visible only in the URL bar. The single long

tenant page became seven places you can be: Overview, Memory, People, Usage,

Integrations, Billing, Settings. Breadcrumbs, empty states everywhere, and ⌘K

to jump to any tenant.

One design system. The customer dashboard had its own stylesheet, palette

and tab strip. It now shares the console's — same shell, same empty states,

same error boxes.

Your API key stops living in a form field. The dashboard used to ask for it

on every visit and keep it in localStorage between visits, where any script on

the page could read it. Now you hand it over once and it is exchanged for an

HttpOnly cookie. Revoking the key ends every session made from it on the next

request, and a read-only key gives a read-only session.

One screen for every queue. Extraction, webhook delivery and thread

summaries, with depth, oldest waiting item and dead-letter counts — plus the

worker's priority order written down as policy rather than left as a comment.

An activity feed. The audit trail has recorded every supersession and

correction since the beginning; nothing ever showed it as a stream.

Prometheus. /metrics on the proxy, LAN only. Request rates and latency,

queue depth, dead letters, pool and cache stats. LOG_FORMAT=json gives one

JSON object per line with the request id already threaded through everything.

Repeated questions stop paying to be embedded. 60.3 ms → 0.001 ms on a

cache hit.

Deploys stop refusing requests. systemd holds the listening sockets across

a restart, so a deploy queues connections instead of dropping them: 400 of 400

requests succeed where 44 used to fail.

The landing page shows the product instead of describing it. A real

supersession from the demo company, read from the live database — what was

true, what is true, and the fact that both are still there.

2026-08-24

Memory without the proxy. /v1/memory/search runs the same retrieval

cascade and returns what it found instead of sending it to a model — one

embedding, no tokens, no model spend. /v1/memory/turns returns the stored

transcript, decrypted and paged. Varve no longer has to sit in your request

path.

Correct a wrong fact, and have it stay corrected. `POST

/v1/memory/fact/{id}/correct and /retire`, both on the transparency screen.

A human correction is marked, and automated extraction may not reverse it —

where the model disagrees it records a conflict for a person to settle rather

than quietly winning.

Send us a conversation from anywhere. POST /v1/ingest/{source_id}, signed

with HMAC over the body and a timestamp. Any system that speaks HTTP can feed

memory without an adapter being written first.

Webhooks out. Six events, signed with the same scheme as inbound. Queued

and delivered by a worker with retry and backoff, never inline — your endpoint

being slow is not allowed to make our writes slow.

Documents. Upload a handbook and a new workspace knows something on day

one, instead of waiting a week for people to happen to say the right things.

Test mode. vrv_test_ keys run against a sandbox twin of your tenant.

Model calls are mocked and nothing is billed.

Scoped API keys. A key can be limited to any subset of read, write,

model-spend and erase. A key embedded in a client to read memory need not also

be able to write to it or spend your budget.

Audit trail, exposed. GET /v1/memory/audit — every change, who made it,

newest first.

Whole-tenant export. GET /v1/tenant/export, streamed. Leaving is a

documented endpoint rather than a request to a human.

Thread summaries. What a conversation came to, between the transcript and

the facts. Erasing a person deletes summaries drawn from them.

Salience. Facts are weighted by what it costs to miss them, and you can

override our priors. Weighting only ever reorders — it never hides a fact.

Multilingual. Per-message language detection and per-language stemming.

Catalan and Spanish are no longer indexed with English rules.

Metrics over time. GET /v1/metrics — latency percentiles, cache hit rate

and cost, bucketed by hour or day.

Request tracing. Every response carries X-Request-Id, and the id follows

a turn into extraction, so a bad fact can be traced to the call that made it.

Pricing, security, API docs and a demo on the public site, plus an OpenAPI

3.1 spec at /v1/openapi.json.

Fixed

  • purge_tenant could silently leave rows behind when the system was busy. It
  • identified rows by physical location, which moves whenever a row is updated.

    Now keyed on the primary key.

  • Typefaces were loaded from a third-party CDN, sending every visitor's IP
  • address to it. Now served from our own machine.

  • Tenants created after quotas were introduced had no limits applied at all.
  • The published recall figure could not be reproduced. It is now measured by a
  • script in the repository, and the site shows the number that script produces.