Rev. 01 · Indie Hacker Edition

CLAUDE CODE OS

A System for AI-Assisted Development

Synthetic Sapiens & Aitelier OPS

STOP EARLYRESTART OFTENVERIFY ALWAYSDOCUMENT DECISIONSARCHITECTURE ≠ CONSTRUCTION
STABLE · Hammer it in, use it every day.EXPERIMENTAL · Works, but still taking punches.

This is the operating system I actually use to build with Claude Code, distilled into 25 practices across five layers: what the agent reads before it thinks, how you care for context, how you operate inside a task, how you talk to it, and everything you stack around it. No theory for theory's sake: every item here earned its place building a real product. The Portuguese original lives at /aprenda-claude, with the interactive blueprint.

Section I

KERNEL

What the agent reads before it thinks.

CLAUDE.MD

stable

The project's DNA, in text.

The file Claude reads every time it opens the project. It is not a README. README is for the human cloning the repo. CLAUDE.md is a briefing for an agent: what the project IS, the voice, the hard constraints, the dangerous commands, the safe shortcuts.

Keep it short. No narration. Point to detailed docs instead of duplicating them. If Claude keeps making the same mistake over and over, a line is missing here.

Concrete tip: start with the monorepo map, the non-negotiable conventions, and the shortcuts that keep you from wiping production. Everything else becomes a link.

# CLAUDE.md (repo root)

## Stack
- Next.js 16 + Convex backend
- Turbo monorepo, main app in apps/sapiens/

## Don'ts
- Never run `npx convex *` from the root, only inside apps/sapiens/
- No em-dash in .md files (a hook blocks it)

## Safe shortcuts
- npm run dev (starts sapiens + aitag + decks)
- npm run convex:deploy (prod deploy)

Related: CONVENTIONS.MD · DECISIONS.MD · HOOKS

HOOKS

stable

Shell triggers the harness runs for you.

A hook is a script that runs on an event: PreToolUse, PostToolUse, SessionStart, Stop. Think middleware. Useful for blocking edits on sensitive files, running lint after a save, firing a notification when a long session ends.

Configured in settings.json. Do not confuse it with Claude's memory. A hook is deterministic, it always runs, without depending on the agent remembering.

In Sapiens, a hook warns whenever an em-dash shows up in a .md file, because the house DNA forbids it. A rule that becomes code, not a preference that becomes wishful thinking.

// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "node hooks/check-emdash.mjs"
      }]
    }]
  }
}

Related: PERMISSIONS · CLAUDE.MD · CONVENTIONS.MD

PERMISSIONS

stable

Which tools run without asking.

Every tool (Bash, Edit, Write, MCP) can be allowed, denied or asked. Defined by command pattern. E.g. Bash(git status:*) frees only status, not push.

Move to user settings what is universally safe (ls, git diff, npm test). Move to project settings what is repo-specific (npm run convex:deploy only in this project).

Never free the whole Bash(*). You lose the seat belt and still feel comfortable.

// .claude/settings.local.json
{
  "permissions": {
    "allow": [
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(npm test:*)",
      "Read(*)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)"
    ]
  }
}

Related: HOOKS · MCP SERVERS

GIT COMMITS

stable

Commit early, commit small.

Before every experiment or big change, commit. It becomes a checkpoint you can revert to painlessly.

Direct messages: fix, feat, chore, refactor. No process narration in the body. The diff tells the story.

When Claude is iterating fast on a feature, commit at every green step. If the next attempt breaks, you run git restore with confidence.

# Before every experiment:
git add -A && git commit -m "checkpoint: pre-refactor"

# Iterating fast:
git add src/feature.tsx
git commit -m "feat: add foo step 1"
# ... next green step
git commit -m "feat: foo step 2"

# Something broke? Roll back painlessly:
git restore src/feature.tsx

Related: VERIFY WORK · STOP EARLY · WORKTREES

CONVENTIONS.MD

stable

Small technical rules, in one place.

Things like: named exports not default, Tailwind before CSS Modules, dates in ISO 8601, no console.log in the final commit.

CLAUDE.md points here. It exists so you do not repeat the same correction 5 times across 5 different sessions.

When you catch yourself saying the same thing for the second time in the same week, open the file and write it down.

# conventions.md

## Code
- Named exports, not default
- Tailwind before CSS Modules
- Dates in ISO 8601
- No console.log in the final commit

## Naming
- Component: PascalCase
- Hook: useFoo
- Util file: kebab-case.ts

## Imports
- @/ for absolute paths
- Order: react > next > third-party > @/

Related: CLAUDE.MD · DECISIONS.MD

DECISIONS.MD

stable

Why I chose this, in one line.

A lean ADR. Format: swapped X for Y on DD/MM because Z.

When Claude (or you) tries to revert something three months from now, this file prevents the classic well, there must be a reason, leave it there.

Only write the entry when the decision is non-obvious. Do not document the trivial.

# decisions.md

## 2026-05-18 · Hash → canonical URL in /aprenda-claude
Reason: per-item OG image needs a real route,
not just a hash. Hash routing loses the share.

## 2026-04-22 · Convex Auth instead of Clerk
Reason: one backend only, no identity bridge,
costs half on the free plan.

Related: CONVENTIONS.MD · CLAUDE.MD

Section II

MEMORY

How you care for the session's context.

CLEAR SESSION

stable

When the conversation turned into soup, reset.

Long sessions pollute the context. Claude starts remembering things that no longer matter and losing focus on what does.

/clear wipes it. Costs nothing, recovers precision.

If you caught yourself re-explaining the same thing twice in the same session, the clear was due one answer earlier.

# In the Claude prompt:
/clear

# Or the shortcut (terminal):
Esc Esc + clear

# Heuristic: re-explained the same thing
# twice in the session? The clear was due
# one answer earlier.

Related: STOP EARLY · MANUAL COMPACTION

SUBAGENTS

stable

Delegate research to keep the main context clean.

A subagent is a parallel Claude with its own scope. It does the search (grep, read, web fetch) and comes back with a short report. Your main context does not get clogged with tool results.

Typical cases: exploring a big folder, reading a huge PR, doing code review as an independent second opinion.

Brief it like a colleague who just walked into the room. No assumptions.

// Via SDK / API:
Agent({
  subagent_type: "Explore",
  description: "Find auth callers",
  prompt: "Find every file importing useAuth or getAuthUser. List path:line. Under 100 words."
})

// In the CLI: > use the Explore agent to map who calls useAuth

Related: BACKGROUND TASKS · EXACT FILES

EXACT FILES

stable

Point at the file, do not describe it.

Edit the login is vague. Edit src/app/auth/page.tsx:42 is surgical.

When you know where it lives, say where it lives. Saves search tools and prevents Claude from editing the wrong file with the same name.

Also works for functions: paste the exact snippet to change. Big models pick up context better from literal text than from descriptions.

# Vague (costs search tools):
> edit the login to use email magic link

# Surgical (Claude goes straight there):
> in apps/sapiens/src/app/login/page.tsx:42,
  swap the Google button block for the magic
  link imported from @/lib/auth/magic-link

Related: SUBAGENTS · VERIFY WORK · TDD INVERTED

MANUAL COMPACTION

stable

Before auto-compact hits, compress it yourself.

Auto-compact erases parts of the session to fit the context. You do not choose what it summarizes.

/compact lets you ask for the compression explicitly, so you continue with the memory curated the way you want.

Useful before switching phases in a long task: research is done, implementation is next, compact the research into a summary and move on.

# Before switching phases in a long task:
/compact

# Or with a curated instruction:
/compact summarizing what we learned about the
hydration bug. Keep the main error's stack
trace and discard the rest.

Related: CLEAR SESSION · STOP EARLY · REWIND

STOP EARLY

stable

When it is going badly, stop.

Claude trying to pull a screw with a hammer? Stop. Do not sit there cheering that the next attempt will land.

Step back, reformulate the prompt, maybe start a new session carrying the lesson from the previous one.

Insisting costs tokens and degrades the next attempt, because the context fills up with broken tries the model starts treating as precedent.

# Signal: Claude tried twice, broke twice.
# Do not go for a blind third attempt.

/clear

# Reformulate with the lesson from the attempt:
> the previous approach failed because
  [X]. Let's try [Y] instead, attacking
  [Z] first.

Related: CLEAR SESSION · MANUAL COMPACTION · VERIFY WORK

Section III

PROCESS

How you operate inside a task.

PLANNING MODE

stable

Think before touching files.

Shift+Tab enters plan mode. Claude proposes a plan, you approve or adjust before it touches a single file.

For any task past 15 minutes of execution, planning mode pays for itself. You fix in the plan in 30 seconds what would cost 10 minutes of undo.

For tweak this copy, it is overhead. Use judgment.

# Shift+Tab enters plan mode

> implement the login flow with Google,
  Magic Link and GitHub, falling back to
  email/password if OAuth fails

# Claude answers with a plan in bullets.
# You correct it before it touches a file.

Related: VERIFY WORK · STOP EARLY

WORKTREES

experimental

Two branches in the same repo, at the same time.

git worktree add ../proj-foo branch-foo creates a parallel folder pointing at another branch.

Useful when you want to run 2 Claudes in parallel, one on main fixing a bug, another on a feature, without the checkout dance that loses IDE state.

Hardcore, but it solves operating on more than one front.

# In the main repo:
git worktree add ../sapiens-hotfix hotfix/x
git worktree add ../sapiens-feat feat/y

# In two different terminals:
cd ../sapiens-hotfix && claude
cd ../sapiens-feat && claude

# List all worktrees:
git worktree list

Related: BACKGROUND TASKS · GIT COMMITS

BACKGROUND TASKS

experimental

Long task, push it to the background.

Bash with run_in_background, or an agent in the background. Claude keeps interacting while the build, the test or the agent runs.

You get notified when it finishes. No watching paint dry.

Combines strongly with subagents: you delegate a big investigation, keep coding something else, receive the report when it is ready.

// SDK
Bash({
  command: "npm run build",
  run_in_background: true,
  description: "Build production"
})

# CLI: agent or bash, both accept --background
# You get a notification when it finishes,
# without blocking the session.

Related: SUBAGENTS · WORKTREES

TDD INVERTED

experimental

You write the test, Claude implements.

Inverts classic TDD. You write the assertion (given this input, I expect this output), Claude implements until it passes.

When the test goes green, it is done. No subjectivity.

Works best for pure functions, algorithms, parsers. UI still needs human verification, a green test does not guarantee a working feature.

// You write only the test:
test("parse BR phone", () => {
  expect(parsePhone("+55 11 9 8765-4321"))
    .toBe("+5511987654321");
  expect(parsePhone("(11) 98765-4321"))
    .toBe("+5511987654321");
});

// > Claude, implement parsePhone until it passes
// When the test goes green, it is done.

Related: VERIFY WORK · EXACT FILES

VERIFY WORK

stable

Do not trust the report, trust the diff.

Claude says done, you read the diff. Especially in UI: type-check passed is not the feature works.

Run the server, click, check the golden path and at least one edge case.

The agent's summary describes the intention, not the result. Verifying is part of the task, not optional.

# After Claude says "done":

git diff main..HEAD     # read what changed
npm run dev             # start the server
# open the browser, click, test the golden path
# test at least 1 edge case

# Green type-check is NOT "the feature works".
# Run it. Click it. Check it.

Related: STOP EARLY · PLANNING MODE · TDD INVERTED

Section IV

INTERFACE

How you talk to it.

TERMINAL PIPE

stable

Everything the terminal outputs can enter Claude.

cat error.log | claude diagnose this. Build output, test logs, production dumps: pipe them straight in.

Do not copy-paste. Pipe is faster, preserves formatting and dodges the clipboard limit.

Works for small files without allocating a read tool. For big files, still use Read, or you blow the context.

# Straight diagnosis:
cat /tmp/error.log | claude "diagnose this"

# Broken build:
npm run build 2>&1 | claude "explain the error"

# Explained diff:
git diff | claude "review this, hunt for bugs"

# Structured JSON:
curl api.example.com/data | claude "extract the email fields"

Related: ALIASES · SLASH COMMANDS

VOICE INPUT

experimental

Speak instead of typing when the prompt is long.

System microphone, transcription, paste.

For a long 5-minute briefing you talk as if explaining to a partner. It comes out more natural than typing and Claude picks up context better than from cherry-picked prompts.

Works great in the car, walking, brushing your teeth. Some of this project's best specs came out that way.

# macOS: Fn twice activates native dictation
# iOS: microphone icon on the keyboard

# Linux: nerd-dictation with Whisper.cpp
nerd-dictation begin --punctuate-from-list

# Talk 5 min explaining the briefing,
# paste into the Claude prompt. More context
# than typing cherry-picked lines.

Related: SLASH COMMANDS

STATUS LINE

stable

See the agent's state without asking.

A custom line at the bottom of the terminal: current branch, tokens consumed, mode, active session.

Configured via /statusline. It is the vim status bar, but for AI.

A small hack that kills the huh, is it still running or did it hang. One glance and you know.

# In the CLI:
/statusline

# Or straight in ~/.claude/settings.json:
{
  "statusLine": {
    "type": "command",
    "command": "echo \"$(git branch --show-current) · $(date +%H:%M) · tokens: $TOKENS\""
  }
}

Related: ALIASES · SLASH COMMANDS

SLASH COMMANDS

stable

Shortcuts for the tasks you repeat.

/quote, /pop-article, /review. Each slash is a skill: a prompt plus tools plus structured instructions.

When you do the same thing 3 times, it becomes a slash. Saves minutes a day and standardizes output.

In Sapiens, the whole editorial flow (generate a quote, review, publish) runs on slashes. That is where the speed comes from.

# Sapiens slashes (editorial):
/quote
/pop-article
/pipeline
/publish-staged

# From Anthropic / built-in:
/clear
/compact
/review
/statusline

# Make your own: skills/<name>/SKILL.md

Related: SKILLS · ALIASES · OUTPUT STYLES

REWIND

experimental

Travel back in the session's time.

Double Esc takes you back to before the last exchange.

Useful when Claude took a wrong branch and you want to reformulate without losing the earlier context.

It is not a code undo, it is a prompt undo. To undo a file, git restore remains the way.

# Shortcut:
Esc Esc

# Goes back to before the last exchange.
# Useful when Claude took the wrong branch
# and you want to reformulate without losing
# the earlier context.

# To undo a file, it is still git restore.

Related: MANUAL COMPACTION · STOP EARLY

Section V

USERLAND

Everything you stack around it.

ALIASES

stable

Long command becomes 1 letter.

alias cl=claude --model opus. alias clc=claude --continue. alias cly=claude --dangerously-skip-permissions (carefully).

Put it in .zshrc or .bashrc.

Every second saved on an operation you do 50 times a day matters. The opposite of glamour, just arithmetic.

# ~/.zshrc (or .bashrc)
alias cl='claude'
alias clc='claude --continue'
alias clo='claude --model opus'
alias cly='claude --dangerously-skip-permissions'

# Per project, in .envrc with direnv:
alias cl='claude --add-dir apps/sapiens'

Related: SLASH COMMANDS · STATUS LINE · TERMINAL PIPE

MCP SERVERS

stable

Connects Claude to real services.

Model Context Protocol. A server that exposes tools: Stripe, GitHub, Notion, databases, Convex, your own MCP.

Claude becomes the brain that orchestrates. You connect once per service, use it forever.

In Sapiens, the house MCP exposes the app's API (create a quote, list drafts, publish) for Claude to operate editorially. It is the jump from assistant to operational colleague.

# Add a ready-made MCP server:
claude mcp add stripe -- npx -y @stripe/mcp-server
claude mcp add github -- npx -y @modelcontextprotocol/server-github

# List:
claude mcp list

# Your own MCP (Sapiens): exposes the app's
# API as tools, Claude uses it to create
# quotes, list drafts, publish.

Related: SKILLS · SLASH COMMANDS · PERMISSIONS

OUTPUT STYLES

experimental

Change the tone without changing the prompt.

Custom output styles: terse engineer, friendly tutor, editorial blueprint, brutally honest.

It becomes a personality preset. Useful when the same agent serves different cases (debugging demands directness, pair programming demands dialogue).

Combines with slashes: each skill can ship with its own output style built in.

# List available styles:
/output-style

# Apply:
/output-style brutally-honest-engineer

# Make your own in ~/.claude/output-styles/foo.md:
---
name: terse-mentor
description: Direct, no flourish
---
You answer like a demanding mentor.
No hedging. No "great question".
Straight to the point.

Related: SLASH COMMANDS · SKILLS

SYNCTHING

experimental

Syncs the repo between machines, no cloud.

P2P sync. Your home machine and your laptop stay identical without GitHub in the middle.

Good for heavy local work you do not want to push to the remote all the time (big assets, builds, downloads).

It does not replace git, it complements it. Git for versioned code, Syncthing for the machine's raw state.

# Linux:
sudo apt install syncthing
systemctl --user enable --now syncthing

# macOS:
brew install syncthing
brew services start syncthing

# Web UI at http://localhost:8384
# Add the ~/projects folder, connect
# the two machines via device ID.
# P2P sync, no cloud in the middle.

Related: GIT COMMITS

SKILLS

stable

Slash commands with structured instructions.

A skill is a folder with SKILL.md plus scripts plus prompts. Claude reads it when you invoke it.

It is teaching a pattern once and using it forever. The Sapiens skills (/quote, /pop-article, /pipeline) live in skills/ and each one is a specialist agent of the editorial flow.

When you want to distill operational knowledge into a reusable, portable format, a skill is the right container.

# Structure:
.claude/skills/quote/SKILL.md
.claude/skills/quote/scripts/draft.mjs

# SKILL.md:
---
name: quote
description: Drafts 1 quote for the Sapiens Column
---
# Instructions
1. Fetch the recent Sapiens Column
2. Identify the thematic gap
3. Propose 3 quotes, user picks 1
4. Stage in the database as draft

Related: SLASH COMMANDS · MCP SERVERS · CLAUDE.MD