Why zvec-grep is an evidence router

zvec-grep is a local-first search layer for people and software agents. The central question is why it keeps semantic discovery, ranked lexical retrieval, and exact ripgrep in one interface rather than choosing one as the universal answer; understanding that distinction lets you judge when its results are useful and when they still need verification.

That question matters because workspace search rarely begins in a neat state. Sometimes you know the exact name of a function, error message, or configuration key. Sometimes you know only the behavior you are looking for: where a preference is restored, why a request is rejected, or which component decides a rendering path. Those are both legitimate search tasks, but they do not ask the same thing of a retrieval system. One needs coverage and exactness. The other needs a way to discover relevant language and locations that you cannot yet name.

Unknown questions and exact anchors are different jobs

Imagine investigating a repository after a feature has been reported as “remembering the wrong theme.” You may not know whether the behavior is implemented in a hook, a service, a configuration loader, or a startup routine. Searching for the word theme could return hundreds of comments, tests, and unrelated options. Searching for a guessed function name could miss the real entry point entirely. The problem is not simply that there are too many files. It is that the question is expressed at a different level from the code that answers it.

A semantic search route helps with that gap. It can look for passages whose meaning is related to restoring preferences even when the files use terms such as “hydrate,” “load settings,” or “initialize user state.” It returns a ranked sample, so the first results are candidates for inspection rather than a complete census of every possible occurrence. Ranking is valuable here because it narrows an unknown search space, but it does not change the meaning of “all.”

Exact search has the opposite strength. Once you have found a symbol, a distinctive error, a filename, or a quotation, exact matching can tell you where that anchor occurs and whether it appears in every place you need to check. A regular expression can expose a pattern across the workspace. Managed ripgrep in zvec-grep is designed for this direct path: it scans files without needing a semantic index or an embedding model, and it is exhaustive by default unless you intentionally bound its output.

This creates the first rule for understanding zvec-grep: discovery and verification are complementary jobs. If the wording or location is unknown, a ranked indexed search can be the efficient first move. If the wording is known and completeness matters, exact ripgrep is usually the more honest tool. A mixed investigation can use both—discover a likely implementation through meaning, then verify the concrete identifier and its occurrences with exact search. Adding a vector index to every small literal lookup would be needless overhead; refusing semantic discovery when the entry point is unknown would make the search depend on guesswork.

The difference is also a difference in evidence. A ranked result says, in effect, “this is a promising place to look.” An exact search can say, “this known pattern occurs in these locations,” subject to the scope and matching rules you selected. Neither statement is automatically a final explanation. The first may need source reading and exact confirmation; the second may still leave relationships and causes distributed across several files. Zvec-grep’s design becomes clearer once its interface is viewed as a way to move between those kinds of evidence.

flowchart LR Q["Question from human or agent"] --> D{"What is known?"} D -->|"Wording or location unclear"| ENTRY["zg CLI or local MCP"] D -->|"Exact anchor is known"| RG["Managed ripgrep"] ENTRY --> IDX["Workspace index"] IDX --> DISC["Ranked lexical and vector discovery"] RG --> FILES["Workspace files"] DISC --> FILES FILES --> OUT["Compact source-linked evidence"]

What zvec-grep puts behind one boundary

The name zvec-grep describes a product boundary, not a claim that every search is vector search. The project presents zg as a single local-first interface over ripgrep, BM25-style ranked lexical search, and vector search. Ranked lexical search works from words and tokens found in the stored text. Vector search represents text numerically so that related expressions can be compared by similarity. Ripgrep works directly from exact text and regular expressions. Zvec-grep gives these routes a common workspace and result language while preserving their different purposes.

That common boundary is useful for humans because it reduces the need to remember which separate tool owns which part of an investigation. It is even more important for agents. An agent answering a repository question must decide not only what to say, but also where to look and when it has enough evidence. A tool that returns a compact passage with a source location can help the agent move from a broad question to a focused read instead of dumping a large directory or scanning every file in sequence. But zvec-grep does not remove the agent’s judgment. Its guidance explicitly leaves exact lookup to native grep or ripgrep when that is sufficient and reserves indexed search for unknown wording, relationships, architecture, lifecycle, and cross-file synthesis.

The workspace remains the subject throughout this arrangement. Zvec-grep does not search an abstract cloud corpus by default. Files are discovered under a workspace root, an index is kept under that workspace, and results point back to files and ranges that a person or agent can inspect. The current project is intended for source code, documentation, structured data, and other recognized text, with additional handling for some images when they are explicitly selected and the embedding model supports them. This is a practical choice: an answer about a local system should be grounded in that system’s material, not merely in a model’s prior knowledge of similar projects.

The interface also connects two kinds of user. A person can run zg from a terminal and read ranked results or exact matches. An agent normally connects through a local Streamable HTTP MCP endpoint, which gives it a search tool designed to return bounded, source-linked context. Both routes reach the same underlying service for indexed work. The distinction is how the request arrives and how long the process remains available, not a separate definition of relevance for humans and agents.

“Local-first” adds a trust boundary to the product boundary. Workspace files, indexes, and local embedding models are intended to remain on the machine. The server listens on a loopback address by default, so an agent integration talks to a local service rather than requiring a hosted search service for the core workflow. A remote embedding provider is a different case: producing vectors remotely can send query text or workspace content outside the machine. Zvec-grep therefore treats provider credentials and permission to transfer data as separate matters. The fact that an agent is allowed to call a local tool does not by itself authorize remote disclosure.

This matters because retrieval is not only a relevance problem. It is also a question of which material is admitted, which computation is performed, and who may see the material during that computation. The local-first default does not promise that every deployment has identical privacy needs, but it gives the operator a clear starting point: keep the ordinary path local, and make remote transfer explicit rather than incidental.

How the pieces connect

A useful mental model begins with the workspace files. Zvec-grep first decides which files belong to the indexed scope. Ignore rules, path filters, file types, size limits, binary checks, and format support affect that decision. The result is not a mirror of everything below a directory. It is a selected evidence surface. The same workspace files remain available to exact ripgrep, which is why a file can be searchable through the exact route even when it was not admitted to the semantic index.

Selected files are then transformed into searchable representations. Code may be recognized as entities such as classes, functions, or modules, with names, signatures, scope breadcrumbs, documentation, and source ranges. Markdown can be organized by headings and sections. Material without a usable structural interpretation can fall back to bounded text chunks. An embedding model can turn those fragments into vectors, while the stored text and metadata support ranked lexical retrieval. The details of this transformation determine what a later query can discover; an index cannot retrieve structure that was never preserved, and it cannot retrieve a file that scope policy excluded.

At query time, a human or agent supplies an intent, an exact route, or a combination. The search service sends the request to the appropriate path. Indexed retrieval consults the stored representations and returns ranked entities with source evidence. Exact retrieval scans the workspace directly. The resulting response is designed to be compact: enough content and location information to judge relevance and continue reading, without making every internal field or the full source of every hit part of the agent’s context.

That last step is more important than it may first appear. Broad retrieval can increase recall while making an answer harder to construct. An agent that receives dozens of loosely related passages must spend additional calls and context deciding which ones matter. Zvec-grep’s product goal is therefore not simply to return more candidates. It is to surface a smaller set of ranked, source-linked evidence and preserve a route to exact confirmation when the question demands it. Compactness is part of the evidence contract because the usefulness of a result depends on whether its recipient can interpret and act on it.

The system map also explains why the project is not just a database with a command-line wrapper. The workspace, representation, retrieval route, execution process, and reader form one chain. A weak scope can hide the relevant file before ranking begins. A flat representation can obscure a symbol’s role. A good candidate list can still be misleading if the index is out of date. A locally available result can still be inappropriate if the question requires exhaustive coverage that ranked retrieval does not provide. Zvec-grep’s value emerges from the interaction of these parts, not from any one label attached to them.

The boundary that makes the next question unavoidable

Zvec-grep is easiest to understand when its promise is stated narrowly and precisely. It offers a local-first way to route workspace questions to evidence: semantic retrieval helps discover what you cannot yet name, lexical ranking supplies recognizable anchors, and exact search verifies patterns whose coverage matters. For people, this can reduce the friction of switching among tools. For agents, it can reduce broad scans and produce context that is easier to ground in local sources.

That promise has limits from the start. Indexed search is a ranked sample, not an exhaustive proof. Results depend on the files admitted to the index, the structure preserved during extraction, the selected embedding model, the freshness of stored state, the query formulation, and the result limit. A compact snippet can be sufficient to establish relevance without being sufficient to establish a complete causal account. And a local server boundary does not make remote embedding authorization irrelevant; those are separate decisions.

So the right question is not “Is zvec-grep better than grep?” It is “What kind of uncertainty does this workspace question contain, and what evidence must the answer withstand?” When uncertainty is about location or wording, zvec-grep’s indexed layer can narrow the search. When uncertainty is about whether every known occurrence has been checked, exact ripgrep has the stronger coverage contract. When both uncertainties appear, the two paths can be used in sequence.

The rest of this series follows that reasoning into the system itself: first the practical route decision, then the way a workspace becomes searchable, then the ranking and context machinery that turns multiple signals into one evidence response. The point is not to make the reader memorize internal components. It is to make the boundary visible enough that every later choice—how to index, how to rank, how to refresh, and whether to send data elsewhere—can be judged against the question zvec-grep is meant to answer.

References