SWE and product engineering in the era of AI
Short intro
Writing software in the era of AI is a significantly different experience than a few years ago.
Processes changed, ways of working changed, and the effort we put into writing and reviewing code is shifting.
In product engineering especially, we used to spend a lot of time designing features, discussing with product managers, and finding compromises. Now that the cost of writing the code has gone down, the paradigm shift is around making the right decisions and parallelizing.
A lot of engineers, managers, and C-levels I’ve worked with have asked how I approach this and how I set up my workflow (one of them more than a year ago). I decided not to share the setup until now—partly encouraged by others in the past couple of days.
Take this with a pinch of salt. Assumptions are mostly subjective (with some objectivity here and there). What follows is how I moved from regular engineering workflows to full product/software development with a formula that multiplies throughput without sacrificing quality and, most importantly, without losing control.
If any of this feels familiar, these notes might help:
- You spend a lot of time with coding agents and throughput is not increasing
- You use many skills and things still don’t work as expected
- Throughput went up but quality went down
- You feel you are losing control of what you are doing
Disclaimer
Personal notes only. They do not represent company process or a standard for colleagues or employers.
How I (and we?) used to work
Staff engineering is a slightly different role from regular engineering; these notes target software engineering and product development. Impact as staff can mean writing code or unblocking others.
For product development (e.g. a web app—desktop/mobile and embedded differ), teams often have backend and frontend engineers, or full-stack / product engineers.
Ceremonies (agile, scrum, waterfall, etc.) aside, the daily outcome was usually the same: work on one task (or a couple), follow requirements, deliver a task (story, epic, whatever).
Focus was typically one, two, maybe three concurrent topics on feature work. The bottleneck was writing the code.
What happened in the last years
Coding agents first suggested next lines while we wrote. Then models got good at something people dislike: writing tests. For at least about a year (from when these notes were written), agents have been capable of managing actual work.
Did the bottleneck go away?
No. The bottleneck didn’t disappear—it moved.
What the hype train tells us
Hype (~9 months of it at time of writing) often says “just tell the agent what to do” and it nails it. Reality is different.
What is true: agents are extremely good at doing what you tell them to do. The hard part is telling them precisely what you want.
Ambiguity turns a clear idea into a clunky implementation that barely matches intent. Finding where it went wrong can be hard (sometimes impossible). These notes are about reducing that failure mode, improving the setup, and hard-won lessons.
What is our goal, anyway?
With AI: increase productivity and get maximum output while keeping everything under control.
Whether that is 2×, 10×, 100×, or 1000× matters less than the pattern and the variables you can turn up or down.
Not about yoloing a toy product (this blog itself took one spec with the workflow)—about enterprise-scale product development. Prototypes and pretty HTML are easy; large orgs are harder. Giving the agent “enough context” helps but is not enough by itself.
Where does the human stand?
Not many people ask where they should act when using AI. Many approaches fail; that’s part of learning.
Places a human can sit in the SDLC:
- YOLO—ask the agent to do something with no intervention (“build me an app that generates pictures of cats”).
- Define the work (spec, PRD, etc.) and ask the agent to execute.
- Break work into smaller pieces and have the agent execute them.
- Write code and ask the agent to review.
- Ask the agent for the smallest unit of code and review it.
The human can stand very close to implementation or far away. Tried all of these (including a personal “AI dark factory”) before landing on what works.
My setup — philosophy and how I got there
Started with agent mode and plan mode. Plan mode was revealing until the controllable unit of work stayed at “small feature.” Bigger features: ambiguity, scope drift, even with steering. Plan mode is still only ideal in a very small subset of cases (barely any).
First light — “grilling”
The grill-me skill (Matt Pocock) was a step change: force common ground and shared understanding with the agent before the implementation plan.
Worth trying for anyone still on plan mode. Navigating ambiguity with an agent is often pleasant—until you realize you still need something else after.
Next step — Spec Driven Development
Grill-me and related skills were good but not enough for enterprise day-to-day. Needed more structure.
The Obra era
Tried obra:superpowers (https://github.com/obra/superpowers)—most loved and most hated skill at once: rigorous, smart, complex, satisfying, but too many tokens and too much time.
The GSD era
Also tried GSD (https://github.com/open-gsd/gsd-core). Cool, still not enough.
Reality check
Other skill packs (awesome claude code, claude code superpowers, etc.) eventually felt wrong.
Lesson: you can’t fully bring someone else’s workflow into your way of working. That’s the best learning from the journey.
Spec-driven development stayed; off-the-shelf skills’ framing of problems and implementation pace didn’t match needed scale and speed.
The final formula
A personal skillset, evolved daily—not shared as a drop-in (it should work for you, not as a copy). Guidelines used to build it:
- Think about what you do daily.
- Identify main workflows that need predictable outcomes.
- Write how you build it; turn it into a skill; steal ideas from similar skills; iterate.
Skills used daily (work across major coding agents; slight guideline differences by model family):
feature— remove ambiguity when designing a feature given a scope. Three lanes:- express — low complexity; all questions in one shot
- standard — mid-sized; important details first, trivial design details later
- deep — large; one question at a time per design section
patch— given existing feature/commit/PR/branch/spec + a change: update the spec and apply the express feature lanesubagent-driven-development— orchestrate subagents; feedback to the root agentbugfix— bugfixing with hypotheseswrite-spec— from a feature input, write an implementation specificationwrite-plans— from a spec, split into smaller isolated implementation unitsplan-handoff— visual table: what the root agent controls vs subagents (groups for parallelization)create-a-pull-request— PRs aimed at humans (not agents): TLDR + suggested review focusloop-commit-pr-code-review— after PR open: listen for comments, apply trivial/objectively true fixes, flag ambiguity for human decisionsecurity-audit— flag security issues; human decides next steps
Skills keep evolving with need.
Where am I as the human?
In a regular SDD workflow, two places:
- Feature spec definition
- Final review
Everything else handed to the agent; skills and repo coding guidelines do the rest.
Intended flow shape: EPIC → Feature (O(n)) → Spec (O(n)) → Tasks (O(n)) → Task review (O(n)) → Final review — human markers on Feature and Final review.
Why not higher in the chain (EPIC)?
Tried EPIC-level ownership. Doubts remain for daily work. Engineers navigate ambiguity many times a day; epic-scale orchestration is fragile—if something goes wrong mid-flight, you burn a huge token budget.
Problem 2 — Larger codebases / larger features
Extra complexity:
- Work distributed across multiple repositories
- Still limited to one feature at a time if the environment isn’t set up for isolation
Own solutions exist; brought together in the final setup section.
Problem 3 — Model choice and token economy
Complex workflows make model choice hard. Guidelines live in the setup section.
Problem 4 — Parallelism
On paper the skill flow is fine; in practice you’re still one feature at a time and can blow the token budget.
Problem 5 — Context switching
Even with parallel work, how do you context-switch efficiently?
The final setup from the learnings
Everything points at one need: be efficient at parallelizing.
That means:
- Focus on what is important
- Isolate by the highest slice (here: feature)
- Compact wording to the bare minimum
Focusing on what is important
Many IDE windows / one IDE per repo does not scale. Most time is not reading code—it’s guiding the agent. Need a lighter tool.
The frame: tmux
- A terminal tab (iTerm2, raw terminal, Ghostty, etc.) is a group: a set of vertical panes
- Each pane is an isolated feature
- Pane and workspace get names
- Each pane runs a coding agent (CLI only): Claude Code, Codex CLI, pi, OpenCode, cursor-cli, grok-cli, etc.
Context switch = switch tab/group.
Reviewing code
No IDE for memory economy (local models may matter later). Review in neovim.
Flow: from the agent pane !pwd | pbcopy, then another pane cd [paste] && nvim, then a shortcut for git diffs ([esc] [space] gd). ~4 keystrokes to start a review most of the time.
Skills wording
Skills instructed to never return sections longer than 40 words. Limits agent “vomit.” Not “caveman” mode—just concise questions and review sections.
Isolate by the highest slice
Hardest place for many engineers: work that spans repos, or parallel features on overlapping repos.
Solution: a custom agent repository manager—Rust CLI that creates isolated environments under ~/.agent-workspaces. Interactively pick repos, starting branches, optional Codegraph indexing, caching.
Shell helpers in ~/.zshrc, e.g.:
yay-grok,yay-claude,yay-codex,yay-cursor-cli,yay-agy,yay-pi,yay-opencode
Pattern:
yay-grok() {
local dir
dir="$(agent-repo-manager)" && [ -n "$dir" ] && cd "$dir" && grok "$@"
}
Start manager → select repos → session name → start agent in that pane. One isolated feature environment regardless of how many repos it needs.
Model selection
Models in daily use (at time of notes): Opus 5, Sonnet 5, GPT 5.6 Sol / Terra / Luna, Composer 2.5, Grok 4.5. Skills work with all of them; choice depends on task and token budget.
General purpose / troubleshooting / exploring
Avoid Opus 5 when possible—verbose, hard to scan.
Incidents / cross-topic troubleshooting: GPT 5.6 (often Sol)—less likely to stop at the first apparent root cause.
Codebase exploration: GPT 5.6 Sol unless out of tokens; then Grok; Opus last for that scope.
Skills / MCPs / implementation
MCP invocation consistently better with Claude Code than other harnesses in this experience.
Feature/bugfix coding feels simpler with Anthropic / Grok families; GPT outcomes better if you master them.
Most workflows: Opus 5 for features; Sonnet 5 / Haiku for implementations.
Effort / family selection for features
Rough decision tree from the notes:
Feature genuinely complex?
- Yes → Opus 5 medium, or Grok 4.5 medium, or GPT 5.6 Sol medium / Terra high
- No → Opus 5 low, or GPT 5.6 Sol low, or Grok 4.5 medium/low
Feature spanning multiple repositories?
- Yes, and repo is large / legacy / full of traps → Opus 5 high, or GPT 5.6 Sol high, or Grok 4.5 high
- Yes, but not that messy → Opus 5 medium/low, or Grok 4.5 medium/low, or GPT 5.6 Sol low
Implementation tasks
- Trivial (few files + tests) → Sonnet 5 low, or GPT 5.6 Luna low/medium, or Grok 4.5 low
- Complex uncommon patterns → Sonnet 5 medium, or GPT 5.6 Luna medium/high, or Grok 4.5 medium
- E2E tests + iterative fix → Sonnet 5 high, or GPT 5.6 Luna xhigh, or Grok 4.5 high
- Still too big → Sonnet 5 high/xhigh, or GPT 5.6 Luna xhigh, or Grok 4.5 high
Personal tips & tricks
- Try lowest effort first; you’ll discover when you need smarter models more often than the reverse
- Thinking effort ≠ smarter model—more time in the thinking loop, better decisions more often
- Keep wording concise; ask agents to do the same
- Iterate skills under version control; use skills to write skills
- MCPs only when they add real value
- Don’t pollute the skills folder with unsure clutter
- Understand your skills. Read them
- Monitor your skills. Track efficiency over time
- Take time to learn new models
- Optimize processes to multiply throughput
- Focus on keeping control of what is happening
Conclusion
To amplify work, three things (opinion):
- Knowledge and patience—keep trying and improving workflows
- Solid, somewhat predictable workflows for day-to-day engineering
- A solid token budget / subscription
With the parallel setup: less AFK waiting, more deliberate context-switch time; manage up to 8–10 concurrent features without losing control.
When a workflow could be better/faster—do it. Building your own tooling is cheaper than it used to be; opportunity to build what you want rather than only adopting what others built (sharing setups is still good).