Features
Local RAG, Every Repo, Zero Leakage
Cortex ingests every markdown file across all 73 AVIAN repos into a Milvus 2.4 vector store, embeds with Voyage-3-large (1024-dim, COSINE/HNSW), and serves retrieval-augmented answers via Anthropic Sonnet 4.6 or Haiku 4.5. A 30-second asyncio indexer loop watches every repo's HEAD SHA and re-embeds only the files that actually changed — no full re-index on every tick. Six MCP tools wire Cortex directly into Claude Code sessions so any active session can search, retrieve, and interrogate the corpus on demand. Patent-adjacent content is filtered at three independent layers before it ever touches the vector store. Binds to 127.0.0.1 only — no auth layer, no telemetry, no cloud egress of code.
Vector Store
Milvus 2.4 — HNSW, COSINE, 1024-Dim
Milvus Standalone
Cortex shares the fleet Milvus 2.4 standalone instance on
localhost:19530(managed bytools/supporting-services). No separate vector DB to run or maintain — it's already part of the development stack.cortex_docsCollectionMarkdown chunks land in the
cortex_docscollection. Schema:id,repo,path,chunk_index,content(up to 65 535 chars),sectionheading trail,embeddingfloat_vector(1024),git_sha,file_sha,updated_at. Scalar indexes onrepoandpathfor filtered retrieval.HNSW Index — M=16, ef=200
The
embeddingfield uses an HNSW index withM=16,ef=200, and COSINE metric. Nearest-neighbor search is sub-millisecond at monorepo scale, and the index survives Milvus restarts without rebuild.Deduplication by File SHA
Every chunk carries a
file_sha(full-file SHA) alongside the blob-levelgit_sha. The indexer skips re-embedding a file whosefile_shahasn't changed, even if a git merge replays its tree entry under a new commit.Source Code Collection (v2)
A second collection
cortex_code— same 1024-dim schema, Voyage-code-3 embeddings — extends coverage to source files. Identical HNSW parameters; separate collection keeps doc and code retrieval independently tunable.
Embeddings
Voyage-3-Large Primary, BGE-M3 Fallback
Voyage-3-Large (Primary)
All production embeddings use
voyage-3-largevia the Voyage API. 1024-dimensional dense vectors, optimized for long-document retrieval. Configured viaCORTEX_EMBEDDING_MODEL; theVOYAGE_API_KEYenv var is required when this backend is active.BGE-M3 Local Fallback
When the Voyage API is unreachable, Cortex automatically falls back to BGE-M3 running fully locally — same 1024-dim output, no external calls. Swap the default permanently by setting
CORTEX_EMBEDDING_BACKEND=bge.Voyage-code-3 for Source
The
cortex_codecollection usesvoyage-code-3— Voyage's code-specific embedding model — rather than the general-purpose large model. Retrieval accuracy on function signatures, class names, and import paths is meaningfully better than a general-purpose embedder.
Indexer
30-Second Git-Diff Loop
Monorepo Discovery
On boot, the asyncio indexer walks the AVIAN root recursively to find every
.git/directory. Discovered repos and their last-seenHEADSHAs are written tostate/repo_state.json. Deleting that file forces a full re-index on the next tick.SHA-Gated Incremental Updates
Every 30 seconds (configurable via
CORTEX_POLL_INTERVAL_S), the indexer runsgit rev-parse HEADper repo. If the SHA hasn't changed, the repo is skipped entirely. Only changed repos pay the cost of agit diff --name-status <old>..<new>.File-Level Delta Indexing
AandMevents from the diff trigger re-embedding of the affected file only.DandRevents delete the old chunks from Milvus. First-time repos get a fullgit ls-files '*.md'seed pass; subsequent ticks are strictly incremental.mtime Fallback for Non-Git Folders
Directories without a
.git/root (currently only the AVIAN root itself) fall back tomtime-based scanning. The same chunk + embed + upsert path runs; only the change-detection mechanism differs.Fault Isolation
Individual file errors are logged and skipped — the daemon keeps going. Repo-level errors pause that repo for one tick and retry automatically. The indexer never crashes the FastAPI process over a bad file.
Live WebSocket Events
The
WS /ws/indexerendpoint streams real-time indexer events to connected clients: file added, file updated, file deleted, tick complete, per-repo chunk counts. The Cortex frontend subscribes on load and renders a live activity feed.
RAG & Answering
Sonnet 4.6 + Haiku 4.5, Prompt-Cached
Sonnet Mode — k=12
Default
/api/v1/askcalls retrievek=12chunks via Milvus and pass them to Claude Sonnet 4.6 (claude-sonnet-4-6). The system prompt and retrieved chunks are prompt-cached — repeated questions against the same context window are cheap.Fast Mode — Haiku, k=6, 3-Sentence Cap
Pass
mode: 'fast'to switch to Claude Haiku 4.5 withk=6chunks and a 3-sentence answer cap. Latency drops from ~2 s to ~400 ms for quick lookups. The MCPasktool exposes both modes directly.Citation-Enforced Answers
The system prompt (cached) instructs the model to cite every claim with a
[repo:path#section]reference drawn from the retrieved chunks. The model is forbidden from inventing — if the answer isn't in the retrieved context, it must respond with “not in index.”Header-Aware Chunking
Markdown is split by heading hierarchy first (H1 → H2 → H3), then by a 500-token budget with 50-token overlap. Fenced code blocks are never split mid-block. Each chunk carries a
sectionfield with the full heading trail (Architecture > Data Model) so retrieval context is unambiguous. Chunks below 100 tokens are merged with the previous chunk.
MCP Integration
Six Tools, Zero Auth, Stdio Transport
search— Vector Retrievalsearch(query, k=10, repo=None, path_glob=None)— run a Milvus nearest-neighbor search and return the top-k chunks with theirrepo,path,section, andcontent. Optionalrepoandpath_globfilters narrow scope to a single repo or subtree.ask— RAG Answerask(question, mode='sonnet'|'fast', repo=None)— retrieve relevant chunks and return a model-generated, citation-grounded answer. Claude Code sessions call this to interrogate the monorepo mid-conversation without leaving the terminal.list_repos&list_fileslist_repos()returns every indexed repo with its chunk count and last-indexed timestamp.list_files(repo, glob='**/*')returns the file list for a given repo, filtered by an optional glob pattern. Both are read-only — no writes go through MCP tools.get_file&statsget_file(repo, path)returns the full raw contents of any indexed file.stats()returns total chunks, total files, total repos, and per-repo last-tick timestamps. All six tools are thin HTTP clients againsthttp://127.0.0.1:3445— the MCP server requires the backend to be running.One-Line Registration
Register Cortex in any Claude Code session with
claude mcp add cortex python -m cortex_mcp.server --cwd <mcp-server dir>. Stdio transport, zero auth, no daemon to manage separately. The MCP server process is launched by Claude Code on demand.
Privacy & Security
Local-Only, Patent-Excluded, Three-Layer Filter
127.0.0.1 Bind, No Auth
The FastAPI backend binds exclusively to
127.0.0.1(controlled byCORTEX_BIND— do not change without understanding the implications). No auth layer exists by design. Exposing Cortex off-localhost is a separate, future epic — not a config flag.Repo-Level Exclusion
Repos listed in
SENSITIVE_REPO_NAMES(currentlyavian-patent-portfolio) are never discovered, never listed inlist_repos(), and never embedded. The scanner doesn't touch them at all. Additional repos can be excluded via theCORTEX_EXCLUDE_REPOSenv var (comma-separated).Path-Substring Exclusion
SENSITIVE_PATH_SUBSTRINGS(currently{“patent”}) applies a case-insensitive bare-substring check to every file's repo-relative path before embedding. Intentionally aggressive — a file namedpatently_obvious.mdalso matches, and that's fine. False positives are cheap; false negatives are expensive.Purge-on-Tick Sweep
Every time the indexer daemon wakes up, it runs a
_purge_sensitive_paths()pass that deletes any Milvus chunk whosepathfield matches a sensitive substring — regardless of how it got there. This is the belt-and-suspenders pass for content embedded before the filter was added.
Accessibility
Built for Everyone
WCAG 2.1 AA Compliance
4.5:1 contrast for body text, 3:1 for large text and UI components, in both light and dark themes.
Keyboard Navigation
Every interaction reachable via keyboard. Logical tab order, visible focus indicators, Escape-to-dismiss for modals.
Screen Reader Support
VoiceOver, NVDA, and JAWS tested. Semantic HTML, ARIA labels, live regions for dynamic updates.
Reduced Motion
Respects
prefers-reduced-motion. Usable at 200% zoom. Touch targets meet 44x44 minimum.
How It Works
Index, Search, Answer, Act
Step 1: Index
The asyncio indexer daemon polls every repo's HEAD SHA every 30 seconds. Changed files are chunked by heading hierarchy, embedded with Voyage-3-large, and upserted into Milvus. Deleted files purge their chunks. Sensitive paths are excluded and swept at every tick.
Step 2: Search
A query hits
POST /api/v1/search(or thesearchMCP tool). Milvus runs COSINE nearest-neighbor over the 1024-dim embedding space and returns the top-k chunks with repo, path, section, and content — optionally filtered to a single repo or path glob.Step 3: Answer
Retrieved chunks and the question are composed into a prompt-cached Anthropic API call. Sonnet 4.6 (k=12) or Haiku 4.5 fast mode (k=6, 3-sentence cap) returns a citation-grounded answer. The model is instructed to respond “not in index” rather than hallucinate.
Step 4: Act
Six MCP tools expose every capability to Claude Code sessions mid-conversation: vector search, RAG answering, repo enumeration, file listing, raw file retrieval, and index stats. Sessions query the live corpus without leaving the terminal or copy-pasting file paths.
Technical Specifications
Under the Hood
Backend
- FastAPI (Python 3.12+) on port 3445
- asyncio indexer daemon — single task, 30 s poll, fault-isolated per file
- pymilvus client to shared Milvus 2.4 on
localhost:19530 - Anthropic SDK — Sonnet 4.6 default, Haiku 4.5 fast mode
- Voyage Python SDK — voyage-3-large primary, voyage-code-3 for source
- Prompt caching on system prompt + retrieved chunks
- State persisted to
state/repo_state.json(repo path → last SHA + chunk counts) - Binds to
127.0.0.1— no auth layer by design
Frontend
- React 19 + TypeScript (strict) + Vite on port 3444
- Tailwind CSS + @avian/design-system tokens and components
- Live indexer activity feed via
WS /ws/indexer - Search and ask interfaces with citation rendering
- Light and dark mode
RAG & Index
- Milvus 2.4 standalone — HNSW, COSINE, M=16, ef=200
- 1024-dim float vectors (
voyage-3-large/voyage-code-3) - BGE-M3 local fallback when Voyage API is unreachable
- Chunking: 500-token target, 50-token overlap, 100-token merge floor
- Header-hierarchy-first split (H1 → H2 → H3); code blocks never bisected
- Section heading trail stored per chunk for unambiguous retrieval context
cortex_docs(markdown) +cortex_code(source) collections- Scalar indexes on
repoandpathfor filtered search
MCP Server
- Python stdio transport — zero auth, launched by Claude Code on demand
- Six tools:
search,ask,list_repos,list_files,get_file,stats - Thin HTTP client against
http://127.0.0.1:3445 - Read-only — no writes via MCP tools
- One-line registration:
claude mcp add cortex python -m cortex_mcp.server
Privacy
- 127.0.0.1-only bind — no network egress of code or docs
- Repo-level exclusion via
SENSITIVE_REPO_NAMES(patent portfolio excluded) - Path-substring exclusion via
SENSITIVE_PATH_SUBSTRINGS(case-insensitive) - Purge-on-tick sweep deletes any sensitive chunk that slipped through earlier passes
- Additional exclusions via
CORTEX_EXCLUDE_REPOSenv var - No telemetry, no cloud sync of indexed content
Development
100% Built by Claude
Every tool in the Renkara fleet was built by Claude (Anthropic) working alongside a single human supervisor. Every line of code, every test, every deployment: AI-authored with human direction. The leverage factor across the fleet runs in the 20x–50x range, with individual sessions regularly exceeding 100x.
See the daily leverage records for per-task numbers across the full build history.