Documentation
Architecture
Doppelganger is a digital twin system with a gateway-first runtime, an agent-side execution seam, Matrix-centered communication surfaces, and sidecar operating planes.
Product Stance
Digital twin, not dashboard
The gateway matters, but the product is the assistant and its operating surfaces, not the transport daemon alone.
Comms Model
Matrix-centered
The operator-facing comms plane is being unified through Matrix and preserved deep comms clients, not flattened into a generic chat widget.
Execution Split
gateway / agent / doppel
Gateway owns ingress, secrets, sessions, and control. Agent owns node-hosted execution. Doppel owns the writable source tree and deploy actions.
Port Posture
24xxx target
Runtime services are standardized on 24xxx. Legacy 18xxx exposure still exists in parts of the runtime.
System Model
Doppelganger is a twin system with several explicit planes.
Doppelganger is a system for operating digital twins, not a thin wrapper around a chatbot gateway. The gateway is the runtime spine: it is the ingress and egress boundary, the session and memory boundary, the policy boundary, and the place where orchestration begins.
That does not mean the gateway is the whole product. The runtime is only one layer. The broader product includes the twin behavior itself, the operator shell, the communication layer, the sidecar systems, and the execution boundary where the twin can actually do work.
The architecture is a gateway-first control plane, a node-host execution plane, a sessionKey-first memory plane, a Temporal orchestration plane, and a growing shell of operator surfaces around them.
Working Truths
- + The gateway is the live runtime spine, not a thin reverse proxy.
- + The hard isolation seam is the node host.
- + Communication and operator comms are moving toward a Matrix-centered model, with Matrix and Element-class surfaces preserved as deep systems while native shell views catch up.
- + The shell direction is a Doppel-owned Paperclip fork backed by gateway contracts and sidecar adapters.
Core Map
The runtime is organized into real cores, not vague layers.
Gateway Core
Ingress, egress, RPC and HTTP surfaces, orchestration entry, auth boundary, and normalized control-plane contracts.
- / Owns user-facing ingress and outbound delivery
- / Owns auth, secrets, and connector boundaries
- / Calls directly into runtime subsystems
Pi / Agent Runtime Core
Turn execution loop, model invocation, tool use, and subagent lifecycle. This is where the twin actually reasons and acts.
- / Embedded agent execution runs through the integrated runtime
- / Tool policy, prompt assembly, and model calls happen here
- / Subagents and tool streaming live in this boundary
Session / State Core
Canonical identity, routing, transcript lifecycle, and the state model that keeps separate twins and sessions coherent.
- / Session identity is canonicalized around `sessionKey`
- / Routing and session lifecycle are first-class subsystems
- / This is one of the main reasons the gateway cannot be treated as stateless
Memory Core
Durable recall, promotion, semantic search, and bridge logic that turns transient turns into usable long-term twin context.
- / Recall injects into turn context before model invocation
- / Promotion extracts durable facts, tasks, decisions, and preferences
- / SurrealDB-backed session memory is in the runtime path
Security / Policy Core
Sandboxing, approvals, secrets resolution, auth posture, and the runtime hardening needed for a twin that can actually act.
- / Gateway remains the credential and connector boundary
- / Policy is not delegated to the UI layer
- / Execution risk is separated from gateway-owned secrets
Temporal Orchestration Core
Durable workflows and schedules, split so long-running orchestration does not become a backdoor into gateway-owned secrets.
- / Temporal control state belongs on the control-plane side
- / Gateway and agent workers have different responsibilities
- / Schedules handle durable cron behavior
Runtime Flow
A twin turn travels through gateway, runtime, memory, and delivery.
Inbound work lands at gateway methods such as `agent` or `chat.send`. The gateway is the first durable boundary, not a pass-through.
Reply dispatch resolves the active route, session identity, and twin context before a run is prepared.
Session memory can be recalled into the prompt path, while tool policy, agent config, and execution posture are assembled for the run.
The embedded Pi runtime performs the model turn, tool calls, subagent work, and any node-hosted execution requests.
Final output is captured, summarized, and promoted back into durable memory without making the user wait for maintenance paths.
Outbound delivery, streaming updates, health, presence, and workflow status all leave through gateway-owned surfaces.
Operating Planes
Control, comms, execution, memory, workflows, and shell each have different owners.
Control Plane
Gateway methods, config, auth, sessions, memory inspection, health, and runtime controls live here.
- + Gateway is the canonical backend for settings, runtime control, chat, approvals, and memory RPCs
- + It is the source of truth for policy and auth
Comms Plane
Operator communication is being organized around Matrix-backed surfaces, with deep comms preserved rather than prematurely flattened.
- + Current Canvas/Paperclip plans keep comms backed by Matrix / Element-class surfaces
- + The comms plane is a product surface, not just another transport adapter
Execution Plane
Node host is the deploy seam for shell and system work.
- + Gateway forwards execution to a paired node host
- + Node-hosted work runs under the `agent` boundary, not the gateway user context
Memory Plane
Memory is keyed by `sessionKey` and maintained as an explicit subsystem rather than an incidental prompt trick.
- + Gateway ingress captures intent and output
- + Recall, promotion, and maintenance are distinct runtime responsibilities
Workflow Plane
Temporal is the durable orchestration layer, split so secret-backed activities and workspace activities run under different owners.
- + Server and control-plane state stay on the gateway side
- + Agent-side workers own workflow logic and workspace activities
Operator Plane
Doppelganger is aiming for a shell-first product that lets operators understand the whole system without moving source-of-truth ownership into the shell.
- + Paperclip fork is the intended operator shell direction
- + Sidecars remain systems of record unless intentionally replaced
Deployment
Same-box deployment is split by ownership, not by pretending the repo is already cleanly separated.
doppel
The human operator account owns the writable source tree, builds, and deployment actions. It is not the autonomous runtime.
Zone
Operator source and release workspace
Responsibilities
- / Owns the monorepo checkout
- / Performs build, promote, and maintenance workflows
- / Should remain the only writable full source tree
gateway
The protected runtime boundary for ingress, egress, sessions, secrets, memory, connectors, and gateway-owned services.
Zone
Protected control-plane runtime
Responsibilities
- / Owns channel ingress and outbound delivery
- / Owns connector credentials, auth profiles, and secret resolution
- / Runs the integrated runtime entrypoint
agent
The execution boundary for node host, workspace activity, caches, logs, generated artifacts, and autonomous tool use.
Zone
Autonomous execution and workspace boundary
Responsibilities
- / Runs node host and receives remote exec
- / Owns broad autonomous workspace and local tools
- / Does not own gateway deploy trees or external credentials
Memory + Workflows
Long-term twin behavior depends on durable memory and durable orchestration.
SessionKey-First Memory
Doppelganger memory should be understood as a runtime plane keyed by `sessionKey`, not as a lane hack or post-hoc summary blob.
- + Recall is injected before turns
- + Gateway ingress captures both intent and output
- + Promotion writes typed durable records such as facts, tasks, decisions, and preferences
Split Temporal Orchestration
Durable workflows exist to coordinate work without collapsing the gateway security boundary.
- + Temporal server and DB belong on the control-plane side
- + Gateway activities own secret-backed integrations such as Matrix, Gmail, and connector mutations
- + Agent activities own repo work, builds, file generation, and local tool execution
Operator Surfaces
Doppelganger brings several operating layers into one visible system.
Primary operator environment
Company Orchestration Platform
The main operator layer for navigation, oversight, and coordination across the twin system. It should present the whole company operating picture without becoming a second hidden runtime.
Unified communications layer
Multimodal Comms
The communication layer ties messaging, events, and operator conversation into one coherent surface. Deep communication workflows remain intact while more native views are built on top.
Long-running execution and schedules
Durable Workflow Engine
This layer owns long-running workflows, durable scheduling, and operational coordination over time, with operator views layered above it where useful.
Approval and decision engine
Granular Policy Layer
The platform can visualize posture and recent decisions, but the actual allow, block, escalation, and approval semantics belong in a dedicated policy layer rather than ad hoc UI checks.
Durable and granular access control
Persistent Secret Storage
Secret material stays on the control side behind durable storage and narrow access boundaries. Operator and agent surfaces consume controlled contracts rather than raw credentials.
Project and knowledge context
Workspace and Research Context
Project work, research context, and institutional knowledge live in dedicated context layers that the twin can adapt and reason over without pretending they do not exist.
Why This Shape
The architecture is layered so the twin can grow without collapsing into one opaque system.
Doppelganger is built so the twin can become more capable without losing operational clarity. The gateway is the control boundary, sidecars are real systems where they have depth, and the execution seam is separated from connector credentials and operator control.
That structure matters because the product is meant to grow into a serious operating companion: one that can communicate, remember, coordinate, and act across systems without turning the whole stack into an opaque monolith.
The result is a deliberately layered system — a durable, inspectable twin built for real operational use.