CortexDB · docs

CortexDB 0.9.12

Two things a pilot asked for by name: you can see what the pipeline costs, and you can change embedding model on a corpus you already have.

Before you upgrade

Nothing here changes a contract. If you are on v0.9.11 there are no new upgrade notes. If you are further back, read the v0.9.10 notes first — scope types are validated when a scope is created, and an explicitly configured embedding endpoint with no credential is a boot refusal rather than a silent fallback to meaningless vectors.

Durable token and cost accounting

GET /v1/admin/usage reports tokens and dollars per pipeline role — embeddings, entity extraction, enrichment, recall, answer, verifier and the background maintenance lanes — and the numbers SURVIVE A RESTART. One bucket per UTC day, role, tenant and model, so summing a range answers month-to-date or since-pilot-start. ?format=csv exports the same buckets flat.

The counter that existed before this release reset to zero on every restart, because it had only ever been process memory. There was no record to lose. Historical spend from before you upgrade cannot be reconstructed, and no estimate here will pretend otherwise.

Read by_role_model, not just the totals. It carries exact token counts beside the model name, which is what lets you recompute dollars at a corrected rate, or at your own rate if you bring your own model, without re-running anything. Cost is a view over the durable record; the tokens are the durable record.

Three fields exist so the report cannot flatter itself:

Two roles are declared uninstrumented rather than quietly read as zero: four calls inside the answer path discard their usage before it can be recorded, and the reranker's interface carries no token or cost data at all (its provider also bills per search unit rather than per token). Both say so in the payload.

Pricing itself was wrong before this release and is worth re-reading if you quoted it. The enrichment lane billed every model at the cheapest model's rate — roughly seventeen times understated if you run gpt-4o there — and anything whose name contained "opus" was billed at the 4.0 rate, roughly three times overstated for claude-opus-4-6. An unrecognised model silently took sonnet's price. One price book now serves every lane, and an unknown model is reported rather than guessed.

In-place embedding migration

Changing embedding dimensions on an existing data directory used to be a hard boot refusal with no way forward except exporting and re-importing into a fresh store. CORTEX_EMBEDDING_REBUILD_VECTORS=1 now authorizes exactly one drop-and-rebuild: the vector indexes whose width no longer matches are dropped and recreated empty at the new width, and the store reports itself incomplete until refilled.

Read docs/EMBEDDING_MIGRATION_RUNBOOK.md before using it. The honest cost: vector recall returns nothing between the drop and the refill, BM25 only, for as long as your corpus takes.

The safety properties, stated because this destroys data on purpose:

The index audit reports all four vector families on every call, not just chunks. It can no longer answer "clean" over a store whose entity or derived vector spaces are empty. It also states plainly that its repair rebuilds EVENT chunks only: enrichment writes fact, triple and summary vectors into the same index and the audit does not re-derive those, so a clean chunk audit means "every event has its chunk vector", not "this index is whole".

Also

The reranker can point at an endpoint you control (CORTEX_RERANKER_URL).

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 — a route pair with a dry-run cost estimate, dual-embed of writes landing during the job, and an atomic swap with no offline window — is designed and not built. This release is the offline path.