Skip to content

ADR-0001: Local daemon — superseded by in-process napi addon

Status: Superseded.

Context

The desktop UI must interact with networking, storage, and cryptography without exposing network services.

Original decision

Use a local daemon communicating with the UI via gRPC over Unix Domain Socket.

  • No TCP ports exposed
  • Authenticated via IPC token
  • High performance
  • Small attack surface

Current state

The desktop no longer spawns a separate daemon process. The peer / daemon runtime and the agent runtime both ship as library crates (soma-daemon, soma-agentd) linked into a napi-rs addon (soma-node) loaded directly by the Electron main process. All daemon operations go through in-process Rust calls; there is no socket, no gRPC, no soma-socket helper.

The original goals are preserved more cleanly than the gRPC topology achieved:

  • No TCP ports exposed (still true; no transport at all).
  • Authentication is moot — every caller already runs inside the same Electron main process as the daemon library.
  • Performance is strictly better: zero serialization, zero context switches.
  • Attack surface shrank: no Unix-socket listener, no proto deserialization on the hot path.

Why this ADR is kept

The decision recorded here informed today's structure: the handle/ module inside soma-daemon (the in-process facade exposed via napi) is a direct descendant of the gRPC service, mapping the same operations onto plain Rust types. New ADRs should reference this one when discussing the desktop ↔ daemon boundary.