Show HN: Xyzzy – AI teamwork in one Python process, with a tamper-evident log Project Nexus YR released Xyzzy, an open-source (Apache-2.0) Python framework for multi-human and AI-agent teamwork with a tamper-evident, hash-chained event log, available via Docker (ghcr.io/project-nexus-yr/xyzzy) and on GitHub. The tool features human-in-the-loop approval, persistent rooms, artifact versioning, and immutable Decision Briefs, with support for Ollama, LM Studio, or any OpenAI-compatible server. It is designed to bring governed, provable, and self-hosted AI collaboration to teams. A team makes a hard technical decision with AI, and keeps the receipts. Live page: xyzzy.yasserameur-dev.workers.dev https://xyzzy.yasserameur-dev.workers.dev/ docker run -p 8000:8000 -e XYZZY DEMO=1 ghcr.io/project-nexus-yr/xyzzy Opens a seeded demo workspace at http://localhost:8000 , signed in with one click. No account, no config. Prefer to run from source? git clone this repo and run docker compose --profile demo up instead see Docker docker below for the non-demo path . One click drops you into a workspace already mid-decision: a channel conversation, a branch with two specialist outputs to compare, and a published Decision Brief with its evidence chain intact. No API key is configured for this recording, so the specialist outputs and the brief show the conspicuously labelled SIMULATED workflow output described above; the collaboration mechanics are the same either way. Modern AI tools are single-player: one human, one chat, one context. Real work happens in teams. XYZZY lets multiple humans and AI agents share a room: a common event history, artifacts, tasks, and decisions, persisted in SQLite with WebSocket-driven real-time sync. Agents branch out in parallel, a human selects or excludes what comes back, and the room publishes an immutable Decision Brief with the evidence chain behind it. Governed. Actions wait for human approval before they execute. What an agent may do is re-read from the room's own state at the moment it acts, so leaving a room or losing access takes effect immediately, mid-task. Provable. Every room's event log is hash-chained: each event is hashed against the one before it, so altering or deleting a row breaks every hash after it: tamper-evident by construction, checkable with the audit CLI. Each Decision links to the Claims and AgentOutputs behind it, so a synthesis is inspectable down to the run that produced it. Yours. One Python process and a SQLite file, self-hosted. Point specialists at Ollama, LM Studio, or any OpenAI-compatible server instead of a hosted API. Apache-2.0 licensed, source included. Persistent rooms with durable event sourcing every action is an ordered event Multi-agent orchestration: spawn, pause, resume, redirect, and delegate between agents Human-in-the-loop: request/approve/reject agent actions before execution Artifact versioning: create and version documents, code, and other artifacts Selective synthesis: explicitly include/exclude outputs and publish immutable Decision Briefs Evidence ontology: typed, reviewable Decision → Claim → AgentOutput relationships Bounded Meta: permission-aware “why” and decision-evidence answers with exact drill-down Decision tracking: record and audit architectural and product decisions Shared memory: room-scoped, workspace-scoped, and org-scoped memory Real-time collaboration: WebSocket broadcasting of all room events Reconnect support: full state snapshot + incremental event replay on reconnect ┌─────────────────────────────────────────────────────────┐ │ Browser web/index.html │ │ WebSocket + REST API │ └──────────────────────────┬──────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────┐ │ FastAPI Server server.py │ │ REST endpoints routes.py + WS endpoint │ ├─────────────────────────────────────────────────────────┤ │ Service Layer service.py │ │ State machines · Input validation · Authorization │ ├──────────────────┬──────────────────────────────────────┤ │ RealtimeHub │ NexusAgentBridge │ │ Pub/sub lock │ AgentExecutor · Budget · Events │ │ Queue delivery │ Pause/Resume/Cancel · Interventions │ ├──────────────────┴──────────────────────────────────────┤ │ Repository Layer repositories.py │ │ 16 typed repos · Atomic event sequencing │ ├─────────────────────────────────────────────────────────┤ │ Database Layer connection.py │ │ aiosqlite · WAL mode · Transaction support │ ├─────────────────────────────────────────────────────────┤ │ NEXUS Runtime optional │ │ AgentExecutor · ModelProvider · PolicyEngine │ │ ToolRegistry · SQLiteStateStore · EventBus │ └─────────────────────────────────────────────────────────┘ src/multiplayer/ ├── domain/ │ ├── models.py 25+ domain models frozen dataclasses │ └── events.py 40+ event types, RoomEvent, OrgEvent ├── db/ │ ├── connection.py aiosqlite wrapper with transaction support │ └── repositories.py 16 typed repository classes ├── migrations/ │ └── 0NN .sql numbered migrations, applied in order at startup ├── services/ │ ├── service.py Core service layer with state machines │ └── presence.py In-memory presence tracking ├── nexus bridge/ │ └── agent bridge.py NEXUS runtime adapter asyncio.Lock protected ├── realtime/ │ ├── hub.py Pub/sub with lock-protected mutations │ └── websocket.py WebSocket endpoint handler ├── api/ │ └── routes.py 40+ REST endpoints └── server.py Uvicorn entry point with lifespan web/ └── index.html Single-page workspace UI tests/ ├── unit/ Domain model tests ├── integration/ Repository, service, API tests ├── concurrency/ Concurrent event generation, hub, bridge ├── security/ State machines, approvals, scope isolation ├── failure/ Error handling, validation, stub tests └── regression/ Reconnect correctness XYZZY includes an optional integration with NEXUS https://github.com/Project-Nexus-YR/NEXUS , a lightweight agent runtime. The NexusAgentBridge adapts NEXUS into the multiplayer context: AgentExecutor manages agent run lifecycle create, reason, pause, resume, cancel Budget enforces token limits, wall time, and tool call limits PolicyEngine gates tool access per agent and room StateStore persists agent state for checkpoint/restart When NEXUS is unavailable, the bridge runs the configured model provider directly. With an OPENAI API KEY , specialists use the OpenAI Responses API. Without a credential, XYZZY emits a conspicuously labelled SIMULATED WORKFLOW OUTPUT so collaboration mechanics remain testable without presenting placeholder text as real analysis. Python 3.11 or newer and nothing else. The database is a file, so there is no service to stand up first. macOS and Linux: git clone https://github.com/Project-Nexus-YR/XYZZY.git cd XYZZY python3 -m venv .venv source .venv/bin/activate pip install -e ". dev " Windows PowerShell: git clone https://github.com/Project-Nexus-YR/XYZZY.git cd XYZZY python -m venv .venv .venv\Scripts\Activate.ps1 pip install -e ". dev " macOS has shipped no python command since 12.3, and /usr/bin/python3 is a stub that offers to install the Command Line Tools rather than an interpreter worth building against, so create the virtualenv with a real python3 brew install python@3.13 , or the installer from python.org . Once .venv is activated, plain python is that virtualenv's interpreter and every command below works as written. Apple silicon needs nothing special: every dependency resolves to an arm64 wheel. Every route below /api/v1 needs a bearer token; /api/v1/health is the exception. Without OPENAI API KEY the server runs a credential-free simulator, which is enough for the whole workflow. Credentials live in the database, hashed, one row per token, revocable without a restart. XYZZY AUTH TOKENS is bootstrap only: its tokens are ingested at startup, and a token an operator revoked stays revoked across restarts. Mint and revoke real credentials with the operator CLI: the token is printed once at mint time and never stored: python -m multiplayer.manage multiplayer.db user add alice --email alice@example.com python -m multiplayer.manage multiplayer.db token mint alice --label laptop python -m multiplayer.manage multiplayer.db token revoke