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.

damn.dev architecture: clients to backend to OpenClaw runtime to models

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 runtimeOpenClaw 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#