Exact
Substring against title, headings, summary, keywords. Always outranks everything below it.
exact title match
Dynamic Revealing Vector Search
Your list stays exactly where it is, in its own order. A query only changes how visible each row is — strong matches stay lit, weak ones dim, misses fade to a ghost. Nothing is moved, re-sorted, or removed. You keep the context that a results page throws away.
Nine documents about entirely mundane things — coffee, balcony tomatoes, a bike chain — deliberately unrelated to anything DRVS was extracted from. This is the actual package running in your browser against a real prebuilt index. Not a mockup, not a recording.
This corpus also exists in Traditional Chinese, with the same ids and the same relations. Both are built and tested the same way — that parallel is how the claim "not script-specific" gets checked instead of asserted.
Confidence, calibrated
A photographer checks an exposure against a step wedge — a strip of known, evenly-spaced densities. DRVS ranks the same way: every result lands on a fixed step, and the step is the opacity you actually see. These are the real numbers from config/search.config.json, not an illustration.
Exact. The query is literally in the title, a heading, or a confirmed alias.
Close. Strong lexical overlap, or an exact hit somewhere less central.
Weak. Character-level or embedding similarity, with no literal anchor.
Distant. Usually structural — a sibling of something that did match.
Masked. Still on the page, still readable, just out of the way.
Tier is never carried by color alone. Each row gets an opacity step and a text label naming the reason, plus data-drvs-tier for assistive tech. In forced-colors mode the opacity ladder flattens and the labels carry it on their own.
Five channels, one honest answer
Not a relevance score. Not "the model thinks so." Every result carries a specific claim you can check — and if a channel has nothing to say about a document, it stays silent rather than inventing a number.
Substring against title, headings, summary, keywords. Always outranks everything below it.
exact title match
CJK bigrams and Latin token overlap, so typos and paraphrases still land. No stemmer, no language config.
lexical similarity
Alias expansion from evidence you can point at — a curated set, or an acronym a document defines in its own title.
matched known alias “avocado”
A document with no direct hit can ride in on a curated link to one that did — and it says so, rather than pretending it matched.
same series as a confirmed match
Embeddings compared in the browser against prebuilt vectors. No API, no per-query cost. Chunk-level, so it can name the passage.
this passage is close (Storage)
Every optional channel degrades structurally. No dictionary, no vectors, model won't load — the rest keeps working and nothing upstream notices.
exact + lexical still ranked
The part most search UIs get wrong
When nothing clears the confidence bar, it relaxes the threshold, still returns the closest documents, and tells you plainly that it did: "No high-confidence direct match. Showing the semantically closest documents only." You can see the results and you can see the caveat.
Dress a weak match up as a confident one. Relaxing the threshold is always disclosed, a low-confidence banner is never suppressed, and an index with genuinely nothing in it says so rather than padding the list. Non-zero results is not permission to fabricate.
Getting started
Python, build time. The helpers do the file-level work — frontmatter, headings, summary, keywords — so your adapter is mostly plumbing.
# your adapter walks your corpus and assigns ids
from build.extract import extract_document, compact_document
docs = [extract_document(doc_id, title, url, text)
for doc_id, title, url, text in my_corpus()]
index = {"count": len(docs),
"documents": [compact_document(d) for d in docs]}
The control markup is built for you. Your rows are left alone except for classes and data attributes.
import { createRevealUI, STRINGS_EN } from "drvs/ui";
createRevealUI({
root: "#search",
rowSelector: "[data-doc-id]",
indexUrl: "/drvs/index.json",
strings: STRINGS_EN,
});
Override custom properties. You should never need to fork the stylesheet.
:root {
--drvs-accent: #e8743b;
--drvs-tier-c-opacity: .62;
}
The adapter that turns your actual files into documents — walking your storage, assigning stable ids, mapping URLs. DRVS deliberately has no opinion on what a corpus is made of, because that is the one part no generic package can do for you honestly.
And what goes in the dictionary. The builder will propose entries from self-defining titles, but a fabricated alias is the most damaging thing this system can do: it makes unrelated documents look like confirmed matches, under the most authoritative label the interface has. Read audit_candidates() output before shipping one.