Self-hosted shared-memory fleet for AI agents — bare-metal Debian 13 setup + Qdrant/Ollama/mem0 stack + per-client integrations, managed by the single-binary olympus CLI/TUI.
  • Python 67.2%
  • Shell 26%
  • TypeScript 6.8%
Find a file
afk 6a79680937 phase20: drop extended-keys on — it breaks paste on tmux 3.5a
Pasting multi-line text into a pane turned every newline into a literal `j`.
Root cause isolated: of the directives 43b1871 added, only `set -s extended-keys
on` + `terminal-features xterm*:extkeys` touch key input. On tmux 3.5a (what
trixie ships) turning extended keys on makes tmux run the bytes of an *incoming
paste* through its mode-2 key encoder, so a pasted newline (LF = Ctrl-J) is
re-encoded as the extended-key sequence for keycode 106 = `j`. A config of just
mouse + focus-events + wheel on the same 3.5a pastes fine, confirming it is these
two lines, not the tmux version as such. It is a 3.5a paste bug, fixed upstream
only in tmux 3.6 (commit 17bab327); no 3.5a config keeps Shift+Enter *and*
working paste.

Remove the pair. The block keeps mouse + wheel, focus-events, allow-passthrough,
truecolor, history-limit and set-clipboard — all verified innocent. The cost is
that Claude Code can no longer tell Shift+Enter from Enter (Enter submits);
getting that back alongside paste needs tmux >= 3.6 (trixie-backports ships an
official 3.6b). The test guard now fails on any extended-keys directive so the
line cannot creep back. Follows b76f702, which removed the csi-u format override
(a valid cleanup, but never the cause — both formats encode keycode 106).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 12:25:05 +08:00
dashboard phase20: agent-user git identity + tmux mouse config 2026-07-14 09:49:13 +08:00
lib phase20: agent-user git identity + tmux mouse config 2026-07-14 09:49:13 +08:00
phases phase20: drop extended-keys on — it breaks paste on tmux 3.5a 2026-07-15 12:25:05 +08:00
plugins docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
scripts phase20: drop extended-keys on — it breaks paste on tmux 3.5a 2026-07-15 12:25:05 +08:00
templates docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
.gitignore chore: gitignore the docs backup dir and a stray in-tree wiki clone 2026-07-12 08:34:19 +08:00
CHANGELOG.md phase20: drop extended-keys on — it breaks paste on tmux 3.5a 2026-07-15 12:25:05 +08:00
CLAUDE.md phase20: drop extended-keys on — it breaks paste on tmux 3.5a 2026-07-15 12:25:05 +08:00
CONTRIBUTING.md docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
LICENSE olympus: bare-metal Debian setup + self-hosted memory fleet 2026-07-07 11:31:57 +08:00
MEMORY_MODEL.md docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
README.md docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
SECURITY.md docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00
setup.sh phase20: agent-user git identity + tmux mouse config 2026-07-14 09:49:13 +08:00
verify.sh docs: move operator docs to the wiki, keep code-coupled docs in-repo 2026-07-11 21:33:06 +08:00

olympus — self-hosted agent memory fleet

A bare-metal Debian 13 setup script plus a self-hosted shared-memory stack (Qdrant + Ollama + mem0-server) and per-client integrations that wire every AI-agent chat turn into one shared, partitioned memory store — with a single-binary olympus CLI/TUI to run the whole fleet.

Target: Debian 13 Trixie · Headless · Hermes agent server · Tailscale network

Trust model: Single trusted operator. Prompt injection is always possible — defense is layered access control, not model trust. See SECURITY.md.

Documentation: operator docs live in the wiki — start at Home for the guided reading order. This README is the one-page overview.


Node roles

The orchestrator prompts for NODE_ROLE up front. Pick one per machine — and build the mem-host first: agent setup asks for its hostname and points every integration at it.

  • agent — runs Hermes profiles. Creates the agent user (agent / agent-dev / agent-prod / agent-pa — your choice), installs Hermes runtime deps, installs the fleet helper library at /opt/fleet_helpers/memory.py, detect_project.py, and redaction.py (memory.py imports redact from it) — so profiles can from memory import search, write and from detect_project import detect_project_name. Phase 17 also installs the coding harnesses you opted into at setup — Claude Code, OpenCode, Pi (latest, as the agent user; login stays manual) — and wires the fleet-mem0 Hermes plugin, the Claude Code / OpenCode hooks, and the Pi extension (broadcast + recall) so every turn auto-writes to mem0 and prefetches from it.
  • mem-host — runs the memory stack: Qdrant + Ollama bound to 127.0.0.1; mem0-server binds the node's Tailscale IP, with a UFW rule opening port 7437 to the tailnet. Forces Docker on, skips the agent-user creation, and enables a nightly restic timer over /srv/qdrant_snapshots (consistent Qdrant snapshots, not the live data dir) and /opt/fleet. Phase 18 also installs /usr/local/bin/olympus — a single CLI for fleet health, memory search/delete, Hermes partition editing, and a full-screen Textual TUI (olympus dashboard).

The memory layer carries five partition dimensions per write: user_id (hard partition), scope (topical tag), audience (visibility filter), agent_id (which agent wrote it), and project (codebase context tag, auto-detected via detect_project_name() from git root or cwd — container dirs like ~/projects yield no tag). MEMORY_MODEL.md is the authoritative taxonomy; the wiki's Memory-Model page is the plain-English explainer.


Quickstart

  1. Debian 13 Trixie installed (netinst, no desktop), console access, a Tailscale account, your API keys.

  2. Get the repo onto the server and run the orchestrator — mem-host first, then each agent node:

    apt install -y git
    git clone https://git.disroot.org/afk/olympus.git /opt/server-setup
    cd /opt/server-setup && chmod +x setup.sh
    sudo ./setup.sh
    
  3. Verify: sudo ./verify.sh, then from the mem-host olympus status.

The full walkthrough — prerequisites, air-gapped install, SSH-key lockout warning, what every prompt means — is the wiki's Getting-Started. What each phase (0019) does and how to re-run one: Setup-Phases.


The mem0 token lives in two files

mem0-server requires a pre-shared key and fails closed — no token means 503, a wrong token means 401. Every node keeps that key in two places: /var/lib/debian-setup/debian-setup.conf (the input you edit, read by setup.sh) and /etc/fleet/mem0-token.env (the deployed artifact everything actually reads; phases 15/17 write it). The flow is one-way, config → phase script → token file, and no node ever fetches the token from another — you paste the same value into every node's config.

Changing or rotating it? Start here: Token-Rotation — rotate agents first, the mem-host last, then re-login everywhere.


Documentation map

Where What
Wiki: Home Guided reading order for a new operator
Wiki: Getting-StartedSetup-Phases Install walkthrough; per-phase reference
Wiki: Operations-Runbook Day-2 operations, smoke tests, troubleshooting
Wiki: CLI-and-Dashboard Every olympus command + the TUI
Wiki: Token-Rotation / Backups-and-Recovery / Upgrades The critical procedures
Wiki: Integrations (Hermes / Claude Code / OpenCode / Pi) Per-tool memory wiring
Wiki: Decisions / Gaps-and-Roadmap Why it's built this way; what's missing
MEMORY_MODEL.md Authoritative partition-field reference (schema-coupled)
SECURITY.md Trust model, PSK limitations, redaction caveats
CONTRIBUTING.md / CHANGELOG.md Contributor loop; release history
dashboard/README.md, dashboard/CONTEXT.md, dashboard/docs/adr/ Dashboard developer docs
plugins/*/README.md Per-plugin env-var tables (kept next to the code)

License

MIT — see LICENSE. Personal-infrastructure project, released as-is; security fixes land on main.