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:
- Check the taskboard for current priorities
- Read memory files before answering domain questions
- Route to specialized agents when a question fits a domain
- Respect privacy rules — some files are excluded from shared sessions
- 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 glancefairplay-check— Household responsibility rotationtenant-status— Rental property communicationsgift-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:
- As a slash command I run interactively in Claude Code
- As a shell script that calls Claude in headless mode
- 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:
- Seed the data — Fill in the markdown templates with real information
- Use it manually — Run commands, ask questions, build the habit
- Automate inputs — Connect calendars, import health data
- 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.