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.
- Core Philosophy
- Directory Structure
- Session State Architecture
- Master Workflow
- Review Triage and Agents
- Workflow Profiles
- Rules System
- On-Demand Reference Docs
- Hooks System
- Model Strategy
- Skills Inventory
- Plugin Ecosystem
- Commands Inventory
- MCP Server Integration
- Repository Registry
- CompanyOS: Multi-Repo Architecture
- CEOS: EOS Framework
- Automated Jobs
- Multi-Instance Safety (Worktrees)
- Backup and Version Control
- Blog and Learning Capture
- Cursor Integration
- Git Workflow Rules
- Coding Standards
- Pre-commit Pipeline
- Quality Automation
- Database Migration Discipline
- Secrets Management
- Testing Patterns
- Critical Gotchas
- Quick Start for New Setup
- Key Insights
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-verifywith stated justification
~/.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.
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 checkoutwould delete config files (PLA-609, PLA-762)- APFS hardlink destruction when
rm -rfran on directory hardlinks (PLA-448) - Worktree symlink ELOOPs
- Project-level
settings.jsonbreaking 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 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.
All tickets follow an identical loop:
/start TICKET-XXX— Fetch ticket from Linear, analyze, create branch, post plan- Implement locally with manual testing
/commit— Quality gates →/simplify(Step 3.5) → auto-triage review → run agents → push → update Linear/staging(magic-platform) — Batch merge to preview, deploy, reset worktrees/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.
| 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.
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 withprompt-reviewer(no compiler for prompts)- Infrastructure config (
vercel.json,next.config.ts,turbo.json,.github/workflows/*.yml) → at least LIGHT
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.
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.
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
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.
20 hook scripts in ~/.claude/hooks/ plus external integrations (ccnotify, iTerm), responding to 12 lifecycle events.
| 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 | 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.
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 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_tokensand compaction triggers - Sampling params removed —
temperature,top_p,top_k400-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
~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 |
| 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.
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.
See CompanyOS and CEOS sections.
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 |
| 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.
72 user-level commands in ~/.claude/commands/. Organized by tier.
/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).
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.
Architecture prefers PAT/API key auth over OAuth because API keys survive Claude Code updates, while OAuth tokens in Keychain become orphaned.
| 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.
/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 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.
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.
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.
- 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.mdcalibrates writing style - Protected email workflow:
co-commsskill enforces draft-review-approve. Never callsend_gmail_messagedirectly.
/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.
~/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.
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 |
| 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.
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.
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).
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.
~/.claude/ contains irreplaceable content (commands, rules, hooks, skills, agents, blog notes, email drafts, memory) not stored in any project git repo. Two protection layers:
~/.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.
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).
Learning capture uses a batch-at-pause-points model — capture happens at natural workflow breakpoints, not per-insight-block.
| 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.
/blog draft aic— aggregates daily notes into Adventures in Claude drafts/blog draft feld— brad feld blog posts/learn review— graduates repeated patterns to permanent rules/skills- Simmer is mandatory — every
/blog draftauto-runs the simmer plugin (3 iterations)
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.
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 updatecursorcommit thorough— includes optional test runcursorcommit 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.
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.
- Never commit directly to
mainorpreview(pre-commit hooks block). Exception:direct_to_main: truerepos. - Branch naming:
feature/TICKET-XXX-description,fix/,refactor/ - Never bypass pre-commit with
--no-verifyexcept four documented exceptions:- Merge commits during
/stagingor/production - Pre-existing type errors in unrelated packages (document in commit message)
- Evidence gate: all convergence models unavailable
- Subagent-driven-development per-task commits blocked by convergence hook
- Merge commits during
- Force push: Always
--force-with-lease, never--force git add -Ais mandatory before every commit — subagents that stage scoped files miss plan files and post-review fixes (MYH-180 incident)- Attribution: Automatic via
settings.jsonattributionsetting - CI monitoring: Self-contained polling, never
gh run watch(13K+ line output) - Production release: Sync preview with main using
git merge -s ours
AI agents reliably emit certain patterns from stale training data. Three enforcement layers catch these before they land:
-
Custom ESLint plugin —
no-bare-logger-context(packages/config/plugins/no-bare-logger-context.mjs, PLA-1278) rejects logger context strings that don't match the canonicalModule:Functionformat. 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). -
no-restricted-syntaxbans inpackages/config/eslint.config.mjs— blocks the patterns Claude reliably produces from training data:error as Errorcasts → usetoError(error)from@platform/typesprocess.env.FOO!non-null assertions → useenv()/envOptional()from@platform/configPromise.all→ usePromise.allSettledwithsettledVal/settledQuery/logSettledRejections- Raw
<input type="date">,<input type="email">, etc. → use specialized@platform/uicomponents
-
.deprecated-termsgrep 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.
- Explicit types for function signatures, type guards for
unknown ?.trim() || "fallback"for database text (empty strings pass through??)prop?: T | undefinedforexactOptionalPropertyTypes- 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 rawprocess.env.X!. Exception: client components usingNEXT_PUBLIC_*vars must useprocess.env.NEXT_PUBLIC_X ?? ""(Next.js inlines at build time) - Export surface: only export the public API. Internal helpers = plain
function
Promise.allis banned via ESLint — usePromise.allSettledwithsettledVal(),settledQuery(),logSettledRejections()from@platform/infra/settled. Decision matrix and full pattern:docs/standards/ERROR_HANDLING.md § "Partial failures".
- Parameterized queries only
- Input validation with Zod at boundaries
- Always
.trim()env vars used in equality comparisons
- 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" />}, noticon={Users}— component refs aren't serializable at the Server→Client boundary and Next.js throws a hidden production crash - Dialog footers always use
DialogFooterActionsfrom@platform/ui(PLA-1432) — never hand-compose<DialogFooter>with raw<Button>children - Tailwind v4
@sourcedirective required when consuming shared package components
startTransitionbreaks native picker inputs — platformInputcomponent skips it for picker types- Check existing abstractions before building new ones
- Context strings use
'Module:Function'format (e.g.,'Auth:Callback') - For Supabase errors, use
logSupabaseError()from@platform/logger— preserves.code/.details/.hint
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.
| 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) |
Beyond per-commit enforcement, ~60 scheduled and on-demand scripts plus 20 GitHub Actions workflows keep the platform healthy.
| 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 everycreate*()reference indocs/ops/ADDING_NEW_APP.mdstill resolves to an exported symbol inpackages/. Catches stale onboarding docs before a new app is added.drift-detection.yml— detects when preview and production have diverged beyond the expected merge laghealth-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
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 |
| 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.
| 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.
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.
- Tables/indexes:
IF NOT EXISTS - RLS policies:
DROP + CREATE(no nativeIF NOT EXISTS) - Every
CREATE POLICYmust include explicitTOclause (defaults to PUBLIC otherwise) - Every migration modifying existing tables:
SET LOCAL statement_timeout = '30s'
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;- RLS without policies = silent deny-all — always create policies in the same migration that enables RLS
USING(true)withoutTOclause grants access to ALL roles- Table GRANT checked BEFORE RLS — missing
GRANT SELECTcauses "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 CONCURRENTLYin migrations — pipeline failure
See the database-migrations skill for the full 7-layer column-drop verification checklist.
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'notechofor env values. Code must also.trim()env vars defensively.
Options come BEFORE the test function:
it("slow test", { timeout: 15000 }, () => { ... });7 rules, 4 incidents — leakage between parallel vitest workers is the #1 source of flake.
- Every
setup.tscallsresetTestState()from@platform/test/resetinafterEach - Use
vi.stubGlobal()notglobal.X = …(direct writes leak across parallel workers; PLA-1249) - Module-scope
vi.stubGlobal/vi.spyOn/vi.stubEnvcalls in test files must be re-registered inbeforeEachbecauseresetTestState()restores them between tests setup.tsfiles setting env defaults across an entire file must use directprocess.env.X = "…"assignments, notvi.stubEnv—vi.unstubAllEnvs()only undoesvi.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 anafterAllsnapshot restore, preventing leakage into the next file in the same vitest worker (PLA-1593) - Exception —
vi.hoisted()callbacks:setTestEnvcan't be called inside a hoisted body because the helper's import is in TDZ at hoist-time. Writeprocess.env.X = "…"directly insidevi.hoistedand pair with a top-levelafterAll(() => { 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".
- 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 exactlyvi.clearAllMocks()doesn't drain once-value queues — usemockReset()- Class constructor mocks need actual classes, not arrow functions
- jsdom v27: class-based
ResizeObservermock required - Recharts v3.6: formatter params now
undefined-able
Tactical "what breaks, why, and how to avoid" — for strategic insights see Key Insights.
-
Stale .next cache (Next.js monorepos): Type-check fails on unmodified apps. Fix:
find apps -name "validator.ts" -path "*/.next/*" -delete -
APFS directory hardlinks: Never use
rm -rfon hardlinked directories — destroys data at both paths (PLA-448) -
Vercel CLI overwrites .env.local: Both
vercel linkandvercel env pullcompletely overwrite. Store local-only vars in.env.development.local -
cn() silent failures: Tailwind's
cn()silently drops invalid class names (hex codes, rgb values). DB color config must store Tailwind class names. -
Nested Supabase joins with RLS: Fail silently. Use step-by-step queries instead of nested
.select()with!inner -
ALTER ROLE SETreplaces, doesn't append: Caused a production outage whenpgrst.db_schemaswas overwritten. Always read current value viapg_options_to_table(), append, then write. -
Reserved Bash variables: Avoid
status,pipestatus,path -
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.
-
Linear MCP unified tools:
save_issuereplaces oldcreate_issue/update_issue.save_commentreplacescreate_comment. Parameterstatenotstatus. Labels replace, not append. Always use project IDs, not names (ambiguous across teams). -
Next.js 16 + Turbopack: Apps with
outputFileTracingIncludes,outputFileTracingRoot, orserverExternalPackagesmust build with--webpack. All apps must setNODE_ENV=productionin build scripts. -
SSE error invisibility:
onRequestErrordoes NOT fire for errors inside SSE async pipeline closures. Add explicitSentry.captureExceptionalongsidelogger.error. -
Auth metadata source mismatch:
user_metadata.full_namepopulated only by Google OAuth. Email/password uses camelCase. Always read fromshared.usersviagetUserIdentity(). -
.schema()chain may silently route to wrong schema:supabase.schema('appname')returns aPostgrestClient, not a fullSupabaseClient. UseadminForSchema(). -
pnpm override gotchas: Use
first_patched_versionfrom Dependabot, not the vulnerable range boundary. Can't fix bundled deps (e.g., Next.js pins webpack). -
git checkout --theirsdrops new files: After conflict resolution, verify new files exist. -
Never bypass
pnpm runscripts with raw CLI tools:pnpm run formathasNODE_OPTIONS=--max-old-space-size=8192; rawnpx prettierOOMs. -
Subagents don't inherit current branch (recurring): Always prefix dispatch prompts with
git checkout <branch>. Verify withgit log --oneline <branch>after. Subagent "DONE" reports aren't trustworthy for git state. -
Subagents invoke slash commands unless forbidden: Paste the
HARD CONSTRAINTSblock (insubagent-stalls.md) verbatim into every dispatch that modifies code. Forbid/commit,--no-verify, pushing, and Linear posts. -
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.
-
Opus 4.7 sampling param rejection:
temperature,top_p,top_k400-error. Platform AI client auto-strips, but direct API callers must update. Thinking budgets also removed — usethinking: {type: "adaptive"}.
-
Create structure —
mkdir -p ~/.claude/{rules,skills,commands,docs,hooks,agents,blog/notes,voice,plans,comms/drafts}, thengit init+ push to private GitHub repo for backup. -
Configure
settings.json— permissions,ENABLE_TOOL_SEARCH=true,effortLevel: xhigh,alwaysThinkingEnabled: true, attribution, hooks. -
Install core plugins — superpowers (dev methodology), episodic-memory (cross-session recall), simmer, documentation-audit, vercel-plugin, LSPs. See Plugin Ecosystem.
-
Add MCP servers to
~/.claude/.claude.json— prefer PAT/API key auth. See MCP Server Integration. -
Write core rules and docs — see Rules System and On-Demand Reference Docs for what belongs in each layer.
-
Add review agents and a global CLAUDE.md with developer context and repository registry. See Review Triage and Agents and Workflow Profiles.
-
Set up daily backup — launchd job running
tar+git pushon~/.claude/. -
Verify —
claude mcp list, inspect rules/skills/hooks/agents, run/global-status.
Strategic observations — "what would someone get wrong without knowing this?" For tactical gotchas see Critical Gotchas.
-
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-linearandmcp-supabasenow activate only when those MCP tools are called. -
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. -
/simplifyruns 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. -
Workflow Profiles are what make
/commitproject-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. -
co-*andceos-*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. -
The 2026-04-15 consolidation eliminated an entire bug class. The old model (project-level
.claude/with worktree symlinks) produced recurring incidents fromgit checkout, APFS hardlinks, and permission inheritance. Moving everything to~/.claude/with daily backup removed the root cause instead of patching symptoms.
-
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. -
.claude/commands/*.mdand.claude/rules/*.mdare NOT exempt from review. They get at least LIGHT withprompt-reviewer. Non-obvious because they look like documentation. Prompt instruction files have no compiler — ordering bugs and dead references are only caught by review. -
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.
-
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.
-
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.
-
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 testcommand 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). -
Anti-slop enforcement is its own category. AI agents reliably emit certain patterns from stale training data:
error as Errorcasts,process.env.X!non-null assertions,@clerk/*imports after migration, generic logger contexts. Three enforcement layers catch these: custom ESLint plugins (whenno-restricted-syntaxcan't regex-match),no-restricted-syntaxbans (for structural patterns), and.deprecated-termsgrep (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.
-
Project-level
settings.jsonbreaks 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. -
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.
-
CompanyOS's GitHub Actions
propose-skills.ymlcreates 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. -
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.
-
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?" -
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.
-
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-verifywith one of the four canonical exceptions stated to the user (PLA-942 incident).
This list is very impressive.