One weekend, I decided to frankenstein some old PC components from my garage. The result was two half-decent machines that I don’t have an explicit use for and can’t sell, so I decided to make them into AI assistants that I’ll call “yolo codex” machines.
I hear frankensteining is in fashion this season so let’s see if I can compose a monster from this junkyard pic.twitter.com/LrWwylZRdD
— Bruno Skvorc (@swader) March 20, 2026
A “yolo codex” machine is a machine on which Codex is installed, has passwordless sudo access, and is running in full permissions mode - everything is allowed.
⚠️ Warning: machines with such a setup are one prompt-injection or supply-chain attack away from total takeover and destruction. If you follow along, make sure you’re okay with all the data on them being completely nuked or leaked.
On top of this yolo power, I also made them capable of talking to me via Telegram, sending and receiving files, talking to other machines on the same network, made it possible for them to issue reminders and have recurring jobs, to change models, and more - all of this will be explained in subsequent parts.
This might sound familiar if you’ve heard of Openclaw, Nano claw, etc. The key differences from Openclaw and co are:
- You don’t install a million lines of unknown code and a legion of dependencies any one of which can become a supply chain attack tomorrow.
- You get a more reliable system.
- You learn how it’s actually built.
- This approach is so light-weight you can run it on a potato.
This is how to turn a sacrificial Linux or macOS box into a Telegram-operated Codex machine with durable topic memory and reboot-safe persistence.
I’ll assume you have a machine set up, you’re a sudo user on it, and can access it directly or via SSH. I’m using Omarchy as a distribution on my rigs so that’s all default, but this guide works equally well on any other Linux distro or even macOS (Mac Studio, MacBook).
Step 1: Codex Yolo
First, we’ll install Codex and make it able to do anything. Follow official instructions for installing it on your own OS. I recommend using the homebrew approach. Then, run codex and log in.
Once you’re logged in, test it:
codex exec "reply with cwd and exit"
If that fails, stop there and fix it. Ask Codex how, until it works.
Then, run Codex and give it the following prompt:
Modify your default configuration to:
approval_policy = "never"
sandbox_mode = "danger-full-access"
model = "gpt-5.4"
model_reasoning_effort = "xhigh"
[projects."/home/<user>"]
trust_level = "trusted"
[notice]
hide_full_access_warning = true
```
Install <user> ALL=(ALL) NOPASSWD: ALL to sudoers such that the current user has passwordless sudo ability.
It might ask you for approval a few times during this process.
Codex stores user config in ~/.codex/config.toml. If you prefer not to let Codex edit its own config and sudoers, make these changes manually instead (replace <user> with your username).
To manually modify sudo, put ~<user>~ ALL=(ALL) NOPASSWD: ALL into /etc/sudoers.d/90-codex and then run
sudo chown root:root /etc/sudoers.d/90-codex
sudo chmod 0440 /etc/sudoers.d/90-codex
sudo visudo -cf /etc/sudoers.d/90-codex
After finishing these steps tell Codex to check if it has unrestricted sudo access on this machine.
codex exec "Test if you have unrestricted sudo access"
It should come back with something like:
codex
Yes. On `2026-03-31`, this machine reports passwordless unrestricted sudo for user `swader`.
sudo -n -l` shows `NOPASSWD: ALL`, and `sudo -n id` succeeded as root:
uid=0(root) gid=0(root) groups=0(root)
tokens used
15,141
Now we need to make it talk to us via Telegram.
Step 2: Make the Bot
We’ll need a Telegram Bot. Interact with BotFather and make a new bot.
Create a Telegram supergroup so you can have Topics in it, add your bot in there with admin rights, and disable Privacy mode in the bot’s settings (needed for plain text commands without slash-commands, and to support captions on images later). BotFather will also give you a bot token - save that.
Optionally, add an image, name, etc to your bot. I called mine Luigi after Luigi Serafini, who created the Codex Seraphinianus.
Checklist:
- Create Bot
- Create Supergroup with Topics enabled
- Remove Privacy from Bot's settings
- Save Bot token
- (Optional) personalize the bot
Step 3: Spin up the control plane
Next, we’ll tell Codex the following:
Goal:
Create a fresh Telegram-driven Codex control plane from scratch under ~/yolomode.
Hard constraints:
- Create the entire project tree yourself under ~/yolomode.
- Linux and macOS only.
- Linux path: user systemd service.
- macOS path: launchd or a clearly documented persistent runner.
- Do not use Docker.
- Prefer Bun and simple shell scripts.
- This is a full-control sacrificial machine. You may use passwordless sudo to satisfy prerequisites.
The name of the service is telemux.
Architecture:
- One Telegram topic = one durable context.
- Context kinds: repo, host, scratch.
- Context states: active, pending, archived, error.
- Plain text in a bound topic starts or resumes the stored Codex session.
- Local workers must execute locally, never via SSH-to-self.
- Remote workers must prefer normal SSH over the Tailscale network.
Config rules:
- `.env` contains only global secrets and service-wide knobs.
- `workers.json` contains only worker inventory and per-worker transport config.
- Use an absolute path for the Codex binary.
- Create `.env.example` and `workers.example.json`.
Durable guidance:
- Create or merge ~/.codex/AGENTS.md with durable cross-project rules for this machine.
- Create ~/.codex/MACHINE.md describing that this machine is the control plane.
- Create ~/.codex/skills/yolomode/SKILL.md.
- Ensure every successful run refreshes:
- .factory/STATE.json
- .factory/SUMMARY.md
- .factory/TODO.md
- .factory/ARTIFACTS.md
Linux install script requirements:
- create ~/.config/systemd/user/telemux.service
- run sudo loginctl enable-linger "$USER"
- run systemctl --user daemon-reload
- run systemctl --user enable --now telemux.service
doctor.sh requirements:
- verify loginctl show-user "$USER" -p Linger returns Linger=yes
- verify systemctl --user is-enabled telemux.service returns enabled
- verify systemctl --user is-active telemux.service returns active
- print journalctl --user -u telemux.service -n 50 --no-pager on failure
Project deliverables:
- working Bun app
- SQLite registry
- Telegram long polling
- topic binding
- local host and scratch bootstrap
- command registration
- Linux install/doctor scripts
- Linux user systemd unit
- macOS run script + launchd plist example
- README
- docs/architecture.md
- docs/operations.md
- tests for local host/scratch and pending remote behavior
Required commands:
- /help
- /explainctx
- /whoami
- /workers
- /newctx
- /bind
- /topicinfo
- /run
- /resume
- /loop
- /archive
- /detach
- /tail
- /artifacts
- /usage
- /synccommands
- /showcommands
At the end:
- summarize what you built
- list the exact manual values I still need to fill
- print the exact files I need to edit
- print the exact commands I need to run on Linux
- print the exact commands I need to run on macOS
- tell me the Telegram-only reboot test
After this is finished, you should know exactly which values to fill in where. You can tell Codex to do this if you can’t find the files manually, or don’t want to edit manually.
Again, note that in a production environment, you should not be giving keys and secrets to codex itself since it phones them home to OpenAI and they can see your chats, but for a fully nukeable yolo machine, it should be fine. If you’re worried about this, just manually edit the files.
At this point, you should be able to initiate new threads from Telegram, so make a new topic, call it something like “yolo-general” and issue the command:
/newctx yolo-general control host
Topics like these are good for “general” discussions with this machine - when it’s not repo-connected, not project specific. You can treat it as your general chatbot about this machine. For a “scratchpad” which you would treat as your regular “chatbot” that you currently use ChatGPT or Claude for, you can use /newctx scratchpad control scratch.
In either of these, ask it to give you info about the system.
Bruno Skvorc, [29.03.2026 14:16]
Tell me uptime, free disk space, RAM usage, and the status of telemux.service.
Luigi, [29.03.2026 14:17]
Checked at `2026-03-29 14:16 CEST`.
- Uptime: `7 hours, 6 minutes`
- Free disk on `/`: `522G` free out of `557G` total (`35G` used, `7%` used)
- RAM: `15Gi` total, `3.0Gi` used, `9.5Gi` free, `12Gi` available
- Swap: `23Gi` total, `0B` used
- `telemux.service`: not found as a system unit, but the user unit is enabled and `active (running)`, started at `2026-03-29 14:15:05 CEST`
- Main `telemux` process: `/home/swader/.bun/bin/bun run src/main.ts`
`git status` at this checkpoint: no commits yet on `main`; `.factory/` and `AGENTS.md` are untracked.
Durable context was updated, and the snapshot is recorded in [2026-03-29-host-status.md](/srv/factory/hostctx/valkyrie-general/.factory/artifacts/2026-03-29-host-status.md).
session=019d3985-8a62-7af3-8271-f8bda2a9e60a | machine=valkyrie | usage=manual
Then we can also check if it’s aware of previous conversations in the same thread - not losing context between messages.
Bruno Skvorc, [29.03.2026 14:22]
Continuity test: What did I ask you just before this?
Luigi, [29.03.2026 14:23]
Just before this, you asked: `Tell me uptime, free disk space, RAM usage, and the status of telemux.service.`
I re-read the `.factory` state and `git status` first, then updated the durable checkpoint...
Good to Know
When you bind a context to a topic, you are not importing the whole previous Telegram thread into Codex memory.
Instead, you are:
- binding the topic to a durable workspace
- binding that workspace to a durable session
- leaving the old Telegram history in Telegram
That distinction matters in preventing your rebinding from becoming context soup that’ll get out of hand fast.
Reboot test
Before you do the reboot test, verify that the control plane is not just working right now, but is actually configured to come back on its own.
Linux: verify the user service and lingering
If your bootstrap prompt did its job, it should have created a user systemd service called telemux.service and enabled lingering for your user.
From the machine, run cd ~/yolomode and if your bootstrap created helper scripts, run them first.
./scripts/install.sh
./scripts/doctor.sh
- lingering must be enabled, or the user service may not start until login
loginctl show-user "$USER" -p Linger
# Expect: Linger=yes
- the service must be enabled
systemctl --user is-enabled telemux.service
# Expect: enabled
- inspect the generated unit and make sure it points at the right path
systemctl --user is-active telemux.service
# Expect: active
- inspect the generated unit and make sure it points at the right path
systemctl --user cat telemux.service
# Check that WorkingDirectory= and EnvironmentFile= point at ~/yolomode
- inspect recent logs if anything looks off
journalctl --user -u telemux.service -n 50 --no-pager
If Linger=no, fix it with:
sudo loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now telemux.service
Why this matters: on Linux, loginctl enable-linger tells systemd to spawn your user manager at boot and keep it around after logout, which is what allows a user-level service like telemux.service to survive without an active login session.
MacOS path
If you followed the macOS path, you will not have systemd or linger. You need a launchd job or another persistent runner instead. Check that your launch agent is loaded:
launchctl list | grep telemux
launchctl print gui/$(id -u)/com.yolomode.telemux
Also make sure the generated runner script points at the correct project path and Bun binary.
In the future, if you need to check which launchd agents your macOS is running, for any reason, there's a cool app for that.
Now, reboot the machine.
- If the disk is encrypted, unlock it when the OS asks.
- Do not log in after boot (unless login is part of disk encryption, like on Omarchy, then do it).
- Wait a minute or two.
- In the same Telegram topic as before, ask:
What is the current uptime and is telemux healthy?
If it replies, we’ve got it working.
What we’ve got now
We have:
- full machine control from Telegram (just ask Codex to do anything from a TG thread)
- continuity and persistence
- skills, and the ability to install them via TG
- internet access and browsability through Codex, since it already has this ability natively and we’re just piping commands through
In Part 2, we’ll give it the ability to send us files into TG. Imagine “I forgot to send myself the BigClient.pdf presentation - it’s in Downloads. Go get it and send it to me!”, and it just works.