scalpel@labs: ~/glossary/evidence-trail.mdx5 sections

The Evidence Trail

An evidence trail is the exact proof behind a detection: which vector fired, the fingerprint pattern that matched, and the matched text from the page. Nothing is asserted without it.

extension: Scalpel Stackupdated: 2026-08-14read_time: 3 min
less evidence-trail.mdx

Why it matters

The single biggest complaint about traditional stack detectors is unexplained false positives: a tool says "React" and you have no way to check. An evidence trail turns detection from a claim into a receipt. You see the <meta> line, the script URL, the cookie name, and can confirm it in your own DevTools.

Explainability is the differentiator. When you trust a tool, you trust its data. When you can see exactly what it matched, you can spot if it made a mistake or if it spotted something real. That transparency is what keeps detection honest.

How it works

Every technology detected by Scalpel Stack carries at least one evidence item. Each item records:

  1. The vector: which channel the detection came from (meta, script, header, js, cookie, html, dom, url, or implied).
  2. The key: the specific attribute or path that was checked (e.g. name="generator" for a meta tag, the script URL for a script src, the cookie name for a cookie).
  3. The pattern: the fingerprint pattern from the database that matched.
  4. The matched text: the actual substring or value from the page that fired the match.

For example, a WordPress detection might show:

  • Vector: meta
  • Key: generator
  • Pattern: ^WordPress(?: ([0-9.]+))? (capture the version if present)
  • Matched text: WordPress 6.4.2

When you expand a technology row in the popup, you see all of its evidence lines. Each one is a separate piece of proof, ranked by the confidence weight of that particular vector-pattern pair.

Implied detections carry an additional "implied by X" evidence line that shows which direct detection led to them. So if WordPress is detected and MySQL is implied, the MySQL row carries an evidence line saying "implied by WordPress" with reduced confidence.

What does not matter

The evidence trail does not prove a business relationship or control. Reading a script from cdn.shopify.com means the page loads from Shopify, not that Shopify owns the site or that this site is a Shopify merchant. The detection is proof of the trace, not proof of the relationship.

An evidence trail also does not prove the technology is in active use. A stale script tag left behind in the HTML, or a generator meta tag from a migration, will fire the same as if the technology were running right now. The detection is proof of presence, not proof of active use.

Code example

Here is what a fully expanded evidence trail looks like in the popup:

WordPress 6.4.2 (Confidence: 98/100)
├─ meta: generator = "WordPress 6.4.2" (confidence 85)
├─ script: /wp-content/plugins/... (confidence 80)
├─ cookie: wordpress_logged_in_* (confidence 60)

jQuery 3.6.0 (Confidence: 95/100)
├─ script: jquery-3.6.0.min.js (confidence 92)
├─ js: window.jQuery.fn.jquery = "3.6.0" (confidence 88)

Google Analytics (Confidence: 72/100)
├─ script: google-analytics.com/ga.js (confidence 70)
├─ html: gtag(...) comment in page source (confidence 40)

Each evidence line shows the vector badge, the key being checked, the matched text from the page, and the confidence weight of that particular signal. You can hover over each line to see the full matched text if it was truncated.

When you open your browser's DevTools and search for the same values (e.g. search the source for wordpress_logged_in_), you will see the exact same text that Scalpel Stack matched. That is the point: the receipt is copy-pasteable.

How Scalpel Stack shows it

Expanding a technology row reveals the evidence list below it. The header row (showing the tech name and confidence meter) carries this concept's ? link. Each evidence line is rendered using textContent only, never innerHTML, so hostile page content (e.g. a comment containing <script>) never executes.

If a technology has many evidence items, only the top few are shown by default, with a "show more" option to expand the full list. This keeps the interface readable without hiding proof.