Building a Life OS

How I replaced a dozen apps with a git repo and an AI that reads markdown files.

The problem

My family's information was scattered everywhere. School schedules in one app, finances in another, contacts in a third, medical records in a folder somewhere, travel plans in email threads. No single system had the full picture, and nothing talked to anything else.

I'd tried the usual suspects — Notion, spreadsheets, shared Apple Notes, Google Keep. Each solved one piece but created another silo. What I actually wanted was a system that could answer questions like:

  • "Do we have anything conflicting with that school event next week?"
  • "When is the lease up on the rental property?"
  • "What gifts did we give the neighbors last year?"
  • "Are the kids' passports current for that trip we're planning?"

These are cross-domain questions. They need context from multiple sources. No single app handles this well — but an AI that can read all my files at once does.

The idea

What if the entire operating layer of our family's life was just a folder of markdown files, and Claude was the interface?

No database. No webapp. No SaaS subscription beyond the AI itself. Just:

  • A git repo with organized markdown files
  • A system prompt that tells Claude how to use them
  • Specialized AI agents for different life domains
  • A privacy model so my partner and I can share the system safely

I called it maev.

The architecture

Everything is a markdown file

The core insight: markdown is the universal format. It's human-readable, version-controlled, greppable, portable, and — critically — it's what LLMs are best at reading and writing. There's no impedance mismatch between how I store data and how the AI processes it.

The directory structure is the schema:

maev/
├── CLAUDE.md              # System prompt — the "kernel"
├── TASKBOARD.md           # Current priorities
├── memory/                # All state lives here
│   ├── family/            # Profiles, school, activities, routines, medical
│   ├── finance/           # Accounts, budget, investments, taxes, insurance
│   ├── health/            # Fitness, medical records
│   ├── mind/              # Journaling, reflection (some files private)
│   ├── social/            # Contacts, birthdays, gifts, events
│   ├── property/          # Rental management, P&L, tenants
│   ├── travel/            # Upcoming trips, history, preferences, packing
│   ├── growth/            # Learning goals, long-term projects
│   └── parenting/         # Approaches, development stages
├── .claude/agents/        # 10 specialized AI agents
├── cowork-plugins/        # Partner-facing interface
├── config/                # API keys, MCP servers
└── scripts/               # Automation (daily brief delivery, etc.)

Every file in memory/ is structured with headers, tables, and bullet points. When I tell the AI something new — "the dentist appointment is moved to Thursday" — it updates the relevant file. Git tracks every change.

The system prompt is the kernel

CLAUDE.md sits at the project root. When Claude Code opens the project, it reads this file first and gets its operating instructions:

  1. Check the taskboard for current priorities
  2. Read memory files before answering domain questions
  3. Route to specialized agents when a question fits a domain
  4. Respect privacy rules — some files are excluded from shared sessions
  5. Update memory when new information comes in

This is the kernel of the system. It doesn't contain data — it contains behavior. It tells the AI how to be a family operating system.

Specialized agents instead of one mega-prompt

I tried having one massive system prompt handle everything. It didn't work well — the AI would lose focus, mix up contexts, and the instructions became unmanageable.

Instead, I built 10 specialized agents, one per life domain:

Domain Model Why
Finance Opus Tax planning, investment analysis — needs deep reasoning
Travel Opus Research-heavy, itinerary building, web search
Mind/Wellbeing Opus Nuanced reflection, journaling, emotional context
Family Ops Sonnet Routine lookups, schedule checks — speed matters more
Property Sonnet Straightforward P&L, lease tracking
Social Sonnet Contact lookups, birthday reminders
Project Manager Sonnet Task management, cross-domain coordination

Each agent has:

  • A focused system prompt (~30 lines, not hundreds)
  • Explicit data files it's responsible for
  • Defined behaviors for its domain
  • A tone (the finance agent is professional; the travel agent is enthusiastic)
  • Tool access scoped to what it needs (only some agents get web search)

The main conversation acts as a router: "which agent knows about this?" When I ask about an upcoming trip, it delegates to the travel agent. When I ask about tax deadlines, it goes to finance. Each agent's context stays clean.

Adding a new domain is trivial: create a memory/newdomain/ directory, create .claude/agents/newdomain.md, and update the routing in CLAUDE.md. No build steps, no deployment.

Privacy by convention

This is a family system. My partner uses it too. But some things are personal — therapy notes, private reflections, certain health records.

I solved this with convention, not encryption:

  • Certain files are tagged [PRIVATE] in the system prompt
  • When the session is identified as shared, the AI is instructed to skip those files
  • My partner's interface (via separate plugins) only references shared directories

Is this cryptographically secure? No. Could someone determined bypass it? Sure — they could just open the files. But this isn't a security product. It's a family system where trust exists but boundaries matter. The AI respects the boundaries, and that's enough.

Two interface layers

I use Claude Code in the terminal. Full access, all agents, all files. This is the power-user interface for system management.

My partner uses Cowork plugins — a GUI-based Claude interface with curated commands:

  • weekly-overview — The family's week at a glance
  • fairplay-check — Household responsibility rotation
  • tenant-status — Rental property communications
  • gift-ideas — Gift tracking and suggestions

Same underlying data, different access patterns. The plugins read from the shared memory files but never touch private directories.

The daily brief

Every morning, a /daily-brief command reads across all domains and compiles a scannable summary:

GOOD MORNING — Sunday, February 8

TODAY'S PRIORITIES
- [pulled from taskboard]

UPCOMING TRAVEL
- [!] Trip in 5 days — tickets still need booking

BIRTHDAYS (next 7 days)
- [!] Kid's birthday on Wednesday

FINANCIAL ALERTS
- Tax documents not yet gathered

It's implemented three ways:

  1. As a slash command I run interactively in Claude Code
  2. As a shell script that calls Claude in headless mode
  3. The script supports delivery via Pushover (mobile push) or email

The idea is to eventually run this on a cron job — wake up, check your phone, see the brief.

What I learned building this

Start with data, not automation

My first instinct was to build workflows: calendar syncs, health data imports, notification pipelines. But the system was useless without actual data in the memory files. I restructured the roadmap into phases:

  1. Seed the data — Fill in the markdown templates with real information
  2. Use it manually — Run commands, ask questions, build the habit
  3. Automate inputs — Connect calendars, import health data
  4. Automate outputs — Daily briefs, push notifications, scheduled checks

Phase 1 is unglamorous but essential. A beautifully architected system with empty files is just a fancy directory tree.

Convention over configuration

I almost built a config system: YAML files defining agent routing, JSON schemas validating memory file formats, a build step that compiled everything. Then I realized — the file paths are the config. The directory names are the schema. The system prompt is the router.

Adding a new domain doesn't require updating a config file. It requires creating a directory and an agent definition. If you can write markdown, you can extend the system.

Model selection matters

Not every task needs the most powerful model. Checking a school schedule is a fast lookup — Sonnet handles it in a fraction of the time and cost. Analyzing tax implications of a property sale needs deep reasoning — that's Opus territory.

By assigning models per agent, the system is both responsive for routine queries and thorough for complex analysis. This wouldn't be possible with a monolithic prompt.

Git is an underrated life tool

Version control for personal data sounds like overkill until you realize what it gives you:

  • History: When did we change the pickup schedule? git log memory/family/school.md
  • Backup: The entire system is on GitHub (private repo). My laptop could vanish and everything survives.
  • Accountability: Every change has a timestamp and a diff. Nothing is silently overwritten.
  • Branching: Want to try a new budget approach? Branch, experiment, merge or discard.

The AI is the interface, not the storage

This is the key architectural choice: the AI reads and writes markdown files, but the files are the source of truth. If Claude's API went down tomorrow, I'd have a well-organized folder of plain text files I can search, read, and edit with any tool.

The AI adds intelligence — answering cross-domain questions, drafting plans, noticing conflicts — but it doesn't own the data. The data is mine, in a format that will outlast any AI platform.

What's next

The system is bootstrapped. The architecture works. Now comes the less exciting but more important part: actually filling in all the data, living with it daily, and seeing where it breaks.

I'll be writing more as the system evolves — connecting external services via MCP, building automation workflows, and testing whether AI-as-interface actually works for a family that isn't all engineers.

The repo is private (it contains my life, after all), but the architecture is simple enough to replicate. If you have Claude Code and a folder of markdown files, you have everything you need to start.