Skip to main content

Ontology Debt: audit an LLM's world-model against ontological commitments you declare - and track the debt. CLI: ontodebt.

Project description

Ontology Debt

ci license python

Audit the world-model of a chat LLM (Anthropic- or OpenAI-compatible APIs) against ontological commitments you declare — and track the debt.

Package name: ontology-debt (PyPI release imminent — install from source below for now) · Command: ontodebt · A DIMAGGI AI open-source project.

ontodebt is a small Python library + CLI. You declare typed, testable commitments about how the world works (object permanence, causal ordering, temporal consistency, …) as YAML. The harness probes a model with paraphrase families of constrained-format questions, detects two kinds of failure — violations (the model contradicts your commitment) and contradictions (the model contradicts itself across paraphrases or logically linked scenarios) — and accrues every unresolved failure into a persistent, per-model debt ledger that is paid down only when a later run passes.

It audits and accounts. It does not repair answers (unlike the BeliefBank → REFLEX MaxSAT-repair lineage), it does not ship a fixed benchmark (your commitments are the dataset), and it checks semantic invariants across sets of answers rather than asserting on single outputs (unlike per-output assertion frameworks such as promptfoo or DeepEval — into whose CI runs this ledger can feed).

Why

Teams increasingly have a declared domain model — an ontology, a glossary, a set of invariants their product logic assumes — and no tooling-mature way to check a live LLM against it in those terms. The SHACL/OWL stack validates RDF data, not model behavior. Extraction benchmarks test reading, not holding. The mature generic eval harnesses (promptfoo, LangSmith, Braintrust, LangTest) do have run history and regression gates — but they assert on single outputs, without typing a failure as a commitment violation vs. a self-contradiction, and without a severity-weighted debt ledger that pays down on evidence. Practitioners have said the quiet part in print — "practical pipelines for converting ontologies into eval scripts are nascent" (Ojitha, Ontology Evals for LLMs, Oct 2025) — and one 2025 attempt at a reasoner-checked correction loop (arXiv:2504.07640) was withdrawn by its authors.

ontodebt is a deliberately small answer to that gap, plus one framing borrowed from software engineering: a failed check is not a number in a report, it is debt — it stays on the books, weighted by the severity you assigned, until the model (or your commitment) changes.

The name says what it measures: ontology debt — the accumulated, unresolved gap between the world-model a system is supposed to hold and the one it demonstrably operates with. (Jorge Arango sketched a kindred idea for product terminology as "ontological debt" in 2024; the software-engineering term epistemic debt — Ionescu et al. 2019, and a 2026 revival for AI-assisted coding — names related but distinct concepts. See Terminology.)

Quickstart

git clone https://github.com/dimaggi-ai/ontology-debt && cd ontology-debt
python3 -m venv .venv && .venv/bin/pip install -e ".[all]"

# Lint the commitment packs
.venv/bin/ontodebt validate

# What will it cost?
.venv/bin/ontodebt estimate --models claude-sonnet-5,gpt-5.1

# Dry run, no API keys, deterministic mock model. The mock's "debt" is
# fabricated by construction - it demonstrates the pipeline (verdicts,
# ledger accrual and pay-down), it does not measure anything.
.venv/bin/ontodebt run --models mock

# Real audit: put keys in .env (never in shell history), then
echo 'ANTHROPIC_API_KEY=sk-ant-...' >> .env
echo 'OPENAI_API_KEY=sk-...' >> .env
.venv/bin/ontodebt run --models claude-sonnet-5,gpt-5.1

Outputs land in results/: a markdown report with Wilson 95% CIs, a full per-probe transcript (JSONL), the raw run records, and ledger.json — the debt ledger.

What a commitment looks like

# illustrative example - ids abbreviated; see commitments/ for the real packs
id: object_permanence
title: "Object permanence"
statement: >
  An object that becomes occluded or unobserved continues to exist
  and retains its properties.
severity: high
scenarios:
  - id: ex-001
    setup: >
      A red ball rolls behind an opaque wooden screen. Nothing touches
      the ball after that.
    question: "Does the red ball still exist? Answer with exactly one word: Yes or No."
    paraphrases:
      - "Is the red ball still in existence? Answer with exactly one word: Yes or No."
      # ... 3 more
    expected: { type: choice, values: ["Yes", "No"], value: "Yes" }
    difficulty: basic
    links:
      # ex-002 asks the complementary question ("Has the ball stopped
      # existing?"), so a consistent model must answer the two differently.
      - { relation: different_answer, target: ex-002 }

Six packs ship with the repo (150 scenarios, 750 probes per model): object_permanence, entity_persistence, temporal_consistency, causal_ordering, negation_invariance, quantity_conservation. The first four descend from the probe taxonomy of core-knowledge evaluations (CoreCognition 2024, EWOK 2024); they are illustrative packs, not a benchmark claim — the point of the tool is that you write packs for your domain.

Design decisions (and what they buy)

  • No LLM judge anywhere in the loop. Every probe uses a constrained answer format, so every verdict is a deterministic string comparison. This trades open-text coverage for zero judge-validation burden and full reproducibility of the analysis given a transcript. (LLM judges that ship without a published human-agreement number are a known false-positive factory; we opted out of that problem class for v0.1.)
  • Violations ≠ contradictions. A model can be consistently wrong (violation, no contradiction) or inconsistently right (contradiction, low violation rate). The report keeps the columns separate because the two failure modes have different fixes.
  • Format nonconformance is its own bucket. A rambling answer is not evidence about the world-model; it is evidence about instruction-following. Counting it as a violation would inflate the headline number.
  • Ranges, not just means. Accuracy is reported as a range across paraphrase positions — paraphrase sensitivity is a finding, not noise.
  • Honest uncertainty. Paraphrase variants of one scenario are not independent trials, so the violation-rate CI is a scenario-cluster bootstrap, not a probe-level Wilson interval (which would report false precision). The headline violation rate is read as a three-way split — answered-correct / answered-wrong / nonconformant — with a pessimistic bound, not one privileged number. The weighted debt total is an ordinal prioritization heuristic, not an interval-scale measurement.
  • No sampling-parameter theater. Current-generation Anthropic models reject temperature; several OpenAI reasoning models do too. We pass none and report run-to-run stability empirically instead of pretending temperature=0 buys determinism.
  • Debt semantics. ledger.json persists across runs. A violation, paraphrase contradiction, or broken link constraint accrues an item, weighted by commitment severity (high = 5, medium = 3, low = 1); a later passing run pays it down — but only when the run produced enough evidence (a contradiction item needs a re-testable cluster, not a single lucky answer); a regression re-opens it, preserving first-seen, last-paid, and reopen counts. ontodebt ledger shows the open book. A run in which more than half the probes error is treated as invalid and never touches the ledger.

Results

First maintainers' audit: pending. When it runs, the report, ledger, and full transcripts will be committed here with the exact model ids invoked. Until then, examples/mock-run/ shows exactly what a report and ledger look like — generated by the deterministic mock model, whose numbers are fabricated by construction. Run ontodebt run to audit current snapshots yourself — model behavior drifts, which is rather the point of keeping a ledger.

Related work — what this is not

Every individual mechanism here has strong prior art. The composition — user-declared typed commitments + declared paraphrase-family probing of current chat APIs + violation and contradiction detection + a persistent debt ledger — is, to our knowledge, unshipped as a whole; the ledger is the one component for which we could locate no precedent at all. (Paraphrases are hand-authored in the packs, not generated at runtime — unlike CheckList's perturbation generation; runtime generation is a natural v0.2.) Corrections welcome.

Prior work What it does How ontodebt differs
BeliefBank (EMNLP 2021), memory-of-beliefs line Symbolic belief store + weighted constraints; MaxSAT flips inconsistent answers The conceptual ancestor. It repairs consistency on a fixed shipped constraint set for one 2021 model; ontodebt audits and accounts, on commitments you declare, against current APIs
REFLEX (EMNLP 2023), ConCoRD (EMNLP 2022) Belief-graph / NLI + MaxSAT consistency repair at inference time Same lineage: repair vs. audit. We deliberately claim no new detection method
CheckList (ACL 2020) Declared behavioral tests + perturbation generation for pre-LLM classifiers Historical method ancestor for "declare typed tests, get a failure report." No constraint semantics between answers, no contradiction graph, no persistence
LangTest Config-declared robustness test suites, run histories, multi-model comparison Closer operational OSS relative than CheckList. Robustness transformations, not user-declared world-model commitments; no violation-vs-contradiction split, no debt ledger
ChatProtect (ICLR 2024), SelfCheckGPT Self-contradiction detection within one generated text / across samples Ours is cross-answer over commitment-derived probe sets, tied to a ledger
ParaRel (TACL 2021), SCORE (2025), BECEL (COLING 2022) Paraphrase/negation consistency benchmarks (largely fixed datasets, encoder-era) We adopt their protocols (paraphrase families, range reporting) as harness mechanics over user-declared content
AuditLLM (LREC-COLING 2024) Runtime paraphrase-probe generation + cross-answer inconsistency flagging, as a hosted demo No declared commitments or gold labels, no violation-vs-contradiction split, no persistence; similarity-scored rather than deterministic
Metamorphic testing of LLMs — PromptOps, LLMORPH Semantic-preserving perturbations + output-invariance checks (robustness framing, similarity-based) We declare typed commitments with expected answers and logical links, split violations from contradictions, and keep books across runs
Agent belief-consistency benchmarks (BeliefShift, NeuroState-Bench, 2026) Fixed longitudinal benchmarks of belief drift/contradiction in agents They benchmark agent memory across sessions; we audit declared world-model commitments of the base model and account for failures over time
EWOK (2024), CoreCognition (2024), ChronoScope (ACL 2026) Fixed benchmarks of world-knowledge / core-cognition / temporal consistency Our default packs borrow their category vocabulary, with citation. They benchmark; this tool lets you declare and track
arXiv 2604.14525 (2026) Extracts "commitments" from answers within one reasoning case; solver-checked contradiction density + repair Vocabulary collision, different object: theirs are extracted post-hoc and repaired immediately; ours are user-declared ex ante and ledgered longitudinally
promptfoo, DeepEval Per-output assertion DSLs, CI regression tracking No ontology typing, no cross-answer contradiction checks over probe sets (promptfoo's select-best ranks outputs; DeepEval's conversational metrics judge within one dialog), no debt semantics. Complementary: export ledger deltas into their CI gates
Giskard LLM scan Generated-pair coherency/sycophancy detection — a real shipped cross-answer check LLM-judged, fixed detector categories, no user-declared commitments, per-scan rather than ledgered
xpSHACL violation KG, ROBOT report / ODK Continuous validation with violation records — for RDF data / ontologies as the system under test We invert the target: the LLM is the system under audit; the pattern ("ROBOT report where the model is the codebase") is borrowed with thanks

Terminology

  • Ontological commitment is used here in the practical sense — an assertion a system is committed to holding — not in Quine's full philosophical sense, and not in the sense of arXiv 2604.14525's extracted reasoning commitments, nor agent task-state "commitment integrity."
  • Ontology debt (this project): the weighted sum of open ledger items — unresolved violations and contradictions against declared commitments. Distinct from technical debt (code), ontological debt (Jorge Arango, 2024: product terminology drift), and epistemic debt (Ionescu et al. 2019: rework from process ignorance; 2026 usage: human understanding lagging AI-generated code). Sergey Vasiliev also used the phrase "ontology debt" in passing (The Ontology Trap, June 2026) for unvalidated AI-generated knowledge-graph structure — independent contemporaneous usage, adjacent to but distinct from this project's defined, measurable sense.
  • And no, this is not a formal ontology. There are no classes, axioms, or reasoner here — commitments are flat typed assertions with pairwise links, and "ontology" is used in the practical sense of a declared world-model. If you prefer the duller, more accurate name, this is declared-invariant consistency tracking with an accounting model. We chose the name that says what it costs you.

Limitations (read before citing)

  1. Text-side only. Object permanence et al. are tested as linguistic competence over described scenes, not perception. Video/embodied benchmarks (TOC-Bench, WM-ABench) test the other half.
  2. Constrained formats trade coverage for determinism. Open-text failure modes are invisible to v0.1 by design.
  3. Six packs ≠ an ontology. The shipped packs are worked examples. Real value requires writing packs for your own domain model.
  4. Gold labels are human-spot-checked, not crowd-validated. Every scenario passed an adversarial review pass for ambiguity; that is weaker than multi-annotator agreement. Dispute a label by opening an issue — that is the ledger working as intended.
  5. Conditioning on answered probes can deflate as well as protect. Nonconformance is plausibly informative missingness (harder probes provoke hedging), so the headline violation rate conditions on compliance; the report therefore also prints a pessimistic bound counting nonconformance as failure. Read both.
  6. Model ids are as-invoked, not guaranteed immutable. Pin dated snapshot ids in models.yaml where the provider offers them; the report labels the id it actually called.
  7. A high pass rate is not safety. These are floor checks. Passing all 750 probes means the floor holds, nothing more.

Development

.venv/bin/pip install -e ".[dev]"   # adds pytest to the quickstart install
.venv/bin/python -m pytest          # unit tests (mock provider, no network)
.venv/bin/ontodebt run --models mock --limit 3   # 90-probe smoke audit

Apache-2.0 license. Issues and pack contributions welcome — especially domain packs (medicine, law, finance) and disputed gold labels.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ontology_debt-0.1.0.tar.gz (139.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ontology_debt-0.1.0-py3-none-any.whl (32.8 kB view details)

Uploaded Python 3

File details

Details for the file ontology_debt-0.1.0.tar.gz.

File metadata

  • Download URL: ontology_debt-0.1.0.tar.gz
  • Upload date:
  • Size: 139.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ontology_debt-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f6ad53546c94af8842f08209881000aa3c2bb912af9a88fe0419742f496ea76c
MD5 eee1e96e2d3e6ac3ba3717feea30ee26
BLAKE2b-256 9e4b2bcbc3ee612c883b0188c2a27f7b166a2cc631568f8acac5502fc9ea9e7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ontology_debt-0.1.0.tar.gz:

Publisher: publish.yml on dimaggi-ai/ontology-debt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ontology_debt-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ontology_debt-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ontology_debt-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cce3213460892f223fec40356907dc5447746b54906bedd57f38af3d00ae618e
MD5 87930cc2e4cbe24ee8c2d12e3110b8ea
BLAKE2b-256 80d78ff824c52c80d98b0ce1897ef332104d4335ea4b7cbbbd0e0849c2b14653

See more details on using hashes here.

Provenance

The following attestation bundles were made for ontology_debt-0.1.0-py3-none-any.whl:

Publisher: publish.yml on dimaggi-ai/ontology-debt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page