The 4-Folder Claude Code Setup Running 3 Live Apps Solo

Every week I watch the same pattern. A solopreneur buys a Claude Code course, installs ten MCP servers, wires up six subagents, and two weeks later their laptop is a graveyard of half-finished folders. They can't tell which repo is the client work and which one is the experiment. Meanwhile I'm running three live products with paying users out of four directories and one shutdown checklist. Here's the actual layout.
Why most Claude Code setups collapse under real users
The courses sell complexity because complexity fills four-hour videos. Subagent orchestrators, MCP zoos, multi-agent coordinators — they look impressive on YouTube and break the moment a real webhook fails at 2 AM.
The math is brutal once you're maintaining production:
- Every MCP server is a thing that can break on the next update
- Every subagent is a thing that can fail silently
- Every extra layer is more time debugging the automation instead of using it
- Context window gets eaten by orchestration scaffolding instead of your actual code
For an agency selling AI-as-a-service, that shape might make sense. For a solo operator keeping three apps alive, it's suicide. The rule I've landed on after two years of this: boring beats clever when there's no one else to fix it.
So I cut everything back to four top-level directories. That's the entire operating layer.
~/work/
├── apps/ # production code, real users
├── ops/ # the operating system on top of apps
├── intel/ # logs, metrics, error captures
└── scratch/ # experiments that haven't earned promotion
That's it. No agents/, no mcp/, no workflows/. Four folders.
The apps/ directory: production only, guarded by CLAUDE.md
apps/ holds the production repos. Today that's three:
apps/fakturko/— invoicing tool for Serbian small businessesapps/una-intel/— Gmail-to-Telegram operations botapps/bizflowai.io-catalyst/— lead-gen engine for an agency client
Each one has its own CLAUDE.md at the root. This is not optional. Claude Code is powerful, which means it's also dangerous — without a guardrail it will happily refactor your migration files at 11 PM because some test case implied it should.
Here's the actual template I use, trimmed:
# CLAUDE.md — fakturko
## Stack
- Python 3.11, FastAPI, Postgres 15
- Frontend: HTMX + Alpine, no build step
- Deploy: Hetzner CX22, systemd, Caddy
## Before any commit
- Run: `pytest -x tests/`
- Run: `ruff check .`
- Confirm no changes to `alembic/versions/` unless explicitly asked
## Do not touch
- `app/billing/invoice_numbering.py` (legal numbering, audited)
- `alembic/versions/*` unless I say "new migration"
- `.env*` files — ever
- `app/pdf/templates/*.html` without showing me the diff first
## Deployment target
- `git push deploy main` triggers systemd reload via post-receive hook
- Rollback: `cd /srv/fakturko && git reset --hard HEAD~1 && sudo systemctl restart fakturko`
The "Do not touch" section matters more than anything else. That's the file that has saved me from at least four self-inflicted production incidents this year.
The ops/ directory: master CLAUDE.md, slash commands, runbooks
ops/ is the operating system on top of apps/. It has its own root CLAUDE.md that loads when I open Claude Code from ~/work/:
# CLAUDE.md — ops root
You are operating across three live apps under ../apps/.
Apps: fakturko, una-intel, bizflowai.io-catalyst.
By time of day, the likely focus is:
- 07:00–10:00 → triage + fakturko (Serbian business hours)
- 10:00–14:00 → bizflowai.io-catalyst (client work)
- 14:00–18:00 → una-intel + scratch experiments
Available slash commands live in ./commands/:
- /status → health check across all three apps
- /triage → rank what needs attention next 2h
- /ship → pre-flight checklist + deploy
Runbooks live in ./runbooks/. Read before improvising.
Three slash commands handle 80% of my day. Each is a plain markdown file with a prompt and a whitelist of tools Claude is allowed to call.
What each command actually does
/status— pings each app's/healthz, checks Postgres replication lag, confirms cron jobs ran in the last 24h, returns a one-paragraph summary/triage— reads the latestintel/file, pulls Gmail labeledurgent, ranks what's bleeding (not what's interesting) for the next 2 hours/ship— runs tests, checks migrations, confirms env vars present on target, then deploys. Stops on first failure and tells me why
Here's the actual /ship command file:
# /ship
You are the pre-flight officer. Refuse to deploy if any check fails.
## Sequence (stop on first failure)
1. Confirm current branch is `main` and clean.
2. Run the project's test command from CLAUDE.md.
3. Diff `alembic/versions/` against origin. If new migrations exist,
show them and ask for explicit confirmation.
4. SSH to deploy target, confirm required env vars are set
(names only — never print values).
5. `git push deploy main`.
6. Poll `/healthz` for 60s. If non-200, run rollback command from CLAUDE.md.
## Allowed tools
- Bash (git, ssh, curl)
- Read (no Write outside ops/journal/)
Report each step as one line. No essays.
ops/runbooks/ is plain markdown. One file per disaster:
rollback-bad-deploy.mdrotate-api-keys.mdstripe-webhook-failing.mdpostgres-disk-full.md
When something breaks at 11 PM, I don't want to remember. I want to read.
The intel/ directory: logs in, attention out
intel/ is where overnight errors and metrics get dumped as dated markdown files. A small cron job runs at 06:30 every morning and writes a single file:
#!/usr/bin/env bash
# ops/scripts/morning-intel.sh
set -euo pipefail
DATE=$(date +%Y-%m-%d)
OUT="$HOME/work/intel/${DATE}.md"
{
echo "# Intel ${DATE}"
echo
for app in fakturko una-intel bizflowai.io-catalyst; do
echo "## ${app}"
ssh deploy@${app}.internal \
"journalctl -u ${app} --since '24 hours ago' --priority=err --no-pager" \
| tail -n 50
echo
echo "### Request volume"
ssh deploy@${app}.internal \
"grep -c 'POST\|GET' /var/log/caddy/${app}.log"
echo
done
} > "$OUT"
The first thing I do every morning is open Claude Code and say: "Read the latest intel file and tell me what needs attention."
That single habit replaces an entire monitoring dashboard for a solo operator. No Grafana to maintain. No PagerDuty bill. One markdown file, one prompt.
Here's a comparison of what a typical "do it properly" stack costs vs what intel/ gives me:
| Approach | Monthly cost | Setup time | Solo-friendly |
|---|---|---|---|
| Datadog + PagerDuty + Sentry | $180-$400 | 2-3 days | No |
| Self-hosted Grafana + Loki + Alertmanager | $20 (VPS) | 1-2 days | Sort of |
intel/ + cron + Claude Code |
$0 | 30 min | Yes |
For three apps with under 10K daily requests each, the markdown approach is not just cheaper — it's better, because the output is already in the format I'm going to ask Claude about.
The scratch/ directory: the one most people skip
scratch/ is where every experiment, client demo, and half-baked idea lives. It never touches apps/. It never touches ops/.
When Claude generates code I'm not sure about, it goes in scratch/ first. The rule is simple:
- If it survives a week and proves useful → promote it to
apps/with a proper CLAUDE.md - If it doesn't →
rm -rfthe folder
This is how I keep production clean. Most people skip this directory because it feels like clutter. It's the opposite — scratch/ is what prevents clutter in the directories that matter. Every reckless claude code session lands here by default, not on top of a working invoicing engine.
Naming convention I use:
scratch/
├── 2025-01-14-pdf-watermark-test/
├── 2025-01-18-telegram-voice-poc/
├── 2025-01-22-stripe-tax-experiment/
└── _promoted/ # symlinks to things that graduated
Date-prefixed. Disposable. No ceremony.
The shutdown ritual: five minutes that prevent chaos
This is the part nobody talks about. At the end of every workday, three steps:
- Commit anything in
scratch/worth keeping. Even half-broken. Tomorrow's me needs the trail. - Write two lines in
ops/journal/YYYY-MM-DD.md— what shipped, what's still open. - Close every Claude Code session cleanly so yesterday's context doesn't bleed into tomorrow's prompts.
Five minutes. That ritual is the single reason three apps don't drift into chaos. Without it, you wake up every morning trying to reconstruct what past-you was doing — and Claude starts hallucinating file paths because the session context is a swamp.
A representative journal entry:
# 2025-01-23
## Shipped
- fakturko: VAT rate update for Q1 (commit 8a3f2)
- una-intel: fixed Telegram retry loop on 429
## Open
- bizflowai.io-catalyst: lead scoring still returns null for LinkedIn source
- scratch/2025-01-22-stripe-tax: promising, retest tomorrow
## Watch
- Postgres disk on fakturko at 71% — clean old PDF cache by Friday
That's it. No Notion, no Linear, no project management theater. A markdown file per day in ops/journal/, grep-able forever.
Why bizflowai.io helps with this
The four-folder layout works because somebody (me) maintains it daily. Most solopreneurs don't have the bandwidth to design their own operating layer on top of Claude Code — they just want the apps to keep running. That's the bulk of what we ship at bizflowai.io: we install a pared-down operating layer (CLAUDE.md guardrails, slash commands, morning intel scripts, shutdown ritual) on top of whatever stack the client already has, then hand them the runbooks. No subagent zoo, no MCP collection. The same four directories, configured for their specific apps.
Frequently asked questions
What is the four-directory structure for running a solo business with Claude Code?
It's a minimal setup using exactly four top-level folders: apps (production repositories, each with its own CLAUDE.md), ops (master CLAUDE.md, slash commands, and runbooks), intel (daily logs, metrics, and error captures dumped as dated markdown files), and scratch (experiments, demos, and unverified Claude-generated code). This structure replaces complex MCP server setups and subagent orchestration with fewer moving parts.
Why does a CLAUDE.md file matter for each project?
A CLAUDE.md at the root of each repository acts as a guardrail for Claude Code. It tells Claude what stack the project uses, what the deployment target is, what tests to run before commits, and which files it must not touch. Because Claude Code is powerful and therefore dangerous, this file prevents hallucinated file paths and accidental damage to production code.
How do I triage problems each morning as a solo operator?
Run a script overnight that pulls errors from each app into the intel directory as a dated markdown file. In the morning, open Claude Code and ask it to read the latest intel file and report what needs attention. A slash triage command can also pull urgent Gmail messages and rank what's bleeding versus what's merely interesting, replacing a full monitoring dashboard.
What are the three slash commands that handle most daily operations?
Slash status runs a health check across all apps, confirming servers, databases, and cron jobs are working. Slash triage reads the latest intel file plus urgent Gmail and ranks what needs attention in the next two hours. Slash ship runs a pre-flight checklist (tests, migrations, environment variables) before deploying, stopping if any check fails. All three live as markdown files in the ops directory.
When should I use the scratch directory vs apps?
Use scratch for every experiment, client demo, half-baked idea, or any code Claude generates that you're not sure about. It never touches apps or ops. If code in scratch survives a week and proves useful, promote it to apps. Otherwise, delete the folder. Apps is reserved strictly for production repositories with real users, keeping production clean and stable.
Want more like this?
I publish practical AI automation, GenAI engineering, and faceless content workflows on YouTube every week.
Subscribe to bizflowai.io on YouTube — never miss a new tutorial.
Planning an AI automation project or need a second opinion on your architecture?
Connect with me on LinkedIn — Lazar Milicevic, GenAI Engineer & bizflowai.io Founder.
Visit bizflowai.io for our services, case studies, and AI consulting.
Frequently asked questions
What is the four-directory structure for running a solo business with Claude Code?
It's a minimal setup using exactly four top-level folders: apps (production repositories, each with its own CLAUDE.md), ops (master CLAUDE.md, slash commands, and runbooks), intel (daily logs, metrics, and error captures dumped as dated markdown files), and scratch (experiments, demos, and unverified Claude-generated code). This structure replaces complex MCP server setups and subagent orchestration with fewer moving parts.
Why does a CLAUDE.md file matter for each project?
A CLAUDE.md at the root of each repository acts as a guardrail for Claude Code. It tells Claude what stack the project uses, what the deployment target is, what tests to run before commits, and which files it must not touch. Because Claude Code is powerful and therefore dangerous, this file prevents hallucinated file paths and accidental damage to production code.
How do I triage problems each morning as a solo operator?
Run a script overnight that pulls errors from each app into the intel directory as a dated markdown file. In the morning, open Claude Code and ask it to read the latest intel file and report what needs attention. A slash triage command can also pull urgent Gmail messages and rank what's bleeding versus what's merely interesting, replacing a full monitoring dashboard.
What are the three slash commands that handle most daily operations?
Slash status runs a health check across all apps, confirming servers, databases, and cron jobs are working. Slash triage reads the latest intel file plus urgent Gmail and ranks what needs attention in the next two hours. Slash ship runs a pre-flight checklist (tests, migrations, environment variables) before deploying, stopping if any check fails. All three live as markdown files in the ops directory.
When should I use the scratch directory vs apps?
Use scratch for every experiment, client demo, half-baked idea, or any code Claude generates that you're not sure about. It never touches apps or ops. If code in scratch survives a week and proves useful, promote it to apps. Otherwise, delete the folder. Apps is reserved strictly for production repositories with real users, keeping production clean and stable.