CortexDB 0.9.13
The durable token and cost accounting v0.9.12 added is now visible in the admin UI, on the Observability page where you were already looking.
Before you upgrade
Nothing here changes a contract. No new upgrade notes since v0.9.12.
This release also carries a dependency security fix (rustls, RUSTSEC-2026-0285) that affects outbound provider calls. See Security below.
What you get
Open the admin UI and go to Observability. There is now a Tokens & cost block reading the durable ledger, and a month-to-date spend strip on Overview.
- Month to date and Since inception are one click each.
- Cost and tokens by role, with calls and mean latency — slow-and-cheap is a different problem from fast-and-expensive.
- A per-day trend, and a by-model table carrying exact tokens beside the model name with an implied rate per million, so you can re-price at your own rate.
- Enrichment coverage: events enriched, facts per event, failed, and the backlog, which is labelled a live gauge because that is what it is.
- Per-scope totals, click to filter.
- A CSV export of the same buckets, flat, for a billing pipeline.
What the page will not do
It will not show you a number that looks measured when it is not. That is the point of the page, not a detail of it, and the same release hardens it twice.
Three marks, distinguishable without hovering:
- exact: a plain number.
- a floor: "≥ n" in amber, when the provider reported only part of the usage. The entity-extraction lane does this: it returns one combined token count with no input/output split, so those tokens are held out of the split rather than priced at an output rate, which would overstate that lane several-fold.
- unmeasured: a hatched chip carrying a WORD, never a figure. A model this build has no rate for is "unpriced", not "$0.00" — because zero dollars there means we could not price it, not that it was free. Set CORTEX_MODEL_PRICES to give that model a rate.
Two roles do not fully reach the ledger and the page says so rather than reading as zero. The reranker records nothing at all: no token or cost data crosses its interface, and its provider bills per search unit rather than per token. The answer lane records every call site except four small fact-join calls.
Those two are NOT the same thing, and this release fixes a bug where the page
treated them alike. A window with no answer calls was drawn as "no tokens, no
dollars, and none will be recorded", which is false and false in the expensive
direction, about the lane most likely to dominate a bill. /v1/admin/usage now
publishes coverage as full, partial or none, so a reader can tell "this lane
was idle" from "this lane is invisible". A partly-counted lane with no calls now
says exactly that, and that a future window can under-report it.
Also fixed: the card header asserted durability before the data arrived and was never corrected, so an in-memory ledger showed "these counters survive a restart" directly above a red banner saying they do not.
The instrumentation and cost_basis blocks are now documented in
docs/schemas/openapi.json. Every honesty mark is derived from them, and they
were previously undocumented.
Security
rustls is updated 0.23.37 -> 0.23.45, which carries the fix for RUSTSEC-2026-0285: TLS 1.3 handshake messages were accepted across encryption level boundaries (CVSS 5.3). CortexDB serves plain HTTP and terminates no TLS itself, so the exposure is on outbound calls to embedding, reranker and LLM providers, not on the listener. Taking the fix pulls aws-lc-rs to 1.18.1 and its compiled backend aws-lc-sys to 0.45.0; the full Linux suite was re-run on that lockfile rather than inherited from the previous one.
Known gap
This repository has no JavaScript test harness, so the page's rendering rules — including the unpriced-is-not-zero behaviour above — are not pinned by anything CI re-runs. The Rust tests cover the wiring only. Worth knowing if you edit it.
Clients
Unchanged from v0.9.11: cortexdbai 0.11.2 on PyPI and 0.9.3 on npm, cortexdb-connectors 0.2.21, cortexdb-mcp 0.7.5, cortexdb-cli 0.5.4.
Notes
Single-node remains the only supported topology.
POST /v1/experience?wait=settled is still accepted but cannot succeed and
returns 503 SETTLEMENT_UNAVAILABLE. Use wait=indexed.
The online re-embed job remains designed and unbuilt; v0.9.12's flagged drop-and-rebuild is the offline path.