Most PRD generators hand you a document. The document is fine. Then your coding agent builds the database anyway β and three days later the tables don't match the document, the API payloads changed shape twice, and nobody wrote the security rules down.
I wanted to see what the output looks like when the spec, the schema, the contracts and the agent rules are generated together and actually agree with each other. So here is one full worked example, end to end. The product is fictional β a stock list app for small shop owners in Bangladesh β but every excerpt below is from the real sample suite that ships with the generator's free template.
A stock list app for small shop owners in Bangladesh that replaces the paper stock notebook, works offline-first on cheap Android phones, and understands products by name, not codes.
That's it. That is the whole brief.
The PRD turns that sentence into decisions a builder can test. It names the problem with evidence marked as what it is β the sample is honest that its interview numbers are example data:
Problem: shop owners track stock in paper notebooks; when a notebook is lost or a helper sells from memory, stock counts drift and reordering is guesswork.
Evidence (example data): 6 of 8 owners interviewed said they discovered a stock-out only when a customer asked.
Then goals with a measure attached ("Owners trust the count β weekly count-vs-app spot checks that match β 90% match by week 4"), two roles with a hard boundary (staff can record sales and stock-in, but must never change prices or delete products; an owner must never see another shop's data), and numbered requirements, each with an acceptance check:
Edge cases are written down before code exists: stock hitting exactly 0 (shows "Out of stock", stays visible), two staff selling the same product at the same time (counts must not go negative; the second sale is re-checked against the fresh count), and a new user with no products (one clear action β "Add your first product").
The PRD says what must happen; the UI spec says what the user sees. The product list, the sale flow, the offline "not yet synced" state from Journey 1, the out-of-stock state, the empty state β each screen with its states and what each button does, so the agent doesn't invent a layout that contradicts the requirements. (The full spec is in the sample suite linked below.)
This is the file a prose PRD never produces, and the one that matters most. Four tables:
create table public.shops ( ... );
create table public.shop_members ( ... );
create table public.products ( ... );
create table public.stock_movements ( ... );
Multi-tenancy is in the schema on day one, not patched later. Row Level Security is enabled on every table, and every policy uses the same helper rule β "the current user is a member of the shop this row belongs to":
create policy "members manage their shop products"
on public.products for all
using (exists (select 1 from public.shop_members m
where m.shop_id = products.shop_id and m.user_id = auth.uid()))
with check (exists (select 1 from public.shop_members m
where m.shop_id = products.shop_id and m.user_id = auth.uid()));
The API contracts are agreed before code exists, and each one points back to the requirement it implements:
POST /api/products β create a product (FR-1)
Auth: shop member (owner or staff); price changes: owner only (FR-4)
Request: { shopId: uuid, name: string (1β120), price: number β₯ 0, stock: integer β₯ 0 }
Success: 201 β { id, shopId, name, price, stock, createdAt }
Errors: 403 β not a member of this shop Β· 422 β validation failed
js
const CreateProduct = z.object({
shopId: z.string().uuid(),
name: z.string().min(1).max(120),
price: z.number().nonnegative(),
stock: z.number().int().nonnegative(),
});
POST /api/sales β record a sale (FR-2, FR-3)
Request: { productId: uuid, quantity: integer β₯ 1 }
Success: 200 β { productId, newStock }
Errors: 409 β quantity exceeds current stock (stock is never allowed to go negative)
Note what the 409 does: the "never go negative" rule from FR-3 lives in the contract, not just in prose. And the list endpoint says explicitly that RLS enforces the same rule at the database layer β the API and the schema are saying the same thing.
The last file is the one you paste into .cursor/rules or CLAUDE.md. The sample's rules are short and strict:
shops, shop_members, products, stock_movements). Never invent a column or relationship.
Rule 8 is the one I care about most. A coding agent that invents a table name is a bug you find in week two. An agent that quietly picks one side of a contradiction is a bug you find in production.
Before handing any generated suite to an agent, run this agreement test β it takes two minutes:
If a suite passes that test, the agent has very little room to improvise. If it fails, fix the spec, not the code.
The full ShopStock sample suite β all four files β is free in the template repo: https://github.com/web-dev-mehedi/ai-prd-template
And the generator that produced this shape of output is live, with 50 free credits on signup and plans from ΰ§³99/month (bKash/Nagad): https://webdevmehedi.com/ai-prd-generator
What do you hand your coding agent before a build β a document, or a contract? Genuinely curious what other people's specs look like.