STIX-aligned extraction and graph reference¶
ZettelForge turns common CTI indicators and names into lowercase entity labels, then connects co-occurring entities in its local knowledge graph. Use this reference when you call an entity-recall method, inspect note metadata, or write a relationship directly.
Prerequisites¶
- ZettelForge 2.8.0.
- A
MemoryManagerinstance when you use the recall or relationship methods. - A working LLM provider only when you need the conversational enrichment labels marked in progress below.
Scope and naming¶
This page covers the ZettelForge open-source extraction index, note metadata,
and the SQLite knowledge-graph path used by MemoryManager. It does not describe
the hosted ThreatRecall.ai graph schema.
ZettelForge 2.8.0 has two related vocabularies. Keep their spelling separate:
- The extraction index and
MemoryManageruse lowercase labels such asintrusion_setand uppercase graph relationships such asUSES_TOOL. - The typed ontology validator uses PascalCase entities such as
IntrusionSetand lowercase relationships such asuses_tool. It is a separate validation surface; do not pass its PascalCase names to the recall methods on this page.
Extraction-index entity labels¶
remember() runs the deterministic regex extractor before it writes entity
mappings. Regex matches are lowercased, and spaces become hyphens. Match order is
not stable because the extractor deduplicates with sets.
CTI labels¶
| Label | Example output | Deterministic match |
|---|---|---|
cve |
cve-2024-3094 |
CVE- + four digits + at least four digits |
intrusion_set |
apt28, unc4990, ta505, fin7 |
APT, UNC, TA, FIN, or TEMP designation plus digits |
actor |
lazarus, sandworm, volt-typhoon |
One of the three built-in actor names |
tool |
cobalt-strike, metasploit, mimikatz, bloodhound, dropbear, empire, covenant |
One of the seven built-in tool names |
campaign |
operation-aurora |
operation followed by one word |
attack_pattern |
t1059, t1059.001 |
ATT&CK technique or sub-technique identifier |
Observable labels¶
| Label | Match |
|---|---|
ipv4 |
IPv4 address with each octet constrained to 0–255 |
domain |
Domain name with one of the suffixes registered in the extractor |
url |
Text beginning with http:// or https:// up to a delimiter |
md5 |
32 hexadecimal characters |
sha1 |
40 hexadecimal characters |
sha256 |
64 hexadecimal characters |
email |
Address-shaped text with a dotted suffix |
The hash extractor rejects candidates that appear in assignment, Git commit, or fenced-code contexts. The URL regex does not strip terminal periods or commas; surround a URL with a delimiter or normalize the captured value before you use it as an IOC.
Conversational labels¶
| Label | Deterministic path | LLM enrichment path |
|---|---|---|
person |
A name of 3–16 letters at the start of a Name: dialogue line, minus the built-in stop list |
Broader person names |
location |
One of 43 built-in city or place names | Broader locations |
organization |
None | Named organizations |
event |
None | Named events |
activity |
None | Described activities |
temporal |
None | Time expressions |
Conversational LLM enrichment is in progress
No Ollama service was listening on 127.0.0.1:11434 during this run, so the
LLM enrichment path was not verified. When generation fails, the extractor
catches the error and returns empty lists for all six conversational labels.
The deterministic person and location matches above were executed.
Entity recall methods¶
| Method | ZettelForge 2.8.0 signature | Lookup behavior |
|---|---|---|
recall_entity |
(entity_type: str, entity_value: str, k: int = 5) -> list[MemoryNote] |
Looks up one lowercase extraction-index label. It lowercases the value. |
recall_actor |
(actor_name: str, k: int = 5) -> list[MemoryNote] |
Searches actor, threat_actor, then intrusion_set, and removes duplicate notes. |
recall_technique |
(technique_id: str, k: int = 25) -> list[MemoryNote] |
Searches attack_pattern; the wrapper uppercases the input before the shared lookup lowercases it. |
recall_entity() does not validate entity_type. An unknown label returns no
mapped notes unless a caller has written mappings under that label.
Note metadata fields¶
Every MemoryNote has a metadata object. These are the STIX-adjacent fields
and related confidence fields in ZettelForge 2.8.0.
| Field | Type | Default | Meaning |
|---|---|---|---|
stix_confidence |
int |
-1 |
STIX confidence from 0–100; -1 means unset. The model does not enforce the range. |
tier |
str |
"B" |
Epistemic tier. A is authoritative, B operational, and C support. The model does not restrict other strings. |
tlp |
str |
"" |
Stored TLP text. ZettelForge 2.8.0 does not normalize or validate this field in Metadata. |
confidence |
float |
1.0 |
Internal confidence. increment_evolution() caps it at 0.95. |
vuln |
VulnerabilityMeta | None |
None |
Structured vulnerability data attached by an import or sync path. |
VulnerabilityMeta¶
| Field | Type | Default |
|---|---|---|
cvss_v3_score |
float | None |
None |
cvss_v3_vector |
str | None |
None |
epss_score |
float | None |
None |
epss_percentile |
float | None |
None |
cisa_kev |
bool |
False |
The model describes the numeric ranges in comments but does not enforce bounds at construction time.
Built-in SQLite graph relationships¶
remember() creates a note node, MENTIONED_IN edges, and heuristic edges for
co-occurring entities. Heuristic edges store first_observed and the note's
internal confidence as properties.
| Relationship | From | To | Writer |
|---|---|---|---|
MENTIONED_IN |
Any extracted entity | note |
remember() |
USES_TOOL |
actor, threat_actor, intrusion_set |
tool |
remember() |
EXPLOITS_CVE |
Actor label or tool |
cve |
remember() |
TARGETS_ASSET |
Actor label or tool |
asset |
remember() when another path supplies asset entities |
CONDUCTS_CAMPAIGN |
Actor label | campaign |
remember() |
USES_TECHNIQUE |
Actor label | attack_pattern |
remember() |
IMPLEMENTS |
malware |
attack_pattern |
remember() when another path supplies malware entities |
AFFILIATED_WITH |
person |
organization |
LLM entity enrichment |
ATTENDED |
person |
event |
LLM entity enrichment |
LOCATED_AT |
person |
location |
LLM entity enrichment |
PARTICIPATES_IN |
person |
activity |
LLM entity enrichment |
HELD_AT |
event |
location |
LLM entity enrichment |
ORGANIZED_BY |
event |
organization |
LLM entity enrichment |
OCCURRED_ON |
event |
temporal |
LLM entity enrichment |
BASED_IN |
organization |
location |
LLM entity enrichment |
SUPERSEDES |
New note |
Old note |
mark_note_superseded() |
The regex extractor does not emit asset or malware. Their rows activate only
when an import, sync, or enrichment path supplies those entity lists. The eight
conversational relationships remain in progress because this run did not
exercise LLM enrichment.
ingest_relationship()¶
The method accepts source and target labels, a relationship string, and optional
properties. It returns None. The method does not validate the labels against
the typed ontology.
mm.ingest_relationship(
from_type="actor",
from_value="apt28",
to_type="tool",
to_value="mimikatz",
relationship="USES_TOOL",
properties={"confidence": 0.9},
)
The SQLite edge key is the source node, target node, and relationship. Repeating the call updates the existing edge properties instead of adding another edge. The method also writes the same edge to the legacy JSONL knowledge graph for backward compatibility.
Typed CTI ontology vocabulary¶
The separate OntologyValidator exposes these core CTI names in 2.8.0:
- Entity types:
IntrusionSet,ThreatActor,Vulnerability,Malware,Campaign,Incident, andAttackPattern. - Relationship types:
attributed_to,uses,uses_technique,uses_tool,exploits,implements, andtargets.
Use this PascalCase/snake_case vocabulary only with the ontology validation
surface. Use the lowercase/uppercase vocabulary in the earlier tables with
MemoryManager.