💡 1. The Problem: Why Grep & Flat RAG Fail Autonomous Agents
When an autonomous coding agent (Cursor, Claude Code, Windsurf, or an Antigravity loop) is assigned a complex feature or bug fix, its initial turns are dominated by code exploration.
In most systems today, that exploration relies on two deeply flawed primitives:
- The Brittle Grep Trap: Agents execute sequential
find_by_nameandgrep_searchqueries. But regex cannot distinguish between a function definition, an interface contract, an import statement, or an occurrence inside a comment string. An agent grepping forhandleAuthroutinely drowns in 40 false-positive text occurrences. - The Flat Vector RAG Trap: When codebases are chunked into 500-token chunks and embedded into generic vector databases, syntactic and topological structure is destroyed. Vector embeddings compress tokens into continuous semantic space. When an agent searches for
res.clearCookie, cosine similarity frequently surfaces adjacent cookie middleware rather than the authoritative method definition. - Topological Blindness: Code is not prose; it is a directed call graph. Knowing that
validateSession()exists tells an agent nothing about which API routes call it, what exceptions it throws, or what database pools it mutates. Without dependency graphs, refactoring is blind.
krusch-git was engineered to replace blind text grepping with an authoritative, structured, and relational code intelligence layer.
🎯 2. What krusch-git Is (and What It Is Explicitly Not)
Before examining the schema, it is crucial to state the product boundary:
krusch-git is explicitly NOT a Git replacement. It does not perform merges, rebases, checkouts, branch creation, or pull requests. Real Git handles version control on disk.
krusch-git is an agent-facing relational index running alongside Git. It indexes Git commits, trees, blobs, AST symbols, and caller/callee edges into PostgreSQL so that LLMs can explore codebases via high-signal SQL queries rather than burning hundreds of turns running ls and cat.
🗄️ 3. The Git DAG in SQL: PostgreSQL + pgvector Storage
Under the hood, krusch-git maps Git's content-addressed Directed Acyclic Graph (DAG) directly into PostgreSQL 16 tables:
-- Core Git DAG Tables in PostgreSQL
CREATE TABLE repositories (
id BIGSERIAL PRIMARY KEY,
name TEXT UNIQUE NOT NULL,
default_branch VARCHAR(64) DEFAULT 'main',
indexed_at TIMESTAMPTZ DEFAULT clock_timestamp()
);
CREATE TABLE git_commits (
id BIGSERIAL PRIMARY KEY,
repository_id BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
commit_sha VARCHAR(40) NOT NULL,
parent_shas VARCHAR(40)[] DEFAULT '{}',
author_name TEXT,
commit_message TEXT,
tree_sha VARCHAR(40) NOT NULL,
committed_at TIMESTAMPTZ NOT NULL
);
CREATE TABLE git_blobs (
id BIGSERIAL PRIMARY KEY,
repository_id BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
blob_sha VARCHAR(40) NOT NULL,
file_path TEXT NOT NULL,
content BYTEA, -- Full content or NULL in pointer-mode
pointer_path TEXT, -- Absolute filesystem path if pointer-mode
embedding vector(1024), -- BAAI/bge-large-en-v1.5 dense vector
tsv_content tsvector, -- Lexical search vector for BM25
last_seen_at TIMESTAMPTZ DEFAULT clock_timestamp()
);
CREATE INDEX idx_git_blobs_repo_path ON git_blobs (repository_id, file_path);
CREATE INDEX idx_git_blobs_embedding ON git_blobs USING hnsw (embedding vector_cosine_ops);
CREATE INDEX idx_git_blobs_tsv ON git_blobs USING gin (tsv_content);
Every indexed file blob receives:
- A 1024-dimensional dense embedding (generated via local Ollama
bge-large). - A PostgreSQL
tsvectorgenerated viato_tsvector('english', ...)for exact token ranking. - A
last_seen_attimestamp anchoring the commit time for exponential recency decay.
📂 4. Pointer-Mode Resolution for Massive Monorepos
When indexing large monorepos containing gigabytes of code, duplicating raw file contents into PostgreSQL BYTEA columns introduces unacceptable database bloat.
krusch-git implements Pointer-Mode Storage:
- For small files or standalone deployments, file content is stored directly in
git_blobs.content. - In pointer-mode (
--pointer-modeor large repos), the database stores only the file metadata, embedding, AST symbols, and an absolutepointer_path. - When an agent invokes
krusch_git_read_blob, the server'sresolveBlobContentengine dynamically resolves the file:export async function resolveBlobContent(blob) { if (blob.content) return blob.content.toString('utf-8'); if (blob.pointer_path && fs.existsSync(blob.pointer_path)) { return fs.readFileSync(blob.pointer_path, 'utf-8'); } return null; // Graceful null handling without uncaught exception }
This architecture delivers instant zero-copy lookups for gigabyte-scale repositories with complete protection against missing files or broken symlinks.
🧩 5. Transparent Pragmatism: Zero-Dependency AST Lexing
Academic code-search systems invariably mandate Tree-sitter C++ bindings. In practical engineering fleets, Tree-sitter introduces severe operational friction:
- Requires
gcc,clang,make,python, andnode-gypbuild environments. - Routinely fails during
npm installon Alpine Docker images, ARM64 Apple Silicon, or restricted CI runners. - Adds 150MB+ of binary footprint and heavy memory overhead.
krusch-git adheres to our core principle of Transparent Pragmatism:
krusch-git implements pure JavaScript balanced-brace scanning and structural regex tokenizers across JavaScript, TypeScript, Python, Go, and Rust.
The Result: Extracts classes, functions, methods, routes, interfaces, and import edges with 90%+ of full AST utility, instant sub-5ms cold startup, zero build dependencies, and 100% cross-platform stability.
🕸️ 6. Relational Symbol Graphs & Recursive Multi-Hop CTEs
Extracted AST symbols are stored in a dedicated relational schema alongside directional dependency edges:
CREATE TABLE code_symbols (
id BIGSERIAL PRIMARY KEY,
repository_id BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
file_path TEXT NOT NULL,
symbol_name TEXT NOT NULL,
symbol_type VARCHAR(32) NOT NULL, -- 'function' | 'class' | 'method' | 'interface' | 'route'
start_line INT NOT NULL,
end_line INT NOT NULL,
signature TEXT
);
CREATE TABLE code_symbol_edges (
id BIGSERIAL PRIMARY KEY,
repository_id BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
source_symbol_id BIGINT REFERENCES code_symbols(id) ON DELETE CASCADE,
target_symbol_id BIGINT REFERENCES code_symbols(id) ON DELETE CASCADE,
edge_type VARCHAR(32) NOT NULL -- 'calls' | 'imports' | 'implements'
);
When an agent calls krusch_git_dependency_graph({ repo: "my-app", symbol: "verifySession" }), PostgreSQL evaluates a recursive Common Table Expression (CTE) walking caller and callee edges up to $N$ hops:
WITH RECURSIVE graph_walk AS (
SELECT source_symbol_id, target_symbol_id, edge_type, 1 AS depth, ARRAY[source_symbol_id] AS path
FROM code_symbol_edges e
JOIN code_symbols s ON e.source_symbol_id = s.id
WHERE s.symbol_name = $1 AND s.repository_id = $2
UNION ALL
SELECT e.source_symbol_id, e.target_symbol_id, e.edge_type, gw.depth + 1, gw.path || e.source_symbol_id
FROM code_symbol_edges e
JOIN graph_walk gw ON e.source_symbol_id = gw.target_symbol_id
WHERE gw.depth < 3 AND NOT (e.source_symbol_id = ANY(gw.path))
)
SELECT * FROM graph_walk;
Within milliseconds, the agent sees the entire blast radius of a proposed refactor, verifying all inbound callers before touching public interfaces.
⏳ 7. Mathematical Recency Prior: Exponential Temporal Decay
In active development, files touched yesterday are dramatically more likely to be relevant to current tasks than dead branches or unmaintained scripts from six months ago.
krusch-git applies an automated exponential recency decay formula:
Under this mathematical formula:
- A blob updated today retains 100% of its semantic score ($e^0 = 1.00$).
- After 30 days of inactivity, relevance score decays by ~26% ($e^{-0.30} \approx 0.741$).
- After 100 days of inactivity, relevance score decays by ~63% ($e^{-1.00} \approx 0.368$).
This recency prior prevents legacy code from cluttering search results while still allowing foundational utility functions to surface when semantic relevance is overwhelmingly strong.
📊 8. Hybrid Reciprocal Rank Fusion (RRF) & Empirical Benchmarks
Pure vector search fails when queries contain exact syntactic tokens (e.g. res.clearCookie or DatabaseSync). Pure BM25 fails when queries are conceptual (e.g. "where is user session persistence handled?").
krusch-git executes a single-query Reciprocal Rank Fusion (RRF with $k=60$) combining dense pgvector cosine similarity and tsvector BM25 cover-density ranking:
Empirical Evaluation on `expressjs/express` (Foreign Codebase)
Evaluated on the foreign, third-party repository expressjs/express (206 files, 3,354 symbols) across frozen queries:
| Retrieval Strategy | Recall@1 | Recall@10 | MRR | Exact Code Identifiers R@1 | Semantic Concepts R@1 |
|---|---|---|---|---|---|
BM25 Lexical (ts_rank_cd) |
10.0% | 10.0% | 0.100 | 20.0% | 0.0% |
Dense Cosine (bge-large 1024d) |
60.0% | 90.0% | 0.733 | 40.0% | 80.0% |
| Hybrid RRF ($k=60$) | 70.0% | 90.0% | 0.783 | 60.0% (+20% gain) | 80.0% |
🛠️ 9. The 7 Canonical Tools: Contract & Dual Signatures
krusch-git exposes exactly 7 canonical tools locked in its public API contract:
| Tool Name | Accepted Signatures | Primary Return Payload |
|---|---|---|
krusch_git_list_repos |
{} |
List of indexed repos, branches, and commit timestamps |
krusch_git_read_tree |
{ repo, tree_sha } |
Directory tree hierarchy and blob SHA pointers |
krusch_git_read_blob |
{ repo, file_path } or { blob_id } |
Complete UTF-8 file contents with pointer-mode resolution |
krusch_git_semantic_search |
{ repo, query, limit } |
Ranked code snippets with hybrid RRF scores and age decay |
krusch_git_search_symbols |
{ repo, query, symbol_type } |
Authoritative symbol declarations, signatures, and line numbers |
krusch_git_file_symbols |
{ repo, file_path } or { blob_id } |
Ordered line-range symbol map for the target file |
krusch_git_dependency_graph |
{ repo, symbol } or { repo, file_path } |
Direct symbol definitions, inbound callers, and outbound imports |
{ repo, symbol, file_path } strings with dynamic SQL ID resolution, while maintaining backward-compatible pg_git_* aliases for legacy pipelines.
🔗 10. Sibling Synergy: The 3-Tier Coding Agent Stack
The most significant architectural breakthrough in our homelab was separating decision memory from codebase structure:
┌─────────────────────────────────────────────────────────────┐
│ 1. SESSION START & INVARIANTS │
│ krusch-context-mcp: retrieve, remember, revise, nudge │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. CODE EXPLORATION & ARCHITECTURE │
│ krusch-git: search_symbols, dependency_graph, read_blob │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. STAGED EXECUTION & VERIFICATION │
│ krusch-harness: run, task_status, diff, apply_diff │
└─────────────────────────────────────────────────────────────┘
In this 3-tier architecture:
- Tier 1 (
krusch-context-mcp): Hydrates working memory, architectural decisions, and pre-commit invariants (why code was written). - Tier 2 (
krusch-git): Explores Git trees, AST symbol declarations, and multi-hop call graphs (how code is structured). - Tier 3 (
krusch-harness): Holds candidate diffs in PostgreSQL staging tables, runs sandboxed verification tests, and executes atomic 2PC applies only after all unit tests pass (how code is safely committed).
🚀 11. Ops Surface, Standalone Testing & Quickstart
krusch-git is packaged for immediate homelab and enterprise deployment:
# 1. Clone repository
git clone https://github.com/kruschdev/krusch-git.git
cd krusch-git
# 2. Run standalone test suite (zero pre-existing .env required)
npm test
# 3. Snapshot and index a project
SKIP_LLM_SUMMARY=true node scripts/sync_to_pg.js /path/to/my-project
# 4. Start MCP stdio server
npx krusch-git
Cursor & Claude Code MCP Configuration
Add to your .cursor/mcp.json or Claude Code configuration:
{
"mcpServers": {
"krusch-git": {
"command": "npx",
"args": ["-y", "krusch-git"],
"env": {
"DATABASE_URL": "postgresql://kdcode:password@localhost:5432/kdcode"
}
}
}
}
🌌 12. Architectural Horizon: Deterministic Code Grounding
The era of throwing raw text files into unindexed prompts and hoping the LLM finds the needle in the haystack is over.
By treating code as a relational Git DAG, extracting symbols with zero-dependency AST lexers, and ranking search results with mathematical recency decay and Reciprocal Rank Fusion, krusch-git gives autonomous coding agents the structural precision of an IDE compiler paired with the semantic depth of modern neural search.