Hivemind runs attested recall agreements between mutually distrusting parties. An owner defines the room rules and contributes private data plus a scope agent; a participant verifies those rules and the running enclave before asking through a fixed query agent or bringing their own. Only the room-approved output leaves the enclave.
Use hmctl to create verifiable rooms, share scoped data access, run sealed
query agents, and bill tenant usage without making the data owner trust the
querying party.
What you can do:
- create signed room invites with inspectable or sealed agents;
- verify live dstack CVM attestation before presenting data or prompts;
- let participants bring their own query agent while preserving room rules;
- meter usage, grant tenant credit, and enforce prepaid balances.
Requires Python 3.11+, uv, Docker for agent builds/runs, and Postgres for
local development.
For regular CLI users, install the CLI into uv's isolated tool environment:
uv tool install hmctl
hmctl --versionThe package installs two equivalent commands: hmctl for the short public CLI
name, and hivemind for existing scripts.
To test an unreleased checkout directly from GitHub:
uv tool install --upgrade git+https://github.com/teleport-computer/hivemind-core.git
hmctl --versionTo upgrade later:
uv tool upgrade hmctlFor repo development, use an editable install from the checkout:
uv tool install --editable .
hmctl --helpJoin an existing room:
hmctl profile use my-tenant
ROOM='hmroom://...'
hmctl room inspect "$ROOM"
hmctl doctor "$ROOM"
hmctl room inspect "$ROOM" --json | jq '.room.manifest'
hmctl room accept "$ROOM"
hmctl balance
hmctl -y room ask "$ROOM" "What changed this month?"room inspect shows the signed room spec and live attestation summary; use
--json to inspect the full manifest. doctor ROOM checks the CLI version,
active profile, service auth, billing balance, room trust, and local room
acceptance in one place. room accept records the verified manifest hash for
this local profile; if you skip it, the first room ask prompts before sending
your question. -y does not accept room manifests.
--dangerously-skip-attestations bypasses both attestation checks and this
first-use manifest acceptance gate. room ask defaults to --timeout 900,
--max-llm-calls 60, and --max-tokens 1000000.
Hosted deployments can clamp requests lower than what you ask for; the current
Phala deployment caps runtime at 900s, LLM calls at 100, and tokens at 1000000.
For invite-token room asks, the CLI bills the active hmk_ tenant profile
automatically. The room token still controls what data can be read; the active
tenant credential controls whose credits pay for the scope/query/mediator run.
To use a different tenant, switch profiles or pass --profile NAME before the
command.
Create a fixed-query room and share the printed invite:
hmctl room create ./scope-agent \
--name example-room \
--query-agent ./query-agent \
--mediator-agent ./mediator-agent \
--allowed-table watch_history \
--scope-visibility inspectable \
--query-visibility inspectable \
--rules-file rules.md \
--trust-mode owner_approvedThe rules file is plain text; Markdown is conventional because humans read
and sign it. The same text is used as the scope/mediator policy unless
--policy-file is passed. Use YAML only if your own agents are written to
interpret YAML.
--allowed-table signs the SQL data sources the room may access. Omit it only
for rooms that should have no SQL table access and rely on room-vault data.
Connect a local profile to a deployed service:
hmctl init --service https://hivemind.example --api-key hmk_...
hmctl trust attest --reproduceIf the hosted service has self-serve signup enabled, users can create their
own tenant key with a $0.00 starting balance. Admin-issued credit codes can
be redeemed later when you want to add prepaid credit:
hmctl --profile alice signup alice --service https://hivemind.example
hmctl redeem-credit 'hmcc_...'Admins mint credit codes with tracked max uses and expiry:
hmctl admin credit-codes create --credit 3.00 --uses 1 --expires-in 7d
hmctl admin credit-codes list
hmctl admin billing accounts
hmctl admin billing ledger
hmctl admin tenants reset-key t_... --clear-seal --revoke-capabilitiesOperator switches:
HIVEMIND_SELF_SERVE_SIGNUP_ENABLED=true
HIVEMIND_BILLING_ENFORCE_CREDITS=trueCredit codes are not signup codes: signup is open when enabled, and credit is
added only through hmctl redeem-credit or the credit-code redemption API.
For local development:
./scripts/quickstart.sh
hmctl init --service http://localhost:8100 --api-key hmk_...For copy-paste room setups, see the room cookbook.
Active agent evaluation lives in eval/. It is room-native and
starts with deterministic checks for leakage, output shape, latency, tool
calls, tokens, and cost. The old GAN-style benchmark is archived under
autoresearch/legacy_bench/ for historical
context only; do not use it as the optimization target for new agents.
owner data + scope agent participant question or query agent
\ /
\ /
signed room manifest
|
dstack CVM attestation
|
scope agent builds the data boundary
|
query agent receives scoped tools
|
pinned mediator audits the answer
|
signed, room-approved output
A signed room is the runtime agreement. Its manifest binds:
- the scope agent and whether its source is inspectable or sealed;
- the query mode: fixed query agent or participant-uploaded query agent;
- query-agent and mediator-agent visibility:
inspectableorsealed; - the pinned mediator agent when one is configured;
- output visibility;
- allowed LLM providers and artifact egress;
- deployment trust policy.
The service is designed for a dstack Confidential VM. Both parties verify the live CVM attestation before presenting data, invite tokens, or agent code.
Important restart property: room data and room-uploaded sealed query agents are encrypted under a per-room key wrapped to the owner key and invite token. After a restart or backend update, private room material stays unreadable until an owner or participant presents a valid room credential again.
- Protects against: the counterparty reading raw data or agent source beyond the signed room policy; backend updates changing execution without observable attestation; a restarted backend reading sealed room material before a valid room credential is presented.
- Does not protect against: a party's own agent or allowed output revealing what that party is authorized to learn; bad room rules that the participant accepts; bugs in the trusted computing base, TEE, cryptography, or agent sandbox.
- You trust: dstack/TDX attestation, the measured CVM image accepted by the room trust policy, the owner signing key in the invite link, and the local client verification path.
Clean rooms are usually data-first and administrator-driven. Agent frameworks usually assume one trust domain. Hivemind is for the gap between them: two parties want an agent-mediated answer, neither party wants to reveal raw material to the other, and both need to verify the computation before any private input is read.
The design follows the conditional-recall framing from NDAI: Non-Disclosure Agreements for AI: let an AI system use private context for a bounded purpose, then constrain what can be recalled outside that purpose. See the mental model for the room data flow and the scope/query agent relationship.
An agent upload is a local directory or .tar.gz archive with a Dockerfile
and source files. The simplest shape is:
agent-dir/
|-- Dockerfile
`-- agent.py
A scope agent defines the room's data boundary. A query agent performs the participant's task through scoped tools. Examples live in:
agents/default-scope-hermes/agents/default-query-hermes/agents/default-mediator-hermes/agents/default-scope/agents/default-query/agents/default-mediator/agents/examples/simple-query/agents/examples/tiktok-analytics/
Canonical flow: create a signed room, add private data, and share the invite.
hmctl room create ./scope-agent \
--mediator-agent ./mediator-agent \
--allowed-table watch_history \
--rules-file rules.md
hmctl room add-data <room_id> --file dataset.md --meta source=dataset
hmctl room data <room_id>The create command prints one hmroom://... invite link. That link contains
the room id, invite token, service URL, and owner signing public key.
Common room variants:
# Owner pre-loads the query logic; participant only supplies the question.
hmctl room create ./scope-agent \
--query-agent ./query-agent \
--mediator-agent ./mediator-agent \
--allowed-table watch_history \
--rules-file rules.md
# Participant can upload their own query agent for this room.
hmctl room create ./scope-agent \
--mediator-agent ./mediator-agent \
--query-visibility sealed \
--allowed-table watch_history \
--rules-file rules.mdVisibility modes:
inspectable: participants can read extracted source files, pin digests, and see stored prompts for room runs.sealed: participants see metadata and digests, but source bytes are encrypted and are not served through the files API. Run prompts are not stored as plaintext; signed run attestations still include the prompt hash.
Dynamic scope/query/mediator rooms need an allowed LLM provider. Room creation
defaults to OpenRouter egress; repeat --llm-provider if you intentionally
want to allow additional providers. --no-llm is only an egress-deny policy
for pinned agents that do not call LLM endpoints.
Canonical flow: inspect the agreement, ask the question, and verify the attested output.
hmctl room inspect 'hmroom://...'
hmctl room inspect 'hmroom://...' --json | jq '.room.manifest'
hmctl room accept 'hmroom://...'
hmctl room ask 'hmroom://...' "What changed this month?"Bring a query agent to an uploadable room:
hmctl room ask 'hmroom://...' "What changed this month?" \
--agent ./my-query-agentroom accept saves the verified manifest hash for the active local profile.
Without it, the first room ask displays the manifest summary and asks for
confirmation before sending the prompt. Every answer is checked against the
accepted room manifest hash and the live CVM run signer. The default behavior
is fail-closed when the run attestation is missing or does not match the room.
Ask defaults are sized for dynamic room agents: --timeout 900,
--max-llm-calls 60, --max-tokens 1000000, and --memory-mb 256.
Hosted services may still clamp lower. For small deterministic agents, pass
smaller explicit budgets when you want a tighter cost/latency envelope.
If the service has billing enabled, invite-token room asks are charged to the
active hmk_ tenant profile. Use hmctl profile use NAME or pass
--profile NAME before the command to choose which tenant API key pays. The data
owner does not pay for participant queries unless the owner is the caller.
Rooms have one deployment trust policy:
operator_updates: trust the operator's governance process to approve enclave upgrades.pinned: trust only the exact compose hashes accepted at room creation.owner_approved: trust the room owner to maintain this room's compose-hash allowlist.
Update a room trust allowlist without changing the invite link:
hmctl room trust <room_id> --mode owner_approved --approve-liveBulk cleanup is dry-run first. Keep current invite links explicitly:
hmctl room prune --name-prefix watch-history- --keep room_...
hmctl -y room prune --name-prefix watch-history- --keep room_... --no-dry-runProduction HTTPS clients require DCAP quote verification and TLS pinning by
default. hmctl trust attest --reproduce walks the source chain from the
attested compose hash to the registered compose source and any deterministic
deploy render hints. The global --dangerously-skip-attestations flag is an
explicit bypass for tenants or operators who choose not to perform client-side
attestation for a command.
The public API is room-first:
Room lifecycle
GET /v1/healthz
GET /v1/health
GET /v1/whoami
GET /v1/attestation
GET /v1/admin/schema
POST /v1/rooms
GET /v1/rooms
GET /v1/rooms/{room_id}
GET /v1/rooms/{room_id}/attest
GET /v1/rooms/{room_id}/key
POST /v1/rooms/{room_id}/open
POST /v1/rooms/{room_id}/trust
DELETE /v1/rooms/{room_id}
Room contents and execution
POST /v1/rooms/{room_id}/data
GET /v1/rooms/{room_id}/data
POST /v1/rooms/{room_id}/runs
POST /v1/rooms/{room_id}/query-agents
Agent inspection
POST /v1/room-agents
GET /v1/room-agents
GET /v1/room-agents/{agent_id}
DELETE /v1/room-agents/{agent_id}
GET /v1/room-agents/{agent_id}/attest
GET /v1/room-agents/{agent_id}/files
GET /v1/room-agents/{agent_id}/files/{path}
Observation
GET /v1/runs
GET /v1/runs/{run_id}
GET /v1/runs/{run_id}/artifacts/{filename}
Tenant trust
POST /v1/tenant/rotate-key
POST /v1/tenants/compose-pin
GET /v1/tenants/compose-pin
GET /v1/tenants/compose-pin/list
DELETE /v1/tenants/compose-pin/{pin_id}
Billing/admin
POST /v1/signup
GET /v1/billing
POST /v1/billing/credit-codes/redeem
POST /v1/admin/tenants
GET /v1/admin/tenants
DELETE /v1/admin/tenants/{tenant_id}
POST /v1/admin/tenants/{tenant_id}/reset-key
POST /v1/admin/tenants/register
POST /v1/admin/rename-database
POST /v1/admin/migrate-to-roles
POST /v1/admin/agents/sweep-broken
GET /v1/admin/billing
GET /v1/admin/billing/ledger
GET /v1/admin/billing/{tenant_id}
POST /v1/admin/billing/{tenant_id}/credits
GET /v1/admin/credit-codes
POST /v1/admin/credit-codes
POST /v1/admin/credit-codes/{code_id}/revoke
GET /v1/admin/billing/prices
POST /v1/admin/billing/prices
GET /v1/admin/llm-probe
Lower-level SQL, token, and generic agent endpoints are internal implementation details. New clients should use the room API only.