C1 Identity & least privilege
Minimal 0.47 / 1.00
In the default setup the agents' tools touch only the local simulation database; the OpenAI key lives in the process environment but no tool can read it or spawn a subprocess. When Discord is enabled each agent posts with its own bot token, which is a per-agent identity, but nothing scopes those tokens beyond what the operator configured. The project has a per-tool authorization flag, but every tool sets it to false, and the authorized-tools list is not enforced on every path.
C2 Approval gates
Minimal 0.15 / 1.00
There is no human approval step for any tool. A requires_authorization flag exists but is false on every tool, so whatever the model picks runs immediately. In the default configuration the tools only write simulation state (messages and documents) into a local database, which limits the damage; once Discord is enabled, agents post to real Discord channels with no gate.
C3 Tool & action scoping
Moderate 0.50 / 1.00
The tool set is narrow by design: speak, wait, ask-a-human, a company directory and save/read document, plus web search and Wolfram Alpha only when their API keys are set. Inputs are typed with pydantic schemas, recipients are resolved against the known agent list, and database queries are parameterized, but there are no length or quantity bounds. Per-location and per-agent tool scoping is not enforced on every path.
C4 Code-execution isolation
N/A · full credit 1.00 / 1.00
No model-reachable code-execution path exists at this commit. A langchain bash tool is defined in src/tools/built_in.py but nothing imports or calls it, and the only subprocess call is the operator's database-reset command. Model output is parsed as JSON and used as parameterized database values, never evaluated.
C5 Untrusted input blast radius
Minimal 0.15 / 1.00
Nothing structurally limits a hijacked agent: tool results and other agents' messages enter the prompt as plain text alongside instructions. In the default configuration the only content agents read comes from other agents in the same simulation and the operator's own stdin answers, there is no outbound channel beyond the model provider, and the only state change is local database rows. If the operator enables Discord, any human in a mapped channel can inject text that becomes agent memory, and agents reply to Discord unattended.
C6 Memory, context & configuration integrity
Minimal 0.10 / 1.00
Every observation and model-generated reflection is written to a persistent sqlite memory table with no validation and is loaded back on the next run, where it drives planning and tool use. Memories are filtered per agent in queries, but documents saved by any agent are readable by all agents, and there is no provenance, expiry or per-entry review. The whole store can be inspected through the agents/*.txt dumps and wiped with db-reset, but nothing finer-grained exists.
C7 Third-party extensions
N/A · full credit 1.00 / 1.00
The agent loads no third-party code at runtime: there is no plugin system, no MCP client, no model download and no package installation. The only deserialization is the app's own local vector store file, which this process writes itself.
C8 Secrets & sensitive-data protection
Minimal 0.25 / 1.00
API keys come from environment variables or a .env file and are never placed in prompts. Nothing is masked: Discord bot tokens are copied into a plaintext column of the local sqlite database, and the full agent transcript is written unredacted to a log file that an unauthenticated local websocket streams to any connecting page. There is no telemetry.
C9 Audit & traceability
Minimal 0.33 / 1.00
Each tool call and its result are written as plain text lines to src/web/logs/agent.txt, and plan scratchpads with tool name and input are saved to the database. The log has no timestamps or structure, consecutive wait steps overwrite each other in the scratchpad, and the log file is truncated every time the world starts, so earlier runs leave no record.
C10 Limits & kill switch
Minimal 0.07 / 1.00
The world runs agents in an infinite loop with no step, time or spending limit. Plan durations are only suggested to the model in the prompt, and the only hard bound is a per-request timeout on some model calls. A runaway simulation keeps calling GPT-4 until the operator kills the process.