Skip to content
ELEMENT 31
ALL RESOURCES

Forge

Vectorizing Your Git Repo: How Forge Uses Local Storage for Semantic Code Search

Turning a repository into a semantic index is a data pipeline, not a one-time import — how Forge embeds, stores, and keeps a codebase searchable entirely inside the appliance.

· 7 min read

Grep is a lexical tool. It finds the string you typed, and nothing you meant instead. Ask it for every place a codebase "validates a user's session" and it will hand back exactly zero results if the code happens to say checkAuthToken instead. The concept is present, the words are not. Semantic code search exists to close that gap: it searches for meaning, not characters, by representing code as vectors in an embedding space where functions that do similar things sit near each other regardless of what they're named. Getting that capability onto a sealed, air-gapped appliance means the entire pipeline that produces and serves those vectors (parsing, embedding, indexing, storing, updating) has to run on hardware that never talks to anything outside the box it lives in. That's the engineering problem underneath Forge's search, and it looks different from a cloud vector search stack at almost every layer.

From files to something a vector index can hold

A git repository, from a storage perspective, is a tree of text files and a history of diffs. Neither of those is directly searchable by meaning. The first step in making a repository semantically searchable is deciding what a "unit" of code even is for embedding purposes. Not the whole file, which is usually too large and topically mixed to embed as one meaningful vector, and not individual lines, which are usually too small to carry meaning on their own. Forge parses source into structurally coherent chunks: functions, methods, classes, and the surrounding context that gives them meaning, using the language's actual syntax rather than naive line splitting, so a chunk boundary lands where a human reader would naturally see one.

Each chunk gets embedded, run through a model that maps it to a point in a high-dimensional vector space, and that embedding, along with the metadata that ties it back to a specific file, line range, and commit, is what actually gets stored. The source text stays exactly where it already lived, in the repository on disk; the vector store holds pointers into that repository plus the numerical representation that makes similarity search possible. Nothing about that pipeline requires a network call, and inside Forge nothing about it makes one. The embedding model runs locally, on the appliance's own accelerators, on code that never leaves the enclosure to be turned into a vector somewhere else.

Why local storage, not a managed vector database

A cloud-native semantic search stack usually reaches for a managed vector database, a separate service, often a separate vendor, that ingests embeddings over a network API and returns nearest-neighbor results the same way. That model assumes the vectors, and by extension something derived from the source code that produced them, are allowed to leave the environment where the code lives. For the buyers Forge is built for, that assumption is the one that doesn't hold. An embedding is a lossy but real representation of the code it came from; sending it to a third-party service reopens the exact exposure the appliance exists to close, even if the raw source text technically never crosses the wire.

The alternative is running the vector store as software on the appliance itself, backed by local storage the same way the rest of Forge's index is. That removes the network dependency entirely: there's no managed service to be unreachable, rate-limited, or subject to a vendor's own retention policy, and it means the vector index inherits the same physical security boundary as the source it was derived from. The index lives on the same sealed hardware, under the same access controls, and never has an occasion to exist as a payload in transit.

The index has to move when the repository does

A one-time import is the easy version of this problem. A git repository is not static: commits land continuously, branches diverge and merge, files get renamed, functions get refactored into other functions. An index built once at onboarding and never revisited degrades the moment the first commit lands after it: searches start returning code that has since moved, been rewritten, or been deleted outright, and the gap between what the index says and what the repository actually contains only widens from there.

Forge treats indexing as a standing pipeline rather than a one-time job. Commits are watched, and the chunks touched by a given change are re-parsed and re-embedded rather than requiring a full repository re-index for every diff, a targeted update keyed to what actually changed, not a batch rebuild that would make the index perpetually a step behind a fast-moving repository. That incremental design matters as much for storage efficiency as for freshness: re-embedding an entire large repository on every commit would waste accelerator cycles on the vast majority of the codebase that a given change didn't touch, and would make indexing latency scale with repository size instead of with change size, which is the wrong variable to be sensitive to.

What similarity search actually returns

A nearest-neighbor query against the vector index doesn't return a file. It returns a ranked set of chunks whose embeddings sit closest, in that vector space, to the embedding of the query. "Where do we handle retry logic for failed API calls" becomes a vector, and the chunks that come back are the ones whose meaning is closest to that concept, whether or not the word "retry" appears anywhere in them. That's the entire value proposition of vectorizing the repository in the first place: it lets an engineer or an assistant working on their behalf search by concept, then let structural retrieval (the call graph, the surrounding definitions, the import chain) fill in the precise context once a starting point has been found by meaning rather than by string match.

Semantic search and structural retrieval are complementary, not substitutes for each other, and Forge treats them that way. Vector similarity is good at answering "where in this codebase is something like this done" when you don't know the exact name; structural traversal is good at answering "what else touches this, once you've found it" with precision a similarity score alone can't guarantee. A search stack that only does one or the other misses half of what makes a coding assistant feel like it actually understands the repository.

Storage as a first-class design constraint, not an afterthought

None of this is free to store. Embeddings for every meaningfully sized chunk across a large repository, plus the metadata linking each one back to its source location and commit, add up to a real storage footprint that scales with codebase size, and unlike a cloud deployment, there's no elastic disk to provision on demand when the index grows past what was planned for. That makes the local storage subsystem underneath the vector index a sizing question that has to be answered at deployment time, based on the size and churn rate of the repositories a given appliance is expected to index, not treated as an implementation detail that will sort itself out.

It also means the index itself needs housekeeping: stale vectors from deleted code or superseded branches have to be reclaimed rather than accumulating indefinitely, and the storage layout has to keep read latency low even as the index grows, since a similarity search that gets slower as the repository ages defeats the purpose of having one. This is the less visible half of "semantic search that works": not just the embedding model that turns code into vectors, but the storage engine, entirely local, entirely inside the boundary, that keeps those vectors fast to write, fast to update, and fast to search over the life of a repository rather than just on the day it was first indexed.

The point of doing it this way

None of this (chunking strategy, incremental re-embedding, a locally hosted vector store, storage sized to the repository rather than assumed elastic) is visible to the engineer who types a question into Forge and gets back the right piece of code. That's deliberate. The felt experience is meant to be indistinguishable from a cloud coding assistant's search, while the actual mechanism underneath it never sends a vector, a chunk, or a query outside the sealed hardware the code already lives on. Semantic search on an air-gapped appliance isn't a scaled- down version of the cloud approach; it's the same capability rebuilt from the storage layer up around a constraint cloud vector databases were never designed to satisfy.