Independent · Single-operator · Est. 2025


CIRWEL Research

— The working path

Build on it.

Four steps: run the server, point a client at it, run the check-in loop, and decide what to do with what comes back. There is no account, no hosted tier, and no outbound call. The install is a Compose file on hardware you control.

The home page states the problem and the ecosystem page describes the architecture. This page is the part you type. What the instrument has and has not been shown to do is in §05, and in full on the research page.


— What you need

Server
CIRWEL/unitares · Apache 2.0 · Docker Compose
Endpoint
http://localhost:8767/mcp/ · Streamable HTTP · REST at /v1/tools/call
Contract
unitares-sdk · for agents you write yourself
Runtime
Python 3.12+ · PostgreSQL with AGE and pgvector · Redis · optional Elixir/OTP coordination
Suited to
one operator running several long-lived agents on their own infrastructure. Usually not worth the overhead for short-lived chat turns.

§01 — Run the server

One compose file, on your own machine.

Self-hosted by design. Identity, telemetry, evidence, and policy history never leave it.

$ gh repo clone CIRWEL/unitares && cd unitares && docker compose up -d --wait

That brings up PostgreSQL with AGE and pgvector, Redis, the lease plane, and the server on loopback. MCP clients connect at localhost:8767/mcp/, the self-hosted dashboard is at /dashboard, and /health answers for readiness checks.

The repository README pins the latest verified release tag. Clone that tag instead of the default branch if you want a fixed checkout; the source version can run ahead of it.

Then watch it move

$ make demo onboards a process, sends six governed check-ins
$ make coordination-demo two agents contend for one surface and hand it off

The second one is the identity guarantee biting rather than being described: governance exchanges each agent's continuity credential for a single-use, request-bound attestation, refuses one agent's attestation when it claims the other's identifier, refuses a captured attestation on replay, and moves a governed surface through an identity-checked handoff before releasing it.

§02 — Connect a client

Client-neutral at the boundary.

Any client that speaks Streamable HTTP MCP can connect. Nothing about the server assumes a model vendor.

The same server answers Codex, Claude Code, Cursor, Goose, Hermes, hosted connectors, and custom hosts. Add it the way that client adds any HTTP MCP server:

{
  "mcpServers": {
    "unitares": {
      "type": "http",
      "url": "http://localhost:8767/mcp/"
    }
  }
}

A client without native HTTP support bridges through stdio. Claude Desktop is the usual case:

{
  "mcpServers": {
    "unitares": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8767/mcp/"]
    }
  }
}

No agent-name header is configured anywhere. The agent identifies itself in its first call, which is the point: a name in a config file is a label, and a label is not an identity.

Non-MCP callers post to /v1/tools/call instead. For Codex and Claude Code, session lifecycle and hooks are packaged separately as unitares-governance-plugin.

§03 — Run the loop

Four calls, and a decision that stays yours.

session = start_session(force_new=True)
sid = session["client_session_id"]

result = sync_state(
    response_text=output,
    complexity=0.6,
    confidence=0.8,
    client_session_id=sid,
)
if result.get("state_summary", {}).get("action") == "pause":
    return_to_operator(result.get("next_action"))

record_result(
    outcome_type="test_passed" if tests_passed else "test_failed",
    prediction_id=result.get("prediction_id"),
    client_session_id=sid,
)
state = check_working_state(client_session_id=sid)
  1. Identify

    start_session

    Binds every later write to this process instance. A fresh process mints fresh identity; continuity across a restart is declared, never inferred from a reused display name.

  2. Claim

    sync_state

    Records what the process says it did, and how confident it is. Returns a policy action of proceed, guide, or pause, always with a named reason and a next step.

  3. Ground

    record_result

    Attaches the real outcome to the claim that predicted it, through the check-in's own prediction_id. Skip this call and the state estimate is self-report with extra steps.

  4. Read

    check_working_state

    Reads the current verdict without writing anything.

Treat the action, the reason, and the next step as the stable contract; the enforcement record rides alongside them. A pause on a governed write surface refuses that agent's later check-ins until recovery succeeds. Everything your agent does outside those surfaces is a boundary you honor, not one the server can close for you, and the page that says otherwise is selling something.

A default profile advertises the checkpoint loop, shared memory, structured review, advisory consultation, and recovery. GOVERNANCE_TOOL_MODE narrows that to the loop alone or widens it to the full surface. The profile decides what discovery advertises, never what dispatches, but schema-driven clients only offer a model what discovery returned, so an unadvertised tool is unreachable in practice.

§04 — Build a resident

The contract is a package, not our repository.

$ pip install unitares-sdk

For an agent that runs for weeks rather than minutes, the SDK handles connection, identity, check-ins, heartbeats, and knowledge participation. Preserve its identity anchor across restarts with identity(agent_uuid=...) rather than minting a new one each run, or its history restarts with it.

A workload registers its own progress source through the unitares.resident_progress_sources entry-point group, with no change to the server's repository at all. That is the whole plug-and-play claim, and it is the strongest one on this site because it is the only one that says you never have to touch our code.

The lowercase agents in the server repository are reference clients and operational examples. They are built on it and are explicitly not part of it, so read them as worked examples rather than a framework to subclass. CIRWEL/unitares-resident is the first-party userland on the same public contract; it is an early skeleton, not yet a usable general-purpose agent.

§05 — What it does not do

A state instrument, not an outcome oracle.

UNITARES does not decide whether an output is correct or ethical, and it cannot detect deliberate concealment without independent evidence. A process capable enough to optimize against a monitored proxy can do so.

No governed-versus-ungoverned comparison has yet shown an incident prevented or an outcome improved. The circuit breaker demonstrably actuates. That it protects anything is untested, and adopting this software on the strength of a benefit claim would mean adopting it on a claim nobody has established.

It also replaces nothing you already run:

Evals

between runs

Is this model good enough for a defined task?

Guardrails

per action

Is this action allowed, and is it contained?

UNITARES

continuously

What has this running process been doing, what evidence supports its claims, and what state is it in now?

Every deployment number this site publishes comes from one operator's own fleet, where most of the governed agents are also the ones building the system. The research page keeps the open questions, the withdrawn results, and the pre-registered read that will settle one of them.