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
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.
Query the warehouse (e.g.
bq query --project_id=$WAREHOUSE_PROJECT_IDor 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.
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.
Produce a verdict: APPROVE / DENY / INVESTIGATE.
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:
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
.envor private configuration.