Six days ago I didn’t have a domain. Today I have a working product live at siterevisions.com — a visual website feedback tool where clients click anywhere on a live page, drop a pinned comment, and the agency owner gets a list of fixes they can paste straight into Claude Code. Free for the first site, ten dollars a year for unlimited. It works. I used it on my own client work this week.
And I’m about to open-source the whole thing.
I want to explain why, because the decision is more interesting than the product.
What I actually built
The core idea is unsexy on purpose. The category — visual annotation tools for website review — already exists. Every agency knows the workflow: client sends an email saying “the button on the about page looks weird,” dev wastes twenty minutes guessing which button, which page, on which browser, on which scroll position. The fix is to let the client click the exact pixel they care about and leave a pin.
What’s new in mine is two things.
The first is the proxy. When a guest opens a review link, my API server-side-fetches the target website, strips its Content-Security-Policy and X-Frame-Options headers, rewrites every same-origin link to route back through the proxy, injects a <base> tag so relative URLs resolve correctly, and then injects a dependency-free IIFE overlay that listens for clicks. The end result is the client sees a real, navigable copy of the live site with a comment layer floating over it. No browser extension, no signup, no embed snippet on the target site. They just click the link.
The second is what happens to the comments after they exist. Every pin captures a CSS selector, an XPath, a text quote of the surrounding element, and a screenshot of the viewport at click time — all on the client side, sent back via postMessage to the parent shell, persisted through the API. When the owner hits Export for AI, the API returns a deterministic Markdown fix-list with an agent instruction header at the top.
That last part is the wedge. The output is not a PDF. It is not a Trello board. It is a prompt:
# Site review feedback for example.com
You are working on the website at example.com. The following list is
client feedback collected from a visual review session. For each item,
locate the element by the CSS selector first, falling back to the
XPath, then the text quote. Apply the requested change. Capture a
screenshot in your reply.
## 1. About page hero button
- URL: https://example.com/about
- Selector: main > section.hero > a.btn-primary
- XPath: /html/body/main/section[1]/a[1]
- Text near: "Get started"
- Comment: "This should say 'Book a call' instead, and be teal."
- Screenshot: https://storage.googleapis.com/.../pin-abc123.png
## 2. ...

You paste that into Claude Code or Cursor and it just goes. The pin coordinates, the redundant selector fallback chain, the screenshot URL — it’s all there because an agent needs more redundancy than a human does to land an edit reliably. That’s the part nobody else in the category has, and it’s the part that justifies the whole stack existing in 2026.
The six-day build
- Day 1Idea + PRDLocked the name, domain, $10/year pricing, and the AI-export wedge. Adversarial PRD review, 17 fixes applied before any code was written.
- Day 2 (morning)Local MVPTurborepo: Next.js web, Hono API, dependency-free overlay package, shared Zod schemas. Proxy + pinning + guest flow working end-to-end on localhost.
- Day 2 (evening)Deployed to Cloud RunTwo services live on us-central1, Firestore deny-all rules deployed, browser API key referrer-restricted. Two deploy bugs fixed: /healthz is reserved on run.app, and --set-build-env-vars doesn't reach Dockerfile ARGs.
- Day 3Real-product UIFloating composer at click point, element auto-highlight, sidebar with Active/Resolved tabs, share button, dashboard with cascade-delete. Email/password auth shipped as a fallback when the API-key referrer restriction blocked the Google sign-in popup handler.
- Day 5Domain cutoversiterevisions.com bought on Cloudflare. Multi-origin CORS so the run.app URL and app.siterevisions.com both work during the transition. DNS-only flag (not proxied/orange) — the one detail that bit hard the next day.
- Day 6Live on siterevisions.comThe apex A record was set to Cloudflare-proxied, which meant Firebase couldn't see its own IP to verify ownership. Flipped to DNS-only and the whole chain unlocked. Marketing on Firebase Hosting, app on Cloud Run, valid certs on all four subdomains.

The hard parts were not the code. The code is one Hono API, one Next.js app, one esbuild IIFE, and a Zod schema package. The hard parts were the three or four infrastructure facts that you only learn when a real packet drops in production — the ^@^ delimiter prefix that Cloud Run needs when an env var contains commas, the order in which WEB_ORIGIN entries are evaluated because the first one is the canonical origin the overlay trusts for postMessage, the Firestore PITR setting that is off by default and would have eaten a deletion incident later.
The math that flipped the decision
Here’s the spreadsheet. Free tier captures one active website. Paid tier is $10 a year, unlimited everything, no upsells, no per-seat pricing, no integrations gated behind a Team plan. The math on a solo-founded micro-SaaS at $10/year — even with a generous 5% conversion rate from a marketing site that doesn’t exist yet — gets you to coffee money, not to a business that justifies the support tail.
You can see where this is going. The product is good. The product is not the bottleneck. The bottleneck is that any solo SaaS at this price point only works if the funnel is gigantic, and building a gigantic funnel is a different job than building a product. I do not want that second job right now.
What I do want is the developer-brand asset. There is a category of buyer — agency owners, freelance devs, indie hackers — who will not trust a SaaS at $10/year because they assume it will disappear in a year. They will trust a self-hostable, MIT-licensed repo with a beautiful README that says “this exists, here is how to run it, here is the architecture.” That repo costs me nothing to maintain beyond what I’d already maintain anyway, and it does the marketing work the SaaS price point can’t.
The micro-SaaS makes ten dollars. The open-source repo makes a developer brand. The brand is the actual business.
— Brett Ridenour
What goes open and what stays
The whole product goes open. The proxy, the overlay, the export pipeline, the Firestore schemas, the Cloud Run deploy scripts, the marketing site. MIT.
What stays mine: the hosted instance at siterevisions.com. If you don’t want to run your own Cloud Run project + Firebase Auth + GCS bucket, you pay me ten dollars a year and I keep the lights on. That’s still the business — it just stops being the only business. Self-host is the lead magnet; managed is the price plan.
The lesson, if there is one
The instinct when you finish a product is to defend it. To gate it. To charge for it. The reason I’m doing the opposite is that the product is not the scarce thing — my time is. A $10/year SaaS spends my time fundraising attention for ten-dollar conversions. An open-source repo with a great README spends the same product to buy something more useful: people deciding I’m someone they want to work with on the next thing.
I’ll post the GitHub link when the repo is cleaned up. If you want a sneak preview, the live product is at siterevisions.com and the AI export endpoint at /v1/sites/:id/export?format=md is the thing to play with first. It is the most interesting feature in the build and the one I’m proudest of — and in about a week, you’ll be able to read the source.