# System Overview

> Applies to: ChengOS v0.1.0+ ｜ Last verified: 2026-08-12 ｜ Source: root `CLAUDE.md`, `deploy/README.md`, `deploy/distributed/README.md`, `crates/cheng-api/src/rest/routes.rs`

This page is the map: which processes exist, which crates make up the backend, and which
deployment shapes those processes can be arranged into.

## Runtime components

A complete installation runs four application processes and up to three datastores.

| Process | Default port | Role |
|---|---|---|
| `cheng-api` | `19225` | The backend. Everything else is its client. |
| `cheng-ui` | `8080` | Workflow editor and admin console (static assets + a small server) |
| `cheng-app` | `5055` | Chat gateway: web widget, H5/PWA, messaging channels |
| `cheng` CLI | — | Terminal client; connects to `cheng-api` locally or over a URL |
| PostgreSQL | `5432` | **The only source of business truth** |
| Valkey (Redis-compatible) | `6379` | Cache, rate limits, agent memory. Optional. |
| Qdrant | `6333`/`6334` | Vector retrieval for RAG. Optional. |

Valkey and Qdrant are disabled by default in native installs (`ENABLE_REDIS`,
`ENABLE_QDRANT`). Turn them on when you start using agent memory or RAG.

## Backend architecture

The backend is a Rust Cargo workspace built on hexagonal architecture — domain logic in the
middle, infrastructure at the edges, with traits ("ports") between them. The practical
consequence is that the domain has no idea PostgreSQL or HTTP exist.

| Layer | Crate | Contents |
|---|---|---|
| **Domain** | `cheng-core` | `Workflow`, `Node`, `Execution`; port traits (`WorkflowRepository`, `Executor`, `NodeRegistry`, `EventPublisher`); domain services. No infrastructure dependencies. |
| **Application** | `cheng-engine` | `WorkflowEngine` implements the `Executor` port: DAG analysis, planning, scheduling, streaming |
| **Infrastructure** | `cheng-storage` | Repository ports implemented over PostgreSQL with Diesel; migrations |
| **Presentation** | `cheng-api` | Axum REST handlers, WebSocket manager, dependency injection |

Supporting crates: `cheng-nodes` (the builtin node library and registry), `cheng-llm`
(provider abstraction), `cheng-vector` (Qdrant), `cheng-adapters` (WhatsApp, Telegram, Slack,
DingTalk, WeCom), `cheng-mcp` (MCP client and server), `cheng-runtime` (QuickJS/Python
sandbox and Docker runtime for code nodes), `cheng-code-index` (tree-sitter code
intelligence), and `chengctl` (offline i18n CLI).

Dependencies are injected at startup rather than reached for through globals, so there is no
mutable global state to reason about.

## How a request becomes a run

1. A client calls `POST /api/v1/executions`.
2. `WorkflowEngine` loads the workflow through the `WorkflowRepository` port.
3. The graph is validated and planned into ordered stages.
4. An `Execution` record is created.
5. A background task schedules ready nodes concurrently, persisting results and publishing
   events as each finishes.
6. Events reach connected clients over WebSocket as they happen.
7. The execution lands in a terminal state.

[The execution model](/docs/exec-model) covers this in detail.

## Deployment shapes

Three arrangements are supported, all driven by the same `deploy/.env`:

| Shape | What runs where | When to use it |
|---|---|---|
| **Native (hybrid)** | Everything on one host; datastores as unprivileged user processes or systemd services | Evaluation, single-machine installs, hosts without root |
| **Docker** | Every service as a Compose container | Production, reproducible installs |
| **Distributed** | Datastores on one host, `cheng-api` on another, both native | Performance-sensitive installs that want no container overhead |

See [deployment modes](/docs/deploy-modes) for how to choose, and
[Docker deployment](/docs/deploy-docker) for the container path.

## How the frontends reach the backend

In production, the UI and app are served as static bundles and reach the API through the URLs
in `UI_API_BASE_URL`, `UI_WS_URL`, `APP_API_BASE_URL`, and `APP_WS_URL` — normally `/api/v1`
and `/ws` behind one reverse proxy.

In development, the Vite dev server on `:5173` proxies `/api`, `/ws`, and related paths to the
backend on `:19225`.

Node UI is schema-driven across the boundary: backend node definitions emit JSON Schema with
`x-*` extensions, and the frontend's field control registry turns those into form controls. A
node's inputs changing on the backend surfaces in the editor with no frontend change.

Internationalization also spans both sides. `chengctl` extracts and translates
node-definition strings offline, and the frontends load the resulting bundles from
`/api/v1/i18n`.

## Security boundaries

Four boundaries are worth knowing before you expose an installation:

- **Credentials** are encrypted with `CREDENTIAL_MASTER_KEY_1` and resolved server-side at
  the point of use. They never enter a model's prompt.
- **Workspaces** isolate data by `user_id` and workspace membership; `X-Workspace-Id` is
  authorized, not trusted.
- **Sandboxes** confine file and shell tools to a workspace directory tree.
- **Network exposure** should be one reverse-proxied `443`. Docker already binds datastore
  and API host ports to loopback; native installs need a host firewall.

## Next steps

- [Core concepts](/docs/core-concepts) — the domain vocabulary.
- [Execution model](/docs/exec-model) — scheduling and state in depth.
- [Environment variable reference](/docs/config-env-reference) — every knob.
