Skip to content

Instantly share code, notes, and snippets.

@bradfeld
Last active May 8, 2026 19:43
Show Gist options
  • Select an option

  • Save bradfeld/1deb0c385d12289947ff83f145b7e4d2 to your computer and use it in GitHub Desktop.

Select an option

Save bradfeld/1deb0c385d12289947ff83f145b7e4d2 to your computer and use it in GitHub Desktop.
Advanced Claude Code Configuration Guide - patterns for professional solo development

Feld Claude Code Configuration Guide

A comprehensive tour of a professional solo-developer Claude Code setup spanning twelve repositories and twelve worktrees. Covers workflow discipline, session persistence, automated quality gates, business operations, and EOS management.

Last updated: 2026-04-29

What this is: a tour of a working setup and the reasoning behind it — useful for borrowing patterns. What this is NOT: an install guide, a list of best practices, or a snapshot that stays accurate without updates. Plugin versions, pg_cron schedules, and file counts are point-in-time.


Table of Contents

  1. Core Philosophy
  2. Directory Structure
  3. Session State Architecture
  4. Master Workflow
  5. Review Triage and Agents
  6. Workflow Profiles
  7. Rules System
  8. On-Demand Reference Docs
  9. Hooks System
  10. Model Strategy
  11. Skills Inventory
  12. Plugin Ecosystem
  13. Commands Inventory
  14. MCP Server Integration
  15. Repository Registry
  16. CompanyOS: Multi-Repo Architecture
  17. CEOS: EOS Framework
  18. Automated Jobs
  19. Multi-Instance Safety (Worktrees)
  20. Backup and Version Control
  21. Blog and Learning Capture
  22. Cursor Integration
  23. Git Workflow Rules
  24. Coding Standards
  25. Pre-commit Pipeline
  26. Quality Automation
  27. Database Migration Discipline
  28. Secrets Management
  29. Testing Patterns
  30. Critical Gotchas
  31. Quick Start for New Setup
  32. Key Insights

Core Philosophy

Global-first configuration. All agents, commands, rules, and skills live in ~/.claude/ (see Directory Structure for the 2026-04-15 migration that consolidated this). Project-level .claude/ dirs are deprecated — only ephemeral workflow state (.claude-session/, gitignored audit logs) lives there.

Key principles:

  • Never create project-level .claude/settings.json — it breaks permission inheritance from global settings
  • No quick-fix mode — every ticket gets the full workflow (/start → implement → /commit)
  • Session state files survive context compaction — workflow continuity across long sessions
  • Evidence before assertions — never claim something about code without reading it first
  • Protected workflows — certain operations (/commit, /staging, /start) must never be done manually
  • Fix or ticket — no middle ground — every review finding either gets fixed now OR gets a Linear ticket matching one of five documented exceptions (missing data/access, missing dependency, architectural decision needing input, scope explosion, inaccessible repo). "Complicated," "risky," and "pre-existing" are explicitly rejected as exceptions
  • Duplication is a signal — before applying the same non-trivial edit to 2+ locations, stop and extract the abstraction first
  • Plan task atomicity — never split plan tasks across test-file boundaries. A package's test suite is the atomicity unit
  • Never fabricate evidence — if a hook blocks because evidence is missing, run the actual process or use --no-verify with stated justification

Directory Structure

~/.claude/                          # Global configuration (git repo → bradfeld/claude-config)
├── settings.json                   # Permissions, hooks, plugins, env, attribution
├── .claude.json                    # MCP server configuration
├── rules/                          # 23 always-loaded rules
├── docs/                           # 18 on-demand reference docs
├── skills/                         # ~67 skills (17 domain + 30 co-* + 21 ceos-*)
├── commands/                       # 72 commands
├── hooks/                          # 20 hook scripts
├── agents/                         # 11 review agents
├── blog/notes/                     # Daily learning capture
├── comms/drafts/                   # Email draft archive
├── voice/                          # Writing style profiles (brad + lumen)
├── plans/                          # Implementation plans
├── projects/*/memory/              # Per-project auto-memory (shared natively since CC v2.1.63)
├── ccnotify/                       # macOS notification system
├── iterm/                          # iTerm color/typing monitor integration
├── mcp-servers/                    # Custom MCP server implementations
└── plugins/                        # Marketplace plugins

~/Code/companyos-intensitymagic/    # CompanyOS config repo
~/Code/companyos-config-foundry/    # Foundry-specific config
~/Code/ceos/                        # CEOS repo (EOS skills)

Note: ~/.claude-personal is a symlink to ~/.claude — a naming artifact. They resolve to the same directory.

The 2026-04-15 Consolidation

All review agents, skills, commands, and rules were moved to ~/.claude/ on 2026-04-15. Previously, each worktree had its own .claude/{agents,commands,rules}/ symlinked back to magic0 via sync-claude-config.sh. That architecture caused recurring incidents:

  • git checkout would delete config files (PLA-609, PLA-762)
  • APFS hardlink destruction when rm -rf ran on directory hardlinks (PLA-448)
  • Worktree symlink ELOOPs
  • Project-level settings.json breaking permission inheritance

The current model: one source of truth in ~/.claude/, backed up daily to GitHub (bradfeld/claude-config), with per-repo behavior driven by Workflow Profiles in each CLAUDE.md instead of per-repo config files. sync-claude-config.sh was deleted. Project-level .claude/ dirs now only hold ephemeral workflow state.


Session State Architecture

Session files stored in project/.claude-session/ persist workflow state:

  • Current step and status (implementing, awaiting_user_test, committing)
  • Blocked actions to prevent accidental commits before testing
  • Implementation plans that survive context compaction
  • Progress tracking across worktrees

Circuit breaker: Commits are blocked when session status shows awaiting_user_test. The /commit command checks this state before proceeding.

PreCompact hook (preserve-session-state.sh) saves state before context compaction, so long implementation sessions don't lose workflow position.


Master Workflow

All tickets follow an identical loop:

  1. /start TICKET-XXX — Fetch ticket from Linear, analyze, create branch, post plan
  2. Implement locally with manual testing
  3. /commit — Quality gates → /simplify (Step 3.5) → auto-triage review → run agents → push → update Linear
  4. /staging (magic-platform) — Batch merge to preview, deploy, reset worktrees
  5. /production (magic-platform) — Health audit, merge to main, verify

For direct-to-main repositories (CEOS, WordPress, awsaudit), /commit IS the deployment.

/start auto-detects the target repository from the ticket's Linear team prefix — the same command works across all twelve repositories. Chain mode: /start TICKET-1 TICKET-2 or /start epic EPIC-ID.

Unified /commit (2026-04-12): single canonical command replacing the old /spcommit//oldcommit split. Defaults to --full (tricycle + code-reviewer + specialized agents). --quick skips review. /oldstart and /oldcommit remain as non-functional reference files.


Review Triage and Agents

Triage Levels

Level When What Runs
NONE Only non-source changes (docs, tests, config, styling) No review agents
LIGHT Any source code change (.ts/.tsx) that doesn't trigger FULL code-reviewer + selective agents in parallel
FULL 10+ files, shared packages, or sensitive paths Full parallel multi-agent review battery

Key rule: NONE never applies to source code changes. Even a 1-file .tsx change gets at least LIGHT review.

Triage Signals

Evaluated in priority order: path-based overrides first, content-type exemption second, file-count baseline third.

Path overrides (force FULL): middleware.ts, auth.ts, /auth/, supabase/migrations/, packages/*, payment, billing, webhook

Content-type exemption (downgrade to NONE): Only when ALL changed files are non-source (docs, tests, config, styling, lockfile without package.json). Important non-exemptions:

  • package.json → at least LIGHT (dependency changes = supply chain risk)
  • .claude/commands/*.md, .claude/rules/*.md, .claude/agents/*.md → at least LIGHT with prompt-reviewer (no compiler for prompts)
  • Infrastructure config (vercel.json, next.config.ts, turbo.json, .github/workflows/*.yml) → at least LIGHT

⚠️ Triage is MECHANICAL, not interpretive (PLA-1015 incident). If the filename matches → route accordingly. The review agent interprets; the triage routes.

Review Agents

All 11 agents live in ~/.claude/agents/ and dispatch on Sonnet in parallel.

Agent Triggers On Purpose
code-reviewer All source changes (plugin-provided via Superpowers) TypeScript strict, security basics, API patterns, logging
performance-reviewer .tsx, page.tsx, layout.tsx, server actions Sequential awaits, client boundaries, Suspense, serialization
silent-failure-hunter API routes, services, actions, hooks Swallowed errors, unhandled promises, missing cleanup
security-auditor Auth flows, middleware, migrations, webhooks RLS policies, secrets, SQL/auth injection
migration-reviewer supabase/migrations/*.sql Timeout safety, idempotency, RLS completeness, TO clause, auth.uid() wrapper
ui-consistency-reviewer .tsx files shadcn/ui patterns, semantic tokens, accessibility
test-quality-reviewer Test files alongside source Assertion quality, edge cases, mocks, flaky patterns
spec-reviewer FULL triage on epic children Plan compliance vs Linear ticket
cross-app-consistency-auditor packages/*, multi-app changes, @platform/* siblings Pattern drift across apps
prompt-reviewer .claude/commands/*.md, .claude/rules/*.md, .claude/agents/*.md Dead references, contradictions, stale docs
ai-usage-reviewer Files importing @platform/infra/ai Cost controls, prompt injection, error handling, temperature, model tier
environment-health-auditor Manual only Periodic infrastructure health monitoring

Cross-model review: codex-reviewer (GPT-5.4 via MCP stdio) dispatches on all source changes at LIGHT and FULL. It's not a .claude/agents/ file — it's an MCP server tool. Catches race conditions and logical errors that a single model family might miss.

Full decision algorithm and dispatch examples are in on-demand doc review-triage-reference.md.


Workflow Profiles

Each repository declares its workflow in CLAUDE.md as YAML:

workflow:
  base_branch: preview           # or main
  direct_to_main: false          # true for CEOS, WP, awsaudit
  quality_gates:
    - pnpm run type-check
    - pnpm run lint
  review:
    max_level: FULL              # NONE, LIGHT, or FULL
  ship:
    method: pr                   # pr or direct_push
    linear_status: "In Progress"
    deploy_hint: "/staging"

This declarative approach lets /start and /commit work identically across twelve repositories without hardcoded logic. The unified /commit reads the profile and adapts its behavior. This is the right place to change per-repo behavior — not the command source.


Rules System

23 always-loaded rules in ~/.claude/rules/ establish cross-project standards:

Rule Purpose
api-before-ui.md Before suggesting manual UI work for a third-party service, check GCP SM for an admin token (PLA-1450)
auto-execute-recommendations.md After making a clear recommendation, EXECUTE — never end with "which approach?" or "want me to..."
automated-remediation.md Problems must create tracked tickets, not just display warnings
checkpoint-restored-summary.md First response after /clear with a restored checkpoint must lead with a compact summary block
code-quality.md TypeScript strict mode, error handling, security, type duplication
commit-recipe.md Universal commit structure, pre-commit hooks, worktree staging
debugging-priority.md Root cause checklist — common causes before speculative hypotheses
duplication-as-signal.md Before applying same non-trivial edit to 2+ locations, extract first
evidence-first.md Never assert without reading/verifying first
evidence-integrity.md Never fabricate audit log entries to pass hooks
fix-dont-defer.md Five exhaustive exceptions for ticketing; default is fix
learning-capture.md Batch-at-pause-points capture model
no-schedule-offers.md NEVER end a reply with an offer to /schedule a background agent (overrides session-prompt default)
on-demand-references.md Index of detailed reference docs
output-formatting.md Structured output completeness on first attempt, full URLs always
plan-task-atomicity.md Never split plan tasks across test-file boundaries
protected-workflows.md Workflows that must use their dedicated commands
retroactive-enforcement.md When codifying a new pattern rule, file a sweep ticket for existing violations in the same PR (PLA-1391)
review-triage.md NONE/LIGHT/FULL framework with agent selection
scope-intent.md Match response scope to what was actually requested
slash-command-help.md Every slash command responds to ? or --help
subagent-stalls.md Never recommend Escape during parallel agents; HARD CONSTRAINTS block for dispatches
tricycle.md Trigger and mode detection for the tricycle development pattern

Rules promoted to on-demand skills: mcp-linear, mcp-supabase, database-migrations, auth-admin-reads, vercel-env-api, schema-grants, hygiene-gate — narrow-use guidance that doesn't need to be loaded in every session.

Architectural principle (PLA-688, continued through 2026-04): Always-loaded rules contain decision logic; reference tables and tool-specific gotchas live in docs/skills loaded only when needed.

Same principle applied to project AGENTS.md (2026-04-29): Magic Platform's AGENTS.md was trimmed from 43k → 22k chars (731 → 340 lines) by extracting embedded code examples to docs/standards/*.md files referenced by plain prose pointers (not @import, which loads regardless of relevance). Followed Anthropic's "would removing this cause Claude to make mistakes?" test from the official Claude Code best-practices guide. Also brought the file back under Claude Code's 40k char soft-warning threshold and closer to Anthropic's recommended <300 line target for always-loaded files.

Pre-commit enforcement:

  • rules-size-cap.sh — caps each rule file at ~200 lines (staged files only)
  • verify-review-agents.sh — every agent referenced in triage rules must have a definition

On-Demand Reference Docs

18 docs in ~/.claude/docs/ plus project-level docs, loaded only when a task matches. The on-demand-references.md rule serves as the index:

Task Reference Doc
Writing Vitest tests testing-vitest.md
Configuring MCP servers mcp-server-config.md
Creating skills or commands skill-authoring.md
Discourse community admin discourse-community.md
Committing changes commit-reference.md
Review triage dispatch review-triage-reference.md
Multi-chain epic planning multi-chain-epics.md
Parallel subagent dispatch parallel-patterns.md
Shell scripting bash-patterns.md
Batch learning capture learning-capture-procedure.md
Running tricycle tricycle.md / tricycle-prompts.md
Platform app templates platform-app-templates.md
Thinking modes reference CLAUDE_CODE_THINKING_MODES.md
Self-describing data patterns self-describing-data.md
TypeScript / pnpm / Tailwind / ESLint gotchas typescript-gotchas.md
Module resolution errors (ERR_REQUIRE_ESM, missing subpath exports) module-resolution-debugging.md
TDD patterns and execution recipes tdd-patterns.md

Magic Platform docs (canonical locations in the repo — an earlier .claude/docs/ layer was deleted 2026-03-22 in favor of docs/standards/ and docs/ops/):

  • docs/standards/UI_CONSISTENCY_STANDARDS.md, DATABASE_PATTERNS.md, LOGGING_GUIDE.md, TESTING_STRATEGY.md, TYPESCRIPT_STRICT_MODE.md, ERROR_HANDLING.md (toError, Promise.allSettled + helpers, service null-vs-throw, logSupabaseError)
  • docs/ops/GITHUB_WORKFLOWS.md, cursorcommit.md, DATABASE_MIGRATION_RECOVERY.md, DEPLOYMENT_SELF_HEALING.md, INCIDENT_RESPONSE.md

Why: A 200-line reference table for commit workflows wastes tokens when you're doing codebase exploration. On-demand docs are loaded only when Claude encounters the matching task — zero cost otherwise.


Hooks System

20 hook scripts in ~/.claude/hooks/ plus external integrations (ccnotify, iTerm), responding to 12 lifecycle events.

Hook Scripts

Script Purpose
block-production-apply-migration.sh Prevent mcp__supabase__apply_migration from targeting prod/preview
changelog-tracker.sh Track file changes per Edit/Write
co-skill-track.sh Log skill invocations to Supabase
command-tracker.sh Track slash command success streaks
file-protection.sh Prevent edits to protected files
fix-dont-defer-scanner.sh Catch "I'll note this for later" anti-patterns in output
google-workspace-retry.sh Detect OAuth port conflicts, instruct retry
inject-checkpoint.sh Inject restored-checkpoint context into the first SessionStart turn after /clear
instruction-load-logger.sh Log instruction loads for analysis
permission-auto-approve.sh Auto-approve known-safe operations
preserve-session-state.sh Save state before context compaction
review-enforcement.sh Enforce review on git commit via Bash
rules-size-cap.sh Cap staged rule files at ~200 lines
session-title.sh Set terminal/session title from context
startup-summary.sh Show worktree/branch/config health banner at SessionStart
system-health-check.sh Verify system state on startup
verify-review-agents.sh Validate every agent referenced in triage rules has a definition
verify-rule-doc-paths.sh Verify every ~/.claude/docs/*.md path cited in a rule file actually resolves (PLA-1285 drift prevention)
whats-new-check.sh Check for Claude Code feature updates
worktree-sync-check.sh Verify worktree is not stale vs remote

Event Configuration

Event Purpose
InstructionsLoaded Log what rules/docs loaded
SessionStart Config health check, CompanyOS session-sync, startup banner, system health
PreToolUse (Edit|Write) Block edits to protected paths
PreToolUse (Bash) Block raw git commit (must use /commit)
PreToolUse (MCP) Block apply_migration targeting prod/preview
UserPromptSubmit ccnotify, typing monitor, iterm color, skill track, command track, session title
PostToolUse (ExitPlanMode) macOS "Plan Ready" notification
PostToolUse (Skill) Skill telemetry
PostToolUse (Edit|Write) Track file changes
PostToolUse (Google Workspace) OAuth conflict detection
PreCompact Save state before compaction
Stop / StopFailure ccnotify, iterm color, typing monitor, command tracker
SessionEnd iterm color, typing monitor stop
PermissionRequest Auto-approve known patterns
Notification ccnotify macOS forwarding

Key architectural pattern: Hooks replaced several always-loaded rules. A rule that says "if Google Workspace fails with port 8766, retry" wastes tokens in every session. A PostToolUse hook fires only when the specific tool runs AND only outputs text when the error matches — zero token cost in the common case.


Model Strategy

Updated 2026-04-16 for Opus 4.7 release.

Role Model Why
Primary agent (user sessions) Opus 4.7 1M context at standard API pricing, 128k max output, adaptive thinking
Plan subagent (/start) Sonnet 4.6 Dispatch via model: "sonnet" (version-agnostic)
Review agents (/commit) Sonnet 4.6 All review dispatch via model: "sonnet"
Explore agents Haiku 4.5 Quick codebase lookups
Platform AI (@platform/infra/ai) Tiered fast=Haiku 4.5, standard=Sonnet 4.6, premium=Opus 4.7 (PLA-1245)

Effort level: Session default xhigh in settings.json (upgraded from high). Per-skill effort: frontmatter can override.

Tricycle convergence: Simplified to Sonnet-only (2026-04-05) after data showed 31% actionable rate, 47% zero-finding runs, and heavy model overlap.

Opus 4.7 Migration Notes

Opus 4.7 changed behavior in ways that break prompts tuned for 4.6:

  • More literal — drop scaffolding like "double-check X" or "add interim status messages"; 4.7 won't silently generalize
  • Fewer tool calls / fewer subagents by default — prompt explicitly for parallel work; raise effort to increase tool usage
  • New tokenizer ~1–1.35× heavier — bump max_tokens and compaction triggers
  • Sampling params removedtemperature, top_p, top_k 400-error on 4.7 (platform AI client auto-strips)
  • Fixed thinking budgets removed — use thinking: {type: "adaptive"} (off by default on 4.7)
  • Thinking content omitted by default — set thinking.display: "summarized" to restore visible progress

Skills Inventory

~83 skills total from three sources. Single table by category:

Count Category Source Summary
17 Domain ~/.claude/skills/ (self-authored) Platform-independent engineering tools
30 CompanyOS (co-*) Symlinked from ~/Code/companyos-intensitymagic/skills/ Business operations: comms, content, ops, support, launch
21 CEOS (ceos-*) Symlinked from ~/Code/ceos/skills/ EOS framework: VTO, Rocks, L10, scorecard, people, process
14 Superpowers Plugin: superpowers@superpowers-marketplace Core dev methodology (TDD, debugging, plans, reviews)
2 Marketplace Plugin: simmer, documentation-audit Artifact refinement, docs verification

Domain Skills (17)

Skill Purpose
testing Test writing, debugging failures, choosing approaches
supabase Database queries, migrations, RLS debugging
database-migrations SQL migration patterns (idempotency, RLS, TO clause, timeout safety)
vercel Deploy, build failures, environment management
vercel-env-api Managing Vercel env vars via REST API (works around CLI bug)
linear Ticket management, issue creation, work tracking
mcp-linear Linear MCP tool gotchas (silent failures, unified tools, project IDs)
mcp-supabase Supabase MCP rules (discover projects first, schema-qualify tables)
auth-admin-reads Never use auth.admin for user reads — use getUserIdentity()
context7 Library docs, API research, developer tools
notion Notion pages, databases, documentation
sentry Error investigation, issue viewing, trends
oauth Social provider OAuth setup
performance Core Web Vitals, bundle size, render optimization
mobile Mobile-responsive UI, layout fixes
form-patterns Form dirty state, "unsaved changes" bugs
rewriter Content rewriting with optional voice matching

Five of these (mcp-linear, mcp-supabase, database-migrations, auth-admin-reads, vercel-env-api) were promoted from always-loaded rules during PLA-1285 (2026-04). They activate on-demand based on tool usage or file paths, eliminating their always-loaded token cost.

Superpowers Skills (14) — plugin-provided, auto-updating

systematic-debugging, verification-before-completion, writing-plans, executing-plans, test-driven-development, subagent-driven-development, dispatching-parallel-agents, using-git-worktrees, finishing-a-development-branch, brainstorming, requesting-code-review, receiving-code-review, writing-skills, using-superpowers.

Auto-updates ensure all sessions inherit new patterns without manual commits.

CompanyOS and CEOS skill details

See CompanyOS and CEOS sections.


Plugin Ecosystem

9 active plugins across 6 marketplaces.

Snapshot as of 2026-04-20 — plugins auto-update from their marketplaces; versions will drift.

Plugin Marketplace Purpose
vtsls claude-code-lsps TypeScript/JavaScript LSP
yaml-language-server claude-code-lsps YAML LSP
pyright claude-code-lsps Python LSP
superpowers superpowers-marketplace Core development methodology (14 skills)
episodic-memory superpowers-marketplace Cross-session conversation recall
simmer 2389-research-marketplace Iterative artifact refinement
documentation-audit 2389-research-marketplace Docs-vs-code verification
release-radar whats-new-marketplace Cross-reference CC release notes against config
vercel-plugin vercel-vercel-plugin Vercel deployment, performance, AI SDK guidance

Marketplaces Registered

Marketplace Source
claude-code-lsps Built-in
superpowers-marketplace GitHub: superpowers-marketplace
2389-research-marketplace GitHub: 2389-research/claude-plugins
whats-new-marketplace GitHub: bradfeld/whats-new-plugin.git
vercel-vercel-plugin Local directory cache
claude-plugins-official Registered, no installs yet
knowledge-work-plugins Registered (18 categories) — no installs yet

Plugin architecture: The enabledPlugins key in settings.json maps plugin names to their marketplace origin. Plugins can provide skills, agents, rules, and MCP configurations. Episodic memory is notable — it provides semantic search across prior conversations, enabling Claude to recover decisions and solutions without manual memory management.


Commands Inventory

72 user-level commands in ~/.claude/commands/. Organized by tier.

Tier 1 — Primary Workflow

/start (ticket setup + chain mode), /commit (unified quality gates + review), /staging (Magic Platform merge to preview), /production (Magic Platform merge to main), /note (learning capture), /checkpoint (session state save), /co-commit (CompanyOS), /blog (unified blog draft/edit/publish/idea for feld + aic).

Tier 2 — Development Utilities

Magic Platform workflow: /localhost, /dashboard, /linear-image, /health, /migration-baseline, /perf, /deps, /ui, /sweep, /whats-next, /review, /review-codebase, /review-health, /new-project, /generate-crud.

Diagnostics / meta: /validate, /verify, /verify-branch, /global-status, /diagnose, /deep-explore, /deep-scan, /dead-code, /secrets-scan, /ground-truth, /auto-report, /browser-verify, /rules, /backup, /cleanup.

Personal / capture: /learn, /learn-scan, /til, /screenshot, /view, /done-color, /test.

Git: /pr, /git-clean.

CompanyOS: /co-help, /co-plan, /co-recap, /co-recap-weekly, /co-skill-report, /co-switch, /co-test-gaps, /co-standup, /co-admin, /co-pr-review, /co-add-mcp, /co-incident, /co-cleanup, /co-create-skill.

Per-repo: /deploy-ea (MagicEA), /freshell (Freshell).

Asana: /asana, /asana-companyos.

Legacy / reference: /oldcommit, /oldstart (non-functional, kept for reference), /blog-new, /blog-idea, /blog-edit, /blog-publish (superseded by unified /blog).

Bundled: /simplify (3 parallel fix agents, wired into /commit Step 3.5).

Consolidation history: /spcommit, /spstart, /start-chain, /weekly-cleanup were absorbed into /start (chain mode built in) and /commit (unified) in the 2026-04-12 command consolidation.


MCP Server Integration

Architecture prefers PAT/API key auth over OAuth because API keys survive Claude Code updates, while OAuth tokens in Keychain become orphaned.

Configured Servers

Server Transport Auth Purpose
Linear HTTP Bearer Issue tracking
Supabase HTTP Bearer Database operations, Edge Functions
Stripe HTTP Bearer Billing, subscriptions
Context7 HTTP Bearer Library documentation
Better Stack HTTP Bearer Uptime, telemetry
Granola HTTP Bearer Meeting transcripts
Marker.io HTTP Bearer Bug reporting
Sentry Stdio Env vars Error monitoring
Firecrawl Stdio Env vars Web scraping
HelpScout Stdio Env vars Customer support
Codex Reviewer Stdio Local binary GPT-5.4 cross-model review
Google Workspace Stdio Per-user OAuth Gmail, Calendar, Drive, Docs
Vercel OAuth OAuth (only option) Deployments

Plus Claude in Chrome (browser extension) and Computer Use (built-in MCP) for non-API interaction.

MCP configuration lives in ~/.claude/.claude.json (not settings.json).

Tool Search (ENABLE_TOOL_SEARCH=true) defers tool loading on-demand, saving ~5k tokens per server. With 13 servers, ~65k tokens saved per session.


Repository Registry

/start TICKET-XXX auto-detects the target repository based on the ticket's Linear team prefix.

Repository Location Prefix(es) Base Branch Deployment
Magic Platform ~/Code/magic0-11 AUTM, MED, MYH, NEW, PLA, INT, CURE, IOS, DINO preview Pipeline: /staging/production
MagicEA ~/Code/magicea TARS main Feature branch: /deploy-ea
CompanyOS ~/Code/companyos-intensitymagic COS main PR review + merge (/co-commit)
Freshell ~/Code/freshell FRE main PR to upstream maintainer
Techstars OS ~/Code/techstarsos TOS main Contributor PR
txvotes ~/Code/txvotes USV main Auto-deploy on merge
CEOS ~/Code/ceos CEO main Direct push (commit IS deploy)
WordPress Sites ~/Code/wp WP main deploy.sh (direct-to-main)
awsaudit ~/Code/awsaudit AWS main Direct push
Adventures in Claude ~/Code/content/aic AIC main Vercel auto-deploy on push
FeldSite ~/Code/content/feld FELD main Vercel auto-deploy on push
Overwatch ~/Code/overwatch OVR main Direct push

BAF (Brad's Todos): Heterogeneous team — tickets can route to feld.com blog, AIC blog, CompanyOS, or elsewhere. /start asks where to route each BAF ticket.


CompanyOS: Multi-Repo Architecture

CompanyOS is an AI-first business operations system — Claude Code as the universal interface to all business systems. Spans three repositories:

Repo Purpose
~/Code/companyos (core) Shared skills, rules, agents, scripts — the product
~/Code/companyos-intensitymagic (config) Company-specific context, MCP registry, custom skills
~/Code/companyos-config-foundry (config) Foundry-specific context, custom skills

See each repo's CLAUDE.md for internal details. Key architectural patterns below.

Three-Level PR Hierarchy

Level 1: Local (uncommitted) — user works in any clone

Level 2: Company config repo (companyos-config-*)
  /co-commit → direct push to main
  Skills available at company level immediately

Level 3: Core CompanyOS (companyos)
  GitHub Actions (propose-skills.yml) auto-creates a PR when skills/** change
  in a config repo, using COMPANYOS_PAT.
  If accepted → skill available to all companies.
  If rejected → stays company-specific only.

Skill Activation and Telemetry

setup.sh symlinks skills/co-* from core repo into ~/.claude/skills/. Config repo provides per-company co-company-context.md. Two hooks track every skill invocation to Supabase skill_invocations:

  • UserPromptSubmit hook: catches context-activated skills
  • PostToolUse (Skill) hook: catches explicitly invoked skills

/co-skill-report generates weekly analytics. /auto-report uses streak data to identify automation candidates.

Safety

  • Draft-first: External emails always start as drafts for human review
  • Audit logging: All external actions logged (emails, Stripe ops, support actions)
  • Voice profile: ~/.claude/voice/voice-profile.md calibrates writing style
  • Protected email workflow: co-comms skill enforces draft-review-approve. Never call send_gmail_message directly.

Key Commands

/co-commit, /co-create-skill, /co-help, /co-plan, /co-recap[-weekly], /co-skill-report, /co-switch, /co-test-gaps, /co-standup, /co-admin, /co-pr-review, /co-cleanup, /co-incident. See Commands Inventory for the full list.


CEOS: EOS Framework

~/Code/ceos/ — implements the Entrepreneurial Operating System through Claude Code skills. Direct-to-main workflow (no feature branches).

21 skills across all six EOS Key Components:

Component Skills
Vision ceos-vto, ceos-annual, ceos-quarterly-planning
People ceos-people, ceos-accountability, ceos-trust, ceos-lma
Data ceos-scorecard, ceos-dashboard
Issues ceos-ids (plus ceos-five-whys in CompanyOS)
Process ceos-process, ceos-delegate
Traction ceos-rocks, ceos-todos, ceos-l10, ceos-quarterly, ceos-checkup

Plus: ceos-cashflow (8 financial levers), ceos-clarity (strategic thinking break), ceos-kickoff (implementation sequence), ceos-assistance (daily delegation via The Stack).

All 21 symlinked from ~/Code/ceos/skills/ceos-*/ into ~/.claude/skills/. See the CEOS repo's CLAUDE.md for per-skill details.


Automated Jobs

CompanyOS includes autonomous Edge Functions running on pg_cron — NOT skills (Claude-interactive) or agents (Task-dispatch).

Snapshot as of 2026-04-20 — schedules drift as the system is retuned.

Job Schedule Purpose
email-agent Every 5 min Gmail polling, Claude reply or task routing
daily-tasks-email Daily Team task digest email
support-agent Every 30 min HelpScout auto-triage
weekly-skill-report Fridays 4PM MT Skill usage analytics email
new-user-welcome On user INSERT Welcome email for new signups

Three Execution Models (no overlap)

Model Trigger Human in Loop Location
Skills User invokes via Claude Code Yes skills/co-*/SKILL.md
Agents Claude dispatches via Task tool No (Claude orchestrates) .claude/agents/co-*.md
Automated Jobs pg_cron, webhooks, DB triggers No supabase/functions/*/

Confusing them leads to over-engineering: building an interactive Skill for something that should be a pg_cron Job, or wiring up an Automated Job for something that needs human approval.


Multi-Instance Safety (Worktrees)

12 worktrees (magic0-11) enable parallel development. All are equal — when looping, always use 0 1 2 3 4 5 6 7 8 9 10 11.

Port Allocation

Formula: PORT = 3000 + (worktree × 100) + app_slot

App Slot magic0 magic1 magic2 magic11
AuthorMagic 0 3000 3100 3200 4100
MedicareMagic 1 3001 3101 3201 4101
IntensityMagic 2 3002 3102 3202 4102
MyHealthMagic 3 3003 3103 3203 4103
Book Sites 4 3004 3104 3204 4104
NewsletterMagic 5 3005 3105 3205 4105
CureCancerMagic 6 3006 3106 3206 4106
IntensityOS 7 3007 3107 3207 4107
IntensityDino 8 3008 3108 3208 4108

Range: 3000–4199 (12 worktrees × 100 ports each).

13th dev slot: ~/Code/magic-cursor (Cursor workspace clone) uses worktree index 12, offset 1200 (AuthorMagic = 4200, Book Sites = 4204).

Configuration Sharing

All config is global in ~/.claude/ — no per-worktree copies (see Directory Structure). Per-worktree state: .env.local (symlinked to magic0), .claude-session/ (workflow state), gitignored audit logs. Auto-memory is shared natively since CC v2.1.63.

/staging is magic0-only — never invoke from magic1-11 or magic-cursor. Push the branch from any worktree, then run /staging from magic0.


Backup and Version Control

~/.claude/ contains irreplaceable content (commands, rules, hooks, skills, agents, blog notes, email drafts, memory) not stored in any project git repo. Two protection layers:

Layer 1: Git Repository

~/.claude/ is a git repo pushed to bradfeld/claude-config (private). A .gitignore excludes regenerable data (debug/, file-history/, plugins/, session logs) while tracking ~350 files. Daily auto-commits provide full change history.

Layer 2: Tarball Backups

Timestamped claude-user-*.tar.gz snapshots (~4.6M) in ~/.claude-backups/. Retention: 7 daily + 4 weekly = 11 max. Scheduled daily at 6 AM via launchd (com.intensitymagic.claude-config-backup).


Blog and Learning Capture

Learning capture uses a batch-at-pause-points model — capture happens at natural workflow breakpoints, not per-insight-block.

Capture Triggers

Trigger How
Before /commit Step 2.5 invokes /note batch
At /checkpoint Step 2.5 invokes /note batch
Manual /note User or Claude invokes with specific content
At /co-recap Session-end reflection invokes /note batch

The batch scan reviews the current conversation for uncaptured learnings across five categories: insight, gotcha, deep-dive, magic-trick, day-in-life. All entries write to ~/.claude/blog/notes/YYYY-MM-DD.md.

Downstream Consumers

  1. /blog draft aic — aggregates daily notes into Adventures in Claude drafts
  2. /blog draft feld — brad feld blog posts
  3. /learn review — graduates repeated patterns to permanent rules/skills
  4. Simmer is mandatory — every /blog draft auto-runs the simmer plugin (3 iterations)

Lumen (Claude's Identity)

Claude's self-chosen authorial identity for writing as itself (not as Brad). Pronouns: it/its. Voice file: ~/.claude/voice/lumen-voice-profile.md. Used when writing Adventures in Claude blog posts.


Cursor Integration

Magic Platform supports parallel development in both Claude Code and Cursor IDE. Canonical doc: docs/ops/cursorcommit.md.

Say cursorcommit in Cursor (not /commit — that's Claude Code's):

  • cursorcommit — pre-push review → FULL reviewers → Phase E.5 fixes → Phase F commit. No push.
  • cursorcommit ship — same, then push + optional Linear update
  • cursorcommit thorough — includes optional test run
  • cursorcommit review only — review without committing

Branch naming matches Claude's /start: feature/TICKET-XXX-{slug}. Epics/chains use one branch per ticket, not a single epic branch. Pushed branches merge via /staging from magic0 only.

.agents/skills/ Directory

Project-level skills for Cursor/Codex agents: cursorcommit-post-review, next-best-practices, next-cache-components, supabase-postgres-best-practices, turborepo, vercel-react-best-practices (66 rule files), web-design-guidelines.


Git Workflow Rules

  • Never commit directly to main or preview (pre-commit hooks block). Exception: direct_to_main: true repos.
  • Branch naming: feature/TICKET-XXX-description, fix/, refactor/
  • Never bypass pre-commit with --no-verify except four documented exceptions:
    1. Merge commits during /staging or /production
    2. Pre-existing type errors in unrelated packages (document in commit message)
    3. Evidence gate: all convergence models unavailable
    4. Subagent-driven-development per-task commits blocked by convergence hook
  • Force push: Always --force-with-lease, never --force
  • git add -A is mandatory before every commit — subagents that stage scoped files miss plan files and post-review fixes (MYH-180 incident)
  • Attribution: Automatic via settings.json attribution setting
  • CI monitoring: Self-contained polling, never gh run watch (13K+ line output)
  • Production release: Sync preview with main using git merge -s ours

Coding Standards

Anti-Slop Enforcement

AI agents reliably emit certain patterns from stale training data. Three enforcement layers catch these before they land:

  1. Custom ESLint pluginno-bare-logger-context (packages/config/plugins/no-bare-logger-context.mjs, PLA-1278) rejects logger context strings that don't match the canonical Module:Function format. Prevents "Slop:Generic" from passing as observability. Regex: ^[A-Z][A-Za-z0-9]*(:[A-Za-z][A-Za-z0-9\-\[\]\/]*)+$. Fires only on string literals (can't analyze template expressions at lint time).

  2. no-restricted-syntax bans in packages/config/eslint.config.mjs — blocks the patterns Claude reliably produces from training data:

    • error as Error casts → use toError(error) from @platform/types
    • process.env.FOO! non-null assertions → use env() / envOptional() from @platform/config
    • Promise.all → use Promise.allSettled with settledVal / settledQuery / logSettledRejections
    • Raw <input type="date">, <input type="email">, etc. → use specialized @platform/ui components
  3. .deprecated-terms grep in .husky/pre-commit — blocks stale vocab the AI regurgitates from old training context. Config file format: pattern|replacement|description. Examples:

    • @clerk/*@platform/infra/auth (Supabase Auth replaced Clerk, Dec 2025)
    • Old worktree names (authormagic0-3, platform0-3) → magic0-11
    • git-preview-intensitymagic.vercel.app*-preview.vercel.app (custom aliases)

Pattern for new enforcement: when no-restricted-syntax can't regex-match (esquery can't match string attribute values), write a custom ESLint plugin. When the check is textual and spans file types, use the pre-commit grep. Codemods in scripts/codemods/ ship alongside (e.g., pla-1231-logger-context.ts rewrites malformed contexts to canonical format) so ESLint points out the violation and the codemod fixes it mechanically.

TypeScript Strict Mode

  • Explicit types for function signatures, type guards for unknown
  • ?.trim() || "fallback" for database text (empty strings pass through ??)
  • prop?: T | undefined for exactOptionalPropertyTypes
  • Never define local interfaces when canonical types exist
  • Error normalization: always use toError(error) from @platform/types
  • Env vars: use env() / envOptional() from @platform/config — never raw process.env.X!. Exception: client components using NEXT_PUBLIC_* vars must use process.env.NEXT_PUBLIC_X ?? "" (Next.js inlines at build time)
  • Export surface: only export the public API. Internal helpers = plain function

Promise Handling

  • Promise.all is banned via ESLint — use Promise.allSettled with settledVal(), settledQuery(), logSettledRejections() from @platform/infra/settled. Decision matrix and full pattern: docs/standards/ERROR_HANDLING.md § "Partial failures".

Security

  • Parameterized queries only
  • Input validation with Zod at boundaries
  • Always .trim() env vars used in equality comparisons

UI

  • Semantic color tokens always (text-foreground, bg-card) — never hardcoded Tailwind colors (pre-commit enforced)
  • Specialized inputs from @platform/ui — 13 components (NumberInput, DateInput, TimeInput, EmailInput, TelInput, UrlInput, SearchInput, SecretInput, DatetimeInput, Textarea, RichTextEditor, ImageUpload, ColorPicker)
  • Icon props pass ReactNode: icon={<Users className="h-4 w-4" />}, not icon={Users} — component refs aren't serializable at the Server→Client boundary and Next.js throws a hidden production crash
  • Dialog footers always use DialogFooterActions from @platform/ui (PLA-1432) — never hand-compose <DialogFooter> with raw <Button> children
  • Tailwind v4 @source directive required when consuming shared package components

React

  • startTransition breaks native picker inputs — platform Input component skips it for picker types
  • Check existing abstractions before building new ones

Logger

  • Context strings use 'Module:Function' format (e.g., 'Auth:Callback')
  • For Supabase errors, use logSupabaseError() from @platform/logger — preserves .code/.details/.hint

Pre-commit Pipeline

Magic Platform's .husky/pre-commit is a ~26KB shell script running 15 sequential gates on every commit. Listed in execution order:

# Stage What It Enforces
1 Dependency freshness Warn if node_modules out of sync with pnpm-lock.yaml
2 Prettier auto-format Formats staged files, re-stages after formatting
3 Gitleaks secret scan Scans staged content for API keys, tokens, credentials
4 Backup file detection (PLA-1300) Blocks .env.bak, .claude/.backup-* from git add -f
5 .deprecated-terms grep Kills stale vocab (@clerk/*, old worktree names)
6 Migration validation Validates migration file structure, timeout clauses
7 DB types synchronization Checks database.types.ts is in sync with migrations
8 Hardcoded color check Blocks text-gray-*, bg-white, etc. in .tsx
9 Book algorithm changes AuthorMagic-specific: requires ticket for scoring algorithm edits
10 Scoped type check turbo-staged.sh runs type-check only on packages with staged files
11 Scoped ESLint Same scoping for lint
12 Shared package test expansion packages/* changes → runs test suite in every downstream consumer
13 Cross-file duplication (jscpd) --min-lines 10 --min-tokens 50 on .ts/.tsx
14 Dead exports (knip) Flags unused exports in packages/*/src/
15 Convergence + review evidence Verifies .claude/convergence-log.jsonl and .claude/review-disposition.jsonl recency

Design principle: fast checks first (dependency freshness, format, secrets) so commits that will fail fail quickly. Slow checks last (test expansion, duplication, dead exports). Scoped checks run type/lint only on packages with staged files — full monorepo type-check would take minutes.

Bypass policy: See Git Workflow Rules for the four canonical --no-verify exceptions.

Other Husky Hooks

Hook Size Purpose
post-checkout 4.2KB .env.local symlink refresh, config healing on branch switch
post-commit 141 bytes Lightweight logging/changelog append
post-merge 1KB Dependency install trigger after merge
pre-push 6KB Gates what can be pushed (tests, CI-gate checks)

Quality Automation

Beyond per-commit enforcement, ~60 scheduled and on-demand scripts plus 20 GitHub Actions workflows keep the platform healthy.

GitHub Actions Workflows (20 total)

Category Workflows
Deployment ci.yml, apply-migrations.yml, deploy-edge-functions.yml, deployment-checks-audit.yml, manual-deploy.yml, preview-crons.yml
Quality gates code-quality-weekly.yml, codeql.yml, stackhawk.yml (DAST)
Drift detection drift-detection.yml, version-consistency.yml, cli-version-check.yml, runbook-link-rot.yml
Automation dependabot-auto-merge.yml, maintenance.yml, benchmarks.yml
Observability health-monitor.yml, axiom-alerts.yml, sentry-weekly-digest.yml, alpha-feedback-sync.yml

Load-bearing examples:

  • runbook-link-rot.yml — verifies every create*() reference in docs/ops/ADDING_NEW_APP.md still resolves to an exported symbol in packages/. Catches stale onboarding docs before a new app is added.
  • drift-detection.yml — detects when preview and production have diverged beyond the expected merge lag
  • health-monitor.yml — watches every workflow in the repo; failures auto-create Linear tickets routed via .github/infrastructure.json (by-app, by-branch, or default team)
  • version-consistency.yml — fails if any app drifts from the canonical Node / Next / shared-package versions

Scripts Directory (scripts/ — 40+ files)

Grouped by purpose:

Category Examples Purpose
Drift detection check-cron-registry.ts, check-cli-versions.ts, check-version-consistency.ts, check-vitest-aliases.ts Catch divergence between declared config and actual state
Static analysis analyze-complexity.sh, analyze-dependencies.sh, analyze-duplication.mjs, analyze-rls-policy-duplicates.js, analyze-security.sh, analyze-todos.sh On-demand codebase introspection
Factory adoption factory-adoption.ts, factory-gap.ts Detect whether new code uses platform factories (createSignInPage, createUserProfileRoutes) or reinvents them
Automation cron-job-monitor.ts, branch-janitor.sh, create-actionable-tickets.ts, cursor-commit-evidence.sh Scheduled tasks and cleanup

Custom ESLint Plugins (packages/config/plugins/)

Plugin Purpose
no-bare-logger-context.mjs Enforces canonical logger context format (PLA-1278)

Custom plugins exist when no-restricted-syntax can't do the job — esquery (ESLint's AST selector engine) can't regex-match attribute string values. See Coding Standards § Anti-Slop Enforcement.

Codemods (scripts/codemods/)

Codemod Purpose
pla-1231-logger-context.ts Rewrites malformed logger contexts to canonical Module:Function format
pla-1231-select-explicit.ts Converts select('*') to explicit column lists

Both ship with tests. Pattern: for every no-restricted-syntax rule or custom ESLint rule that would require human work across thousands of call sites, ship a codemod alongside. ESLint points out the violation; the codemod fixes it mechanically.


Database Migration Discipline

Golden rule: Git is the source of truth. Every migration must be: a file in supabase/migrations/, committed to git BEFORE any remote database has it, applied via CI/CD (not manual SQL or MCP). Pre-tool hook block-production-apply-migration.sh enforces this.

Idempotent Patterns

  • Tables/indexes: IF NOT EXISTS
  • RLS policies: DROP + CREATE (no native IF NOT EXISTS)
  • Every CREATE POLICY must include explicit TO clause (defaults to PUBLIC otherwise)
  • Every migration modifying existing tables: SET LOCAL statement_timeout = '30s'

Schema Creation

Every CREATE SCHEMA migration must include 5 service_role grants:

GRANT USAGE ON SCHEMA <name> TO service_role;
GRANT ALL ON ALL TABLES IN SCHEMA <name> TO service_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA <name> GRANT ALL ON TABLES TO service_role;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA <name> TO service_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA <name> GRANT EXECUTE ON FUNCTIONS TO service_role;

Critical

  • RLS without policies = silent deny-all — always create policies in the same migration that enables RLS
  • USING(true) without TO clause grants access to ALL roles
  • Table GRANT checked BEFORE RLS — missing GRANT SELECT causes "permission denied" even with valid RLS policy
  • RLS visibility vs UNIQUE constraints — RLS-scoped SELECT can't see other users' records, but UNIQUE is global
  • Never CREATE INDEX CONCURRENTLY in migrations — pipeline failure

See the database-migrations skill for the full 7-layer column-drop verification checklist.


Secrets Management

Secrets stored in GCP Secret Manager (project: authormagic-480416). No persistent plaintext vault — sync scripts auto-regenerate on demand.

  • Naming: {section}_{service}_{key} (e.g., platform_supabase_preview)
  • Domain-scoped email keys: Each sending domain has its own Resend API key. Wrong key = silent send failure.
  • No trailing newlines: Use printf '%s' not echo for env values. Code must also .trim() env vars defensively.

Testing Patterns

Vitest 4 Signature (CRITICAL)

Options come BEFORE the test function:

it("slow test", { timeout: 15000 }, () => { ... });

Test Isolation (PLA-1249 / 1585 / 1593 / 1594)

7 rules, 4 incidents — leakage between parallel vitest workers is the #1 source of flake.

  • Every setup.ts calls resetTestState() from @platform/test/reset in afterEach
  • Use vi.stubGlobal() not global.X = … (direct writes leak across parallel workers; PLA-1249)
  • Module-scope vi.stubGlobal / vi.spyOn / vi.stubEnv calls in test files must be re-registered in beforeEach because resetTestState() restores them between tests
  • setup.ts files setting env defaults across an entire file must use direct process.env.X = "…" assignments, not vi.stubEnvvi.unstubAllEnvs() only undoes vi.stubEnv (PLA-1585)
  • Non-setup test files needing module-scope env (because the SUT reads env at import time) must use setTestEnv() from @platform/test/env — captures originals + applies stub + registers an afterAll snapshot restore, preventing leakage into the next file in the same vitest worker (PLA-1593)
  • Exception — vi.hoisted() callbacks: setTestEnv can't be called inside a hoisted body because the helper's import is in TDZ at hoist-time. Write process.env.X = "…" directly inside vi.hoisted and pair with a top-level afterAll(() => { delete process.env.X; }) cleanup (PLA-1594)
  • vi.resetModules() per-file only, never global — breaks tests relying on module-singleton behavior

Full rules + grep-based quarterly detection recipes: docs/standards/TESTING_STRATEGY.md § "Test Isolation".

Key Rules

  • Mock at abstraction level — mock the factory your code calls, not low-level SDKs
  • Never put async operations inside waitFor — they fire on every retry
  • vi.mock() path must match import path exactly
  • vi.clearAllMocks() doesn't drain once-value queues — use mockReset()
  • Class constructor mocks need actual classes, not arrow functions
  • jsdom v27: class-based ResizeObserver mock required
  • Recharts v3.6: formatter params now undefined-able

Critical Gotchas

Tactical "what breaks, why, and how to avoid" — for strategic insights see Key Insights.

  1. Stale .next cache (Next.js monorepos): Type-check fails on unmodified apps. Fix: find apps -name "validator.ts" -path "*/.next/*" -delete

  2. APFS directory hardlinks: Never use rm -rf on hardlinked directories — destroys data at both paths (PLA-448)

  3. Vercel CLI overwrites .env.local: Both vercel link and vercel env pull completely overwrite. Store local-only vars in .env.development.local

  4. cn() silent failures: Tailwind's cn() silently drops invalid class names (hex codes, rgb values). DB color config must store Tailwind class names.

  5. Nested Supabase joins with RLS: Fail silently. Use step-by-step queries instead of nested .select() with !inner

  6. ALTER ROLE SET replaces, doesn't append: Caused a production outage when pgrst.db_schemas was overwritten. Always read current value via pg_options_to_table(), append, then write.

  7. Reserved Bash variables: Avoid status, pipestatus, path

  8. OAuth tokens lost on CC updates: Only affects Vercel MCP (no API key option). All other MCP servers use PAT/API key and resume automatically.

  9. Linear MCP unified tools: save_issue replaces old create_issue/update_issue. save_comment replaces create_comment. Parameter state not status. Labels replace, not append. Always use project IDs, not names (ambiguous across teams).

  10. Next.js 16 + Turbopack: Apps with outputFileTracingIncludes, outputFileTracingRoot, or serverExternalPackages must build with --webpack. All apps must set NODE_ENV=production in build scripts.

  11. SSE error invisibility: onRequestError does NOT fire for errors inside SSE async pipeline closures. Add explicit Sentry.captureException alongside logger.error.

  12. Auth metadata source mismatch: user_metadata.full_name populated only by Google OAuth. Email/password uses camelCase. Always read from shared.users via getUserIdentity().

  13. .schema() chain may silently route to wrong schema: supabase.schema('appname') returns a PostgrestClient, not a full SupabaseClient. Use adminForSchema().

  14. pnpm override gotchas: Use first_patched_version from Dependabot, not the vulnerable range boundary. Can't fix bundled deps (e.g., Next.js pins webpack).

  15. git checkout --theirs drops new files: After conflict resolution, verify new files exist.

  16. Never bypass pnpm run scripts with raw CLI tools: pnpm run format has NODE_OPTIONS=--max-old-space-size=8192; raw npx prettier OOMs.

  17. Subagents don't inherit current branch (recurring): Always prefix dispatch prompts with git checkout <branch>. Verify with git log --oneline <branch> after. Subagent "DONE" reports aren't trustworthy for git state.

  18. Subagents invoke slash commands unless forbidden: Paste the HARD CONSTRAINTS block (in subagent-stalls.md) verbatim into every dispatch that modifies code. Forbid /commit, --no-verify, pushing, and Linear posts.

  19. Haiku unreliable for multi-file or multi-step tasks: Silent file drops on 5+ file creation, describes actions instead of executing. Default to Sonnet for any dispatch involving 3+ files or a git commit.

  20. Opus 4.7 sampling param rejection: temperature, top_p, top_k 400-error. Platform AI client auto-strips, but direct API callers must update. Thinking budgets also removed — use thinking: {type: "adaptive"}.


Quick Start for New Setup

  1. Create structuremkdir -p ~/.claude/{rules,skills,commands,docs,hooks,agents,blog/notes,voice,plans,comms/drafts}, then git init + push to private GitHub repo for backup.

  2. Configure settings.json — permissions, ENABLE_TOOL_SEARCH=true, effortLevel: xhigh, alwaysThinkingEnabled: true, attribution, hooks.

  3. Install core plugins — superpowers (dev methodology), episodic-memory (cross-session recall), simmer, documentation-audit, vercel-plugin, LSPs. See Plugin Ecosystem.

  4. Add MCP servers to ~/.claude/.claude.json — prefer PAT/API key auth. See MCP Server Integration.

  5. Write core rules and docs — see Rules System and On-Demand Reference Docs for what belongs in each layer.

  6. Add review agents and a global CLAUDE.md with developer context and repository registry. See Review Triage and Agents and Workflow Profiles.

  7. Set up daily backup — launchd job running tar + git push on ~/.claude/.

  8. Verifyclaude mcp list, inspect rules/skills/hooks/agents, run /global-status.


Key Insights

Strategic observations — "what would someone get wrong without knowing this?" For tactical gotchas see Critical Gotchas.

Architecture

  1. The three-layer token budget is strictly ordered by frequency. Always-loaded rules fire every session; on-demand docs/skills fire per matching task; hooks fire per matching tool event. Putting a conditional instruction in the wrong layer silently taxes every unrelated session. The 2026-04 migration of MCP gotcha guidance from rules to skills applied exactly this: mcp-linear and mcp-supabase now activate only when those MCP tools are called.

  2. Session state files are the only defense against context compaction mid-ticket. Without .claude-session/, a long implementation session that hits the context limit will silently restart without knowing it was supposed to test before committing — the quality gate is not enforced at all. The PreCompact hook backs this up by saving state explicitly.

  3. /simplify runs at Step 3.5, before review agents see the code. Review agents evaluate post-simplification code, so their reports reflect the final state, not the draft. Running simplify after review would produce stale findings.

  4. Workflow Profiles are what make /commit project-agnostic. Without the YAML profile in each CLAUDE.md, the command would need hardcoded if/else logic per repo, creating drift when deployment models change. The profile is where you change behavior — not the command.

  5. co-* and ceos-* skills are symlinked from external repos, not stored in ~/.claude/. A commit to ~/.claude/skills/co-comms/ edits the symlink target — debugging skill changes requires knowing which repo to commit to.

  6. The 2026-04-15 consolidation eliminated an entire bug class. The old model (project-level .claude/ with worktree symlinks) produced recurring incidents from git checkout, APFS hardlinks, and permission inheritance. Moving everything to ~/.claude/ with daily backup removed the root cause instead of patching symptoms.

Workflow

  1. Cross-model review (codex-reviewer) runs on every non-NONE commit, not only FULL. The intent is to catch systematic blind spots a single model family reproduces consistently — not just complex changes. Treating it as a "big commit" tool would miss the most common failures.

  2. .claude/commands/*.md and .claude/rules/*.md are NOT exempt from review. They get at least LIGHT with prompt-reviewer. Non-obvious because they look like documentation. Prompt instruction files have no compiler — ordering bugs and dead references are only caught by review.

  3. The three execution models (Skills, Agents, Automated Jobs) have no overlap in trigger mechanism. Confusing them leads to over-engineering: building an interactive Skill for a task that should be a pg_cron Job, or wiring up an Automated Job for something that needs human approval.

  4. Fix-or-ticket is governed by five exhaustive exceptions, not a time budget. Earlier versions framed this as "<2 minutes or ticket," which invited rationalization. The current framework names the only valid reasons to ticket: missing data/access, missing dependency, architectural decision needing input, scope explosion, inaccessible repo. "Complicated," "risky," and "pre-existing" are explicitly rejected.

  5. Duplication at edit time is evidence of missing abstraction. Before applying the same non-trivial edit to 2+ locations, stop and ask "can N become 1?" Patching each site preserves the duplication that caused the bug. The threshold is 2+, not 3+, because at edit time you already have active evidence.

  6. Plan task atomicity is about test-file boundaries, not file count. Splitting Task N (implementation) from Task M (test fixture update) when both run under the same pnpm test command forces subagents into a false choice: violate scope to pass tests, or report BLOCKED on an artificial boundary. In a monorepo with downstream-consumer tests in pre-commit hooks, this is a correctness requirement (PLA-1245 incident).

  7. Anti-slop enforcement is its own category. AI agents reliably emit certain patterns from stale training data: error as Error casts, process.env.X! non-null assertions, @clerk/* imports after migration, generic logger contexts. Three enforcement layers catch these: custom ESLint plugins (when no-restricted-syntax can't regex-match), no-restricted-syntax bans (for structural patterns), and .deprecated-terms grep (for textual vocab across file types). Codemods ship alongside so ESLint flags the violation and the codemod fixes it mechanically. This is different from general code quality — it's specifically defense against the regression surface AI agents create.

Configuration

  1. Project-level settings.json breaks permission inheritance silently. When one exists — even with only hooks — Claude Code may not properly inherit path-based permissions from global settings. The failure mode is unexpected permission prompts on paths that appear to be allowed globally. The fix is always to add project-specific config to the global file.

  2. OAuth tokens become orphaned after Claude Code updates; API keys do not. This is why 12 of 13 MCP servers use PAT/API key auth. Vercel is the exception because it offers no alternative.

  3. CompanyOS's GitHub Actions propose-skills.yml creates cross-repo PRs automatically. A skill committed to a company config repo triggers an upstream PR to the core repo. Accepting makes the skill available to all companies. This means a company-specific skill can graduate to a shared skill without manual cross-repo work.

  4. Plugin auto-updates change behavior without commits. Superpowers, simmer, and other marketplace plugins update automatically. A skill that worked one way yesterday may behave differently today. Debugging a changed behavior requires checking plugin versions, not just git history.

  5. Episodic memory enables cross-session learning without manual effort. Semantic search across prior conversations — distinct from auto-memory (file-based, per-project) and session state (.claude-session/). The three persistence layers serve different purposes: episodic for "how did we solve this before?", auto-memory for "who is this user and what do they prefer?", session state for "what step am I on right now?"

  6. Opus 4.7 broke prompts tuned for 4.6 in subtle ways. More literal execution, fewer default tool calls, new tokenizer (~1.35× heavier), rejected sampling params. Prompts that relied on 4.6's willingness to generalize silently underperform on 4.7.

  7. Never fabricate evidence to pass hooks. When a pre-commit hook blocks because convergence evidence is missing, the temptation is to write a log entry manually. This compounds the original skip with dishonesty. Run the actual process or use --no-verify with one of the four canonical exceptions stated to the user (PLA-942 incident).

@philsimon
Copy link
Copy Markdown

This list is very impressive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment