unitares
UNITARES enables self-regulating AI agents to monitor and adjust their behavior in real-time.
Status: live. For architecture details, see docs/UNIFIED_ARCHITECTURE.md and docs/CANONICAL_SOURCES.md.
Most AI agents fly blind: they can't tell when they're thrashing, drifting, or overconfident until a human notices. UNITARES is a runtime layer that lets agents see their own state and regulate themselves — slow down when disorder spikes, ask for review when integrity drops, hand off when they're running on fumes.
Each check-in returns four numbers — EISV: energy, integrity, entropy, valence (the signed energy/integrity imbalance) — plus a verdict, guidance, and calibration. Agents use those numbers to adjust their own behavior before external circuit breakers have to fire. Humans and peer agents read the same state, so one signal serves three consumers: agents regulating themselves, humans watching dashboards, peers coordinating.
Circuit breakers and kill switches are still there — they're just the last line of defense, not the first.
Running continuously in production since November 2025 with 6,200+ passing tests at 77% coverage. Long-run trajectories are stored in PostgreSQL + AGE; the state model is derived from what agents actually do (EMA-smoothed observations, not model predictions).
| What it does | Give agents live readings of their own state (EISV) plus a verdict (proceed / guide / pause / reject), so they can regulate themselves — and share the state with humans and peers through the dashboard and knowledge graph. |
| Workflow | onboard() → process_agent_update() → get_governance_metrics() — details in Getting Started. |
| Transports | MCP on /mcp/ (Streamable HTTP) · REST on /v1/tools/call · Dashboard on /dashboard |
| Stack | Python 3.12+ · PostgreSQL + AGE + pgvector · Redis (optional) |
The self-regulation loop
- Agent acts — tool call, response, decision.
- UNITARES updates state — four numbers that summarize how it's going.
- Agent reads its own state back in the check-in response.
- Agent applies its own policy — proceed, narrow scope, ask for review, or stop.
# Inside the agent's loop
result = process_agent_update(response_text=output, complexity=0.6, confidence=0.8)
if result["metrics"]["integrity"] < 0.4:
agent.require_human_review("integrity low — pausing autonomous actions")
elif result["metrics"]["entropy"] > 0.7:
agent.narrow_scope() # fewer tools, tighter search
elif result["metrics"]["energy"] < 0.2:
agent.stop_and_summarize() # avoid thrashing
The agent reads its own metrics and adjusts before external controls have to fire. Humans see the same state on the dashboard; peer agents read it over the API. UNITARES isn't an output validator (guardrails, evals) or a behavioral sandbox (permissions, container limits) — it's a state layer the agent itself can read.
What makes the signal trustworthy
Self-relative scoring. After ~30 check-ins, the four numbers are graded against your baseline, not a universal threshold. You're flagged when you drift.
Drift from observables, not an ethics oracle. The drift signal comes from calibration accuracy, complexity divergence, coherence, and stability — things the system already measures. No hand-labeled "is this ethical?" classifier.
Trajectory as identity. Long-run EISV patterns answer continuity questions ("still the same agent?") and surface drift no single check-in could see.
Peer review when needed. When an agent's confidence and the system's assessment disagree, UNITARES can run a short adversarial review with peer agents — or with an LLM when no peers are around — before anything halts.
Production snapshot
As of April 2026:
| Metric | Value |
|---|---|
| Agents onboarded | 2,574 total |
| Unique agents active (last 7 days) | 2,226 — mostly ephemeral CLI sessions, plus long-running resident agents |
| Governance events processed | 94,000+ (≈51K in the last 7 days) |
| Knowledge graph discoveries | 578 |
| V operating range | Active agents often within [-0.1, 0.1] |
| Tests | 6,200+ passing · 77% coverage |
Integrating an agent? Jump to Quick Start.
Quick Start
1. onboard() → Get your identity
2. process_agent_update() → Log your work
3. get_governance_metrics() → Check your state
Example check-in (non-mirror responses include full metrics, decision, etc.):
process_agent_update({
"response_text": "Refactored auth module, added rate limiting",
"complexity": 0.6,
"confidence": 0.8,
"task_type": "refactoring",
"response_mode": "mirror" // or: minimal, compact, standard, full, auto
})
response_mode: "mirror" shapes the payload for self-awareness: mirror is a list of strings (actionable signals), not a nested object. Optional top-level question and relevant_prior_work surface a targeted nudge and knowledge-graph items when relevant. See _format_mirror in src/mcp_handlers/response_formatter.py.
{
"verdict": "proceed",
"_mode": "mirror",
"mirror": [
"Fleet calibration: 72% accuracy over 12 fleet-wide decisions (high-conf: 0.8, low-conf: 0.5)",
"Complexity divergence: you reported 0.60 but system derives 0.45 (divergence=0.15)"
],
"question": "What's driving your sense of difficulty?",
"relevant_prior_work": [
{ "summary": "Rate limiter bypass in auth …", "by": "agent-abc", "relevance": 0.82 }
]
}
Verdict field: Responses expose verdict from decision.action. Governance actions are proceed / guide / pause / reject (Architecture). If action is absent, formatters fall back to continue — see response_formatter.py.
The onboard() response includes agent_uuid — store it and pass it to identity(agent_uuid=..., resume=true) on subsequent connections. See Getting Started for alternative entry paths.
Installation
Prerequisites: Python 3.12+, PostgreSQL 16+ with Apache AGE + pgvector (examples use PostgreSQL 17), Redis optional (session cache only).
Full local server (recommended for MCP + HTTP stack):
git clone https://github.com/CIRWEL/unitares.git
cd unitares
pip install -r requirements-full.txt
export DB_BACKEND=postgres
export DB_POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/governance
export DB_AGE_GRAPH=governance_graph
export UNITARES_KNOWLEDGE_BACKEND=age
python src/mcp_server.py --port 8767
Lean dev install (venv, lighter dependency set): use requirements-core.txt and follow CONTRIBUTING.md. Database setup (PostgreSQL 17 + AGE + pgvector): db/postgres/README.md.
The EISV ODE engine ships as the compiled unitares-core package (installed via requirements). See CONTRIBUTING.md for CI and local symlinks.
MCP configuration
Cursor / Claude Code (native type: http):
{
"mcpServers": {
"unitares": {
"type": "http",
"url": "http://localhost:8767/mcp/"
}
}
}
Claude Desktop (via mcp-remote):
{
"mcpServers": {
"unitares": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:8767/mcp/"]
}
}
}
Agents self-identify through onboard(); no hardcoded agent-name header is required.
| Endpoint | Transport | Use case |
|---|---|---|
/mcp/ | Streamable HTTP | MCP clients |
/v1/tools/call | REST POST | CLI, scripts, non-MCP clients |
/dashboard | HTTP | Web dashboard |
/health | HTTP | Health checks |
Security: The server binds to 127.0.0.1 by default. For LAN or remote access, set UNITARES_BIND_ALL_INTERFACES=1 and configure UNITARES_MCP_ALLOWED_HOSTS and UNITARES_MCP_ALLOWED_ORIGINS (comma-separated). See scripts/ops/ for an example plist.
For AI agents: Resident agents: save
agent_uuidfromonboard(), pass it toidentity(agent_uuid=..., resume=true). No token management needed. See docs/guides/START_HERE.md and docs/operations/OPERATOR_RUNBOOK.md.
How state works (EISV)
Agents emit text and tool results; they rarely expose a stable notion of internal condition. UNITARES exposes four continuous variables any client can report and any observer can read:
| Variable | Range | What it tracks |
|---|---|---|
| E (Energy) | [0, 1] | Productive capacity |
| I (Integrity) | [0, 1] | Information coherence |
| S (Entropy) | [0, 1] | Disorder and uncertainty |
| V (Valence) | [-1, 1] | Signed energy/integrity imbalance: energetic-but-incoherent (positive) vs coherent-but-depleted (negative) |
Behavioral EISV (primary, verdict-driving) — Implemented in src/behavioral_state.py and src/behavioral_assessment.py: EMA-smoothed observations per dimension, no ODE and no universal attractor. After ~30 updates, per-agent Welford baselines enable self-relative scoring (z-score vs your operating point). Earlier check-ins use bootstrap behavior; absolute safety floors still apply.
ODE in governance_core (secondary, diagnostic/fallback) — The same four variables also evolve in a coupled ODE with contraction-style stability analysis. That integration runs in parallel for analysis; governance verdicts normally follow behavioral EISV once behavioral confidence is established, while ODE remains the fallback when behavioral confidence is still insufficient. See Architecture for the full pipeline (drift → entropy, calibration, circuit breaker, dialectic).
dE/dt = α(I - E) - β·E·S Energy tracks integrity, dragged by entropy
dI/dt = -k·S + β_I·C(V) - γ_I·I Integrity boosted by coherence, reduced by entropy
dS/dt = -μ·S + λ₁·‖Δη‖² - λ₂·C Entropy decays, rises with drift, damped by coherence
dV/dt = κ(E - I) - δ·V Valence accumulates E-I mismatch, decays toward zero
</details>
Architecture
graph LR
A[AI Agent] -->|check-in| M[MCP Server :8767]
M -->|observations| BS[Behavioral EISV]
BS -->|verdict + guidance| M
M -->|parallel diagnostic| UC[unitares-core ODE]
UC -.->|analysis only| M
M -->|verdict + guidance| A
M <-->|state, audit, calibration| PG[(PostgreSQL + AGE)]
M <-->|knowledge graph| PG
M -.->|session cache| R[(Redis)]
M -->|web UI| D[Dashboard]
style BS fill:#1a5c1a,stroke:#666,color:#fff
style UC fill:#2d2d2d,stroke:#666,color:#fff
Use cases: Fleet monitoring and early warning, inter-agent state observation, trajectory-based identity and continuity, outcome-calibrated confidence tracking, dialectic peer review, persistent knowledge graph with staleness awareness.
Documentation
| Guide | Purpose |
|---|---|
| Getting Started | Setup, workflows, tool modes |
| Architecture | Pipeline, verdicts, recovery, storage |
| Case Study | Project summary and context |
| Troubleshooting | Common issues |
| Dashboard | Web UI |
| Database | PostgreSQL + AGE |
| Contributing | Development setup, testing, style |
| Changelog | Releases |
Paper
UNITARES v6 — Information-Theoretic Governance of Heterogeneous Agent Fleets. Framework + migration paper (30 pages, latest: paper-v6.8.1). Reframes EISV in Shannon + variational free-energy terms, presents class-conditional calibration as a first-class design constraint, and documents the pipeline-ordering migration mechanism used to re-ground the live system. Headline empirical finding: a 13,310-row verdict counterfactual shows 28.9% of governance basin assignments flip under class-conditional grounded coherence relative to the legacy fleet-wide form, with a strong directional bias into the low basin — direct empirical support for the homogenization-failure-mode argument. Concept DOI: 10.5281/zenodo.19647159 (resolves to latest version; each tagged release has its own version DOI).
Related Projects
- Lumen / anima-mcp — Embodied agent on Raspberry Pi
- unitares-discord-bridge — Discord presence and governance events
- eisv-lumen — Governance benchmark (21K trajectories on HuggingFace)
Installable client adapters for Codex and Claude live in the companion unitares-governance-plugin repo. This unitares repo is the governance server/runtime; any plugin-side .codex-plugin/, hooks/, skills/, and commands/ content should be treated as belonging to the companion adapter repo, not as canonical copies here.
MIT (server, dashboard, tooling) — see LICENSE. The ODE dynamics engine ships as a compiled dependency (unitares-core); see CONTRIBUTING.md.
Built by @CIRWEL