How Mila did it: case studies and news
Before each message in Telegram, Mila’s text goes through a guard. A wrong chat, a key, a card number, the name of another client’s chat — and the message does not go out. Mila gets the reason and writes it again. Every line below links to the code.
For an agency or a consultant with many clients in one Mila.
The guard is a small script that Claude Code runs before Mila sends anything to Telegram. A rule in a prompt can be forgotten; a script on the way out cannot. send-guard.py:1-5 settings.json:35-46
It runs on a new message and on an edit of one already sent. Other tools are not touched.
send-guard.py:13-15It sees which chat the message goes to and the text itself, and compares both with its rules.
send-guard.py:16-21If something is wrong, the message stays. Mila gets “Not sending:” and every reason, and writes the text again.
send-guard.py:179-187In the settings template the guard has onFailure: block: if it crashes or hangs, the message is not sent unchecked. The test runs on every change in the repository.
Mila has one session for all chats; there is no wall between them inside. So the lock is on the way out: the check happens at the moment of sending. It is law 1 of her constitution: a detail of one case is not heard in a talk about another. send-guard.py:116-120 CONSTITUTION.md:15
The guard learns who is where from the journal of incoming messages: which people wrote in which chat and what each chat is called. send-guard.py:137-155
same-case-chats.json; inside the list nothing is “another case”. send-guard.py:127-135 test_send_guard.py:38-42A message goes to the owner, to groups the owner connected her to, and to private chats of people let in through the access list. Any other chat gets nothing: “I speak only where I was connected.” send-guard.py:23-36 test_send_guard.py:23-24
If the owner’s id is not set, the access list is enough. If there is neither, as in a Mila not yet connected, the recipient is not checked. send-guard.py:33-35 test_send_guard.py:44-49
✓ owner (OWNER_ID) ✓ groups in access.json ✓ people in allowFrom ✗ any other chat
The same guard looks for things that should never be in a chat, whoever the message is for.
Provider keys, a Telegram bot token, AWS, GitHub and Slack keys, API tokens. The message stays, and the advice is “reissue the key”.
send-guard.py:38-48 test_send_guard.py:2613–19 digits that pass the card checksum never go to a group. In a private chat the number goes out masked as ****1234. Your own payment details can be allowed; a phone number with “+” is not a card.
send-guard.py:49-83 send-guard.py:179-184 test_send_guard.py:59-75Server paths, container commands, raw provider errors, hook internals, chat ids like -100… She says the result in plain words instead.
send-guard.py:84-95 test_send_guard.py:27“Sorry”, “my fault”, “unfortunately I could not” do not go out, to a client or to the owner: a fact, a conclusion and the next step instead. Law 7 of the constitution. Exceptions: the developers’ chat and a report with a defect number.
send-guard.py:97-104 CONSTITUTION.md:21 test_send_guard.py:25One more rule: bold, lists or links without Telegram formatting do not go out either, so nobody sees raw asterisks. More on the Telegram page. send-guard.py:106-114
The installer copies send-guard.py into the hooks folder and writes it into Claude Code’s settings for replies and edits. A second run does not add it twice; a test checks both. install/install.sh:116-121 install/install.sh:292-297 test_install_hooks.sh:23-26
The owner’s id comes from MILA_OWNER_ID and goes into the settings, so the guard knows whose DM is whose. install/install.sh:305-309
Updates bring new guard code with the other core hooks. Your settings file is never touched by an update. release.json:41-49 release.json:71
$ python3 templates/home/.claude/hooks/test_send_guard.py # 24 cases: wrong chat, key, path, apology, # another client’s @username, card in a group, # masked card in a DM, chats of one case # 24 of 24 passed on 8a6b97d
| File | What it does |
|---|---|
| send-guard.py | the guard: recipient, keys, cards, internals, apologies, another chat’s business |
| test_send_guard.py | 24 checks of the guard (in Russian) |
| settings.json | settings template: the guard on reply and edit, onFailure: block |
| install/install.sh | copies the guard and writes it into the settings |
| test_install_hooks.sh | checks that the installer registered the guard once |
| release.json | updates bring the hooks, never the settings file |
| CONSTITUTION.md | law 1 (secrets) and law 7 (no apologies), in Russian |
| SECURITY.md | how to report a hole in the guard |
The kit is open: skills, hooks, tools and templates. Run test_send_guard.py yourself; found a hole in the guard? SECURITY.md says how to report it.
Facts on this page: github.com/shakhruz/mila (main, 8a6b97d, v1.5.2), checked 24 Oct 2026; test_send_guard.py passed 24 of 24. The chat in the phone is an illustration. “Mila”, “MILAGPT” and the logo are trademarks of MILAGPT.