Website-to-demo delivery pipeline

Role
Sole engineer and technical lead. Self-directed build through Fridai, for my own outreach.
Scope
Seven staged skills: intake, site inventory, design directions, build, grounded chatbot, deploy, priced proposal.
Stack
Astro · Cloudflare Pages and Functions · MiniSearch + Gemini embeddings, RRF-fused · Firecrawl · Playwright
Status
Live. Two independent instances deployed from a template repo plus seven agent skills.

An agency selling an AI-assisted website rebuild is selling something the prospect cannot picture. The pitch that closes is the prospect's own site, already rebuilt, with a chatbot answering real questions from their real content. Hand-building one of those costs days per prospect, most of whom never reply, so what limits how many businesses an agency can pitch is the cost of the demo rather than the difficulty of the work.

This is the pipeline I built to remove that cap. A prospect's URL goes in; a rebuilt site of around ten pages, a chatbot grounded only in that business's own content, and a priced proposal come out, with every stage stopping at a human gate before the next one starts. It runs against education-sector businesses because that is where my outreach points. The two instances below are prospect demos, not paying clients.

1. Why it became a pipeline

The first demo was hand-built. Six days took one education business's live site to a deployed replacement with a working grounded chatbot. The artefact sold well. The delivery model did not: a week of work per prospect, spent before anyone has replied, is not a sales motion an agency can run at volume.

So I extracted the machinery from it. On the day that build closed, the repeatable parts came out into a template repo and seven agent skills, one per stage, with the client-specific material isolated behind a config file, a facts file and a token sheet. The demo stayed a live pitch asset; everything reusable moved out from under it.

The second instance is the proof. Two days later, a different education business went from intake to live deployment inside a single day, with the priced proposal out the following morning. Same architecture, entirely separate content, brand and chatbot corpus. The six-days-to-one-day gap is the whole return on productising it.

2. The seven stages

Each stage ends at a human gate. Nothing advances until I sign off on the previous stage's output. The gates sit where an autonomous run would otherwise commit to something expensive to undo: scraping a live site, picking a visual direction, shipping a chatbot, sending an offer.

  1. Intake and qualification: take the URL, fingerprint the existing stack, judge fit, and scaffold the project. A prospect running a real store on WordPress changes what can be offered, so the stack fingerprint is captured before anything is designed.
  2. Site inventory, with a three-way coverage diff: map the site three independent ways and diff the results against each other, so pages go missing loudly rather than silently. On the second instance that produced 158 in-scope URLs out of 418 discovered. Nothing is scraped in full until the coverage report is approved.
  3. Design directions: turn the site's own brand signals into a small set of concrete directions, each rendered as a real homepage using the business's actual copy and imagery. Choosing from rendered pages rather than descriptions is what keeps the direction argument to one round.
  4. Build: generic templates carry the routine pages; the one or two pages that do the selling are built bespoke, against screenshots of the real site rather than from memory of it. The second instance shipped thirteen pages.
  5. Grounded chatbot: retrieval-augmented answering over the business's own content only, with a curated facts file where every line traces back to a scraped source, and a golden-QA suite it has to pass before it is allowed near a deploy.
  6. Ship, then re-evaluate live: deploy to Cloudflare Pages, verify on the deploy alias before touching the production one, then re-run the same eval suite against the live URL.
  7. Priced proposal and outreach kit: a branded one-pager carrying the offer, what stays on the prospect's existing stack, and the cold-email and DM copy to go with it.

3. The evals are the ship gate

The suite passes in full or nothing ships. Each instance has its own golden question-and-answer set, 33 cases on one and 29 on the other, asserted with must and must-not patterns against the reassembled streamed answer. A shared guard appended to every case catches leaked chain-of-thought, model or provider names, and "as an AI". Both suites reserve a block for adversarial input: prompt injection, identity probes, invented offerings, price and off-topic bait, and citing a page that was deliberately cut from the build.

Then the same suite runs against production. A chatbot that passed against a local build is a different system once it is serving from another origin with separately configured secrets, so the pre-deploy green is treated as necessary and not sufficient. Both instances passed their full suite against the deployed worker, not just in development.

The evals earned that status by catching a real bug. An adversarial question about the business's location came back with an address the rendered site no longer showed. The cause was structural, not a prompt problem: the index builder chunked the raw scrape directly and bypassed the editorial layer that had already corrected roughly 89 FAQ answers, so the chatbot could resurface exactly the content the site had been fixed to stop showing. Correcting it at the source cut the index from 1,315 chunks to 753, most of the loss being navigation and footer noise.

One failure was the eval's fault, and was treated that way. A price-bait case failed because the model asked an honest clarifying question instead of matching the expected phrasing. I relaxed the assertion rather than steer the model into satisfying it, because a suite tuned to keep itself green stops measuring anything.

4. Retrieval that degrades instead of failing

Keyword and vector search, fused. MiniSearch over the chunked corpus and 768-dimension embeddings are retrieved separately and combined by reciprocal rank fusion, which keeps the answers that only exact wording finds alongside the ones that only semantics finds.

The vector store self-guards. Each build stamps the corpus with a hash; if the vector file is missing or its hash no longer matches the index, retrieval falls back to keyword-only instead of answering from a stale embedding or failing outright. A keyword-only answer is worse than a fused one and much better than a confident answer built on an index that no longer matches the site.

5. Live instances

Two education businesses have demos running the full pipeline output, each with its own content, brand, chatbot corpus and eval suite:

6. Evidence