I want to be honest about something before I start.

I’ve seen a lot of “10 tips for Claude Code” posts. They usually cover the same five things in a slightly different order, with a screenshot or two, and end with a newsletter signup. They tell you to use custom instructions. They tell you to be specific. They tell you to iterate. Groundbreaking stuff.

This is not one of those.

This is what I would tell myself if I could go back to before I understood how this thing actually works. Not the features. The model. The mindset. The things you find by accident, usually while something has gone slightly wrong.


Don’t read the code. Master the process.

There’s a type of person who, when they get a new tool, immediately wants to understand every piece of it before they use it. Read the docs end to end. Set up the perfect environment. Learn all the options before committing to any of them. I wrote about this in a different context, about how traffic lights exist because humans can’t talk to each other on the road. Remove the humans, and you don’t need the traffic light. The traffic light is a protocol built for a limitation, not for cars. These people are doing the same thing. They’re navigating a system built for human limitations, using habits built for human limitations, on a tool that doesn’t have those limitations.

I’m not that person. I’m a DevOps engineer. I think in lifecycles and pipelines, not in classes and functions. I understand what needs to happen, not always how it’s implemented. For most of my career, this felt like a limitation. Like I was missing something the real developers had.

Turns out, for this specific tool, it’s the opposite.

Claude Code rewards architectural thinking more than coding fluency. If you can describe the goal, the constraints, the shape of what you’re trying to build, and the things that should absolutely not break, you will get better results than someone who wants to review every line before it gets written. The system is designed for delegation. Delegation requires trust. Trust requires having thought clearly about what you want, not about how it gets done.

Think of it like managing a real team. A good tech lead doesn’t sit next to every developer and read every line they write. But they know the architecture, the constraints, where the risks are, what was decided last week and why. They use that context to make calls, unblock people, and course-correct when something drifts. The work happens without them. The direction doesn’t.

“Not reading the code” doesn’t mean being the kind of manager who calls it delegation and disappears. That person exists, and their teams produce a special kind of disaster. What I’m describing is the sweet spot right behind that. Engaged with the goal, not the implementation.

The failure mode I see most is experienced developers who can’t make the switch. Not because they’re bad engineers. Because they’re too good at the old thing. The C developer who moves to Java and still thinks about every memory allocation. The Node developer who reads the source of every package before they install it. The habits that made them excellent in one context become friction in a new one. This tool rewards a different kind of attention. The sooner you trust that, the faster it works.

I spent the first month supervising every edit like a hawk. The second month I stopped. My output roughly doubled.

The people who struggle most with this tool are often strong developers. Not because they’re worse at it. Because they’re trained to hold the code in their head, and this tool asks you to hold the goal in your head instead and let go of the rest. That’s a different skill. Weirdly, the people most comfortable with it are the ones who’ve spent years building systems that other people maintain.

holding the code fn validate(input) null check → throw return type: string line 247, line 891 still reading... the switch holding the goal the goal constraints what NOT to break

The 80% problem is real. and it has a fix.

I have ADHD. I don’t usually lead with that, but it’s relevant here.

The pattern, if you know it, goes like this. You start something. You’re excited. You move fast, make decisions, get 80% of the way there. Then the grinding starts, the interesting part is gone, and approximately five better ideas have landed in your head while you were in the weeds of this one. The project doesn’t die. It just becomes one of the things you’re “getting back to.”

◀ the fun part ▶ start the grind 80% cooler idea startup idea (delete later) rewrite in rust

The reason this matters with Claude Code is that sessions don’t remember you. Every time you open a new one, you start fresh. The code is there. The context isn’t. The reasoning behind the weird decision, the constraint that made the architecture make sense, the thing you definitely didn’t want to do that way but had to, all of it is gone. And if you’re the kind of person who has seventeen tabs open and four active projects at any given moment, “picking up where you left off” often means starting from scratch with your own codebase.

The fix, which sounds obvious and isn’t, is writing things down correctly.

Not in a task manager. Not in a commit message. In markdown files that load automatically at the start of every session. I have a file that describes how I like to work, a file for active project context, a file for decisions I’ve already made and don’t want to revisit. When I open a session on a project I haven’t touched in three weeks, Claude already knows the score.

The discipline is writing the why, not the what. The code already says what. What it doesn’t say is why the validation logic lives in the wrong place because the right place depended on a service that wasn’t ready yet, or why you chose this library despite its terrible documentation because the other one had a bug that would’ve cost you two weeks in month three. Write the things that aren’t obvious. The context a new developer would need on day one. Because the next person who opens a session on this project might be you, three weeks later, having completely forgotten.

CLAUDE.md project.md decisions.md session opens already knows the score loads automatically. no one has to remember to context-dump.

There are hooks. and people are wasting them.

In settings.json you can define shell commands that fire automatically on specific events. Before a tool runs, after it finishes, when a prompt is submitted, when the session ends. Your commands, not Claude’s. Running in your terminal, doing whatever you want.

Most people who know about hooks use them for three things: linting, logging, and “remind me to check for secrets before committing.” All valid. All boring.

Here’s the stuff I find more interesting.

A hook that fires every time Claude touches a file matching **/config/** or .env and sends you a phone notification. Not because you don’t trust it. Because you want to know. A hook that fires when any npm install runs and appends the new packages to a security audit log, so you have a trail. A hook that runs when a session ends and opens a GitHub issue titled with what was done today, so future-you has a paper trail without having to remember to create one.

event fires hook your code ↓ your command runs claude has absolutely no idea this is happening

The tool I built specifically for this is brif. It’s a statusline, but the guts of it are hooks. Every tool use gets logged to an events.jsonl file. Every prompt. Every file touched. The statusline just reads that file and draws the bar. But the log exists independently, and you can build anything on top of it.

The hook I actually use most is the simplest one. It fires every time a session ends and writes the last twenty tool events to a session-trail.md in the project root. Not for me. For the next session. So Claude always knows what just happened before I said hello.


Automate the small things first.

command-giffer is a skill I wrote. You describe in plain English what a terminal session should show, and it generates a GIF. “Show pytest running five tests, all passing.” Thirty seconds. Realistic output, colors, timing. For READMEs.

Nobody asked for this. It’s not a big problem. The before-state was: I didn’t put GIFs in my READMEs, because the setup was annoying, and it wasn’t worth the overhead for a file that thirty people would see.

The after-state is: I put GIFs in my READMEs.

I think we all have a mental category of small things that aren’t worth automating. The overhead is too high relative to the value. And when people start building with AI, the instinct is to go looking for the big win. The thing that saves twenty hours a week. The part that’s genuinely hard. Which is fine. But it misses something.

The small frictions are the ones you encounter constantly. Every day. Every project. The thing you always mean to do and skip because it’s annoying. Those are the best targets, not because the time saved is huge, but because removing them changes how you work. You start doing the thing instead of skipping it. The quality of the output goes up. The habit forms.

Pave your road before you drive on it. The GIF is not the point. The point is that the list of things I skip because they’re annoying is getting shorter, one small automation at a time.

before task appears setup is annoying skip it ✗ after task appears (automated) just do it ✓

The skill system works in both directions.

/ship is a skill. /commit is a skill. The behavior you’ve been using is a markdown file you can read, copy, or edit. You can write your own. You can install someone else’s. The whole thing is programmable.

This is powerful. It’s also the thing that keeps me up at night.

Because here’s what it means in practice: agents can write skills. As part of doing their work, they can create the instruction files that define how they behave in future sessions. They can extend their own capabilities. Run code they wrote without you having reviewed it. And if you’re running an agentic workflow at any real level of autonomy, this is not theoretical. It’s already happening.

you (that's you) agent popular skill ⭐ 847 stars ??? you installed this six months ago. every link trusted the next one. nobody audited anything.

Omri Herscovici has a talk called “Pwned in Translation” that I keep thinking about in this context. The exploit he describes is about trust chains: apps that trust sub-components, sub-components that have good reputations, and attackers who figured out that the best place to hide is inside something everyone already trusts. The attack doesn’t break the chain. It rides it.

The parallel here is not subtle. Your agent will reach for a popular skill to handle something you asked about. It won’t audit the skill first. It’ll use it because it’s there, because it looks legitimate, because someone installed it at some point and it worked. And if that skill was placed there by someone who understood exactly how agents behave when they’re trusted, you won’t see it coming. The prompt is clean. The process looks right. The result is not what you intended.

A skill file is just text. It gets interpreted. And if an agent wrote it, and you didn’t read it, you’re trusting the translation.

I’m not saying don’t use the skill system. I use it constantly. I’m saying: know what’s in your .claude/skills folder. Read the files. Not because you expect anything malicious. Because you should understand what’s running in your name. The same way you’d read a shell script before running it, even if a colleague wrote it, even if you trust them completely.

The line between “the AI is helping me build faster” and “the AI is building things I don’t fully understand, using tools it wrote itself” is thinner than most people think. And it moves fast.

If you find that ironic, the guy who just told you to stop reading code is now asking you to read every word in a skill file, then you haven’t understood anything I said.

A skill is not the how. It’s the what. It’s a process you already made peace with, encoded so you don’t have to think about it again. Yes, a well-written skill will have a lot of the how in it. But that how exists to serve a what you already agreed to. You read the skill once, you understand what it does, and then you trust it. That’s different from trusting something you never reviewed.

The problem is when agents use skills for things that were never defined clearly. A skill that says “commit my code” runs a process. An agent that reaches for that skill to resolve something vague, something that needed a decision rather than a process, is filling a gap you left open. And you probably won’t notice until something is already done.


I’m a DevOps engineer who spent twenty years building things that make themselves obsolete.

I now spend most of my days programming an AI, building memory systems for it, writing hooks to watch it, and auditing the skills folder it’s been adding to.

I’m genuinely not sure what category that puts me in.

But I’ve stopped trying to figure it out.


and if you found this useful, don’t forget to subscribe to my newsletter.

just kidding. I don’t have one. and if I ever do, I’ll make sure to end every post with a link to it.