DEV Community

Cover image for The Missing Layer Between LLMs and Reality
Vladyslav
Vladyslav

Posted on

The Missing Layer Between LLMs and Reality

"Every AI demo works perfectly... right until someone asks, 'Where did you get that fact?'"

Every week, a new language model appears. More parameters. Longer context windows. Higher benchmark scores. The race is impressive.

But after months of building applications on top of LLMs, we kept running into the same question. Not "Can the model answer this?", but "Can we trust the answer tomorrow?"

That question changes everything. Hallucinations are only one symptom. The real problems look like this: sources disappear, facts contradict each other, knowledge silently changes over time, two agents modify the same graph, nobody knows which version introduced the mistake. Those aren't language problems. They're infrastructure problems.

Twenty years ago, Git solved this for source code. We think AI needs something similar for knowledge. That's why we built Canonical Knowledge Structure (CKS).

Two weeks ago, it was mostly a structural validator. Today, it's become something much bigger — a verifiable knowledge laboratory.


CKS, Two Weeks Later

24 tools. 650+ tests. Offline semantic search. Version history.
Sandboxed experiments. Contradiction detection. Async runtime.
Telemetry. Security hardening. Zero API keys.
Enter fullscreen mode Exit fullscreen mode

Not because we wanted a bigger feature list. Because every one of these solved a real problem we hit while building AI systems. Let's look at a few of them.


Experiment #1 — Can an LLM Search by Meaning Instead of Keywords?

Most semantic search systems start with an API key. We wanted something different. So we integrated FastEmbed — a lightweight ONNX runtime that downloads a ~90MB sentence-transformers model once and runs forever, offline. No API key. No cloud. No rate limits.

To see whether it actually understood meaning, we created a tiny graph with three objects: apple, banana, and car. Then we searched for fruit. The ranking was:

apple      0.705
banana     0.671
car        0.214
Enter fullscreen mode Exit fullscreen mode

Exactly what you'd hope to see. The interesting part isn't that semantic search works — it's that it now works entirely on your machine. No OpenAI embeddings, no Hugging Face token, no remote inference. Meaning became local.

We wrote up the full experiment, with code and scores, in our local embeddings case study.


Experiment #2 — Can We Catch Contradictions Before Humans Do?

LLMs rarely produce obviously wrong knowledge. They produce almost correct knowledge, and that's harder to spot. Consider a graph where "Earth supports Theory X" and "Earth refutes Theory X" both appear. Each statement is structurally valid. Together they're nonsense.

So we introduced structural constraints: MutualExclusionRule and FunctionalRelationRule. They don't evaluate language — they evaluate consistency. Because inconsistent knowledge is still incorrect knowledge. The system flagged the contradiction immediately. We ran the full experiment with conflict detection and sandbox resolution, and documented it here.


Experiment #3 — Can We Rewrite History Safely?

Imagine an agent proposes "remove this relation." Should it? Maybe. Maybe not. Most systems force you to decide immediately. CKS doesn't. Instead it creates a sandbox — try the change, inspect the graph, compare versions, discard it or merge it. Nothing touches production until you decide.

It feels surprisingly similar to opening a Git branch, except the repository is knowledge itself. We tested this by forking a session, applying a destructive edit in the sandbox, and confirming the parent session remained untouched. Then we merged the fix back. The whole flow took three tool calls.


Experiment #4 — Can We Break It?

This became our favourite experiment. Instead of adding features, we spent days trying to destroy the system. Could forged provenance records sneak in? Not anymore. Could RDF/XML trigger Billion Laughs attacks? Blocked. Could document ingestion bypass SSRF protection? No. Could middleware leak stack traces? Also fixed.

Most release posts celebrate features. We're equally proud of the bugs users will never see. We ran a full security audit, patched every hole we found, and wrote regression tests so they stay fixed. The full changelog is on GitHub.


Making Infrastructure Invisible

As the project grew, something unexpected happened. The hardest problems were no longer algorithms — they were operations. How do background workers coexist with semantic search? How do multiple sessions evolve simultaneously? How do you know which tool suddenly became slow?

So CKS became fully asynchronous. The JSON-RPC server no longer blocks on I/O. Embedding generation runs in background tasks. PostgreSQL workers coordinate through atomic SKIP LOCKED claims. Telemetry tracks every tool invocation — latency, success rate, error distribution — because infrastructure should explain itself, not require guesswork.


Bigger Than a Validator

CKS started as a way to stop fake citations. It became something else. Today it can search knowledge by meaning, detect contradictions, validate provenance, evolve graphs safely, compare versions, branch experiments, monitor itself, and run completely offline. We didn't plan for that — it happened naturally. Every missing capability became another layer in what we now think of as a knowledge operating system for LLMs.


Why This Matters

The AI industry is obsessed with making models smarter. We think the next leap forward may come from making them more trustworthy — not through larger parameter counts, but through better infrastructure.

The future probably isn't bigger prompts or bigger context windows. It's software that can answer questions like: where did this fact come from? When did it change? What contradicts it? Can I reproduce this result? Can I verify it? Language models generate knowledge. But trust has to be engineered.


Getting Started

pip install cks-mcp
Enter fullscreen mode Exit fullscreen mode

Find the absolute path to the executable:

which cks-mcp
Enter fullscreen mode Exit fullscreen mode

Then add this to your claude_desktop_config.json (replace /absolute/path/to/cks-mcp with the output of which):

{
  "mcpServers": {
    "cks-mcp": {
      "command": "/absolute/path/to/cks-mcp"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop (Cmd+Q, then reopen). Done. No API keys, no cloud setup, no extra services. Just ask "Use cks-mcp to..." and start building knowledge you can actually verify.


GitHub · Documentation · PyPI

Git changed how we trusted source code. We think AI now needs the same thing for knowledge.

Top comments (2)

Collapse
 
mads_hansen_27b33ebfee4c9 profile image
Mads Hansen

The Git analogy becomes especially interesting when knowledge has two clocks: when a claim was true in the world, and when the system learned or corrected it.

I’d make that bitemporal distinction first-class. A later commit should not simply overwrite “price was X” or “policy allowed Y”; it should preserve valid-time, recorded-time, source snapshot, extraction method, and the actor or agent that asserted the change.

A reproducible semantic result also needs more than graph versioning: content hashes for evidence, canonical claim IDs, embedding model/version, chunking configuration, and ranking parameters. Otherwise the same commit can produce a different search result after a local model upgrade.

For merges, some conflicts are not contradictions. Two claims may apply to different regions, dates, definitions, or authority levels. A policy-driven merge that can return unresolved/needs_review is safer than forcing one canonical winner.

That would make “where did this fact come from?” answerable without pretending knowledge evolves exactly like source code.

Collapse
 
deuscorp profile image
Vladyslav

Thanks for this — genuinely thoughtful feedback. A few reactions, in the order you raised them:

1. Bitemporal distinction (valid-time vs recorded-time). This is the right next step for the version model. Today CKS has a single linear commit log per session: every operation creates a new RuntimeVersion with a wall-clock timestamp, and get_version_state can reconstruct any point in that history. That's the "recorded-time" axis. What's missing is a way to say "this claim was true in the world starting at a different date than when we learned it." We've discussed adding a second, declarative axis — either as a standard field on InferenceStep/Claim objects, or as a separate timeline annotation — but haven't spec'd it yet. Your framing of "two clocks" captures the tension exactly.

2. Reproducibility beyond graph hashing. This is an excellent point, and one where we've taken a partial step already. Runtime.embedding_client is a single, shared instance used for both indexing and query — so you can't accidentally search in a different embedding space than what was indexed. But you're right that the model name/version, chunking config, and ranking parameters aren't yet hashed into the version record. Embedding those into a search_config stanza on the session or version, and including it in the Merkle root, would close that gap. It's a natural extension of the _cks_metadata / _cks_format_version pattern we already use for serialization determinism.

3. Policy-driven merge vs binary conflict. This aligns with where the merge system is heading. Today merge_knowledge/merge_branch can return structured conflicts with target_diff/source_diff, and the resolutions parameter lets the caller supply per-object strategies ("branch_a", "branch_b", null, or a custom object). So the machinery for "not forcing one canonical winner" already exists — what's missing is a declarative policy layer (region, date range, authority level) that could automatically route some conflicts to needs_review instead of flatly rejecting them. That's something we'd like to build on top of the existing conflict-reporting infrastructure.

Overall, your comment gets at something we've been circling: knowledge doesn't evolve like source code. We built the Git-like primitives first (branch, diff, merge, revert) because they're well-understood and mechanically solid. The next layer — temporal semantics, search reproducibility, and policy-aware merging — is exactly the kind of work that turns those primitives into a real knowledge infrastructure rather than just a versioned graph.

Appreciate you taking the time to write this. If you have thoughts on what a bitemporal annotation model should look like — especially around how valid-time interacts with inference chains — I'd be genuinely interested.