follow-the-money
Context load
Run rainmaker context --check first. It prints what exists, what is stale, and exits 1 if anything this skill requires is missing.
Then read, in this order:
context/business.mdin full. If absent, stop: "No business context. Runrainmaker audit, then theknow-my-buyerskill."context/voice.mdif this skill writes prose. If absent, stop and say so.context/glossary.mdif this skill names products, features or competitors.data/strategy.jsonif this skill reads or writes strategy.- Only the
data/files listed in this skill's Consumes table. Never crawl or call an API the core already covers.
If strategy.json.context_hash does not match the current hash of context/business.md, say exactly:
"Business context was edited after the strategy was written. Re-run know-my-buyer, or run rainmaker context --sync to accept the prose as authoritative."
Then stop.
If context/business.md carries confidence: stub, continue, and stamp every output with: "Built on a stub context. Nothing in it came from a buyer. Run know-my-buyer to replace it."
Consumes
| File | Why | If missing |
|---|---|---|
data/snapshots/<latest>/diagnosis.json |
tier distribution across all pages | run rainmaker audit |
data/snapshots/<latest>/ga4.json |
sessions and key events per tier | continue at confidence 0.5, ranking on sessions only |
data/state.json |
which findings are open, so this is grounded in current state | run rainmaker audit |
Produces
clusters[].target_tier (shared owner with pick-my-battles), the revenue narrative section of context/business.md.
Refuses when
Never refuses outright; degrades. With key_events_configured empty, state so in the confidence section, skip every step depending on key events, and rank on sessions with confidence 0.5.
Procedure
- Build the tier distribution table from
state.json: how many pages sit in each tier. - Join sessions and key events per tier from
ga4.json. - Compute, per tier: share of pages, share of sessions, share of key events. The gap between those three shares is the entire point of this skill.
- State the imbalance in one sentence with numbers: for example, "Tier 3 is 78 percent of pages and 6 percent of key events."
- Map every URL in
config.primary_conversionto its measured key events. A declared conversion page with zero key events over the window is the single highest-value finding available here, and it is reported first, above any tier-distribution commentary. - Assign each cluster in
strategy.json.clustersatarget_tier: the tier its content should occupy, which is often not the tier its existing pages currently sit in.
Decision rules
- Never assert the imbalance is a mistake. State the numbers and let the reader draw the conclusion; a 78/6 split might be a deliberate content-marketing strategy with a long payback, and this skill's job is to make the tradeoff visible, not to declare it wrong.
- A zero-key-event declared conversion page is only reported as a finding when
key_events_configuredis non-empty and the page carries no outbound link to a host inconfig.offsite_conversion_hosts. Otherwise it is unmeasured, not broken, perspec/false-positives.mdsection 3.5. target_tieron a cluster may also be set bypick-my-battles; where the two disagree, the more recent write wins and adecisionsentry must explain why.
Output
## Revenue map
Tier 0: <n>% of pages, <n>% of sessions, <n>% of key events
Tier 1: ...
...
Declared conversion pages with zero measured key events:
<url>: 0 key events over <window>d (ga4.json, confidence <c>)
Cluster tier reassignments:
<cluster id>: currently tier <n>, should be tier <n>, because <reason>
Done when
The output states, in one sentence with numbers, where effort has gone and where money is made, every cluster has a target_tier, and the confidence section states plainly whether key events were configured.