Documentation menu
Getting started
New in v2.0
Feature deep dives
Reference
System atlas
System atlas
Interactive map of AutoTelegramForward derived from its own source: every module, import link and service, plus a 3D simulation of the runtime connections.
Verified against the checkout built for v2.2.4 · updated 20 Oct 2026
On this page
Most architecture pages describe the software. This one is computed from it: a build-time sweep walks the checkout, resolves the imports of every language it finds, reads the protobuf registry and the compose file, and renders what it found. The result is 524 module nodes and 1,869import links across 593 source files — plus the 23 runtime connections between 16 components, drawn in 3D on theconnection map.
Shape of the system
Nine subsystems, one deployable stack. The split is not decoration: it is the reason a Telegram session can be replaced without touching the REST contract, and the reason a log flood cannot slow a delivery down. Three languages carry the runtime — Python for the engine, Go for the control plane, Rust for the gateway — with Dart for the client and TypeScript for the dashboard.
Lines by language, counted from the checkout
- python92,431 · 324 files
- go29,711 · 77 files
- typescript25,597 · 60 files
- dart23,577 · 55 files
- astro14,160 · 75 files
- proto1,032 · 1 files
- rust252 · 1 files
2 of those files are generated (.pb.go, _pb2_grpc.py), and 203 are tests. Both are excluded from the keystone ranking on thedependency page, because a generated stub is not an authored decision.
Subsystems
Each card is a directory in the repository, with its real size and its real areas. The largest area of the engine, tests, is 35,015 lines on its own.
Python Core
Forwarding engine
Domain model, rule engine and the durable delivery pipeline. Owns the Telegram sessions and the database.
245 files · 78,889 lines · python
Go API
Control plane
Stateless REST control plane. Authenticates clients, applies tenant scoping, and speaks gRPC to the core and the logger.
77 files · 29,711 lines · go
Web gateway
Dashboard host
Serves the compiled dashboard, proxies the REST API and streams the live log feed over SSE.
1 files · 252 lines · rust
Dashboard UI
Operator console
Task control, log explorer, diagnostics and admin surfaces for a signed-in tenant.
50 files · 23,142 lines · typescript
Mobile app
Client
Native client with its own 10-locale catalog and the same REST contract as the dashboard.
55 files · 23,577 lines · dart
DevOps CLI
Operator tooling
Install, validate, diagnose and upgrade the stack from one command surface.
78 files · 12,485 lines · python
Interfaces
Contracts
The gRPC service definitions, the generated Go stubs and the cross-language JSON fixtures that pin the wire format.
1 files · 1,032 lines · proto
This website
Documentation
The site you are reading, generated from the same checkout it documents.
85 files · 16,615 lines · astro, typescript
Runtime topology
Import links only exist inside one language. What connects the languages is the wire: gRPC between the control plane and the engine, HTTP between the gateway and the API, MTProto between the engine and Telegram, and SQL to the two separate stores. Those 23 links are what this map draws — hover a component to trace them, click one for its files and evidence.
Pipeline & rule engine· Service
Policy resolution, cleaning, shortcodes, replacements, AI pass
Python · domain model · 24 source files · 9,604 lines
3 gRPC boundaries
Control plane → engine, control plane → log store, engine → log store. All three are protobuf, all three fail loudly.
5 HTTP boundaries
Dashboard → gateway → API, mobile → API, CLI → running stack. The browser never sees an API key.
4 SQL boundaries
Engine database and log database are separate files, so history cannot lock the delivery path.
What a request does
Three paths cover almost everything an operator will ever ask about. Each one is replayed as a packet animation on the 3D connection map, where every step is also written out as text.
A post is forwarded
From an incoming Telegram update to a delivered copy in every target chat, with the durable queue absorbing rate limits.
9 steps · 20 log tags
An operator edits a task
A dashboard write travels through the gateway, the REST control plane and gRPC into the engine — with optimistic concurrency and an audit trail.
8 steps · 0 log tags
An event is investigated
Live logs, the diagnostic window and the dead-letter queue: how an operator answers "what happened to that message?".
6 steps · 1 log tags
How this map is verified
A map that describes a system is only useful if it is allowed to say "I could not confirm that". The sweep that builds this page does three kinds of check, and publishes the failures in the same place as the successes.
Derived, never typed
Counts, node lists, protocols, ports and log tags are parsed fromscripts/sync-architecture.mjs reading this checkout at 23bafe6. A number on these pages that is not in architecture.json does not exist.
Every claim has a source
12 inter-service links were emitted only after a real search hit in the repository — the matching files are printed with each link. No probe failed in this build.
5 checked absences
The strongest statements are the negative ones. Each of these is a search that came back empty on this checkout: Mobile speaks no gRPC · No secrets in the browser bundle · No label chosen by a language branch · Two separate databases · The engine opens no HTTP port.
empty result Mobile speaks no gRPC — The mobile client never dials the engine directly: every call goes through the REST control plane. (searched: mobile/lib)
empty result No secrets in the browser bundle — Neither the API key, the master key nor the AI provider address is shipped to the browser. (searched: web/frontend/src)
empty result No label chosen by a language branch — A localised label is never picked by a hardcoded ternary — the catalogue lookup does it, and it falls back to English. (The language switcher itself still shows the target language natively, which is the point of a switcher.) (searched: core/infrastructure/telegram , core/application , atfcli)
empty result Two separate databases — The logger never opens the engine database — the log store is its own file. (searched: logger , rust/logger/src)
empty result The engine opens no HTTP port — The engine is reachable only over gRPC; there is no HTTP server inside the core. (searched: core)
open item No committed credential defaults — Every credential in the compose file is an interpolation; no working secret is committed as a default. (hits: docker-compose.isolated.yml)
The negative checks and the dropped probes are regenerated on every build, so a claim that stops being true stops being printed — the page cannot silently drift from the software it maps.
Go deeper
Dependency & structure atlas
The full module graph: 524 nodes and 1869 resolved imports, filterable by subsystem, language and test status — with the ranked keystones, the 6 import cycles and the cross-subsystem traffic matrix.
Connection simulation
16 components in three dimensions, 23 real links, and packets you can fire along the 3 traced flows — the fastest way to explain the system to somebody who has never read the code.
Looking for behaviour rather than shape? The architecture reference covers the pipeline stage by stage, the security model covers the isolation boundary, and the source of this page is scripts/sync-architecture.mjs, which re-derives every figure above on each build of AutoTelegramForward.