Skip to content

Promotion & the Knowledge Graph

Promotion is where Athena stops remembering conversations and starts knowing facts. On a 30-minute ticker, the promoter scans active chains, recomputes their heat, and for every chain at or above the promotion threshold, extracts structured knowledge into the athena_ltm graph in ArangoDB.

Triple extraction

The chain's summary is sent to the LLM with a strict JSON schema (structured outputs: the model cannot return anything malformed; schema violations increment memos_extractor_schema_failures_total and abort that chain's promotion).

The schema enforces the ontology:

Nodes: exactly four labels:

Label Holds Examples
Identities Anything with agency or persona sangalo, prescott_data, athena
Tools Concrete software, hardware, languages go, arangodb, docker
Projects Scoped initiatives and repos nexus_protocol
Concepts Abstract ideas and methodologies spaced_repetition, authentication

Node IDs are lowercase snake_case, enforced by the schema.

Edges: a whitelisted relation vocabulary:

Relation Meaning
USES Actively utilizing a tool
WORKS_ON Building or developing something
BUILT_FOR_CLIENT Developing on behalf of another identity
STRUGGLES_WITH Difficulty with a tool/concept/project
EXHIBITS Displays a personality trait or behavior
EXPRESSED_INTEREST Curiosity or desire to learn
RELATES_TO Generic fallback; must carry context_nuance

Every edge carries context_nuance (a free-text qualifier) and a confidence in \([0,1]\) assigned by the LLM. Relations outside the whitelist are auto-corrected to RELATES_TO with the original intent preserved in the nuance.

Idempotent writes: the UPSERT contract

Re-observing a fact must strengthen it, not duplicate it. Nodes UPSERT on _key:

UPSERT { _key: @key }
INSERT { _key: @key, name: @name, created_at: @now, last_seen: @now }
UPDATE { last_seen: @now }
IN Tools   // or Identities / Concepts / Projects

Edges UPSERT on the (_from, _to, relation) triple:

UPSERT { _from: @from, _to: @to, relation: @relation }
INSERT { ..., confidence: @confidence, weight: 1, heat_score: @heat, ... }
UPDATE {
  confidence: (OLD.confidence + @confidence) / 2,   // running average
  weight: OLD.weight + 1,                           // frequency counter
  context_nuance: @context_nuance,                  // overwritten
  heat_score: @heat, last_seen: @now
}
IN MemoryEdges

The semantics per field:

  • weight: how many times this fact has been independently observed. The primary retrieval sort key.
  • confidence: a simple running average of old and new. (Deliberately not an EMA; an EMA variant was reverted after skewing production data.)
  • context_nuance: latest observation wins.
  • heat_score: snapshot of the source chain's heat at promotion time.

Retrieval

SearchMemory enriches its results by traversing the graph from entities matched in the query:

FOR v, e IN 1..2 ANY @startNode MemoryEdges
  FILTER e.confidence >= 0.5
  SORT e.weight DESC, e.heat_score DESC
  LIMIT 50
  RETURN DISTINCT { node: v, edge: e }

Three properties worth internalizing: low-confidence edges (< 0.5, hardcoded) are invisible to retrieval even though they exist in the graph; frequency beats recency (weight sorts before heat_score); and traversal depth is 1–2 hops, so Athena surfaces neighborhoods, not transitive closures.

Scope and safety

Graph nodes and edges are tenant/user-scoped like everything else (Sessions & Identity). Promotion is idempotent and crash-safe: a re-promoted chain just re-UPSERTs. The graph is never written synchronously from an API call; only the promoter and the analytics job touch it.

athena_ltm only

All graph writes target the athena_ltm database. If your ArangoDB instance hosts databases for other applications, Athena will never touch them; equally, nothing else should write into athena_ltm.