OfferGuard

How OfferGuard decides

Three independent layers — deterministic rules, retrieval over labeled cases, and a quote-verified LLM — composed by a pure function. Either layer alone can raise the alarm; the top tier needs corroboration.

The pipeline

  1. Validation + rate limit

    Zod schema (200–20,000 chars), 64KB body cap, per-IP limits

  2. Normalization + extraction

    whitespace fold, homoglyph fold, entities (emails/URLs/IM/phones/crypto), sha256 dedup cache

  3. Deterministic rules

    14 weighted red-flag rules with ±40-char evidence excerpts

  4. Embedding retrieval

    qwen3-embedding-8b (Fireworks, 1536d) → pgvector cosine kNN, 6 scam + 6 legit ≥ 0.55

  5. LLM verdict (advisory)

    Kimi K3 via Fireworks, strict JSON schema, temperature 0, untrusted-data framing

  6. Tier composition

    deterministic override logic — not the LLM; verbatim-quote verification drops hallucinated evidence

Rule catalog (14 rules)

CodeRuleSeverityWeightTrigger
R01FEE_OR_PAYMENThard40Applicant is asked to pay money (processing/training/registration fee, deposit).
R02CRYPTO_PAYMENThard35Payment requested in cryptocurrency or a wallet address is supplied.
R03WIRE_OR_GIFT_CARDhard35Payment via wire transfer, money order, or gift cards.
R10CHECK_OVERPAYMENThard35Classic overpayment/check-refund scam structure.
R11MONEY_MULE_SIGNALShard35Duties involve receiving and forwarding funds or reshipping packages.
R04IM_ONLY_CONTACThard25Interviews/communication exclusively via consumer IM apps.
R05SENDER_DOMAIN_MISMATCHhard30Sender email domain is freemail while the posting cites a corporate site.
R06DISPOSABLE_EMAILmedium20Contact uses a disposable email domain.
R12NO_VERIFIABLE_PRESENCEsoft10Freemail-only contact and no company website mentioned anywhere.
R07IDENTITY_OVERREACHmedium20Sensitive personal/financial data requested before hire.
R08URGENCY_PRESSUREsoft10Artificial urgency or offer-expiry pressure.
R09TOO_GOOD_COMPsoft15Implausible pay for unskilled/entry work.
R13FORMAT_SPAMsoft5Spammy formatting: caps/punctuation density.
R14VAGUE_ROLEsoft5No concrete responsibilities or skill requirements.

Evaluation

  • E1 — Kaggle EMSCA holdout: 150 fraudulent + 300 legitimate, disjoint from the corpus.
  • E2 — manual holdout: 30% of a modern scam/legit set (FTC/IC3-pattern).
  • E3 — adversarial: 20 prompt-injection payloads on known-legit postings; verdict must not flip.
  • Binary collapse: LIKELY_SCAM = positive, SUSPICIOUS = abstain (reported separately).

First production run — 2026-10-03 (Kimi K3 + qwen3-embedding, 450 held-out cases)

  • Precision 98.1% · false-positive rate 0.33% (1 of 300 legitimate postings flagged)
  • Recall 36% as LIKELY_SCAM + 20% abstained to SUSPICIOUS — precision-first by design (spec §8)
  • Adversarial set: 20/20 injection attempts left the verdict unchanged; 19 were reported as red flags

Full tables and history: docs/eval-results.md in the repository.

Security notes

  • Prompt injection: untrusted-data framing, delimiter stripping, temperature 0, strict schema, deterministic tier overrides independent of the LLM, verbatim-quote verification.
  • No URL fetching (SSRF surface avoided by design); paste-only input.
  • PII: public excerpts are email/phone-redacted; logs never contain posting text.

Educational tool — not legal or financial advice. Analyses are stored (hash-deduplicated) to improve the corpus; request deletion anytime.