The week ZCode's "code library indexing" blew up on V2EX, I was already halfway through wiring a code-search helper for my own repos, so I read every thread with more than idle interest. The short version, pulled from the community reports and the vendor's own Feishu statement: a feature called Repo Wiki, which was default-on at launch, could trigger a full workspace upload to the cloud when it generated its wiki pages. People were passing around claims that entire git histories went up, not just current files. One report even quoted a line about the encryption using an RSA public key handed down by the server, with the private key living only in the cloud, so you couldn't decrypt your own uploaded snapshot. I can't verify that encryption detail, and I'd treat it as unverified, but the pattern is clear enough from the vendor's admission that Wiki generation "may trigger repository data upload."
The vendor apologized, said the uploaded data was destroyed immediately after the cloud generated the wiki page, promised to open-source the codebase, and threw a weekly quota reset at affected users. The community reaction was about what you'd expect. One reply put it bluntly: telling people you deleted the stolen thing afterward is not the same as not taking it. Someone else pointed out that uploading tens of gigabytes of history is expensive bandwidth, so the "we deleted it" line was a hard sell. And a chunk of people just uninstalled.
Here's the thing I keep coming back to, though. The feature itself was not the problem. A searchable, wiki-style Q&A over your own code is genuinely useful. You point it at a repo, you ask "where do we validate the webhook signature" or "what calls the billing reconciliation job," and it answers with the actual relevant snippets instead of you grepping through six directories. The useful half is worth keeping. The silent, full-history, can't-opt-out upload is the part that has to go. So I rebuilt the useful half on infrastructure I control, and the whole exercise came down to one principle: I decide exactly what goes in.
Start with an allowlist you can read with your own eyes
The root failure in the ZCode case was scope. "Index the repository" quietly meant "everything, including .git." So the first thing I built was a plain ingestion allowlist, a hand-editable file that lists exactly which paths get pulled in. Not an exclude list, an include list. Excludes fail open, which is how you end up shipping your git history and a stray .env you forgot about. Includes fail closed. If a path isn't on the list, it never gets read, never gets chunked, never lands in the index.
Mine is just a small config: a set of glob patterns for the directories and file extensions I actually want searchable, plus an explicit block for anything under version control internals, dependency folders, and dotfiles that tend to carry secrets. When I add a new area of the codebase, I add a line. That five-second friction is the feature, not a bug. It keeps the boundary visible.
Chunk locally in Python, on execution you can see
Once the allowlist decides what's eligible, the ingestion step reads those files, splits them into retrieval-sized chunks, and attaches metadata like file path and a rough symbol or section label. I did the chunking in Python because the tooling for walking files, respecting the allowlist, and tokenizing is straightforward there. VicroCode lets you run Python online, so the whole ingestion job lives in the same place I'm going to host the rest of it, and I'm not shuttling code out to some opaque service to get it split up.
The chunking logic is boring on purpose. Split on function and class boundaries where I can detect them, fall back to a fixed window with overlap where I can't, and keep chunks small enough that a retrieval hit lands on something a human would actually read. Every chunk carries its source path so an answer can cite where it came from. If a path isn't in the allowlist, the reader skips it before a single byte is chunked, which is exactly the guarantee the original feature failed to give.
Ground retrieval in a knowledge base, not a black box
The retrieval layer is where the "wiki-style Q&A" actually happens. I load the chunks into a LanceDB knowledge base and query it by similarity, so a question pulls back the handful of code chunks most relevant to it, and the answer is built from those grounded snippets rather than from whatever a model half-remembers. Code-grounded retrieval matters here because you want answers that point at real lines in your repo, with the file path attached, so you can go verify. It's the difference between "here's roughly how auth probably works" and "here's the actual middleware and the file it lives in."
Because the knowledge base only ever contains what the allowlist let through, its contents are auditable. I can look at what's indexed and it will only be the code I chose. There's no separate hidden snapshot of my full history sitting somewhere, because that history was never read in the first place.
Put a small UI in front of it and host it yourself
The last piece is the front door. A single-page HTML app with a search box, a results view showing the matched chunks and their file paths, and an answer panel. Nothing fancy. You can run HTML online on the platform and publish it, so the interface and the Python backend and the knowledge base all sit under one roof that I control, instead of a desktop client phoning home to a cloud I can't inspect. If I want it private, it stays private. If I want to share it with a teammate, I share it deliberately.
One honest boundary worth stating plainly: this runs on the VicroCode platform's hosting and execution, so "self-hosted" here means hosted by me on that platform, not on my own hardware or some arbitrary cloud of my choosing. I'm not going to pretend it deploys to anything the platform doesn't support. What it does give you is a clear, single-owner setup where the data flow is visible end to end, which is precisely the thing the ZCode incident took away from people who trusted a default.
What this actually buys a small team
The trade-off is that you give up the one-click magic of a feature that indexes everything for you. You do a little manual curation up front. In exchange you get a code Q&A tool where you can answer, with certainty, the question every developer in those V2EX threads was suddenly asking about their own machine: what left the building. With this setup, the answer is "only what's on the allowlist, and I can show you the list."
I won't make performance or accuracy claims I can't back up, and I haven't run this against a huge monorepo to see where retrieval quality starts to strain, so treat scaling behavior as unverified until you test it on your own code. But the design goal was never to beat a commercial tool on features. It was to keep the useful half and delete the part that ships your git history behind your back. On that, it does the job. And if you want to turn it into something you offer to others, the platform's publishing and sharing side means you can package and even monetize the same build, still on a consent-first foundation you can explain to anyone who asks.