Article
The Spec Is the New Prompt: How to Guide AI Coding Agents
Why bigger prompts help AI coding agents, where they still fall short, and how specs keep product and architecture decisions visible before implementation.
The First Prototype Asked the Right Question
The first prototype was fast, and the code was not the main problem.
The problem was that important decisions were happening without being named.
So the next question became simple:
If silent decisions are the problem, can we solve that by giving the agent all the details upfront?
Maybe a Bigger Prompt Is Better?
One reader asked me a fair version of that question: why not write one mega prompt with all the details?
So I decided to give it a try.
I used GPT-5.5 XHigh in plan mode and gave the agent a much larger prompt for the same training-request app. I specified the stack, database, user spaces, core workflows, demo data, and verification expectations.
Here is the mega prompt if you are curious about it.
Full mega prompt
Build a local full-stack MVP for an internal training request platform.
Use:
- React + TypeScript + Vite for the frontend
- NestJS + TypeScript for the backend
- PostgreSQL with Prisma for persistence
- pnpm if you need a package manager
- Local development only; no production deployment
Goal:
Colleagues can request trainings, certifications, books, or AI subscriptions.
Office Management can review, assign, process, and update those requests.
Important constraint:
Do not create separate requirements.md, design.md, or tasks.md files before implementation.
Use this single prompt as the source of truth. You may create a README only for setup and run commands.
Users:
- Colleague users:
- Ala
- Sofia
- Office Management users:
- Meriem
- Omar
Authentication:
Do not implement real authentication.
Create a local-only persona selector on the first screen.
The selector is only a development shortcut.
It must not appear as the real product model inside the main app.
After choosing a persona, route the user into the correct workspace.
User spaces:
Colleague and Office Management must feel like separate workspaces, not one generic screen with a role switcher.
Colleague workspace:
- Create a new request
- See my requests
- See request status
- See request history/comments
- See renewable requests such as subscriptions or yearly certifications
- See linked accounts for AI subscriptions or learning platforms
Office Management workspace:
- See an operational queue of all requests
- Filter by status, type, requester, assignee, and priority
- Search by requester name or request title
- Assign a request to an Office Management user
- Change status
- Add comments
- See requester context
- See renewal-related requests clearly
- Use a board or queue view that feels useful for processing work
Request types:
- Training course
- Certification
- Book
- AI subscription
- Other
Request statuses:
- Draft
- Submitted
- In review
- Waiting for requester
- Approved
- Rejected
- Purchased
- Completed
- Cancelled
Request fields:
- id
- title
- type
- description
- business justification
- requester
- status
- priority
- estimated cost
- currency
- provider or vendor
- target date
- assignee
- created date
- updated date
- comments
- renewal flag
- renewal frequency if applicable
- linked account if applicable
Data model:
Use PostgreSQL and Prisma.
Do not use file-backed storage.
Seed the database with realistic demo data for both colleagues and Office Management.
Include enough data to make filters, statuses, renewals, and assignees visible.
API:
Create REST endpoints for:
- listing requests
- creating requests
- reading one request
- updating request status
- assigning requests
- adding comments
- listing renewable requests
- listing linked accounts
- health check
Frontend:
Make the UI clean, modern, and workflow-shaped.
Do not build a marketing landing page.
The first screen should be the persona selector.
After persona selection:
- colleagues should land in their own request area
- Office Management should land in the queue or board
Verification:
Before finishing, run the available checks.
At minimum:
- backend typecheck or build
- frontend typecheck or build
- Prisma migration or schema validation
- seed script
- API health check
- browser/manual verification of the main user flows if possible
Main flows to verify:
1. Select a colleague persona.
2. Create a request.
3. Confirm it appears under that colleague's requests.
4. Select an Office Management persona.
5. Confirm the request appears in the Office Management queue.
6. Assign the request.
7. Change its status.
8. Add a comment.
9. Go back as the colleague and confirm the status/comment are visible.
Output:
- Implement the app.
- Give me exact run commands.
- Tell me what checks passed.
- Tell me what you did not verify.
- List any assumptions you made.As you might have expected, the result was much better than the first prototype.
It had separate workspaces, a cleaner colleague view, and a more useful Office Management queue.
The bigger prompt helped, and it also showed the limit of the approach.
The agent still had to make decisions during the work: how to model persona selection, what status a new request should start with, how much verification was enough.
To be fair, most of those decisions were reasonable.
But reasonable is not the same as EXPLICIT. I want those decisions visible before the code is written, because building the right business behavior upfront is cheaper than changing the requirements and implementation later.
At that point, the problem was no longer how much detail I could fit into a prompt. The problem was where those decisions should live.
Then Where Should the Decisions Live?
This is where the spec enters the picture.
By spec, I do not mean a traditional document that nobody reads.
Spec definition: A spec is shared memory before implementation. It keeps the important decisions in one place: product intent, constraints, architecture choices, business rules, and checks.
This matters because the agent will keep moving. If the decisions live only inside a long prompt, they are easy to mix, miss, or forget. If they live in a spec, they can be reviewed before implementation and reused during the work.
A prompt tells the agent what to build. A spec keeps visible what the agent should not decide silently.
A Simple Spec Structure
A useful spec does not need to be one huge document.
For this series, I think about it as three small files:
requirements.md answers: what should the system do?
design.md answers: what decisions are already made?
tasks.md answers: how do we turn this into implementation steps?
The filenames are not important. What is important is the separation.
When everything lives in one prompt, intent, design decisions, constraints, shortcuts, and checks compete for attention. When they are separated, the agent has a clearer place to look for each type of decision.
Here is a simple example of a spec: one requirement, one design decision, and one task.
Requirement:
Colleagues can see only their own requests.
Design decision:
The local persona selector is only a development shortcut. It must not become the real user model.
Task:
Build the colleague request list and verify it only returns requests owned by the selected colleague.
Once the Decisions Are Visible
Once the decisions are visible, the agent can still move fast.
It can implement the request list, but not decide who can see which requests.
It can build the local persona selector, but not treat it as the real user model.
It can add checks, but not decide by itself what "working" means.
The engineer keeps ownership of the decisions. The agent gets clearer boundaries for the work.
The Spec Is Only the Start
At this point, the spec has a clear job.
It gives the work memory before implementation starts.
But having a spec is not the same as using it well.
The next problem is practical: how do we move from the spec to implementation without creating a slow process?
That is where tasks, checks, context management, and backpressure start to matter.