WP-03 · Grounded generation
Pages without lies: grounding generated web pages in the owner's own words
Abstract. Generative page builders fail small businesses in a specific way: the output is fluent, plausible and wrong. It invents review counts, years in business, partner logos and "trusted by" figures, and it converges on the same anonymous layout for every trade. I describe a constrained generation pipeline that treats the owner's own words as the only admissible source of facts. A pre-generation completeness gate converts missing inputs into questions. A declarative rule layer forbids unsourced entities, numerals and known layout clichés. A post-render audit diffs every figure and proper noun on the rendered page against a verbatim record of what the owner said, and walks the DOM for structural violations. A multimodal critic scores full-page desktop and phone captures on ten lines, with the overall score defined as the minimum, inside a repair loop bounded at three rounds. I report the design, the measured cost per critique round, the test evidence and the failure modes that remain.
1. The failure mode
A language model asked for "a website for a pizzeria in Mineola" has no access to the facts that make a local business page useful: the real hours, the real phone number, the dish people actually drive for, the year the owner opened, if the owner wants to say it at all. It does have a strong prior over what such pages usually contain. Left alone, it fills every gap from that prior. The result is a page that reads well and asserts things nobody said: "4.9 stars from 187 reviews", "serving the community since 1998", three icon cards, a stats row, a testimonial from a customer who does not exist.
Two properties make this worse for small businesses than for software companies. First, the owner is the only source of truth and is usually reached by text, so every invented fact either goes unnoticed or costs a round trip to correct. Second, the cost of a false claim on a local business page is real: a wrong price, a phantom discount or an invented review is a consumer protection problem, not a styling problem.
A design report assembled on 2026-10-22 from 61 sources summarized the pages the system was producing at the time as "anonymous, not ugly". The layout was competent and indistinguishable from any other trade's page. The same week, an internal review of an early insurance agency page found an invented "coverage at a glance" card, pill badges, eyebrow labels, a stat row and "call to confirm" hours. The pipeline described here is the response.
2. Threat model for a generated page
I treat the builder model as a capable but untrusted author. Its outputs are checked against an explicit model of what may appear on the page and where each claim came from. The failure classes fall into four groups:
- Fabrication. Numbers, prices, percents, "N+" figures, years in business, customer counts, ratings, reviews, testimonials, awards, and named carriers, partners, suppliers or logos that the owner never supplied. This includes self-counting numbers such as "6 services" or "2 states", which are technically true of the page and meaningless to a customer.
- Genericity. Headlines a competitor could paste onto their own site unchanged, banned stock phrases ("peace of mind", "tailored to your needs", "seamless", "solutions"), repeated taglines, and software-marketing structure on a local business page.
- Structural clichés. More than one card grid, three equal icon cards, stats rows, "at a glance" boxes that repeat the header, two consecutive sections with the same layout, everything centered, pill badges and eyebrow labels, gradient glows.
- Functional dishonesty. Buttons that go nowhere, "coming soon" features, edit links or logins that do not exist, hours given as "call to confirm", contact details that do not match the owner's number, scripts that throw, and layouts that scroll sideways on a phone.
Each class is assigned to the earliest layer that can see it. Most are covered twice: once by an instruction the builder is told to obey, and once by a measurement taken after the page exists. Fig. 1 shows the coverage.
Fig. 1 · Defense in depth
3. Layer 0: the completeness gate
Before any design work, the builder checks whether it has five inputs, each in the owner's own words:
- what the business does and for whom, in one or two sentences;
- the services or products the owner wants on the page, as a list;
- one reason a customer picks this business over the one down the street, as a sentence the owner said;
- phone, address and real hours;
- at least one photo, or an explicit "no photo yet".
The gate has two thresholds. With one input missing, the builder proceeds with what is real, omits the gap from the page and lists the missing item as a question in its summary. With two or more missing, it does not build at all: it returns the questions only, and the assistant asks the owner. Requests with a higher blast radius, such as a rebuild of an existing site, a custom domain or more than six services, trigger a fixed set of five numbered questions before anything is generated.
The design principle is stated in the routine itself: a page with real content and no design beats a designed page with made-up content. The gate makes that trade explicit and moves the cost of missing information to the cheapest point in the pipeline, a single text message, instead of a correction after the owner has already seen a wrong page.
4. Layer 1: the rule layer
The build routine (version 2.0.0, rewritten on 2026-10-22) opens with hard rules written as short imperatives, placed before any procedural step so they dominate the builder's context. They encode the threat model directly:
- Provenance. No number, price, discount, percent, "N+", year, customer count, carrier, partner, supplier, award, rating, review, testimonial or logo unless the owner said it. Missing facts become questions, never filler.
- Structure. At most six sections, chosen from hero, what we do, proof, about the owner, how to reach us and footer, and cut when there is no real content for them. Cards in at most one section and only for truly parallel items such as a menu. No stats row, no "at a glance" box, no two consecutive sections with the same layout. Under 3,000 px tall at desktop width unless the owner supplied a lot.
- Typography and color. Two typefaces at most, with common system and default faces banned for headings. A five-step type scale with a named ratio, body text at 17 to 19 px, line length under 75 characters, an 8 px spacing scale. One accent color, used only for buttons and links. Every color is a role-named CSS variable on the root, so a new look or the owner's logo colors can be applied later without touching structure.
- Imagery. Owner photos first, placed in an image element with real alt text, resized and stripped of location data. With no photo, a type-only hero, recorded as an explicit decision so later checks do not penalize it. Licensed local stock only when a key for it exists, never a stock stranger standing in for staff, and never generated people, places, products or storefronts.
- Language. A short banned-phrase list, no long dashes, the tagline said at most twice, real hours or none. Every heading is tested against a single question: could a competitor across town paste it onto their site unchanged? If yes, it is rewritten with something only this business can say.
- Function. Every button and link works. No "coming soon", no fake features, no edit links or logins that do not exist. Contact details go in exactly as given, and every telephone and text link is checked against the owner's number.
Before writing markup, the builder produces a design specification next to the page: a section list with one job and one layout per section, the two faces, the type scale, the spacing scale, the four color roles, and where each photo goes. Only sections on that list may be built. The specification is later handed to the critic, so the plan and the result can be compared.
Rules alone are not sufficient. A model that has been told not to invent numbers will still, occasionally, invent numbers. The remaining layers exist because the rule layer is a prior, not a guarantee.
5. Layer 2: the post-render audit
The finishing check runs after the page is written and served. It is deterministic and does not use a language model. It opens the page in a headless browser, scrolls to the bottom so that scroll-triggered reveals have completed, and takes full-page captures at desktop width and at 390 px. It then runs three families of checks.
Runtime checks. Script errors in the console, sideways scroll at phone width, entrance-animation budget (one hero entrance plus one staggered list), long-running animations, buttons and links with no real target, and the presence of the owner-editable region markers described in section 8.
Structural checks, by DOM walk. A single evaluation inside the page returns card grids, stats rows, centered headings outside the hero, the typefaces actually in use, the heading face, gradients, box and button corner radii, the image count and the page height. These map one to one onto the structural rules, so a violation is a measurement, not an opinion.
Provenance checks, by diff. The owner's own messages about the business are copied verbatim into a known-file, never augmented with details the builder filled in. The audit extracts every number, price, percent and "N+" figure from the rendered text and flags any that does not occur in the known-file. It applies the same test to company names, using a short list of insurers and suppliers plus a capitalized-phrase pattern ending in Insurance, Group, Inc, LLC, Mutual or Financial. It also flags "call to confirm" hours, middle dots between facts, arrows at the end of links, banned phrases, repeated lines, and any page with no image that was not explicitly marked as type-only.
unsourced(page) = { x in numerals(page) ∪ entities(page) : x not in known_file }
deliver(page) ⇐ unsourced(page) = ∅ ∧ structural_violations(page) = ∅ ∧ critic(page) ≥ 7
Findings are graded. FIX lines block delivery. NOTE lines are reported but do not block: two-digit numbers, a styled word inside the headline and a page taller than 3,000 px are NOTEs, because each has legitimate uses. When the DOM walk itself fails, the audit says so in a NOTE and those rules are skipped rather than silently passed.
Fig. 2 · Grounding data flow
6. Layer 3: the multimodal critic
Some failures are not mechanically detectable. Whether a headline is generic, whether the first phone screen shows what the business is, whether the page sounds like the person who runs it: these need a reader. The critic is a separate, fast multimodal model that receives both full-page captures, the design specification and the known-file, and is instructed to judge the page as the owner would on a phone in five seconds: bluntly, specifically, without praise.
It scores ten lines from 0 to 10:
- Specific. Could a competitor paste the headline and first section onto their site unchanged?
- Real. Is there a real person, place or piece of work above the fold?
- Honest. Any invented numbers, prices, partners, reviews or stats, judged against the owner's words?
- Layout variety. Repeated consecutive layouts, or more than one card grid?
- Centered and badged. Everything centered, pill badges, eyebrow labels, icon squares, stat rows, a highlighted headline word?
- Type. Two faces at most, a clear scale, left-aligned, readable on the phone capture without zoom?
- Color. One accent, buttons and links only, no gradients or glow?
- Length. Does every section earn its place?
- Phone. Is the first 390 px screen the business name, what it does and a call or text button, with nothing cut off?
- Owner voice. A person who runs this business, or software marketing?
The overall score is the minimum of the ten, not the mean. This is deliberate: a page that is beautiful and contains one invented review is not a 9, it is a page that cannot ship. The critic returns the score, up to five concrete FIX lines naming what to change and where, and exactly one KEEP line naming the single best element, so that repair does not destroy what already works. Two context rules are appended: a page explicitly marked as type-only scores 7 on the photo line when the hero is clean type, and the yellow markers that flag sample content for the owner are not to be judged as design.
The critic runs on infrastructure configured for zero data retention, with hidden reasoning disabled. That last setting is operational, not stylistic: with images attached and reasoning enabled, the critic spent its entire 500-token budget on hidden reasoning and returned no text, a failure reproduced twice before the setting was changed.
7. The bounded repair loop
The builder runs the finishing check itself, in the same shell, after writing the page. If the check prints FIX or MISSING lines, the builder must fix every one and run it again, or explain in one line why the owner's own words require the flagged element. It may not argue with the critic. It must preserve whatever the KEEP line names.
Fig. 3 · Repair loop
Three properties keep the loop well behaved:
- Bounded. At most three critic rounds per page, counted per page in a tries directory shared by the audit and the critic. After the third round, the page is delivered with the remaining issues listed for the owner, instead of looping indefinitely or failing silently.
- Fail-open on the critic, fail-closed on the audit. If the critic cannot run (no key, timeout, malformed output), it exits with a distinct code and the pipeline continues on the deterministic checks alone. The audit never depends on a network call.
- Observable. Each round writes a JSON record of score, fixes, keep line and cost next to the capture, plus a per-round copy. An earlier version overwrote rounds one and two before they could be read; per-round copies were added to fix that.
Only when the page is clean, or the round cap is reached, does the check create the owner's edit link and form and produce the single line the assistant texts to the owner. A no-text marker exists for tests so that test runs never message anyone.
8. Owner-editable regions
Grounding is not a one-time property. Hours change, specials change, prices change. Rather than regenerate the page, the builder marks the regions the owner will update as typed, editable spans: a single value (for example hours), or a list whose direct children are items with named fields (name, description, price, time, day, note). At least three such regions are required, only for content the owner will really change, and never for contact details or legal text. Marked text stays plain, with no links or bold inside, so edits cannot break markup.
From those marks the finishing check generates a private edit form. Edits write back into the same spans, so the page's structure, typography and contact details are outside the owner's edit surface and outside the model's reach after delivery. Sample content that still needs the owner's confirmation stays highlighted in yellow until the owner replaces it.
Fig. 4 · Worked example, test business with made-up details

4a The rebuilt page after the rule rewrite: type-only hero in the owner's words, left-aligned, one accent, a plain list instead of cards, no invented figures.

4b The edit form generated from the marked regions. The owner changes specials and prices; layout and contact details are not editable here.
9. Evidence
All runs below were on a non-client test server, with the no-text marker present so no owner was messaged.
Before the rewrite. A third rebuild of an insurance agency page, built from a one-line request with no owner facts, failed try one of three. The audit fired on a 25-second animation, numbers absent from the owner's words (two phone numbers, a street number and a ZIP code, because the request contained none of them), "call to confirm" hours, an arrow at a link end, two banned phrases, eight entrance effects plus two stagger groups, no photo, five pill buttons and corner radii of 999, 22 and 14 px. The DOM walk found one six-card grid. The critic scored it 2 and named a fake summary card, no real photo, a generic headline, badges and a stat row, and the card grid; it kept the call button under the headline on mobile.
After the rewrite. A test pizzeria page built end to end through the assistant, with no owner photo, produced a type-only hero in the owner's words, left-aligned, no pill badges or eyebrows, no icon squares, no card grid, no stats row, no invented numbers or partners, one accent on the call button only, two faces, a plain list for the menu and an address block with a map link, at about 1,900 px tall. On re-run after the type-only and sample-marker fixes, the critic scored it 3 and named exactly the three remaining problems a human reviewer had also found: the tagline restated three times in different words, two editable rows whose placeholder text read as filler, and a contact block nested inside another box.
Cost. Each critique round sends two full-page captures of roughly 450 KB, the specification and the known-file, for 5,600 to 7,200 input tokens and 330 to 360 output tokens, and cost $0.0007 to $0.0009 at list price, measured from the response usage. Three rounds per page cost under 0.3 cents. Latency was 3 to 8 seconds per round.
The honest summary of the evidence: the pipeline produces a real improvement in structure and honesty, and it does not yet produce pages that pass its own critic. That is the intended direction of failure. A page that ships with its open issues listed is recoverable; a page that ships with an invented review is not.
10. Limitations and open problems
- Minimum scoring is strict. With the overall score defined as the lowest of ten lines, both test pages scored 2 to 3 even where most lines would have scored 7 or more. Whether to keep the minimum, use the mean, or lower the pass mark to 6 is an open decision.
- Paraphrase evades the diff. The repeated-tagline check matches identical lines only. Reworded repeats, and paraphrased claims that carry no numeral or proper noun, are left to the critic.
- Entity coverage is a list. Company-name detection uses a short list plus a suffix pattern. A fabricated partner named without a corporate suffix can pass the audit and depends on the critic.
- Structural checks need a browser. When the DOM walk fails, card-grid and stats-row detection are skipped and reported, not enforced.
- Competing guidance. A shared motion skill still recommends entrances on every section; the build routine overrides it in words. The cleaner fix is to trim the motion skill itself.
- Grounding is only as good as the known-file. If the owner's words are thin, the gate asks; if the owner's words are wrong, the page is faithfully wrong. The pipeline guarantees provenance, not truth.
11. Claim table
| Claim | Evidence | Confidence |
|---|---|---|
| The build routine opens with hard rules forbidding invented numbers, prices, partners, ratings, reviews and testimonials. | Build routine v2.0.0, hard rules section | high |
| A completeness gate requires five owner-supplied inputs and halts with questions when two or more are missing. | Build routine, step 0 | high |
| Pages are capped at six sections, two typefaces and one accent color. | Build routine, hard rules | high |
| The routine was rewritten on 2026-10-22 after a 61-source design report diagnosed the pages as "anonymous, not ugly". | Release notes and Queva working paper | high |
| The audit diffs numbers, prices, percents and N+ figures against the owner's verbatim messages. | Finishing check release notes | high |
| The critic scores ten lines and reports the lowest as the overall score; 7 or better passes. | Critic source and release notes | high |
| Repair is bounded at three critic rounds per page, after which the page ships with open issues listed. | Critic source (round cap) and build routine step 4 | high |
| A critic round cost $0.0007 to $0.0009 at list price, with 5,600 to 7,200 input tokens. | Release notes, measured on two test pages | high |
| A pre-rewrite insurance page scored 2 with about a dozen mechanical FIX lines; the rebuilt test pizzeria page scored 3. | Release notes, test evidence | high |
| Scoring by the minimum of ten lines is harsh; a pass mark of 6 or an average was left as an open decision. | Release notes, open points | medium |
| Reworded tagline repeats are caught only by the critic, not the audit. | Release notes, open points | high |
12. Sources
- The page build routine, version 2.0.0, 2026-10-22: hard rules, completeness gate, design specification, photo policy, editable regions and the finishing step.
- The finishing-check and critic source code, and the release notes for the "Better pages" release, 2026-10-22, including test evidence, cost measurements and open points.
- The design report of 2026-10-22, compiled from 61 sources, on why generated small-business pages read as anonymous.
- WP-01, Queva, stealth edition, for the surrounding system.