Knowledge Graph
The Wisdom Tree in depth — atoms, voice types, evidence chains, bond types, and the conflict detection system that keeps knowledge accurate automatically.
What Is an Atom?
An atom is the smallest unit of knowledge that can stand alone. Not a paragraph, not a document — a single, falsifiable claim. The discipline of atomicity is what makes knowledge searchable, linkable, and worth maintaining.
Good atoms:
- Make exactly one claim: "API p99 latency is 180ms at 1,000 RPS"
- Are self-contained — readable without surrounding context
- Can be confirmed or refuted by evidence
- Have the right type (DATA, LEARNING, DECISION, or PRINCIPLE)
Bad atoms:
- Make multiple claims in one statement
- Contain vague language ("sometimes", "might", "could be better")
- Duplicate another atom already in the graph
The Four Atom Types
Each type encodes the atom's epistemic role — how certain it is and how it was derived. The types form a derivation chain from raw observation to distilled wisdom:
flowchart LR D["DATA<br/>Raw measurement<br/>or observation"] L["LEARNING<br/>Pattern synthesized<br/>from multiple data points"] DE["DECISION<br/>Committed choice<br/>with rationale"] P["PRINCIPLE<br/>Guiding rule derived<br/>from repeated decisions"] D -->|DERIVES_FROM| L -->|DERIVES_FROM| DE -->|DERIVES_FROM| P
| Type | What it captures | Example |
|---|---|---|
| DATA | Measurements, observations, raw facts | "NPS dropped 12 points in Q3" |
| LEARNING | Insights synthesized from multiple data points | "Enterprise users churn when onboarding exceeds 2 weeks" |
| DECISION | Committed choices with documented rationale | "We will sunset the free tier in Q2 — unit economics don't support it at scale" |
| PRINCIPLE | Guiding beliefs that apply to future choices | "Always optimize for time-to-value over feature breadth" |
Voice Types
Every atom has a voiceType that encodes the epistemic authority behind it — who
said it, how it was derived, and how much weight it should carry in search and conflict
detection. Voice type is not optional. It is the signal that lets Momental distinguish a
measurement from an opinion from a committed decision.
| Voice type | Meaning | Use when |
|---|---|---|
OBSERVED | Directly witnessed or measured — highest epistemic authority | Metrics, A/B test results, incident observations, code behaviour confirmed by running it |
BELIEVED | Team's current working belief, not yet confirmed by data | Hypotheses, working assumptions, things the team acts on but hasn't proven |
DECIDED | A committed choice the team has made and will act on | Architecture decisions, product strategy choices, policy commitments |
RECEIVED | Heard from an external source (customer, partner, analyst) | Customer interview quotes, analyst reports, partner feedback — cited with source |
PROPOSED | A suggestion or recommendation that has not been decided yet | Options under evaluation, recommendations awaiting approval, ideas in flight |
Conflict detection accounts for voice type. An OBSERVED atom that contradicts a
BELIEVED atom is ranked as a higher-priority conflict than two BELIEVED
atoms that disagree — because observation supersedes belief.
// A received customer insight, cited with source
await node_create({
statement: "Enterprise users churn when onboarding exceeds 2 weeks",
nodeType: "LEARNING",
voiceType: "RECEIVED", // from customer interviews
voiceSource: "CUSTOMER",
voiceAuthority: "INFORMED",
sourceQuote: "Cohort analysis: 94% retention when onboarding <= 14 days, 61% otherwise",
status: "ACTIVE",
authorEntityName: "Claude Code",
tags: ["onboarding", "churn", "enterprise"]
});
// A decision the team has committed to
await node_create({
statement: "We use Redis for session storage — chosen for TTL support over PostgreSQL",
nodeType: "DECISION",
voiceType: "DECIDED",
status: "ACTIVE",
authorEntityName: "Engineering Team"
});
Strategy Node Hierarchy
Atoms live in the Wisdom Tree. Your goals and work live in the Strategy Tree. The two are connected — atoms link to strategy nodes to explain why decisions were made and what evidence supports each goal.
The Strategy Tree has a strict six-level hierarchy. Every node must have a parent of the correct type:
flowchart TD V["VISION<br/>Where we're going<br/>(one per workspace)"] M["MISSION<br/>How we get there<br/>(one per workspace)"] O["OBJECTIVE<br/>Quarterly goal<br/>(3-5 per cycle)"] KR["KEY_RESULT<br/>Measurable outcome<br/>(2-4 per objective)"] S["SOLUTION<br/>How we'll achieve the KR<br/>(features, bets, initiatives)"] E["EPIC<br/>Group of related tasks"] T["TASK<br/>Atomic unit of work"] V --> M --> O --> KR --> S --> E --> T
| Node type | Purpose | Example |
|---|---|---|
VISION | Long-term aspiration, one per workspace | "Become the operating system of the autonomous company" |
MISSION | How we pursue the vision, one per workspace | "Provide Momental for early-stage startups" |
OBJECTIVE | Quarterly, ambitious, qualitative goal | "Grow the developer audience significantly" |
KEY_RESULT | Measurable outcome that confirms the objective is met | "10,000 daily visitors through organic search" |
SOLUTION | Strategic bet or initiative to achieve the KR | "Publish world-class technical documentation" |
EPIC | Group of related implementation tasks | "Write Agent Catalog and MCP Tools Reference pages" |
TASK | Discrete, assignable unit of work | "Create /agents/sirius.astro with full capabilities doc" |
When you create a strategy node, pass the correct parentId. Momental will reject
a TASK placed directly under an OBJECTIVE — you must create a SOLUTION and EPIC first.
// Full hierarchy: OBJECTIVE → KEY_RESULT → SOLUTION → EPIC → TASK
const keyResult = await node_create({
nodeType: "KEY_RESULT",
statement: "10,000 daily visitors through organic search",
parentId: objectiveId // KEY_RESULT is a child of OBJECTIVE
});
const solution = await node_create({
nodeType: "SOLUTION",
statement: "Publish world-class technical documentation",
parentId: keyResult.id // SOLUTION is a child of KEY_RESULT
});
const epic = await node_create({
nodeType: "EPIC",
statement: "Write the Agent Catalog and MCP Tools Reference",
parentId: solution.id // EPIC is a child of SOLUTION
});
const newTask = await task({
action: "create",
statement: "Write the Agent Catalog page",
parentId: epic.id, // TASK is a child of EPIC
acceptanceCriteria: "All 15 agents documented with slugs and task types"
});
Bond Types — Connecting Atoms
Bonds are typed edges between atoms (and between atoms and strategy nodes). They encode the relationship's meaning — not just "these things are related" but how they relate. Bonds are what make the knowledge graph queryable rather than just searchable.
| Bond type | Meaning | Example |
|---|---|---|
DERIVES_FROM | This atom was synthesised or inferred from the linked atom | A LEARNING that derives from 3 DATA atoms; a DECISION that derives from a LEARNING |
SUPPORTS | This atom provides evidence for the linked atom | A customer quote that supports a pricing DECISION |
CONTRADICTS | This atom presents evidence or reasoning against the linked atom | New A/B result that contradicts an existing BELIEVED assumption |
SUPERSEDES | This atom replaces the linked atom as the current truth | Updated latency measurement that supersedes an older one |
LINKED_TO | General association — related but no specific epistemic relationship | An atom linked to the strategy node it informed |
// Create a derivation chain
const dataAtom = await node_create({
nodeType: "DATA",
statement: "Checkout abandonment rate is 67% — GA4 Q3 2026",
voiceType: "OBSERVED"
});
const learningAtom = await node_create({
nodeType: "LEARNING",
statement: "Users abandon when shipping costs appear late in the flow",
voiceType: "BELIEVED"
});
// Bond: the LEARNING derives from the DATA
await node_link({
action: "link",
fromNodeId: learningAtom.id,
toNodeId: dataAtom.id,
linkType: "DERIVES_FROM"
});
// Bond: link the learning to the strategy node it informed
await node_link({
action: "link",
fromNodeId: learningAtom.id,
toNodeId: checkoutEpicId,
linkType: "LINKED_TO"
});
Evidence Chains
The most valuable knowledge graphs have evidence chains: a DECISION linked back to the LEARNING that justifies it, which links back to the DATA that prompted the insight. When a decision exists without documented evidence, Momental flags it as a gap worth filling.
flowchart TD D1["DATA: Checkout abandonment 67%"] D2["DATA: 84% of abandoners cited surprise shipping cost"] L["LEARNING: Users abandon when shipping costs appear late"] DE["DECISION: Show estimated shipping cost before payment step"] P["PRINCIPLE: No surprise costs - ever"] D1 --> L D2 --> L L --> DE DE --> P
Every node in this chain is independently searchable. An agent working on the checkout flow can search for DECISIONS about checkout and find this, along with the evidence trail that justifies it — without reading any documents.
How Agents Read and Write the Graph
Agents interact with the knowledge graph using MCP tools. The pattern is the same whether the agent is a Momental built-in agent or your own Claude Code instance:
Reading
recall({ query })— semantic search over your personal agent memories (learnings from past sessions)search({ query, scope })— unified search across atoms, strategy, products, people, and codenode_read({ nodeId })— read any node by ID, including its relationshipsbrowse({ tree })— traverse a full tree (strategy, product, people, external)ask({ question })— free-form Q&A against the full knowledge graph
Writing
node_create({ nodeType, statement, voiceType, status: "ACTIVE" })— create an atom or strategy nodecapture({ statement, source })— intelligent shortcut: auto-classifies type and auto-links to related atomsnode_link({ fromNodeId, toNodeId, linkType })— create a bond between two nodesremember({ topic, content })— save a private learning to your personal agent memory (not visible to other agents)
status: "ACTIVE" on atoms you create.DRAFT atoms are invisible to search and to other agents.
An atom in DRAFT is functionally not in the graph.
The agent knowledge workflow
// 1. Session start: recall personal memory on the task domain
const memory = await recall({ query: "checkout flow decisions" });
// 2. Search the shared knowledge graph
const existing = await search({
query: "checkout abandonment reasons",
scope: "atoms",
nodeType: "LEARNING"
});
// 3. Do the work, then save findings immediately
await node_create({
nodeType: "DATA",
statement: "Shipping cost surprise caused 84% of checkout abandonment in July",
voiceType: "OBSERVED",
status: "ACTIVE",
authorEntityName: "Claude Code",
tags: ["checkout", "shipping", "abandonment"]
});
// 4. Save personal memory for future sessions
await remember({
topic: "checkout: shipping cost surprise",
content: "Key finding: 84% of abandonments traced to late shipping cost reveal. GA4 Q3 2026."
});
// 5. Check for conflicts your new atom may have triggered
await health({ action: "conflicts" });
Knowledge Stays Current
Knowledge ages. Momental keeps the graph current automatically — recent observations rank higher than older ones in search results. Old decisions get flagged for review when the evidence they were based on has been updated. You don't have to maintain freshness manually.
Conflict Detection
Every time a new atom is added, Momental automatically checks it against existing knowledge for contradictions. If two atoms say opposing things — or if a new observation invalidates an older decision — the conflict is flagged and routed to your team for review.
High-confidence conflicts are surfaced immediately. Ambiguous cases are analyzed further before surfacing, so you don't get buried in noise.
To manage conflicts, see Conflicts & Gaps. To understand how Momental monitors for these signals continuously, see Autonomy & agents.
Gap Detection
Momental also scans for missing knowledge — areas where reasoning should exist but doesn't. Examples: a decision without documented evidence behind it, topics with asymmetric coverage, or knowledge that implies a policy violation.
Detected gaps appear in health({ action: "gaps" }) and can be assigned to agents
to fill. You can trigger a scan on demand:
// See current health gaps
await health({ action: "gaps" });
// Trigger a fresh conflict scan
await health({ action: "trigger_scan" });
// Full graph audit
await health({ action: "audit" });