# telegram A channel of the operator's conversation: kind `telegram` of the `channel` and `intake` benches the router (`messenger`) declares (novox/hq ADR 0234, ADR 0259). It reaches the operator away from the machines, and it proves who answered: Telegram authenticates the sender, and the router compares it with the account linked as the operator. - **Shows what the router sends** (its kind's worker on the `channel` queue): a message, a question with buttons — each button carries only the router's one-time ticket — or an edit of a message shown before. It sends to the account the router names as linked, or, before one is, to the chat a `/start` came from. - **Says what the operator chose** on `intake` under its own kind: a tapped button (`choice`), with the sender as Telegram authenticated it; `/start` (`link`); a message it could not deliver (`failed`); and whether it can send (`standing`). Only a private chat with the account itself counts. - **A code** (six digits, the one shown on the desk when linking) is asked of the router as a proof, by request and reply: never in an event, never kept, and deleted from the chat at once. - **Judges nothing.** Whether the sender is the operator, and what an answer may do, is the router's. ## The defects of the client it replaces (novox/hq to-be 46 §12) | | fixed here | |---|---| | D1 | up to 4096 characters arrive whole; longer is cut and the cut said | | D4 | a warning or a clearing arrives without sound; an urgent message or a question rings | | D5 | a rate limit is waited out as told | | D6 | a refusal is a permanent failure, said to the router and not retried; an edit to the same text is a success | | D7 | the deprecated preview flag is gone | | D8 | a request that cannot be written is said | | D10 | `standing` checks the token with Telegram (`getMe`), not only that a value is present | D2 and D3 (a reopening said by an edit; a clearing edits the first message) are the router's, and D9 the watcher's. ## How it keeps the token from the agents (novox/hq ADR 0259 §8) - **It runs as the account `telegram`**, which the module makes (no shell, no login). The tool runner, which runs as root, starts this bundle as that account (`MESH_RUN_AS`) and refuses root and the operator's account. - **Its state directory is the account's, 0700, and its secret `telegram-token` the account's, 0600.** The operator's account — which every agent runs as — reads neither, and cannot attach to its process. - **The bus credential stays the runner's**, root's only. The bundle reaches the bus through its own standard input and output, and the runner publishes for it only its own kind's subjects. - **An agent reaches the runner only through the mesh MCP server's tools**, which make tool calls; no tool says a choice, a link or a proof. - **If an agent holds root on the machine, none of this holds**: root reads the token and the runner's bus credential and can publish anything. ## Where it runs Held once for the mesh: assign it to the control node, the stably reachable one. Long polling is outbound only, so no route into the mesh is needed, and a stolen token can read updates (a conflict says so) but never inject one. ## What the operator gives 1. **A bot**: in Telegram, talk to @BotFather, `/newbot`, a name and a username. BotFather answers with the bot's token. Keep it on the phone; never paste it into a chat with an agent. 2. **The token, to the vault**, as this module's own secret `telegram-token` (novox/hq ADR 0259 §10, the vault's verb for a secret given at the desk; until it is built, `secret accept telegram telegram-token` at a terminal on the control node, which reads it without echoing it). Then push the control node. 3. **The link**: send the bot `/start`. A six-digit code appears on the desk; send it to the bot within ten minutes. The account answers acknowledgements at once and approves an hour later; every channel says so. `messenger_identities` shows it, `messenger_unlink` undoes it. ## Tools | tool | does | |---|---| | `telegram_status` | whether it can send and why not (never the token), the bot's name, when updates last arrived, the last delivery and error, counts since start, and its rules |