the second brain kit: my entire claude code system in one file you can paste
this morning a friend texted me: "I went camping this weekend and all I could think about was Claude. what do I tell it to do with my computer and files?"
he's not a developer. he's the friend who coaches me on my health. he watched me ship an app to the App Store at 4am, saw the screenshots of my 3am sessions, and wanted in.
so i started explaining my setup over text. the master folder. the hidden memory directories. the CLAUDE.md routing. the flush command. three messages in, i realized something: i've written thousands of words about this system across my articles — the .claude/ folder, how sessions compound, agent memory architectures — but there was no version someone could actually take.
so i built one. a single file. you paste it into Claude Code and your Claude builds the entire system for you — folders, rules, memory, the works. it even interviews you to fill in who you are.
this post is that file, plus the explanation of why each piece exists.
bookmark this one. it's the whole system.
let's get into it.
how any of this is possible
everything in this kit rides on five mechanics that Claude Code gives you for free. nobody explains them together, so here they are:
the behavioral layer — Claude Code auto-loads
~/.claude/CLAUDE.mdplus every file in~/.claude/rules/at every session start. whatever you put there shapes every conversation.the routing layer — it also auto-loads the CLAUDE.md of the folder you launch from, and lazily loads subfolder CLAUDE.mds only when it actually works in them. context arrives when it's relevant, not before.
the persistence layer — it keeps a per-launch-location memory folder and saves every transcript automatically. every conversation you've ever had is on your disk.
the automation layer — any markdown file in
~/.claude/commands/becomes a slash command. no code, no plugin. a text file is a program now.the compounding layer — everything is plain markdown, so Claude itself can read, write, and maintain its own brain.
that's the whole magic. no plugin, no product, no subscription. the system is just those five mechanics used deliberately.
what you're actually building — an agent, not a notes app
don't mistake this for a filing system. what you're building is the operating system for an autonomous AI agent — the same pattern the always-on agent frameworks use.
the lineage: OpenClaw runs each agent off a workspace of markdown files — AGENTS.md (operating rules), SOUL.md (personality), USER.md (owner profile), MEMORY.md (long-term knowledge), plus daily memory logs — read at the start of every conversation. Hermes (from NousResearch) evolved the pattern: keep almost nothing in the prompt, retrieve knowledge on demand, run scheduled loops so the files update themselves while you sleep. i broke down all three architectures in 3 ways to give your AI agent a memory.
this kit is that architecture, ported to Claude Code. the Framework files are the agent's organs:
- SOUL is who it is
- USER is who it serves
- AGENTS is what it may do on its own
- HEARTBEAT is what's alive right now
- MEMORY is the index to everything it knows
two upgrades over the originals: the index + domain file split keeps the context window lean (a single MEMORY.md grows until it drowns the agent), and /flush gives it a deliberate capture cycle instead of hoping knowledge sticks.
once it's running you'll notice the shift: you're not "using a chatbot." you're working with something that has a personality, remembers yesterday, knows its own rules, and picks up where it left off. that's the point.
how the kit works
two documents. document 1 is a build prompt — you don't follow the instructions, your Claude does. document 2 is the /flush command — the save button that makes tomorrow's session smarter than today's.
the placeholder trick: the kit uses HUB for your master folder name and YOURNAME for your mac username. you never fill these in by hand. you paste the document and tell Claude to substitute them. it runs whoami itself. the last placeholder — who you actually are — gets filled by Claude interviewing you before it writes USER.md.
that's the part i'm proudest of: the kit isn't documentation. it's an executable.
document 1 — the build prompt
how to use this: open Terminal, type claude, paste this ENTIRE document and say: "Build this exactly. My master folder will be ~/HUB (I'll tell you the real name). Replace every YOURNAME with my real username (run whoami to get it). Ask me the interview questions at the end before writing USER.md."
=== STEP 1 — THE MASTER FOLDER ===
Create (rename the topic folders to fit your life):
~/HUB/
├── CLAUDE.md
├── Framework/
├── Health/
├── Finance/
├── Work/
├── Projects/
├── Personal/
└── Logs/
└── memories/
├── daily/
└── transcripts/
~/HUB/CLAUDE.md contents:
---
# CLAUDE.md — ~/HUB House Rules
~/HUB is my master life folder. Not a code project — a filesystem organized
by topic. Always launched from this root.
## Session startup (every session, in order)
1. Read Framework/HEARTBEAT.md — what's in flight
2. Read Framework/threads.md — open action items
3. Read today's log at Logs/memories/daily/YYYY-MM-DD.md if it exists
4. Greet me using the template in Framework/AGENTS.md
## Where files go
- Money, bills, receipts, taxes → Finance/ (receipts named "YYYY-MM Description")
- Health, labs, workouts → Health/
- Job stuff → Work/
- Things I'm building → Projects/ (one subfolder each, each gets its own CLAUDE.md)
- Family, documents, identity → Personal/
## Hard rules
- NEVER delete or move anything in Finance/ or Personal/ without asking me first
- Don't create new top-level folders without discussing it
- No vague filenames ("scan.pdf", "doc(1).pdf") — always rename descriptively
- At the end of every session, run /flush
---
=== STEP 2 — THE GLOBAL BRAIN (~/.claude) ===
~/.claude/CLAUDE.md contents (thin index — keep it under 30 lines forever):
---
# Global Rules — all projects
Behavioral rules live in ~/.claude/rules/ and auto-load every session:
| File | What |
|------|------|
| core-behaviors.md | Push back, surface assumptions, stop when confused |
| hard-rules.md | Non-negotiables |
---
~/.claude/rules/core-behaviors.md contents:
---
# Core Behaviors
## Push back when warranted
You are not a yes-machine. When my approach has problems: point out the issue,
explain the downside, propose an alternative, accept my decision if I override.
## Surface assumptions
Before doing anything non-trivial, state the assumptions you're making and let
me correct them.
## Confusion management
If something is unclear or contradictory: STOP. Name the confusion. Ask.
Never silently guess.
## Simplicity
Prefer the boring, obvious solution. If it can be done in fewer steps, do that.
---
~/.claude/rules/hard-rules.md contents:
---
# Hard Rules
1. Do not expand scope beyond what I asked
2. Touch only what you're asked to touch
3. Never overwrite a whole file when a small edit works
4. Never invent info you don't have — say "I don't know" and ask
5. Flag anything risky BEFORE doing it, not after
6. Never mark a task done without verifying it actually worked
7. After any correction from me, append the pattern to Framework/lessons.md
so it never happens again
---
Also create ~/.claude/settings.json with this (or merge the "hooks" key into
it if the file already exists):
---
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "printf '{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"Current local time: %s\"}}\\n' \"$(date '+%Y-%m-%d %H:%M:%S %Z')\" 2>/dev/null || true",
"timeout": 5
}
]
}
]
}
}
---
This is the clock hook: it injects the real time into every prompt you send.
Without it, the model has NO way to know what time it is and will confidently
guess every timestamp it writes (see the postscript for how I learned this).
=== STEP 3 — THE FRAMEWORK (the brain's organs) ===
~/HUB/Framework/SOUL.md:
---
# SOUL — how you talk to me
- Direct and concise. No filler, no "Great question!", no repeating my question back
- Push back when I'm wrong. Agreement isn't helpfulness
- When confident, be confident. When unsure, say so plainly
---
~/HUB/Framework/USER.md:
(Claude: interview me to fill this — name, what I do, family situation,
what I'm trying to accomplish this year, how I like to work, pet peeves.
Keep it under 40 lines. Ask before ever editing it later.)
~/HUB/Framework/AGENTS.md:
---
# AGENTS — operating manual
## Autonomy levels
| Action | Rule |
|--------|------|
| Read any file in ~/HUB | always allowed |
| Append to daily log | always allowed |
| Update HEARTBEAT/threads | allowed when status clearly changed |
| Edit lessons/infra/connections | show me the entry first |
| Edit USER.md or SOUL.md | never without me asking |
| Delete/move Finance or Personal files | never without asking |
## Session greeting template
After the startup reads, greet with exactly:
Framework loaded. [N] open threads, [N] active projects.
Last session: [one-line summary from most recent daily log]
We left off at: [next step from HEARTBEAT or last log]
Heads up: [anything time-sensitive — skip line if nothing]
---
~/HUB/Framework/HEARTBEAT.md:
---
# HEARTBEAT — active state
(one section per active project: status, last touched, next step.
Claude keeps this current.)
---
~/HUB/Framework/MEMORY.md:
---
# MEMORY — index only, 35 lines MAX. Never put content here.
| File | What |
|------|------|
| lessons.md | mistakes + patterns, read at session start |
| threads.md | open action items, read at session start |
| infra.md | tools, apps, how my stuff is configured |
| projects.md | quick reference table of all projects |
| connections.md | people |
---
Also create as empty files with just a # title line:
lessons.md, threads.md, infra.md, projects.md, connections.md
=== STEP 4 — THE LOGS ===
Create empty:
~/HUB/Logs/decisions.md (the decision register: one line per durable
decision — WHAT + WHY + [ACTIVE]/[REVERSED] tag.
Reversals flip the tag, never delete. Stops
future sessions from relitigating or silently
contradicting old choices)
~/HUB/Logs/config-changelog.md (every change to the system itself)
~/HUB/Logs/thread-archive.md (closed action items)
=== STEP 5 — THE /FLUSH COMMAND ===
Save DOCUMENT 2 as:
/Users/YOURNAME/.claude/commands/flush.md
(replace YOURNAME and HUB inside it the same way)
This is the save button. It's what makes tomorrow's session smarter than today's.
=== STEP 6 — THE HABITS (the system is 20% files, 80% these) ===
1. ALWAYS launch from ~/HUB (cd ~/HUB then claude). Never from random folders
2. End every session with /flush — no exceptions, it's 30 seconds
3. When Claude messes up: "add that to lessons so it never happens again"
4. When something should be permanent: "remember that" or "add to CLAUDE.md"
5. One topic per session. Long meandering convos = dumber Claude. Start fresh
6. Once a week ask: "read the last 7 daily logs and tell me what patterns
you see" — that's how observations become durable knowledge
=== THE SIZE RULES (what keeps it fast) ===
Every always-loaded file costs context window every single session. The
system stays sharp because the always-on layer stays SMALL:
- MEMORY.md: hard cap 35 lines. It's an index, not a notebook. If it's
growing, knowledge is leaking in — move it to a domain file. (I enforce
mine with a hook; discipline works too)
- Global ~/.claude/CLAUDE.md: under 30 lines forever. Also an index
- Master folder CLAUDE.md: when it passes ~200 lines, split rules out into
~/.claude/rules/ files. Mine hit 400+ lines once and Claude started
ignoring the stuff buried at the bottom — adherence came back the day
I split it
- USER.md: under 40 lines
- Domain files (lessons, infra, threads...) CAN grow — they're read
on-demand, not auto-loaded. But when an entry is proven wrong, update or
delete it. Stale knowledge is worse than no knowledge
Rule of thumb: the always-on layer (CLAUDE.mds + rules + MEMORY index)
should fit in a couple thousand tokens. Fat startup = dumb agent.
=== WHAT NOT TO BUILD YET ===
Obsidian vaults, symlinks, extra hooks, semantic search, custom agents —
that's month 2+. (The clock hook in STEP 2 is the one exception: it's three
lines of JSON and without it your agent fabricates timestamps from day one.)
Every advanced piece gets added AFTER the basics annoy you into it.
Build the above, use it two weeks, and the system will tell you what it needs.document 2 — the /flush command
this is the most important thing in the kit. without it, every session evaporates when you close the terminal. with it, every session leaves a structured trail the next session picks up.
what it does, in order: writes a readable transcript of the conversation, writes a session block to today's daily log (what shipped, decisions, files touched, discoveries), then routes every piece of knowledge to its permanent home — mistakes to lessons.md, tool facts to infra.md, people to connections.md, project status to HEARTBEAT, big decisions (with the WHY) to the decision register. it checks for duplicates and contradictions before writing, health-checks your open threads, and leaves a one-line pointer for the next session.
save it as /Users/YOURNAME/.claude/commands/flush.md:
End the current session and capture everything to the daily log.
0. **First run only:** if any folder or file referenced below doesn't exist yet, create it.
1. **Determine today's date AND time** by running `date "+%Y-%m-%d %H:%M"` NOW.
Every timestamp you write during this flush must come from a real source —
this `date` call, a message timestamp from the session JSONL, or the clock
hook. NEVER write an [HH:MM] from memory: you have no internal clock, and
an unsourced time is a fabrication.
2. **Extract raw conversation transcript (delegate to a Haiku agent):**
- Spawn a **Haiku model agent** using the `Agent` tool with `model: "haiku"` to do the mechanical parsing
- The agent's task: find the current session JSONL file by searching `/Users/YOURNAME/.claude/projects/-Users-YOURNAME-HUB/` for .jsonl files, pick the most recently modified one, verify its first user message matches today's date, then parse it with Python and write the transcript
- Parsing rules for the agent:
- Extract human messages and assistant text responses
- Truncate assistant responses at 1000 chars if very long, but preserve key content
- Keep tool names AND meaningful result summaries (file paths found, errors hit, key data returned)
- Strip: base64 blobs, raw JSON dumps over 500 chars, internal IDs
- Count existing transcript files for today to determine session number
- Write to `/Users/YOURNAME/HUB/Logs/memories/transcripts/YYYY-MM-DD-session-N.md`
- Format:
# Transcript — YYYY-MM-DD Session N
---
**Human:** [message]
**Assistant:** [response]
**Tool:** [tool name] → [brief result]
**Human:** [message]
...
- Run this agent in the **background** — don't wait for it. Continue with step 3 immediately.
- For quick sessions, skip with `/flush quick` (no transcript, just daily log + checks).
3. **Create or append to** `/Users/YOURNAME/HUB/Logs/memories/daily/YYYY-MM-DD.md`
4. **If the file doesn't exist yet**, start with `# YYYY-MM-DD` header and `## Sessions` section.
5. **Count existing sessions** in the file to determine the session number.
6. **Write a session block** with this structure. Use `[[wikilinks]]` for Framework files and project names. Include a done list at the end of the summary. The `[HH:MM]` in the header is the session START time — take it from the session JSONL's first message timestamp or the clock hook, never from memory:
### Session N — [HH:MM] [Topic Summary]
**Summary:** [1-2 paragraph recap of what was accomplished. Link project
names and Framework files like [[MEMORY]], [[HEARTBEAT]], [[USER]].]
**Shipped:** [bulleted list of things completed this session]
**Decisions Made:**
- [decision and reasoning]
**Files Changed:**
- Created `path/to/file` — why
- Edited `path/to/file` — what changed
- Deleted `path/to/file` — why
**Discoveries:**
- [unexpected findings, bugs, insights]
**Open Threads:**
- [ ] [things to follow up on]
**Quality check — good vs bad session blocks:**
BAD: "Worked on various things. Updated some files. Made progress."
GOOD: "Organized 2024 tax receipts into Finance/2024/ — 47 files renamed to
'YYYY-MM Description' format. Found 3 duplicate insurance PDFs, deleted
after confirming. Key insight: bank statements download with wrong dates."
The test: could a future agent reading ONLY this log reconstruct what
happened and why?
7. **Add to Extract Queue** at the bottom of the daily log (create section if it doesn't exist).
Categorize each item into the correct domain file — **NEVER write `→ MEMORY:`** — MEMORY.md is an index only.
Route to:
- `→ lessons:` — mistakes, patterns, things that broke and how to avoid them
- `→ infra:` — tools, apps, configs, how things are set up
- `→ connections:` — people, collaborators, new contacts
- `→ projects:` — new projects to add to quick reference table
- `→ threads:` — new action items opened, or existing threads to close
- `→ USER:` — user preferences, working style observations
- `→ HEARTBEAT:` — project status changes
- `→ decisions:` — durable decisions made this session (what + WHY + status).
A decision = a deliberate choice between alternatives that future sessions
must respect — not routine task picks
Example:
## Extract Queue
### Session N new items:
- → lessons: HEIC files can have .jpg extension — check before reading
- → infra: scanner saves to ~/Documents/Scans by default
- → threads: [CLOSE] Organize tax receipts — DONE
- → USER: prefers decisive cleanup over analysis paralysis
- → HEARTBEAT: receipt organization COMPLETE
8. **Update HEARTBEAT.md** (`/Users/YOURNAME/HUB/Framework/HEARTBEAT.md`) if any project statuses changed during this session.
9. **Apply extract queue items immediately (with verification).** For each `→` item in this session's extract queue, run this verification gate BEFORE writing:
**Verification gate (mandatory per item):**
- (a) **Right target?** Is this the correct domain file for this content?
- (b) **Duplicate check:** Read the target file. Does a semantically similar
entry already exist? If yes → SKIP and note
`SKIPPED (duplicate): [item] — similar to: [existing]`
- (b2) **Contradiction check:** Does this new entry contradict or supersede
an existing entry in the target file? If yes → UPDATE the old entry with
current info instead of adding a new line. Note:
`UPDATED (superseded): [old claim] → [new claim]`. Dead knowledge is as
bad as dead code — don't let contradictory claims coexist.
- (c) **Cross-file check:** Does HEARTBEAT/connections also need updating
for this item?
- (d) **Source check:** Does the entry include when/where it was learned?
If not, add `(source: YYYY-MM-DD session)` before writing.
If an item fails verification, skip it and report why at the end of step 9.
Then for each verified `→` item, apply it now to the matching file in
`/Users/YOURNAME/HUB/Framework/` (lessons.md, infra.md, connections.md,
projects.md, threads.md, USER.md — ask before changing USER.md).
For `→ decisions:` append a one-line entry to
`/Users/YOURNAME/HUB/Logs/decisions.md`:
`- **[ACTIVE]** [YYYY-MM-DD] <decision> — **why:** <reasoning>`
If this session reversed a prior decision, flip the old entry's tag to
`[REVERSED YYYY-MM-DD]` — never delete it — and update any rule file that
encodes the old decision in this same flush.
When closing a thread, also append one line to
`/Users/YOURNAME/HUB/Logs/thread-archive.md`:
`- [YYYY-MM-DD] Thread name — resolution`
10. **Thread health scan.** Single pass over threads.md — read it once, check everything:
a. **Blocked thread check.** Any thread with blocked/waiting status where
follow-up date has passed:
FOLLOW-UP DUE: "[thread]" — follow-up date was [date]. Time to ping.
b. **Stale kill.** Any thread marked in-progress that hasn't moved in 7+ days:
STALE: "[title]" has been sitting for [N] days. Ship, rework, or kill?
c. **Too many open?** If more than ~10 threads are open, say so and suggest
which to close or park.
11. **Config changelog.** If any rules, settings, commands, or CLAUDE.md files
were created or modified during this session, append entries to
`/Users/YOURNAME/HUB/Logs/config-changelog.md`:
## YYYY-MM-DD
- [HH:MM] `file` — what changed and why
([HH:MM] = the output of `date "+%H:%M"` at write time — never estimated.)
12. **Commit the knowledge layer to git (only if ~/HUB is a git repo — skip
this step silently if not).** After all the above writes:
cd ~/HUB && git add -A && git commit -m "Session YYYY-MM-DD: <short summary>"
NEVER commit passwords, API keys, or ID documents. If any file like that
changed, do not commit it — tell the user instead. Never `git push` —
this repo stays local-only.
13. **Close out.** Two things in one block:
**Next session pointer:**
**NEXT SESSION:** [One specific thing to do next. Not three. One.]
**Report:** transcript path (if not skipped), daily summary path, extract
items applied, thread health results.
Do NOT ask questions. Review the full conversation history and extract
everything relevant. Be comprehensive — this log is the raw material for
long-term memory.the decision register — the file that stops your agent from arguing with itself
there's one file in the kit that didn't exist in my system until it cost me real pain: Logs/decisions.md.
here's what happened. my system's founding rule said "this folder is never a git repo" — written down, encoded in the rule files. three months later, a session deliberately reversed that decision, for good reasons, and set up versioning. but the old rule text survived in the rule files. the next session read the stale rule, hit the live contradiction, and burned about 80k tokens of archaeology figuring out which version of reality was true.
the fix is a register: one line per durable decision, with three parts — WHAT was decided, WHY (the actual reasoning, so future-you can't relitigate it without seeing what past-you knew), and a status tag: [ACTIVE] or [REVERSED YYYY-MM-DD].
two rules make it work, and they're both baked into the flush command above:
- a decision is never deleted — its tag is flipped. the history of what you believed and when is part of the knowledge.
- reversing a decision means updating every rule file that encoded the old one, in the same session. a reversed decision with a stale rule file is exactly how my git contradiction survived a day.
what counts as a decision? a deliberate choice between alternatives that future sessions must respect — architecture, policy, tool pivots, kill/ship calls. not routine task picks. the flush command routes these automatically with → decisions:.
this file matters more the longer you run the system. by month two, your agent has opinions — and without the register, it will eventually argue with its own past self.
what the kit deliberately leaves out
my real system has more: three Obsidian vaults wired to the memory folders through symlinks, a semantic search engine indexing 16,000+ files, git versioning with a secret-sweep pre-commit hook, and seventeen behavior-patch files born from specific corrections. none of that is in the kit.
that's on purpose. every advanced piece of my setup got added AFTER the basics annoyed me into it. the rules that stuck are the ones born from actual friction, not hypothetical best practices — i wrote about that in the .claude/ folder breakdown. your version should grow from your friction, which will be different from mine.
build the kit, use it for two weeks, and the system will tell you what it needs next.
the honest part
the kit assumes a Mac (paths, whoami, Terminal). it assumes Claude Code on a paid plan. and it assumes the one habit no file can enforce: actually running /flush before you close the terminal. the system is 20% files, 80% habits. the files do nothing without the habits.
also: this pattern works because Claude Code's loading mechanics are stable and documented. if you're reading this from some other agent tool, the architecture still translates — markdown organs, index + domain files, a capture cycle — but the specific paths won't.
postscript: your agent has no clock
three days after this post was written, i caught the system in a months-long lie i didn't know it was telling.
my daily log said a session happened at 3:45am. the git commit for that same session — a real timestamp, from a real clock — said 11:55am. eight hours apart. i asked Claude what time it thought it was, and the honest answer was: it doesn't know. the harness injects today's DATE at session start, but the model has no internal clock and no sense of elapsed time. every [HH:MM] it wrote into my logs without running date first was a plausible-sounding guess — some landed close because it anchored on the session-start time, plenty didn't. months of them. the dates were real. the times were unreliable.
this is the "trust but verify" lesson from the fact-check section, except aimed at the system itself: an agent will confidently fill any gap it can't measure, including the current time. the fix wasn't a rule asking it to be careful — rules it has to remember are exactly the kind of thing it forgets. the fix was mechanical: a UserPromptSubmit hook that runs date and injects the real clock into every single prompt, plus a hard line in /flush banning any timestamp that didn't come from a command, a message timestamp, or the hook. and the old logs are recoverable, because ground truth existed all along in places the model never touched — git commit times and the per-message timestamps in the session files.
if your agent writes times anywhere, go check one against a commit. i'll wait.
(both fixes are now baked into the kit above — document 1 installs the clock hook, document 2 bans unsourced timestamps. if you built the kit before this postscript existed, add them.)
if you made it this far: paste document 1 into a fresh Claude Code session and watch it build. the whole thing takes about five minutes, and the interview at the end — where your Claude asks who you are so it can write USER.md — is the moment it clicks for most people.
my friend from the camping trip? he's getting this kit this week. his system will look different from mine in a month. that's the point.
i'm @Dogwiz. i build this stuff in public — the wins and the failures. if you build the kit and something breaks or something clicks, tell me. the kit gets better every time someone new runs it.