The promise
- Every claim links to a real quote. Each finding, quote, competitor gap, launch-copy line, and feature carries a link to the actual source it came from — a Reddit thread, a Hacker News comment, a Stack Exchange answer, a GitHub issue, a web page. metalworks reads across many sources, spanning consumers to developers to procurement, so a need isn’t measured from one crowd alone — but whatever the source, you can open it and read it yourself.
- Anything it can’t back, it drops. If the tool can’t tie a statement to a real quote (or, for web facts, a real source URL), that statement never ships. It isn’t softened or guessed — it’s removed.
- It tells you when there’s nothing there. When the demand is thin or there’s no real opening, metalworks says so and stops, instead of manufacturing an opportunity to please you.
How it actually works
- Quotes are matched, not paraphrased. A quote in a report is the exact text of a real stored record. If a piece of generated text doesn’t match a real one, it’s dropped.
- Numbers are counted, not asserted. “312 people raised this” comes from counting distinct authors, never from a model estimate.
- Demand-volume numbers rank, they don’t decide. A source can attach an absolute number to a theme — a package’s downloads, a search term’s volume. That lifts a high-volume theme in the ranking, but the go / no-go call reads only how many distinct people raised the need. A number can sharpen the order; it can never manufacture a verdict.
- Web facts carry their real source. When a finding comes from the web, its URL comes from the search tool’s citation data — never from model prose. No source, no finding. The web discovery lane is agentic — it searches, reads, and searches again to reach niche forums and community threads — but it ingests only verbatim citations, never a synthesized summary.
- Every later step inherits this. Positioning, the design system, the build spec, launch copy — each reads from the same report and links every claim back to it. The chain runs from a real quote all the way to the line in your launch copy.
Measuring what triage throws away
Reading thousands of threads through an LLM is slow, so the pipeline first triages on embedding score: the top band is auto-kept, a middle band goes to the LLM classifier, and the bottom band is auto-rejected on rank alone — never shown to the model. That’s a recall risk: if the cosine floor is set too aggressively, a genuinely relevant thread could be discarded before anything reads it. So the pipeline keeps itself honest with a recall backstop. It samples threads from that auto-rejected band — spread evenly across the band, not just the just-missed top edge — and runs them through the same classifier the live path uses, purely to measure the false-reject rate: the fraction the classifier would have kept. A high rate is a warning that the auto-reject cutoff is too aggressive. Crucially this is observability only — the sampled threads are scored, not promoted into the report, so the surviving corpus is unchanged. The measuredfalse_reject_rate (and a dedup_merge_rate for how much near-
duplicate merging the synthesis stage did) are surfaced on the exploration report, so you can
see the cost of the speed/recall trade-off rather than take it on faith.