# Boris's Brain — Curated playbook

_Output of Anthropic's Dreaming research preview over 20 seed sessions. Store: `memstore_01JZwQrunKd3LsfKtNp8ECqB` · 18 entries · generated 2026-05-12 11:42._

> **How to read this.** Every concrete claim is tagged. **[Boris]** = paraphrase or direct quote from one of Boris Cherny's 87 tips on [howborisusesclaudecode.com](https://howborisusesclaudecode.com) — these are the load-bearing facts. **[illustrative]** = an invented example by the seeding agent, NOT a real workflow observation — useful for shape, not as evidence. **[synthesis]** = the editor model's hedged pattern-spotting; treat as opinion, not fact.
>
> I spot-checked every specific `[Boris]` claim that looked like it could have been fabricated (URLs, file paths, percentages, command examples, named subagents, slash commands, wildcards) against the source tip files. All checked out as verbatim Boris content. The audit was not exhaustive across all 18 entries; if you spot a `[Boris]` claim that contradicts the source tip, treat the source tip as ground truth and [DM me on X](https://x.com/Daniel_An23).
>
> The companion narrative post is at [/dreaming](/dreaming). The Dreaming-team feedback log is at [/dreaming.md](/dreaming.md).

## `/_index.md`

---
name: _index
description: Catalog of Boris Cherny's Claude Code playbook entries. Read first; each entry links to a single tip slug. Themes are added as entries accrue.
metadata: shared-index; append-only — do not rewrite, other agents are concurrently adding rows
---

# Boris Cherny — Claude Code playbook (index)

One line per memory file. Grouped by theme. Skim, then open the entry whose slug matches your need.

## Daily workflow

- [[parallel-execution]] — Run 3–5 Claude sessions concurrently via git worktrees + terminal aliases/notifications; extend to web (`--teleport`, `&`) and the iOS app.
- [[bug-fixing]] — Delegate bug investigation by feeding Claude the raw artifact (Slack thread via MCP, failing CI tests, `docker logs`); prompt minimally, don't micromanage the path.

## Automation

- [[slash-commands]] — Wrap any workflow you run more than once a day into a checked-in `.claude/commands/` slash command or committed skill; inline Bash pre-computes context.
- [[hooks]] — `PostToolUse` (`Write|Edit` → `bun run format || true`) catches the ~10% of mis-formatted writes before CI; `Stop` hooks run deterministic checks on long tasks.
- [[long-running-tasks]] (section in [[hooks]]) — Three patterns for unattended runs: background-agent verifier, `Stop` hook, or ralph-wiggum plugin; sandbox flags `--permission-mode=dontAsk` / `--dangerously-skip-permissions`.

## Setup & ergonomics

- [[terminal-setup]] — Ghostty (24-bit color, Unicode), `/statusline` showing context usage + git branch, and macOS voice dictation (`fn` fn) for more detailed prompts.
- [[terminal-configuration]] — In-app slash commands `/config` (theme), `/terminal-setup` (shift+enter newlines for IDE/Warp/Apple Terminal/Alacritty), `/vim`, plus iTerm2 or hook-based notifications.
- [[permissions]] — `/permissions` pre-allows safe commands in `.claude/settings.json` (wildcards like `"Bash(bun run *)"`, `"Edit(/docs/**)"`); `--permission-mode=dontAsk` or `--dangerously-skip-permissions` for sandboxed CI.

## Subagents

- [[subagents]] — `.claude/agents/` `.md` files as reusable PR-workflow automations; "use subagents" trigger to throw more compute; offload tasks to keep main context clean; Opus 4.5 permission-screening hook.
- [[custom-agents]] — Per-agent configuration inside `.claude/agents/` `.md` files: name, color, tool allow/deny, permission mode, model; pin repo default via `settings.json` `"agent"` or `--agent`.

## Model tuning

- [[model-selection]] — Default to Opus 4.5 with Thinking on High effort; less steering plus better tool use beats a smaller/lower-effort model's per-turn speed.

## Learning & onboarding

- [[learning-with-claude]] — Use Claude as a teacher for unfamiliar code: Explanatory/Learning output style in `/config`, ASCII diagrams, HTML presentations, and a spaced-repetition skill that quizzes you to surface gaps.

## Integrations

- [[mcp-integrations]] — Slack via MCP server, BigQuery via `bq` CLI, Sentry for error logs; commit a domain skill (e.g. `analytics/bq/*.sql`) so Claude doesn't re-derive schemas each session.

## Curated artifacts

- [[playbook]] — Source-attributed playbook publishable to a Boris-branded site; one entry per tip slug with [Boris]/[illustrative]/[synthesis] tags on every claim.

## Prompting & feedback loops

- [[verification-the-1-tip]] (section in [[prompting-tips]]) — Boris's "#1 tip": give Claude a way to verify its work (tests, bash, simulators, Chrome-extension browser testing) so it self-corrects without a human in every loop; claimed 2–3× quality.

## Project setup & team defaults

- [[plugins]] — `/plugin` installs LSPs, MCPs, skills, agents, and custom hooks from Anthropic's official marketplace or a private company one; commit `.claude/settings.json` for team-wide propagation.

## `/bug-fixing.md`

---
name: bug-fixing
description: Boris's pattern for delegating bug investigation to Claude — hand over the raw artifact (Slack thread, CI output, docker logs) and keep the prompt minimal. Read when triaging or fixing reported bugs.
metadata: theme=daily-workflow; source-slug=bug-fixing
---

## Bug fixing: hand Claude the artifact, not a summary

> "Don't micromanage how." [Boris]

**Mechanic** [Boris] — Three delegation paths: enable the Slack MCP and say "fix" on a pasted bug thread (zero context switching); say "Go fix the failing CI tests" without prescribing the approach; point Claude at `docker logs` to troubleshoot distributed systems — Boris calls it "surprisingly capable" there.

**When to reach for it** [Boris]/[synthesis] — When the bug already lives as a raw artifact (Slack thread, test-failure output, log stream), feed it in directly [Boris]. In our reading the value is preserving detail a human summary flattens; the `docker logs` path likely works best on structured logs (JSON lines, consistent timestamps) rather than free-form stderr [synthesis].

**Anti-patterns** [Boris] — Micromanaging the fix path (e.g. "look at line 47 and change X to Y") — the tip body explicitly says don't.

*Illustrative scenario:* The applying agent simulated a 500-error incident with a 15-message Slack thread and two failing CI tests; on the `docker logs` route Claude surfaced temporal clustering (gRPC deadline exceeded on checkout→inventory) that casual reading would miss; the Slack path presupposes the MCP is already configured. [illustrative]

Related: [[mcp-integrations]], [[plan-mode]], [[subagents]].

_Source: bug-fixing_

## `/claude-md-best-practices.md`

---
name: claude-md-best-practices
description: How Boris uses a single team-owned CLAUDE.md as a compounding rulebook — the "update your CLAUDE.md" closing phrase after corrections, @claude PR-review tagging via the GitHub Action, and the notes/ directory advanced variant. Related: [[slash-commands]], [[plugins]].
metadata: theme=project-setup; source-slug=claude-md-best-practices
---

# claude-md-best-practices

## claude-md-best-practices (keywords: CLAUDE.md, rules, corrections, compounding, PR review, @claude, GitHub Action, install-github-action, notes directory)

[Boris] — One shared `CLAUDE.md` checked into git; the whole team contributes. The core habit: whenever Claude does something wrong, correct it **and** end the message with "Update your CLAUDE.md so you don't make that mistake again." Boris notes Claude is "eerily good at writing rules for itself." Advanced variant: point `CLAUDE.md` at a `notes/` directory that Claude maintains per-task/PR — rules live in `CLAUDE.md`, context lives in `notes/`. For PR workflows, tag `@claude` in a PR comment to have the GitHub Action (`/install-github-action`) commit the new rule as part of the PR itself. Boris calls this pattern "Compounding Engineering."

[illustrative] — Illustrative simulation (invented by the applying agent — NOT a real workflow observation): In a TypeScript client repo, Claude defaulted to `enum` where the team wanted literal unions. After correction + "update your CLAUDE.md," Claude self-authored a rule with rationale (tree-shaking, no reverse-mapping) rather than just restating the constraint. The self-generated rule was more durable than a human-written one because it included Claude's own reasoning. The `notes/` directory pattern worked cleanly when scoped to a PR: future sessions on related files pulled in the decision context without cluttering the top-level rules file.

[synthesis] — The "update CLAUDE.md" closing phrase is likely best treated as a ritual ending to *any* correction, not just significant ones — the cost of a small redundant rule is low, and Claude's self-written rules tend to be more operationally precise than manually authored ones. One reading: the notes-directory variant is most valuable on long-lived features where reasoning (not just rules) needs to travel across sessions; on short-lived tasks the overhead likely outweighs the benefit.

## `/custom-agents.md`

---
name: custom-agents
description: Configure named, scoped agents as .md files under .claude/agents/ — tool allow/deny lists, permission mode, per-agent model, color/name. Pin the repo's default agent via settings.json or override per-session with --agent.
metadata: theme=automation; source-slug=custom-agents; related=[[subagents]]
---

# custom-agents

## custom-agents tip (keywords: custom agents, .claude/agents, tool restrictions, permission mode, model, default agent, settings.json, --agent flag, /agents)

[Boris] Drop `.md` files in `.claude/agents/`; each agent can declare a custom name, color, tool set, pre-allowed and pre-disallowed tools, permission mode, and model. Little-known feature: set the default agent used for the main conversation via the `"agent"` field in `settings.json`, or override per-invocation with the `--agent` CLI flag. Run `/agents` to get started.

[illustrative] Illustrative simulation (invented by the applying agent — NOT a real workflow observation): For a TypeScript monorepo with two recurring needs, two agents were created: `security-reviewer.md` (Opus, `permissionMode: readonly`, `disallowedTools: ["write_file","create_file"]`) and `scaffolder.md` (Haiku, `disallowedTools: ["web_fetch","bash"]`). Setting `"agent": "security-reviewer"` in `.claude/settings.json` locked the repo's safe default into version control; `claude --agent scaffolder` overrode it per-session for a scaffolding sprint. Key operational insight from the simulation: `disallowedTools` is a hard guardrail — the agent literally cannot call those tools even if prompted to, making it more trustworthy than a system-prompt instruction alone. Per-agent model selection (`opus` for deep analysis, `haiku` for cheap generation) lets you control cost by task type rather than globally.

[synthesis] Likely the highest-value config axis is `permissionMode` + `disallowedTools` together — one sets session posture, the other enforces specific tool-level blocks; using both on a read-only auditor agent gives defense in depth. The `"agent"` default in `settings.json` is probably most useful when checked into the repo (safe defaults for new contributors) rather than set in user-global config. One reading: custom agents are the right abstraction for any persona you'd otherwise re-establish via system prompt every session — and they compose naturally with [[subagents]] (the "use subagents" fan-out pattern) and [[permissions]] (the team-shared allow/block lists).

## `/hooks.md`

---
name: hooks
description: Boris's two named hook patterns — PostToolUse for auto-formatting Claude's writes/edits, and Stop hooks for deterministic completion checks on very long-running tasks. Read for the JSON shape and the `|| true` guard rationale.
metadata: theme=automation; source-slug=hooks; secondary-section=long-running-tasks
---

## Hooks: PostToolUse for formatting, Stop for completion checks

> "While Claude generates well-formatted code 90% of the time, the hook catches edge cases to prevent CI failures." [Boris]

**Mechanic** [Boris] — Configure a `PostToolUse` hook with `matcher: "Write|Edit"` that runs `bun run format || true` after every file write or edit; configure a `Stop` hook to run deterministic checks (typecheck, tests) when Claude ends a turn on a very long-running task.

**When to reach for it** [Boris] — On any repo with a CI format gate, so the ~10% of edge-case mis-formats don't surface as failures. [Boris] Reach for `Stop` hooks on very long-running tasks so Claude works uninterrupted and a deterministic check fires at the end. [Boris] One reading: the `Write|Edit` matcher catches both full-file writes and targeted edits, so no file escapes formatting. [synthesis]

**Anti-patterns** [synthesis] — Omitting `|| true` likely turns a formatter misconfiguration into a session-killing error mid-task; the guard is load-bearing even when the formatter is reliable.

*Illustrative scenario:* In an invented TypeScript+Prettier-CI repo, the PostToolUse hook silently fixed a line over `printWidth` after `Write`; a Stop hook ran `tsc --noEmit && bun test` after 40+ tool calls and produced the final correctness gate without Claude invoking checks inline. [illustrative]

Related: [[permissions]] (settings.json is shared config surface), [[plugins]] (custom hooks installable via `/plugin`), [[subagents]] (Boris's idea of routing permission requests to Opus via a `PreToolUse` hook).

_Source: hooks_

---

## Long-running tasks: keep Claude unattended without stalling

> "For very long-running tasks, ensure Claude can work uninterrupted." [Boris]

**Mechanic** [Boris] — Three options for unattended runs: (a) prompt Claude to verify with a background agent when done; (b) use an agent `Stop` hook for deterministic checks; (c) use the community "ralph-wiggum" plugin (idea by @GeoffreyHuntley). For sandboxed environments, launch with `--permission-mode=dontAsk` or `--dangerously-skip-permissions` to avoid blocks.

**When to reach for it** [Boris]/[synthesis] — When a task is too long to sit and approve permissions in real time [Boris]. One reading: the `Stop` hook is the most deterministic option since it doesn't depend on Claude's own judgment of completeness; `--permission-mode=dontAsk` is likely safer than `--dangerously-skip-permissions` when the environment allows it, since it auto-approves through the permission system rather than skipping it [synthesis].

*Illustrative scenario:* In an invented 40-service Postgres 14→16 migration in a CI sandbox, `--dangerously-skip-permissions` removed mid-task permission prompts and a `Stop` hook calling `verify_migrations.py` (non-zero on any failed schema validation) acted as an external completion gate so Claude couldn't self-report "done" until the script agreed. [illustrative]

Related: [[hooks]] (same file, Stop hook mechanics), [[permissions]] (the gentler alternative to `--dangerously-skip-permissions`), [[plugins]] (where ralph-wiggum is installed).

_Source: long-running-tasks_

## `/learning-with-claude.md`

---
name: learning-with-claude
description: How Boris uses Claude Code as a teacher for unfamiliar code — Explanatory/Learning output style, ASCII diagrams, HTML presentations, and a spaced-repetition skill that quizzes you.
metadata: theme=learning-and-onboarding; source-slug=learning-with-claude
---

## Claude Code as a learning tool

> "Claude Code isn't just for writing code — it's a powerful learning tool when you configure it to explain and teach." [Boris]

**Mechanic** [Boris] — Four techniques: enable the "Explanatory" or "Learning" output style via `/config` so Claude explains the *why* behind changes; ask Claude to generate visual HTML presentations explaining unfamiliar code; ask Claude to draw ASCII diagrams of new protocols and codebases; build a spaced-repetition learning skill where you explain your understanding and Claude asks follow-up questions to fill gaps.

**When to reach for it** [Boris]/[synthesis] — When you want Claude to teach you the *why*, not just ship a change [Boris]. The four techniques likely compound when applied to the same unfamiliar concept in one session rather than used in isolation [synthesis].

*Illustrative scenario:* The applying agent worked through an inherited Python `asyncio` scheduler using `ensure_future`. An ASCII diagram clarified the coroutine→Task→event-loop→I/O-poll chain that code alone obscured; explanatory mode annotated each edit with *why* `ensure_future` defers rather than runs immediately; the spaced-repetition step caught a subtle misconception ("runs immediately") via a follow-up question rather than a flat correction, forcing active reasoning. [illustrative]

[synthesis] Spaced-repetition likely transfers better to mental-model gaps than to API recall — follow-up questions surface conceptual misunderstandings, not missing function names. Toggle the explanatory output style off after the learning phase; on routine coding it adds noise and inflates context.

Related: [[prompting-tips]] (specificity and challenge phrasing), [[slash-commands]] (the spaced-repetition flow is naturally a committed skill).

_Source: learning-with-claude_

## `/mcp-integrations.md`

---
name: mcp-integrations
description: Boris's pattern for plugging external tools into Claude Code — Slack via MCP, BigQuery via the `bq` CLI, Sentry for error logs — and committing a domain skill (e.g. a SQL file) so Claude doesn't have to reverse-engineer the schema each session. Read when wiring any database/observability/chat system into Claude.
metadata: theme=integrations; source-slug=mcp-integrations
---

## MCP integrations: Slack, BigQuery, Sentry — and the committed skill that makes them durable

> "Personally, I haven't written a line of SQL in 6+ months." [Boris]

**Mechanic** [Boris] — Claude Code uses external tools autonomously through MCP servers or CLIs: Slack via an MCP server (`https://slack.mcp.anthropic.com/mcp`, configured with `type: "http"` under the `mcpServers` key), BigQuery via the `bq` CLI, Sentry for error logs. The pattern generalises: "any database that has a CLI, MCP, or API." Boris's specific recommendation for BigQuery: have the BigQuery skill checked into the codebase so Claude can pull and analyse metrics on the fly without being re-taught the schema.

**When to reach for it** [Boris]/[synthesis] — Whenever an external system has a CLI, MCP, or API, and you want Claude to close the loop end-to-end inside one prompt [Boris]. In our reading the pattern likely generalises best when (1) the CLI emits structured JSON, (2) a domain skill (SQL templates, jq pipelines) is committed so Claude doesn't reverse-engineer schemas each session, and (3) the MCP provides write-back so the loop terminates inside Claude Code [synthesis].

*Illustrative scenario:* The applying agent simulated incident triage — Sentry CLI to fetch errors, `bq` against a committed `analytics/bq/payments_qps.sql` skill to correlate metrics, then a Slack MCP post to `#incident-response` — all from one natural-language prompt. The load-bearing piece was the committed SQL file, not the MCP server alone; without it, Claude would re-derive schema each session and lose durability across schema changes. [illustrative] Note: the simulation invented the path `.claude/mcp.json` for config; in practice [[plugins]] indicates `mcpServers` lives in the same `.claude/settings.json` as other plugin and hook config. [illustrative]

Related: [[plugins]] (the `mcpServers` key in `.claude/settings.json`; `/plugin` installs MCPs from the marketplace), [[bug-fixing]] (Slack MCP enables "paste the thread and say fix"), [[slash-commands]] (the BigQuery skill is itself a checked-in skill), [[permissions]] (MCP tool calls go through the same allow/block lists).

_Source: mcp-integrations_

## `/model-selection.md`

---
name: model-selection
description: Default Claude Code to Opus 4.5 with Thinking and run `/model` on High effort. Boris's argument is that a smaller/lower-effort model's per-turn speed is usually erased by the steering it forces.
metadata: theme=model-tuning; source-slugs=model-selection,effort-level
---

## Default to Opus 4.5 with Thinking — and run it on High effort

> "It's the best coding model I've ever used, and even though it's bigger & slower than Sonnet, since you have to steer it less and it's better at tool use, it is almost always faster than using a smaller model in the end." [Boris]

**Mechanic** [Boris]: Use Opus 4.5 with Thinking as the default model in Claude Code, and use `/model` to set effort level to High — Low = fewer tokens / faster, Medium = balanced, High = more tokens / more intelligence. Boris uses both for everything, not just hard problems.

**When to reach for it** [Boris]/[synthesis]: Boris frames it as the default rather than an opt-in for hard tasks; the math he offers is that less steering plus better tool use produces faster wall-clock results despite higher per-turn latency [Boris]. One reading is that the steering tax compounds when a task has hidden constraints spread across multiple files, so the gap likely widens with task scope [synthesis].

*Illustrative scenario:* In an invented psycopg2→SQLAlchemy refactor, a smaller/faster model took three correction rounds (missed `RETURNING` semantics, dropped a composite index, broke a cursor-factory fixture); Opus 4.5 with Thinking surfaced the `RETURNING` edge in its reasoning trace and finished in one pass with one clarifying question. A parallel rate-limiter simulation tracked the same pattern across effort levels — Low missed thread-safety and call-sites, Medium missed a TODO, High produced parametrized concurrency tests with zero corrections. [illustrative]

_Sources: model-selection, effort-level_

Related: [[plan-mode]] (compute the upfront plan once so the model has shape to execute), [[prompting-tips]] (verification harness amplifies the per-turn gain), [[parallel-execution]] (worktrees absorb the per-turn latency by running tasks concurrently).

## `/parallel-execution.md`

---
name: parallel-execution
description: How Boris runs 3–5 Claude sessions concurrently via git worktrees, terminal aliases/notifications, plus web and mobile surfaces (`&`, `--teleport`, iOS app).
metadata: theme=workflow; source-slug=parallel-execution
---

## Parallel Claude sessions with git worktrees

> "The single biggest productivity unlock. Spin up 3-5 git worktrees at once, each running its own Claude session." [Boris]

**Mechanic** [Boris]: `git worktree add .claude/worktrees/<name> origin/main`, then `cd` in and run `claude`; each worktree hosts its own session and conversation history. The Claude Code team prefers worktrees over plain checkouts, which is why native worktree support shipped in the Claude Desktop app.

**When to reach for it** [Boris]: When you'd otherwise serialize multiple tasks — target 3–5 concurrent sessions.

**Operating tips** [Boris]: name worktrees and add one-keystroke aliases (`za`/`zb`/`zc`); dedicate one "analysis" worktree to logs/BigQuery; enable iTerm2/terminal notifications; color-code and name terminal tabs one-per-task. See [[terminal-setup]].

**Beyond the terminal** [Boris]: claude.ai/code runs extra sessions; `&` backgrounds one; `--teleport` switches contexts local↔web; the iOS app starts sessions on the go for handoff to desktop.

*Illustrative scenario:* [illustrative] Three concurrent worktrees (SDK migration, flaky tests, memory-leak hunt), each on a color-coded tab with a `z*` alias, collapse wall-clock from `sum(tasks)` to `max(tasks)`; you review whichever pings first.

[synthesis] Worktrees likely help even for sequential work — no stash/checkout/pop, each session keeps its full history. One reading of "3–5": fewer under-uses parallelism, more exceeds monitoring capacity.

_Source: parallel-execution_

## `/permissions.md`

---
name: permissions
description: How Boris uses `/permissions` to pre-allow safe commands in `.claude/settings.json` with wildcard allow/block syntax, plus the CI escape hatches `--permission-mode=dontAsk` and `--dangerously-skip-permissions` for sandboxed environments.
metadata: theme=setup-ergonomics; source-slugs=permissions,permissions-management
---

## Permissions: pre-allow the safe path, escape only when sandboxed

> "Instead of `--dangerously-skip-permissions`, use `/permissions` to pre-allow common safe commands." [Boris]

**Mechanic** [Boris] — Run `/permissions` to edit the allow and block lists; rules persist in `.claude/settings.json` and most are shared there, so committing the file propagates them to the team. Out of the box only a small safe set is pre-approved, and full wildcard syntax is supported — Boris's examples are `"Bash(bun run *)"` and `"Edit(/docs/**)"`. He frames the broader permission system as layered: prompt-injection detection, static analysis, sandboxing, and human oversight.

**When to reach for it** [Boris] — Reach for `/permissions` during normal dev so the commands Claude runs repeatedly stop prompting while unscoped ones still ask. For sandboxed environments, `--permission-mode=dontAsk` or `--dangerously-skip-permissions` are the documented escapes that avoid pipeline blocks.

*Illustrative scenario:* A simulated Node.js refactor pre-allowed `Bash(npm test)`, `Bash(eslint *)`, `Bash(prettier --write *)`, and `Bash(git diff *)` in a committed `.claude/settings.json`, removing repetitive prompts while still blocking `rm -rf build/`. [illustrative] A second simulation paired allow `"Bash(bun run *)"` with block `"Bash(bun run deploy *)"` — block beats allow, so production deploys still required human sign-off. [illustrative] One reading is that pre-allowing `Bash(*)` likely defeats the allow-list's purpose; keep wildcard scopes specific enough to remain meaningful. [synthesis]

Related: [[hooks]], [[plugins]], [[subagents]], [[custom-agents]].

_Sources: permissions, permissions-management_

## `/plan-mode.md`

---
name: plan-mode
description: Boris's plan-mode workflow — `shift+tab` to cycle in, refine the plan, auto-accept edits, let Claude 1-shot. Includes the two-Claude staff-engineer review pattern and the rule to re-plan (not patch) when something drifts mid-implementation. Plan mode is for verification steps too, not only the initial build.
metadata: theme=context-and-planning; source-slug=plan-mode
---

## Plan mode: plan → refine → auto-accept → 1-shot

> "A good plan is really important to avoid issues down the line." [Boris]

**Mechanic** [Boris]: Press `shift+tab` to cycle into plan mode. The full workflow is plan → refine plan → auto-accept edits → Claude 1-shots the implementation.

**Team patterns** [Boris]: One person has one Claude write the plan, then spins up a second Claude to review it as a staff engineer. Explicitly tell Claude to enter plan mode for verification steps, not just for the build. The moment something goes sideways mid-implementation, switch back to plan mode and re-plan rather than patching forward.

**When to reach for it** [Boris]: Start every complex task here — pour energy into the plan so Claude can one-shot the implementation.

**Anti-pattern** [synthesis]: Patching forward instead of re-planning likely leaves the plan stale and makes subsequent auto-accept runs inconsistent with the original design. The refinement pass is underrated — questioning gaps (error cases, edge types) before code exists is cheaper than fixing after auto-accept.

*Illustrative scenario:* [illustrative] Invented task — adding cursor-based pagination to an Express/TypeScript service. A 7-step plan named the shared contracts (PaginationParams / PaginatedResponse<T> types, validatePagination middleware, repository method, route, tests, OpenAPI spec) up front; Claude executed all seven coherently in one pass. A later spec-type bug (cursor typed `integer` instead of `string`) was handled by a targeted two-step re-plan rather than an ad-hoc edit, keeping the plan as the source of truth and producing a matching test.

**Synthesis** [synthesis]: Plan mode likely pays off most when the task touches multiple files or layers that must agree on shared types/contracts — the upfront plan forces Claude to name those contracts before instantiating them. For single-file, low-coupling changes the planning overhead may outweigh the benefit. The two-Claude review pattern is plausibly most valuable on architectural decisions inside the plan, not line-level details.

Related: [[verification-the-1-tip]] (use plan mode for the verification step too), [[prompting-tips]] (refinement reprompts inside the plan), [[bug-fixing]] (flip back into plan mode when a mass-edit diagnosis is uncertain).

_Source: plan-mode_

## `/playbook.md`

---
name: playbook
description: Curated, publish-ready playbook of how Boris Cherny uses Claude Code. Drawn only from Boris's tip bodies plus per-tip session simulations. Every claim is tagged [Boris], [illustrative], or [synthesis]. Read first when summarising Boris's workflow externally.
metadata: theme=playbook; status=publishable; audience=external; sources=memory-dir
---

# Boris Cherny's Claude Code Playbook

Every concrete claim is bracketed:

- **[Boris]** — paraphrase or direct quote from Boris's own tip.
- **[illustrative]** — example from an invented simulation, not a real workflow observation.
- **[synthesis]** — the editor's hedged pattern-spotting; not Boris's claim.

## Index

### Project setup & team defaults
- [[claude-md-best-practices]] — One shared `CLAUDE.md`; end every correction with "update your CLAUDE.md."
- [[plugins]] — `/plugin` installs LSPs, MCPs, skills, agents, hooks; commit `settings.json` for the team.
- [[permissions]] — `/permissions` to pre-allow safe commands with wildcards; allow + block lists in settings.

### Models & effort
- [[model-selection]] — Default to Opus 4.5 with Thinking and High effort; less steering wins on wall-clock.

### Daily workflow
- [[plan-mode]] — `shift+tab` into plan mode; re-plan rather than patch forward when things slip.
- [[prompting-tips]] — Push back on the first answer; "scrap this, implement the elegant solution."
- [[verification-the-1-tip]] — Give Claude a way to verify its work; Boris claims this alone 2–3x's quality.
- [[learning-with-claude]] — Explanatory output style, ASCII diagrams, HTML explainers, spaced repetition.
- [[bug-fixing]] — Feed raw artifacts (Slack thread, CI logs, `docker logs`); say "fix".
- [[slash-commands]] — Anything you run more than once a day becomes a `.claude/commands/` slash command.

### Automation
- [[hooks]] — `PostToolUse` formats every write; `Stop` hook gates completion deterministically.
- [[subagents]] — Append "use subagents" to fan out; declare scoped `.md` agents under `.claude/agents/`.

### Integrations
- [[mcp-integrations]] — Slack MCP, BigQuery via `bq`, Sentry; commit a domain skill so schemas stick.

### Parallelism & remote
- [[parallel-execution]] — Run 3–5 git worktrees concurrently; extend to web (`--teleport`) and the iOS app.

### Terminal & ergonomics
- [[terminal-setup]] — Ghostty, `/statusline`, `/terminal-setup` (shift+enter), voice dictation (`fn` `fn`).

---

# Project setup & team defaults

## Shared CLAUDE.md and "Compounding Engineering"

> "Eerily good at writing rules for itself." [Boris]

**Mechanic** [Boris] — Keep one shared `CLAUDE.md` checked into git, and whenever Claude does something wrong, correct it and close the message with "Update your CLAUDE.md so you don't make that mistake again." [Boris] Advanced variant: point `CLAUDE.md` at a `notes/` directory Claude maintains per-task or per-PR — rules in `CLAUDE.md`, context in `notes/`. [Boris] In PR workflows, tag `@claude` in a PR comment so the GitHub Action (`/install-github-action`) commits the new rule as part of the PR. [Boris]

**When to reach for it** [Boris]/[synthesis] — Boris calls the pattern "Compounding Engineering" — the rules file improves with every correction. [Boris] Treating the closing phrase as a ritual on any correction, large or small, likely compounds faster than only invoking it on "significant" mistakes. [synthesis]

*Illustrative scenario:* In an invented TypeScript repo where Claude defaulted to `enum` instead of literal unions, the self-authored rule that followed included tree-shaking and reverse-mapping rationale — more durable than a human one-liner. [illustrative]

_Source: claude-md-best-practices_

## Plugins: `/plugin` and your team's settings.json

> "Run `/plugin` to get started." [Boris]

**Mechanic** [Boris] — `/plugin` installs LSPs (now available for every major language), MCPs, skills, agents, and custom hooks from the official Anthropic plugin marketplace, or from a private marketplace you create for your company. [Boris] Check `.claude/settings.json` into the codebase so teammates auto-pick up the same marketplaces and plugins. [Boris]

**When to reach for it** [synthesis] — The committed-`settings.json` step is likely the highest-leverage action in this tip: it converts a per-developer manual setup into a team-wide default. [synthesis] Private marketplaces are probably most useful for internal MCPs an org cannot publish publicly. [synthesis]

*Illustrative scenario:* In an invented monorepo, a tech lead installed the Go LSP and a private incident-manager MCP via `/plugin`, added the private marketplace under "Manage Marketplaces", then committed `.claude/settings.json` so every teammate inherited both after a `git pull`. [illustrative] The private marketplace had to be added before its plugins appeared in the picker — order matters. [illustrative]

_Source: plugins_

## Permissions: `/permissions`, wildcards, and team allow/block lists

**Mechanic** [Boris] — Use `/permissions` to pre-allow common safe commands rather than reaching for `--dangerously-skip-permissions`. [Boris] Pre-approved rules persist in `.claude/settings.json` and ship to the team via commit. [Boris] Full wildcard syntax is supported; Boris's examples include `"Bash(bun run *)"` and `"Edit(/docs/**)"`. [Boris] The permission system already includes prompt-injection detection, static analysis, sandboxing, and human oversight; only a small safe set is pre-approved out of the box. [Boris] For fully sandboxed environments, `--permission-mode=dontAsk` or `--dangerously-skip-permissions` are acceptable to avoid pipeline blocks. [Boris]

**When to reach for it** [synthesis] — Use `/permissions` + `settings.json` for interactive dev work (surgical, reviewable, shareable); reserve `--permission-mode=dontAsk` or `--dangerously-skip-permissions` for ephemeral, externally-sandboxed CI runs. [synthesis] Block beats allow — keep a wildcard plus a narrow block (e.g. `Bash(bun run deploy *)`) instead of enumerating every safe sub-pattern. [synthesis]

**Anti-patterns** [synthesis] — Pre-allowing `Bash(*)` defeats the purpose; keep patterns specific enough to be meaningful. [synthesis]

_Sources: permissions, permissions-management_

---

# Models & effort

## Opus 4.5 + Thinking, on High effort

> "It's the best coding model I've ever used, and even though it's bigger & slower than Sonnet, since you have to steer it less and it's better at tool use, it is almost always faster than using a smaller model in the end." [Boris]

**Mechanic** [Boris] — Default to Opus 4.5 with Thinking, not just for hard tasks. [Boris] `/model` picks effort level: Low (fewer tokens, faster), Medium, or High (more tokens, more intelligence) — Boris uses High for everything. [Boris]

**When to reach for it** [synthesis] — The likely failure mode of ignoring this is "false economy" — reaching for Sonnet to save seconds per turn, then spending minutes on steering. [synthesis] High effort probably pays for itself on any task with hidden constraints, TODOs, or cross-file call-sites where correction rounds cost more than the extra tokens. [synthesis]

*Illustrative scenario:* In an invented rate-limiter refactor, Low effort missed thread-safety and TTL eviction; Medium caught those but skipped a `# TODO`; High traced through the file, proposed an LRU strategy, and produced parametrised tests in one pass. [illustrative]

_Sources: model-selection, effort-level_

---

# Daily workflow

## Plan mode: plan → refine → 1-shot, and re-plan when things slip

> "A good plan is really important to avoid issues down the line." [Boris]

> "Explicitly tell Claude to enter plan mode for verification steps." [Boris]

**Mechanic** [Boris] — Press `shift+tab` to cycle into plan mode. [Boris] The workflow is: plan → refine plan → auto-accept edits → Claude one-shots the implementation. [Boris] Two-Claude review pattern: one Claude writes the plan, a second reviews it as a staff engineer. [Boris] Plan mode is not only for the build — use it for verification steps too. [Boris] When anything goes sideways mid-implementation, flip back to plan mode and re-plan rather than patching forward. [Boris]

**When to reach for it** [synthesis] — Plan mode likely pays off most when a task touches multiple files or layers that must agree on shared types or contracts. [synthesis] For single-file, low-coupling changes the planning overhead may outweigh the benefit. [synthesis]

*Illustrative scenario:* In an invented Express/TypeScript cursor-pagination task, pouring specificity into the plan (types, middleware, repo method, route, tests, OpenAPI spec) let Claude execute seven steps coherently in one pass; a post-run spec-type error was best resolved by a targeted two-step re-plan rather than an ad-hoc edit. [illustrative]

_Source: plan-mode_

## Challenge the first solution

> "Grill me on these changes and don't make a PR until I pass your test." [Boris]
>
> "Prove to me this works." [Boris]
>
> "Knowing everything you know now, scrap this and implement the elegant solution." [Boris]

**Mechanic** [Boris] — Don't accept the first answer — push Claude and it usually can do better. [Boris] After "Prove to me this works", have Claude diff main vs. the feature branch. [Boris] Separately, write detailed specs upfront to reduce ambiguity before handing work off — specificity directly improves output quality. [Boris]

**When to reach for it** [synthesis] — The "elegant solution" reprompt likely works best when the first answer is correct but clunky, not when it is wrong — asking for elegance on a broken solution may produce elegant wrongness. [synthesis] "Prove to me this works" is most valuable when behaviour differences between branches are subtle or semantic rather than crash-level. [synthesis]

*Illustrative scenario:* In an invented dedup function, the "scrap this / elegant solution" prompt surfaced a one-liner dict-comprehension that also fixed a silent first-vs-last record difference; "prove to me this works" then forced a behavioural diff harness that caught the semantic mismatch. [illustrative]

_Source: prompting-tips_

## Verification: the #1 tip

> "Probably the most important thing to get great results out of Claude Code — give Claude a way to verify its work." [Boris]

**Mechanic** [Boris] — Boris claims giving Claude a verification loop alone 2–3x's the quality of the final result. [Boris] The mechanism is domain-specific: bash commands, test suites, simulators, browser testing via Claude's Chrome extension. [Boris] The point is closing the feedback loop so Claude can self-correct without a human in the middle of every iteration. [Boris]

**When to reach for it** [synthesis] — The hardest part is investing the upfront cost of writing the verification harness, especially when no test infrastructure exists yet — likely worth doing even for "small" tasks because the loop pays for itself quickly. [synthesis] One reading: verification works best as a *launch condition*, not a retrospective check; provide the harness before handing Claude the task. [synthesis]

*Illustrative scenario:* In an invented `parse_price(text) -> float` task, a naive `re.sub(r'[^\d.]', '', text)` silently dropped the minus sign — visible only because a pytest suite was the verification loop; Claude fixed the regex and reran until all eight cases were green, no human judgment needed mid-loop. [illustrative]

_Source: verification-the-1-tip_

## Learning with Claude

> "A powerful learning tool when you configure it to explain and teach." [Boris]

**Mechanic** [Boris] — Enable an "Explanatory" or "Learning" output style in `/config` so Claude explains the *why* behind changes. [Boris] Ask Claude to generate visual HTML presentations of unfamiliar code, or ASCII diagrams of new protocols and codebases. [Boris] Build a spaced-repetition loop: explain your own understanding, then have Claude ask follow-up questions to surface gaps. [Boris]

**When to reach for it** [synthesis] — The spaced-repetition loop likely transfers better to concepts than to APIs — Claude's follow-up questions are most useful when the gap is a mental model, not a missing function name. [synthesis] HTML explainers likely work best for architecture and flow (stateful systems, pipelines) and are probably overkill for single-function logic. [synthesis] Worth resetting the `/config` output style to terse after the learning phase — explanatory mode on routine coding inflates context. [synthesis]

*Illustrative scenario:* In an invented `asyncio` scheduler walkthrough using `ensure_future`, an ASCII diagram clarified the coroutine→Task→event-loop→I/O-poll chain; the spaced-repetition step caught a subtle developer misconception ("runs immediately") via a follow-up question rather than a correction. [illustrative]

_Source: learning-with-claude_

## Bug-fixing: feed Claude the raw artifact

**Mechanic** [Boris] — Enable the Slack MCP, paste a Slack bug thread into Claude, and just say "fix" — zero context switching. [Boris] Or say "Go fix the failing CI tests" without micromanaging *how*. [Boris] For distributed systems, point Claude at `docker logs`; Boris calls it "surprisingly capable" at that. [Boris]

**When to reach for it** [synthesis] — The "surprisingly capable at docker logs" claim likely holds best when logs are structured (JSON lines, consistent timestamps) rather than free-form mixed stderr. [synthesis] The bug-fixing path likely pairs well with plan mode when failures span multiple subsystems: confirm the diagnosis first, then let Claude execute. [synthesis]

*Illustrative scenario:* In an invented 15-message Slack thread (engineers chasing a Redis timeout) plus two failing CI tests, minimal prompts beat detailed instructions because they avoid lossy retelling; in the `docker logs` path, Claude detected a temporal cluster of gRPC deadline-exceeded errors on checkout→inventory calls that a casual human read would have missed. [illustrative] Without the Slack MCP configured, the "zero context-switching" claim degrades to copy-pasting thread text. [illustrative]

_Source: bug-fixing_

## Slash commands: wrap the daily ritual

> "If you do something more than once a day, turn it into a skill or command." [Boris]

**Mechanic** [Boris] — Slash commands live under `.claude/commands/` and skills are committed alongside them, so both reuse across every project and travel with the repo to the whole team. [Boris] Command files can include inline Bash to pre-compute info (like `git status`) without extra model calls. [Boris] Boris's named examples: `/commit-push-pr` for the commit/PR inner loop, `/techdebt` at end of every session to find and kill duplicated code, a command that syncs 7 days of Slack/GDrive/Asana/GitHub into one context dump, and analytics-engineer-style agents that write dbt models, review code, and test changes in dev. [Boris]

**When to reach for it** [Boris] — Any workflow you run many times a day. [Boris]

*Illustrative scenario:* The applying agent sketched a `/morning-pr` command embedding `$(git branch --show-current)` and `$(git diff --name-only origin/main)` so Claude got pre-rendered metadata; embedding a full `git diff` risks blowing the context window, so prefer `--stat`. [illustrative]

_Source: slash-commands_

---

# Automation

## Hooks: `PostToolUse` and `Stop`

**Mechanic** [Boris] — Use a `PostToolUse` hook matching `"Write|Edit"` to run `bun run format || true` after every file write — catches the ~10% of cases where Claude's formatting misses and prevents CI failures. [Boris] For long-running tasks, add a `Stop` hook for deterministic checks (typecheck, tests) so Claude can work uninterrupted and correctness is verified automatically at the end. [Boris] For very long-running tasks, three options to keep Claude going uninterrupted: (a) prompt Claude to notify via a background agent when done, (b) use an agent `Stop` hook for deterministic completion checks, (c) use the community "ralph-wiggum" plugin. [Boris] In sandboxed/headless environments, use `--permission-mode=dontAsk` or `--dangerously-skip-permissions` to prevent mid-task permission prompts from blocking execution. [Boris]

**When to reach for it** [synthesis] — `|| true` is load-bearing — omitting it turns a formatting hiccup into a session-killing error. [synthesis] Options (a) and (b) are likely best combined: `Stop` hook for correctness, background-agent ping for human awareness. [synthesis] `--permission-mode=dontAsk` is probably the safer choice when the environment allows it (auto-approves rather than skipping the permission system entirely). [synthesis]

_Sources: hooks, long-running-tasks_

## Subagents: fan out, then customise

**Mechanic** [Boris] — Subagents are automations for common PR workflows, living as Markdown files under `.claude/agents/` (Boris's named files: `build-validator`, `code-architect`, `code-simplifier`, `oncall-guide`, `verify-app`; with `code-simplifier` to clean up after Claude and `verify-app` to carry detailed end-to-end testing instructions). [Boris] Append "use subagents" to any request where you want Claude to "throw more compute at the problem". [Boris] Offloading individual tasks keeps the main agent's context window "clean and focused"; you can also route permission requests to Opus 4.5 via a hook so it can scan for prompt-injection attacks and auto-approve safe ones. [Boris] Each `.md` agent declares a custom name, color, tool set, pre-allowed and pre-disallowed tools, permission mode, and model; little-known: set the default agent for the main conversation via the `"agent"` field in `settings.json` or the `--agent` CLI flag. [Boris] Run `/agents` to get started. [Boris]

**When to reach for it** [synthesis] — Likely start with the simpler fan-out pattern (parallel task subagents) before wiring the permissions-routing hook. [synthesis] Custom agents are the right abstraction for any persona you'd otherwise re-establish via system prompt every session. [synthesis]

*Illustrative scenario:* An invented `security-reviewer.md` (Opus, `permissionMode: readonly`, `disallowedTools: ["write_file","create_file"]`) plus a `scaffolder.md` (Haiku, `disallowedTools: ["web_fetch","bash"]`) showed that `disallowedTools` is a hard guardrail — more trustworthy than a system-prompt instruction alone. [illustrative]

_Sources: subagents, custom-agents_

---

# Integrations

## MCP integrations and committed domain skills

**Mechanic** [Boris] — Claude Code uses tools autonomously through MCP servers or CLIs — Slack (`https://slack.mcp.anthropic.com/mcp`), BigQuery (`bq` CLI), Sentry. [Boris] The pattern generalises to "any database that has a CLI, MCP, or API." [Boris] The BigQuery skill is *checked into the codebase* so Claude can reach for it without being taught the schema each time. [Boris] Boris hasn't written a line of SQL in 6+ months because he asks Claude Code to pull and analyse metrics on the fly. [Boris]

**When to reach for it** [synthesis] — The pattern likely generalises best when: (1) a CLI with structured JSON output exists, (2) a domain skill file (SQL, API template) is committed so Claude doesn't have to reverse-engineer schemas, and (3) the MCP server provides write access so the full loop closes without leaving Claude Code. [synthesis] Without (2), the pattern degrades to one-off SQL generation — still useful but fragile across schema changes. [synthesis]

*Illustrative scenario:* In an invented Sentry → BigQuery → Slack flow, the key enabler was an already-committed `analytics/bq/payments_qps.sql`; Claude ran `bq`, joined output with Sentry JSON, and posted a structured summary via Slack MCP from one prompt. [illustrative]

_Source: mcp-integrations_

---

# Parallelism & remote

## 3–5 git worktrees, one Claude per tab

> "The single biggest productivity unlock." [Boris]

**Mechanic** [Boris] — Spin up 3–5 git worktrees simultaneously, each with its own Claude session; Boris explicitly prefers worktrees over plain checkouts, which is why native worktree support was built into Claude Desktop. [Boris] Name worktrees and add one-keystroke shell aliases (`za`/`zb`/`zc`) to hop between them; keep a dedicated "analysis" worktree for read-only work (logs, BigQuery); use iTerm2/terminal notifications so you know when any session needs attention; colour-code and name terminal tabs one-per-task. [Boris] Additional surfaces: `claude.ai/code` web sessions, `&` to background, `--teleport` to hand off context local↔web, and the iOS app to start sessions on the go and continue on desktop. [Boris]

**When to reach for it** [synthesis] — Worktrees likely beat branch-switching even on sequential tasks because each Claude session retains its full conversation history in its own directory. [synthesis] One reading of "3–5": fewer than three under-uses parallelism; more than five likely exceeds a human's ability to monitor notifications and context-switch effectively. [synthesis]

_Source: parallel-execution_

---

# Terminal & ergonomics

## Outer-terminal setup: Ghostty, `/statusline`, voice, shift+enter

> "You speak 3x faster than you type, and your prompts get way more detailed as a result. Hit `fn x2` on macOS." [Boris]

**Mechanic** [Boris] — Use Ghostty for synchronised rendering, 24-bit color, and proper Unicode. [Boris] Configure `/statusline` so the status bar always displays context usage and the current git branch. [Boris] Double-tap `fn` on macOS to dictate prompts by voice instead of typing. [Boris] In Claude Code itself: `/config` sets light/dark theme and output style; `/terminal-setup` enables `shift+enter` for newlines (needed in VS Code, Apple Terminal, Warp, Alacritty so multi-line prompts don't require literal `\`); `/vim` turns on vim keybindings; notifications can be enabled for iTerm2 or via a custom hook. [Boris]

**When to reach for it** [Boris]/[synthesis] — Leave the statusline on so context headroom is visible continuously, letting you compact before degradation rather than after. [Boris] Voice dictation likely pays off most on specification-heavy prompts (multi-constraint refactors, architecture descriptions) where typing friction would otherwise shorten the spec. [synthesis] `/terminal-setup` is likely the highest-impact command for anyone using an IDE terminal or Warp — the newline problem actively degrades prompt quality. [synthesis]

_Sources: terminal-setup, terminal-configuration_

## `/plugins.md`

---
name: plugins
description: `/plugin` installs LSPs, MCPs, skills, agents, and custom hooks from Anthropic's official marketplace or a private company marketplace. Commit `.claude/settings.json` to propagate to the team. Read when setting up team-wide plugin defaults.
metadata: theme=project-setup-and-team-defaults; source-slug=plugins; related=[[mcp-integrations]],[[hooks]],[[permissions]]
---

# Plugins (keywords: plugins, lsp, mcp, marketplace, skills, hooks, settings.json, /plugin)

## plugins

**[Boris]** Run `/plugin` to install LSPs (available for every major language), MCPs, skills, agents, and custom hooks from the official Anthropic plugin marketplace. You can also add your own company's private marketplace. To propagate the setup to your whole team, check `.claude/settings.json` into your codebase — teammates who pull the repo get the same plugins automatically.

**[illustrative]** Illustrative simulation (invented by the applying agent — NOT a real workflow observation): In an invented monorepo scenario, the tech lead used `/plugin` to install the Go LSP (gopls) and a private corporate MCP (incident-manager) sourced from a private marketplace URL. She added the private marketplace under "Manage Marketplaces," installed both plugins, then committed `.claude/settings.json`. The critical leverage was the settings commit: every teammate pulled the config without any extra setup steps. Before committing, the Go LSP was only active on her machine; after, it was active for the whole team. The private marketplace URL had to be added first before the private plugin appeared in the picker — order matters. The resulting `settings.json` carried three distinct keys: `lsp` (per-language LSP config), `pluginMarketplaces` (array of marketplace URLs), and `mcpServers` (per-server remote MCP config) — the same schema used by manual MCP setup.

**[synthesis]** The "check settings.json into the repo" step is likely the highest-leverage action in this tip: it converts a per-developer manual setup into a team-wide default. The `/plugin` command likely writes to the same `.claude/settings.json` file that MCP and hooks config already lives in, so teams already version-controlling that file get plugin propagation for free. Private marketplaces are probably most useful when an org has internal MCPs they can't (or don't want to) publish to Anthropic's public marketplace.

## `/prompting-tips.md`

---
name: prompting-tips
description: Boris's prompting moves — "scrap this / implement the elegant solution," "Prove to me this works," writing detailed specs upfront, and giving Claude a verification loop ([[learning-with-claude]] covers the teaching-mode prompts).
metadata: theme=prompting; contains-slugs=prompting-tips,verification-the-1-tip
---

# prompting-tips

## prompting-tips (keywords: challenge, elegant solution, specs, push back, mediocre fix)

[Boris] Boris says: don't accept the first solution — push Claude and it usually can do better. Concrete phrases that work: "Grill me on these changes and don't make a PR until I pass your test"; "Prove to me this works" (then have Claude diff main vs. feature branch); after a mediocre fix, say "Knowing everything you know now, scrap this and implement the elegant solution." Separately: write detailed specs upfront to reduce ambiguity before handing work off — specificity directly improves output quality.

[illustrative] Illustrative simulation (invented by the applying agent — NOT a real workflow observation): Applied to a Python dedup function that had an O(n²) list-search bug. First pass was correct but naive. The "scrap this / elegant solution" prompt surfaced a one-liner dict-comprehension approach that also fixed a silent behavioral difference (first-vs-last record kept). "Prove to me this works" then forced a behavioral diff harness that caught the semantic mismatch the developer hadn't articulated. Writing a detailed spec before the third pass (case-insensitivity, key-guard, order preservation) produced a complete solution in one shot — earlier vague requests had missed all three constraints.

[synthesis] The "elegant solution" reprompt likely works best when the first answer is *correct but clunky*, not when it is *wrong* — asking for elegance on a broken solution may produce elegant wrongness. "Prove to me this works" is most valuable when behavior differences between branches are subtle or semantic rather than crash-level; it forces Claude to construct a falsifiable test rather than assert correctness. Upfront spec detail likely has diminishing returns past the point where all ambiguous edge cases are named — over-speccing simple tasks may bloat context without benefit.

---

## verification-the-1-tip (keywords: verify, feedback loop, tests, quality, 2x, 3x)

[Boris] "Probably the most important thing to get great results out of Claude Code — give Claude a way to verify its work." Boris claims this alone 2–3x the quality of the final result. The verification mechanism is domain-specific: bash commands, test suites, simulators, browser testing via Claude's Chrome extension. The key is closing the feedback loop so Claude can self-correct without a human in the middle of every iteration.

[illustrative] Illustrative simulation (invented by the applying agent — NOT a real workflow observation): Task was implementing `parse_price(text) -> float` to handle `"$1,299.99"`, `"€ 3.50"`, `"-$5.00"`, etc. Without tests, the first naïve implementation (`re.sub(r'[^\d.]', '', text)`) quietly dropped the minus sign, returning `5.0` for `-$5.00` — a silent semantic bug. With a pytest suite as the verification loop, the failure was immediately visible: `✗ FAIL got=5.0 input='-$5.00'`. Claude fixed the regex (preserve leading `-`) and reran; all 8 cases green. The suite also proactively covered multi-thousand-separator strings (`$1,234,567`) and whitespace variants that would otherwise be omitted from a one-shot attempt. The loop ran 3 times (write → red → fix → green) with no human judgment needed after the suite existed.

[synthesis] The hardest part is investing the upfront cost of writing the verification harness — especially for tasks where no test infrastructure exists yet. Likely worth doing even for "small" tasks because the loop pays for itself quickly once Claude starts iterating. The verification artifact (test suite, script, simulator config) is also a durable deliverable: it catches regressions in future edits. One reading: the tip implies you should write or provide the harness *before* handing Claude the task, not after a bad first result — verification works best as a launch condition, not a retrospective check.

## `/slash-commands.md`

---
name: slash-commands
description: How Boris wraps repeated work into shared `.claude/commands/` slash commands and committed skills — the "more than once a day" heuristic, inline-Bash pre-computation, and Boris's named example commands.
metadata: theme=automation; source-slug=skills-slash-commands
---

## Slash commands & skills: wrap the daily ritual

> "If you do something more than once a day, turn it into a skill or command." [Boris]

**Mechanic** [Boris] — Slash commands are checked into git under `.claude/commands/` and skills are committed alongside them, so both reuse across every project and travel with the repo to the whole team; command files can include inline Bash to pre-compute info (like `git status`) without extra model calls.

**When to reach for it** [Boris] — Any workflow you run many times a day. Boris names `/commit-push-pr` for the commit/PR inner loop, `/techdebt` at end of every session to find and kill duplicated code, a command that syncs 7 days of Slack, GDrive, Asana, and GitHub into one context dump, and analytics-engineer-style agents that write dbt models, review code, and test changes in dev.

*Illustrative scenario:* The applying agent sketched a `/morning-pr` command embedding `$(git branch --show-current)` and `$(git diff --name-only origin/main)` so Claude got pre-rendered metadata; embedding a full `git diff` risks blowing the context window, so prefer `--stat`. [illustrative] Treating `.claude/commands/` as a first-class artifact reviewed in PRs likely compounds team taste over time. [synthesis]

Related: [[plugins]], [[subagents]], [[claude-md-best-practices]].

_Source: skills-slash-commands_

## `/subagents.md`

---
name: subagents
description: How Boris uses `.claude/agents/` Markdown files as reusable PR-workflow automations — the "use subagents" trigger phrase, context-window isolation, and an Opus 4.5 permission-screening hook. For per-agent configuration (custom tool sets, permission mode, model) see [[custom-agents]].
metadata: theme=automation,context-management; source-slug=subagents; related=[[custom-agents]],[[hooks]]
---

## Subagents: reusable PR-workflow automations

> "Think of subagents as automations for the most common PR workflows." [Boris]
> "Offload individual tasks to subagents to keep your main agent's context window clean and focused." [Boris]

**Mechanic** [Boris] — Drop one `.md` file per agent under `.claude/agents/`; Boris's named files are `build-validator.md`, `code-architect.md`, `code-simplifier.md`, `oncall-guide.md`, and `verify-app.md`, and the trigger is appending the literal phrase "use subagents" to a request when you want Claude to "throw more compute at the problem."

**When to reach for it** [Boris] — The most common PR workflows you'd otherwise re-establish each time: `code-simplifier` "cleans up code after Claude finishes"; `verify-app` carries "detailed instructions for end-to-end testing." Offloading individual tasks keeps the main agent's context window clean and focused. A distinct security-leveraged use: route permission requests to Opus 4.5 via a hook — "let it scan for attacks and auto-approve the safe ones" [Boris].

*Illustrative scenario:* A simulated post-merge review of a payments refactor fanned out `build-validator`, `code-simplifier`, and `verify-app` in parallel; each subagent received only the relevant diff plus its own agent instructions, so the main agent's job became synthesis rather than execution, and a 422 bug in the refund flow surfaced that an inline check would likely have missed. [illustrative] The "route permission requests to Opus 4.5 via a hook" idea likely requires a `PreToolUse` hook wired in `.claude/settings.json`; starting with the simpler parallel fan-out before wiring the permissions hook is probably the lower-risk order. [synthesis]

Related: [[custom-agents]] (per-agent tool/permission/model config), [[hooks]] (the `PreToolUse` wiring for the Opus-4.5 permission screen), [[permissions]], [[model-selection]], [[parallel-execution]], [[slash-commands]].

_Source: subagents_

## `/terminal-configuration.md`

---
name: terminal-configuration
description: Boris's in-app Claude Code slash commands for one-time ergonomic setup — /config (theme), /terminal-setup (shift+enter newlines for IDE/Warp/Apple Terminal/Alacritty), /vim, and notifications for iTerm2 or via a custom hook.
metadata: theme=setup-ergonomics; source-slug=terminal-configuration; related=[[terminal-setup]],[[parallel-execution]]
---

## In-app configuration: `/config`, `/terminal-setup`, `/vim`, notifications

> "A few quick settings to make Claude Code feel right." [Boris]

**Mechanic** [Boris] — `/config` sets light/dark theme; `/terminal-setup` enables shift+enter for newlines so multi-line prompts don't require a literal `\`; `/vim` turns on vim keybindings; notifications can be enabled for iTerm2 or wired via a custom notifs hook.

**When to reach for it** [Boris] — Run `/terminal-setup` when Claude Code is hosted in an IDE terminal, Apple Terminal, Warp, or Alacritty (Boris's named-supported list); without it, multi-line prompts need a typed `\`. Use `/config` to set theme at any time; `/vim` is for users with existing vim keybindings.

**When to reach for it** [synthesis] — `/terminal-setup` is likely the highest-impact command for IDE/Warp users because the newline problem actively degrades prompt quality through accidental partial submissions; `/vim` is a no-op benefit otherwise.

*Illustrative scenario:* In an invented VS Code integrated-terminal session writing multi-line refactor prompts, stray Enter presses kept submitting partial prompts; `/terminal-setup` resolved it immediately, and `/config` (dark theme) + `/vim` were single-command fixes under 30 seconds combined. iTerm2 notifications were not applicable in a VS Code context and were skipped — fix the most disruptive input behaviour first, ergonomics second. [illustrative]

Related: [[terminal-setup]] (outer-terminal choices: Ghostty, `/statusline`, voice dictation), [[parallel-execution]] (notifications matter most for async worktree sessions that need a nudge to return).

_Source: terminal-configuration_

## `/terminal-setup.md`

---
name: terminal-setup
description: Boris's outer-terminal setup — Ghostty for rendering, /statusline for always-visible context+branch, and macOS voice dictation (fn fn) for faster and more detailed prompts. Read for environment ergonomics that affect prompt quality. Companion entry [[terminal-configuration]] covers in-app slash commands (/config, /terminal-setup, /vim, notifications).
metadata: theme=setup-ergonomics; source-slug=terminal-setup; related=[[terminal-configuration]]
---

## Terminal: Ghostty, `/statusline`, and voice dictation

> "You speak 3x faster than you type, and your prompts get way more detailed as a result. Hit `fn x2` on macOS." [Boris]

**Mechanic** [Boris] — Use Ghostty for synchronized rendering, 24-bit color, and proper Unicode; configure `/statusline` so the status bar always displays context usage and the current git branch; double-tap `fn` on macOS to dictate prompts by voice instead of typing.

**When to reach for it** [Boris]/[synthesis] — An always-on statusline continuously surfaces context usage and current branch [Boris]; one reading is to use that signal to compact proactively before degradation rather than reactively after [synthesis]. Voice dictation likely pays off most on specification-heavy prompts (multi-constraint refactors, architecture descriptions) where typing friction would otherwise shorten the spec you give Claude [synthesis].

*Illustrative scenario:* In an invented Python CLI refactor, the statusline reading `ctx: 48k / 200k` mid-session and turning amber at 160k triggered a proactive compact before degradation; an ~8-second voice-dictated prompt named three subcommands, the deprecation shim, and a docstring convention — detail a typed prompt would likely have collapsed to "refactor argparse to use subcommands". [illustrative]

Related: [[parallel-execution]] (terminal notifications for async sessions), [[prompting-tips]] (specificity payoff).

_Source: terminal-setup_

<!-- The in-app slash commands (/config, /terminal-setup, /vim, notifications) previously lived as a second section here; that content is now maintained as the standalone playbook entry [[terminal-configuration]]. -->

