The Causal Knowledge Graph: how cachly learns from cause-and-effect
Most AI memory systems store facts. cachly stores causation — what led to what, with confidence scores.
The difference between facts and causes
“Use 127.0.0.1 instead of localhost in the ClickHouse healthcheck.”
Tells you what to do. Not when, not why.
Using localhost causes restart loops when IPv6 is disabled, because localhost resolves to ::1 which ClickHouse isn't bound to.
Tells you why — and exactly when this fix applies.
The distinction matters most at the moment you are least able to think clearly: something is broken, and a tool is offering you a suggestion. A fact gives you a thing to try. A cause gives you a condition to check first. If IPv6 is enabled on this host, the ClickHouse fix above is simply irrelevant, and applying it anyway costs you the next twenty minutes chasing a change that could never have helped.
What one causal edge actually contains
Every call to learn_from_attempts() creates or strengthens a causal edge:
learn_from_attempts( topic = "fix:clickhouse-healthcheck", outcome = "success", what_worked = "Use 127.0.0.1 not localhost", what_failed = "localhost → ::1 on IPv6-disabled servers", severity = "critical", tags = ["docker", "clickhouse", "ipv6"], )
Four parts, and none of them is optional.
Drop the condition and you have advice that fires everywhere, including on the machines where it cannot possibly apply. Drop the mechanism and nobody can tell whether a similar-looking failure is actually the same failure.
Drop the observation count and every claim carries the same weight, whether it was seen once or seven times. That last one is the quiet killer, because a store without counts still looks authoritative.
Bayesian confidence updates
Each edge has a confidence score that updates with each observation:
outcome: success→ confidence increases toward 1.0outcome: failure(same approach) → confidence decreasesoutcome: partial→ small upward adjustmentseverity: critical→ observations weighted more heavily
A fix seen 10 times with outcome: success has near-certainty. A fix tried once with outcome: partial stays marked uncertain. The Brain gets better with use.
Reading a confidence score honestly
Two numbers travel together, and the smaller one is usually the more useful: the score, and the observation count it rests on. An edge at 0.95 built from a single success is a guess wearing a lab coat. An edge at 0.78 built from nine observations across four machines is worth acting on. When the two disagree, trust the count.
This is also why silence decays a score rather than preserving it.
A lesson that nothing has recalled in weeks has not been confirmed by that silence. It has simply gone unchecked while the world moved on. The package manager changed a default. The base image shipped a new kernel. Someone rotated a key.
Decay does not claim the lesson is wrong. It withdraws the claim that the lesson is still known to be right — which is a different and much more defensible statement.
Inspecting the graph yourself
None of this is meant to be taken on faith. Two tools open the graph up directly: ckg_inspect shows the edges around a concept, and trace_dependency walks the chain between two of them.
It is worth running these on your own instance early. A causal graph is only as good as what people wrote into it, and looking at the edges is the fastest way to find out whether your team records conditions or just records fixes.
When the ground moves, the lessons on it should move too
A lesson can declare what it stands on with depends_on — a runtime version, a service that must be up, a tunnel that must be active. When one of those prerequisites is marked stale, every lesson that named it is flagged for review rather than left quietly trusted.
The failure this prevents is a quiet one. Nothing turns red.
The recall still returns a fix. It still carries a high score. It is still phrased with total confidence — and it has been wrong since the day the runtime was upgraded. Nobody finds out until the fix is applied to something that matters.
A flag that says “check this” is a small thing to build and an expensive thing to lack.
Contradictions are surfaced, not overwritten
When a new observation conflicts with what an edge already claims, the store does not silently take the newer one. It warns that the outcomes disagree and keeps the audit trail, because a contradiction is usually information rather than noise: the same command really does succeed on one host and fail on another, and the difference between those hosts is the condition nobody has written down yet.
The brain_predict tool
Before attempting a task, an agent can ask the Brain what's likely to go wrong:
brain_predict(
context = "Deploying ClickHouse with Docker on a new Ubuntu server",
)
# Response:
{
"predicted_failures": [
{
"description": "Healthcheck using localhost may fail if IPv6 is disabled",
"probability": 0.91,
"mitigation": "Use 127.0.0.1 + listen_host = 0.0.0.0",
"severity": "critical",
"based_on": 7
},
{
"description": "ClickHouse OOM on low-memory hosts",
"probability": 0.63,
"mitigation": "Set max_server_memory_usage_to_ram_ratio = 0.8",
"severity": "major",
"based_on": 3
}
]
}Pre-load mitigations before the failure happens. That's the difference between reactive debugging and proactive deployment. Note that based_on ships with every prediction: seven observations and three observations are not the same kind of warning, and the response says so rather than flattening both into a percentage.
Why not just a vector database?
Vector DBs are great for “find things that look like X.” The CKG adds: “find things that cause X, or are caused by X, under what conditions.” A vector search for “healthcheck failure” returns text chunks. The CKG returns the condition, mechanism, fix, confidence, and observation count — together.
The two are not rivals. Similarity search is how you find the neighbourhood; causal edges are how you decide which house to knock on. cachly runs both, which is why a recall can answer “what looks like this” and “what does this lead to” in one round trip.
Edge types supported today: causes, fixes, requires, blocks, conflicts_with.
What a causal graph gets wrong
Worth saying plainly, because the phrase “causal graph” promises more than any such system can deliver. These edges are built from self-reports. When an engineer writes down what fixed a problem, they are recording what they changed last, which is not always what made the difference. A graph fed on that inherits every one of those mistakes, and a high confidence score means many people agreed — not that anyone verified.
Two habits keep this honest.
Record the condition even when it feels obvious. The condition is what stops a fix from being applied where it cannot help, and it is the first thing people leave out when they are tired.
Treat a contradiction as a finding rather than a merge conflict. When the same action succeeds here and fails there, the graph is telling you a condition is missing — and that missing condition is usually the most valuable thing in the whole entry.
Using it today
The CKG is live in all Brain instances. Every learn_from_attempts call contributes to it. Every recall_best_solution and smart_recall query benefits from it. No configuration needed.
npx @cachly-dev/mcp-server@latest autopilot
cachly is a persistent AI Brain for developers — memory shared across Claude Code, Cursor, GitHub Copilot & Windsurf simultaneously. Auto-detects every editor. Bootstraps from your git history. 122 MCP tools. Free tier, EU servers, no credit card.
Your AI is forgetting everything right now.
Every session starts blank. Every bug re-discovered. Every deploy procedure re-explained. cachly fixes that in 30 seconds — your AI remembers every lesson, every fix, every teammate's hard-won knowledge. Forever.
Four ways to install