AI and agents18 min read

40 rules for an engineering approach to building a product with vibe coding

A digest of the lecture "From vibe coding to engineering": forty rules that turn an AI agent from a "build me an app" button into part of a working process.

40 rules for an engineering approach to building a product with vibe coding
Contents

This article is a digest of the lecture “From vibe coding to engineering”

Vibe coding can be a powerful tool if you use an AI agent not as a magic “build me an app” button but as an assistant inside a proper engineering process.

The main mistake is asking the AI to write code straight away. Code is only one stage of development. Before it there should be an idea, requirements, an architecture and a plan. After it come testing, security, refinement, release and support.

An engineering approach to vibe coding rests on simple logic: first understand what we’re making, then describe it, then break it into small manageable pieces, take each piece through a clear life cycle, and only after that consider the task done.

Below is a list of rules that help you build a product with AI in a more deliberate, safe and controlled way.

1. Start with the product problem, not with code

Before asking the AI to write code, you need to understand what exactly we’re building, for whom and what problem it solves.

The wrong way:

“Build me a CRM.”

The right way:

“We’re building a CRM for an HR agency so that recruiters can store candidates, see statuses, leave comments and track the communication history.”

The AI should understand the product goal, not just the technical action.

2. Gather the requirements first

A product idea isn’t yet a technical task. You need to describe the users, the scenarios, the constraints and the success criteria.

Example:

If we’re making an enquiry form, we need to decide in advance:

which fields there are;

which fields are required;

where the data is sent;

what the user sees after submitting;

what happens on an error;

which data must not be accepted.

Without requirements the AI will fill in the gaps itself.

3. Write the requirements down in a document

Don’t keep the requirements only in your head or in a chat thread. The AI can forget context, reconstruct it wrongly or start contradicting earlier decisions.

Example:

Create a PRD.md file that describes:

the product goal;

the audience;

the key scenarios;

the main features;

the constraints;

what’s in the first version;

what’s not in the first version.

A document like this becomes the single source of truth for you and the AI agent.

4. Use a spec-driven approach

A spec-driven approach means: specification first, then code.

A specification is the blueprint of the task. It explains to the AI what needs to be done, how it should work, what the constraints are and how to tell that the task is finished.

The wrong way:

“Build authentication.”

The right way:

“Build authentication with email and password. We need sign-up, sign-in, sign-out and protection for private pages. 2FA, password recovery and Google sign-in are out for now.”

The clearer the spec, the less the AI will guess.

5. Don’t ask the AI to build the whole app at once

A big task without boundaries almost always leads to chaos. The AI starts making too many decisions on its own, mixes up the levels of the system and can break what already works.

The wrong way:

“Build a marketplace.”

The right way:

“Start with the first vertical slice: the user sees a list of products, opens a product card and adds the product to the basket.”

One small finished piece is better than a huge unfinished foundation.

6. Work in vertical slices

A vertical slice is a small feature built from start to finish through every layer of the product.

Example:

For a CRM, the first vertical slice is creating a candidate.

It includes:

a form on the frontend;

data validation;

an API method;

a database write;

a success message;

error handling;

a basic check of the result.

A piece like this can be tested, shown to a user and improved further.

7. Don’t build a huge foundation before testing the hypothesis

At the MVP stage you don’t need to build a perfect architecture for years ahead straight away. First you need to check whether users need the feature at all.

Example:

For an HR CRM you don’t need complex analytics, roles, or integrations with email, calendar, Telegram and HH.ru right away.

At first it’s enough to test the basic scenario: a recruiter can add a candidate, change the status and leave a comment.

8. But even an MVP shouldn’t be a chaotic dump

An MVP can be simple, but it shouldn’t be thoughtless.

Fast doesn’t mean without structure.

Example:

You can skip a complex reporting module, but you still need to:

understand the data structure;

keep secrets out of the code;

validate forms;

separate the UI from the business logic;

record architectural decisions.

Otherwise the MVP will quickly become a product that can’t be developed any further.

9. Write an architecture document before the code

The architecture explains which parts the system consists of and who is responsible for what.

An example ARCHITECTURE.md file:

frontend: Next.js;

backend: API routes;

database: Supabase;

UI components live in /components;

data schemas live in /schemas;

business logic lives in /services;

database access must not sit inside UI components.

A document like this helps the AI avoid putting code in random places.

10. Separate the responsibilities of components

Each part of the system should be responsible for its own job.

The wrong way:

A React component shows the form, validates the data, checks permissions, queries the database and applies the business rules, all at once.

The right way:

the UI component shows the interface;

the schema validates the data;

the service holds the business logic;

the API handles the exchange between client and server;

the database layer handles working with the database.

That way the project is easier to understand, test and develop.

11. Explain the architectural boundaries to the AI

The AI shouldn’t decide by itself where to put code and which parts of the project to change. The boundaries need to be set explicitly.

Example request:

“Don’t add business logic to UI components. Move validation into /schemas/candidate.ts and database access into /services/candidates.ts. Don’t change authentication or the database structure.”

The more precise the boundaries, the fewer accidental breakages.

12. Use a lifecycle for every feature

A feature shouldn’t begin and end with code generation. It should have a life cycle.

A good lifecycle:

context check: understand the context;

scope: define the boundaries of the task;

plan: draw up a plan;

components: identify the affected parts;

implement: build it;

verify: check it;

test: test it;

review: do a review;

document: update the documentation;

close: close the task.

Example:

Before the task “create a candidate card”, ask the AI:

“First check the project context, define the scope and propose a plan. Don’t write any code yet.”

13. Don’t let the AI write code before there’s a plan

If the AI jumps straight into code, it may solve the task the wrong way. First it should show that it has understood the task.

Example prompt:

“First draw up an implementation plan. List the files you’ll change and why. Then stop and wait for confirmation. Don’t write any code yet.”

This helps you avoid the situation where the agent rewrites things it shouldn’t or heads off in the wrong direction.

14. Introduce a Definition of Done

A Definition of Done is a list of conditions under which a task counts as finished.

Without it, the AI may say “done” when in fact the feature only partly works.

An example Definition of Done for an enquiry form:

the form displays on desktop and mobile;

required fields are validated;

the email is checked for correctness;

the data is sent to the server;

after a successful submission the user sees a confirmation;

on an error the user sees a clear message;

secrets don’t end up in the frontend;

the changes don’t break existing pages.

The task is done only when every item is met.

15. Don’t trust the word “done”

The AI can confidently say that everything is done, but that doesn’t mean the task is actually finished.

Example request after implementation:

“Check the result against the Definition of Done. Separately state which items you can confirm and which can’t be checked without running the project.”

That way the AI won’t paper over uncertainty.

16. Use FSM logic: don’t skip stages

An FSM is a finite state machine. Put simply, it’s a process where you can’t move to the next step until the current one is closed.

Example:

no writing code until the scope is agreed;

no closing the task until the check has passed;

no release until the secrets have been checked;

no changing the architecture without a separate decision.

This approach protects you from chaotic jumps between tasks.

17. Keep the AI in one mode at a time

There’s no need to ask the AI to be a product manager, architect, designer, developer, tester and security specialist all at once.

It’s better to separate the roles.

Example:

first: “You’re a product analyst, clarify the requirements”;

then: “You’re an architect, propose a structure”;

then: “You’re a developer, implement the first slice”;

then: “You’re a reviewer, check the code for risks”.

That way the AI works more precisely.

18. Anything that can be automated shouldn’t be left to the AI’s discretion

AI is a probabilistic system. For strict checks it’s better to use deterministic tools.

Example:

bad: “Claude, check whether there are any type errors”;

good: run npm run typecheck;

bad: “AI, see whether the code is formatted properly”;

good: run npm run lint.

AI is useful for analysing errors, but the checks themselves are better done with tests, linters, type checking and scripts.

19. Ask the AI to explain its changes

After implementation the AI should explain what it changed, why, and what risks have appeared.

Example request:

“Give me a changelog: which files were changed, why, what the potential risks are, and what needs to be checked by hand.”

This helps you keep control of the project.

20. Limit the area of change

The AI shouldn’t rewrite half the project for the sake of a small task.

Example:

“Solve the task only within /components/CandidateForm.tsx and /schemas/candidate.ts. Don’t change authentication, routing or the database structure without separate agreement.”

The smaller the area of change, the easier it is to check the result.

21. Don’t let the AI “refactor everything” without a reason

Refactoring should solve a specific problem. Otherwise it can turn into chaotic rewriting of working code.

The wrong way:

“Improve the project.”

The right way:

“Remove the duplication in error handling in these three API methods without changing the public API contract.”

Refactoring should have a goal and boundaries.

22. Data should have a contract

A DTO, Data Transfer Object, is a description of the shape of the data passed between parts of the system.

An example candidate DTO:

id;

name;

email;

phone;

status;

source;

createdAt.

If the contract isn’t described, the AI may call the field name in one place, fullName in another and candidateName in a third.

A data contract protects the project from sprawl.

23. Validate incoming data

You can’t trust data that comes from the user, the frontend or an external API.

Example:

If the user submits an email, the server should check that it really is an email.

If a candidate’s status can only be new, screening, interview, offer or rejected, the server shouldn’t accept an arbitrary string.

Validation is the basic safeguard of data quality.

24. Use zod or similar schemas

Zod helps you describe a data schema and check it while the application is running.

Example:

Before a candidate is saved to the database, the object goes through candidateSchema.

If the data is correct, we save it.

If the data is broken, we return an error.

Zod works like a bouncer at the entrance to the system.

25. Don’t trust even your own frontend

Even if the form on the site checks the fields, the server still has to check them again.

Why?

The user can tamper with the request;

the frontend can break;

a bot can send data directly;

an external service can return an unexpected format.

Example:

The frontend form won’t let you submit an empty email. But the server must still check the email again.

26. Secrets must not end up in the code

API keys, tokens, passwords and private data must not be stored in the code or committed to the repository.

Bad:

const API_KEY = "sk_live_..."

Good:

process.env.PAYMENT_API_KEY

Secrets should be kept in environment variables or dedicated secret stores.

27. Don’t send real secrets to an AI chat

The AI can help with setup, but it doesn’t need your real keys, passwords and tokens.

Bad:

“Here’s my real API key, help me set up payments.”

Good:

PAYMENT_API_KEY=[REDACTED_SECRET]

or

PAYMENT_API_KEY=your_key_here

Give the AI the structure, not the real secrets.

28. Don’t write your own cryptography and authentication unless you have to

Authentication, passwords, tokens and cryptography are a high-risk zone.

The wrong way:

“AI, write me my own password storage system.”

The right way:

Use a proven solution: Supabase Auth, Firebase Auth, Clerk, Auth0, OAuth or another mature service.

Security is a bad place for amateur improvisation.

29. Turn on basic security from the very start

Security shouldn’t appear only just before release.

The minimum right from the start:

don’t commit .env;

turn on 2FA on GitHub;

validate forms;

don’t store passwords in plain text;

limit access;

don’t give the AI unnecessary permissions;

don’t use unknown dependencies without checking them.

Example:

Even if it’s an MVP, secrets still shouldn’t sit in the repository.

30. Assess risk on three axes

Risk can be assessed with three questions:

what is the attack surface;

what is the possible damage;

how likely is an attack.

Example:

A notes app for yourself and a payment service need different levels of protection.

In the first case a mistake is annoying.

In the second it can lead to lost money, a data leak and legal consequences.

31. Separate devsec from prodsec

Devsec is the security of development.

Prodsec is the security of the running product.

Examples of devsec:

don’t store tokens in GitHub;

turn on 2FA;

limit access;

check dependencies.

Examples of prodsec:

a user mustn’t see other people’s submissions;

data must be validated;

authentication must work correctly;

personal data must be stored securely.

Both zones matter.

32. Don’t put critical products into production without an audit

If a product involves payments, medicine, finance, personal data or legally significant processes, AI-written code isn’t enough.

Example:

AI can help put together an MVP of a payment form. But before real payments you need an engineering audit: security, data storage, errors, access, compliance.

The higher the cost of a mistake, the less you can rely on “seems to work”.

33. Set up logs and monitoring, at least at a basic level

After release you need to understand what’s happening in the product.

Example:

A user says: “The form won’t submit.”

Without logs you don’t know what happened.

With logs you can work out whether it’s:

a validation error;

the API being unavailable;

the database not responding;

an external service returning an error;

an environment variable not being set.

Monitoring turns “something broke” into a specific task.

34. Separate “works on my machine” from “ready for users”

The fact that the project runs locally doesn’t yet mean it’s ready for real users.

Example:

Locally the form works, but in production:

an environment variable is missing;

the mobile version is broken;

errors aren’t logged;

the database rejects some of the data;

the user sees a technical error.

Readiness isn’t just a local run.

35. Document decisions as you go

Documentation isn’t there for looks; it’s there so the project doesn’t lose its memory.

Example:

If you’ve decided that a candidate’s status can only be:

new;

screening;

interview;

offer;

rejected;

this needs to be written down in the documentation and in the data schema.

A month from now, the AI shouldn’t invent a new system of statuses.

36. Update the project context after every feature

If the architecture, the API, the data structure or the rules have changed, this needs to be recorded.

Example:

We added a source field to the candidate.

We need to update:

the data schema;

the API documentation;

the model description;

the form;

the validation;

the tests, if there are any.

Otherwise the next task will be built on outdated context.

37. Ask the AI to flag doubtful spots explicitly

The AI shouldn’t confidently paper over uncertainty.

Example prompt:

“If there isn’t enough information for the solution, don’t make things up. Separately list the questions, the assumptions and the places that need checking by a human.”

This is especially important in architecture, security and integrations.

38. Don’t adopt architectural decisions just because the AI suggested them

The AI can propose a solution that sounds convincing but doesn’t fit.

Example:

The AI suggests microservices for a small MVP.

Before agreeing, you need to ask:

what problem does this solve;

what does it cost to maintain;

can it be done more simply;

are we creating unnecessary complexity;

who is going to look after it.

The decision is made by a human, not by the model.

39. Use AI to amplify your competence, not to replace your responsibility

AI can explain, suggest and help implement. But responsibility for the product stays with the human.

Example:

You can ask the AI to explain how authentication works. But if the product stores customer data, responsibility for a secure implementation is still yours.

AI helps you think, but it isn’t answerable for the consequences.

40. Think not only about building, but about maintaining

A product doesn’t end after the first round of code generation. It has to be fixed, extended, supported and handed over to other people.

Example:

If a developer joins tomorrow, they should be able to understand:

how the project is structured;

where the documentation is;

what data schemas there are;

which decisions have already been made;

how to run the project;

where to look for errors;

which parts mustn’t be changed without care.

If after 200 AI iterations the project is impossible to understand, the process was bad.

A short formula for engineering-minded vibe coding

Don’t ask the AI to “build a product”.

First:

describe the product;

gather the requirements;

pin down the specification;

set the architecture;

break the product into small vertical slices;

use a lifecycle for every feature;

don’t write code before there’s a plan;

introduce a Definition of Done;

check the result;

think about security;

document decisions;

update the project context.

Only after that can the task be considered done in an engineering sense.

The main takeaway

Vibe coding becomes dangerous not because AI is bad. It becomes dangerous when a person hands the AI a task without boundaries, requirements, architecture or checks.

The mature approach looks different:

“Here’s the product context. Here are the requirements. Here’s the architecture. Here are the constraints. Here’s the task. Here are the criteria for done. First check the context, then propose a plan, then implement the agreed slice, then check the result and update the documentation.”

That way AI becomes not a chaotic code generator but an assistant inside an engineering process.

Separately, on how to brief a model so it doesn’t have to guess: prompt engineering according to OpenAI and Anthropic.

Your people nearbyAsk your own crowd — the chat answers faster than searchThe main chat of IT Party Pattaya: IT people, digital professionals and entrepreneurs who have already been through the same thing. Since July 2023. The chat is in Russian.Join the chat (in Russian)Need baht?Roubles and USDT to baht — inside the communityIT OBMEN has been running since 2023: roubles from any Russian bank or via SBP, USDT from Bybit and Binance. Cash delivered across Pattaya, a transfer to a Thai account or a withdrawal at an ATM. The rate is updated daily. Site in Russian.Terms and rate (in Russian)

Related reading