Lovable is very good at turning a description into a working web application quickly. That makes it useful for prototypes, internal experiments, landing pages, and validating whether an idea deserves further investment.

But working software is not automatically production-ready software.

Generated code may contain missing or overly broad authorisation rules, frontend-only validation, exposed configuration, weak error handling, duplicated logic, and dependencies nobody has reviewed. Lovable has built-in security scanning, but its own documentation says those tools do not replace a thorough security review.

Our recommendation is simple: do not publish Lovable-generated code unchanged for a system that handles sensitive data, payments, regulated workflows, or business-critical operations. If Lovable is the only practical way to get started, treat its output as a first draft and put engineering guardrails around it.

Give Lovable Persistent Project Context

Repeated prompting is fragile. The agent may follow a rule in one conversation and forget it in the next. A root-level AGENTS.md gives Lovable persistent instructions about how your codebase should work. Lovable officially supports repository instruction files and says a root-level AGENTS.md is always read by its agent.

The best instructions are specific, short, and testable. “Write clean code” is not useful. “All tables containing user data must enable RLS, and policies must restrict access by user_id or organisation_id” gives the agent something it can act on and a reviewer something they can verify.

Here is a practical starting point:

# AGENTS.md

## Project
- This is a production web application built with TypeScript, React, and Supabase.
- Prefer small, reviewable changes. Do not rewrite unrelated code.
- Before changing architecture or adding a dependency, explain why it is needed.

## Naming conventions
- React components and their files use PascalCase: `AccountSettings.tsx`.
- Hooks use camelCase and start with `use`: `useCurrentUser.ts`.
- Functions and variables use camelCase. Constants use UPPER_SNAKE_CASE.
- Database tables and columns use snake_case and plural table names.
- Use domain names such as `subscription` or `organisation`; avoid vague names
  such as `data`, `item`, `helper`, and `utils`.

## TypeScript and application structure
- Keep TypeScript strict. Do not use `any`; use `unknown` and narrow it safely.
- Keep UI components presentational. Put data access in dedicated services/hooks.
- Share business rules from one domain module; do not duplicate them in pages.
- Validate every external input with a schema at the server boundary.
- Return typed, structured errors. Do not expose stack traces or internal details.

## Database and Edge Functions
- Treat the browser as untrusted. Never enforce security only in the UI.
- Enable Row Level Security on every table exposed through the API.
- Default to deny. Policies must explicitly scope access to the authenticated user
  or organisation. Never add a permissive policy just to make a query work.
- Put privileged operations, third-party API calls, payment logic, and shared
  business rules in server-side Edge Functions.
- Edge Functions must authenticate the caller, authorise the action, validate the
  payload, handle expected failures, and avoid logging secrets or personal data.
- Use migrations for schema and policy changes. Never edit production data manually.
- Make retryable writes idempotent and use transactions for multi-step changes.

## Environment variables and secrets
- Never hardcode credentials, tokens, private URLs, or service-role keys.
- Frontend variables are public. Only expose explicitly public values there.
- Keep secrets in the platform secret store and read them only server-side.
- Maintain `.env.example` with placeholder values and a short description.
- Do not commit `.env`, production credentials, or real customer data.
- Fail fast with a clear error when a required environment variable is missing.

## Security
- Use server-side authorisation for every protected operation.
- Do not render unsanitised HTML or build SQL from string concatenation.
- Apply rate limits to authentication, public forms, and expensive endpoints.
- Use least-privilege credentials and minimise collection of personal data.
- Do not weaken RLS, CORS, authentication, validation, or security headers to fix
  a development error.
- Run Lovable's security scans after material changes and before every release.

## Quality gates
- Add or update tests for changed behaviour, including failure and permission cases.
- Run type-checking, linting, tests, and a production build before completion.
- Keep dependencies minimal and run an audit when dependencies change.
- Report what changed, which checks ran, and any remaining risks.

Adapt that file to the project. Document the real schema, roles, architecture, deployment process, and commands. An incorrect instruction repeated consistently is still incorrect.

Keep Security Decisions Out of the Browser

Frontend code is delivered to the user. They can inspect it, modify it, and bypass its controls. Hiding an admin button is not authorisation; checking a form in React is not server-side validation; an environment variable bundled into the frontend is not a secret.

For a typical Lovable application, the secure boundary should be clear:

This defence in depth matters because any one layer can be wrong. In particular, never use a Supabase service-role key in browser code. It bypasses RLS and belongs only in a trusted server-side environment.

Make Database Rules Explicit

Generated applications often evolve table by table. Without a documented model, naming drifts, relationships become ambiguous, and access policies are added reactively when a query fails.

Add a compact database section to AGENTS.md that lists the important tables, ownership model, and roles. For example:

## Data model
- `organisations`: owned collectively by organisation members.
- `organisation_members`: joins users to organisations and stores their role.
- `projects`: belongs to one organisation through `organisation_id`.
- `invoices`: readable by organisation admins; writable only by server functions.

Roles: `member`, `admin`, `owner`. Do not introduce new role strings.
All organisation-scoped queries and RLS policies use the authenticated user's
membership. A URL parameter alone never proves access.

Then test the negative cases: a user from another organisation, an unauthenticated request, a member attempting an admin action, and a request with a guessed record ID. Permission tests are more valuable than a happy-path demo.

Treat Environment Variables as an Interface

Configuration deserves the same discipline as code. Keep an .env.example, classify each variable as public or server-only, validate required values at startup, and document which service owns each secret.

Names such as VITE_* or PUBLIC_* usually signal that a value will be included in browser code. That is appropriate for a public API URL or publishable key—not a private API token. Moving a secret into a frontend environment variable does not protect it.

Use separate credentials for development, preview, and production. Give each credential the minimum permissions it needs, rotate it when exposure is suspected, and never paste real secrets into prompts, source files, screenshots, or issue descriptions.

Add Quality Gates the Agent Cannot Negotiate Away

AGENTS.md improves the agent's decisions, but it is guidance, not enforcement. Put objective checks in CI:

Run Lovable's RLS, database, dependency, and code-security scans too. Resolve critical findings before publishing, then arrange an independent review when the application's risk warrants it. A green scanner is evidence, not a guarantee.

Before production, verify:

  • No secret or service-role key reaches the browser.
  • Every sensitive action is authenticated and authorised server-side.
  • RLS is enabled and tested for both allowed and denied access.
  • Inputs are validated at trust boundaries.
  • Logs exclude credentials and unnecessary personal data.
  • Backups, monitoring, alerts, rollback, and incident ownership exist.
  • A human has reviewed the generated code and deployment configuration.

Use Lovable for Speed, Then Apply Engineering

Lovable can shorten the path from idea to useful prototype. It cannot decide your acceptable risk, understand every implicit business rule, or own the consequences of a production incident.

The practical approach is not to reject generated code automatically. It is to make generated code earn its way into production through explicit architecture, persistent instructions, automated checks, adversarial testing, and accountable human review.

We are publishing reusable Lovable guidance—including an AGENTS.md starter and supporting skills—in our public GitHub repository. Download it, adapt it to your application, and keep it updated as the system changes. The file is a starting point, not a substitute for understanding the code you ship.

Need to turn an AI-generated prototype into reliable software?

We can review the architecture, security, and code, then help your team create a safe path to production.

hello@boringai.tech

No pitch deck, no obligation. If AI is the wrong answer for your problem, we'll tell you that too. Not ready for a call? Send us a message instead.