Skip to main content

Claude Code adapter for credence-governor — a thin PreToolUse hook that Bayesian-governs tool calls (proceed/block/ask) via the governor daemon. Requires the credence-governor daemon on :8787 — fails open (silent no-op) without it. Start it: credence-governor-daemon.

Project description

credence-governor — Claude Code adapter

A thin Claude Code adapter for credence-governor: a PreToolUse subprocess hook that Bayesian-governs tool calls (proceed / block / ask) by asking the governor daemon, which runs the one EU-max reasoner over the Credence engine.

The adapter carries no probabilistic code and no feature logic. Its only job is to translate Claude Code's native hook events into the harness-neutral wire shape and render the daemon's decision. Feature & taint extraction is server-side in the daemon (single-sourced — DRY).

How it works

Claude Code  ──PreToolUse JSON on stdin──▶  credence-governor-claude-code (this hook)
                                                  │  transcript_path JSONL → neutral messages
                                                  ▼  POST /decide  (tool, input, session)
                                            governor daemon (credence-governor-core)
                                                  │  server-side feature/taint extraction
                                                  ▼  one EU-max decision over the skin wire
                                            credence-skin engine (Julia)
        ◀──permissionDecision JSON on stdout──────┘
  • transcript.py — replays the session transcript (transcript_path) into the neutral messages list the extractors expect (user / assistant / tool_call / tool_result). The proposed call — already persisted to the transcript before PreToolUse fires — is excluded so loop counts see priors only. Sidechain (subagent) turns are excluded by default.
  • client.pyPOST /decide (stdlib urllib).
  • effectors.py — maps the governor action to a PreToolUse decision.
  • hook.py — the entry point (credence-governor-claude-code).

Overlay semantics (the governor never weakens the host)

governor action Claude Code decision effect
proceed (nothing emitted) defer to Claude Code's own permission rules
block deny + reason refuse regardless of native rules
ask ask + reason force a user prompt even if native rules would auto-allow

permissionDecision: "allow" is never emitted — that would bypass Claude Code's own safety prompts. The governor can only add friction, not remove it.

Fail-open is absolute. A malformed event, a daemon that is down, a timeout, or any error prints nothing and exits 0 — the call proceeds through Claude Code's normal flow. Run with CREDENCE_GOVERNOR_DEBUG=1 to log decisions/failures to stderr.

Capability boundary (Claude Code, hook transport)

Dimension Supported
Waste gating (loops / repetition)
Safety (taint-flow / exfil / injected imperatives)
Routing / model selection ❌ (no model-resolve hook)
Cost / dollars-saved ◑ observe-only
Online ask-response learning ◌ deferred — see below

v1 gates PreToolUse only. PostToolUse / UserPromptSubmit are intentionally not wired: neither carries a clean approval label, and treating "the call completed" as belief evidence would be a second learning path (a constitutional violation), not just a weak one. The warm-trained brain governs; the daemon logs every decision. Online ask-learning on Claude Code (inferring the user's reply from the next transcript turn) is an open design question, deferred.

Install

1. Start the daemon — every adapter shares one local daemon; see the core README or the repo quickstart. In short:

pip install credence-governor-core   # pulls credence-skin-client
credence-governor-daemon             # zero-config: auto-runs the engine via docker/podman
#   with uv:   uvx --from credence-governor-core credence-governor-daemon   (one-off; --from required)
#              uv tool install credence-governor-core  → puts it on PATH (needed for autostart, below)
#   overrides: CREDENCE_ENGINE_DIR=~/git/credence  (dev checkout)  ·  CREDENCE_SKIN_COMMAND=…  (pin a digest)

⚠️ The daemon is required — the hook does nothing without it. The hook fails open: with nothing listening on :8787, every tool call just proceeds, so you get no governance and no error. Confirm the daemon is up with curl -s localhost:8787/ready, and run a session with CREDENCE_GOVERNOR_DEBUG=1 to watch each decision (and any fail-open) on stderr. The plugin is only the thin hook; install it and run the daemon. The bundled SessionStart hook warns you at the start of every session if the daemon is down (and can auto-start it — see below), so the no-op state is never silent.

2. Register the hook — two ways; both end at the same PreToolUse hook.

Method A — as a Claude Code plugin (recommended; no pip install)

The hook is pure stdlib, so the plugin bundles it and runs it via ${CLAUDE_PLUGIN_ROOT} — there's nothing to pip install. Three ways, pick one:

a. Zero-touch — declare it in settings.json. Add this to ~/.claude/settings.json (user scope, all projects); Claude Code registers the marketplace and enables the plugin at next start, no /plugin interaction:

{
  "extraKnownMarketplaces": {
    "credence-governor": {
      "source": { "source": "github", "repo": "gfrmin/credence-governor" }
    }
  },
  "enabledPlugins": {
    "credence-governor-claude-code@credence-governor": true
  }
}

Put the same block in a project's .claude/settings.json to offer it to everyone who trusts that repo.

b. One command. Add the marketplace, then install:

/plugin marketplace add gfrmin/credence-governor
/plugin install credence-governor-claude-code@credence-governor

(From the shell instead: claude plugin install credence-governor-claude-code@credence-governor. --scope project|local to scope it.)

c. Interactive. /plugin marketplace add gfrmin/credence-governor, then open /plugin, find credence-governor-claude-code in the Discover list, and install it.

Run /reload-plugins to activate in the current session (it's on automatically in new ones); manage or remove it from the /plugin menu. The plugin reuses the same credence_governor_claude_code package this directory ships — plugin_hook.py is a thin launcher that puts it on sys.path and calls the same entry point the pip console script uses (one implementation, two install paths). Manifests: .claude-plugin/plugin.json, hooks/hooks.json, and the repo-root .claude-plugin/marketplace.json.

Method B — as a pip package + settings hook

If you'd rather manage it with pip (or script the registration):

pip install credence-governor-claude-code
credence-governor-cc-install               # → ~/.claude/settings.json  (idempotent)
#   --project   → ./.claude/settings.json   ·   --uninstall → remove

Either way the hook has no runtime dependencies (pure stdlib); credence-governor-core is needed only for the daemon and the parity test. Static config example: settings.example.json.

Environment

Variable Default Meaning
CREDENCE_GOVERNOR_URL http://127.0.0.1:8787 governor daemon base URL
CREDENCE_GOVERNOR_TIMEOUT 5.0 per-call /decide timeout (s); on timeout → fail open
CREDENCE_GOVERNOR_PROFILE (none) utility profile passed to the daemon (e.g. flow-guard)
CREDENCE_GOVERNOR_DEBUG (off) log decisions/failures to stderr
CREDENCE_GOVERNOR_SHADOW (off) truthy → observe-only: the daemon still decides and logs, but the hook never enforces (block/ask become a systemMessage saying what it would do). The safe way to run while beliefs are still being calibrated; parity with the OpenClaw adapter's shadowMode.
CREDENCE_GOVERNOR_AUTOSTART (off) truthy → the SessionStart hook auto-starts the daemon (detached) if it's down
CREDENCE_GOVERNOR_AUTOSTART_WAIT 8.0 post-autostart /ready poll budget (s) before reporting STARTING
CREDENCE_GOVERNOR_READY_TIMEOUT 1.5 SessionStart /ready probe timeout (s)

SessionStart hook (daemon-down warning + opt-in autostart)

Alongside the PreToolUse gate, the plugin registers a SessionStart hook (plugin_session_start.py). At the start of every session it probes GET /ready:

  • daemon up → silent (no spam).
  • daemon down → a systemMessage warns you and additionalContext tells Claude that this session is ungoverned (fail-open), with the exact start command — the no-op state is never silent.
  • CREDENCE_GOVERNOR_AUTOSTART=1 + down → spawns credence-governor-daemon detached (idempotent — keyed off /ready, so a concurrent harness can't double-start it), polls briefly, and reports ONLINE / STARTING. Default-OFF, because booting the engine is heavyweight (~18s) and the daemon is shared across harnesses.

The pip path registers both hooks too (credence-governor-cc-install).

Tests

python -m pytest tests -q

Pure-stdlib at runtime; the round-trip parity test (test_roundtrip.py) imports credence-governor-core to assert the wire payload deserialises through the daemon's event_and_session_from_payload to the Session the extractors expect — it is skipped if the core isn't importable.

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

credence_governor_claude_code-0.3.0.tar.gz (24.4 kB view details)

Uploaded Source

Built Distribution

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

credence_governor_claude_code-0.3.0-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file credence_governor_claude_code-0.3.0.tar.gz.

File metadata

File hashes

Hashes for credence_governor_claude_code-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4fcddb1b683c07f015b6d68e9311f32d9a12d9eb106a33de2af7514ed7c9e570
MD5 f3bbff8f967b8f72639d55e6a91d9c36
BLAKE2b-256 6df621ec367f7006481437f00ed53f6916fe2222ee3e6002fb41e79db41a9230

See more details on using hashes here.

File details

Details for the file credence_governor_claude_code-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for credence_governor_claude_code-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b0faba002c303cf18f341b850cde875d5ae3b8746216cba8fb0683a3511088db
MD5 84e9fe374c1dfe98cb15c5b196e0dcab
BLAKE2b-256 611e75079f9bb82d8088a3e3c3f9969225d4f527bb956adf0fd96fbb226e6f59

See more details on using hashes here.

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