Skip to main content

Veritas — Truth Maintenance for AI Agents

Your agent's memory is rotting. Veritas fixes it.

from veritas import BeliefStore

store = BeliefStore()
store.assert_belief("Acme's CEO is Alice", source="board_meeting", source_reliability=0.95, ground=True)
store.assert_belief("Acme's CEO is Bob", source="twitter_rumor", source_reliability=0.2)
# → "Acme's CEO is Bob" rejected. Alice stays. Audited. Deterministic.

Every long-lived agent accumulates contradictions. A CEO changes, a deadline moves, an assumption proves false — and the agent's memory quietly rots. Today's systems handle this three ways, all broken:

Approach Problem
Latest wins A rumor overwrites a verified fact. Recency ≠ truth.
Manual review Doesn't scale; nobody reviews 10,000 beliefs.
LLM shrug Ask the model per-case, get an unprincipled, unaudited, expensive guess.

Veritas is the fourth way: a deterministic epistemic engine. Contradiction in → entrenchment-ordered contraction → dependency propagation → audit trail out. No black box in the retraction decision.

Before garbage collection, programmers managed memory by hand and drowned in bugs. Agents today manage contradictions by hand and drown in stale beliefs. Veritas is garbage collection for beliefs.

Works with any model — Claude 5.5, GPT-6, Gemini 4, Llama, whatever's next. Veritas operates at the memory layer, not the model layer. The models change; the need for truth maintenance doesn't.

What's new

  • v0.17.0 — Product + heuristic detector 20% → 80%: Canonical contradiction detection quadrupled via new patterns (lives in, is on, departs from, works as, starts/begins at, opens/closes at, parked in), possessive adjectives (My/His/Her X is Y), substring whitelist matching, and new functional relations (name, color, personal best, deadline, start_time, etc.). Adjudication 100% correct when detected. Benchmark: python3 benchmarks/bench_adjudication.py. Product: REST API + web playground + Docker (product/).
  • v0.16.0 — RAGS_2 audit (17 bugs): 6 new critical bugs — flagship ARTICLE_FRONTIER.md crash (location patterns added), duplicate REJECTED audit events, constraint retract order (primary violators only), dynamic _SPLAIN from all 37+ relations, NLI dict format + metadata contradicts, inf/-inf validation. Plus 11 from previous audit.
  • v0.15.0 — Deep audit fixes: 8 critical bugs from line-by-line audit — MemoryGovernor false cascade (removed entity-based premise guessing), phantom corroboration code (now implemented), reactivation rollback on rejection, batch detector temporal/vector fixes, point-in-time temporal overlap, ancestor-only ground-path check, framework subclass crashes fixed, persist/timetravel glitches.
  • v0.14.1 — Audit cleanup: pyflakes clean across all files, mypy clean (31 files), docstring corrections, PEP 562 lazy import for BFT. No behavior changes.
  • v0.14.0 — Byzantine tolerance: ByzantineTolerantLog — Ed25519-signed events, equivocation detection with automatic blacklisting, author-only retraction. Honest nodes converge despite malicious nodes. pip install veritas-tms[bft].
  • v0.13.0 — P2P gossip: GossipEventLog — every node keeps a full copy, no single point of failure, partition-tolerant with deterministic merge on heal. No Raft, no leader, no coordinator.
  • v0.12.0 — Distributed: DistributedBeliefStore shares one consistent belief state across machines via a shared event log. Event sourcing + deterministic replay = eventual convergence, no consensus protocol.
  • v0.11.0 — Export: JSON, Graphviz DOT, GraphML — visualize belief graphs in Gephi.
  • v0.10.0 — Time-travel: Reconstruct what the agent believed at any point. "What did it know when it made that decision?"
  • v0.9.0 — LLM-as-judge: Use Claude 5.5, GPT-6, or Gemini 4 as the contradiction detector. The LLM judges, Veritas still decides.
  • Earlier: Explanations (why_retracted() answers "why did my agent forget X?"), SQLite persistence, CLI, async API, standalone memory helpers, metrics, n-ary constraints, Horn-clause justifications.

How it works

new evidence arrives
       │
       ▼
┌──────────────┐
│  DETECT      │  pluggable contradiction detector
│  conflicts?  │  (ships with a transparent heuristic)
└──────┬───────┘
       │ yes
       ▼
┌──────────────┐
│  CONTRACT    │  order contradictors by entrenchment (weakest first);
│ (Hansson)  │  retract until consistent. If the newcomer is weaker
│              │  than ANY contradictor, it is REJECTED — the store
│              │  refuses to corrupt itself.
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  PROPAGATE   │  JTMS-style: every belief records its justifications.
│  (JTMS-style)│  Retracted belief → dependents re-evaluated →
│              │  orphaned beliefs cascade unless they stand alone.
└──────┬───────┘
       │
       ▼
┌──────────────┐
│  AUDIT       │  every assertion, retraction, cascade, and rejection
│              │  recorded with its reason. Replayable.
└──────────────┘

Entrenchment (higher = harder to retract) is a transparent weighted score:

entrenchment = 0.40 × source_reliability
             + 0.25 × corroboration (log-scaled justification count)
             + 0.20 × confidence
             + 0.15 × recency (30-day half-life)

No single factor dominates; a fresh rumor can't beat an old verified fact, and a verified fact can't beat a fresher verified fact.

What is Veritas?

Veritas is Latin for "truth" — the Roman virtue of truthfulness. The name is the claim: this is the component that keeps an agent's memory truthful over time.

The problem

Every LLM agent with long-term memory has the same untreated wound: memory is append-only. The agent learns "the CEO is Jane" in March, "the CEO is John" in June — and both facts sit in the index forever. Retrieval returns stale alongside fresh. The agent hallucinates with confidence, citing outdated context as current truth.

Existing answers are all bad:

Approach Problem
Latest-wins overwrite Silently destroys history; no audit; a rumor overwrites a verified fact
Manual curation Doesn't scale past a demo
Ask the LLM per-case Expensive, unprincipled, unaudited, non-deterministic
Nothing (most agents) Memory rots; long-horizon agents degrade

How Veritas fixes it

Veritas treats memory as a belief base — a set of propositions that must stay consistent — and maintains it automatically:

  1. Beliefs carry pedigree. Every fact records where it came from (source, reliability), how sure the agent is (confidence), what justifies it (premise beliefs), and when it holds (temporal validity). This pedigree is what makes principled retraction possible. Without it, the system can only do "latest wins".

  2. Contradictions trigger adjudication, not overwrite. When "CEO is John" arrives against "CEO is Jane", Veritas computes each side's entrenchment — how resistant it is to retraction — from source reliability, corroboration, confidence, and recency. Weakest retracts first. If the newcomer can't outrank every contradictor, it's rejected — the store refuses to corrupt itself with weak claims.

  3. Retractions propagate. Beliefs record their justifications (JTMS-style). Retract "CEO is Jane" and "Jane founded Acme" — which was justified by the CEO belief — is re-evaluated: it lost its premise, so it cascade-retracts too, unless it can stand on its own source. Changes ripple through the dependency graph automatically.

  4. Nothing disappears silently. Every assertion, retraction, cascade, and rejection is written to an append-only audit log with its reason. "Why did my agent forget X?" always has an answer.

How this helps any LLM or agent

  • Kills stale context — the #1 failure mode of long-horizon agents. Outdated beliefs are retracted when updates arrive, so retrieval returns the current truth, not a mix of eras.
  • Deterministic — the same evidence always produces the same memory state. Debuggable, testable, reproducible. No LLM in the retraction decision.
  • Model-agnostic — operates at the memory layer, not the model layer. Swap Claude for GPT for Gemini; Veritas doesn't care. Your agent's memory survives model upgrades.
  • Temporal sanity — "was online" (past) doesn't contradict "is offline" (now). Beliefs carry validity intervals; only overlapping intervals can conflict.
  • Auditable compliance — time-travel reconstructs what the agent believed at any timestamp. Prove what was known when a decision was made.

Installation

pip install veritas-tms

Quick start

from veritas import BeliefStore

store = BeliefStore()

ceo = store.assert_belief("Acme's CEO is Jane Smith",
                          source="tech blog", source_reliability=0.65)
store.assert_belief("Jane Smith directs Acme's product strategy",
                    source="derived", source_reliability=0.4,
                    justifications=[ceo.id])
store.assert_belief("Acme's HQ is Austin",
                    source="company website", source_reliability=0.9)

# Press release arrives: the CEO changed.
store.assert_belief("Acme's CEO is John Doe",
                    source="official press release", source_reliability=0.97)

# → "Jane Smith is CEO" retracted (outranked)
# → "Jane directs product strategy" CASCADE-retracted (lost its justification)
# → "HQ is Austin" survives (independent)
# → store.is_consistent() == True, full audit trail available

for e in store.audit:
    print(e.event_type, "|", e.proposition, "|", e.reason)

Run the full demonstration: python3 examples/demo.py Watch Veritas audit its creator's own memory: python3 examples/dogfood.py

Testing

Tested like infrastructure, not a demo:

Suite What it does Status
tests/run.py 40 core unit tests (contraction, cascades, audit) 40/40 pass
tests/test_v02.py 23 persistence/CLI/detector/index tests 23/23 pass
tests/test_edge.py 11 adversarial cases (cycles, 5000-deep chains, hostile detectors, 50-way contradiction storms) 11/11 pass
tests/test_ordering.py 6 entrenchment-ordering proofs + 200 randomized decision-rule trials 6/6 pass
tests/test_robust.py 10 API-misuse/detector-contract/CLI-fuzz cases 10/10 pass
tests/test_readme.py Every README code block runs 3/3 pass
tests/test_readme_sync.py README version/exports/test-files/changelog match code 68/68 pass
tests/test_realistic_trajectory.py 30-day support agent: subscription, outage, stale cache, GDPR pass
tests/test_determinism.py Frozen-time replay byte-identical across hash seeds pass
tests/test_audit_proof.py Audit completeness: every state change causally logged pass
tests/test_differential.py 15 trials × 200 ops vs naive reference implementation: every decision and final state identical clean
tests/test_adversarial.py 14 adversarial cases: corrupt DBs, future/legacy schemas, 10k fan-out cascade, hostile detectors, clock skew, concurrent CLI, unserializable metadata, snapshot isolation, deepcopy 14/14 pass
tests/test_v03.py 12 formal rigor tests (EE2/EE3, zombie prevention, Hansson) 12/12 pass
tests/test_v04.py 22 well-foundedness/Horn/constraint tests 22/22 pass
tests/test_properties.py 7 mathematical invariant proofs 7/7 pass
tests/test_benchmarks.py 3 head-to-head vs naive baselines 3/3 pass
tests/verify_e2e.sh 38 end-to-end checks (package, CLI, deployment, publish-clean) 38/38 pass

The fuzzer and edge cases found and fixed 4 real bugs: dead justifications accepted at assert time, duplicate justifications leaving dangling references, stack overflow on deep cascades (now iterative), and a thread-safety race (store is now fully locked). The store is safe for concurrent use from multiple threads.

Persistence & CLI

Stores survive restarts via SQLite:

from veritas import BeliefStore, save, load

store = BeliefStore()
store.assert_belief("Acme's CEO is Jane Smith", source="blog", source_reliability=0.6)
save(store, "memory.db")

store2 = load("memory.db")  # beliefs, audit log, config — all restored

Or use the command line — every command is audited like programmatic use:

veritas init
veritas assert "Acme's CEO is Jane Smith" --source "tech blog" --reliability 0.65
veritas assert "Acme's CEO is John Doe" --source "press release" --reliability 0.97
# → contracted 1 belief(s): Acme's CEO is Jane Smith (contradicted...)
veritas list
veritas contradictions
veritas audit
veritas stats

Detectors

Contradiction detection is a plugin interface (veritas.Detector):

  • Heuristic (default) — transparent, no model. Functional-property conflicts ("X's CEO is A" vs "X's CEO is B"), direct negation ("S is O" vs "S is not O", "S will O" vs "S will not O"), and explicit metadata["contradicts"] pairs.
  • NLI (veritas.HuggingFaceNLIDetector, requires pip install veritas-tms[nli]) — production-grade detection via natural language inference, both directions, configurable threshold. Verified against real roberta-large-mnli weights: 4/4 test pairs correct, drives store contraction end-to-end.
  • Custom — implement contradicts(a, b) -> bool, pass as detector= or contradiction_fn=. Register named detectors with veritas.register_detector so persisted stores resolve them on load.

Contradiction search is indexed, not quadratic: claims are indexed by (subject, relation) and (subject, object), so assertion cost scales with candidate contradictors, not store size.

Benchmarks

Measured on 10,000 synthetic beliefs (single thread, no GPU):

Operation Result
Bulk insert ~58,000 beliefs/sec (17 µs/belief)
contradictors_of() (hot path) ~80 µs per new belief
find_contradictions() over 10k 0.87 s (29k pairs found)
assert_belief() with contraction ~15,800/sec
Memory ~2.6 KB per belief

Indexed search is 433× faster than brute force at n=1,000 (verified identical results). Run them yourself: python3 examples/benchmark.py.

Theory

Veritas implements two classical ideas, combined as a working system for LLM agent memory:

  • Hansson's non-prioritized belief base revision (Sven Ove Hansson): contraction is entrenchment-ordered and minimal — give up as little as possible, weakest first. Unlike classical AGM (which requires accepting every input via the Success postulate), Veritas screens newcomers: a weaker belief is rejected rather than corrupting stronger incumbents. This is the correct formal framework for noisy agent environments. Entrenchment respects Gärdenfors–Makinson EE2 (dominance) and EE3: a derived belief is capped at its weakest premise.
  • JTMS (Doyle 1979): beliefs carry justifications; retraction propagates through the dependency network automatically. Orphaned beliefs survive only if grounded in direct observation — derived beliefs cannot outlive their premises (zombie-belief prevention).

As of October 2026, Veritas is the first standalone, general-purpose, fully audited belief-base revision engine with automated entrenchment-based contraction and dependency cascades for Python agent runtimes. (See docs/ for the prior-art survey, including yigraf, which tracks justifications but resolves conflicts manually rather than by automated entrenchment ordering.)

Design principles

  1. The retraction decision is deterministic. Detectors are pluggable (bring your own NLI model), but given a contradiction, which belief goes is computed, not guessed.
  2. Nothing disappears silently. The audit log is append-only and records reasons, not just events.
  3. Derived beliefs are second-class. A belief standing only on retracted justifications falls too — unless its independent source is strong enough to hold it up.
  4. Weak claims can't corrupt strong memory. A low-entrenchment newcomer contradicting a high-entrenchment incumbent is rejected, loudly.

Status

v0.17.0 — Product + heuristic detector 20% → 80%:

  • REST API + web playground + Docker (product/).
  • Heuristic detector quadrupled via new patterns and relations.

v0.16.0 — RAGS_2 audit (17 bugs):

  • 6 new critical bugs + 11 from previous audit (see What's new above).

v0.15.0 — deep audit fixes:

  • 8 critical bugs fixed from line-by-line audit (see What's new above).
  • MemoryGovernor no longer guesses premises from shared entities.
  • Corroboration linking now implemented (was phantom code).
  • Reactivation safely rolls back on rejection.

v0.14.1 — audit cleanup:

  • pyflakes clean across veritas/, tests/, examples/.
  • mypy clean (31 files). Docstring corrections.

v0.14.0 — Byzantine-tolerant gossip:

  • ByzantineTolerantLog(path, node_id, private_key) — Ed25519 signatures on every event, equivocation detection (double-signing = blacklist), author-only explicit retraction. Honest nodes converge despite malicious nodes trying to forge, equivocate, or spam.
  • Honest about limits: not PBFT (no 3-phase voting, no 3f+1 requirement). Eventual convergence, not real-time total order. See LIMITS.md.

v0.13.0 — peer-to-peer gossip replication:

  • GossipEventLog(path, node_id, peers) — each node has its own SQLite file, events replicate via gossip. Kill any node, the rest keep working. Partition-tolerant: both sides progress independently, merge deterministically on reconnect. CRDT-style, no coordinator.

v0.12.0 — distributed belief sharing:

  • DistributedBeliefStore(node_id, log) + SQLiteEventLog(path) for multi-machine truth maintenance. Writes append to a shared ordered log; nodes replay to converge. Eventual consistency, deterministic.

v0.11.0 — export formats:

  • to_json, to_dot (Graphviz), to_graphml (Gephi/Cytoscape) for belief-graph visualization and analysis.

v0.10.0 — time-travel:

  • TimeTravel: reconstruct belief state at any timestamp via audit replay; when_retracted, history_of.

v0.9.0 — LLM-as-judge detector:

  • LLMJudgeDetector: use any frontier model (Claude 5.5, GPT-6, Gemini 4) as contradiction judge via OpenAI-compatible API or custom callable. The LLM judges; Veritas still decides.

v0.8.0 — explanations + policies + calibration:

  • Explainer: why_retracted(), why_rejected(), belief_lineage(), summary() — "why did my agent forget X?" has an answer.
  • Contraction policies: entrenchment (default), conservative.
  • CalibrationTracker: confidence-vs-survival calibration curves.

v0.7.0 — semantic + async + temporal:

  • SemanticDetector: embedding-based contradiction detection (antonyms, semantic opposition beyond patterns).
  • AsyncBeliefStore: asyncio API for modern agent frameworks.
  • Temporal reasoning: valid_from/valid_until; non-overlapping beliefs don't contradict.
  • Framework helpers: CrewAI, AutoGen (standalone memory helpers, not drop-in framework adapters).
  • Observability: Metrics with cache hit rates, latencies.
  • 7/7 property tests, 3/3 benchmarks. Mypy clean (16 files).

v0.6.0 — async + caching + temporal (internal):

  • AsyncBeliefStore, entrenchment caching (2800x speedup), temporal validity intervals.

v0.5.0 — n-ary constraints + production hardening:

  • Constraint system: add_constraint(name, check_fn) for joint inconsistencies that pairwise detectors miss (e.g. budget violations). Weakest involved beliefs retracted in entrenchment order.
  • Mypy clean (9 files, 0 errors). Empty proposition validation.
  • 22/22 v0.4 tests (incl. 4 constraint tests).

v0.4.0 — well-foundedness + Horn clauses:

  • Circular bypass fix: cascade checks for directed path to ground (Doyle well-foundedness); A↔B loops with no ground retract.
  • Horn-clause justifications: list of AND-sets (OR across sets). Corroboration across independent derivations; EE2 caps by best proof.
  • Detector commutativity harness: contradicts(A,B) = D(A,B) ∨ D(B,A).
  • 14/14 v0.4 tests.

v0.3.0 — formal rigor + zombie prevention:

  • Reframed as Hansson's non-prioritized belief base revision (not AGM).
  • EE2/EE3 dominance: derived entrenchment capped at weakest premise.
  • Ground observations: orphaned beliefs survive only if grounded; derived beliefs cannot outlive their premises.
  • Invalidation bus: store.subscribe() for retraction events.
  • 12/12 v0.3 tests.

v0.2.0 — core engine + production surface:

  • Truth maintenance core: belief model, entrenchment, Hansson-style contraction, JTMS-style propagation, append-only audit. 40/40 core tests passing.
  • SQLite persistence (beliefs, audit log, config round-trip). 23/23 v0.2 tests.
  • Pluggable detectors: transparent heuristic (default), HuggingFace NLI (optional), custom via Detector protocol.
  • Indexed contradiction search (sub-quadratic).
  • Full CLI (veritas init/assert/retract/list/contradictions/audit/stats).
  • Dogfood: Veritas audits its creator's own memory (examples/dogfood.py).

Roadmap: multi-agent shared stores, formal verification of contraction properties, hosted demo.

License

MIT — use it, fork it, hire us.

Metadata

Release files for veritas-tms 0.17.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for veritas-tms 0.17.0
File Size Uploaded Provenance
veritas_tms-0.17.0.tar.gz 139.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for veritas-tms 0.17.0
File Interpreter ABI Platform
veritas_tms-0.17.0-py3-none-any.whl Python 3 none any Details

Total release size: 249.5 kB

Release files / veritas_tms-0.17.0.tar.gz

Download URL veritas_tms-0.17.0.tar.gz
Size 139.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8290381ea325f1a8ae3fb039d3da126cf8638ced3b8cc2c2ca3048e50b5f2639
BLAKE2b-256 checksum
How to use checksums
d615255e864d1da4d3b80a0819b5434c989fd5f882474e240a01249658579839
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / veritas_tms-0.17.0-py3-none-any.whl

Download URL veritas_tms-0.17.0-py3-none-any.whl
Size 110.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
00e904ace07f1b415c43aed17a3794f2a8206ce04012270730a5e4845aeaa057
BLAKE2b-256 checksum
How to use checksums
31888e006f5ce456efbcf8efebac19b7905c0bec08aee91a3502394e27dd83de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for veritas-tms 0.17.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page