Open-tier governance wrapper for enterprise AI agents
Project description
sentience-governor
See exactly what your AI agents did, why they did it, and where they crossed boundaries — in real time.
Install → run → see your first trace in under 2 minutes.
sentience-governor is the open-tier governance wrapper for AI agents. It intercepts agent tool calls at the execution boundary, evaluates them against a default policy set, and produces a structured local trace.
It does this without modifying agent behavior, without blocking execution, and without sending anything anywhere automatically.
Status: v0.2.2. Apache 2.0 licensed. Runtime + Sentience Sync CLI + live production sync endpoint at
https://sync.getsentience.ai/v1. Full test suite (385 tests) + golden-trace coverage + per-commit acceptance gate against live prod.
Simple mental model
Session = one run of an agent Event = one action inside a session Trace = all events in a session
What it does
- Captures agent tool calls at the execution boundary
- Emits structured governance events
- Evaluates each event against five default policy rules
- Produces local traces you can inspect
- Shows what the paid control plane would have done, without blocking anything
What it does not do
- Does not block or modify agent execution in the open tier
- Does not send telemetry, licensing checks, or data automatically
- Does not persist data across sessions
- Does not require a Sentience account, API key, or network connection
- Does not classify data unless classification is provided by the integration
Install
Requires Python 3.10+.
pipx install sentience-governor
That installs the four CLIs (sentience, sentience-cli, sentience-sync, sentience-claude-code-hook) into an isolated environment and exposes them on your $PATH.
If you don't have pipx: brew install pipx on macOS, or python3 -m pip install --user pipx on Linux. Then pipx ensurepath and restart your shell.
If you're integrating Sentience as a library inside your own virtualenv (MCP wrapper, LangChain callback, or your own Python code), pip install sentience-governor works fine inside an active venv.
No account. No signup. No API key.
Start here: first trace
If you use Claude Code, this is the fastest path.
-
Install:
pipx install sentience-governor
-
Add the Claude Code hook config shown in the Quickstart (Claude Code hook) section below.
-
Run Claude Code normally.
-
Review the latest trace:
sentience open --latest --summary
You should see:
- A session listed
- Events captured
- A summary explaining what happened
If you see nothing, run:
sentience status
sentience list
Commands
Most used commands
sentience open --latest --summary # see what happened
sentience list # see recent sessions
sentience status # confirm the hook is capturing
sentience-sync run # optional: upload aggregated counts
Installing the package registers four CLI entry points. Skim this table before reading further; pick the one that matches what you're doing.
| Command | Use it when… | Details |
|---|---|---|
sentience |
reviewing an agent-hook session trace (Claude Code today; more coming). Curated, signal-first output. | sentience status / sentience list / sentience open [--latest | <id>] [--summary] |
sentience-cli |
inspecting a library trace (MCP wrapper / LangChain handler) or a golden-trace fixture. Raw, full-fidelity. | sentience-cli <file> / my-agent | sentience-cli |
sentience-claude-code-hook |
invoked by Claude Code via .claude/settings.json. Not run directly by operators. |
Reads JSON on stdin, emits governance events, exits 0. |
sentience-sync |
opting in to send aggregated rule-fire counts to Sentience Cloud. Manual, explicit, one run at a time — never automatic. Requires --email and --name on first register. |
sentience-sync init / register --email ... --name ... / run / status / update-check |
sentience subcommands (agent-hook viewer):
| Subcommand | What it does |
|---|---|
sentience status |
Is the hook capturing sessions? Prints the trace path and last session. |
sentience list |
One line per session, newest first, max 20. |
sentience open --latest |
Full curated render of the most recent session (Summary / Focus / Notes / Key Events / Full Trace / Footer). |
sentience open --latest --summary |
Same render, minus the Full Trace block — fits one terminal screen. |
sentience open <session_id> |
Render a specific session by id or prefix. |
Two-CLI discipline: sentience-cli and sentience exist on purpose. They serve different audiences (library integrators vs agent-hook operators) with different trace shapes (10–50 events vs hundreds).
Quickstart (Claude Code hook)
If you're using Claude Code, governance is a four-line settings block — no code changes. Drop this into .claude/settings.json (project-local) or ~/.claude/settings.json (user-global):
{
"hooks": {
"PreToolUse": [
{"matcher": "", "hooks": [{"type": "command", "command": "sentience-claude-code-hook"}]}
],
"PostToolUse": [
{"matcher": "", "hooks": [{"type": "command", "command": "sentience-claude-code-hook"}]}
]
}
}
Every Claude Code tool call now emits a governance event. Per-session traces land at ~/.sentience/traces/claude-code/<session_id>.jsonl by default. Fail-open, observe-only, no credentials.
Known blind spot: Bash commands are captured at the tool-call boundary but the shell command string itself is not parsed (the hook sees Bash(cmd='...'), not what the shell ultimately resolves).
Review what Claude Code actually did with the curated sentience CLI:
sentience status # did the hook fire? yes / no
sentience list # what sessions exist
sentience open --latest --summary # curated view of the latest session, one screen
This is the main first-value path for operators.
Quickstart (MCP client wrapper)
wrap_mcp_client() targets an internal MCPClientLike protocol. To wrap a concrete MCP SDK client, adapt it through SentienceMCPAdapter — the adapter keeps the wrapper free of any SDK-specific method names.
from sentience_governor.cache.cache import InProcessCache
from sentience_governor.session_manager.manager import SessionManager
from sentience_governor.sink.writer import SinkWriter, StdoutSink
from sentience_governor.wrapper.mcp import (
SentienceMCPAdapter,
wrap_mcp_client,
)
# Shared per-process collaborators.
session_manager = SessionManager()
cache = InProcessCache()
sink = SinkWriter(StdoutSink())
# Adapt your SDK client to the MCPClientLike protocol.
# `call_fn(delegate, tool_name, arguments) -> dict` is the only SDK-aware bit.
adapted = SentienceMCPAdapter(
delegate=your_sdk_client,
call_fn=lambda client, name, args: client.call_tool(name, args),
)
wrapped = wrap_mcp_client(
target=adapted,
session_manager=session_manager,
cache=cache,
sink_writer=sink,
agent_id="my-agent",
agent_version="1.0.0",
vendor_id="my-company",
declared_capabilities=["crm.read"],
owner_claim="user_123",
stated_objective="Generate Q1 customer report",
)
async with wrapped:
result = wrapped.send_tool_call("crm.get_customer", {"id": "123"})
Integration consists of three steps: import Sentience, assemble the collaborators, wrap the client.
Quickstart (LangChain-based agent)
Attach SentienceCallbackHandler as a callback. It duck-types the LangChain BaseCallbackHandler interface, so no hard dependency on langchain-core at import time.
from sentience_governor.cache.cache import InProcessCache
from sentience_governor.session_manager.manager import SessionManager
from sentience_governor.sink.writer import SinkWriter, StdoutSink
from sentience_governor.wrapper.langchain_adapter import SentienceCallbackHandler
session_manager = SessionManager()
cache = InProcessCache()
sink = SinkWriter(StdoutSink())
handler = SentienceCallbackHandler(
agent_id="my-agent",
session_manager=session_manager,
cache=cache,
sink_writer=sink,
agent_version="1.0.0",
declared_capabilities=["crm.read"],
owner_claim="user_123",
)
agent.invoke(
{"input": "Generate Q1 customer report"},
config={"callbacks": [handler]},
)
If you are building with create_react_agent and prefer the middleware integration path, SentienceMiddleware wraps the same handler and plugs in via the middleware= keyword. It is observe-only in v0 — it never blocks.
from sentience_governor.wrapper.langchain_adapter import SentienceMiddleware
middleware = SentienceMiddleware(handler)
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt, middleware=[middleware])
Control points
sentience-governor wraps your agent's execution boundary and emits structured governance events at five control points:
- AGENT_REGISTERED — who is acting
- INTENT_DECLARED — what they are trying to do
- SCOPE_ASSERTED — what tool they are calling and why
- CONTEXT_SNAPSHOT — what data is in their context
- MEMORY_WRITE_ATTEMPT — what they are trying to persist
A sixth event type, GOVERNANCE_ERROR, is emitted by the runtime itself when an internal fault occurs (sink unavailable, schema violation, intercept failure, timeout). It is always routed to stdout regardless of the configured sink, and never interrupts the agent.
View your trace
For Claude Code sessions:
sentience open --latest --summary
For raw library traces:
sentience-cli path/to/agent.jsonl
Use sentience for high-volume agent-hook sessions. Use sentience-cli for full-fidelity library traces.
Default policy rules
| Rule | What it checks |
|---|---|
| POL-001 | Agent must declare intent before executing mutating operations |
| POL-002 | Agents must be registered before accessing tools |
| POL-003 | Data entering context must be classified |
| POL-004 | Memory writes must carry classification and retention policy |
| POL-005 | Sensitive data must not escalate in context without explicit authorization |
All five rules are evaluated on every session. Violations are surfaced and simulated — never enforced in the open tier.
Sinks
Three sinks are shipped. Pick one at construction time and pass it to SinkWriter.
| Sink | Use |
|---|---|
StdoutSink |
Default. One JSON object per line to stdout. Pipe into sentience-cli. |
FileSink |
Append newline-delimited JSON to a file path. |
HttpLocalSink |
POST each event as JSON to a local URL. 500 ms timeout, no retry. Loopback only. |
Failure semantics are uniform across sinks:
- Writes are synchronous, unbuffered, and never retried.
- On failure, the event is dropped and a
GOVERNANCE_ERRORis routed to stdout. - Severity escalates per session: 1 failure →
warning, 3 consecutive →degraded, remainder of the session →criticalon close. - The agent is never blocked.
Sentience Sync
Optional. Manual. Sends only aggregated counts — never raw events, tool arguments, tool responses, or payloads.
Sentience Sync is the opt-in feedback channel between your installation and Sentience Cloud. It is how both sides learn:
- For you (the operator): is my policy working? are my agents actually hitting the rules I care about? is my installation running the version I think it is?
- For Sentience (the maintainer): which policies fire in the wild, at what frequency, across which runtime versions? Signals that inform the next release.
It is completely opt-in. Installing the runtime sends nothing. Wrapping an agent sends nothing. Events land in local trace files on your machine only. Sync transmits anything to Sentience Cloud only when you explicitly run sentience-sync register and then sentience-sync run.
Why it exists
Sync gives operators a lightweight roll-up of policy activity and update notices for their installed runtime version. It also gives maintainers aggregate signal about which rules fire in real deployments.
It never auto-applies updates and never changes runtime behavior.
What Sentience Cloud sees
Every sentience-sync run POST contains only:
installation_idruntime_versionwindow_start/window_endcounts_by_rule
Sentience Cloud never sees raw event content, agent IDs, user IDs, tool names, arguments, responses, payloads, source code, logs, or business context.
Registration additionally collects email and name because Sync is the update/support channel. organization and operator_role are optional.
Safety
Built for unattended runs. Failure is safe.
- No state advancement on failed uploads — failed runs retry from the same offset, no data loss.
- Logs are always the source of truth.
- Duplicate runs are idempotent (server returns
duplicate=true, CLI exits 0).
CLI
sentience-sync init
sentience-sync register --email you@example.com --name "Your Name"
sentience-sync run # default
sentience-sync status
sentience-sync aggregate
sentience-sync update-check
Exit codes: 0 success · 1 config · 2 network · 3 not registered · 4 server · 5 state.
Config
{
"endpoint": "https://sync.getsentience.ai/v1",
"log_sources": ["/var/log/sentience/agent.jsonl"],
"report_geo": false
}
Precedence: CLI > env > file > defaults.
The default endpoint is live. Use SENTIENCE_SYNC_ENDPOINT or the endpoint field in your config to point at a different target.
Boundary
- Runtime has zero dependency on Sync — enforced in tests across the codebase.
- Sync cannot influence execution or policy.
- Uninstalling Sync (deleting the
sentience_syncdirectory) does not affect the runtime.
Upgrade to enforcement
The open tier answers: what happened. The paid control plane adds enforcement: what should be blocked, narrowed, paused, or escalated.
Real enforcement — block, narrow, scope contraction, pause — and organisational memory across sessions and agents are paid control-plane capabilities.
License
Apache 2.0. See https://www.apache.org/licenses/LICENSE-2.0.
Copyright 2026 Crescere Labs, Inc.
Sentience — Crescere Labs, Inc.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sentience_governor-0.2.2.tar.gz.
File metadata
- Download URL: sentience_governor-0.2.2.tar.gz
- Upload date:
- Size: 99.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1daad6c7a4f51058708d80e4e0a097700308114c2493d9a85b0ddbeebcdee477
|
|
| MD5 |
2b4680970d8d424d3861fdc373bb59bd
|
|
| BLAKE2b-256 |
5b6773a35c818d41cd9bcba29025d53801c1521424b3ec05c416d87993859e71
|
File details
Details for the file sentience_governor-0.2.2-py3-none-any.whl.
File metadata
- Download URL: sentience_governor-0.2.2-py3-none-any.whl
- Upload date:
- Size: 103.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85c5d0b97dbffa1af299aafee1178ed0c421c83e015edf0d59944968faa67294
|
|
| MD5 |
20327d15f975b9c4788bd57b0e87c281
|
|
| BLAKE2b-256 |
ab430f4ee5d07b259cf0dd6c97e79623eacd93874cc8c839cd2df660674fdd54
|