The Desire Path: Teaching 2025 AI to Survive 1990s Infrastructure
There is a specific kind of intellectual satisfaction in building a ship in a bottle. You voluntarily accept a set of absurd constraints--working through a tiny glass neck, using long, awkward tools--to build something beautiful in a place it shouldn't fit.
I've felt this satisfaction before. It's the same reason I listen to podcasts about packet radio on my commute. Why would anyone in the 21st century want to send an email by bouncing bleeps and bloops off the ionosphere over many minutes of error-correcting nerd-math?.
Because working with and against constraints is intellectually stimulating. It forces you to understand the raw materials of communication. You can't just call an API; you have to understand the signal.
For the last few months, this has been my reality with AI. I'm not using fancy agents or modern APIs. I am asking Claude to do what I have done for 30 years: SSH into a jump host, launch a tmux session, hop to a server, and type commands into a shell.
It sounds simple, but it turns out that modern Large Language Models have zero intuition for "terminal physics". They type too fast. They don't realize that a 300ms network lag can turn a database query into a syntax error. They are trying to stream 2025 intelligence through a 1980s serial interface.
To survive this, I built a suite of "raw and bespoke" shell scripts--my own version of the long, awkward ship-in-a-bottle tools. I call them tmux-sane1. They aren't pretty, and I don't intend for them to be a product. They are "desire paths"--the muddy tracks worn into the grass that show where the users actually walk, ignoring the paved sidewalks of cleaner software architecture.
APIs vs. physics
When we build tools for AI today, we usually reach for an API. APIs are clean. They are atomic. You send a JSON payload, and you get a JSON response. It either worked, or it didn't.
But the world isn't built on APIs. It's built on 30 years of accumulated infrastructure that expects a human on the other end of a TTY.
My current workflow involves a 4-layer "constraint stack":
- My Mac: Running the AI agent.
- The Viewport: A tmux session acting as the universal interface.
- The Jump Host: An SSH connection to a remote server.
- The Endpoint: An ephemeral Docker container or a locked-down network switch.
The AI sees this as text in, text out. But it misses the Terminal Physics:
- Latency: It doesn't know that typing
git statustakes 300ms to echo back characters over a WAN. - Echo: It doesn't know that if you type while the previous command is still running, you might garble the input buffer.
- Special Characters: It definitely doesn't know that sending a semicolon to a raw database shell through tmux requires specific escaping.
If that character vanishes, it doesn't just cause a syntax error--that would be the best case scenario. The worst case is semantic drift: the command still runs, but the meaning changes. A mangled path, a joined argument, or a SQL query that drops the wrong number of rows because the terminator disappeared. That isn't a bug; it's a catastrophe.
Scars as code
I didn't set out to build a framework. I just wanted my agent to stop breaking things. So I started writing wrapper scripts--muddy paths worn into the grass where I needed to walk. I call them the tmux-sane suite:
sane-wait-ready(The Guardrail): This is the most critical desire path. Before the AI types a single character, this script checks the pane. Is the prompt visible? Is the previous command actually finished? It forces the hyperactive AI to pause and respect the physics of the connection.sane-run-command(The Translator): The AI wants structured data; the shell gives raw text. This script runs a command, captures the exit code, and wraps the whole messy result in a clean JSON object. It allows the AI to "feel" if a command succeeded without guessing.sane-send-keys(The Typist): This handles the "physics" of typing. It creates a verified injection of keystrokes, ensuring that what the LLM thinks it typed is what actually appeared on the remote line.
These tools are born from frustration. I literally have a script in this suite named sane-tmux-send-a-goddamned-semicolon. That name isn't a joke; it's a friction log. It exists because I lost hours of my life watching PostgreSQL queries fail silently because a single character was eaten by the terminal buffer.
Authorized hacking
So, do these "muddy paths" actually get you anywhere?
To prove the philosophy, I ran a "Ship in a Bottle" experiment. The goal was simple: Transfer a file from my local Mac to a remote, ephemeral Docker container running deep inside the stack.
The Constraints:
- 4 Layers Deep: Workstation → tmux → SSH → Container.
- The Container: A fresh, minimal Ubuntu image. No curl. No wget. No git. No node. Just a root shell and apt.
- The Rule: No cheating. The AI can only "type" into the terminal.
As I watched the AI work, I realized something: This is indistinguishable from gray-hat hacking.
- Enumeration: The AI probed the environment. No Python? No Node? Okay, we have apt.
- Exploitation (The Good Kind): It bootstrapped a runner by typing the commands to install Python 3 and pip.
- Exfiltration: To move the file, we didn't tunnel HTTP. We looked at the history books and installed
trzsz(a modern Go implementation of ZMODEM). It struck me later that this wasn't nostalgia--ZMODEM solves the same problem as packet radio's AX.25: reliable data transfer over a noisy, high-latency serial link. A tmux pane is just another ionosphere. - Cleanup: We removed the tools (
pip uninstall,apt remove) and left no trace.
The technical skills--enumeration, bootstrapping binaries, living off the land--are identical to a penetration test. The difference is Professional Hygiene. A hacker cleans up to evade detection; a sysadmin cleans up because we respect the system.
We used 2025 AI to bootstrap 1990s tooling because, in the constraint of a tmux viewport, the old ways are still the best ways.
Paving the desire paths
The trzsz experiment proved the point: If you respect the constraints of the medium, you can do almost anything. But right now, achieving that requires a backpack full of custom scripts and hard-earned scars.
I'm looking at the emerging ecosystem of LLM tooling--projects like claude-code-tools--and I see a lot of brilliant software architecture. But I also see a need for the "battle-tested" reality that comes from 30 years of systems administration.
My New Year's resolution isn't to dump my entire messy toolkit into a Pull Request and walk away. That's bad open-source citizenship. Instead, I'm taking a "dip toes in first" approach:
- Identify the Pain: Start with the "Execute on the other side" protocol.
- Prove the Value: Show that the friction isn't theoretical; it's the difference between a working SQL query and a semantic disaster.
- Contribute the Pattern: Offer the logic of the desire path to help the community build robust guardrails.
Pundits like to gush about how AI will replace the old ways. But my experience suggests the opposite: it's breathing new life into the foundational layers of our infrastructure. This is infrastructure archaeology. We aren't just building ships in bottles; we're teaching our new robot friends how to build them with us.
1 SANE: Structured Agent Navigation Environment for tmux ↩