Claude Code Setup — How It All Works


By Robert Barcik

Reference guide


This document explains how Claude Code is configured across this repository hub. Useful as a reference for Robert and as teaching material for students.

Section 1

The Big Picture

Claude Code is an AI coding assistant that runs in the terminal. It can read/edit files, run shell commands, and use CLI tools (like git, gh, aws). What makes it powerful is the persistent context system — files and settings that tell it about your projects, preferences, and conventions.

There are three layers of persistent context:

~/.claude/                          <-- Global (your machine)
  settings.json                     <-- Global settings & permissions
  projects/
    -Users-robertbarcik-git-repos/  <-- Per-project memories (keyed by launch directory)
      memory/
        MEMORY.md                   <-- Memory index
        user_profile.md             <-- Individual memory files
        ...

~/git-repos/                        <-- Your working directory
  CLAUDE.md                         <-- Project instructions (Claude reads this)
  .claude/
    settings.local.json             <-- Local permissions for this directory
  barcik-training/
    CLAUDE.md                       <-- Repo-specific instructions
    .claude/
      settings.local.json           <-- Repo-specific permissions
Section 2

Layer 1: CLAUDE.md — Project Instructions

CLAUDE.md is a markdown file Claude reads at the start of every conversation. Think of it as a briefing document. It typically contains:

  • What the project is
  • Key commands (build, test, deploy)
  • Architecture conventions
  • Anything Claude should know before touching the code

Where Claude looks for it:

  • In the directory you launch from
  • In parent directories (walking up the tree)
  • It does not descend into subdirectories automatically

Example: The hub-level CLAUDE.md in this directory lists all repositories with one-line descriptions and documents the shared AWS deployment pattern. Each repo (like barcik-training-demos/) has its own CLAUDE.md with repo-specific deploy commands and conventions.

Hub pattern: When launching Claude from a parent directory that contains multiple repos, a hub CLAUDE.md provides cross-repo context. When Claude focuses on a specific repo, it can read that repo's own CLAUDE.md on demand.

Section 3

Layer 2: Memory — What Claude Remembers Across Conversations

Claude Code has a file-based memory system that persists between conversations. Memories are stored in ~/.claude/projects/<encoded-path>/memory/.

The path encoding is based on where you launch Claude from. For example:

  • Launching from /Users/robertbarcik/git-repos/ stores memories in ~/.claude/projects/-Users-robertbarcik-git-repos/memory/
  • Launching from /Users/robertbarcik/git-repos/bloom-session/ stores memories in ~/.claude/projects/-Users-robertbarcik-git-repos-bloom-session/memory/

This means each launch directory has its own memory bucket. If you always launch from the same place, memories accumulate there. If you launch from different directories, memories are spread across multiple buckets.

Memory Types

Each memory file has YAML frontmatter with a type:

Type Purpose Example
user Who you are, your expertise, preferences "Robert is a professional AI trainer, prefers Claude as creative partner"
feedback Corrections and confirmed approaches "Never use reveal.js for slides — custom HTML works better"
project Ongoing work context, goals, decisions "Migrating barcik.training from Google Sites to S3+CloudFront"
reference Pointers to external resources "Pipeline bugs are tracked in Linear project INGEST"

Example memory file (user_profile.md):

---
name: Robert Barcik - Trainer & Consultant
description: Robert is a professional AI/Data trainer and consultant
type: user
---

Robert Barcik is a professional trainer specializing in Data, AI,
and EU AI Act compliance. He runs his business through LearningDoe, s.r.o.
He values Claude as a creative partner and prefers building/deploying
things directly rather than using traditional CMS tools.

MEMORY.md is the index file — it lists all memories with one-line summaries. Claude loads this at the start of every conversation to decide which memories are relevant.

What Claude Does NOT Save to Memory

  • Code patterns or architecture (derivable from reading the code)
  • Git history (use git log)
  • Debugging solutions (the fix is in the code)
  • Anything already in CLAUDE.md files
  • Temporary task state
Section 4

Layer 3: Permissions — settings.local.json

Claude Code asks for permission before running shell commands. To avoid being prompted repeatedly, you can whitelist commands in .claude/settings.local.json:

{
  "permissions": {
    "allow": [
      "Bash(aws s3:*)",
      "Bash(gh:*)",
      "Bash(git:*)"
    ]
  }
}

The * is a wildcard — Bash(aws s3:*) allows any command starting with aws s3.

These files can exist at multiple levels:

  • ~/.claude/settings.json — global (all projects)
  • <project>/.claude/settings.local.json — per-project

Note: Permission entries often contain absolute paths (e.g., /Users/robertbarcik/...), which makes them machine-specific. This is by design — they're meant to be local configuration.

Section 5

CLI Integrations

Claude Code doesn't have its own AWS or GitHub credentials. It uses whatever CLI tools are already configured on your machine:

GitHub (gh)

  • Installed and authenticated separately (gh auth login)
  • Auth token stored in the macOS keyring
  • Claude uses it by running gh commands (create PRs, check issues, etc.)
  • Config lives in ~/.config/gh/

AWS CLI

  • Configured separately (aws configure)
  • Credentials stored in ~/.aws/credentials (plaintext — be aware)
  • Claude uses a named profile (e.g., --profile barcik-demos)
  • The profile name is documented in CLAUDE.md so Claude knows which one to use

API Keys for LLM Projects

The research and tutorial repos need API keys (primarily OpenRouter, sometimes OpenAI) to call LLM APIs. These are managed separately from AWS/GitHub credentials.

Framework/research repos (geobias, selfjudge, vigil, bloom-session, localdesk, petri-session):

  • Keys are stored in .env files in each repo's root directory
  • All repos use python-dotenv — the .env file is loaded automatically when running the CLI
  • .env is gitignored in every repo, so keys never get committed
  • Each repo has a .env.example showing which keys are needed
# Typical workflow to set up a new key:
cd geobias/
cp .env.example .env
# Edit .env and paste your key:
#   OPENROUTER_API_KEY=sk-or-v1-your-actual-key

When collaborating with Claude Code, you can simply paste a new key in the conversation and ask Claude to write it into the appropriate .env files. Since these files are gitignored, the key stays local.

Tutorial repos (genai-in-python-tutorial, testing-tutorial, vector_databases-tutorial, ADK-tutorial, MCP-tutorial):

  • Notebooks use a Colab-first pattern with local fallback:
try:
    from google.colab import userdata
    api_key = userdata.get('OPENAI_API_KEY')
except:
    api_key = getpass.getpass("Enter your API key: ")
os.environ["OPENAI_API_KEY"] = api_key
  • On Google Colab: students store keys in Colab Secrets (sidebar > key icon)
  • Running locally: students get an interactive prompt — the key is never saved to disk
  • No keys are hardcoded or leaked in notebook outputs

Key rotation: When you revoke and regenerate API keys on a provider's dashboard, the only files that need updating are the .env files in the repos you're actively using. Tutorial notebooks don't need changes — students always enter their own keys at runtime.

Section 6

Portability Across Machines

This is the key gotcha — most of the Claude Code context system is local to one machine.

What Portable? How
CLAUDE.md files (in repos) Yes Travels with git
Per-repo .claude/settings.local.json Partially Only if committed to git; paths may differ across machines
Memories (~/.claude/projects/) No Manual copy
Hub CLAUDE.md (not in a repo) No Manual copy
Hub settings.local.json No Manual copy
gh auth No Run gh auth login on each machine
AWS credentials No Copy ~/.aws/ or reconfigure

Practical Transfer Checklist

When setting up a new Mac:

  1. Clone your repos (CLAUDE.md files come along)
  2. Copy ~/.claude/ from the old machine (memories + global settings)
  3. Copy the hub CLAUDE.md and README.md to the parent directory
  4. Run gh auth login
  5. Configure AWS credentials (aws configure --profile barcik-demos)
  6. Re-create or copy .claude/settings.local.json files (adjust paths if needed)

Alternatively, skip steps 2-3 and let Claude rebuild memories naturally over a few conversations. The CLAUDE.md files in repos carry the most critical context.

Section 7

Security Considerations

When giving an AI agent access to your terminal, CLI tools, and browser, it's important to understand the attack surface and set up appropriate guardrails. The key principle is defense in depth: don't rely on a single layer (like the AI's behavioral rules). Use server-side protections that can't be bypassed locally.

The Two Types of Protection

Server-side (can't be bypassed from your machine):

  • GitHub branch protection — blocks force-push/deletion regardless of what runs locally
  • AWS IAM policies — blocks unauthorized actions regardless of what runs locally
  • GitHub token scopes — missing scopes can't be worked around

Client-side (bypassable with --dangerously-skip-permissions or a rogue tool):

  • Claude Code's permission system (settings.local.json)
  • Claude's behavioral rules ("never force-push without asking")
  • Interactive approval prompts

A well-secured setup uses server-side walls for catastrophic risks and client-side controls for everyday guardrails.

GitHub — Branch Protection

Claude (and any coding assistant) uses the gh CLI with your authenticated token. The repo scope grants full access: push, force-push, delete branches, manage PRs/issues. The delete_repo scope is not granted, so repos can't be deleted.

Branch protection is the critical server-side safeguard. When enabled on main:

# Enable on a repo (one-time setup):
gh api repos/OWNER/REPO/branches/main/protection \
  -X PUT \
  -F "enforce_admins=true" \
  -F "required_pull_request_reviews=null" \
  -F "required_status_checks=null" \
  -F "restrictions=null" \
  -F "allow_force_pushes=false" \
  -F "allow_deletions=false"

Key settings:

  • allow_force_pushes=false — no tool can rewrite history on main
  • allow_deletions=false — no tool can delete the main branch
  • enforce_admins=true — even the repo owner can't bypass (this matters! without it, any tool using your credentials could still force-push)
  • No required PRs — keeps the solo workflow frictionless (normal pushes still work)

Result: Any git push --force to main gets rejected by GitHub with Cannot force-push to this protected branch. This works regardless of which AI tool, script, or human runs the command.

GitHub Pro ($4/month) is required for branch protection on private repos. On the free plan, only public repos can be protected.

If you ever legitimately need to force-push, temporarily disable enforce_admins, do the push, then re-enable. The friction is intentional.

AWS — IAM Policy Analysis

Claude uses the AWS CLI with a named profile (barcik-demos). The IAM user (barcik-demos-deployer) has a tightly scoped policy:

Permission Scoped to Risk
S3 PutObject/DeleteObject/ListBucket 3 specific buckets only Low — can only modify website files
CloudFront CreateInvalidation Specific distribution + all Low — cache busting only, free tier
CloudFront CreateDistribution All (*) Low — could create distributions but no cost risk
Route53 ChangeResourceRecordSets All (*) Medium — could modify DNS records
ACM ListCertificates/Describe All (*) None — read-only

What this user explicitly CANNOT do:

  • Launch EC2 instances, RDS databases, Lambda functions, or any compute
  • Create/delete S3 buckets (except the named ones)
  • Modify IAM users, roles, or policies
  • Access billing or account settings

Cost risk: effectively zero. The only billable actions are S3 storage (pennies) and CloudFront invalidations (first 1,000/month free). No path to expensive resources.

Potential tightening (optional, for after initial setup is complete):

  • Scope cloudfront:CreateDistribution to specific distributions instead of *
  • Scope route53:ChangeResourceRecordSets to the specific hosted zone ARN
  • These broader permissions were useful during initial infrastructure setup but aren't needed for day-to-day deploys

Local Machine — The Permission System

Claude Code asks for approval before running shell commands. Commands can be pre-approved in .claude/settings.local.json:

{
  "permissions": {
    "allow": [
      "Bash(aws s3:*)",
      "Bash(git:*)",
      "Bash(gh:*)"
    ]
  }
}

The * wildcard matches anything after the prefix. Bash(git:*) allows git status, git commit, but also git push --force and git reset --hard. For tighter control:

{
  "permissions": {
    "allow": [
      "Bash(git status:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push origin:*)",
      "Bash(git log:*)",
      "Bash(git diff:*)",
      "Bash(git branch:*)",
      "Bash(git checkout:*)"
    ]
  }
}

This version allows everyday git operations but would prompt you before git push --force, git reset --hard, or git clean. The trade-off is more prompts during normal work.

What the permission system controls vs. doesn't:

What Permission needed?
Shell commands (Bash tool) Yes — must be approved or pre-approved
Reading files (Read tool) No — always allowed, any file on your machine
Writing/editing files (Write/Edit tools) Depends on permission mode
Creating files Depends on permission mode

--dangerously-skip-permissions: This flag disables all prompts. Every command runs without approval. Server-side protections (GitHub branch protection, AWS IAM) still hold, but local damage (deleting files, overwriting uncommitted work, exfiltrating secrets) has no safety net. Avoid this unless you have a specific reason and understand the risks.

Commands to Watch Out For

When an AI coding assistant asks to run a command and you're reviewing the approval prompt, here's a quick reference of commands that deserve extra scrutiny:

Destructive — can lose work irreversibly:

Command What it does Danger
rm -rf <path> Recursively deletes files/directories Gone forever (no trash)
git reset --hard Discards all uncommitted changes Uncommitted work is lost
git checkout . / git restore . Discards all modified files Same as above
git clean -fd Deletes all untracked files New files you haven't committed are gone
git push --force Overwrites remote branch history Blocked by branch protection if set up
git branch -D <branch> Force-deletes a local branch Commits only in reflog for 90 days

Data exfiltration — could leak secrets:

Command What it does Danger
curl -X POST <url> -d "$(cat ...)" Sends file contents to a URL Could leak credentials, keys
wget/curl piped to bash Downloads and runs unknown code Arbitrary code execution
cat ~/.aws/credentials Reads AWS secrets Fine locally, dangerous if shared
cat ~/.ssh/id_* Reads SSH private keys Same as above
echo $ENV_VAR Prints environment variables May contain API keys

System modification — hard to undo:

Command What it does Danger
brew install/uninstall Installs/removes system packages Usually fine, but check what
pip install / npm install -g Installs packages globally Could conflict with other projects
chmod/chown Changes file permissions/ownership Can break things subtly
sudo <anything> Runs as root Full system access
launchctl Manages system services Can start persistent processes

Rule of thumb: If you're tired and not sure, deny the command and ask what it does. A denied command can always be re-run; a destructive command can't be un-run.

Chrome and Computer Use

Claude can interact with your browser via the Chrome extension and with native apps via computer use:

Tool Access level
Chrome extension (claude-in-chrome) Can navigate, click, fill forms, read page content in Chrome
Computer use on browsers Read-only (can see screen, can't click/type)
Computer use on terminals/IDEs Click-only (can click buttons, can't type)
Computer use on other apps Full access (mouse + keyboard)

Risks:

  • If you're logged into sensitive accounts (banking, email, admin consoles) in Chrome, Claude could interact with those pages through the extension
  • Computer-use screenshots capture whatever is on screen, including sensitive content
  • Accidental clicks on "delete" or "send" in web apps could have consequences

Recommended setup:

  • Use a dedicated Chrome profile for Claude work sessions (Chrome > Profile icon > Add). Keep your personal/work accounts logged in on a different profile.
  • Only enable the Chrome extension when you need browser automation
  • Claude must call request_access before controlling any native app — you approve each one

Using Other AI Coding Assistants

The security analysis above applies to any AI coding tool, not just Claude Code. If you're testing another LLM-based assistant:

  • Server-side protections hold: GitHub branch protection and AWS IAM policies work regardless of which tool is running locally. These are your most reliable safeguards.
  • Behavioral rules don't transfer: Claude Code has built-in instructions to confirm destructive actions. Other tools may not. The permission prompt is your last line of defense.
  • Never use "skip permissions" with untested tools. Without a permission system, a less careful model could delete files, leak secrets, or trash your local repos without any prompt.
  • The commands-to-watch-out-for list above applies universally. Memorize the red flags — they're the same regardless of which AI is proposing the command.
Section 8

Directory Structure Reference

~/.claude/
  settings.json                           # Global settings
  projects/
    -Users-robertbarcik-git-repos/
      memory/
        MEMORY.md                         # Index of memories for this launch dir
        user_profile.md                   # Who Robert is
        project_website_rebuild.md        # barcik.training migration project
        reference_aws_deployment.md       # AWS infra details
    -Users-robertbarcik-git-repos-bloom-session/
      memory/
        MEMORY.md
        project_bloom_session.md          # Bloom framework session context
    -Users-robertbarcik-git-repos-EXIN-AI-Foundation-Prep/
      memory/
        MEMORY.md
        project_exam_prep.md              # EXIN exam prep context
    -Users-robertbarcik-git-repos-barcik-training-exin-ai-foundation/
      memory/
        MEMORY.md
        project_overview.md
        feedback_slides.md                # Never use reveal.js
        reference_aws.md

~/git-repos/
  CLAUDE.md                               # Hub instructions
  README.md                               # This file
  .claude/settings.local.json             # Hub permissions
  barcik-training/
    CLAUDE.md
  barcik-training-demos/
    CLAUDE.md
    .claude/settings.local.json
    .claude/skills/SKILL.md
  ...