Plan mode or bust
Ideation is now free, but taste remains expensive.
The last ~12 months have been a whirlwind. Working at a smaller company during an aggressive growth phase has run the gamut of emotions - exciting and overwhelming, stressful and joyful. But I’ve received what I was optimizing for in spades, and it’s been satisfying to get back into the details, challenge the limits of my comfort zones and push forward in the midst of collective aspiration.
Like the rest of the industry, one of the most exciting challenge-the-limits-of-my-comfort-zone developments has been AI-centric workflows. It felt like the capabilities / trust / workflows with tools like Claude Code hit a tipping point in late 2025, and the adoption curve of coding workflows today is on a different planet than it was 12 months ago. Is a single line of code at Imprint written by hand today? I seriously doubt it.
My job remains firmly on the management track, and I’ll be the first to admit I was on the latter wave of AI workflow adopters than most of the ICs I work with. Sure, I’d ask an LLM to proofread a document or even address a trivial code change far outside of the critical path, but I couldn’t seem to find the appropriate nexus of “this task is really important to me” and “I think AI would bring utility here.” Could I have an LLM prepare questions for a weekly 1:1 with a report? For sure. Do I actually care about spending time on this type of outcome? Not at all. I had a tremendously exciting hammer and couldn’t find a compelling nail. 1
But I’ve firmly been in a place for months now where logging into Claude Code is the first thing I do in the morning. And like any other practice, reps have increased my intuition on what works well and what works less well over time.
Plan mode or bust
AI is an exceptionally good conversationalist. In my personal life I have long, meandering AI conversations on my phone about clean meal prep ideas, exercising, effective golf practice strategies, etc. These conversations have no real beginning or end, and I swoop in with a question every few days and it probably picks up where we left off. The context window - however long it is - carries along enough to keep the conversation directionally aligned. “This middle aged man with a mediocre golf swing wants to eat clean.” Totally fine.
When I first started using Claude Code I used the same approach. I’d follow best practices by establishing some context - I am an Engineering manager looking to understand how our Datadog monitors are configured... - and I’d ask an extremely broad question - ...Explain our usage patterns across the codebase. And the conversation would begin. And Claude, given the lack of precision in my request, would bring up 8 different viable paths forward to answer this question. This is aligned with Claude’s incentives - it gets paid by the token. And 30 extremely substantive and exploratory messages later, I’d feel totally overwhelmed by the universe of what we’ve discovered, having lost the original intent of my conversation hours ago.
This is why Claude is an exceptionally good onboarding buddy. If you’re looking to explore via breadth first search, you can talk to Claude forever. But if you’re looking to accomplish something rooted in a discrete outcome, this is an imprecise and time intensive way to get there.
One thing I’ve grown to appreciate about Claude’s mechanics is in many ways it represents a normative perspective on software engineering:
- Start with a plan
- Explicitly define constraints
- Explicitly define acceptance criteria
- Iterate
Every single substantive task I complete with Claude starts with this prompt:
“Work with me interactively to create a plan. Ask me questions interactively in order to establish the plan’s details.
The audience is…
My goals are…”
And then based on the prompt I’ll add other sections:
- “Here’s a list of things that I know already: …”
- “Here are documents that you should read and analyze to build relevant context: …”
- “Here are points of confusion:”
All of my substantive interactions with Claude start with a Plan. It grounds Claude (and myself, via the CLI as a proxy) in our original intent and a constrained outcome, regardless of the breadth of our resulting interactions. While going deep on a conversational thread, I often ask Claude things like, “Wait, isn’t this irrelevant to what we’re trying to accomplish anyway?” And if it is, we’ll both discard that thread.
In my very lived experience, the outcomes are explicitly worse when you have conversations without a Plan first. When you are 30-messages deep on a very insightful thread and ask Claude to “summarize what we’ve talked about so far,” it will generate something that sounds pretty good. But it will be less successful at capturing your original intent, and as you work with it interactively to get to that intent, it’s very easy for Claude to begin to contradict itself within its own conversation in an effort to please you2. This happened to me frequently before I made it my own rule to always use Plan mode.
Eloquent slop
A thing I’ve said frequently over the last ~8 months is “AI is a lubricant, not a replacement, for your thinking.” If you know what Good looks like, AI will get you there, quickly. If you have no idea what Good looks like, AI will also get you there, quickly.
If you run /insights in the Claude CLI, it’ll give you a fun narrative on your own usage patterns. Here’s mine:
Your interaction style is iterative and correction-heavy. You frequently let Claude run with a task, then push back when results are wrong — whether that’s inflated metrics, incorrect root causes, or factual inaccuracies in documents. You’re comfortable interrupting to refine requirements but generally give Claude room to explore before course-correcting. The 27 instances of “wrong_approach” friction show you expect Claude to get things right but are patient enough to redirect rather than abandon.
In my Plan prompt, I’m very explicit about working with Claude interactively. This is because I argue with Claude a lot. I explicitly tell it to verify any assumptions it’s making with me first, and I don’t let it write a Plan to disk until I verify its contents first. It will make contradictions. It will offer statements as facts when it shouldn’t, or when it would require more due diligence to reach those conclusions. It will reach nonsensical conclusions. And it will reach all of these pitfalls extremely eloquently.
Claude is the most capable research assistant humanity has ever known, but that’s all it is. It’s not accountable to your outcome, nor does it care existentially about the holistic quality of its responses beyond the fact that it has responded to you. Whether its outcomes meet the standards of your Taste is solely on you, the operator.
AI has dramatically changed the volume and pace of not only code but artifacts like RFCs. Engineers who used to struggle over weeks to author RFCs now author them in hours. I no longer find myself proofreading documents for syntactic clarity. Surprisingly, that hasn’t correlated to better documents. In fact, especially closer to ~6 months ago, it resulted in a higher volume of worse documents. A lot of eloquent slop.
The most important aspect of these documents - the logical, strategic clarity - remains the same, pre and post-AI. And I often find that engineers who either struggled or excelled with this pre-Claude remain in the same spots post-Claude. An eloquently written RFC that prescribes a poor technical outcome is still a bad RFC. But the good RFCs - those written with a plan and intended audience, and using AI to articulate incentives, prior art, codepaths, and metrics/data - these have become truly excellent.
This is one reason why I think engineering leaders must be increasingly smart/technical in the AI era. If the main differentiator between a good and bad proposal is no longer its presentation but only its substance, can you tell the difference?
Workflows
Some random notes on my Claude workflows.
Iterating on plans / documents
In my local CLAUDE.md, I’ve told Claude to always output all of my plans and artifacts into a specific local folder (~/claude-output/), with a YYYY-MM-DD_topic.md file scheme. I keep that folder loaded in VS Code. When I’m working with Claude on a plan or a document, I’ll read/modify the plan written to disk via VS Code, and then tell Claude to pick up those local changes before responding to any subsequent prompts.
Local skills
We push globally-relevant skills to org repos, but I develop a lot of skills locally (~/.claude) for my own repeating tasks.
/notion-upload: Uploads a file I specify (or the most recent Claude output) as a subpage within my private notion space./linear-triage: Uses Linear MCP to triage the status of Active / Open / Older issues, given heuristics I specify. Generates a report that I often feed into other Plans./shipped-report: Uses Linear and Github MCP to look for work closed over a specific time period. Generates a report that usesnotion-uploadto upload the report into a specific Notion database./triage-alerts: Uses Datadog MCP to investigate Datadog alerts that fired within a time window, filtered by teams, priority, or notification channels/new-hire-onboarding: Uses Notion and Linear MCP to generate a new hire onboarding document for an incoming engineer or engineering manager, with interactive prompts.
Local memory
I’ll often run into a recurring problem where Claude will attempt to do the same dumb thing over and over again until it figures out that it needs to do something different. That’s fine, but it does get very annoying if I attempt to execute that workflow a lot.
As a specific example, the Datadog MCP server is limited in its permissions, so I also have Datadog API credentials available to interact with the Datadog API directly if necessary. Claude would consistently have issues injecting those credentials into its Python scripts and get stuck for minutes at a time during every new Claude session. When I run into issues of this type now, I’ll fix forward via prompting Claude like this:
This API credential injection issue happens every time you attempt to call the API. Save the fix to memory.
I don’t know how this works, but it does!
Ultrathink makes a difference
Claude Code can detect an inline keyword - ultrathink - that makes Claude “think harder.” If that feels intellectually dissatisfying, you’re right. I am also fairly confident it’s significantly more expensive in terms of token cost. But it does set Claude to higher effort (???) which, in my experience for certain tasks, actually makes a difference in outcomes.
I use this most when trying to reach conclusions while traversing confusing codebases. Claude is very good at reaching conclusions that sound good based on an initial read, and sometimes that’s fine based on my goals. But if I want a very precise, rigorously defended conclusion without unverifiable conclusions, I will end a prompt with this:
Do not state any conclusions you cannot explicitly verify. Ultrathink.
And ultrathink has forced Claude to reach a different conclusion often enough that I continue to use it. 🤷♂️
Footnotes
-
The headline-grabbing narrative that I think misses the plot (like many headline-grabbing narratives) is “just turn into an IC!” I am not saying this is not possible (and I have committed more code in the last 3 months than the last three years combined), but flatting to [50 AI-empowered engineers]::[1 manager who cares about their human and career needs] will never work. Not only for the humans, but for every cross-functional organization that expects to align disparate incentives and priorities. Engineers, even ones using AI, still have human needs. ↩
-
An extremely dystopian sentence, but if you use these tools, you get it. ↩