Credence — Epistemic Guard

io.github.Lakshmi-Chakradhar-VijayaraoPublished by GitHub account Lakshmi-Chakradhar-Vijayaraov1.2.5Updated Nov 10, 2026

Epistemic guard for AI coding: tracks uncertain values and blocks writes until verified.

VerifiedSTDIODesktop onlyKnowledge & MemoryDeveloper Tools

Overview

AI-generated overview

A local epistemic guard for AI coding that records values you state as uncertain and blocks file writes or commands embedding them until you confirm.

What you can do
Register uncertain values from your prompts through a passive observer hook before the assistant responds, and keep them in a local SQLite registry with session tracking and a constraint cap. Block Write, Edit, Bash and NotebookEdit actions that embed unverified or stale values, and clear the block once you confirm the value. Inspect pending constraints and review gate statistics and feedback tags. Run a demo smoke test and latency reports from the command line.
When to use it
Worth adding when an assistant writes code that hard-codes configuration values, limits, versions or expiries you only guessed at, and you want a hard stop before those guesses reach a file or command. It suits Claude Code users who want enforcement rather than warnings.
Requirements
A local Python install with the credence-guard package; the README also describes a Rust gate alternative. Setup requires adding an MCP server entry and Claude Code hooks for UserPromptSubmit and PreToolUse in the project settings. No API key is required. Optional environment variables configure the registry path, session ID, event log and constraint cap.
Before you install
The gate blocks writes and commands, so expect interrupted edits until values are confirmed; it only catches uncertainty you explicitly stated and does not check whether a value is correct. It writes a SQLite registry into the working directory and a local event log under the home directory, both of which can be relocated or disabled. It is desktop-only and depends on hook configuration in Claude Code.

Installation

In SourceWeft

  1. Open Credence — Epistemic Guard in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

Credence

AI doesn't remember what it wasn't sure about. Credence does.

[PyPI] [CI] [Python] [License: Apache 2.0]

bash
pip install credence-guardcredence demo   # 30-second smoke test, no API key required

[mcp] adds the FastMCP server for Claude Code. Core package has zero hard dependencies.


The problem

You say: "The rate limit is probably around 50 — I haven't confirmed it yet."

Fifteen turns later, Claude writes:

python
RATE_LIMIT = 50   # no warning. no flag. shipped.

The API rejects every request at 2am. The real limit was 10. Claude forgot you weren't sure.

This isn't hallucination. The model reproduced exactly what it read. What it read had the qualifier stripped — by context compression, fifteen turns back.


What Credence does

Tracks uncertain values the moment you state them. Blocks writes that embed those values until you confirm them.

you say "rate limit is probably 50"    → observer registers it (before Claude responds)    → Claude writes: RATE_LIMIT = 50  # ⚠ CREDENCE[unverified]    → write blocked until you confirm

Every other tool warns. Credence enforces.


What it looks like

python
# Claude generates this. Credence intercepts before it ships.
class StripeClient:    API_VERSION  = "2023-10-16"  # ⚠⚠ CREDENCE[stale]: API date versions change on release — verify before shipping    RATE_LIMIT   = 100           # ⚠  CREDENCE[unverified]: I think Stripe rate limit is around 100 req/min    TOKEN_EXPIRY = 3600          # ⚠⚠ CREDENCE[stale]: Token/session lifetime values are set by the vendor — verify    MAX_RETRIES  = 3    TIMEOUT_MS   = 5000
credence: blocked Edit — 2 unverified value(s)  → I think Stripe rate limit is around 100 req/min | TOKEN_EXPIRY = 3600  Verify first, then retry. Use credence_constraints to see all pending.

After you confirm: "Confirmed — rate limit is 100 req/min per stripe.com/docs" → gate clears.

[Gate demo]


Setup

1. Add to .mcp.json:

json
{ "mcpServers": { "credence": { "command": "credence-server" } } }

2. Add to .claude/settings.json:

json
{  "hooks": {    "UserPromptSubmit": [      { "hooks": [{ "type": "command", "command": "python3 -m credence.observer" }] }    ],    "PreToolUse": [      {        "matcher": "Write|Edit|Bash|NotebookEdit",        "hooks": [{ "type": "command", "command": "python3 -m credence.hooks" }]      }    ]  }}

Done. No API key required.

Registry: Credence creates epistemic_registry.db in your working directory. Add *.db to your .gitignore, or set CREDENCE_DB=~/.credence/registry.db to keep it global.

Session tracking: Set CREDENCE_SESSION_ID=my-project to keep constraints stable across directory changes and terminal restarts.

Event log: The gate writes block/allow events to ~/.credence/events.jsonl (local only, never sent anywhere). Set CREDENCE_NO_LOG=1 to disable.

Constraint cap: The registry allows up to 500 constraints per session by default. Override with CREDENCE_MAX_CONSTRAINTS=<n>.


How it works

Two layers, neither requires model cooperation:

LayerHookRole
ObserverUserPromptSubmitPassive listener — registers uncertain values before Claude generates anything
GatePreToolUseBlocks writes that embed unverified values

The observer fires before the model processes your message. If you say "I think the rate limit is 50", the registry has that entry before Claude generates a single token.


What gets blocked

credence: blocked Edit — 2 unverified value(s)  → rate limit is probably 50 req/min | token expires in 3600s  Verify first, then retry. Use credence_constraints to see all pending.

Once verified, the gate clears.


What Credence does NOT do

  • Does not verify facts — it cannot tell you if a value is correct
  • Does not catch uncertainty that was never stated
  • Does not block the model from saying a wrong value in prose — only from writing it to a file or command

Known issue (November 2026): the PreToolUse gate (python3 -m credence.hooks) only enforces when CREDENCE_SESSION_ID is set. Without it, the observer files constraints under an id derived from the working directory, which the gate never reads, so nothing is blocked. The Rust gate filters by Claude Code's own session id and reads CREDENCE_DB_PATH rather than CREDENCE_DB, so it can miss them too. Making the ids match is planned, together with a stricter value-level match: the current two-shared-words rule over-blocks once it enforces.


Measured results

46% of uncertainty qualifiers are stripped by Claude Haiku during context compression. Credence's probe skips compression for 100% of those segments (n=50), so no qualifier is lost.

Validated across 7 open-weight models (Qwen, Mistral, Llama, Phi, Gemma) from 5 organizations: same failure mode, same block rate.

bash
credence demo                     # smoke test, no API keycredence stats                    # false-positive rate from real gate usagecredence feedback 1|2|3           # tag last gate block: correct / noise / skippython3 -m pytest tests/ -q       # 829 testspython3 -m evals.latency_report   # P50/P95/P99

Full methodology: docs/TECHNICAL_REPORT.md


Project layout

credence/         pip-installable package  observer.py     passive UserPromptSubmit hook  hooks.py        PreToolUse enforcement gate  mcp_server.py   17-tool MCP server  registry.py     SQLite constraint store  memory.py       cross-session persistencetests/            829 testsevals/            validation studies + multi-model benchmarksdocs/             technical report, architecture, ETP speccredence_gate/    Rust gate (alternative to Python hooks.py)experimental/     Phase 2 work — not yet shippedpaper/            Research paper draft + figures

Research

The scientific basis for Credence is documented in paper/ (EQL / EQLR / FCR).

The companion geometry thesis — on confabulation detection and why the detection axis is dissociable from the causal control axis — lives in a separate repo: → Detection Without Control


Built by

Lakshmi Chakradhar Vijayarao — GitHub · LinkedIn · X

Apache 2.0 License

Source: README.md at commit a75329a

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v1.2.5LatestSep 16, 2026

Score

40% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.