My favorite byproduct of the AI shift in engineering is that it is making us think harder at workflows and ideas we have taken for granted for a long time.
In some cases, we even invented words we didnāt use before, like context, or, one of my favorite lately, intent. These words are abstractionsāour bread and butter as engineersāand are born out of the necessity to discuss ideas, understand whatās going on, and improve how we work.
The intent concept is both important and, AFAIK, quite novel. These days you may hear it in sentences like āmaking sure PMsā intent is captured into specsā, or āAI code should reflect the engineersā intentā.
This angle frames software engineering as a translation act between something you want to achieve and what gets actually captured in artifacts like specs, UI design, up until code. If we continue this analogy, translation happens at every step, with different steps following different rules. Many engineering practices exist essentially to reduce the error rate of such translation.
So, seen through this lens, software development becomes an elaborated version of the telephone game. You win the game if the message is passed properly and ends up in⦠production.
That said, what the steps of the telephone game are (or should be), or what the best winning strategy is, frankly, itās all up for discussion today. Should we write big specs beforehand? Should we keep human code reviews? Who should do this and that, and when, and how often?
Today I want to explore this, taking from what I have personally learned from my recent coding efforts, and ideas I bounced off with Amelia Wattenberger, who I interviewed last week on the podcast, and is joining me today on this piece.
So here is the agenda for today:
š From intent to code ā the journey of translating what you really want to do
š§± Creating good platform ā for each step of the journey, so AI doesnāt mess things up.
š« Staying at the right altitude ā evolve your artifacts to match what you want to inspect
š¬ Using product to improve understanding ā not just to implement it.
Letās dive in!
Disclaimer: Amelia works at Augment Code and created Intent, a developer workspace with strong opinions about all of this. Augment is a long-time partner of Refactoring, I use it, I am a fan, and I am happy if you check it out.
However, we are not here to promote Augment today, but rather compare notes about problems and try to predict where the puck is going. (The puck, Luca? In a telephone game? Yes)
š From Intent to Code
Starting from something you want to achieve on the product you are building, then itās a long way to encode that into, well, code.
Intermediate steps may vary based on your process, but you probably have some version of these:
1) Product intent
A high-level, one or two-sentence version of what you want to build. It may only live in your head.
Making an example from my own experiments (I am building an editor), letās say I want to add split panes, like many editors have. In my head, thatās it. I donāt think about it a lot more.
2) Product specs
Product intent needs to be turned into a spec, like a PRD, which needs to stay faithful to my original intent, while deciding a lot more things.
How is this triggered? Is there a button? What does it look like? What about keyboard shortcuts? What happens if I drag a tab from one pane to the other? And more.
Some of these are just additional detail, but some might derail the feature in a direction I didnāt intend. For example, a legitimate interpretation might be to open up the tab in a new window, which is not what I want.
3) UI/UX design
Product specs are turned into design specs. What it looks like, how it behaves, where it lives.
4) System design
Product and design specs inform the strategy to implement this with code. Abstractions that should be reused or created, data structures (when relevant), migrations, instrumentation, testing, rollout and rollback, and more.
5) Code!
Finally, thereās code! All of this turns into a bunch of LOCs, to be pushed, reviewed, and released in prod.
Phew. Thatās a lot of work.
Of course YMMV and you may skip creating actual artifacts for some of these steps, based on the complexity of the work at hand, and your team's workflows. But there are at least decisions to be made about all of these, even without the artifacts:
Every step adds details that the previous kept implicit or simply did not consider.
Every step can act as a lossy translation of the original intent. It can miss important details or interpret them incorrectly.
What is our goal with respect to this process? The ultimate goal is always to ship value to customers as fast as possible, so you can get feedback and iterate.
To ship fast you want to avoid rework: you want to reduce the misunderstandings between the various steps and the mistakes that would make work move backwards instead of forwards. You want code abstractions that match the PRD, a PRD that matches the product intent, and not getting to the point where a review fails and some of this gets back to the drawing board.
This angle is relevant with humans, and especially relevant with AI. AI models today are really good, and it feels most of their mistakes now come from not understanding what you wanted, rather than e.g. bad coding skills.
So how do you get good at this? The most convincing way, to me, is:
Creating good platform for each step ā which acts as guardrails and helps you minimize the amount of intent you need to encode into specs.
Use specs as active collaboration surface ā updating it with more details as the work progresses, so it stays at the right altitude all the time. Kudos to Amelia for making me think about this.
Letās explore both š



