The Zettelkasten philosophy in ZettelForge¶
ZettelForge borrows five ideas from Niklas Luhmann's Zettelkasten: small notes, meaningful links, emergent structure, stable addresses, and preservation of old thinking. It translates those ideas into memory notes, a SQLite knowledge graph, and retrieval that combines vector and graph signals.
The analogy is a design lens, not a claim that the software reproduces Luhmann's method. ZettelForge 2.8.0 implements some parts directly and leaves other parts to your ingestion and review policy.
Prerequisites: None. Use the Memory Manager API for exact operations and the knowledge graph edge schema for stored edge shapes.
The historical model¶
Johannes F.K. Schmidt's study, Niklas Luhmann's Card Index: The Fabrication of Serendipity, describes about 90,000 handwritten cards across two collections. Each card received a fixed address. Numbered cross-references connected cards that often sat far apart in the physical collection, while a keyword index supplied entry points.
The important property was not the box. It was the network. A note gained new meaning when a later note linked it into another line of thought.
Five ideas in the released system¶
1. You choose the note boundary¶
A MemoryNote stores one raw content string with semantic, embedding, link, and
lifecycle fields. The direct remember() path keeps the input you give it as
one note. remember_chunked() splits longer text on sentence boundaries, while
remember_with_extraction() asks an LLM to rank candidate facts and processes
each retained fact separately.
This makes atomicity a choice rather than an enforced invariant. A concise fact gives retrieval a precise target. A whole report preserves context but gives each query a larger, less specific unit to rank. Choose the boundary that matches the questions you expect to ask.
2. Links carry direction and provenance¶
Every recognized entity can become a graph node. A MENTIONED_IN edge connects
the entity to the note that contains it. When an actor and another CTI entity
occur in the same note, the fast ingestion path can also write relationships
such as USES_TOOL, EXPLOITS_CVE, TARGETS_ASSET, and USES_TECHNIQUE.
The relationship label and direction make these edges more useful than a flat tag list. Provenance can connect an edge to its source note, so you can inspect the text behind a graph route.
Relationship inference is in progress
The fast path infers these CTI edges from entity co-occurrence. It does not
understand whether the sentence affirms or denies the relationship. In the
verified v2.8.0 probe, the text "Sandworm does not use Cobalt Strike"
still produced Sandworm --USES_TOOL--> Cobalt Strike. Treat heuristic
edges as retrieval leads and validate them against the source note.
3. Structure emerges during retrieval¶
recall() begins with vector similarity and extracts entities from your query.
It follows outgoing graph edges for at most two hops, scores nearer notes more
highly, and blends graph and vector scores with weights selected from the query
intent. A note found by both signals receives both contributions.
This gives you two paths into the same collection. Similar wording can find a note even when the graph has no route. A named actor, tool, or CVE can open a route to notes that use different wording.
The graph remains directional. A route stored only in the reverse direction is not traversed by this retrieval stage. ZettelForge also drops high-fanout query entities from graph retrieval so a name attached to too many notes does not overwhelm the useful signal.
4. Addresses are stable inside one store¶
On its first SQLite write, a note receives an ID shaped like
note_YYYYMMDD_HHMMSS_xxxx. Rewriting the note preserves that ID.
Graph entities use a different identity. SQLite enforces one node for each
exact (entity_type, entity_value) pair and reuses that node across notes in the
same store. The node's internal handle is a random node_ ID.
These are local storage identities, not global content identifiers. Capitalization, alias resolution, or a different entity type can produce a different composite key. Deleting and recreating an entity can also produce a new internal handle. Use the typed value as the durable meaning and the internal ID as a store-local address.
5. Supersession preserves explicit history¶
The verified supersession path keeps both notes. mark_note_superseded() points
the old note's superseded_by field to the new note, adds the old ID to the new
note's supersedes list, and writes a SUPERSEDES edge from the new note to the
old one. recall() excludes the old note by default without deleting it.
The two-phase update path uses this mechanism when an extracted fact updates or corrects an existing note. You keep the prior assertion for audit while current recall favors the replacement.
Automatic evolution is in progress
Direct ingestion can automatically supersede an older note after one shared entity, even when the two notes express different facts. The background neighbor-evolution path also fails to persist on the released SQLite backend because it calls a rewrite method that backend does not expose. Use explicit supersession after review as the reliable v2.8.0 path.
Where the analogy stops¶
Luhmann chose every insertion point and cross-reference. ZettelForge automates candidate extraction, entity recognition, graph construction, and ranking. Automation changes the failure mode: it can scale beyond a handwritten index, but it can also create a confident-looking link from shallow co-occurrence.
Luhmann navigated a fixed-address paper network. ZettelForge adds vector similarity, intent-weighted score fusion, and typed entities. That makes rough language a useful entry point, but the ranking is an information-retrieval result rather than an explanation of why a fact is true.
The practical rule follows from both systems: preserve the source, keep addresses stable, and treat links as routes back to evidence. Structure helps you find a claim; the claim's source determines whether you trust it.
This page describes the self-hosted ZettelForge model. ThreatRecall.ai is the separate hosted SaaS and is outside this explanation's scope.