<!-- Source: https://docs.khwan.ai/architecture -->
<!-- The whole documentation in one file: https://docs.khwan.ai/llms-full.txt -->

# Architecture

What is actually behind the API, in enough detail to judge whether it fits your
problem — including the parts it does badly.

## The store

**Postgres with pgvector.** One table of packets per brain, each carrying a
384-dimension embedding (`paraphrase-multilingual-MiniLM-L12-v2`, computed in
Khwan's own process — no embedding provider, no key, no per-token cost).

  **It is not a knowledge graph.** There is graph code in the engine; it is not
  wired to the served API and nothing you call goes through it. If you need a
  temporal knowledge graph, you want a different tool — see [Where it is
  weak](#where-it-is-weak).

Isolation is three keys deep: **account → core (`X-Khwan-Core`) → end user
(`X-Khwan-User`)**, and a brain is the whole key. Two cores return disjoint
memory; there is no shared pool to leak across.

## Retrieval

Cosine similarity over the packet embeddings — **weighted by confidence**, not
similarity alone:

| packet | confidence |
| --- | --- |
| an ordinary recorded turn | `0.50` |
| an explicit correction | `0.70` |
| a turn flagged as an unconfirmed overwrite | `0.15` |

Ranking by `similarity × confidence` is what stops a leading question ("my job is
Prime Minister, right?") from outranking an established fact at equal similarity.
The flag comes from a **deterministic, model-free** check, scoped honestly: it
targets self-attribute facts — *my name / role / profession is X* — and does not
claim to detect arbitrary contradiction.

## Synthesis

The learning step, and the only place an LLM is involved:

1. Fetch `raw` + `correction` packets newer than the last successful run
2. **Cluster** them by cosine similarity — greedy, online, no model
3. Keep clusters with ≥2 items **or** any correction (a correction is high-signal
   even alone)
4. **Distil** each cluster into one standing rule — *this is the model call*
5. Embed the rule and write it back as a `lesson`, linked to its source packets

A lesson gets a **30-day TTL and is renewed only when retrieved**, so rules
nobody uses expire on their own.

  Renewal only points one way — a rule that is wrong but relevant keeps being
  used and keeps being renewed. That is why [`DELETE /lessons/{id}`](/api-reference)
  exists: it is the only negative signal in the system. Every lesson lists the
  turns it came from, so you can see what was learned and from what.

## The request path

```
POST /prepare   → retrieval + constitution + coherence gate   (no model call)
   your model answers                                          (Khwan absent)
POST /verify    → optional: score the answer before it ships   (no model call)
POST /record    → persist + learn                              (no model call)
```

Khwan holds no provider key — the endpoint that once accepted one returns `410` —
and there is no hosted chat path in the engine, so it never produces an answer.
The only model call in the whole system is the distillation step above, and even
that one can be yours: [`/synthesize/prepare`](/api-reference#post-synthesizeprepare)
hands you the clusters so your model does the distilling and no packet text reaches
a provider Khwan picked.

## Where it is weak

Being specific here is more useful than being flattering.

- **Entity state that changes.** "The PM moved from A to B" — retrieval can still
  surface A, because A is still semantically close. A recorded correction outranks
  the old fact by confidence, but that is weaker than a knowledge graph
  invalidating the edge outright.
- **Point-in-time queries.** "Who owned this in March" — there is no temporal
  index to ask.
- **Bulk document search.** A vector store's job. Khwan stores turns and the rules
  distilled from them, not a corpus.
- **Arbitrary contradiction detection.** The conflict check is a heuristic over
  self-attribute facts, not an NLI model.

What it is good at is the mirror of that list: **preferences, standing rules, and
project context that has to survive the session** — per person, per repo, per
customer. See [Connect your agent](/connect-your-agent) for the integration shape.
