Skip to content
Brad Johnson, home
All projectsSoftware / 01 of 07

gaidin

A personal agent built on Pi Durable. Slack, a web page and the command line share one conversation that survives crashes and restarts.

Category
Software
Updated
2026-10-11
Status
Running since October
Built with
TypeScript, Node.js, Pi Durable, SQLite, bubblewrap, Tailscale
The gaidin web console: four exchanges with tool calls for a reminder, a scheduled job, a question and a web fetch, with the fetch waiting on an Allow once, Always allow or Deny prompt above the message box.
Running on a scripted model with a made-up conversation.

gaidin is a personal agent for one person, built on Pi Durable. I talk to it from Slack, a web page or the command line, and all three share one conversation stored in SQLite. Every run saves a checkpoint after each step, so if the server dies partway through, the run picks up where it stopped. A reminder set for next week still fires, and a question waiting on my answer keeps waiting through a restart without asking twice.

It sets reminders that reach my phone, runs scheduled jobs like a weekday morning briefing, keeps notes I can see and edit, searches the web and runs commands in a sandbox. Anything that reaches out asks first: fetching from a new host, scheduling a job or working on one of my other machines. A reply in a Slack thread forks the conversation, so the thread sees the channel up to that point and nothing after.

Shell commands run under bubblewrap with no network, and the sandbox directory is the only place they can write. The web view listens only on localhost, with Tailscale Serve in front, and answers only my login. gaidin can also write its own tools, which run in a bubblewrap box of their own once I approve them.

In the Wheel of Time, a Warder (gaidin) is bonded to one Aes Sedai and always on watch.

Next project, 02Raken