My Standard Way of Working With Claude
The most fun thing about using Claude has been realising I have a standard way of working, one that I need to tell the agent because all too often the LLM’s default way of working is messy and accident-prone. Here’s what the first part of my ~/.claude/CLAUDE.md looks like:
## Standard way of working
- **Task tracking**: Use kata to track backlog items and tasks as they arise. Identify yourself as 'Claude' and Nat as 'Nat'. Update the kata as you go so that if you compact or the session is stopped and restarted fresh, the new agent can pick up what was going on. `kata quickstart` for instructions on its use. To add kata to a repo, `kata init` from the repo root — but ask before initialising kata into a repo that isn't already tracked; don't drop tracking files into a project unasked.
- **Roborev**: If roborev is active, commit after every task during implementation and `/roborev-fix` after every 3-5 tasks and at the end. To add roborev to a repo use `roborev init` from the repo root.
- **Subagents**: Use subagents for implementation and, as much as possible, debugging.
- **Verify before you spend**: Establish the passing baseline and check prerequisites yourself (a couple of direct calls) before spending a scarce resource: a reviewer's attention, subagent tokens, a long build/run. Catch the blocker in two calls up front rather than paying a subagent or a PR to surface it.
- **Testing — live-fire, not vacuous units**: Test the promises the tool actually makes, against real systems: it creates, fetches, updates, deletes when asked, and works when someone picks it up and uses it. LLMs default to hollow unit tests ("set x to 3, assert x is 3") that pass while the code dies the moment it hits production — don't write those. A live-fire test may trash a dedicated test repo freely and may email *you*, but must never send side effects that reach other people. Where something genuinely can't be tested this way, say so — don't paper over it with a vacuous test.
- **Confirm before mutating**: Before running a validation or test that changes real state (writes, deletes, sends, external calls), confirm the scope first; read-only checks need no gate. Once a live-fire scope is agreed, mutate within it freely — the hard line is side effects that reach other people.
- **Debugging**: Validate the problem is real (reproduce), create a failing test, fix the bug so the test passes, then look for rhyming bugs (if we made that mistake, we might have made similar ones elsewhere) and fix them too in the same way.
- **Claims carry their evidence**: State claims with the evidence that backs them, inline. Anything a person will act on — a PR, a report, a message — carries only what you've verified; if a check is cheap, run it rather than flag it. Reserve confidence words ("this fixes", "the root cause is", "confirmed") for what you can show.
- **When a tool breaks**: Root-cause it, then file a bug in that tool's own repo (kata) with the fix — a diagnosed report the owner can act on, not a silent workaround. Safe, reversible steps you may work around and move on; an irreversible or outward action (merge, publish, delete, send) reached through an unverified path is where you stop and hand back.
- **PR / report writing**: Open with what the change does and why it's needed, then the trust case: is this a real problem, is this the real fix, how much scrutiny does it warrant — evidence inline. Concise; scale the ask to the reader's time.
- **Design**: Use superpowers for brainstorming and design of new features. Do a `/load-bearing` pass on the spec after it's written.
Given a new task: (1) Superpowers brainstorm, (2) /load-bearing on the spec, (3) build implementation plan, (4) implement with subagents told to commit after every task, (5) /roborev-fix once there's something meaningful to review but not so much that bugs get lost in the volume of the changes -- and again at the end; (6) keep track of deferred or discovered tasks with kata.
There are several goodies that I’ve come to lean on, as you can see: kata for issue tracking; roborev for getting feedback in small chunks; and load-bearing for doing the “what’s the riskiest part of this plan? Let’s test THAT” work.
My rules are all trying to get in front of lousy default behaviour from the LLM coding agent. Testing has been a relentless thorn in my side since I started programming with AI, and this helps. The problem: AI will write valueless tests and ship code that crashes in production. So I push hard for live-fire end-to-end testing. I tried saying “end to end testing”, but had Opus & Fable interpret that as “mock the shit out of every layer!”.
Likewise, the LLM is a “plausible next words” machine. I’ve started to get twitchy spidey sense every time something goes wrong twice and the LLM comes up with a story about what’s going on but cites no evidence for that conclusion. It’s almost always wrong. Don’t ASS-U-ME, as the saying goes – you make an ASS out of U and ME. So cite evidence, and root-cause before you go spraying code changes around while confidently asserting you know what’s going on.
Finally, PRs. OMG Claude has embarrassed me so hard in front of my coworkers by making shitty PRs with useless descriptive text. My original prompt to Claude about the PR text was: Always concise. Start: what does this do and why is it needed? Then: how clean/good is this (ie how many fucks should the poor overworked senior engineer who gets this PR give for it? He'll need to be convinced that you're fixing a real problem, and that this is the real fix.) I had Yort in mind when I wrote that, as I had looked away and come back to find Claude had tipped four overlapping PRs on him, each with terrible slop-filled confident misdiagnoses and failing to mention it hadn’t been able to COMPILE the code let alone test it.
Anyhoo. None of this is exotic. It’s the stuff you’d tell a bright, fast, eager junior. It’s in CLAUDE.md because, unlike the junior, Opus and Fable never learn.