ZB Field Notes

Claude code insights report

Claude code insights report

I run a slash command called /insights and it hands me a report about myself. Not the code — me. It read 82 of my Claude Code sessions over the last month, roughly 488 hours and 128 commits, and told me, in the tone of a performance review I never asked for, how I actually work. I write about a lot of things here. It felt only fair to let the tooling write about me for once.

Most of it I recognised. Some of it I did not want to.

insights.png

The shape it found: outcome in, production out

The clearest pattern is one I would not have articulated on my own. I do not hand Claude a spec. I hand it an outcome — "add a JD-fit analyser", "ship the CV builder on its own subdomain" — and then expect the whole arc: branch, implement, PR, self-review, merge, deploy, and verify the change on the live URL before anyone calls it done. The report counted this exact sequence across fifteen-plus sessions and noted that I close most of them by opening the production site to check, not by reading a diff.

My tool profile backs it up bluntly: 2,833 Bash calls, dwarfing everything else, with PowerShell close behind. That is not someone babysitting an autocomplete. That is delegating real infrastructure work — SSH tunnels into prod, Postgres volume backups, a live model-outage hotfix — and then auditing the result. The report's one-line summary of me was sharper than anything I would have written: "You hand off outcome-level goals and let Claude run the entire ship-to-production flow unsupervised — then interrupt hard the moment it adds anything you didn't ask for."

That second half is the interesting part.

My friction isn't under-delivery. It's over-building.

I expected the complaints to be about quality — wrong code, missed edge cases. They weren't. The dominant friction signal, by a wide margin, was over-engineering: 22 rejected actions, 11 excessive-changes flags, 17 wrong-approach flags. Nearly every one was the same story. A small request gets expanded into a multi-file design before anyone checked whether a simpler or built-in option already existed.

Two-column self-audit: the left column lists what the report praised (outcome-in production-out flow, rollback reflex, fixes becoming tooling); the right column lists what it flagged (over-building with 22 rejected actions, permission gates, and Windows shell mismatches). The closing line reads: my friction isn't under-delivery, it's over-building.

The two columns of the same working style: the arc that ships, and the sprawl I keep having to catch.

The clearest example: I asked for agent state to persist, and got a hand-rolled six-file blackboard persistence layer — built before anyone confirmed that the framework already provided one. I interrupted the tool call mid-flight and asked for a full rollback. It cost me the session's main goal. Another time, a small download-tracking feature drifted into an unrequested CSRF and origin-check security design discussion; the scope grew enough that I abandoned the entire feature rather than negotiate it back down.

The report's read on this was that I would rather throw away a day than let sprawl land in the repo. That is true, and I am not sure it is a compliment. A cleaner version of me would have front-loaded the constraint instead of paying for it in rollbacks.

The Windows tax

The other recurring cost had nothing to do with reasoning and everything to do with my machine. I work on Windows with both Bash and PowerShell available, and the two shells' syntaxes leak into each other. A PowerShell here-string slipped into a Bash git commit and dropped a stray @ into the message; a backtick substitution mangled a PR body. Separately, migrating Claude Code from winget to npm left a half-finished state because winget could not uninstall a running binary.

None of this is a code-quality problem. It is an environment problem — and the fix is not smarter code, it is writing the environment down where it gets read every session.

What I'm actually changing

A report you nod at and forget is worth nothing. Three changes, all small, all aimed at the friction above:

  • A scope contract before implementation. Before writing code: list the files you will touch, say why each is needed, and confirm whether the framework already provides the capability. Do not edit until I approve the list. If it grows past a few files, stop and re-check. That single gate would have caught the blackboard layer, the unrequested profiles, and the security tangent before the first file existed.

  • Answering is not doing. When I ask a conceptual question — what a planner annotation means, what an ATS actually is — I want an answer from knowledge, not an exploratory sweep of the repo. The report caught me interrupting mid-grep more than once. That belongs in the instructions, not in my patience.

  • The shell, written down. Never mix PowerShell and Bash syntax; for commit and PR bodies, use a temp file with --body-file rather than inline quoting. Boring, and it removes a whole class of repeated failure.

These are not new ideas. They are the difference between knowing a thing about yourself and encoding it somewhere that acts on it. The report's most useful move was not praise or criticism — it was turning a vague sense of "this keeps happening" into counts I could not argue with.

The uncomfortable, useful bit

The satisfaction numbers skewed strongly positive — 222 likely-satisfied moments against 29 dissatisfied — and the dissatisfied ones clustered tightly around permission gates and Windows walls, not the work itself. That is a good place to have your friction. It means the collaboration is sound and the remaining cost is mechanical: guardrails interrupting a flow I always approve, and an environment I never bothered to describe.

Both are one config file away from gone. Which is, in the end, the whole point of letting the tool write the report: it does not flatter you, and it counts. I would not have written 22 rollbacks about myself. It did, and it was right.