A few days ago I wrote about solving portable Claude context with a symlink instead of an MCP server. The setup was simple: a private GitHub repo with my CLAUDE.md, cloned on two machines, symlinked into place. Two commands. Done.
That was the right solution for the original problem. But the original problem was small: make Claude remember who I am on both machines.
The problem grew.
The toolkit outgrew the file
The first version of claude-context had three things: a CLAUDE.md file, a persona definition, and six agent markdown files (code review, technical writing, editing, specs, research, test analysis). Everything Claude needed to know about how I work, loaded at session start.
Then I started building skills — custom slash commands that Claude Code executes like macros. /checkpoint stages and pushes all my repos. /pdf converts markdown to styled PDFs. /runbook generates operational documentation with rollback steps and escalation contacts.
Then came templates. Meeting notes with decisions and action item tables. Architecture decision records with auto-numbering. 1:1 coaching notes with growth goal tracking. Process documentation with Mermaid flowcharts.
Then more agents. A change advisor that evaluates blast radius before I approve anything. A mentor coach that helps me prepare for 1:1s. A process mapper for documenting the gap between "how we do it" and "how we should do it." An incident reporter that structures blameless post-mortems.
The repo went from 8 files to 30. And the problem shifted from "Claude doesn't know who I am" to "Claude doesn't have access to how I work."
The constraint that shaped everything
I use Claude Code in two environments. One is personal — side projects, home lab infrastructure, this blog. The other is work — enterprise engineering at a healthcare company. Different machine, different vault, different data.
The rule is absolute: work data and personal data do not mix. Not in the same vault, not in the same repo, not in the same conversation. There's no gray area here. Patient-adjacent systems, compliance requirements, corporate policy — the wall exists for good reasons.
But the way I work doesn't change between 9 AM and 9 PM. I still want structured meeting notes. I still want architecture decision records. I still want an agent that asks "what breaks if this goes wrong?" before I approve a change. The tools are the same. The data they touch is completely separate.
That's the design constraint: share the toolkit, never the content.
What's portable and what isn't
The dividing line from the first post still holds — if it describes how I work, it's portable. If it describes what I'm working on, it stays local. But with 30 files, the line needed to be explicit.
Portable (lives in claude-context, syncs to both environments):
| Type | Examples |
|---|---|
| Skills |
/meeting-notes, /decision-record, /runbook, /pdf
|
| Agents | CodeReview, ChangeAdvisor, MentorCoach, ProcessMapper, IncidentReporter, Scribe, Editor |
| Templates | Meeting Notes, Decision Record, Runbook, 1:1 Notes, Process Doc |
Stays local (environment-specific, not portable):
| Type | Examples |
|---|---|
| Skills |
/tailor (tied to personal resume) |
| Agents | LabOps (home lab infrastructure), BlenderArtist (3D modeling), AppStoreOptimizer (iOS app), InfrastructureMaintainer |
| Templates | Lab Note, Opportunity (market evaluation), Marketing Plan |
| Data | Everything in each Obsidian vault, project notes, accumulated memory |
Some skills straddle the line. /checkpoint lives in the repo and syncs everywhere, but it detects which machine it's on — full behavior on the personal Mac (15 repos, build verification, Homepage sync), stripped-down fallback on any other machine (just commit and push whatever directory you're in). Same file, environment-aware behavior.
The general test: could someone on a different team, with different projects, use this tool and get value from it? If yes, it's portable. If it assumes knowledge of my specific infrastructure, repos, or projects, it stays local.
The repo structure now
claude-context/
├── CLAUDE.md ← global context (symlinked to ~/.claude/CLAUDE.md)
├── personas/
│ └── charlie-seay.md
├── agents/
│ ├── change-advisor.md ← new
│ ├── code-review.md
│ ├── editor.md
│ ├── incident-reporter.md ← new
│ ├── mentor-coach.md ← new
│ ├── process-mapper.md ← new
│ ├── research.md
│ ├── scribe.md
│ ├── tech-spec.md
│ └── test-results-analyzer.md
├── commands/
│ ├── meeting-notes.md ← new
│ ├── decision-record.md ← new
│ ├── runbook.md ← new
│ ├── pdf.md
│ ├── clone.md
│ ├── brand-name.md
│ ├── checkpoint.md
│ └── ...
└── templates/
├── 1-1-notes.md ← new
├── decision-record.md ← new
├── meeting-notes.md ← new
├── process-doc.md ← new
└── runbook.md ← new
Setup on a new machine is still two commands:
git clone https://github.com/youruser/claude-context.git ~/Projects/claude-context
ln -sf ~/Projects/claude-context/CLAUDE.md ~/.claude/CLAUDE.md
The symlink gives Claude Code your global context at session start. Skills in commands/ get symlinked to ~/.claude/commands/ so they're available as slash commands everywhere. Agents and templates are referenced by the global CLAUDE.md, which points to them relative to the repo root.
The drift problem
Here's where it gets interesting. I also have an Obsidian vault for personal projects. Obsidian has a Templates plugin that inserts templates from a Templates/ folder. Agents live in an Agents/ folder where Claude reads them for task-specific behavior.
So the same files exist in two places: the claude-context repo (canonical, git-synced) and the Obsidian vault (where I actually use them day-to-day). Edit a template in Obsidian, forget to update the repo — drift. Push a new agent definition through the repo, forget to copy it to the vault — drift.
Drift is the thing that kills two-copy systems. Not immediately. Slowly. You don't notice until you're on the work machine and the meeting notes template is missing the "Follow-up" section you added two weeks ago.
The fix: automated drift detection
My /checkpoint skill already runs after every work session — it stages, commits, and pushes all tracked repos. I added a step: after committing everything, diff every portable file between the repo and the vault.
The mapping table handles the naming convention difference (the repo uses kebab-case, the vault uses Title Case):
| claude-context | Vault |
|-----------------------------|--------------------------------|
| agents/change-advisor.md | Agents/ChangeAdvisor.md |
| agents/code-review.md | Agents/CodeReview.md |
| templates/meeting-notes.md | Templates/Meeting Notes.md |
| templates/1-1-notes.md | Templates/1-1 Notes.md |
| ... | ... |
If any pair differs, checkpoint reports which files drifted, shows a summary of the differences, and asks which version to keep. Then it copies the winner to the other location and commits.
On the work machine, where vault paths don't exist, the check skips entirely. It only runs where both locations are present.
This isn't clever. It's a diff in a loop. But it catches the problem that actually kills multi-copy systems: the quiet divergence you don't notice until it matters.
What I'd do differently for a team
This setup is built for one person across two environments. If I were scaling it for a team, a few things would change:
What stays the same: The repo-as-source-of-truth pattern. Git is the right sync layer for structured text files. Everyone clones, everyone pulls. It's solved infrastructure.
What changes:
- Templates become a shared library, not a personal toolkit. A team needs consensus on what a decision record looks like. That's a conversation, not a solo design decision.
- Agents get scoped. My ChangeAdvisor asks questions that matter to me specifically — blast radius, rollback time, stakeholder notification. A team's version might weight differently based on their deployment model.
- The drift check becomes CI. Instead of running at checkpoint, a GitHub Action diffs against a known-good state and flags PRs that modify shared templates without updating the version.
-
Skills need documentation, not just implementation.
/runbookworks because I wrote it and know what it expects. A team member picking it up needs a README, examples, and probably a--helpflag.
But honestly? Start with one person's portable repo. If it sticks, the team adoption path is just "clone this and tell me what's missing."
The pattern
If you're using Claude Code across environments — work and personal, desktop and laptop, or even just "my main machine" and "the one I use on the couch" — here's the pattern:
- Create a private repo for your portable AI toolkit
- Put your global CLAUDE.md, agents, templates, and skills in it
-
Symlink the CLAUDE.md to
~/.claude/CLAUDE.mdon each machine - Draw the line between what's portable (how you work) and what's local (what you're working on)
- Detect drift if the same files exist in multiple locations — automate the check so you don't have to remember
The separation isn't just organizational hygiene. It's what makes the toolkit trustworthy. When I type /meeting-notes at work, I know it's pulling from the same template I refined on a personal project last weekend — and I know it's not pulling anything else.
One Claude. Two lives. Same toolkit. Separate data. That's the whole thing.
Originally published at charlieseay.com
Top comments (0)