Skip to content

Nexus

Nexus is the ecosystem’s knowledge base. It answers questions about your organization’s knowledge (documents, policies, configs) and its operational reality (OpenTelemetry traces) only from evidence it can cite. Every answer carries a confidence score and a link back to the source chunk or trace it came from.

Ordinary RAG retrieves text and lets the model improvise, so it returns a plausible answer whether or not it has grounds. Nexus works the other way around: the system decides what can be retrieved and whether an answer is supported, and the model only writes over evidence that already exists. If nothing can be cited, Nexus returns no answer.

In short: enterprise retrieval for grounded answers. It’s the context layer for code-review and troubleshooting agents, so they work from real documents and observed telemetry rather than guesses.

› payment-service dependencies? BM25 · MECAB-KO PIPELINE_SPEC API_CONTRACT VECTOR · PGVECTOR PIPELINE_SPEC ledger.svc GRAPH · 2-HOP payment→fx · payment→ledger not scored — attached after fusion RRF · BM25 + VECTOR 1 PIPELINE_SPEC.md 2 ledger.svc 3 API_CONTRACT.md GROUNDED ANSWER ✓ CITED payment-service → ledger, fx-rate documented + observed · no drift SOURCE PIPELINE_SPEC.md CONFIDENCE 0.92

Core concepts

  • Hybrid search. Two retrievers run in parallel and fuse with RRF (Reciprocal Rank Fusion, k=60): BM25 over Korean morphology (mecab-ko, so particles and endings are stripped correctly) and vector search over pgvector. Fused results are then capped per document so one file cannot flood the answer.
  • Graph is context, not ranking. A 2-hop entity traversal runs on graph-enabled routes, but it happens after fusion and never contributes to a hit’s score. Its edges are returned alongside the answer, not blended into the ranking.
  • Citations are verified, not trusted. The model is asked to cite, and then the citations are checked in code against the evidence packet it was actually given. Anything that does not resolve is reported separately as unverified rather than being passed off as a source. Numbers in the answer are checked the same way.
  • Evidence-driven edges. No relationship (edge) exists without evidence. Every edge is bound to a source chunk or a trace query reference.
  • Dual knowledge layer — Designed vs. Observed. Relationships extracted from design documents (CALLS, PUBLISHES) live alongside relationships observed in real traces (CALLS_OBSERVED, with call counts, error rates, latency).
  • Design-Observation diff. Nexus flags doc_only (documented but never observed — dead docs), observed_only (observed but undocumented — shadow dependencies), and conflict (both present but mismatched).
  • Default-deny security. PII/secrets (Korean SSN, card numbers, AWS keys, JWTs) are quarantined on detection and never indexed; every query is filtered by classification (PUBLIC < INTERNAL < RESTRICTED).
  • Provenance tier. A chunk written by a person and a chunk a model read out of a screenshot are not the same kind of evidence. Machine-read text is labelled as such, and the label travels all the way into the prompt, the API response, and the web UI — so an answer never quietly launders an extraction into an authored policy.
  • Declared index generations. The embedding model, its dimension, and the vector column move together as one generation, declared append-only in the database. Ingestion is refused before a single document is collected if the running configuration does not match a declared generation — the failure mode this closes is a documented command silently writing into a column nothing searches. The repository default is nomic-embed-text (768-d); a KURE-v1 (1024-d) generation is available and selected per deployment.
  • Staleness is shown, not enforced. Answers carry a per-snippet age warning against a per-type TTL. It is a label for the reader; it deliberately does not re-rank or exclude anything.
  • Honest absence. If nothing can be cited, Nexus does not call the model at all — it returns a fixed statement that it has no evidence, and says so in the response payload.
  • Index, not storage. Originals stay in Git and in Tempo. Nexus stores only derived data — chunks, embeddings, graph edges.

Quickstart

Nexus runs as a Docker Compose stack. By default only the core containers start (PostgreSQL + Ollama + the FastAPI app); the OTel observability pipeline is opt-in. The task one-liners below wrap the underlying docker compose commands — each step shows the raw equivalent too.

Prerequisites

  • Docker Desktop
  • (Optional) go-task for the task shortcuts
  • (Optional) an Anthropic API key, for LLM grounded-answer generation

1. Clone & configure

Terminal window
git clone https://github.com/LivingLikeKrillin/khala.git
cd khala
cp nexus/.env.example nexus/.env
# (optional) set ANTHROPIC_API_KEY in nexus/.env for LLM answer generation

2. Start — one line

Terminal window
task up

task up starts the containers (waiting for health), applies DB migrations, and pulls the embedding model automatically. No Task? Run those three yourself from nexus/:

Terminal window
docker compose up -d --wait # containers + model auto-pull
docker compose exec -T nexus-app python -m scripts.migrate # ← skip this and the source console / document management break

Starts PostgreSQL 16 + pgvector (5432), Ollama (11434), and the FastAPI app on 8000. The OTel collector + Tempo are opt-in — add them only for trace aggregation: docker compose --profile observability up -d.

Open http://localhost:8000/ and ask in the chat — or use the CLI:

Terminal window
docker compose exec nexus-app nexus ingest ./docs
docker compose exec nexus-app nexus query "payment service dependencies"

The Web UI is served directly from FastAPI at http://localhost:8000/ — no build step. New to it? See Using the Nexus web app.

Update / stop

Terminal window
git pull && task update # rebuild image, restart, apply DB migrations
task down # stop (or: docker compose down)

How-to

Get a grounded answer (with evidence)

Terminal window
curl -X POST http://localhost:8000/search/answer \
-H "Content-Type: application/json" \
-d '{"query": "which services does the payment service call?", "clearance": "INTERNAL"}'

The response includes evidence snippets with source URIs and provenance. Use /search/answer/stream for SSE streaming in the chat UI.

Explore the knowledge graph

Terminal window
docker compose exec nexus-app nexus graph payment-service # 1-hop
docker compose exec nexus-app nexus graph payment-service -h 2 # 2-hop

Or via the API: GET /graph/{entity} resolves by name or rid.

Find design-vs-observation drift

Terminal window
docker compose exec nexus-app nexus otel-aggregate # roll traces up into CALLS_OBSERVED
docker compose exec nexus-app nexus diff # report doc_only / observed_only / conflict

The same report is available at GET /diff.

Reference

  • Source repo README: github.com/LivingLikeKrillin/khala (README.md)
  • API contract, pipeline, MCP server, Slack bot, and UI integration docs live under that repo’s docs/ (API_CONTRACT.md, PIPELINE_SPEC.md, MCP_SERVER.md, SLACK_BOT.md, UI_INTEGRATION.md).
  • MCP server exposes nine tools — nexus_search, nexus_answer, nexus_graph, nexus_suggest, nexus_diff, nexus_status, nexus_supersede, archon_claim_value, archon_grade_authority — via python -m nexus.mcp. Set NEXUS_MCP_TOKEN, or every call returns 401 (auth defaults to enforced).