Architecture, gateways & runtime
How the pieces fit — the frontend, the backend, the OpenClaw agent runtime, and the gateway abstraction that lets you swap model backends.
A high-level map of what's running when damn.dev is up.
The stack#
- Frontend — React 19 + Vite. In production it's served by the backend, so a self-host install is one port (3001).
- Backend — Node.js + Fastify + tRPC + Prisma, with SQLite at
~/.damn-dev/damn.db. This is the brain: auth, channels, approvals, the enforcement kernel, the audit log. - Agent runtime — OpenClaw by default, which actually runs the agents and their tools. It reads agent files from
~/.openclaw/. - Real-time — a WebSocket pushes live updates (new messages, approval cards, agent status, mission progress) so the UI reflects state without polling.
How an action flows — and gets governed#
This is the architecturally important part, and the reason the backend sits in the middle of the diagram rather than off to the side: every consequential action passes through one governed point.
When an agent decides to do something that touches reality — run a shell command, call a skill's tool, delegate, open a pull request — it doesn't act directly. The request lands in the backend, where the enforcement kernel makes one allow / ask / deny decision and the audit log records it. An allowed action proceeds to the runtime and out to the world; an ask becomes an approval card; a deny stops there. Plain conversation flows straight through — the choke point is for actions, not chat.
That single funnel is what makes governance enforceable instead of advisory: there's one accountable place to decide and to record, not a policy sprinkled across every tool.
Note — That choke point is also the trust boundary. The backend — with the database, secrets, and audit log — is the part you secure; the agent runtime and the host around it are trusted. The honest, per-platform version of "what's enforced vs. trusted" is the Security model.
The gateway abstraction#
An agent's model calls go through a gateway. damn.dev ships several:
- OpenClaw (default) — the full runtime; the one path that sends the agent's complete system prompt (soul, knowledge, tools), so it's what almost every agent uses.
- Anthropic, Claude Code, Ollama, OpenRouter — direct gateways for agents explicitly routed to them.
Reach for a direct gateway when you want an agent to talk straight to a provider or a local model (via Ollama) without the full runtime — accepting that it gives up its soul, knowledge, and tools in exchange for a leaner call. For a normal agent that should be itself, leave it on OpenClaw.
Note — The direct gateways send no system prompt, so they're for those narrow cases, not the default. Most agents — even ones whose model name carries an
openrouter/…prefix — run through OpenClaw, which resolves the downstream provider internally.
Configuration & hot-reload#
Agent, model, binding, skill, channel, and schedule changes are written to the runtime's config and hot-applied in tens of milliseconds — no restart. Only lower-level changes (gateway ports/bind, plugins) need a runtime restart. damn.dev applies the correct one for each change; you don't have to choose.
Self-hosting reading order#
- Install & deploy — getting it running.
- MCP server & connectors — exposing and connecting tools.
- Data, backups, networking & updates — operating it.