# Referral Fraud Check

> Investigate referral-program fraud for a given email address by spawning a cloud agent with data-warehouse access to query referral data and score fraud signals. Use when someone asks to "check referrals", "inspect a referrer", "is this referral legit", "should we approve a reward for X", or "referral fraud check". Also use when processing reward-approval requests that need a fraud assessment first. This skill delegates the data work to a cloud agent; it does not require warehouse access in the local environment.

- Skill: `warpdotdev/referral-fraud-check` (Agent Skill)
- Install (CLI): `npx skillmds@latest add warpdotdev/referral-fraud-check`
- Raw SKILL.md: https://api.skillmd.com/api/skills/warpdotdev/referral-fraud-check/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: warpdotdev (https://skillmd.com/u/warpdotdev)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/warpdotdev/referral-fraud-check

---


# Referral Fraud Check

Investigate a referrer's referral activity and produce a fraud verdict to help
humans decide whether to approve or deny referral rewards.

This skill assumes it is running locally **without** direct warehouse access. It
delegates the data work to a cloud agent that has query access.

## Configuration

Set these in your `.env` (see `.env.example`):

- `DATA_WAREHOUSE_ENV_ID` — the cloud agent environment that has warehouse access.
- `WAREHOUSE_PROJECT_ID` — the warehouse project the agent should query.
- `APPROVALS_CHANNEL_ID` — optional Slack channel for posting verdicts.

## Workflow

### Step 1: Get the referrer email

Collect one or more email addresses to investigate.

### Step 2: Spawn a cloud agent with warehouse access

Use `run_agents` to start a single cloud agent in the environment named by
`$DATA_WAREHOUSE_ENV_ID`. That agent has warehouse access and can discover the
relevant tables and write its own queries.

The child agent's prompt should include the email(s), the investigation goal,
the scoring framework, the output format, and instructions to report results
back via messaging.

### Step 3: What the cloud agent should do

1. **Discover the data model.** Identify the tables/models that hold referral
   relationships and user activity (e.g. a referral-relationships model and a
   user-facts model). Prefer discovering columns from your own schema/catalog
   rather than assuming names.

2. **Query the warehouse** (e.g. `bq query --project_id=$WAREHOUSE_PROJECT_ID`
   or your warehouse's CLI) to gather:
   - The referrer's own profile (plan, activity, existing fraud status).
   - The referees: signup dates, onboarding/activation status, activity levels,
     and any existing fraud flags.
   - Aggregate stats: total referrals, activation rate, retention, and signup
     timing patterns.

3. **Score fraud signals.** Use a weighted rubric appropriate to your program.
   In general, weigh signals such as: shared device/identity between referrer
   and referees, referrers with no genuine product usage, low activation or
   retention among referees, abnormal signup bursts, disposable-email domains,
   and clusters of similar/sequential referee identities. Keep your specific
   thresholds in a private configuration rather than in this public skill so the
   detection logic is not trivially evadable.

4. **Produce a verdict:** APPROVE / DENY / INVESTIGATE.

5. **Send the verdict back** to the parent agent via messaging, using the format
   below.

```
## Referral Fraud Check: <email>

**Verdict: [APPROVE | DENY | INVESTIGATE]**

### Referrer Profile
- Plan / signup / own activity / already fraud-flagged

### Summary
- Total referrals, onboarded %, active %, fraud-flagged referees, duplicate
  devices, never-opened %, max referrals in one day

### Red Flags
- [list each red flag with evidence]

### Recommendation
- [1-2 sentence plain-language recommendation]
```

### Step 4: Present results

Present the verdict to the user. If they ask to post to Slack, format as mrkdwn
and post using `$BUZZ_SLACK_TOKEN` to `$APPROVALS_CHANNEL_ID`:

```python
import json, os, urllib.request

TOKEN = os.environ["BUZZ_SLACK_TOKEN"]
CHANNEL = os.environ["APPROVALS_CHANNEL_ID"]

payload = json.dumps({
    "channel": CHANNEL,
    "text": formatted_verdict,
    "unfurl_links": False,
    "unfurl_media": False,
}).encode()
req = urllib.request.Request(
    "https://slack.com/api/chat.postMessage",
    data=payload,
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read())
assert result["ok"], f"chat.postMessage failed: {result}"
```

## Notes

- When in doubt, prefer INVESTIGATE over APPROVE — approving fraud is more
  costly than a false positive.
- For referrers with very large referral counts, focus on aggregate patterns
  rather than listing every referee.
- Do not commit real thresholds, table names, project IDs, or environment IDs to
  this repository. Keep them in `.env` or private configuration.

