CodeScope is a self-hosted code search service. A Python package,
compute_service, clones repositories, splits them into
syntax-aware chunks, embeds those chunks, and answers queries by fusing a
keyword index with a vector index. A Next.js application in
web/ is the reading room. These seven cards describe what the
code actually does — including the parts that are wired and the parts that
are not.
00.1What the object is
The distributed artefact is a single Python package plus a web client.
pyproject.toml:6 names the distribution compute-service
at version 0.1.0, classified
Development Status :: 3 - Alpha. It exposes one console entry point,
compute-service = "compute_service.main:run"
(pyproject.toml:91), which is a thin wrapper over
uvicorn.run. There is no argparse or click CLI; the operational
surface is the ASGI app, a shell wrapper at scripts/start.sh, and
a two-profile docker-compose.yml.
Card 00-aRetrieval
Two indexes, one ranking
Keyword recall comes from Zoekt (with a ripgrep fallback); semantic recall
comes from a FAISS inner-product index over normalised embeddings. The two
result lists are merged by Reciprocal Rank Fusion at
hybrid_search.py:183, then re-scored by a cross-encoder or by
Cohere's rerank API.
Card 00-bChunking
Syntax-aware units
ASTChunker (ast_chunker.py:133) uses tree-sitter to
cut files at function, class and import boundaries for fourteen declared
languages, splitting anything over 150 lines and back-filling uncovered
regions as module chunks. Files with no parser fall back to
80-line windows with 10 lines of overlap.
Card 00-cEmbedding
Local or hosted, swappable
UnifiedEmbeddingService fronts a local
sentence-transformers model and two hosted providers (Voyage, OpenAI).
Switching provider changes vector width, so the FAISS index is torn down and
rebuilt via reinitialize() (vector_store_faiss.py:135).
Card 00-dAnswering
Retrieval-augmented Q&A
POST /chat classifies the question, retrieves up to 50 chunks,
optionally prepends a stored repository summary, and forwards the whole
thing to either a local Ollama model or the Anthropic Messages API. The
response carries citations, a confidence number and the routing rationale.
00.2Module topology
Figure 00.1 — Module topology
Drawn from the import graph, not from the README (which describes a
routes/tasks.py and services/executor.py that no
longer exist). Dashed modules are physically present but have no importer
reachable from main.py; they are catalogued in
Drawer 06.
00.3Shelf list
The register below is the complete compute_service tree. “Wiring”
records whether the module is reachable from the mounted application, not
whether its logic is correct.
Nothing is constructed at import time. The whole object graph is assembled once
inside the async context manager at main.py:69, wrapped in a single
try/except that appends to app_state.startup_errors
and lets the process continue in a degraded state
(main.py:245-249). This is why /health can report
"degraded" rather than refusing to start.
Figure 00.2 — Construction order
Steps 1–13 correspond one-to-one with statements in
compute_service/main.py:79-218. The right-hand panels record two
consequences worth knowing before reading the rest of the catalogue: the
cross-encoder is pinned to CPU, and service injection uses two different
mechanisms.
00.5Operator surface
scripts/start.sh is the only command-line front door. Its four
subcommands are a case statement at the foot of the file; the help
text below is reproduced from print_usage().
Terminal 1 · scripts/start.shverbatim from print_usage()
$./scripts/start.sh --help
Usage: ./scripts/start.sh [dev|prod|docker|gpu]
Commands:
dev Start in development mode with auto-reload (default)
prod Start in production mode with multiple workers
docker Start with Docker (CPU)
gpu Start with Docker (GPU)
Environment Variables:
COMPUTE_HOST Server host (default: 0.0.0.0)
COMPUTE_PORT Server port (default: 8080)
COMPUTE_WORKERS Number of workers (default: 1 for dev, 4 for prod)
COMPUTE_LOG_LEVEL Log level (default: info)
$./scripts/start.sh dev[INFO] Using virtual environment: /app/.venv
[INFO] Python version: 3.12
[WARN] No GPU detected, running on CPU
[INFO] Server starting on http://0.0.0.0:8080
[INFO] API docs: http://0.0.0.0:8080/docs
exec uvicorn compute_service.main:app --host 0.0.0.0 --port 8080 --reload --log-level info
dev
Checks for a virtualenv, asserts Python ≥ 3.11, probes
torch.cuda then torch.backends.mps, installs the
package if import compute_service fails, then execs uvicorn with
--reload.
prod
Same checks minus the venv warning; defaults COMPUTE_WORKERS to
4 and execs uvicorn with --workers. Note that each worker builds
its own copy of the service graph, including its own in-process FAISS index.
docker
docker compose --profile cpu up --build — the compute-service container, faiss-cpu, no Zoekt binaries.
gpu
docker compose --profile gpu up --build — the
compute-service-gpu container with
network_mode: host, an NVIDIA device reservation, and the host's
zoekt / zoekt-index binaries bind-mounted read-only.
Reading order
Drawer 01 follows a repository from clone to
stored vector. Drawer 02 follows a query in the
other direction. Drawer 03 is the arithmetic
of ranking, Drawer 04 the on-disk schema, and
Drawer 05 the HTTP and browser surface.
Drawer 06 is the honest assessment.