diff --git a/FIX-NOTES-false-positive-redesign.md b/FIX-NOTES-false-positive-redesign.md
new file mode 100644
index 0000000..0d0a375
--- /dev/null
+++ b/FIX-NOTES-false-positive-redesign.md
@@ -0,0 +1,235 @@
+# Patch notes — false-positive redesign (master)
+
+## Problem
+
+Operators reported the scanner was generating ~130 findings on a clean
+technical PDF (*Linux from Scratch*). The findings were mostly false
+positives: every plain-HTTP URL, every URL whose path contained a word
+like "support" or "account", every URL mentioning a brand in its path,
+every `mailto:` link, every in-document cross-reference, and every
+paragraph mentioning `wget` or `exploit` in prose.
+
+An earlier revision attempted to fix this by adding a hard-coded
+allow-list of well-known documentation domains (`linuxfromscratch.org`,
+`kernel.org`, `github.com`, etc.). This was correctly rejected by the
+operator as a per-file band-aid — it made the Linux-from-Scratch PDF
+stop alerting without solving the underlying problem, and it would
+produce the same false positives on every other technical document the
+scanner had never seen.
+
+This revision takes the principled approach: every detector must be
+backed by a verifiable property, either of the document itself or of
+an external authority. No thresholds, no per-file or per-domain
+exceptions, no "suspicious" tier.
+
+## Design
+
+Every detector in the redesigned scanner falls into exactly one of two
+categories.
+
+### Category 1 — Verifiable executable intent
+
+The vector contains a structure whose only purpose is to execute code
+or spawn a process. Presence is the threat. There is no "benign
+JavaScript in a PDF action" or "benign Launch action".
+
+| Detector | Triggers on | Verifiable property |
+|---|---|---|
+| Active script in PDF | `/JavaScript` or `/JS` action stream | The action dictionary has `S = JavaScript` |
+| Program launch in PDF | `/Launch` action with `/F`, `/Win`, `/Mac`, `/Unix` | The action dictionary has `S = Launch` |
+| External program exec in EPUB | ` // PoC for CVE-2024-1234",
+ );
+ let finding = evaluate(&node, &Config::default()).unwrap();
+ assert_eq!(finding.classification, ThreatClassification::EducationalContent);
+ }
+
+ #[test]
+ fn cve_writeup_prose_without_signature_is_no_finding() {
+ // Text that mentions `eval()` in prose but does not contain a
+ // structural signature (`/JavaScript`, `