How it all works

GitHub + Claude Code Skills

How Git and GitHub work, how the global rules system works, and how the skills/hooks fit together.

Part 1 — Git & GitHub: the mental model

What is Git?

Git is a time machine for your code. Every "commit" is a snapshot of all your files at that moment. You can always go back. GitHub is just a cloud host where you store these snapshots and collaborate.

Remote (GitHub): main ──A──B──C──────────────G──▶ ↑ merge Local feature branch: feature/fix-login──D──E──F──▶ ↑ checkout from main

The golden rules

🌿

Always work on a feature branch

Never commit directly to main. Create a branch (git checkout -b feature/my-thing), do your work, then merge (or let /finish-session handle it). The guard hook blocks direct main pushes.

📸

Commit early and often

Claude auto-commits after each task. One task = one commit. Small commits are easier to review and revert if something breaks.

📥

Pull before you start

/start-session automatically pulls the latest changes. This prevents merge conflicts.

📢

Announce before pushing

Claude will tell you the branch, files, and remote before any push. /finish-session does this safely. Never force-push — the hook blocks it.

The shared repos and who does what

🤖 telegram-coach

The AI habit coach app (Telegram + voice). Runs on Modal. Matt's personal second-brain system. Dani may contribute to the coaching logic.

🎨 clientsflow-studio

The client-facing studio/portal app. Hosted on Modal. Shared client work — both Matt and Dani contribute.

🔒 claude-setup (temporary)

The setup repo with all API keys. Delete after Dani is set up. Never make public.

Essential Git commands

bash
# See what changed
git status
git diff

# Create and switch to a feature branch
git checkout -b feature/my-feature-name

# Stage and commit (Claude does this automatically)
git add -A
git commit -m "feat: describe what changed"

# Push your branch
git push -u origin feature/my-feature-name

# Get latest from remote (auto on /start-session)
git pull --ff-only

# See recent history
git log --oneline -10

Part 2 — Claude Code: how it's wired

The CLAUDE.md "constitution"

The file ~/.claude/CLAUDE.md is loaded at the start of every Claude Code session. It tells Claude how to behave globally — which model to use by default, how to handle git commits, when to ask before doing something destructive, how to format responses, etc.

Think of it as the standing orders that apply in every session, across every project. You can override them per-project by creating a CLAUDE.md in the project folder.

How hooks work — the event pipeline

Hooks are Python scripts that automatically run when certain events happen in Claude Code. They never block a session by default (fail-open design).

SessionStart

session_start.py — auto-briefing

Runs when you open Claude Code. Pulls git, reads PROJECT_STATE.md and recent CHANGELOG, prints a "you are here" briefing. Wired in settings.json.

UserPromptSubmit

turn-nudge.py — session hygiene

Every 15 prompts, injects a reminder to /clear (new task) or /compact (same task, too much context). Advisory — never blocks.

PreToolUse (Bash)

guard-bash.py — safety guard

Before every Bash command, checks for: force-push, curl|bash piping, rm -rf on / or ~, sudo rm, chmod 777, direct main-branch push. Blocks with a clear reason message. The only hook that can actually deny an action.

PreCompact

Prompt injection — context preservation

When Claude compacts context, it's instructed to preserve: file list, open bugs, current branch + unpushed commits, exact deploy commands. So you don't lose track after compaction.

Stop

changelog-guard + html-review-guard

When Claude stops: checks if files changed but CHANGELOG.md wasn't updated (reminds you to run /finish-session). Opens any new HTML files in browser for review.

SessionEnd

session-metrics.py — analytics

On session end: counts turns, checks git for file changes, logs to ~/.claude/session-metrics.log, sends a desktop notification (macOS: terminal-notifier, Windows: PowerShell balloon).

How skills work

Skills are Markdown files with a frontmatter that describe a capability. Claude Code loads them automatically based on their description matching your request. You can also trigger them manually with /skill-name.

~/.claude/skills/model-help/SKILL.md (example)
---
name: model-help
description: Print Matt's Opus-vs-Sonnet decision sheet. Use when /model-help.
---
# model-help
Print the decision sheet from DECISION-SHEET.md in this skill folder.

When you type /model-help, Claude loads this skill, reads DECISION-SHEET.md, and prints it. Each skill = one folder with SKILL.md + optional scripts/.

/start-session

Opens a session: git pull, load project state, print briefing. Auto-runs on open.

/finish-session

Closes a session: tidy repo, changelog, commit, announce, push. Run this every time you're done.

/model-help

Prints the Opus vs Sonnet decision sheet — when to escalate, when to stay cheap.

/house-reference

On-demand lookup for the full API keys table, file paths, accounts.

How subagents work

Subagents are specialized AI workers that run in isolated contexts. The main Claude delegates tasks to them to avoid bloating the main context window (especially for screenshots and large searches).

🤖

You don't invoke subagents manually — they fire automatically when the situation matches. "Where is X wired up?" → codebase-mapper fires. "Check how this page looks on mobile" → browser-qa-runner fires (screenshots stay out of main context).

The model decision rule

simple rule
# Default: Sonnet (fast, good for ~95% of tasks)
/model sonnet    # or just leave it — this is the default

# Switch to Opus when ≥2 of these are true:
# - Novel architecture with no pattern to copy
# - Bug survived 3+ Sonnet attempts
# - Wrong call is expensive (payment, irreversible, prod data)
# - Ambiguous spec needing real judgment
/model opus      # solve the hard thing
/model sonnet    # always switch back after

Part 3 — Working together

The daily loop

typical day
Morning: open VS Code + project
→ /start-session auto-runs (pulls git, shows last commit, open tasks)
→ See what Matt committed overnight

Work: one task at a time
→ Tell Claude what to do
→ Claude edits code, runs tests, auto-commits on each finished task
→ Switch tasks → /clear first

End of work: close out properly
→ /finish-session
→ Claude: tidy repo, update CHANGELOG, announce branch + files, push

When Claude pushes vs when you push manually

✅ /finish-session pushes

Feature branches: Claude pushes automatically after announcing. Safe — the guard and finish-session check everything first.

🛑 main branch: push manually

The guard blocks Claude from pushing to main/master directly. You do it yourself in terminal after review, or Matt triggers it.

Communicating across sessions

Since you and Matt work at different times, the CHANGELOG.md and PROJECT_STATE.md in each repo are the handoff notes. /start-session reads them. /finish-session writes them. They're the "what I did + what's next" for the next person who opens the project.

⚠️

Always run /finish-session before closing your laptop. If you just close VS Code without finishing, the next session might not know what state things are in.