← Back to showcase

Showcase / Applied AI Systems and Agent Orchestration

Atlas Agentic OS

I run a personal AI operating system on a self-hosted server. A team of named agents, a shared file-based knowledge system, async inbox communication, and no always-on process. Each agent is a pickable chat model backed by a real coding agent, it works across devices, and it survives a change of model.

Self-hosted Live and in daily use Multi-provider, zero lock-in

The problem

Context dies at session end

Most people use AI as a single assistant they re-explain context to every session. The window fills, the session ends, and the next conversation starts cold. Across a work monorepo, a personal site, a homelab, and a second brain, this compounds: each project has different conventions, state, and history that no single assistant can hold.

The team

A hub-and-spoke agent org

One chief of staff coordinates; one named specialist owns each major project or domain. I talk to one agent and the work routes to the right specialist.

Kiki avatar
Kiki
Chief of staff · franzy-os brain
Juno avatar
Juno
a work project
Argus avatar
Argus
QA under Juno
Jarvis avatar
Jarvis
self-hosted server
Alfred avatar
Alfred
portfolio site
Plato avatar
Plato
another work project

The knowledge layer

franzy-os, an OKF second brain

A file-based second brain structured as an OKF (Open Knowledge Format) bundle: markdown with YAML frontmatter, organized as a graph. Every concept has a type; cross-links use bundle-relative paths, not external URLs. The intelligence is in the structure and the manual, not in any specific model. Swap the model and nothing breaks, because all context is in files any model can read.

career/      portfolio, resumes, interview prep, applications
learning/    study plans and notes
life/        personal milestones and admin
notes/       daily captures, meeting notes
projects/    project index
references/  external references and standards
runbooks/    step-by-step procedures
systems/     system descriptions
tasks/       open loops and tracked commitments

The front door

Agents you can pick like any chat model

A file-based brain is only useful if it is easy to reach. Every agent is exposed as a pickable model in a self-hosted chat UI, so I select "Kiki" or "Alfred" from the model dropdown exactly like picking any hosted assistant. Each is a Workspace Model whose short prompt boots the agent from its domain README, so it orients from a couple of files and retrieves the rest of the knowledge base on demand instead of reloading the whole brain into every chat. That is where the token saving comes from.

The engine

A real coding agent per chat

Behind those models sits one custom function I wrote. On every turn it spawns a full Claude Code session through the Claude Agent SDK, with filesystem access to the live knowledge base plus artifact handling. This is not a plain API call to a hosted model; the chat window and the terminal are two doors onto one set of files. No import step and no separate RAG index to keep in sync.

Model-agnostic, made concrete

One pipe, many providers

The same function fronts a subscription Claude model and cheaper open models, selectable per agent from a dropdown. A heavy reasoning task picks the strong model; a bulk or throwaway task picks a cheap one. The persona is identical either way, because it lives in files, not in the model. This is the model-agnostic principle proven at the access layer, not just asserted in a design doc.

Engineering war story

The cross-pipe credential leak

Running several provider variants of the same pipe inside one server process surfaced a real production bug: provider credentials leaked across chats. It is a small story with a general lesson about shared mutable state, which is exactly why it belongs here.

Root cause to durable fix
The symptom. The subscription agent started answering as the cheap open model. A restart fixed it, then it broke again after the next chat, so it flip-flopped and looked intermittent.
The cause. Each pipe set its provider by mutating the shared process environment and never cleared it. One agent's credentials persisted between turns, and the next agent, which relied on that ambient state, inherited them.
The trap. A restart gave a clean environment, which is why it flip-flopped rather than failing outright. A partial fix cleared the leftover key but not the leftover endpoint, so the right token was posted to the wrong URL and failed auth.
The fix. Reset the auth variables at the top of every turn, before applying that pipe's own config, so a turn is self-contained and cannot inherit what ran before it. The durable answer was not "clear one more variable" but "make each turn idempotent from a known clean baseline," and stop selecting a provider from ambient state at all.
🔁 The communication pattern: inbox/
📥
Drop a file
any agent or franzy
🧭
Kiki reads
next session
🗂
Files or holds
asks if ambiguous
Reports back
git-timestamped
Why the inbox pattern works
No always-on process. No daemon, no event bus, no hosted queue.
Cross-device by default. The inbox lives in the git repo; any session on any machine can read it.
Auditable. Every filed artifact carries a git timestamp.
Safe. Ambiguous items wait; they are never silently guessed and misfiled.

The foundation

A self-hosted server

Bare-metal Ubuntu backing the whole system. AMD Ryzen 7, 48 GB RAM, 2 TB NVMe. 12+ Dockerized services for media, photos, file sync, backups, and AI agent supervision.

  • Ryzen 7
  • 48 GB RAM
  • 2 TB NVMe
  • 12+ services

Access and safety

Private by design

Zero public-facing ports; all access over a private VPN. An agent-orchestration service runs on PostgreSQL with a sandboxed systemd runner wired to Claude Code. Multi-tier backup: nightly rclone to Google Drive, Restic snapshots, offsite NVMe rotation.

  • Private VPN only
  • Sandboxed runner
  • Multi-tier backup

The dashboard

Honest gamification, not vanity metrics

A static card-grid dashboard (private network only) turns the OKF bundle into a glanceable HUD, rebuilt every 15 minutes straight from the same markdown files the agents write to. Nothing shown can be stale or fabricated, because there is nowhere else for a number to come from.

How it stays honest
Levelling HUD. Level/XP bar, wellness streak, and a goals ring, all derived from real files, not hardcoded.
Importance-ranked backlog. A deterministic P1-P4 heuristic scores each open task from its own text: deadlines and production issues score highest, cleanup lowest. Tasks sort by tier within their project group, and the group holding the most urgent task floats to the top. There is no separate priority field to maintain or drift from.
Honest Done-XP. A task's open XP is exactly what it grants once cleared, computed by the same heuristic and summed, replacing an earlier flat per-task rate. The "Next Level" quest points at the single highest-value open task.
The point. A gamification layer is easy to build dishonestly. This one is built so every number on screen is a provable function of real markdown, reproducible by hand.

How I think

Design principles

File-based over daemons

A markdown file over a script, a STATUS.md table over a bot, an inbox folder over an event queue.

Model-agnostic by design

All intelligence lives in the operating manual and the OKF structure. A different model reads the same files and follows the same conventions.

No vendor lock-in

The system runs on a private server. No hosted AI infra, no proprietary agent platform beyond the model API itself.

Human in the loop

Agents draft, prepare, and stage but never send a message, post a comment, or push to a remote without explicit approval.