The Rashomon Engine: Truth from Conflicting Testimony
What happens when you give YantrikDB five witness statements about a data breach — some of them deliberately lying — plus badge logs and git logs as ground truth?
The engine names the perpetrator, cites the exact lies, and explains its reasoning. The final verdict is computed from the claims ledger, not scripted in Python.
No other memory system can do this end-to-end.
The Scenario
Section titled “The Scenario”2026-03-15, 19:00–00:00 UTC. Helios Labs, Cambridge MA.
Source code for the flagship product leaks to a public repo at 23:15. Five people had badge access that night. Each gives a statement.
The cast
Section titled “The cast”| Person | Role | Their story |
|---|---|---|
| Maya Chen | Senior engineer | ”Left at 10pm. David’s light was on.” (truthful, partial) |
| David Park | CTO | ”Home by 10. Did NOT touch production repo.” (lying) |
| Alex Rivera | Night janitor | ”David typed in his office at 11pm. Stressed exit at 11:30.” (truthful) |
| Sarah Kim | Receptionist | ”WFH, have badge alerts on phone.” (corroborative only) |
| Jamie Torres | Junior engineer | ”Worked from home. Pushed a PR at 10:45pm.” (partial lie) |
The two authoritative log sources
Section titled “The two authoritative log sources”system.badge— every card swipe on building doorssystem.git— every commit, push, and visibility change on the code repos
What the engine produced
Section titled “What the engine produced”The showcase runs 8 phases against the YantrikDB HTTP cluster. Here is verbatim output from a live run:
Phase 3: Polarity contradictions detected automatically
Section titled “Phase 3: Polarity contradictions detected automatically”[1] POLARITY_CONTRADICTION subject: David relation: accessed --> production_repo (system.git) CLAIMS YES [23:14-23:15] conf=high (david.park) CLAIMS NO [21:00-23:59] conf=high
[2] POLARITY_CONTRADICTION subject: Jamie relation: was_at --> Helios_office (system.badge) CLAIMS YES [22:48-23:07] conf=high (jamie.torres) CLAIMS NO [19:00-01:00] conf=highThe engine walked the claims ledger, found the same (subject, relation, object) asserted with opposite polarity values by different sources, and flagged it as a contradiction. This is RFC 006 Layer C detection — no LLM involved.
Phase 4: Temporal contradictions
Section titled “Phase 4: Temporal contradictions”[1] David left Helios_office: system.badge says 23:31, david.park says 21:45 (106 min gap)[2] David left Helios_office: system.badge says 23:31, maya.chen says 22:00 (91 min gap)David claimed 21:45 exit. Badge log shows 23:31. That’s a 106-minute lie, caught by comparing validity windows across sources.
Phase 5: Presence denial caught
Section titled “Phase 5: Presence denial caught”[1] Jamie denies being at Helios_office, but system.badge logs 22:48-23:07Jamie said “I was home all night” (polarity=-1). The badge system says otherwise (polarity=+1). Contradiction found in one query.
Phase 8: The verdict (computed, not scripted)
Section titled “Phase 8: The verdict (computed, not scripted)”Suspect contradiction scores (weighted): David 9 points (VERY HIGH) Jamie 5 points (VERY HIGH)
PRIMARY SUSPECT: David
Actions attributed to this suspect by AUTHORITATIVE sources: [system.git] David --leaked--> production_code at 23:15 [system.git] David --accessed--> production_repo at 23:14
Their stated position (proven false): [david.park] denied accessed --> production_repo [system.git] confirmed it at 23:14Why no other system can do this
Section titled “Why no other system can do this”Before YantrikDB v0.6.1, every cognitive memory system had one of these problems:
| System | Failure mode |
|---|---|
| Vector DB (Pinecone, Weaviate, Qdrant) | Returns all 5 witness statements as “similar.” No concept of contradiction. No source attribution. No polarity. |
| Full-text search (Elastic, Meilisearch) | Finds keyword matches. Can’t tell that “David was home by 10” contradicts “David left at 11:31”. |
| File-based memory (CLAUDE.md, memory files) | Stuffs all 5 statements into context, lets the LLM figure it out. Doesn’t scale, no provenance chain. |
| Graph DB (Neo4j, Memgraph) | Can model entities + relations, but no temporal validity or polarity on edges. Can’t distinguish “David claims X” from “X is true.” |
| YantrikDB v0.6.1+ | Scoped claims with polarity, validity windows, source attribution. Multi-source assertions coexist. Polarity contradiction detection is automatic. |
The V18 schema fix that made this possible
Section titled “The V18 schema fix that made this possible”The V17 schema had UNIQUE(src, dst, rel_type) on the claims table. That silently overwrote any previous source’s claim whenever another source asserted the same fact. In the Rashomon case, David’s denial would overwrite system.git’s confirmation — or vice versa. Multi-witness investigation was theoretically possible but practically broken.
V18 (yantrikdb 0.6.1):
UNIQUE(src, dst, rel_type, extractor, polarity, namespace)Now David’s accessed = -1 (denial) and system.git’s accessed = +1 (confirmation) are both stored as distinct rows. The contradiction detector sees them. The showcase can surface them.
Before this fix: the Rashomon pattern couldn’t work on the real engine. After this fix: a 300-line Python script against the HTTP API.
What this unlocks
Section titled “What this unlocks”This exact pattern applies to:
- Legal discovery — conflicting depositions, timelines, documentary evidence
- Incident response — logs from multiple systems + human bug reports + postmortems
- Investigative journalism — source statements, official records, timeline reconstruction
- Medical diagnosis — patient self-report, test results, family history, symptom timeline
- Financial forensics — transaction logs, interviews, stated vs actual activity
- Historical research — primary sources that contradict each other across time
- Multi-agent AI systems — sub-agents reporting observations, some stale, some buggy, some biased
Any domain where truth must be reconstructed from partial, biased, or deceptive sources is a domain for this pattern.
Run it yourself
Section titled “Run it yourself”git clone https://github.com/yantrikos/yantrikdb-serverpython yantrikdb-server/docs/showcase/rashomon_engine.py \ ydb_your_token \ http://your-cluster:7438Requires yantrikdb-server v0.7.2+ and yantrikdb v0.6.1+.
Full script: rashomon_engine.py
Memory as a reasoning substrate, not a search index.