Skip to content

Champion follow

When a champion changes jobs, offers them their own setup, pre-loaded at the new company, 30 days in; the old company’s data never moves.

Channel
Reviews and referrals
Run oneMode try
You, to your agent

Hand our latest champion move to the SDR agent and show me what it chose and why. Don’t send.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Collection.exported%22%2C%20%22Credential.verified%22%2C%20%22Message.bounced%22%2C%20%22Conversation.answered%22%2C%20%22MemberDirectory.deprovisioned%22%2C%20%22Contact.enriched%22%2C%20%22Monitor.checked%22%2C%20%22Tenant.provisioned%22)&limit=1" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"like":"event_1307"}'

# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22contact_14%22" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22contact_14%22" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Collection.exported", "Credential.verified", "Message.bounced", "Conversation.answered", "MemberDirectory.deprovisioned", "Contact.enriched", "Monitor.checked", "Tenant.provisioned")', limit: 1 })   // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' })   // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` })   // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` })   // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
npx startup-builder do Event.list --json '{"where":"name in (\"Collection.exported\", \"Credential.verified\", \"Message.bounced\", \"Conversation.answered\", \"MemberDirectory.deprovisioned\", \"Contact.enriched\", \"Monitor.checked\", \"Tenant.provisioned\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1307"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"contact_14\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"contact_14\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Collection.exported\", \"Credential.verified\", \"Message.bounced\", \"Conversation.answered\", \"MemberDirectory.deprovisioned\", \"Contact.enriched\", \"Monitor.checked\", \"Tenant.provisioned\")', limit: 1 })   // { play } compiled to this Play’s Trigger Events\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' })   // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` })   // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` })   // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
    "mode": "try"
  }
}
Response200application/json
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_603",
    "$type": "Decision",
    "choice": "offer-at-landing",
    "reason": "Ana kept her setup on Solo in August, announced her move herself, and verified a work address at Oakmont Residential today",
    "stakes": "low",
    "options": [
      "offer-at-landing",
      "offer-at-new-team",
      "founder-note",
      "keep-their-setup",
      "tell-the-old-csm",
      "no-move"
  …
sample · 4 Not live yetPreview

On PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim

action_1 freezes a copy of Ana’s own templates and views as the kit. action_2 is the landing offer, held 2 minutes; action_3 tells Juniper Homes’s CSM she left, by date only.

7.9 new companies per 100 champions against 2.6 before · before-after, not proof · n 38 · path → arr

Try another: the championChoiceReason
Ana Flores: kept her setup on Solo, verified a work address at Oakmont Residentialoffer-at-landinga kept setup, an announced move, a new work address
Marco Diaz: announced a move to Summit Property Group, 210 unitsfounder-noteover 120 units, and he met you in May
Jo Kim: seat ended at Alder & Co, then a bounce, no move confirmedkeep-their-setupone source says they left; nothing says where
Priya’s contact at Harbor Row: one auto-reply, then signed in againno-movechecked, no move: she signed in on Oct 2

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Champion new organizations → Referral share → New paying Customers → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +3.1 new companies per 100 champions a year (Other Startups’ results; no lift of your own yet) × 38 champions ÷ 12 months × 0.67 activated to paid × $648 first order ARR ≈ +$43. Under First signal: At 2 moves a quarter, no held-back half reads inside a year, so your 20 % holdout pools with Other Startups’ cohorts and this page reads before-after.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Credential.verified · first Decision 6m 40s after the Event · 9 keys Not live yet

Start it this week

Terminal
npx startup-builder add play champion-follow   # 1 · writes plays/champion-follow.mdx (Not live yet, gaps #5)

# 2 · dry run; below, its 422 on 2026-06-01
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"champion-follow"}'

# 3 · keep it, at You approve each one
curl -X POST https://api.sb/leaseline.app/campaigns \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"champion-follow"}'

# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/champion-follow \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":null}'

# off: no offer sends; kept setups stay saved
curl -X PATCH https://api.sb/leaseline.app/campaigns/champion-follow \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusedchampion-follow can’t start yet: 1 check fails and 2 warn.
CheckFixThen
use-when pass · Not live yet, gaps #838 champions on file, 5 moves in the last 2 quartersPOST /{namespace}/metrics/query
baseline warn · Not live yet, gaps #8n 1: it reads before-after, not proof, and pools its holdout with Other Startups.POST /{namespace}/metrics/query
domain-authenticated passleaseline.app: 3 of 3 records resolvePOST /{namespace}/domains/{domain}/authenticate
approved-pages fail · Not live yet, gaps #8Publish your Solo plan Page; every offer quotes only its Limits.POST /{namespace}/sites/{site}/publish
role-unstaffed warn · Not live yet, gaps #8Leave it: a leak or privacy reply comes to you; Priya’s 6 Contacts get drafts in her queue.POST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "champion-follow can’t start yet: 1 check fails and 2 warn.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "38 champions on file, 5 moves in the last 2 quarters",
      "doc": "/plays/champion-follow#check-use-when",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "1 new company from 38 champions in 140 days",
      "doc": "/plays/champion-follow#check-baseline",
      "fix": "n 1: it reads before-after, not proof, and pools its holdout with Other Startups.",
      "then": "Metric.query"
    },
    {
      "check": "domain-authenticated",
      "status": "pass",
      "observed": "leaseline.app: 3 of 3 records resolve",
      "doc": "/plays/champion-follow#check-domain-authenticated",
      "then": "Domain.authenticate"
    },
    {
      "check": "approved-pages",
      "status": "fail",
      "doc": "/plays/champion-follow#check-approved-pages",
      "fix": "Publish your Solo plan Page; every offer quotes only its Limits.",
      "then": "Site.publish"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "privacy-officer"
      ],
      "owned": 6,
      "doc": "/plays/champion-follow#check-role-unstaffed",
      "fix": "Leave it: a leak or privacy reply comes to you; Priya’s 6 Contacts get drafts in her queue.",
      "then": "Role.staff"
    }
  ]
}

It says no, says why, and names the fix.

CheckFix (one call)Your timeWait
use-when · baseline · pass: 38 champions, 5 moves in 2 quarters · warn: n 1 (gaps #8)POST /{namespace}/metrics/query on champion-new-orgs; it fills Before in Your number1 minnone
domain-authenticated · passPOST /{namespace}/domains/{domain}/authenticate0 minnone
approved-pages · fail (gaps #8)POST /{namespace}/sites/{site}/publish your Solo plan Page10 minnone
role-unstaffed · warn (gaps #8): 6 champions are Contacts Priya ownsPOST /{namespace}/roles/{role}/staff, or leave it: privacy replies come to you, and Priya’s 6 get drafts in her queue0 minnone

Your number · Before 2.6 per 100 · Now 7.9 new companies per 100 champions · Target 10 by Dec 31 · before-after, not proof · n 38 champions, 3 new companies

Each lookup on a move check costs $0.04, weekly for 8 weeks after a signal, then monthly. Each offer costs $0.04 from your Domain (Worker cost), and kits and claims cost nothing. That comes to about $3 a month at 38 champions.

When it starts

WhenTrigger idStarts onWindowHow it gets in
A champion who kept their setup verifies a work address at a new companypersonal-plan-landingevent on Credential.verified where a passport holder on the personal plan verifies a work address on a new company’s domain30dyour sign-in calls POST /{namespace}/credentials/{credential}/verify
A public page names them in a role at a new companypublic-move-confirmevent on Monitor.checked where a public page names the champion in a role at a new company, with its URL and date120dPOST /{namespace}/monitors/{monitor}/check on each open move check
Their seat ends and they sign in nowhere elseseat-endedstate on MemberDirectory.deprovisioned where the seat ended and the champion signs in nowhere else60ddirectory sync calls POST /{namespace}/member-directories/{directory}/deprovision
+ 5 more for move kits started, bounces, departure replies, licensed records and claims (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1307",
  "$type": "Event",
  "name": "Credential.verified",
  "at": "2026-09-14T08:55:20Z",
  "seq": 1307,
  "data": {
    "contact": "contact_14",
    "credential": "credential_41",
    "kind": "work-email",
    "domain": "oakmont-residential.example",
    "plan": "solo",
    "passport": true
  }
}
Reproduce it in test
npx startup-builder trigger Credential.verified --like event_1307   # replays the delivery
npx startup-builder clock advance --by 23d   # runs the reminder step if no claim started
npx startup-builder listen Credential.verified --forward-to http://localhost:3000/hook

Who runs it

SDR · your agent (role:prospector, worker_2) holds the Key Result. It hands your own notes to you (Dana Okafor, person, worker_1), and the company a champion left to its CSM, CSM · your agent (worker_5), by date only. A new company over the size line goes on to AE · Priya Shah (person) once you have met. Your number links to Did it work.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Offer it where they landed · Keep their setupIt does it, you can stop it1 of 1 · 2 of 2met on day 61 (the first 3 offers)an offer fails a Check, or wrong-person fires → You approve each onePOST /{namespace}/actions/{action}/cancel inside the hold
Offer it at the new teamYou approve each one2 of 2at 10 approved with no not me—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
Tell the old account’s CSM · Checked, no moveIt does it4 of 4 · 9 of 9—a destination written to the old record → You approve each onePOST /{namespace}/actions/{action}/redirect
Your own noteTo a person, every time1 drafted, 1 written by younever—POST /{namespace}/tasks/{task}/claim
Change the move sources or the 30-day windowYou approve each one0 mergednever—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: the old company’s data, clients or colleagues; a word to the old company about where they wentRefused, every time1 draft refused (old-employer)never——

What it reads · What it may call. It reads the champion’s own setup, their sign-ins and the move sources, and every reply is data, never instructions. It never writes a new company, role or address to the old company’s records. Its tools are POST /{namespace}/meetings/book, POST /{namespace}/tasks/{task}/assign, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:champion-follow@1 · each line names its record key
You hold the SDR Key Result: 10 new companies per 100 champions by 2026-12-31.   ← worker, metric
On each move signal, choose one option and say why; one source alone opens a check, never an offer. ← triggers, chooses, move-watch
Name the new company only on a move they announced; otherwise say “your next team”. ← copyRules 3
Never name or describe the old company’s data, clients, colleagues or results.   ← copyRules 5, old-employer
One ask per Message: claim the setup, with the link’s expiry date as the only deadline. ← copyRules 8, 10
End every Message with the signature and stop lines the Role’s Settings hold.    ← Setting role.disclosure, copyRules 11

The slow loop. The window-day Experiment (day 30 against day 14) has 4 delivered offers against the 40 per arm it needs, so the weekly Decisions kept day 30 and no Change was merged; there is no replay or read-back to print.

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Offer it where they landed offer-at-landinga kept setup, a new work address verifiedYour rule (line 5)landing-offer, one reminder at day 23 if a claim startedthe champion’s own claimthe same
Offer it at the new team offer-at-new-teama move announced, or confirmed by 2 sources; day 30 after the start dateAgent’s call, with its reasonnew-org-offeryou approve it · Take this onethe same
Your own note founder-noteover 120 units, or they met youAgent’s call, with its reasonfounder-move-note from your Mailbox → POST /{namespace}/meetings/bookyou write it, due 1 business day · Take this onethe same
Keep their setup keep-their-setupa seat end, bounce or departure reply, no move confirmedYour rule (move-watch)keep-setup-note, oncenobodythe same
Tell the old account’s CSM tell-the-old-csmthe company they left is a CustomerYour rule (line 5)POST /{namespace}/tasks/{task}/assign: the departure, by date onlyCSM · your agent, due 1 business dayyou
Checked, no move no-movethey sign in again, or one source onlyYour rule (move-watch)nothing; the move check holds them, weekly for 8 weeksnobodythe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interested“Yes, set it up for Oakmont.”the claim link provisions their Tenant, pre-loaded; a Lead opens on the new companythe champion’s own press—POST /{namespace}/tenants/provision
Send me pricing“What would Oakmont pay after Solo?”the Pricing Page’s list Prices for Pro and Team, and one next stepSDR · your agent5 minPOST /{namespace}/conversations/{conversation}/answer
Not now“Settling in. Ask me next month.”the reminder cancels; the claim link stands until its expiry datenobodyat oncePOST /{namespace}/conversations/{conversation}/close
Wrong person“Not me. Wrong Jo.”nothing else sends to that address, and the source’s not me count risesnobodyat oncePOST /{namespace}/contacts/{contact}/suppress
Out of officean auto-reply until Oct 28the reminder waits for the return date, inside the link’s expirynobodythe return datePOST /{namespace}/messages/{message}/schedule
Question it can’t answer“Can I bring my old company’s templates?”To a person: the old company’s data never movesyou1 business dayPOST /{namespace}/conversations/{conversation}/escalate
Stop“Please stop emailing me.”nothing else sends to them, from any of your Startupsnobodyat oncePOST /{namespace}/contacts/{contact}/suppress

When it hands to you

Your own notes come to you (Dana Okafor, person), and the company a champion left goes to its CSM, CSM · your agent, by date only. One Brief per Role, as captured (brief is Not live yet, gaps #7).

What lands in each queue · sample
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_611",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-09-03T17:00:00Z",
    "on": "contact_19",
    "brief": {
      "who": "Marco Diaz, now operations director at Summit Property Group (210 units)",
      "said": "announced the move on Aug 3",
      "chose": "founder-note",
      "why": "over 120 units, and he met you on a call in May",
      "draft": "two times for a 20-minute move call, and the claim link",
      "never": [
        "his old company’s data or clients",
        "a price the Offer lacks",
        "congratulations on the new role"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_598",
    "$type": "Task",
    "assignee": "worker_5",
    "due": "2026-09-15T17:00:00Z",
    "on": "customer_23",
    "brief": {
      "who": "Juniper Homes, on Leaseline Pro",
      "chose": "tell-the-old-csm",
      "why": "their main daily user left on Sep 12",
      "held": "by date only: never where she went or her new address"
    }
  }
]

Each receiver answers with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{action}/redirect, each a one-call window. Once a person claims, the agent’s pending offer to that champion cancels with claimedByPerson (Not live yet, gaps #7), and every reply goes to that person. A Task nobody claims by its due time goes up a Role through POST /{namespace}/tasks/{task}/escalate (CSM to you), and person-promise fires.

On time: you, 3 of 3 claimed within their due time, median 1 h 05 min; CSM · your agent, 4 of 4; n 7, ■□□□ Too early to tell beside Other Startups’ 93 % on time. Your queue: counted by kind: in month 1, 2 approvals and 1 note of your own; since then, about 1 move a month.

The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.

When it won’t send

Check (refuses one send)RefusesFixThen
owned-by-a-person (rule j; Not live yet, gaps #8)an offer to a champion whose new company is a Lead or open Deal a person ownsLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
old-employer (the record’s Old-employer guard)a new company, role or address written to the old company’s records, or the old company named in an offerCut the line about the old company; the kit is their own setup.POST /{namespace}/content/draft
admin-lock (the record’s Admin lock guard)a kit holding an item an admin lockedLeave the locked item out; the kit rebuilds without it.POST /{namespace}/files/generate
customer-collision (Not live yet, gaps #1)an offer to a champion whose new company is already a CustomerSend it to that company’s CSM instead.POST /{namespace}/leads/{lead}/assign
Stop (pauses the Play)Pauses whenThen
bouncebounces over 2 % of a day’s sendsthat Mailbox pauses
complaintcomplaints near 0.1 %email pauses on every Mailbox
stop-linestop clicks over 2 % of a template’s last 100that template returns to You approve each one
claim-floorclaims plus positive replies under 3 per 100, after 60 delivered offersthe run stops
wrong-person2 not me replies in the last 30 work-address sendsthe work-address route returns to You approve each one
source-accuracya source’s moves marked not me or contradicted over 5 % of 40that source stops firing until you sign it again
leaka kit, Page or import holds company datathe Play pauses, every open claim link voids, and the task comes to you
privacy2 replies in 90 days objecting to how the move was knownthe new-team offer pauses
person-promisea started claim waits past 1 business hour for a personnew fires pause; you are notified
holdout-integritya held-back champion is touched; over 5 % voids the cohort’s readoutPOST /{namespace}/tasks/{task}/assign names the Play that sent it
spend-limitmonth-to-date model or lookup spend reaches its Limitthat part pauses until the month turns
kill-switchyou press itevery step pauses; kept setups stay saved

The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that sent is the Lee Park thread in Example.

422RefusedThe offer to Lee Park did not send: it names the company he left.
CheckFixThen
old-employer failCut the line about the old company; the kit is their own setup.POST /{namespace}/content/draft
owned-by-a-person pass · Not live yet, gaps #8—POST /{namespace}/tasks/{task}/assign
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The offer to Lee Park did not send: it names the company he left.",
  "checks": [
    {
      "check": "old-employer",
      "status": "fail",
      "doc": "/plays/champion-follow#check-old-employer",
      "fix": "Cut the line about the old company; the kit is their own setup.",
      "then": "Content.draft"
    },
    {
      "check": "owned-by-a-person",
      "status": "pass"
    }
  ]
}

It says no, says why, and names the fix.

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "person-promise",
      "observed": "1 h 40 min",
      "bound": "1 business hour",
      "window": "1 claim"
    },
    "doc": "/plays/champion-follow#stop-person-promise",
    "task": "task_604"
  }
]

Did it work

At 2 moves a quarter, no held-back half reads within a year, so the basis is before-after (rule o): the columns read Now and Before, nothing prints as Added, and your 1 held-back move pools with Other Startups’ cohorts. Each figure’s call is POST /{namespace}/metrics/query by node, and every node above the leaf is Not live yet (gaps #4).

7.9 new companies per 100 champions against 2.6 before · before-after, not proof · n 38 · path → arr

Chose
offer-at-landing
Why
Ana kept her setup on Solo in August, announced her move herself, and verified a work address at Oakmont Residential today
From
offer-at-landing · offer-at-new-team · founder-note · keep-their-setup · tell-the-old-csm · no-move
Expects
a claimed Tenant at Oakmont, active within 30d
Reopens when
no Tenant.provisioned for contact_14 within 23d
By
worker_2
JSON
{
  "$id": "decisions/decision_603",
  "$type": "Decision",
  "choice": "offer-at-landing",
  "reason": "Ana kept her setup on Solo in August, announced her move herself, and verified a work address at Oakmont Residential today",
  "stakes": "low",
  "options": [
    "offer-at-landing",
    "offer-at-new-team",
    "founder-note",
    "keep-their-setup",
    "tell-the-old-csm",
    "no-move"
  ],
  "by": "worker_2",
  "on": "contact_14",
  "expected": "a claimed Tenant at Oakmont, active within 30d",
  "reopensWhen": "no Tenant.provisioned for contact_14 within 23d"
}
NodeNow (140 days)Before (the 140 days before)AddedConfidenceBasis
champion-new-orgs7.9 per 100 champions (3 of 38)2.6 (1 of 38, a move nobody offered)— · Worth about +$45 a month—before-after, not proof · Other Startups’ results +3.1 per 100 champions a year, ■■■□ Likely, n 41
referral-share ↑2 of 11 new paying Customers (18 %) came through a moved champion1 of 9 (11 %)——before-after
new-paying-customers · new-arr$1,296, 2 Customers · Booked $1,296: credited, not all caused by this Play$348, 1 Customer——before-after · Summit’s Deal on the $2,400 plan still deciding
net-new-arr · arrcarried from new-arrcarried——carried

A new company counts when its claimed Tenant activates within 30 days and held no Subscription or open Deal at the move. The rolling read covers 365 days, and the held-back read waits until 100 champions are on file.

How it moves it: each moved champion gets their own templates and views, ready at the new company, 30 days after they start; median claim 2 h 28 min after the offer.

Guardrails: before against after: logo-churn at the companies champions left, 0 of 3 gone against a trailing 2.1 % a month, and not me replies, 0 of 4 offers.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/champion-follow",
  "$type": "Campaign",
  "play": "play:champion-follow@1",
  "path": [
    "champion-new-orgs",
    "referral-share",
    "new-paying-customers",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "champion-new-orgs",
    "unit": "per-100",
    "heldBack": 1,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 38,
    "maturing": 1,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 11,
    "workerCost": 2,
    "hours": 1.6,
    "pipelineArr": 2400,
    "wonArr": 1296,
    "projectedArr": 43,
    "paybackDays": 4
  }
}

Outside benchmark: none recorded for this Play yet; Other Startups’ results print beside every row.

Before it · After it. Before it: usage-upsell and customer-referrals keep champions active, and the move kit sits on every Customer’s settings Page. After it: instant-response answers the new company’s first questions, the AE takes a Deal over the size line, and the CSM agent runs the save at the company they left.

Example

Leaseline ran it from 2026-06-01 to 2026-10-19 (140 days): 38 champions on file, 15 kept their setup (39 per 100), 14 move checks opened, 9 closed as checked, no move, and 5 moves fired. 1 move was held back at random. Read every captured thread at ?threads=all; three follow the tables.

What happened, by optionDecisionsDelivered or doneClaimed · paying (Booked: credited, not all caused by this Play)
Offer it where they landed11 offer1 · Oakmont on Pro, $348
Offer it at the new team22 offers, 1 rewritten after old-employer1 · Cobalt Rentals on Team, $948
Your own note11 note, 1 Meeting1 · Summit, a $2,400 Deal still deciding
Keep their setup · Tell the old account’s CSM · Checked, no move2 · 4 · 92 notes · 4 Tasks · ——
At 30 champions (the Use it when volume)about 2 moves a quarterbefore-after, not proofOther Startups’ results: +3.1 per 100 champions a year, ■■■□ Likely, n 41
DayEventWhat happenedYour time
0event_610 Campaign.createdthe three steps; the dry run fails approved-pages20 min
0event_612 Site.publishedthe Solo plan Page, with its Limits10 min
1–14event_640 Message.scheduled, first of 38the one ask to keep a setup: 15 of 38 said yes—
61event_902 Role.updatedpromoted: landing offers send after a 2-minute hold—
64event_918 Monitor.checkedMarco’s public move confirmed; your note went Sep 3 and booked a Meeting25 min
89event_1012 Action.refusedold-employer refused the first draft to Lee Park; the rewrite sent—
105event_1307 Credential.verifiedAna verified her Oakmont address; she claimed the kit at 11:30—
106event_1322 Campaign.pausedperson-promise: Ana’s started claim waited 1 h 40 min; you answered it10 min
1–140event_661 Approval.created, first of 2you approved 2 offers and wrote 1 note; weekly reviews, from the POST /{namespace}/tasks/next log30 min · total 1.6 h measured, 2 h asked

Leaseline → Ana Flores (her own address), Sep 14, 09:02 · Your Leaseline setup is ready at Oakmont Residential: your 14 notice templates, 3 renewal calendars and 22 saved views.¹ Claim it with one press; the link works until Oct 14.² Solo stays free for one Person, with its Limits one click away.³ *Signed with the Role’s disclosure line and the stop line.*⁴

Ana, Sep 14, 11:30 · claimed it. Tenant.provisioned, a Lead opened on Oakmont (lead_47), and Oakmont moved to Pro on Sep 29.

Lee Park, 2026-08-29 · the draft old-employer refused, then the rewrite that sent
- Maple Court still runs 56 units on Leaseline. Bring the same setup to your new company.
+ Your Leaseline setup is ready for your next team: your 9 notice templates and 2 renewal calendars.

Dana → Marco Diaz (her own note, from her Mailbox), Sep 3 · two times for a 20-minute move call on his own setup. · Marco, Sep 4 10:12 · “Yes, Tuesday works; we have 210 units.” The reply landed in your queue with the Brief (task_611), due 11:12; you answered at 10:40, and POST /{namespace}/meetings/book booked Tue 14:00.

¹ Counts from the kit manifest: Ana’s own setup, nothing of her old company’s. ² The link’s expiry is the only deadline. ³ The Solo plan Page, with its Limits. ⁴ The fixed signature and stop lines, compiled from the Role’s Settings.

Your settings

plays/champion-follow.mdx
---
holdout: 0.2      # 1 in 5 fired moves gets no offer for 120 days
offer-day: 30
---
Offer a champion their own setup where they land, 30 days after they start. Tell the company they left by date only. Over 120 units, or anyone I’ve met, I write the note myself.
Text
$ npx startup-builder show plays/champion-follow
holdout 0.2 · offer-day 30 · your note over 120 units     your file  plays/champion-follow.mdx:2-3,5 (Ask 2026-06-01)
family referral · worker role:prospector, owns never · chooses 6 (4 rule, 2 read) · sequences landing-offer, keep-setup-note, new-org-offer, founder-move-note · checks owned-by-a-person, old-employer, admin-lock, customer-collision · stops 12 · placements gmail, outlook, yahoo-mail, linkedin (your own note)    catalog  play:champion-follow@1 (Not live yet, gaps #5)

Every key from the catalog

Key Id What it is
Tactic setup-passport Setup passport marks each setup item Person or Organization scope, scans Person items for Organization data, and asks each champion once to keep it. Starts at You approve the first wave.
Tactic move-watch Move watch turns a bounce, an automatic reply, a seat end or silence into a move check, and fires on an announcement or two sources. Starts at Sends nothing.
Tactic move-kit-build Move kit build freezes a copy of the champion’s own Person-scope setup as a manifest, re-scanned, with no old-Tenant data, behind a signed claim Page. Starts at Sends nothing.
Tactic champion-follow-compose Champion follow compose drafts one Message per route from the kit manifest and the claims source, checks its facts, and builds the approval card. Starts at You approve each one.
Tactic champion-follow-send Champion follow send sends one approved Message per move on its window day, through the send gate for a new work address, with no follow-up. Starts at You approve each one.
Tactic setup-claim Setup claim verifies the claimant, provisions a new Tenant pre-loaded with the kit, and opens a Lead on the new Organization carrying its trigger. Starts at Sends nothing.
Tactic old-side-handoff Old side handoff records a champion’s departure on the old Organization by date only, and hands the save to the expansion family. Starts at Sends nothing.
Tactic champion-readout Champion readout counts new Organizations per 100 champions, reads the holdout at day 120, scores each move source, and proposes one change per review. Starts at Sends nothing.
Tactic send-gate-check Send gate check: Checks Suppression, a live reason, the Market, the basis stamp, the Person-month grant, the facts and the labels before any cold Message exists. Starts at Sends nothing.
Tactic reply-matrix Reply matrix: Labels every outreach reply with one of 11 labels, maps it to one of seven reply kinds, and runs that kind’s move by its deadline. Starts at You approve each one.
Trigger setup-move-started Setup move started: event on Collection.exported, window 14d.
Trigger personal-plan-landing Personal plan landing: event on Credential.verified, window 30d.
Trigger work-address-bounce Work address bounce: state on Message.bounced, window 60d.
Trigger departure-auto-reply Departure auto-reply: event on Conversation.answered, window 60d.
Trigger seat-ended Seat ended: state on MemberDirectory.deprovisioned, window 60d.
Trigger licensed-move Licensed move: event on Contact.enriched, window 120d.
Trigger public-move-confirm Public move confirm: event on Monitor.checked, window 120d.
Trigger setup-claimed Setup claimed: event on Tenant.provisioned, window 30d.
Sequence landing-offer Landing offer: 4 steps; it ends on A claim; A reply; A not me reply; A stop; The claim link expires at 30 days.
Sequence keep-setup-note Keep setup note: 1 steps; it ends on A reply; A move started; A stop; 30 days.
Sequence new-org-offer New organization offer: 4 steps; it ends on A claim; A reply; A not me reply; A stop; A lifecycle conflict at the new Organization; 30 days.
Sequence founder-move-note Founder move note: 4 steps; it ends on A claim; A reply; A booked Meeting; A not me reply; A stop; 30 days.

Compiled, not written: edit the Play record champion-follow and its Leaseline run, then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.