threadify-go-make-money · diff
git:20261020.7ffad50 to git:20261021.ae7c112
43 added, 18 removed. Audit B to B.
---
name: threadify-go-make-money
- description: Give Claude your real money goal, not a task. Go Make Money reads your raw Threads money data through Threadify (posts, tracked clicks, signups, offers and the page your links land on), finds the biggest leak in your funnel with receipts, tests your own belief about why, has a different model judge the diagnosis, lists the 3 claims a skeptical buyer would doubt, argues three decisions and ships fix #1 after one exact yes, then saves a goal ledger so the next run grades the fix on the same numbers. Use when someone says "go make money", "get me to N paying customers by <date>", asks where their funnel leaks, or why clicks do not turn into signups.
+ description: Give Claude your real money goal, not a task. Go Make Money finds and confirms what actually makes you money, reads your raw Threadify rows (posts, tracked clicks, signups, offers and the page your links land on), finds the biggest leak with receipts, tests your belief about why, has a different model judge it, plans the best actions for your setup with you, then writes one post from a proven viral structure with an Auto Plug built from your best CTAs and schedules it after one yes. It ends with a celebration page and an optional Claude check-in that grades the fix on the same numbers. Use when someone says "go make money", "get me to N paying customers by <date>", asks where their funnel leaks, or why clicks do not turn into signups.
---
# Go Make Money
- "Claude, go make money" usually fails because Claude cannot see the money. Go Make Money gives it eyes and hands: your goal goes in, your raw Threadify rows get read, a script does every number, and one fix ships after your yes.
+ "Claude, go make money" usually fails because Claude cannot see the money. Go Make Money gives it eyes and hands: your goal goes in, your raw Threadify rows get read, a script does every number, you agree the plan, and one post ships after your yes.
It is free: the workflow runs in your agent on your computer. The reads, the offer, the Auto Plug and the scheduled post run on your Threadify account.
- Follow [Threadify-001: setup and first-loop video](references/threadify-001.md) before the first connected call. A connection never authorizes a change. Only the owner's exact "yes" to the fix card does.
+ Follow [Threadify-001: setup and first-loop video](references/threadify-001.md) before the first connected call. A connection never authorizes a change. Only the owner's "yes" in chat does.
- Resolve `scripts/` and `references/` paths against the directory containing this SKILL.md. The script is `node scripts/go-make-money.mjs` (Node 18+, no npm packages); every command prints JSON and the agent never does funnel sums in its head.
+ Resolve `scripts/` and `references/` paths against the directory containing this SKILL.md. The script is `node scripts/go-make-money.mjs` (Node 18+, no npm packages); every command prints JSON and the agent never does funnel sums in its head. The run folder is `./go-make-money/<YYYY-MM-DD>/`.
## Rules
- Follow [demo feedback rules](references/demo-feedback-rules.md) for the whole run. If `~/.threadify/owner-overlay.md` exists, read it too and follow it; it is private, so never quote it into posts, files you publish or receipts.
- **Outcome, not task.** Work from the goal. At every step ask "what has to happen next for the goal?", not "what was I asked to do?".
- **Raw rows, never summaries.** Every count comes from per-link and per-post rows through the script. A tool summary is only a cross-check (`summary_check`).
- **Unknown stays unknown.** A number the tools did not return is UNKNOWN, never 0. An unknown baseline is labelled "needs real baseline". A small sample is called a small sample.
- **No guarantees.** Never promise revenue, customers or results. Say "attributed", not "caused". Say "signups" or "conversions" exactly as the rows label them; say "paid" only for rows with a sale.
- **Privacy.** Aggregates only. Never print, save or show signup names or emails, credentials, tokens or account ids.
- - **Public copy** (posts, Auto Plugs, offer text, page copy): no em dashes, lowercase with proper nouns kept, one CTA, plain words. It must pass `go-make-money.mjs check-copy`. Threadify writes posts with `generate_content`; the agent may only lowercase them and proves `lower(original) == lower(final)` with `scripts/casing-guard.mjs`.
- - **One fix, one yes.** Show the exact change, ask "yes" once, then do it and read it back. Never publish now. Never merge a pull request.
+ - **No code assumed.** Plan for this owner's setup, not a developer's. No-code actions come first: the Auto Plug, the existing offer's copy or destination, a post, page copy they can paste. A pull request only when the site's repo is open in this session and they want one.
+ - **Reuse the offer.** Never create a new offer per run. Use the offer the money activity already points to; the Auto Plug carries this run's specific message. `create_offer` only when the owner has no offer at all, as its own action with its own yes.
+ - **Channel casing.** Threads posts and Auto Plugs are lowercase with proper nouns kept (`check-copy`). Site and offer copy keeps the site's own casing (`check-copy --channel site`). Both: no em dashes, one CTA, plain words a 10-year-old gets.
+ - **Threadify writes, the agent lowercases.** Posts come from `generate_content`; the agent may only lowercase them and proves `lower(original) == lower(final)` with `scripts/casing-guard.mjs`. A copy warning means a new `generate_content` call, never a hand edit.
+ - **The chat yes is the approval.** Show the exact change, ask once, do it, read it back. Never publish now. Never merge a pull request. If the host (an approval queue, a hook or a gate) holds a call after the yes, say so in one line with where to approve it, then wait. Never route around it and never retry another way.
+ - **Show it in chat.** Print every post and Auto Plug in full as plain chat text, never only inside a card, box, next-step prompt or file.
## Steps
- 1. **Goal (altitude).** Call `get_connection_defaults` first and say only "@handle · timezone". If a ledger exists (`node scripts/go-make-money.mjs ledger read`), do step 9's grade first, before anything else. Take the owner's goal; the default prompt shape is "go make money: get me to <N> paying <customers/members> by <date>". Ask once for the current number if it is not readable from the owner or their own data: "How many paying <metric> do you have today? Say unknown if you're not sure." Run `node scripts/go-make-money.mjs goal --dir <run> --text "<goal>" --current <N or unknown>` (run folder `./go-make-money/<YYYY-MM-DD>/`). Say its `line`: `required_net_new_per_week = ceil((goal - current) / weeks_left)`, or UNKNOWN with "needs real baseline".
- 2. **Raw data (depth).** Read through Threadify and save each result as returned in `<run>/raw/`: `read_post_performance` (`days: 30`, `include_full_text: true`, a `limit` above `total_matched`; also `days: 90` if it is one more call), `read_link_attribution` (`days: 30`, a `limit` high enough for every link), `get_growth_signal`, `list_offers`, and `read_conversion_setup` or `check_conversion_tracking`. Optional files the owner put in `data/` (for example YouTube analytics JSON with average % viewed, a retention curve and CTA timestamps) are read too. Run `node scripts/go-make-money.mjs funnel --dir <run> --attribution <run>/raw/attribution-30d.json --performance <run>/raw/performance-30d.json --dest <the owner's own site host> --days 30` (the owner's site is where a signup can happen; leave out `--dest` only when unsure, and say so). Show its `table` as is: views -> clicks -> signups -> paid, with each step's rate. If conversion tracking is not measurable, signups and paid are UNKNOWN; say so. Fetch the public page the tracked links point to: `node scripts/go-make-money.mjs page-text --url <destination> --out <run>/page.txt` (public pages only, no logins).
- 3. **The leak.** Name the single biggest drop from the script's `leak` with its receipts (the exact rows it prints): "The leak: <from> -> <to>: <out> of <in> (<rate>%)." The leak is the step furthest below its rule-of-thumb yardstick (views -> clicks 1%, clicks -> signups 5%, signups -> paid 5%); a step with fewer than 20 going in is a small sample and is not named the leak while a bigger step exists. The yardsticks only compare steps; they are not targets or promises.
- 4. **Challenge one belief.** Ask one question: "Why do you think this happens?" Then test the answer against the raw rows and say supported, not supported or unknown, with the evidence:
- - "The link lands on a page that doesn't match what the post or video promised": write the promise (the post text, or the video title and the line where the link is mentioned) to `<run>/promise.txt` and run `belief --dir <run> --kind page-mismatch --promise <run>/promise.txt --page <run>/page.txt`. Show the score and the promise words missing from the page.
+ ### Find the money
+
+ 1. **Start.** Call `get_connection_defaults` first and say only "@handle · timezone". Then read the ledger first: `node scripts/go-make-money.mjs ledger read`. If it has an entry, run step 4's reads and `funnel`, then `ledger grade --dir <run>` and say its `line` (the same step, before vs now, attributed not caused) before anything else.
+ 2. **Goal (altitude).** Take the owner's goal; the default prompt shape is "go make money: get me to <N> paying <customers/members> by <date>". Ask once for the current number if it is not readable from the owner or their own data: "How many paying <metric> do you have today? Say unknown if you're not sure." Run `node scripts/go-make-money.mjs goal --dir <run> --text "<goal>" --current <N or unknown>`. Say its `line`: `required_net_new_per_week = ceil((goal - current) / weeks_left)`, or UNKNOWN with "needs real baseline".
+ 3. **The money activity, confirmed.** Read `read_link_attribution` (`days: 30`, a `limit` high enough for every link) and `list_offers`, save both as returned in `<run>/raw/`, and run `money --dir <run> --attribution <run>/raw/attribution-30d.json --offers <run>/raw/offers.json`. Say its `line` and ask one question: "Is that where your money comes from? If not, tell me what people pay you for and where." With no tracked links, ask that question straight away. Everything after this works on the confirmed activity, its destination and its offer.
+ 4. **All the data, and what is missing.** Read through Threadify and save each result as returned in `<run>/raw/`: `read_post_performance` (`days: 30`, `include_full_text: true`, a `limit` above `total_matched`; also `days: 90` if it is one more call), `get_growth_signal`, and `read_conversion_setup` or `check_conversion_tracking`. Read any files the owner put in `data/` (for example YouTube analytics with average % viewed, a retention curve and CTA timestamps). Then name what this money activity needs that is not connected yet, up to three in one message, each with the one thing it unlocks: conversion tracking (`setup_conversion_tracking`: signups and paid become countable), the payment tool's connector (paid becomes real, not UNKNOWN), site analytics (what happens between the click and the signup), YouTube analytics in `data/` (CTA reach), and the site's code repo (a page fix as a pull request). Carry on with what is connected; never block on a suggestion.
+ 5. **The funnel and the leak.** Run `funnel --dir <run> --attribution <run>/raw/attribution-30d.json --performance <run>/raw/performance-30d.json --dest <the confirmed destination host> --days 30`. Show its `table` as is: views -> clicks -> signups -> paid, with each step's rate. If conversion tracking is not measurable, signups and paid are UNKNOWN; say so. Name the single biggest drop from `leak` with its receipts: "The leak: <from> -> <to>: <out> of <in> (<rate>%)." It is the step furthest below its rule-of-thumb yardstick (views -> clicks 1%, clicks -> signups 5%, signups -> paid 5%); a step with fewer than 20 going in is a small sample and is not named the leak while a bigger step exists. Say the `upside` line too; it is a yardstick, not a target or a promise. Fetch the public page: `page-text --url <destination> --out <run>/page.txt` (public pages only, no logins).
+ 6. **Challenge one belief.** Ask one question: "Why do you think this happens?" Then test the answer against the raw rows and say supported, not supported or unknown, with the evidence:
+ - "The link lands on a page that doesn't match what the post or video promised": write the promise (the post text and its Auto Plug, or the video title and the line where the link is mentioned) to `<run>/promise.txt` and run `belief --dir <run> --kind page-mismatch --promise <run>/promise.txt --page <run>/page.txt`. Show the score and the promise words missing from the page.
- "People don't get far enough to see the CTA": run `belief --dir <run> --kind cta-reach --youtube data/<file>.json` (add `--cta-seconds N` if the owner says when the CTA is). A retention curve is strong evidence; an average view duration alone is weak and is labelled so; no data is unknown.
- Any other belief: test it against the saved raw rows the same way (which rows, which numbers), and say unknown when the rows cannot answer it. Never agree just because the owner said it.
- 5. **Outside judge.** Write a two to four sentence diagnosis to `<run>/diagnosis.txt` (the leak, the belief verdicts, what you think is going on). Run `node scripts/go-make-money.mjs judge --dir <run>`. It sends only the diagnosis and the raw funnel table (never the chat) to a different model: `codex exec -s read-only "<prompt>"` when Codex is installed, otherwise a fresh Claude instance with no prior context. It has a hard 4-minute limit. Say which judge ran (`judge_label`, `model`), its verdict (agree or dispute) and its reasons. Show a dispute in full; never hide it. If it was stopped or gave no verdict, say so in one line and carry on.
- 6. **Range: the short seller.** Do what a short seller does: read the offer and the landing page looking for what will not hold up. Write `<run>/short-seller-input.json` as `{"claims": [{"quote": "<exact words from the page>", "doubt": "<why a skeptical buyer would doubt it>", "evidence": "<the row, number or missing proof that would make them doubt it>"}]}` with exactly 3 claims, and run `short-seller --dir <run> --file <run>/short-seller-input.json --page <run>/page.txt`. Every quote must be on the page word for word (the script checks).
- 7. **Three decisions.** Write `<run>/decisions-input.json` with exactly 3 decisions that attack the leak: `{"decisions": [{"title", "fix_kind": "offer" | "post" | "landing-page-pr" | "other", "for": [...], "against": [...], "impact": 1-3, "speed": 1-3, "reversibility": 1-3}]}`, and run `rank-decisions --dir <run> --file <run>/decisions-input.json`. Show the three ranked by impact on paid conversion x speed x reversibility, each with its for and against. Then run `report --dir <run>` and open `<run>/report.html` (step 10).
- 8. **Ship fix #1 with one exact yes.** Follow [the fix step](references/fix.md) for the top-ranked decision. Allowed actions only: (a) update or create the Threadify offer, its Auto Plug and tracked link so the destination and the copy match the promise; (b) one post written by Threadify `generate_content` about the decision, casing guard, then `schedule_post` at the best time after the yes; (c) optional: when the site's git repo is open in this session, a small landing-page copy change on a new branch and a pull request (`gh pr create`), printing the PR URL and preview URL. Never merge it. Show the exact change, ask "yes" once, do it, read it back, and write the readbacks to `<run>/fix.json`.
- 9. **Make it durable.** Save the goal ledger: write `<run>/ledger-entry.json` with `goal` (`number`, `metric`, `deadline`), `baseline` (number or "UNKNOWN"), `pace`, `leak` (`step`, `upstream`, `downstream`, `rate_pct`), `decision`, `fix` (`kind`, `ids`: offer id, schedule id, PR URL), and `date`, then `ledger save --entry <run>/ledger-entry.json` (it saves to `~/.threadify/go-make-money/ledger.json` and refuses an entry with an email in it). **On the next run, read the ledger first**: run steps 2's reads and `funnel`, then `ledger grade --dir <run>` and say its `line` (the same step, before vs now, attributed not caused) before anything else.
- 10. **The report.** `node scripts/go-make-money.mjs report --dir <run>` writes `<run>/report.html`: the goal, a big leak card, the funnel table, the belief verdicts, the judge, the short seller, the three decisions and the fix readbacks. Serve it on this computer only (`python3 -m http.server 8051 --bind 127.0.0.1 --directory <run>` in the background) and open `http://127.0.0.1:8051/report.html` with the host's browser tool, or `open -a "Google Chrome" http://127.0.0.1:8051/report.html` (macOS). Confirm it opened. Re-run `report` after the fix and the ledger so the page shows them. Stop the server when the run ends.
+ 7. **Outside judge.** Write a two to four sentence diagnosis to `<run>/diagnosis.txt` (the leak, the belief verdicts, what you think is going on). Run `judge --dir <run>`. It sends only the diagnosis and the raw funnel table (never the chat) to a different model: `codex exec -s read-only "<prompt>"` when Codex is installed, otherwise a fresh Claude instance with no prior context. It has a hard 4-minute limit. Say which judge ran (`judge_label`, `model`), its verdict (agree or dispute) and its reasons. Show a dispute in full; never hide it. If it was stopped or gave no verdict, say so in one line and carry on.
+ 8. **The short seller.** Do what a short seller does: read the offer and the landing page looking for what will not hold up. Write `<run>/short-seller-input.json` as `{"claims": [{"quote": "<exact words from the page>", "doubt": "<why a skeptical buyer would doubt it>", "evidence": "<the row, number or missing proof>"}]}` with exactly 3 claims, and run `short-seller --dir <run> --file <run>/short-seller-input.json --page <run>/page.txt`. Every quote must be on the page word for word (the script checks).
+ ### Plan it with the owner
+
+ 9. **The action plan.** Write `<run>/decisions-input.json` with exactly 3 actions that attack the leak and fit this owner's setup, no-code first: `{"decisions": [{"title", "fix_kind": "offer" | "post" | "page-copy" | "landing-page-pr" | "other", "for": [...], "against": [...], "impact": 1-3, "speed": 1-3, "reversibility": 1-3}]}`, and run `rank-decisions --dir <run> --file <run>/decisions-input.json`. Show them ranked by impact on paid conversion x speed x reversibility, each with one line of why and its for and against. Then ask: "Here's what I'll do, in this order, and why. OK?" Change the plan as the owner pushes back until they say yes; the agreed plan is the scope. Run `report --dir <run>` so the full diagnosis is saved (the reward page links to it).
+ 10. **Do it, most important first.** Follow [the action step](references/fix.md) for each agreed action in order. When an action is slow (a pull request, page copy, a connector), start it, ship the post (steps 11 to 13), then finish it. Each change to the account or the public shows its exact content and gets one yes.
+
+ ### Ship the post
+
+ 11. **The post, from a proven full structure.** Build the template library: `greatest_hits` (all-time, by views and by engagement), `list_vault_items` (`sort_by: "most_liked"`, open picks with `get_vault_item`), `list_viral_items` (`sort_by: "most_liked"` with a topic `query`, open picks with `get_viral_item`), the Viral Vault's `search_corpus` and `get_template` when that connector is on, and `library --dir <run> --attribution <run>/raw/attribution-30d.json` (the owner's own posts that drove the most clicks). Pick the one post whose whole structure fits this story and turn the WHOLE post into a template (hook, line breaks, list shape, length and ending), not just its hook. Then follow the fix step's post section. The post:
+ - Its hook carries a benefit for as many readers as possible, with specific numbers that do not shut most of them out.
+ - It has diary energy: what just happened to me, told like I just found out.
+ - It ends with a grand, bold, emotional so-what line for the reader.
+ - It never leads with numbers that kill social proof ("1 signup", "0 paid"); the leak is the discovery, not the confession.
+ 12. **The Auto Plug, from your best CTAs.** `library`'s `plugs_to_read` ranks each Auto Plug by the clicks it earned itself; read the top plugs' text with `get_post_thread`: that is the CTA library. Write one plug in the shape of the best one, specific to this post, pointing at the existing offer's destination. The fix step has the limits.
+ 13. **Show it, one yes, scheduled.** Print the post and the plug in full in chat as plain text. Pick the next best time (fix step) and ask one question: "Reply yes to schedule this for <weekday date, local time>, with the plug 50 minutes later." On yes: `schedule_post`, read it back with `get_schedule_status`, and say the readback in one line.
+
+ ### Keep score and celebrate
+
+ 14. **Make it durable.** Write `<run>/ledger-entry.json` with `goal` (`number`, `metric`, `deadline`), `baseline` (number or "UNKNOWN"), `pace`, `leak` (`step`, `upstream`, `downstream`, `rate_pct`), `decision`, `fix` (`kind`, `ids`: offer id, schedule id, PR URL), and `date`, then `ledger save --entry <run>/ledger-entry.json`. It saves to `~/.threadify/go-make-money/ledger.json` and refuses an entry with an email in it. **On the next run, read the ledger first** (step 1).
+ 15. **The celebration.** Write `<run>/reward-input.json`: `{"why": "<the leak in one plain sentence>", "what": ["<each thing done, with its readback>"], "next": "<the one next step>", "post": {"text", "plug", "when", "plug_delay": "50 min later"}, "tz": "<owner timezone>"}` (optional `headline`, `headline_2`, `share`; no emails, no weak counts in `share`). Run `celebrate --dir <run>`. It writes `<run>/reward.html`, a Threadify-branded page with confetti: progress to the goal, six achievements, why (the leak), why it's a big deal (the upside and the pace), what we did, the post, the value, the next step, the check-in, a share line, and a star for Threadify Workflows on GitHub. Serve it on this computer only (`python3 -m http.server 8051 --bind 127.0.0.1 --directory <run>` in the background) and open `http://127.0.0.1:8051/reward.html` with the host's browser tool, or `open -a "Google Chrome" http://127.0.0.1:8051/reward.html` (macOS). Confirm it opened.
+ 16. **The check-in.** Ask one question: "Want Claude to check in on <weekday date, about 7 days after the post goes out>, read your numbers and grade this fix?" On yes, book it with the host's own scheduler: a one-time scheduled task in the Claude desktop app (`create_scheduled_task` with `fireAt`), a `/schedule` routine in Claude Code, or an automation in Codex. Its prompt must stand alone: "Use $threadify-go-make-money. Check-in: read the ledger first and grade my last fix on the same numbers." Read it back from the scheduler, then run `checkin --dir <run> --at <YYYY-MM-DDTHH:MM> --tz <timezone> --when "<weekday date, time>" --how "<what booked it>" --scheduled` and re-run `celebrate` so the check-in badge unlocks. With no scheduler (or if the booking can't be read back), run `checkin` without `--scheduled`: it writes `checkin.ics`, and the page says the reminder is ready and offers "Add to calendar", never that Claude will check in. Stop the server when the run ends.
+
## When something is missing
- No Threadify connection: say "Connect Threadify at threadify.app so Claude can see your posts, clicks and signups" and stop after the goal. No tracked links or no clicks in 30 days: say so plainly, show the funnel with UNKNOWNs and make decision 1 "add one tracked link to the next post". Conversion tracking not set up: say signups are UNKNOWN and offer `setup_conversion_tracking` as a decision (it needs its own yes). No Codex and no `claude` command line: say the outside judge could not run, and carry on without inventing a verdict. Auto Plug tier-blocked: follow the fix step and offer the post without a plug. A scheduled post is not a published post, a click is not a sale, and an opened pull request is not a shipped page.
+ No Threadify connection: say "Connect Threadify at threadify.app so Claude can see your posts, clicks and signups" and stop after the goal. No tracked links or no clicks in 30 days: say so plainly, show the funnel with UNKNOWNs and make action 1 "add one tracked link to the next post". Conversion tracking not set up: say signups are UNKNOWN and offer `setup_conversion_tracking` as an action (it needs its own yes). No Codex and no `claude` command line: say the outside judge could not run, and carry on without inventing a verdict. Auto Plug tier-blocked: follow the fix step and offer the post without a plug. A host gate holding the schedule: say where to approve it and wait; the post is held, not scheduled. A scheduled post is not a published post, a click is not a sale, and an opened pull request is not a shipped page.