# Machine Inventory Detailed reference for every machine in the environment. For network topology, see `tools/tailscale.llm.md`. --- ## Tabitha — Silma's Primary Machine | Field | Value | |-------|-------| | **Role** | Silma AI primary — OCPlatform host, k8s stack, all Silma infrastructure | | **Hardware** | MacBook Pro (arm64 / Apple Silicon) | | **OS** | macOS (Darwin arm64) | | **User** | `Tabitha` | | **Tailscale IP** | `100.76.192.116` | | **LAN IP** | `192.168.12.236` | | **Hostname aliases** | `macbook-pro-3` (Tailscale) | ### What runs here - **OCPlatform** — Silma's AI ops platform (`/Users/Tabitha/.openclaw/`) - **k8s silma-ai namespace** — Postgres, Redis, Elasticsearch, Kafka, Qdrant, MinIO, Vault, Temporal, Grafana - **LLM inference** — llama.cpp with Metal acceleration (`localhost:8080`, `localhost:8081`) - **Silma workspace** — `/Users/Tabitha/.openclaw/workspace/` - **MCP servers** — GitHub, Postgres, Memory, Redis, Qdrant, Elasticsearch, MinIO, Playwright, Kubernetes, Google Workspace ### External storage - **Hagia** — 8TB Seagate external HDD mounted at `/Volumes/Hagia` (k8s PVC data, model archive, workspaces) - **Theodora** — 1TB SanDisk SSD served via WebDAV from Orson at `/Volumes/Theodora` (hot model cache) ### Key paths ``` /Users/Tabitha/.openclaw/ OCPlatform install root /Users/Tabitha/.openclaw/workspace/ Silma's workspace (memory, soul, skills) /Users/Tabitha/.openclaw/k8s/ Kubernetes manifests /Volumes/Hagia/ Cold storage (8TB) /Volumes/Hagia/workspaces/workspace_Father/ Father's projects ``` ### Connecting ```python # Kittens (local, same machine — not typically needed) # SSH: local terminal access only ``` --- ## Orson — Gitea Host + CI Runner | Field | Value | |-------|-------| | **Role** | Self-hosted Gitea, act_runner CI, Hagia/Theodora storage server | | **Hardware** | MacBook Pro (arm64 / Apple Silicon) | | **OS** | macOS (arm64) | | **User** | `orson` | | **Tailscale IP** | `100.79.253.19` | | **LAN IP** | `192.168.12.138` | | **Hostname aliases** | `orson`, `Orson`, `Hagia`, `Theodora` (all resolve to same IP) | ### What runs here - **Gitea v1.26.2** — self-hosted git server (`http://100.79.253.19:3000`) - **act_runner v0.6.1** — Gitea Actions CI runner (`orson-runner`, host mode) - **wsgidav** — WebDAV server serving Theodora at port 8090 - **silma-kittens** — remote exec bridge (port 8765) ### Storage attached - **Hagia** — 8TB Seagate ExFAT HDD (workspace archives, model cache) - **Theodora** — 1TB SanDisk SSD APFS (hot model storage, served via WebDAV) ### Key paths ``` /Users/orson/bin/act_runner CI runner binary /Users/orson/.config/act_runner/ Runner config + .runner registration ~/Library/LaunchAgents/com.silma.act-runner.plist Auto-start plist /tmp/act_runner.log Runner stdout /tmp/act_runner.err Runner stderr ``` ### Connecting ```python import asyncio, json, websockets async def orson(cmd, timeout=20): async with websockets.connect('ws://192.168.12.138:8765/?token=silma-kittens-2026', open_timeout=5) as ws: await ws.recv() await ws.send(json.dumps({'type': 'exec', 'id': '1', 'cmd': cmd})) r = json.loads(await asyncio.wait_for(ws.recv(), timeout=timeout)) return r.get('stdout', ''), r.get('stderr', '') ``` ### Known quirks - Timezone is **US/Pacific (PDT)** — causes timezone-sensitive tests to fail if they hardcode CST - Node.js is at `/opt/homebrew/bin/node` — LaunchAgents need `EnvironmentVariables` PATH set explicitly --- ## Ozymandias — Travel Laptop / Coding Box | Field | Value | |-------|-------| | **Role** | Travel laptop, secondary coding box | | **Hardware** | MacBook (x86_64 / Intel) | | **OS** | macOS (x86_64) | | **User** | `ozymandias` | | **Tailscale IP** | `100.115.222.5` | | **LAN IP** | `192.168.12.202` | ### What runs here - **silma-kittens** — remote exec bridge (port 8765) - General dev work (Python, Node, etc.) ### Connecting ```python async def ozy(cmd, timeout=20): async with websockets.connect('ws://192.168.12.202:8765/?token=silma-kittens-2026', open_timeout=5) as ws: await ws.recv() await ws.send(json.dumps({'type': 'exec', 'id': '1', 'cmd': cmd})) r = json.loads(await asyncio.wait_for(ws.recv(), timeout=timeout)) return r.get('stdout', ''), r.get('stderr', '') ``` --- ## Hunter's Machine (DESKTOP-J88BDET) | Field | Value | |-------|-------| | **Role** | Hunter Albert's primary dev machine | | **Hardware** | Windows 10 Pro x64 | | **CPU** | AMD Ryzen 7 9800X3D (8-core, 3D V-Cache) | | **RAM** | 64 GB | | **GPU** | NVIDIA GeForce RTX 5090 (32GB VRAM) | | **User** | `hjkal` | | **Tailscale hostname** | `hunter-wsl2` | | **Tailscale IP** | `100.118.15.20` | | **Static ngrok** | `creon.ngrok.app` (permanent) | ### What runs here - **silma-kittens** — at `F:\Projects\silma-kittens\` (port 8765) - **Whisker** — AI browser engine (port 7420) - **Creon** — static ngrok domain for permanent remote access - WSL2 (Ubuntu), Node v24, Python 3.13, VSCode, Claude Code ### Connecting ```python import asyncio, json, websockets, base64 CREON_URL = 'wss://creon.ngrok.app/?token=3ClCIkJOCu1Gd5RO2PA4JHRD1ji_soHXcU4c3vMCbvEBFsKi' async def hunter(cmd, timeout=20): headers = {'ngrok-skip-browser-warning': 'true', 'User-Agent': 'SilmaKittens/1.0'} async with websockets.connect(CREON_URL, additional_headers=headers, open_timeout=10) as ws: await ws.recv() await ws.send(json.dumps({'type': 'exec', 'id': '1', 'cmd': cmd})) r = json.loads(await asyncio.wait_for(ws.recv(), timeout=timeout)) return r.get('stdout', ''), r.get('stderr', '') ``` --- ## Mimir | Field | Value | |-------|-------| | **Role** | Linux server — Hunter's AI bridge box | | **Tailscale IP** | `100.100.117.5` | | **Tailscale hostname** | `mimir-mme3l` | | **OS** | Linux | --- ## GoatLord (Aaron Pressey's Machine) | Field | Value | |-------|-------| | **Role** | Aaron Pressey's Windows 11 machine | | **Tailscale IP** | `100.123.22.58` | | **Static ngrok** | `exsufflicate-ineradicable-cortez.ngrok-free.app` (port 8765, permanent) | | **Token** | `silma-kittens-2026` | ⚠️ See `AGENTS.md` — Aaron Pressey (`goatlord2567` on Discord) is a human friend and AMS member. The GoatLord machine runs Sage (a separate AI). Do not conflate the two.