# Chitmark farming-baseline analysis A free, read-only analysis that puts a dollar figure on how much of your free tier is being drained by AI-agent farming: fake signups spinning up credits and API keys. It runs on your machine, against your own data. Nothing leaves your system. - **Zero dependencies, zero installs, zero network calls**, pure Python 3.9+ stdlib, or Node ≥ 18 built-ins - **~200 lines, fully readable**, your engineers can audit it in 10 minutes or skip it entirely and reproduce the math themselves - **Public source:** [github.com/nonameuserd/dpa](https://github.com/nonameuserd/dpa) · Chitmark by Open Agent Ledger ## What you need Three CSV exports from your own warehouse: | File | Columns | Notes | | ---------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------- | | `signups.csv` | `user_id, signed_up_at, email_domain, ip, credits_granted` | `ip`, `email_domain`, `credits_granted` optional. `user_id` must match `usage.csv`. | | `usage.csv` | `user_id, used_at, credits_used` | One row per metered event. Any numeric unit. | | `conversions.csv` (optional) | `user_id, converted_at` | Accounts that became paying customers. | Timestamps: ISO (`2026-08-01T09:00:00`) or `YYYY-MM-DD HH:MM:SS`. ## Run ```bash # Python (3.9+) python3 farming-baseline.py --signups signups.csv --usage usage.csv \ --credit-cost-usd 0.002 --out summary.json # TypeScript: Node >= 24 (type stripping is built in, nothing to install) node farming-baseline.mts --signups signups.csv --usage usage.csv \ --credit-cost-usd 0.002 --out summary.json # TypeScript: any Node >= 18 (npx fetches tsx once; no project install) npx tsx farming-baseline.mts --signups signups.csv --usage usage.csv \ --credit-cost-usd 0.002 --out summary.json ``` The `summary.json` output (rounded aggregates and group counts, no identifiers) is the only thing worth sharing from the run. ## Try it first The `example/` folder has a small synthetic dataset (30 signups: 12 farm accounts and 18 normal users, 3 conversions). Run it to see what the output looks like before touching real data: ```bash cd example python3 ../farming-baseline.py --signups signups.csv --usage usage.csv \ --conversions conversions.csv --credit-cost-usd 0.002 --out summary.json ``` Expected output: 12 flagged accounts burning ~96% of credits with 0 conversions, 18 clean accounts with 3 conversions. (The committed `example/summary.json` is the outcome-backtest reference. Run the baseline against your own CSVs and review the printed report.) ## Options | Flag | Default | Meaning | | ------------------------ | --------------------- | --------------------------------------------------------------------------- | | `--credit-cost-usd` | 0 | Your cost per credit (blended infra cost or retail; pick one and say which) | | `--domain-cluster-min` | 3 | Accounts sharing an email domain to flag a cluster | | `--ip-cluster-min` | 3 | Accounts sharing an IP prefix to flag | | `--cluster-ip-prefix` | 24 | IPv4 prefix bits for clustering (/48 for IPv6) | | `--burst-window-minutes` | 15 | Signups this close together in a flagged group count as a burst | | `--burst-min` | 3 | Signups needed in a window for a burst | | `--ignore-domains` | common public domains | Comma-separated domains excluded from domain clustering | | `--out` | `summary.json` | Output path | ## Verify the file you received The scripts work correctly with **no network access**. Run them in a sandbox with the network unplugged if your security team wants proof. Compare checksums against this page and the GitHub repo: ```bash shasum -a 256 farming-baseline.py # macOS sha256sum farming-baseline.py # Linux ``` - `farming-baseline.py` → `8b54f92d6ceccd45b9ad369005ca7b08a12df1809f9c1f61d67769b70ead6d3f` - `farming-baseline.mts` → `fce09991717415010ee87c830f6bd6e17fa331c4b4d46909d337b526a644cbd0` - `outcome-backtest.py` → `845089831a44bacd2da2006c0ed3131040de7033a745c014ad0b4bdd92f21993` - `outcome-backtest.mts` → `f1990518f13c8eb9c8e1af8d3b0740d321e93894ae205452d069245cb5de0d93` ## What it computes - **Totals:** signups, accounts with usage, total credits used, conversions. - **Clusters:** accounts sharing an email domain (public domains excluded), accounts sharing an IP prefix, and burst signup windows within a flagged group. - **Fast label:** credits burned within 72h of signup. - **Dollar figure:** credits used by the flagged cohort × your per-credit cost, plus its share of total burn. Conservative by construction, it only counts accounts in clusters, never lone accounts. The 72h credit-burn and the conversion contrast (flagged vs. clean cohorts) are the numbers that separate farming cohorts from real users. ## Outcome backtest: the follow-up comparison The baseline puts a dollar figure on the farm. The **outcome backtest** answers the next question: would block decisions tuned by your outcomes (credit burn, conversion, chargeback) beat your current funnel-blind rules? The metric is **dollars saved per false-block**: same abuse stopped, fewer paying customers blocked. One CSV, three new columns on the same event IDs: | Column | Values | Meaning | | ------------------------ | -------------------------------- | ----------------------------------------------- | | `decision_funnel_blind` | `allow` / `block` | What your current rules decided | | `decision_chitmark` | `allow` / `block` | What outcome-tuned decisions would have decided | | `outcome` | `abuse` / `converted` / `silent` | The label your feedback joined to the event | | `credit_burn_usd` (opt.) | number | Credits burned × your cost basis | | `chargeback_usd` (opt.) | number | Chargeback value | | `converted_usd` (opt.) | number | Revenue from a converted account | ```bash python3 outcome-backtest.py --events events.csv --out summary.json node outcome-backtest.mts --events events.csv --out summary.json # Node >= 24 ``` - `--label-maturity-days 14` (default): drops events signed up within the last 14 days, their outcome labels have not matured yet (burn shows up at 24-72h, conversions later). `0` disables. - `--false-block-cost-usd`: substitute a flat value for `converted_usd` if you don't export revenue. Try it first with `example/events.csv`: the reference result is `example/summary.json`. Both implementations produce **byte-identical** `summary.json` (verified against the shared fixture). Same guarantees as the baseline: offline, stdlib only, aggregates only. ## License Business Source License 1.1: free to run, audit, modify, and use for your own internal analysis (including production use on your own data). The only thing the license restricts is offering the scripts (modified or not) to third parties as a product, service, or hosted offering. The Licensed Work converts to Apache License 2.0 on 2030-08-08. Full text in [LICENSE](LICENSE).