Moderation & Fraud Spec
Listing note moderation (hard requirement)
Every listing's free-text note field is scanned before a sync is accepted. Blocked patterns:
- Phone numbers (any recognizable international format, including obfuscated forms like "five five five" or digits separated by spaces/dashes/dots beyond what a normal size/model string would contain)
- Email addresses
- Physical addresses / ZIP-plus-locality patterns
- URLs / social handles (@handle, "IG:", "insta", "snap", "whatsapp", etc.)
- Explicit off-platform-deal-making language ("text me", "cash only outside app", "DM me")
On a match, moderation-service (stub, Phase 12) rejects the sync with a structured reason
in the API error response (code: "NOTE_CONTAINS_CONTACT_INFO", details: {matchedPattern: "phone"}) — never a silent drop. See docs/business/conflict-resolution-log.md item 11 for the
false-positive/appeal handling (merchant UI surfaces the reason; ops console gets a manual
override queue).
Fraud signals (fraud-service, stub, Phase 12)
Duplicate accounts (same device fingerprint across multiple sellers rows that haven't been
legitimately federated), device fingerprint anomalies, trade-session failure rate, cancellation
velocity, and behavioral anomalies (e.g. a seller creating and cancelling many high-value trade
sessions in a short window). TBBN never sees seller payment data at all — the only payment
signals fraud-service can ever draw on are on the merchant-billing side
(billing-service/Stripe), not from sellers (see docs/business/conflict-resolution-log.md
item 14). Output is a fraud_score consumed
by matching-engine's reputationMatch sub-score (see
docs/architecture/matching-algorithm-spec.md) and by ops console for manual review triggers —
never an automatic account ban without a human-reviewable trail.
Reputation (reputation-service, stub, Phase 12)
Tracks completion rate, cancellation rate, return rate, refund rate per seller, rolled into
sellers.reputation_score. Defaults to a neutral score (not 0) for sellers without enough
history, so new/early-network participants aren't penalized in matching before there's data —
see matching-algorithm-spec.md's reputationMatch note.