Qroda app icon
flagship · iphone app for riders

Record your rides, share them beautifully.

GPS track, speed, lean angle and weather, captured on the road and turned into a map poster. No accounts, no servers: everything stays on your iPhone.

Get Qrodamade for riders

There's a file at ~/.claude.json that I had never opened on purpose. Among a lot of telemetry, it keeps a counter for every plugin and skill Claude Code has ever loaded on my machine: how many times each one fired, and when. I opened it while writing this post, to check a number I was about to quote from memory.

It showed a setup with a clear core. The five skills I use every day all come from one plugin, with counts in the dozens. The Swift language server has fired over a thousand times, the browser plugin a few hundred. Around that core is a long tail I'd stopped noticing: a bundle of plugins installed for the day I might need them, most still at zero, and a pack of 84 Apple framework skills of which eight have ever fired. None of it is broken or expensive on its own, but every entry costs a line in every prompt, and the file made that visible in a way my memory didn't.

So this post is about the core: what I'd set up first on a new machine, why each part is there, and how you can build the same in an afternoon. My latest side project is an iPhone app, so many examples are Swift, simulators and Xcode. Most of my working life is Go, Terraform, Kubernetes config and other kinds of YAML, and nothing here depends on the stack; where it helps, I say what that version looks like. A whole session, start to finish, is at the top of the skills section. If you only read one section, read the last one.

The model I use for thinking about this

What I want from Claude Code isn't code. It's code I'd merge, into a codebase I have to live with, without reading every line twice. Getting an LLM to write code has been easy for a couple of years. Getting the second thing is a systems problem, and I treat it like one: constrain the inputs, automate the checks, and make the feedback loop fast enough that mistakes are cheap.

I split the setup into prose and machinery because Anthropic's own docs are blunt about what prose can do. CLAUDE.md files are "context, not enforced configuration", with "no guarantee of strict compliance". To block an action no matter what the model decides, you use a hook or a permission rule. Every "never" in your instructions file is a request the model honors most of the time, and most of the time is not all of the time.

So prose shapes judgment: what the project is, what's out of scope, which pattern to copy, what has bitten you before. Machinery guarantees outcomes: warnings as errors, the linter in strict mode, the test suite on a clean checkout, a script that fails the build when a layer imports something it shouldn't. When the model keeps ignoring a rule, don't shout louder in the markdown. If a check can express the rule, put it there. If it can't, and plenty can't, the answer is better tooling around the model, not a longer instructions file.

The loop decides how much you can hand over. On a web project the model finds out it was wrong in seconds, from a lint and a unit run. On an iOS project it's xcodebuild ... build test on a pinned simulator, and it's minutes. A slow loop means you plan more before you build, batch pushes because each costs a CI runner, and only let the model run unattended when the checks are good enough that you don't have to watch.

My Claude Code setup, and what each piece is for

Here's what's on my machine and why, so you can pick what applies to you.

Plan and model. I want long, unattended sessions without thinking about quota, so I'm on the Max 20x plan while I'm building in my free time; I'll drop to 5x or Pro when I'm not. The model is the 1M-context variant of the current top model, and the long context is the feature I'd miss most. On 20x I've never hit a limit. On 5x I hit one once, mid parallel-subagent run, and stopped it with "That's too expensive in parallel. Do the tasks one by one." Pro would be a limit problem every day. For scale, Claude Code's own estimate for a two-hour session on an iOS app is about $54 in API-equivalent cost, a quarter-hour of bug fixing about $6; the subscription covers it. On a smaller tier, plan more in one context, dispatch fewer subagents, and babysit the long runs.

Permissions. I want to approve almost nothing by hand and still have a short list of things that are never touched, so permissions run in auto mode. A classifier decides, based on a description of my environment in settings: which repository is trusted, that there's no cloud provider to protect, that anything with prod in its name is sensitive, and which build and lint commands are routine. Projects add small allowlists and the odd deny rule; one utility repo has exactly two, both protecting a data file from ever being written by the model. Write your environment description once, honestly, and put the genuinely dangerous paths in deny rules, where no prompt can reach them.

Global instructions. There's no ~/.claude/CLAUDE.md, because every rule should live next to the code it governs. The one user-level rule tells the model to look up library docs through Context7 before answering from memory, even for frameworks it thinks it knows. That applies everywhere; nothing else does.

Skills and plugins. The ones that matter: one process plugin (superpowers), a language server for the stack I'm in most right now (Swift, because of the iOS project; the Go one is installed too), browser automation (Playwright), documentation lookup (Context7), symbol-aware code search (Serena), a reviewer agent (feature-dev), a security check on every edit, and humanizer for anything a person will read. On the MCP side, two global servers, Kubernetes in read-only mode and XcodeBuildMCP, two more scoped to one project, and the rest come with the plugins. Output style is Concise, because I read the result, not the narration. Everything else is the long tail; the pruning section deals with it.

Memory and notifications. Auto memory is on, so corrections stick. The Warp terminal plugin sends a native notification when a session stops or needs input, mobile push is on too, and so I can walk away from a running session. ~/.claude lives in my dotfiles repo, so I can see what I changed.

CLAUDE.md is a contract, not documentation

The per-project file is the thing I'd rescue from a fire, because it's where the model learns what the project is and what it must never do to it. My two most developed files come from one template, which I had Claude design. The brief asked for a definitive CLAUDE.md: research what Anthropic recommends, mine my existing project file for what was universal, and sort every requirement into prose, hook, CI check, skill, or dropped. It had one constraint I'd tell you to steal:

markdown
Budget the rule surface, not the line count: context lines (commands,
vocabulary, maps, budgets) are cheap and prevent mistakes; rule lines
(prohibitions, rituals) are expensive and dilute each other.

Anthropic's docs say to aim for under 200 lines per file. I think that counts the wrong thing. A repository map, the exact test command with the simulator UDID, a table of domain terms: those lines prevent a wrong change. "Keep the code clean" costs the same tokens, changes no diffs, and dilutes the rules next to it. My template budgets the always-on rules at forty to sixty lines and lets the facts run. Both of my iOS apps land around 520 lines, most of it facts.

The section that earns its keep is "Things that will bite you", because it stops the model from walking into a trap I've already paid for. From Qroda, the iPhone app I'm building (more on the projects page), a few toolchain entries:

markdown
- **Two simulators named "iPhone 17"** (iOS 26.4 + 26.5) — always pin
  `-destination` by UDID; a name-based erase+test pair can hit different devices.
- **Swift Testing prints a fake XCTest summary** ("Executed 0 tests") — grep
  `Test run with N tests`, never the XCTest line.
- When grepping xcodebuild output, match `": error:"` — a bare `error` matches
  unrelated tool paths in the environment dump.
- **Every plain push to `main` runs macOS CI** unless it only touches
  `docs/**`, `site/**`, or `**.md`. Batch accordingly.

This website's file has the same section: Prettier's Tailwind plugin eats the leading space in a conditional class-name fragment, so write complete per-branch strings; deleting .next while the dev server runs corrupts it; a 404 in dev poisons the session until restart. Each entry cost me an afternoon and saves a session regularly. Start this section on day one and add to it in the same commit as the fix. It never survives a "keep it under 200 lines" pass, and it's the part you'd miss most.

The other thing to decide once is the architecture, because a model trained on a decade of blog posts defaults to whatever the average blog post did. For iOS that's a ViewModel per screen and a manual refetch after every write. Qroda's stack block says the view is the view-model layer, the persistence framework is the single source of truth and is never manually refetched, and views never import a system framework directly. Without those rules I get MVVM. With them I get the architecture I chose. Write yours down before the first feature, not after the third rewrite.

The template has sixteen sections, summarized near the end of this post: project facts at the top, universal rules in the middle, maintenance at the end. To start you need the facts block, a workflow, and a maintenance rule. Three sections are worth looking at now.

The workflow section makes the ceremony match the size of the change:

markdown
- **Direct:** the diff can be described in one sentence and has no behavioural
  effect a user or caller would notice (a typo, a rename, a comment, a config
  value). Do it.
- **Plan only:** a behavioural change whose approach is obvious and whose blast
  radius is one module — a well-understood bug fix, a small addition matching
  an existing pattern. Skip Phase 1; write the Phase 2 plan, get approval,
  implement.
- **Full:** anything multi-file, unfamiliar, ambiguous, architectural, or
  touching a §1 security-critical path. All three phases.

The phases are brainstorm, plan, implement, each naming the skill that runs it. "Done" is defined once: check command and tests green with results in the report, tests at every layer that applies, docs in the same diff, and, above the direct tier, a fresh-context review and a stated rollback path. Once on purpose: repeating "always run the tests" makes the model over-verify.

The plan is a document under docs/superpowers/plans/, so I can approve it and subagents can execute it without me. It reads like a work order. A recent one opens with a "Global Constraints" list along these lines:

markdown
- Approachable Concurrency is on: blocking leaves need `@concurrent`;
  clustering is microsecond arithmetic and deliberately stays on the caller's
  actor — do NOT mark it `@concurrent`.
- No `try!`, no force unwraps outside tests, no `fatalError`; warnings are
  errors; strings `String(localized:)`.
- If a launch test stops passing because the first tab changed, changing
  that test is a DELIBERATE test change: its own commit, message explaining
  the launch surface.

and closes with "Done-bar verification": build and tests on every destination, an honest report per destination, the fallbacks used, what wasn't done, and the rollback ("revert the PR"). The subagents tick the checkboxes as they go.

My favorite rule makes the model tell me when a hook or a rule file would have saved us time, instead of me noticing three corrections later:

markdown
- **Propose the harness feature, not just the code.** When a request, a
  repeated correction, or a mistake you just made would have been prevented or
  made cheaper by a Claude Code capability this repo does not use yet — a hook
  for "every time X", a `.claude/rules/` file for a path-scoped constraint, an
  isolated worktree or subagent for parallel or risky work, a scheduled or
  looped run for a recurring check — say so in one line with the concrete
  config, and let the user decide.

The model suggests where its own leash should go, and I get to say no. Add this to your file. It's one paragraph, and it's how the kill switch in the session below got into mine.

The maintenance section keeps the file shrinking as well as growing:

markdown
This file is code. When Claude misbehaves, find the rule that allowed it and
patch that rule — or, if the rule is one it keeps ignoring, move it into CI,
pre-commit, or a hook where it cannot be ignored. When Claude already does
something correctly without a rule, delete the rule.

That last sentence is the one people forget. A rule the model follows anyway is pure cost.

Tests, lint and CI: the gates Claude Code runs into

Instructions get the model to write the right kind of code. Gates stop the wrong kind from being merged, and I set them up so the model, not me, finds out something is wrong.

On Qroda the model runs into three checks on every push: a formatter in lint mode and a linter with --strict, so a formatting diff or a warning fails the build before I see the PR; the test suite on a simulator pinned by UDID; and a dead-code scan, so the leftovers of a refactor fail instead of landing in my review. On my newer app the gates are stricter on purpose, so the "no" comes from the compiler: warnings are errors on every platform, strict concurrency is on, and a shell script in CI and pre-commit enforces the layer rules from CLAUDE.md (the domain layer imports only Foundation, each layer has a framework allowlist, nothing imports a networking framework), failing with a path:line: rule per violation. That script exists because "views never import a system framework" is exactly the kind of rule the model honors most of the time.

None of this is iOS-specific. On a Go service it's go vet, golangci-lint at its strictest, and go test -race on a clean checkout, plus an import-boundary check if the repo has layers worth protecting. On Terraform it's terraform validate, a linter, and a plan on every pull request that a human reads before anything applies. On Kubernetes config it's a schema check and a server-side dry run. Same point: the model finds out it was wrong from a tool, before I find out from a review.

On this site the gates are what the model passes before it can call a UI change done: unit tests, ESLint with Prettier inside it, a production build, and a Playwright suite with an accessibility pass that fails on serious violations. After any UI change the model runs all four, then drives the running app in the Playwright browser at 390 pixels wide, because the suite runs at 1280 and won't catch mobile overflow. The banner at the top of this post shows why that last step matters. Brief, design canvas, pick a direction, implement with the site's own tokens, screenshot at 1280 and 390. The first screenshot showed the article's prose styles adding heading margins inside the card. No test would have caught that; a screenshot did. If you do UI work with Claude Code, give it a browser and make it look.

A gate failure should have a particular shape, and the best recent example is a CI crash the model fixed. The sync framework my newer app uses traps, uncatchably, when the process has no iCloud entitlement, and a CI build with code signing off has none. So the unsigned builds on the GitHub runner crashed before any test ran, on a background queue where no catch could see it. The fix is worth describing for what it didn't do: it didn't delete the test and it didn't skip the macOS leg. The simulator legs now sign ad hoc so the entitlement is embedded, and the macOS leg checks for it up front and degrades to a designed "unavailable" state, with the UI tests that need a healthy state moved to the legs that can have one. The commit also added the trap to "Things that will bite you". Fix the cause, keep the gate, write down the surprise.

The gates also protect me from the model's worst instinct, turning a red check green by any means available. The template's hard rules, which override everything including an approved plan, include this one:

markdown
5. Never disable, weaken, or skip a test, type check, or lint rule to make a
   check pass (§7).

Of all the gates, the test suite is the one that changes what the model can do, because it's how the model checks its own work. Without tests, "done" means "it compiled and I read it back". With tests, every task a subagent picks up has a check attached, and the model runs it before it reports. That's why the template says every behavioural change ships with tests, every bug fix with a regression test that fails before the fix, and implementation goes through the test-driven-development skill: failing test, minimal code, refactor. The rules that matter most should be tests too, because a test is a rule the model can't argue with. In Qroda, the sync backend requires every new model property to be optional or defaulted; a migration test pins that, so a non-optional field fails the test before the backend fails on someone's phone. Where you can turn a rule into a test, do, and the prose version becomes a comment on why the test exists. The better your tests, the more you can hand over.

To be honest about the gaps: the template lists mutation testing "where the stack supports it" and a commit-message lint under what CI must back, and neither exists in either repo. The brief asked for a hook that makes test files read-only to the agent, which the research I'd read called the single most effective way to stop a model from gaming its tests. I haven't built it, and I have no hooks of my own at all. The test rule holds because CI runs the suite on a clean checkout and a human reviews test-file diffs, which is weaker than a hook, and I know it. If you build that hook before I do, tell me.

Claude Code skills, subagents and commands, and which ones I actually use

Here is one session, start to finish. On Qroda I wanted a feature that reads from Apple Health, and I opened with a question rather than an order: could the app get heart rate from the watch, or from Health in general, and could it record the activity under a different type? The brainstorming skill came back with the problem restated, what Health allows, two ways to get the data, and the trade-offs. I picked one. The planning skill wrote a plan into the repo: files to touch, tests to add, what a device without a watch should do, the rollback. I asked for two amendments and approved it. The model asked how to execute, I answered "subagent", and it worked through the plan one task at a time, each in a fresh context, with the tests and the linter as referee. CI was green. The feature landed in one commit, the plan in another. And because of the harness rule, it ended with a suggestion: put the feature behind a local kill switch, since the app has no backend to flip a remote flag. I said yes, and that pattern is now a line in the project file. The only prompts I wrote were the question, two amendments, and one word.

I want every session to follow that procedure without me typing it, and that's what the skills I lean on hardest do. They all come from one plugin, superpowers, and they're process skills rather than knowledge: brainstorming, writing plans, subagent-driven development, systematic debugging, and finishing a development branch, in that order of use. Each phase of the session above was one of them doing its job. The prompts that start a session are short, because the skills carry the procedure:

text
Find every TODO in the codebase. Brainstorm how to resolve each one, write a
plan, and implement it once I've approved the plan.
 
Do all of the remaining roadmap items. Use worktrees and subagents where the
work is independent. When you're done, remove the completed items from the
README.

"Subagent" is in my history more times than any other prompt. I don't use the built-in plan mode; the skill does the same job and leaves a document behind. If you install one plugin, install this one, and name its skills in your project file's tool map, because the model doesn't reliably reach for them on its own.

Knowledge skills only fire when something points at them. I have a pack of 84 Apple framework skills installed, one per framework. Eight have ever fired, and the eight are exactly the ones Qroda's tool map names:

markdown
| Any Apple framework API, availability, behaviour | Context7 MCP, then the matching repository skill (`swiftui-*`, `swiftdata`, `cloudkit`, `storekit`, `mapkit`, ...) |
| Prose the user will post (PRs, commits, ADRs, team messages) | `humanizer` skill |

The language-server plugins make the same point from the other direction: the Swift one has fired over a thousand times, while the TypeScript, Go, Rust and C ones, installed with the same click, sit at zero. Nobody curates skills by hand, and I don't. A pack for a stack you touch now and then can sit there; an unused skill costs a line of context and an idle language server costs nothing. What matters is that the stack you actually work in has its pack installed and its skills named in the project file, because a skill nobody points at never fires.

Humanizer is there because I don't want anything that leaves my machine to read like a model wrote it. It strips the tells of machine-written prose, and I call it by name for a marketing site, App Store descriptions, work summaries, this post.

The review has to catch what the implementation missed, so it can't share the implementation's context. I have no custom agent definitions; I use the subagent pattern from superpowers and the reviewer agent from feature-dev, which the tool map names for the fresh-context review. After implementing, the diff gets reviewed once in a fresh context, scoped to correctness and the stated requirements: "report gaps, do not report style preferences". A reviewer that shares the implementer's context shares its blind spots, and a reviewer with a broad audit checklist finds things to say about everything, so the checklist lives in a skill called at that moment and nowhere else.

I've written no slash commands. The plugin that provides /commit and /commit-push-pr has fired once, ever, and asking a model to commit and push is overkill anyway; that's muscle memory. Where the model earns its keep in git is the part I used to dread: rebasing a long-lived branch, untangling a merge conflict across a dozen files, splitting a messy working tree into commits that each make sense. It reads both sides of a conflict faster than I can and explains what it resolved. Slash commands are for things you do the same way every time and can't describe in a sentence, and most people don't have many of those.

MCP, and the context budget

I want the model to have hands on the things it touches all the time, and nothing else, so the MCP list is short: Kubernetes in read-only mode and XcodeBuildMCP globally; Playwright, Context7, GitHub, Serena and Vercel through plugins; Apple's own xcrun mcpbridge and an Apple documentation server scoped to Qroda.

Each has a job the model does every session. XcodeBuildMCP is named in both iOS projects' Commands section as the way to build, run and test on a simulator. Context7 carries the global rule to look up library docs before answering, because the Apple frameworks I use "have changed materially across recent releases". Playwright is how the model checks a web page it changed instead of telling me it's fine. GitHub's plugin is for PR work. Kubernetes is what I reach for from ~/.kube to ask a cluster a question in plain English, and read-only is the whole point: it can't be talked into a delete. Serena works when a project file tells the model to use it for declarations and call sites instead of grep; otherwise it sits idle.

Keep the list short for the same reason you keep the instructions file short on rules: every tool an MCP server exposes is a schema the model carries on every turn. Tool search, which loads schemas only when needed, helps; it doesn't make a dead server free. Install a server when a project file needs it, and prefer read-only mode when there is one.

Pruning: asking Claude to audit its own setup

I want the setup to stay the size of what I use, and the cheapest way I've found is to have Claude audit itself. I open a session in my home directory and ask, in three steps:

text
Which skills, MCP servers and plugins has Claude Code actually used on this
machine? Show me the usage counts and last-used dates.
 
Which of the MCP servers do something the built-in tools don't?
 
Are any plugins and MCP servers duplicates of each other? Where they are,
keep the plugin and uninstall the server.

Claude knows where its own counters are (skillUsage and pluginUsage in ~/.claude.json, a count and a last-used date per entry) and reads them. Then I delete things. The two global MCP servers are what's left after that audit. This post prompted the latest pass, which found a 57-plugin bundle at zero, 76 idle Apple skills, a plugin for a backend one of my apps no longer has, two teaching-style plugins injecting instructions into every session (gone now), and a hooks plugin that had run 64,000 times with no hooks to run.

"Unused" means what the counter says: zero uses across every session. I've stopped guessing whether I might want a thing later; the bundle was that guess, and the counter is its scorecard. If a project needs a capability, its CLAUDE.md names it and I install it then. Installing is one command; carrying the thing around is a tax on every turn. So far I've run the audit when the setup felt slow, twice; monthly is the cadence I'm switching to, not one I can vouch for yet. It takes ten minutes, and the model is good at it, because for once the question has a numeric answer.

Not only code

The same setup carries the sessions that aren't in a code repository, about one in ten of mine. Two recent ones show what that buys.

I wanted my Unsplash photos on Pexels too. Pexels has no upload API, which meant an evening of re-entering titles, tags and locations by hand. I asked whether Claude Code could do it if I gave it both accounts and the photos. It wrote a small resumable script that pulled all 89 photos with their tags and locations from the Unsplash API into a manifest, downloaded the originals into a pending folder, then uploaded them to Pexels in batches of 50 through the browser, moving each file to uploaded as it went so a crash couldn't cause a duplicate. The manifest is the state, the folders are the progress bar, and I could walk away from it.

I wanted a map of photography and day-trip spots across Triveneto, the north-east corner of Italy made up of Veneto, Trentino-Alto Adige and Friuli-Venezia Giulia, that matched my own criteria: reachable from home, worth a lens, not a car park with a view. It started in the chat app: I had Claude generate lists and poured them into Google My Maps, which left me with seven layers, seven inconsistent schemas, 3,549 pins, and a lot of the same place three times. Claude Code then built the pipeline that fixed that: parse, normalize the schemas, geocode the address-only entries through OpenStreetMap with the model resolving the names no gazetteer matches, cluster anything within a hundred meters, merge, and emit one clean layer of 2,286 places where each merged duplicate survives as a "Nearby" field. The source file that started it all is the one file the model may never write to.

The rest is smaller: batches in my photography export folder, questions to a cluster from ~/.kube, work summaries drafted with humanizer on so they read like me, first drafts of every App Store text, every commit message. The pattern is the same: describe the outcome, give it the accounts or the folder, keep the state in files so a crash is resumable, and read the result before it goes anywhere.

Where it falls over, and what I don't hand off

The failures I care about aren't the ones where the model writes a bug; the gates are for those. The ones that cost me time are where the system around the model is wrong, and I've learned four the slow way.

The first is asking for thoroughness instead of spelling it out. "Audit everything. Do not forget anything." produces a report shaped like thoroughness, and the model still misses the thing you'd find in five minutes using the app on a real phone. Anything you can't express as a test, or as a rule that names the failure, expect it to miss. Qroda's "native-first" rule exists for exactly that reason: a hand-rolled component where the platform already provided one, found by using the app, not by any audit.

The second is losing track of what the model has already done. Cleaning up a release checklist, I've typed "Was the audit already done? If not, run it, then clear the finished items." I couldn't tell from the documents whether a task had happened. That's a documentation failure on my side, and the template's rule that every finished change reports "what changed, the commands run and their results, what was not done" exists because of it.

The third is a rule quietly disappearing. Instruction files get restructured, and a working rule can fall out without anyone deciding to remove it. The only symptom is a usage counter that stops moving. Diff the old file against the new one the way you'd diff code.

The fourth is cost. Subagent-driven development fans out. On 20x that has never been a problem; on 5x it was, once, and I dropped to one task at a time. On a smaller tier, plan more in a single context, dispatch less, and keep the model out of unattended loops. The five-hour rolling window on paid plans is what shapes a day, more than any per-token number.

What I still do myself is a shorter list than it used to be, and I'm not sure where it will settle. Outward communication, mostly: the model drafts store copy, release notes and summaries, and I decide what goes out with my name on it. Architecture calls that are expensive to reverse go through an ADR I read and approve; my newer app's rendering framework was chosen by numbers from a spike on real hardware, not by the model's opinion. And I read every diff, which is less a boundary than the job.

Getting the same Claude Code setup

The single change that made the biggest difference to how good Claude Code is for me was installing plugins and skills for the stack I actually work in. Out of the box the model knows a framework the way a good generalist does. With a language server it sees what the IDE sees, with a skill pack it knows the current idioms instead of the ones from two releases ago, and with a browser it can look at what it built. Here is what I use, with links.

Plugins come from three marketplaces. The official one ships with Claude Code; the other two I added with /plugin marketplace add.

  • anthropics/claude-plugins-official: the ones I use daily are superpowers (the process skills, from obra/superpowers), playwright, context7, github, vercel, serena (symbol-aware code search, from oraios/serena), feature-dev (the reviewer agent), security-guidance, and swift-lsp. Install the LSP plugin for your own language; TypeScript, Go, Rust and C are in the same place.
  • warpdotdev/claude-code-warp: native notifications when a session stops or needs input, if your terminal is Warp.
  • blader/humanizer: strips the tells of machine-written prose.
  • wshobson/agents: a large community marketplace of role-shaped plugins. I installed most of it and use almost none of it. Pick the two or three that match your stack and skip the rest.

Skill packs are installed with the skills CLI from vercel-labs/skills: npx skills add owner/repo drops them into ~/.agents/skills and links them into Claude Code. On my machine:

MCP servers, beyond the ones the plugins bring:

And the master CLAUDE.md, summarized, so you can write your own or have Claude write it from the same brief. Sixteen sections in three groups.

Project facts, per repo, as long as they need to be: what the project is and where the spec lives; what's explicitly out of scope; a domain vocabulary table; stack, vendors and environments; a repository map; the exact commands for starting, testing, a single test, migrations and the "done" check; a tool map from topic to the skill, server or document to consult; files never to hand-edit; conventions; data classification; security-critical paths; budgets as numbers; where each kind of test lives; the documentation suite; "things that will bite you"; git and CI conventions.

Universal rules, forty to sixty lines: use the installed skills, never invent an API surface, propose the harness feature when one would have helped; tier every change as direct, plan-only or full, with "done" defined once; the smallest change that fully solves the request, no dependency or vendor without asking, third occurrence justifies extraction; vendor code behind an internal layer; every behavioural change ships with tests, a bug fix with a regression test, never weaken a test to pass; secrets from the environment only; an observability story in every plan; performance and cost against the budgets; review in a fresh context; schema changes through migrations and infrastructure through code; conventional commits; docs in the same diff; seven hard rules that override even an approved plan; honest reporting, including what was not done.

Maintenance: the file is code. Patch the rule that allowed a mistake, move a rule the model keeps ignoring into a check, delete a rule the model follows anyway, and add every surprise to "things that will bite you" in the same change. A stack customization block at the end holds the rules a linter can't express for your platform.

If you'd rather not write that by hand, the brief is the shortcut. Ask Claude for a definitive CLAUDE.md with the rule-surface constraint quoted earlier, give it your current project file to mine, and make it sort every rule into prose, hook, CI check, skill or dropped before it writes anything. Mine took an afternoon and has needed only small patches since.

Something you can do this afternoon

If you're setting this up from nothing, I'd do it in the opposite order from most people.

Gates first: warnings as errors, the strictest lint the codebase survives, tests on a clean checkout in CI. An hour if the repo already has a linter and a test job, most of the afternoon if it doesn't. The model will hit them a hundred times before you do, and that's the point.

Then one process plugin (superpowers) and the language server for your stack, plus a browser if you do UI work, and nothing else until a project file asks for it. Ten minutes.

Then the project file, facts only: what it is, what's out of scope, the exact commands, the vocabulary, and an empty "things that will bite you" section you add to in the same commit as each fix. An hour for the facts; the rest writes itself over the following weeks. Add a rule only when the model gets something wrong twice, and for every "never" you write, ask what enforces it. If the answer is "nothing", you have a wish.

Then, every so often, run the audit: ask Claude which of its skills, plugins and MCP servers have a usage count of zero, and delete them. Ten minutes, and the answer will surprise you at least once.

What's left is a contract: short on rules, long on facts, and edited every time the code surprises you.