Skip to content
Agents of Humanity
Public preview. Results are preliminary (criteria v1.0, 30 Sept 2026). Tell us what we got wrong
Open sourceself-hostedMIT

nanobot

HKUDS · github.com/HKUDS/nanobot

nanobot is an MIT-licensed, self-hosted Python agent runtime that keeps all agent state in local files and sends nothing to its maintainers, which gives it strong exit, provider-independence and no-unilateral-change results. Its main gaps are auditability (no complete, tamper-evident or agent-protected action record), control (no approval gates, no per-recipient or per-domain limits, and in the default full-access mode the agent can edit its own config), and the lack of export, full-deletion and build-provenance tooling.

Strengths
  • Local-first state with no provider account or hosted store (P2, P5, T3)
  • No telemetry and nothing held by the provider (T3)
  • No auto-update or remote flags; owner-initiated upgrades only (M5)
  • Single command stops all local agent activity (C3)
Gaps
  • Action record incomplete, prunable, unsigned and writable by the agent by default (A1, A2, A3)
  • No owner approval gates, and limits the agent can edit away in default mode (C1, C2)
  • No export/import command and no full-deletion command (P1, C6)
  • Unattested PyPI wheels with a prebuilt TUI binary; memory-only change history (V1, V3)
Evidence

All 26 findings

Release tag v0.3.5, commit 1bb712d3488915ca4ed9ccc1a93067ff722f5ab9 (2026-09-15); main was at 678cd8f4 on the evaluation date. Platform: Linux/macOS/Windows Python 3.11+ package with bundled WebUI and native TUI. Default configuration per nanobot/config/schema.py. Desk review only; evaluated 2026-09-30.

Portable · Can you leave, take the whole agent with you, and keep it alive?

70%
  • P1
    Owner-usable round trip

    No export/import command exists. State is plain local files under ~/.nanobot (config, workspace, sessions) that the owner can copy at any time without approval, but restoring on another machine means reinstalling nanobot and moving folders by hand (one shortfall: restore is not a single documented action).

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Ship a `nanobot export` / `nanobot import` pair (or WebUI equivalent) that bundles config, workspace, sessions and all OAuth token files
    • Document a one-step move-to-another-machine procedure
    Partial
  • P2
    Complete export

    All agent state (config and credentials, instructions, Markdown memory with its source history, session JSONL, cron jobs and triggers, skills, plugins, files, channel sessions) is on the owner's disk, and HKUDS holds nothing. OAuth integrations re-link through the model vendors' own clients or MCP dynamic client registration, not an HKUDS-registered client; Codex and Copilot token files sit outside ~/.nanobot but can be recreated by logging in again.

    Pass
  • P3
    Runs without the provider

    The runtime is MIT-licensed and needs no HKUDS account, licence key, relay or telemetry, so the core agent runs with HKUDS unreachable. The CLI Apps capability (on by default) resolves apps through a hard-coded, HKUDS-hosted catalog (hkuds.github.io/CLI-Anything/registry.json) that the owner cannot repoint; without it or a cached copy, installing and running CLI Apps fails.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Make the CLI Apps catalog URL owner-configurable
    • Let installed CLI Apps run from their local install record without a catalog lookup
    Partial
  • P4
    Model independence

    Ollama, vLLM, LM Studio and any OpenAI-compatible endpoint are documented, and tools, memory, cron and channels run in the runtime. However, no minimum model contract is documented, and some capabilities are lost off hosted models: voice transcription has only hosted backends, and reference-image editing is unsupported for the local image providers.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Document the minimum model contract (native tool calling) and test it against a local open-weight model
    • Add a local speech-to-text backend
    • Support reference-image edits for local image providers
    Partial
  • P5
    Exit survives termination

    The default offering is local-first: all agent state is written to the owner's disk, with no HKUDS account or hosted store, so provider termination or shutdown cannot remove access to it.

    Pass

Transparent · Can you see everything the agent is, and everything shaping it?

75%
  • T1
    Readable without the provider

    State is stored as JSONL, JSON, SQLite, Markdown and a git repo, with no nanobot-applied encryption. The docs give file locations and roles but no field-level schema for session records, run records, cron/trigger stores or the llm_usage SQLite tables.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Publish schemas for session JSONL (including provider_state and metadata lines), run records, jobs.json/action.jsonl, trigger stores and llm_usage tables
    Partial
  • T2
    What runs is what you see

    Model, tools and access settings are visible through /status, nanobot status, the WebUI and config.json, and compaction summaries and runtime-context blocks are persisted with the session. The assembled system prompt, built each turn from package templates, has no documented viewer: the WebUI context view shows only the session part, and full request capture needs a third-party Langfuse plugin (OpenAI-compatible providers only), which G3 caps at partial. NANOBOT_* environment overrides are not shown in status (edge gap, not counted).

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Add a documented view or log of the exact assembled request for any model call
    • Show the effective merged configuration including environment overrides
    Partial
  • T3
    No shadow data

    nanobot is self-hosted, and HKUDS operates no service that receives owner content or usage data. The code contains no telemetry or analytics, and the only HKUDS-related requests (an owner-triggered PyPI version check, the GitHub-hosted CLI Apps catalog, a TUI binary fallback) carry no content.

    Pass
  • T4
    No hidden steering

    The source shows no paid placement or self-preference in the agent's context, provider order, search default (DuckDuckGo) or tool choices, and the setup has no preselected partner provider. Partner and affiliate links appear only in the README and docs. The bundled clawhub skill is visible and can be switched off with disabledSkills.

    Pass

Auditable · Can you reconstruct exactly what the agent did, and trust the record?

17%
  • A1
    Complete action record

    Main, cron, heartbeat and trigger turns are saved to session JSONL with full tool-call arguments. However, subagent tool calls stay only in memory and Dream runs are ephemeral (unrecorded entry paths), nothing tells the owner when an action goes unrecorded, and by default tool results over 16,000 chars are cut to a 1,200-char preview whose full copy is deleted after 7 days, with run history capped at 20 entries (three shortfalls).

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Persist every subagent and Dream tool call with arguments
    • Alert the owner, or block the action, when recording fails
    • Stop pruning offloaded tool outputs and run history without owner instruction
    Fail
  • A2
    Tamper-evident, owner-checkable

    Session JSONL is rewritten in full on each save, and sessions, run records and usage data carry no hashes, signatures or chain, so the record can be changed without trace.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Hash-chain or sign action-record entries and publish an open verifier
    • Anchor checkpoints with the owner or an independent witness
    Fail
  • A3
    Agent cannot rewrite its record

    By default (restrictToWorkspace false, no exec sandbox, full access mode, shell guard skipped), the agent's shell and file tools can edit or delete its session JSONL, usage database and logs. The documented bwrap/seatbelt sandbox masks ~/.nanobot from the agent, but cron/trigger run records and tool-result offloads stay in the writable workspace, and Windows has no sandbox.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Write the action record from a component the agent's tools cannot reach, outside the workspace
    • Make that protection the default on every platform
    Partial

Verifiable · Can you prove what it runs, who it is, and what changed?

50%
  • V1
    Obtainable source, matching build

    All components are open source: the core is MIT, the WebUI and TUI source ship in the repo, and the Bun runtime is LGPL with a source offer. The default PyPI wheels (with a prebuilt ~119 MB TUI binary and WebUI bundle) are uploaded by hand, with no attestations, provenance or reproducible-build claim, so the distributed build cannot be tied to source independently.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Publish via PyPI Trusted Publishing with PEP 740 attestations or SLSA provenance, for wheels and TUI archives
    • Make the WebUI and TUI builds reproducible and document how an owner verifies them
    Partial
  • V2
    Owner-rooted identity

    nanobot has no agent-level identity (no keypair, DID or agent card). The agent acts through owner-configured channel accounts, such as an email sender on the owner's domain, which HKUDS cannot revoke or impersonate, so attribution is per channel only.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Add an owner-held agent keypair or DID that signs outbound actions across channels
    • Document how recipients verify it and how the owner rotates it
    Partial
  • V3
    Change history and rollback

    A dulwich git repo versions SOUL.md, USER.md and MEMORY.md, and /dream-restore reverts a Dream commit. All commits are attributed to Dream, owner or agent edits between Dream runs are folded into the next Dream commit, and config, skills, AGENTS.md, cron, the model and the runtime version have no history or rollback (agent self-changes via the my tool are only a log line).

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Version all agent state, including config, skills, instructions and cron
    • Attribute each change to its true actor
    • Offer one-step restore to any earlier state
    Partial

Modifiable · Can you change anything, and can only you change it?

60%
  • M1
    Instructions and logic

    SOUL.md, USER.md, AGENTS.md, the Dream and evaluator prompts and built-in skills can be overridden or disabled from the workspace, and updates never overwrite owner files. The core system-prompt templates (identity, platform policy, tool contract and others) load only from the installed package, with no documented override.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Add a workspace override for every agent template, including the base prompt, that survives upgrades
    Partial
  • M2
    Memory

    SOUL.md, USER.md and memory/MEMORY.md are plain, editable Markdown. The cross-session memory/history.jsonl archive is documented as append-only, with no supported item-level edit or delete, and past sessions the agent can search and read can only be deleted as whole topics.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Provide item-level view, edit and delete for history.jsonl and reusable session transcripts
    • Purge deleted memory from the git history, or document how
    Partial
  • M3
    Tools

    Owner tools can be added without review through MCP (with enabledTools filters), entry-point plugins, skills and CLI apps, and exec, file, web, my, CLI Apps and image generation each have an enable switch. Built-ins such as message, spawn, cron, goals and the session tools have no switch and register whenever their services exist.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Add a documented per-tool disable list covering every built-in
    Partial
  • M4
    Owner has the final say

    Sandbox, workspace restriction, SSRF guard (via ssrfWhitelist), exec timeout, rate limit and the exec deny list (via allowPatterns) are all owner-configurable. The http/https-only URL restriction for web_fetch and MCP HTTP, and the refusal to bind the WebUI to 0.0.0.0 without auth, have no owner override.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Make the remaining hard-coded protections overridable with a warning
    • Document allowPatterns and the built-in deny list in the configuration reference
    Partial
  • M5
    No unilateral change

    There is no auto-update, remote flag or server-side setting. The PyPI version check runs only when the owner clicks it and installs nothing, and model, instruction and runtime changes happen only when the owner upgrades or edits config.json, so a self-hosted install stays pinned indefinitely.

    Pass

Controllable · Is your word final?

33%
  • C1
    Boundaries

    Instruction sources are limited per sender (allowFrom plus pairing), and spend is met under G11 (no payment capability). Contact and network egress are on/off only (no per-recipient or per-domain lists). By default the shell guard is skipped and the agent's file and shell tools can rewrite ~/.nanobot/config.json and pairing.json, changing its own permissions (two shortfalls, and limits can be overridden by model output).

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Add per-recipient and per-domain allow/deny lists for messaging, email and web egress
    • Put config, pairing and the settings API out of reach of agent tools in every mode
    • Enforce owner shell allow/deny patterns in full-access mode too
    Fail
  • C2
    Approval gates

    nanobot v0.3.5 has no mechanism for the owner to require approval before a tool call or action class runs. Access modes are scope limits, and approval exists only for pairing new senders.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Let the owner gate any tool or action class with approval shown at the time
    • Make every path, including cron, heartbeat and subagents, honour the gate
    Fail
  • C3
    Immediate halt

    `nanobot gateway stop` terminates the single local process that runs turns, subagents, cron, heartbeat and shell sessions (SIGTERM, then SIGKILL after a 20 s default). Interrupted turns come back as awaiting_user rather than replaying. In-chat /stop covers one session only, and completion within seconds needs a hands-on check.

    Pass
  • C4
    Data serves only the owner

    nanobot sends no telemetry, and HKUDS receives no owner content. By default web search queries go to DuckDuckGo and every fetched URL goes to Jina Reader (useJinaReader true), third-party destinations the owner did not specifically choose, disclosed only in the configuration reference. Both can be switched off, and no data terms are published.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Make third-party search and reader services opt-in
    • Publish a list of every outbound endpoint and binding data terms
    Partial
  • C5
    Credential custody

    All credentials are local, in plaintext config.json and OAuth token files, and HKUDS holds none. Each can be removed through `nanobot provider logout`, WebUI settings or MCP server removal. There is no single list of credentials (Codex and Copilot tokens sit in platform data folders outside ~/.nanobot), and after Codex logout the oauth-cli-kit dependency re-imports ~/.codex/auth.json if present.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • List every stored credential in one place with a revoke control for each
    • Stop re-importing Codex CLI tokens after logout
    Partial
  • C6
    Full deletion

    No uninstall-and-purge command or documented delete-all procedure exists; `gateway uninstall-service` removes only the service unit. Agent data spans ~/.nanobot, OAuth token folders outside it and the installed package environment, and nothing confirms removal.

    › How it could pass

    Suggestions. Any change that meets the test counts.

    • Ship a `nanobot uninstall --purge` (or documented script) that removes all data, tokens, services and the package, and confirms completion
    Fail
Provenance

How this assessment was produced

One run, in a fresh container with stock Claude Code and no custom instructions, memory, hooks or plugins. The evaluator received only the prompt below.

Prompt given to the evaluator
Load the AFH sovereignty skill at https://agentsforhumanity.dev/skill.md and follow it to write a desk review of nanobot (https://github.com/HKUDS/nanobot).

During the run the skill was read from a local copy of this site with identical content; only the host in its URLs differed. The transcript records the exact prompt.

Model
claude-opus-5-5
Harness
Claude Code 2.1.285
Ran
2026-09-30 15:38:07 UTC · 11 turns
Criteria hash
a9a46c32d9065380a3eeb09185cedd4734856fdc63b7ca509a15a1bbede75c6c
Full transcript
Download (JSONL, gzip) · every tool call, page read and reply
Run protocol
2026-09-30-v1

Every agent evaluated once, each in its own fresh Podman container running stock Claude Code with Claude Opus 5.5. The container has no CLAUDE.md, AGENTS.md, memory, settings, hooks, plugins or MCP servers. The evaluator received only the one-line prompt and nothing else, and no published scores were available to compare against during the run.

Human review
pending
Check it with your own agent
Verify this assessment
Load the AOH sovereignty skill at https://agentsofhumanity.ai/skill.md and follow it in verify mode for https://agentsofhumanity.ai/evaluations/nanobot.json.

Or grade it from scratch. See Check any score yourself.

Something wrong or out of date?

Vendors and the public can dispute any finding with evidence. Disputes and their resolutions are published.

Dispute a finding