How the team works together in aicro-os — what git is, why your laptop doesn't auto-update, the morning habit that prevents 90% of problems, and what to do when things go sideways.
Last week Josh updated a skill in a pull request, merged it into the main branch, and then ran the skill from his laptop. He got the old version. The update was live on GitHub but invisible to his local Claude Code session. This guide explains why, and what to do about it.
Josh opened PR #221 to fix the /client-call-prep skill — a real bug in the prompt that was hurting client call quality. The PR merged. Hours later, he invoked /client-call-prep from a branch he'd been working on for a couple weeks. Claude ran the pre-fix version of the skill. The fix on main had no effect on what Josh's terminal was running.
This was not a bug in Claude Code or in GitHub. It is exactly how git works. The branch Josh was on had been forked from main weeks ago and never updated since. From git's point of view, "main" on his laptop and "main" on GitHub were two different things — connected by name only.
This pattern is everywhere on our team right now. As of today, we have feature branches sitting 47, 60, 90, and even 264 commits behind main. Anyone working on those branches is running ancient versions of every skill, every rule, every prompt, every helper script. We don't notice because the failures are silent — the old version still runs, it just runs wrong.
The fix is not technical. It's a daily habit, supported by three small Claude Code helpers we're shipping alongside this guide. By the end of this page you'll have:
Read it once. Bookmark the cheat sheet at the bottom. Run the daily ritual every morning. That's it.
Three sentences. If you remember nothing else, remember these.
fetch, pull, push, rebase) are how you ask.
┌─────────────────────┐
│ GitHub.com │
│ (the shared copy) │
│ │
│ main: commit X │ ◄────── PR #221 lands here
└──────────┬──────────┘
│
┌──────────┴──────────┐
│ │
git fetch git push
git pull (you send up)
(you pull down)
│ │
▼ │
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Josh's Mac │ │ David's Mac │ │ Doug's Mac │
│ main: W │ │ main: V │ │ main: X │
│ (3 behind) │ │ (5 behind) │ │ (current) │
└───────────────┘ └───────────────┘ └───────────────┘
GitHub holds the canonical "main." Every laptop has its own snapshot of main, which only updates when that person runs git pull. Until then, they keep working off the old version — even though the new version is sitting on GitHub.
Same picture applies to feature branches. When you create feat/my-thing, you're branching off whatever your local main currently is. If your local main is 60 commits stale, your feature branch starts 60 commits stale.
You can't tell whether your laptop is current just by looking at it. Git won't warn you. The files on your disk look the same whether you're 0 commits behind or 264 commits behind. The only way to know is to ask — either by running git fetch manually or by letting the tools we ship below check for you.
Plain English. Two sentences each, with an analogy. Read once, reference forever.
The whole project — every file, plus the history of every change ever made. Like a Google Doc with version history turned on, but for thousands of files at once.
A saved snapshot of your changes with a label. Each commit has a unique ID (like 73d9416) and a message describing what changed. Like hitting "Save As" on a document with a clear name attached.
A named line of changes that can move independently from main. You create one when you want to make edits without affecting everyone else's work. Like making a copy of a Google Doc to mark up, leaving the original alone until your version is ready.
The default branch — the "real" version of the project that everyone is supposed to end up running. The published version of a Google Doc that you don't edit directly.
Ask GitHub "what's new?" and download it to your laptop, but don't apply it to your working files yet. Checking your mailbox without opening any letters yet.
Fetch and apply — bring GitHub's latest version of a branch into your local copy of that branch. Checking mail and opening every letter into your inbox in one step.
Send your local commits up to GitHub so the rest of the team can see them. Nothing goes up automatically — you push when you're ready to share. Sending the marked-up Google Doc back to the team channel.
Take the changes on your branch and replay them on top of the latest main. After rebasing, your branch is current with main and your changes still exist, just at the new tip. Like taking your edits from the old copy of the doc and pasting them into the latest version of the doc.
Combine the changes from one branch into another (almost always: combine your feature branch into main). On AICRO we do this through pull requests. The team accepts your marked-up version and replaces the published doc with it.
A formal proposal on GitHub to merge your branch into main. The team reviews, comments, approves, then merges. Sending your draft doc to a stakeholder for approval before it goes live.
When git can't figure out how to combine two sets of changes automatically — usually because two people edited the same line. You resolve it by manually choosing which version to keep. Two people edited the same paragraph in the doc; you have to pick which version stays.
How many commits your branch is missing versus main ("behind") and how many it has that main doesn't ("ahead"). "You're 47 emails behind on this thread" — that's behind 47.
When you see origin/main, "origin" is just git's name for "GitHub." So origin/main means "what GitHub thinks main is right now." Your local main is what your laptop thinks main is. They drift apart until you sync them.
Every morning, before you open Claude Code, before you start a campaign, before you touch any file — run this. It is one command.
/syncType this in Claude Code. That's it. It fetches the latest from GitHub, tells you what changed, and offers to bring your current branch up to date.
What /sync does under the hood, in case you're curious:
git fetch origin --all --pruneAsks GitHub for every branch update and removes references to branches that no longer exist on GitHub.
Tells you what branch you're on, how many commits you're behind main, what skills or rules have changed on main since you last synced.
If your branch is behind, asks if you want to bring it up to date by replaying your changes on top of the latest main.
Offers to delete local branches whose remote counterparts have already been merged and deleted.
If you haven't run /sync today, do it before you start anything else. If you opened your laptop more than three hours ago and haven't synced, do it again. The cost is one command. The cost of skipping it is the PR #221 story.
/sync yet?If your Claude Code session doesn't recognize /sync, you're either on an older version of the repo (run git pull origin main on your local main first) or in a Claude Code session that started before the command was added. Restart Claude Code from your terminal.
The Session Start banner that ships with this guide will fail silently if you have no internet. You can keep working — git is happy offline. Just remember to sync before you push anything up.
Run /sync again any time:
Not every change needs the full pull-request process. We have three tracks, calibrated to how much damage a bad change could do.
.claude/skills/, .claude/rules/, .claude/commands/,
execution/, scripts/, dashboards/, _mcp/,
.github/workflows/, apps/
These run against real client data. A bug in a skill or a script propagates to every client and every teammate the moment it merges. We keep the strict bar here — branch, PR, two reviewers, squash-merge.
01_clients/{slug}/profile.md, 01_clients/{slug}/playbook/,
01_clients/{slug}/campaign-briefs/, 00_foundation/,
knowledge_base/ (non-methodology)
Client structural files are read-mostly content — playbooks, ICPs, campaign briefs. They feed copywriting and strategy, so an error matters, but they're not executable. One reviewer is enough; speed matters more than belt-and-suspenders.
01_clients/{slug}/notes/{YYYY-MM-DD}-*.md only
Timestamped notes — weekly briefs, call notes, ad-hoc observations — are append-only journal entries by one owner. The cost of a bad note is essentially zero. Forcing a branch and a PR for every weekly brief creates exactly the long-lived branches that cause the PR #221 problem. If you're the GTME for this client per Airtable, commit straight to main.
If you're not sure which track applies, default up — Track B is the safer choice than Track C, Track A is safer than B. The friction cost of one extra reviewer is much smaller than the cleanup cost of a bad change that landed without review.
Any branch you keep open for more than three days needs to be rebased on the latest main. The longer a branch lives without syncing, the harder the eventual merge becomes. Three concrete checkpoints:
/sync handles this.Our team is mostly GTM operators making client-context updates, not software engineers shipping features. The blanket "two reviewers for everything" rule from our original git workflow was a copy-paste from how engineering teams work — it didn't fit. The two-track model puts strict review where the risk actually lives (code) and removes friction where it doesn't (notes). Most weekly updates fall into Track C and become a single commit to main.
You don't need to memorize git. We wrapped the four operations you'll do every day into Claude Code commands. Type a slash, press tab, you're done.
/sync
daily
The morning ritual. Run this first thing every day.
/sync — no arguments. The command figures out the rest.
/push "what changed"
ship
The full ship-it flow in one command — branch, commit, push, open PR.
/push "fix henry-ai voice rule for E1 hooks" — branch will be named fix/henry-ai-voice-rule-for-e1-hooks, PR title will match.
/push will refuse and tell you to /sync first. This prevents shipping a PR that's based on an ancient version of main.
/save-context [name]
before /clear
Save what you're working on before clearing the conversation.
session-context.md at the project root, so you can pick it back up after /clear.
/save-context capitalize-weekly-brief — saves under that label so you can resume specifically that thread later.
/resume
after /clear
Restore session context after clearing.
session-context.md and walks you through which saved thread to pick up.
/resume — pick from a list of saved contexts.
Even if you forget to run /sync, Claude Code will now show you a banner at the start of every session telling you how far behind main you are and which skills or rules differ from main. You can't miss it. If it warns you, run /sync.
You can absolutely use git fetch, git pull, git rebase, git push, git status, git log directly from your terminal. The slash commands are wrappers, not replacements. If you prefer raw git, the daily ritual is:
git fetch origin # if on main: git pull origin main # if on a feature branch: git rebase origin/main
Both paths get you to the same place.
Git's error messages are scary but the situations are usually simple. Here are the four you'll hit, in order of frequency.
origin/main by N commits"What's happening: Other people have merged things to main since you last synced. Your laptop is running an old version.
Fix: Run /sync. If you're on a feature branch, it will offer to rebase. Say yes. If you're on main, it will offer to pull. Say yes.
Prevent: Run /sync every morning. The Session Start banner will warn you if you forget.
What's happening: Two people edited the same lines in the same file. Git can't auto-decide which version wins.
Fix: Open the file. You'll see markers like:
<<<<<<< HEAD my version of the line ======= the other version of the line >>>>>>> origin/main
Pick the right version (or combine them), then delete all three marker lines. Save the file. Run git add <file> then git rebase --continue (or git merge --continue, depending on what you were doing).
If you're not sure which version to keep — stop and ask. Slack #aicro-ops with the file path, or ping Anderson, David, or Josh directly. Conflicts in copy or rules are higher-stakes than they look; resolving them wrong silently undoes someone else's work.
Prevent: Rebase often. The more frequently you rebase, the smaller each conflict is. A branch synced daily rarely conflicts at all.
What's happening: You ran git commit without realizing you were on the main branch. Your changes are on local main but not yet pushed.
Fix: Don't push. Run this from your terminal:
# Save your work to a new branch git branch oops-rescue # Reset main back to where GitHub thinks it is git reset --hard origin/main # Switch to your rescue branch — your changes are here git checkout oops-rescue
You're now on a feature branch with your changes intact, and local main is back to clean. Rename the branch to something meaningful (git branch -m feat/whatever) and proceed normally.
Prevent: The Session Start banner shows your current branch. Glance at it before you start editing. If it says main and you're about to change something other than a client note, create a branch first: git checkout -b feat/whatever.
What's happening: You ran some destructive command (git reset, git checkout over uncommitted changes, git rebase that went sideways) and your file is gone or your commits seem to have vanished.
Fix: Don't panic. Git keeps a log of every state your branch has been in for ~30 days, even after a "reset." Run:
git reflog
You'll see every recent action. Find the line that looks like the state you want back (right before the destructive command). Note its short hash on the left (like a1b2c3d). Then:
git reset --hard a1b2c3d
Your branch is back to that state. If you're unsure which line to pick — stop and Slack Anderson or Josh. Don't run more commands; you might overwrite recovery options.
Prevent: Commit small and often. Push to a feature branch as soon as you have something you'd be sad to lose. The more committed work you have, the harder it is to actually lose anything.
If a git command fails twice and you don't understand the error, stop. Don't run more commands trying to fix it — you can dig the hole deeper. Take a screenshot of the terminal, post in #aicro-ops, and ping Anderson or Josh. Most "I broke git" situations are fully recoverable if you stop early.
Three commands tell you everything you need to know about where you are, what's changed, and how far behind you are.
git statusWhat branch am I on, and what have I changed?
feat/scheduler-multi-client-live. Modified: 01_clients/capitalize/profile.md. Untracked: 01_clients/capitalize/notes/2026-05-14-weekly-brief.md."
Tells you the branch name and lists every file that's been changed since the last commit. Run it constantly.
git log --oneline -10What are the last 10 commits on my branch?
73d9416 feat(scheduler): multi-client cron ac04d5c chore: bump heyreach-cli submodule 5dda048 feat(attribution-report): v2 27833c7 feat(henry-ai): bi-weekly brief generator 780163a feat(balance-cash): HubSpot deal pipeline
Tells you what your branch has — and by comparison with main, what it's missing.
git rev-list --count HEAD..origin/mainHow many commits behind main am I?
0 means you're current. 47 means main has moved 47 commits forward since you forked.
Run this any time you're not sure if you're current. Or just look at the Session Start banner — it shows the same number automatically.
When you open Claude Code in this repo, you'll now see one of these at the top:
✓ On main, current with origin/main
⚠️ This branch is 12 commits behind origin/main. Run /sync to update.
⚠️ Skills changed on main since this branch forked: - .claude/skills/client-call-prep/SKILL.md - .claude/rules/cold-email-subject-lines.md Run /sync first if you plan to use these.
You don't have to remember any of this. The banner does the remembering for you. When it warns you, run /sync.
When you open a pull request page on GitHub, look for the small status line near the top:
/sync locally) and force-push before merging.Never merge a PR that says "behind" or "has conflicts." Fix the local branch first.
Print this. Stick it on your monitor. Refer to it whenever you forget which command does what.
/sync
Brings your laptop up to date with GitHub. Run before anything else.
/sync # then make your changes /push "short description"
/push handles the branch, the commit, the push, and opens the PR.
git checkout main git pull origin main # create or edit your note file at: # 01_clients/<slug>/notes/<YYYY-MM-DD>-<name>.md git add <path-to-your-note> git commit -m "docs: capitalize weekly brief 2026-05-14" git push origin main
Track C only — timestamped notes you own. Anything else needs a branch.
git status # branch + changed files git log --oneline -10 # last 10 commits on this branch git rev-list --count HEAD..origin/main # how many behind
/sync
If on a feature branch, it offers to rebase. Say yes.
# Open the file, find <<< / === / >>> markers # Pick the right version, delete markers git add <file> git rebase --continue
If unsure which version to keep, stop. Slack #aicro-ops.
git branch oops-rescue git reset --hard origin/main git checkout oops-rescue git branch -m feat/whatever
git reflog # find the line right before the bad command git reset --hard <short-hash>
If unsure, stop and ping Anderson or Josh first.
feature/<what> — new workfix/<what> — bug fixdocs/<what> — docs onlychore/<what> — tooling, cleanup, refactortype: short imperative description
Types: feat, fix, docs, refactor, chore, style. Lower case. No period.
.claude/, execution/, scripts/, dashboards/, _mcp/: branch + PR + 2 reviewers.profile.md, playbook/, campaign-briefs/: branch + PR + 1 reviewer.