Before I kick this off, a quick disclosure: I'm a Lovable partner. That's an honor, and it was an easy yes, because no tool gets more real use inside my business. What follows is the same build log I would have written either way.
Here is how fast the industry is moving.
In February I published The Definitive Guide to Question Mining. It went viral, at least by B2B newsletter standards, and traveled further than anything I had put out to that point. The reason it traveled is the reason it matters: discovery changed underneath us. Buyers stopped browsing ten links and started asking an assistant, and the assistant hands back one synthesized answer. There is no page two. When someone asks a question inside an AI interface, the model assembles the clearest available explanation, and if your company's explanation cannot survive that synthesis, you are absent from the exact moment the decision gets made.

The guide's argument was that winning that world starts with a different unit of strategy. Keywords describe topics. Questions expose uncertainty. Uncertainty is where decisions happen. "Headless CMS" is a topic. "Is a headless CMS overkill if my marketing team needs to move fast" is a decision. The marketing teams that win AEO find the questions shaping decisions in their market, systematically, and own the answers so clearly that AI systems reuse their explanation instead of a competitor's, a reviewer's, or a Reddit thread's.
I gave the discipline a name, question mining, and gave the loop underneath it a name, the Answer Ownership System: capture real questions from live sources, normalize the phrasing, qualify what actually shapes decisions, cluster by intent, answer canonically, refresh forever. Fifteen sections. A complete operating discipline for owning how your market gets explained.
It was also a spec. I did not know that when I wrote it. A detailed description of software that did not exist, published with a note that you would need a platform, a workflow tool, and real discipline to run it.
Here is what running it feels like. I click one button. Ninety seconds later I am looking at every theme of uncertainty in the CMS category, mined live from Reddit, Hacker News, and Stack Exchange, clustered by why buyers are asking rather than what they are asking about, each theme scored, and each one sitting on a stack of verbatim quotes linking back to the exact comments.
The top cluster was called Architecture Selection Risk. Canonical question: which CMS architecture best balances developer velocity against long-term operational complexity. It scored 83 out of 100 on my qualification rubric, which the app labels "Own it." Seven receipts underneath. Each receipt is a real human in a real thread, one click from the original comment.

I did not read those threads. I did not collect those quotes. I did not sort anything into buckets. I described the system once, in February, in prose. Six months later the spec compiles.
February to August. Framework to machine. A quarter of engineering to a day of prompting. That collapse is the real subject of this piece: how the build went, what broke on the way, and why a question mining engine you can stand up in a day is one of the most powerful AEO weapons you can point at a market right now.
If you read the NarrativeOS MCP piece, this is the same arc one layer down. That one covered making a finished research engine callable from Claude. This one covers something earlier and stranger: watching a published framework become a working product in a single sitting, because the cost of turning a described system into a running system collapsed while nobody was looking.
What changed since February
Reread the guide with 2026 eyes and one thing jumps out. Every hard part is described as a scale problem.
Normalizing ten phrasings of the same question. Clustering across thousands of inputs. Detecting drift. Keeping the backlog alive past week three. In February, each of those was a reason to put a platform in the stack. The guide says it outright: building the machine manually is possible, and it is also fragile.
Both halves of that sentence expired at the same time. The build is no longer manual, and the result is no longer fragile, because the machine stopped being you and a spreadsheet. It is an agent-built app with a database, a scraping layer, and a synthesis pipeline, and the cost fell from a quarter of building to a day of prompting.
Here is the part that took me a minute to see, and it is the sentence I want you to steal.
The guide was the hard work. The app was the easy part.
Everything difficult about question mining is judgment. What counts as a good question. Why intent beats topic. Which four buckets matter. What deserves a page versus a section versus a sentence. Why low-volume, high-consequence questions beat high-volume curiosity. I spent years learning that at Webflow and Affirm and spent February writing it down. The app is that judgment, executed by machines that do not get bored and do not skip week three.
Which flips the leverage question for anyone with a documented methodology. It used to be whether your framework was good enough to publish. Now it is whether your framework is specified well enough to run. Every playbook you have ever written is latent software. Mine happened to be about questions.
What I built
The app is called AnswerMine. React front, Supabase back, the default Lovable stack, same as NarrativeOS. Scraping and synthesis live in edge functions, where the API keys stay off the client.
It runs the Answer Ownership System as a pipeline, end to end, from one button:
Capture. Edge functions mine the three sources where buyers talk when nobody from marketing is in the room: Reddit through its public JSON API, Hacker News through the Algolia API, Stack Exchange through its public API. The Reddit miner follows the rule from the guide. Ignore the posts. Mine the comments, three levels deep, because titles are optimized for attention and comments are optimized for truth. The capture filter hunts the exact language patterns the guide catalogued: regret ("wish I had known," "in hindsight," "if I were starting over"), rage, comparison phrasing, and the quiet fear tell ("I might be missing something here, but").

Filter. Every captured signal gets scored for relevance to the category before it can become anything else. This step exists as a scar. The story is below.
Normalize. The app reads each signal and extracts every distinct question, including the implicit ones. A rant about sales overpromising becomes "what is the gap between this product's claims and reality." A regret post becomes the question the buyer wishes they had asked. Then phrasings collapse. "What's the downside," "what breaks," and "is this risky long term" merge into one canonical question, because treating them separately mistakes repetition for novelty.
Qualify. Every canonical question gets scored 0 to 100 on the four criteria from the guide, 25 points each: real decision uncertainty, likelihood AI systems will encounter it, whether a clear answer would reshape how the category gets explained, and whether the brand can credibly own it. 75 and up reads "Own it." 50 to 74 reads "Support it." Below 50 reads "Ignore on purpose," which the guide insisted is a decision, never a failure.
Cluster. Questions group into themes by the four intent buckets: Evaluation, Fear, Outcome, Process. Never by topic. "Is this overkill for us," "are we too small for this," and "is this enterprise-only" land in one cluster, fit anxiety, because they are one uncertainty wearing three outfits.
Prove. The rule I am proudest of, and it is one sentence: no proof, no cluster. A theme cannot exist in this app without at least two verbatim quotes attached, each carrying its source, author, date, and a link to the original. Under two receipts, the cluster renders as a ghost and cannot be promoted. Every claim the app makes traces back to a human who typed it in public.

Answer. Each promoted cluster gets a drafted canonical answer that names tradeoffs, states who the product is for and who it is not for, and mirrors the buyers' actual phrasing pulled from the evidence. Then an owner, a format, a status. If a question has no answer owner, the guide said, it does not exist. The app enforces the sentence.
Refresh. Published answers decay to "needs refresh" at 90 days. And the flag I find most useful: when new evidence keeps attaching to a question that already has a published answer, the cluster turns red and the label reads "the answer isn't working." The guide called resurfacing the signal most teams miss. The app watches for it so nobody has to remember to.
How Lovable built it in a day, including the parts that face-planted
The whole thing was four prompts into the Lovable agent. Long ones, but four. The first described the data model, the screens, the intent buckets, the scoring rubric, and the proof rule, and Lovable stood up the database, the sign-in, the permissions, and every screen in one pass. The second wired real scraping through edge functions. The third built the reading and scoring layer. The fourth added the refresh loop and the polish. Four prompts could produce a working system because the February guide already existed. The design work was done six months ago in prose. The prompts were transcription.
The first pass did not work, and the three ways it failed are worth more than everything that worked.
Failure one: Lovable built the furniture and skipped the engine. Version one had every screen rendering beautifully and a zero in every stat. The pipeline existed as disconnected pieces I was supposed to trigger by hand, screen by screen, and when the scraper hit an error it failed in total silence. The fix was one function that runs the entire loop start to finish and streams its progress to the screen, plus a standing rule that every failure must be loud. Any stage that breaks writes the actual error where I can read it. If you build one of these, make silent failure impossible before you make anything pretty. Agents default to shipping the demo. You have to demand the engine.
Failure two: my CMS project developed opinions about Medicare. The early miner searched Reddit for uncertainty patterns without binding them to the category, so a test project about Webflow came back with confident clusters about real estate purchase diligence and Medicare coverage gaps. Real quotes, real links, real receipts, complete nonsense. The fix became the filter stage. Every query now pairs the category with the pattern ("headless CMS regret," never bare "regret"), and a second pass scores each captured signal for relevance before it enters the pipeline. Below threshold, discarded, with the reason displayed. Watching a run report "67 captured, 41 relevant, 26 discarded" is strangely satisfying. It is the app demonstrating judgment in public.
Failure three: the app decided the whole market was terrified. The first clustering run put nearly everything in the Fear bucket, because fear is the easiest label to reach for when definitions are mushy. Comparison questions belong in Evaluation. Regret about results belongs in Outcome. The buckets balanced only after I wrote explicit examples and tie-breaking rules into the instructions. The lesson generalizes further than the bug: an agent executes your framework exactly as precisely as you wrote it, and every vague sentence in the source material becomes a wrong answer in the output.
Add up the fixes and the day splits into roughly one hour of describing the system and several hours of teaching the machine the judgment calls I thought were obvious. The judgment was the work in February and it was the work again in August. The typing is what disappeared.
Each failure, it turns out, lived in a different layer of the build. That pattern will matter again when you get to the prompts.
Why Lovable is the unlock for marketing teams specifically
Read my build section again and notice what every line describes: work that used to require an engineering team. Lovable handled the database, the sign-in, the permissions, the scraping functions, the hosting, and every deploy, all from prose. My contribution was the framework and the taste. At no point did I write code. At no point did I wait on a sprint.
That last sentence is the unlock, because custom tooling is the thing marketing has never been able to get built. The product roadmap always wins. An internal tool for mining buyer questions is exactly the kind of project that dies in prioritization, at every company I have worked in, because it is valuable to one team and urgent to nobody.
AEO makes that gap expensive. The work is new, the workflows are bespoke, and the vendors are still catching up to the frameworks the best operators are inventing. Which means the teams doing the strongest AEO work right now are creating process faster than any platform can productize it, and until now that process lived in docs and heroic manual effort. Lovable collapses the distance between the process you invented and the software that runs it.
This is the Marketing Engineer thesis with a build log attached. The highest-leverage marketer on a 2026 team is the one who can turn the team's own methodology into the team's own tooling, in a day, without asking engineering for anything. The skill is no longer writing code and it was never really prompting. The skill is specifying judgment precisely enough that a machine can execute it. Marketers who can do that now mint their own software.
The bubble galaxy, because dashboards lie about what matters
The first working version displayed clusters as columns of cards. Accurate, clinical, dead. It looked like every insights tool that gets opened twice and abandoned, and it committed the dashboard sin the guide warned about: it made everything look equally important.
So the default view is now a physics simulation. Every cluster is a bubble floating in a field. Size is evidence count, which means the themes with the most receipts have the most gravity, literally. Color is intent bucket. A gold ring means the score says own it. Dashed ghosts are clusters that have not earned their proof yet. Bubbles drift toward their intent region, jostle each other, and grow with a small ripple when a pipeline run attaches new evidence. You can drag them and they spring back, which serves no purpose, and I will not be removing it.

The galaxy earns its place on one criterion. The guide called clusters gravity wells, and the columns were hiding exactly what that phrase was meant to show. In the galaxy, one glance tells you where the market's uncertainty is massing, which themes are heavyweight, and which are speculative ghosts. The view says the true thing by default. That is the real bar for a data visualization, and most tools clear a decorative version of it instead.
Why this is an AEO weapon and not a toy
Go back to the guide's core claim. When a buyer asks an assistant a question, there is no page two. One synthesized answer gets assembled from whoever reduces uncertainty most clearly, and if your explanation cannot survive synthesis, you are absent from the moment that decides the deal.
The whole game, then, is knowing which questions are worth owning before your competitors do. That discovery work is exactly what this app industrializes.
The Webflow run makes it concrete. Ninety seconds of mining surfaced Architecture Selection Risk at 83. Editorial Autonomy at 73, with buyers asking whether marketing teams can create, preview, and localize without engineering dependence. Implementation Overhead at 71, with buyers probing hidden costs and configuration timelines. Every one of those is a question an assistant is being asked right now by someone evaluating the category. Every one carries receipts showing the exact language buyers use when they ask. And every one is ground where the clearest published answer gets reused in synthesis while the vaguest gets skipped.
The receipts matter beyond winning arguments in meetings. The canonical answers this system drafts are written in mined buyer language, and mined buyer language is what AI systems are trying to match when they resolve a prompt. You stop guessing which phrasing to align with. It is sitting in the proof panel, quoted, dated, and linked.
And because the pipeline is a button rather than a quarter-long research project, the loop from the guide finally runs at its intended cadence. Weekly triage stops being aspirational when the backlog refills itself. The compounding the guide promised was always downstream of the loop actually running, and the loop actually running was always the part teams could not sustain. A machine does not lose momentum in week three.
The February version of this capability required a stack, a budget, and a rollout. The August version requires an afternoon and the willingness to be precise about your own methodology. When the cost of a capability falls that far, having it stops being impressive. Lacking it starts being negligent.
The honest limits
Same policy as always: I do not trust a build write-up without a limits section.
Scraping is the fragile layer. Reddit's public API, Algolia's Hacker News index, and Stack Exchange are the three sources you can mine reliably without real infrastructure. G2 and X block server scraping, so the review layer and the social layer from the guide sit outside this build. The public trio is high signal. It is still a subset of where buyer truth lives.
Public data is loud people. Same caveat as NarrativeOS. Frustrated users post more than satisfied ones, so every output is directional, and you say so when you present it. The receipts keep you honest about what was actually said. They do not make the sample representative.
The relevance gate has a dial, and the dial is a judgment call. Too strict and you lose the weird adjacent threads where the best questions hide. Too loose and your CMS project starts worrying about Medicare again. I retune it per category, by hand, and I expect to keep doing so.
The machine finds the questions. Deciding which one is the hill stays human. The score can tell you Architecture Selection Risk is an 83. Choosing to stake positioning on owning that answer, and deciding what the answer should argue, is the analyst's chair. Same conclusion as the Jasper run: the engine deletes the grunt work between the question and the answer, and the call stays yours.
Your framework is a prompt now
The move, in order, and it starts before you open any tool.
Write your methodology down first, at the precision where a stranger could run it. Definitions, rubrics, thresholds, tie-breakers, the calls you currently make on instinct spelled out as rules. That artifact was this newsletter's job in February, and it turned out to be the spec.
Then hand it to the agent and make it build the loop before the screens. Demand the one-button run, loud errors, and a relevance gate on day one. Expect the three failure modes I hit: pretty furniture with no engine, confident nonsense from unfiltered capture, and mushy classification wherever your definitions were mushy first. Each one is the machine pointing at a vague sentence in your own thinking. Fix the sentence, rerun, and the app sharpens because the framework did.
Then run it on a category you know cold, so you can smell wrong output instantly. Mine, cluster, read the receipts, and check the machine's read of the market against the one you carry in your head. Where it matches, you have leverage. Where it beats you, you have the good kind of problem.
Mine hands me proof-backed buying themes for any category in about ninety seconds, and the next step is already sitting there. Switch on Agent integrations and Claude runs it mid-conversation, the same toggle the last piece walked through with NarrativeOS. The question mining guide became an app in a day. The app becoming a tool my assistant calls is a switch. That piece is coming.
One more thing, because "build one" is cheap advice without the materials. The four prompts I fed Lovable are the February framework made portable: the data model, the scoring rubric, the mining functions, the relevance gate, the galaxy, all of it, ready to paste. Reply to this email with the word "prompts" and I will send you all four.
Build yours. Then tell me what your engine surfaced that your gut had wrong. I read every reply.
Prompts to steal (the method to my madness)
These four prompts follow a pattern that works for any documented methodology, not just question mining. The first prompt is the blueprint: your framework translated into what a builder needs. What gets stored, what rules can never be broken, what each screen shows. The second is the intake layer: where raw material comes from, how it gets pulled in, and the rule that nothing is allowed to fail quietly. The third is the judgment layer: the scoring, the sorting, the definitions and tie-breakers you would otherwise carry in your head. The fourth is the finish: how results get displayed, and how they age so the system stays honest.
If you have a written playbook, it already contains all four. Your job is separating them into instructions a machine can follow one at a time.
Here are mine, unedited. I use Claude to develop my prompts that I put into Lovable. I found it is the best way to get the highest quality product vs. trying to type your prompts alone.
PROMPT 1 — The Foundation
Build AnswerMine, a question mining and answer ownership platform for GTM teams. It operationalizes one idea: markets are won by whoever owns the clearest answers to the questions that shape buying decisions. The app mines raw buyer language from public communities, extracts question-shaped uncertainty, clusters it by buying intent (never by topic), scores what actually shapes decisions, and attaches verbatim proof to every theme.
The product's one law: NO PROOF, NO CLUSTER. Every theme must be backed by at least 2 verbatim quotes with source, link, and date. A cluster without receipts cannot exist or be promoted. This turns "I think buyers care about X" into "here are 14 humans saying X in their own words, here are the links."
Tech
React + TypeScript + Tailwind + shadcn/ui. Supabase for auth (email), database, and edge functions. d3 available for visualization later.
Data model (Supabase, RLS on everything scoped to the user's projects)
projects — id, user_id, company_name, category, icp_description, competitors (text array), created_at
sources — id, project_id, type (enum: reddit, hackernews, stackexchange, manual), label, config (jsonb, e.g. subreddit list), last_mined_at
raw_signals — id, project_id, source_id, verbatim_text, author_handle, url, signal_date, signal_type (enum: explicit_question, implicit_question, regret, rage, comparison, quiet_fear), relevance_score (0–10, nullable), status (enum: new, processed, discarded), discard_reason (nullable), created_at
questions — id, project_id, canonical_text, cluster_id (nullable), aeo_score_decision (0–25), aeo_score_ai_likelihood (0–25), aeo_score_category_shaping (0–25), aeo_score_credibility (0–25), aeo_total (computed), status (enum: unclustered, clustered, answered, parked, ignored)
evidence — id, question_id, raw_signal_id (the join that makes every question traceable to receipts)
clusters — id, project_id, theme_name, intent_bucket (enum: evaluation, fear, outcome, process), canonical_question, recommended_surface (enum: dedicated_page, section, inline), status (enum: new, promoted, parked, ignored), evidence_count (computed), avg_aeo_score
answers — id, cluster_id, canonical_answer (markdown), owner_role (enum: pmm, growth, sales, support, content), format, status (enum: draft, approved, published, needs_refresh), last_refreshed_at
pipeline_runs — id, project_id, stage, status, detail, counts (jsonb), error (nullable), created_at. This is the log table that makes every failure loud.
The four intent buckets (hardcode these, they are the spine)
Clusters are NEVER organized by topic (pricing, security, integrations). Only by why the buyer is asking:
Evaluation — "Is this right for me?" (blue)
Fear — "What could go wrong?" (red)
Outcome — "What actually changes if this works?" (green)
Process — "What does this look like in practice?" (amber)
The AEO score
Every canonical question scores 0–100 across four criteria, 0–25 each: (1) real decision uncertainty, not curiosity; (2) likelihood AI systems encounter it across prompts; (3) whether a clear answer would change how the category gets explained; (4) whether this brand can credibly own the answer. 75+ = "Own it" (green badge), 50–74 = "Support it" (amber), <50 = "Ignore on purpose" (gray). Show a score gauge on every question and cluster. Position everywhere: high volume is not high leverage; low-volume, high-consequence questions win.
Screens
Onboarding wizard: company, category, ICP, competitors → source picker with subreddits suggested by buyer maturity stage (early: r/startups, r/Entrepreneur, r/marketing, r/smallbusiness; mid: r/SaaS, r/webdev, r/ProductManagement, r/growthmarketing; late: r/sysadmin, r/devops, r/dataengineering), user can add custom → one screen explaining the loop: Capture → Filter → Normalize → Qualify → Cluster → Prove → Answer → Refresh.
Overview: the loop as six stage cards with live counts, a "Run Full Mining Pipeline" button (wired in Prompt 2), this week's triage summary, top clusters by score, coverage stat (% of promoted clusters with an approved answer), and an expandable "Pipeline log" panel reading from pipeline_runs in mono font.
Mine: card per source with type icon, last mined date, signal count, mine button. A small "Add signals manually" paste box at the bottom for edge cases.
Signal Inbox: feed of raw_signals styled as pull-quotes (serif italic) with source badge, signal_type badge, date, link-out. Discarded signals render as collapsed gray rows showing discard_reason. Filters by source, type, status.
Clusters: four columns by intent bucket for now (Prompt 4 adds the galaxy view). Cards show theme name, canonical question in quotes, score gauge, receipts badge ("7 🧾"), surface chip. Click opens Cluster Detail.
Cluster Detail: left = canonical question (large, serif), bucket, the four sub-scores each with a one-line rationale, recommended surface. Right = THE PROOF PANEL: every verbatim receipt as a quote card with source badge, author, date, external link, plus a sources-represented row. Under 2 receipts = red "INSUFFICIENT PROOF" state, promotion blocked. Bottom = canonical answer draft area (markdown), owner assignment, status pipeline, and three explicit actions: Promote / Park / Ignore on purpose.
Backlog: all clusters sorted by score with columns for question, intent, receipts, score, status, owner. A "Weekly Review Mode" toggle filtering to: new this week, gaining momentum, and answered clusters where the question keeps resurfacing (flag red: "the answer isn't working").
Export: per-cluster "Copy AEO brief" (markdown with question, intent, score breakdown, all evidence with links, draft answer) and full CSV.
Design
Editorial research desk, not generic SaaS. Paper/off-white light mode, ink-dark default. Serif display font (Fraunces or Newsreader) for canonical questions and quotes, Inter for UI, tabular mono for counts and scores. Verbatim quotes always styled distinctly, they are the product. Hairline borders, generous whitespace, no gradient hero nonsense. Receipt badges styled like receipt stubs. Empty states each teach the framework in one line (Signal Inbox: "Keywords describe topics. Questions expose uncertainty. Mine a source to start capturing it.").
Seed data
Seed a demo project ("Vertex CMS", category "headless CMS") with ~30 realistic signals across sources including regret posts, quiet-fear hedging, comparison threads, and polite risk probes. Pre-form 5 clusters across all four buckets with evidence attached and varied scores, plus one in the "answer isn't working" state, so every screen renders full on first visit.
PROMPT 2 — Real Mining + The One-Button Pipeline
Wire real external mining and make the whole loop run from one button. Two rules govern everything here: the pipeline must run end to end without manual steps between screens, and every failure must be loud. Silent zeros are the enemy.
Three mining edge functions
mine-reddit: for each configured subreddit, fetch https://www.reddit.com/r/{sub}/search.json?q={query}&restrict_sr=1&sort=relevance&t=year&limit=25 plus /hot.json?limit=25. Always send header User-Agent: AnswerMine/1.0 (question mining research tool); on 403/429 retry the same path on https://api.reddit.com; 1-second delay between requests. Critical: for the top 10 matching posts per subreddit, fetch the comment trees to depth 3 via /comments/{post_id}.json. Comments are the primary target, not posts. Capture any post or comment over 80 characters containing "?" OR any of: "wish I", "in hindsight", "regret", "overkill", "worth it", "vs", "switched", "am I missing", "starting over", "nightmare", "honestly", "downside", "gotcha", "be aware". When in doubt, capture; the relevance gate filters later. Assign a best-guess signal_type from the language. Dedupe by url + text hash.
mine-hackernews: Algolia public API, no auth. https://hn.algolia.com/api/v1/search?query={query}&tags=comment&hitsPerPage=50 and tags=story, plus search_by_date for recency. Permalink = https://news.ycombinator.com/item?id={objectID}.
mine-stackexchange: https://api.stackexchange.com/2.3/search/advanced?q={query}&site={site}&sort=relevance&filter=withbody&pagesize=30, no key needed at this volume. Auto-pick sites from the category (CMS → stackoverflow, webmasters, webapps). Titles AND bodies are signals; strip HTML.
Query construction (this prevents garbage)
Every search query pairs the project's category with an uncertainty pattern, never the pattern alone. "headless CMS regret", "webflow vs", "{category} worth it". Generate 6–10 variants per project from: category, category synonyms, each competitor name, and category + "worth it / vs / regret / migration / overkill". Never search bare "regret" or "overkill"; unbound patterns pull in off-topic communities.
The orchestrator: run-pipeline
One edge function runs the whole loop sequentially: mine all sources → relevance filter (stub for now, built in Prompt 3) → extract & normalize (stub) → score & cluster (stub) → recompute counts and stats. Writes a status row to pipeline_runs at every step with counts and any error. Wire the Overview "Run Full Mining Pipeline" button to it, auto-trigger once after onboarding completes, and while running replace the six loop cards with a live progress view polling pipeline_runs every 2 seconds: spinner → running count ("Mining r/SaaS… 14 signals") → checkmark per stage. On completion, animate the dashboard numbers up and toast a per-source summary ("Reddit: 34 · Hacker News: 22 · Stack Exchange: 11").
Loud errors
Any stage that throws writes the full error to pipeline_runs and renders a red error card in the progress view with the actual message and a "Retry this stage" button. If one subreddit or source fails, log it and continue; one bad source never kills the run. If Reddit rate-limits everything, show an amber notice suggesting a retry in a minute, and proceed with whatever the other sources returned.
PROMPT 3 — The Reading and Scoring Layer
Build the analysis stages using Lovable AI (or an OpenAI key in Supabase secrets). Three edge functions, all called automatically inside run-pipeline, all batched, all fault-tolerant: batch 10 signals per model call, strip markdown fences before JSON.parse, retry a failed batch once, then skip it, log it, and continue. One bad batch never kills the run.
1. filter-relevance — runs FIRST, before anything becomes a question. Batch new signals to the model with the project's company, category, ICP, and competitors. Score each signal 0–10: "is this about buying, evaluating, using, or regretting something in the {category} space?" Below 6 → status discarded, discard_reason "off-topic: {detected topic}". Report the funnel in pipeline_runs so the progress view can show "67 captured → 41 relevant, 26 discarded." Add a "Re-run relevance filter" action on the project that re-scores all existing signals, discards off-topic ones, deletes orphaned questions and clusters, and re-clusters the remainder.
2. extract-and-normalize — for each relevant signal, the model extracts every distinct question INCLUDING implicit ones: a rant about sales overpromising becomes "what is the gap between this product's claims and reality"; a regret post becomes the question the buyer wishes they had asked. Normalize into clean canonical buyer language, preserving the uncertainty and stripping the phrasing noise ("What's the downside?" / "What breaks?" / "Is this risky long term?" are ONE question). Before inserting, send the project's existing canonical questions as context and MERGE via a new evidence row instead of duplicating; only create a new question when the intent genuinely differs. Mark signals processed.
3. score-and-cluster — score every unclustered question on the four AEO criteria (0–25 each) with a one-line rationale per criterion, using project context for the credibility score. Assign intent buckets with these definitions and tie-breakers, verbatim, because vague definitions dump everything into Fear:
Evaluation = fit and choice ("is this right for a team like ours", "X vs Y for us"). A comparison question is ALWAYS Evaluation, not Fear.
Fear = downside and risk ("what breaks", "hidden costs", "what do people regret buying into").
Outcome = results and payoff ("did it actually improve X", "what changed after switching"). Regret about results is Outcome, not Fear.
Process = lived reality ("what does migration actually involve", "how long until the team is productive").
Group questions into clusters by shared underlying uncertainty, never shared topic ("Is this overkill for us?", "Are we too small?", "Is this enterprise-only?" = one cluster: fit anxiety). Per cluster generate: theme_name (2–4 words, e.g. "Fit Anxiety", "Hidden Cost Fear"), the single canonical question that absorbs all members, and recommended_surface (dedicated_page if it shapes category explanation + spans sources + influences evaluation; section if important but secondary; inline if narrow friction). Return strict JSON. Enforce the law: clusters with fewer than 2 evidence rows get flagged insufficient, never auto-promoted.
4. draft-answer — on demand from Cluster Detail. Using the canonical question, ALL verbatim evidence, and project context, draft a canonical answer that: leads with the direct answer in 2–3 sentences, names tradeoffs honestly, states who the product is for AND not for, and mirrors the buyers' actual phrasing from the receipts. No marketing fluff, no evasion. It should survive being lifted verbatim into an AI-generated response. Save as draft.
Show the analysis stages in the pipeline progress view as their own steps (Filtering → Extracting → Scoring → Clustering). After building, run the full pipeline on the seed project and verify: signals > 0, off-topic signals discarded with reasons, questions > 0, clusters spread across all four buckets (not concentrated in Fear), every cluster's receipts have working external links.
PROMPT 4 — The Bubble Galaxy + The Refresh Loop
Two additions: make the clusters view alive, and make the answers age.
The Bubble Galaxy (new default Clusters view)
Replace the columns as the default with a force-directed bubble field built with d3-force. Keep the column board behind a Galaxy / Board toggle.
Physics: each cluster is a bubble. Radius scales with sqrt(evidence_count), min 40px, max 130px, so themes with more receipts have more gravity, literally. Four invisible anchors, one per intent bucket, in quadrants; bubbles drift toward their bucket's region via weak forceX/forceY, never overlap via forceCollide, and float continuously via a slow sinusoidal jitter so the field never sits still. Color = intent bucket at ~15% fill with a solid 2px border. AEO 75+ gets a gold outer ring with a subtle glow. Clusters under 2 receipts render as dashed-border ghosts at 40% opacity.
Inside each bubble: theme name (serif, centered), receipt count in mono ("7 🧾"), score as a small filled arc on the bubble's edge. Hover: scale up 8%, tooltip with full canonical question + score + "↑ N in 14d" momentum. Click: pulse, then a side drawer with the full Cluster Detail including the proof panel. Drag: bubbles are draggable and spring back. When a pipeline run attaches new evidence, the affected bubble grows with a spring animation and emits a brief ripple. Quadrant labels in the corners in low-opacity small caps ("EVALUATION — Is this right for me?"). Legend chips: intent colors, gold ring = "Own it", dashed = "needs more proof". Empty state: one gray bubble floating alone: "Nothing mined yet. Run the pipeline and watch this fill up."
The Refresh Loop
Freshness decay: any published answer with last_refreshed_at older than 90 days flips to needs_refresh with an amber "STALE" badge. Add a "Needs refresh" queue to the Backlog.
Resurfacing detection: when new evidence attaches to a question whose cluster already has a published answer, flag the cluster red: "Question resurfacing after answer. The answer isn't working." Surface these first in Weekly Review Mode, and in the galaxy give them a red pulsing border.
Momentum: cluster cards and bubbles show a subtle ↑ when evidence grew in the last 14 days, and a fading treatment after 60+ days with no new evidence ("Fading, consider retiring").
Final pass
Count-up animations on dashboard stats, a green-check cascade across the loop stages when a run completes, a completion toast written like a person ("Mined 67 voices across 3 communities. 41 were about your market. They cluster into 6 themes, 2 you should own."), loading skeletons on all async views, mobile responsive, dark mode default. Then run the pipeline once more end to end and fix anything that renders empty.