--- name: fake-data-guard description: Find demo, seed, and fixture data that can reach a real database or a real user — fabricated users, invented metrics, placeholder testimonials, hardcoded counts — and check whether anything actually stops it. Use before a launch, before seeding any shared environment, when adding a seed script, or when the user asks whether their numbers are real. --- # Fake Data Guard ## Install Save this file as `~/.claude/skills/fake-data-guard/SKILL.md`, or `.claude/skills/fake-data-guard/SKILL.md` to scope it to one repo. Claude Code auto-discovers it. Invoke with `/fake-data-guard` or by asking "could any fake data reach production?". ## Why this exists Every project grows demo data. Seed scripts with plausible users, fixtures with realistic-looking metrics, a placeholder testimonial nobody removed. All of it is correct locally and radioactive in production. The damage is asymmetric. A crash is embarrassing and recoverable. Published invented traction is a trust failure, and for anything that sells, reviews, or reports numbers it is the one mistake that cannot be walked back. It is also usually invisible: the fake row looks exactly like a real row. The path is almost always short and boring. A seed script one keystroke from a migration command in a runbook. A fixture imported by a component that ships. A constants file someone reached for because the real query was not ready yet. ## Step 1 — Find the fabricated data Search for the shapes, not the word "fake". Fabricated data rarely labels itself. **Invented people.** Realistic full names next to handles or emails in source: ``` rg -n "name:\s*['\"][A-Z][a-z]+ [A-Z][a-z]+['\"]" --type-add 'src:*.{ts,tsx,js,jsx,py,rb,go}' -tsrc rg -n "@(example|test|demo|acme)\.(com|org|local)" -tsrc ``` **Invented numbers.** Hardcoded counts, ratings, revenue, follower counts: ``` rg -n "(downloads|stars|users|revenue|rating|reviews|followers|installs|customers)\s*[:=]\s*[0-9]{2,}" -tsrc ``` **Invented words.** Testimonials and quotes with no source: ``` rg -n "(testimonial|quote|review|says|praise)" -tsrc ``` **The seeders themselves:** ``` rg --files -g '*seed*' -g '*fixture*' -g '*factory*' -g '*mock*' -g '*demo*' -g '*sample*' ``` Read what each one WRITES, not just its name. A file called `sample-data.ts` may be inert; a file called `bootstrap.ts` may create 500 users. ## Step 2 — Trace the reach of each finding For every candidate, answer one question: **can this reach a real database or a real user?** Trace it, do not assume. ``` rg -n "getProducts|SEED_|FIXTURES|DEMO_" --type-add 'src:*.{ts,tsx,js,jsx}' -tsrc ``` Follow every import. Classify honestly: - **REACHABLE — writes.** A script or job that inserts fabricated rows into whatever database it is pointed at. Highest severity. - **REACHABLE — renders.** Fixture data imported by shipped UI. It will be seen. - **DORMANT.** Present but nothing imports it today. Still report it: dormant data is one careless import from reachable, and it will be reached for precisely when someone is in a hurry. - **CONTAINED.** Provably test-only, by a guard you have READ, not by convention. Watch for partial safety, which is the most dangerous result. A script that discards fabricated sellers but copies fabricated counts is not safe, and it will be described as safe by whoever wrote it. ## Step 3 — Check whether anything actually stops it For every REACHABLE-writes finding, look for a guard and read it: - An environment check (`NODE_ENV`, an explicit opt-in variable). - A target check: does it inspect the connection string and refuse a non-local host? - An interactive confirmation. Then check how easy the mistake is. Is it exposed as a friendly script name (`npm run seed`)? Does documentation put it next to a command someone runs on a real environment? Is it named similarly to a safe script? **A guard's job is to survive a tired person at 3am, not a careful person at noon.** `NODE_ENV !== "production"` is weak on its own. Local shells frequently have no `NODE_ENV` while pointing at a production connection string. Prefer inspecting the actual target. ## Step 4 — Fix, in this order 1. **Delete** anything fabricated that nothing needs. Least code, least risk. 2. **Guard** what must stay. Refuse by default, inspect the real target, exit non-zero, and print what to run instead: ``` REFUSING: DATABASE_URL does not point at a local database. target host: This script creates FABRICATED users and metrics. Local development only. To populate a real environment, run instead: ``` 3. **Separate.** Move fabricated fixtures out of any directory shipped code imports from. 4. **Verify the guard fires.** Run it against a production-shaped connection string and confirm it refuses and exits non-zero. Run it against a local one and confirm it still works. An unverified guard is decoration. ## Step 5 — Report ``` Fabricated data found: sites REACHABLE-writes: <- fix first REACHABLE-renders: DORMANT: CONTAINED: Guards present: Shortest path to production: ``` That last line is the finding. "A seed script exists" is not alarming. "`npm run seed` is one line below `db push` in the recovery runbook and has no guard" gets fixed today. ## Rules - Trace reachability; never assume a file is unused because of its name. - Report dormant data too, with its severity honestly lowered. - Never propose replacing fabricated data with better fabricated data. If a number is not real, the fix is to show nothing, or to show zero and say zero. - An empty state is not a bug. "No reviews yet" outperforms an invented review the first time someone checks. --- From [Toolbay](https://toolbay.ai/product/fake-data-guard). Free to use, modify, and share. Keep this line and others can find it too.