+**********
+ Telegram
+**********
+
+The daemon also connects the agent to a Telegram bot when
+``telegram.json`` exists in the data directory. It polls the Bot API for
+new messages, so it needs no open port.
+
+#. Make a bot with BotFather and keep its token.
+
+#. Find your numeric Telegram user ID.
+
+#. Write the token and the ID to ``telegram.json``, and give the file
+ mode 0600, because the token is a secret. The daemon refuses the file
+ with any other mode.
+
+#. Start the daemon, open a private chat with the bot, and write.
+
+.. code:: json
+
+ {"token": "123456:ABC-token-from-BotFather", "owner": 123456789}
+
+The bot reads only the private chat of the owner and ignores all other
+updates. Each text message goes to the agent as a user message, the line
+``/stop`` interrupts the running turn, and the line ``/stop NAME`` stops
+the subagent NAME. The bot sends the replies in parts of at most 4096
+characters, with their Markdown as Telegram formats: bold, italic,
+strikethrough, code, code blocks, links, and headings as bold text. When
+Telegram refuses the formats of a part, the bot sends the part again as
+plain text. Each error goes as a short message in plain text. It shows
+the typing action while a turn runs. It does not send the tool calls. It
+sends each message that the user types in the terminal client, with the
+mark ``[terminal]``.
+
+``agent/telegram-offset.json`` holds the ID of the next update. The bot
+moves it past an update only after the message is durable in the log, so
+a restart of the daemon does not lose a message. A crash just after the
+write of a message can make the message repeat once. A network failure
+or a rate limit makes the bot wait and try again, and does not stop the
+daemon.
+