URL: /plays/champion-follow · Id: `play:champion-follow`

# 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.

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.

```text title="Set it up · Ask"
Be our SDR: when someone who uses Leaseline every day leaves for another property manager, offer them their own setup there, 30 days after they start. Never move their old company’s data, and tell that company’s CSM by date only. If they land somewhere over 120 units, or I’ve met them, I write the note myself. Show me what’s missing; don’t send.
```

```text title="Run one · Ask"
Hand our latest champion move to the SDR agent and show me what it chose and why. Don’t send.
```

```ts title="Run one · SDK"
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 }
```

```json title="Run one · Response · sample"
{
  "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"
    ],
    "by": "worker_2",
    "on": "contact_14",
    "expected": "a claimed Tenant at Oakmont, active within 30d",
    "reopensWhen": "no Tenant.provisioned for contact_14 within 23d"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "File.generate",
      "checks": [
        {
          "check": "admin-lock",
          "status": "pass"
        },
        {
          "check": "old-employer",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingTime",
      "mode": "try",
      "by": "worker_2",
      "verb": "Message.schedule",
      "checks": [
        {
          "check": "owned-by-a-person",
          "status": "pass"
        },
        {
          "check": "customer-collision",
          "status": "pass"
        },
        {
          "check": "old-employer",
          "status": "pass"
        },
        {
          "check": "admin-lock",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Task.assign",
      "checks": []
    }
  ]
}
```

`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 champion | Choice | Reason |
| --- | --- | --- |
| Ana Flores: kept her setup on Solo, verified a work address at Oakmont Residential | `offer-at-landing` | a kept setup, an announced move, a new work address |
| Marco Diaz: announced a move to Summit Property Group, 210 units | `founder-note` | over 120 units, and he met you in May |
| Jo Kim: seat ended at Alder & Co, then a bounce, no move confirmed | `keep-their-setup` | one source says they left; nothing says where |
| Priya’s contact at Harbor Row: one auto-reply, then signed in again | `no-move` | checked, no move: she signed in on Oct 2 |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$45 ARR a month at 38 champions | 30 min week 1, then 10 min per move | $0.04 per lookup, ~$3 a month at 38 champions | Day 30 after a move: the first claim | 30+ champions on file, 2+ job moves a quarter | Under 30 champions: `customer-referrals` · no kept setups yet: ask once (<Op verb="Message.schedule" />) |

**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
```bash
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"}'
```


```json title="The dry run’s 422 · 2026-06-01 · sample"
{
  "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"
    }
  ]
}
```

| Check | Fix (one call) | Your time | Wait |
| --- | --- | --- | --- |
| <a id="check-use-when"></a>`use-when` · <a id="check-baseline"></a>`baseline` · pass: 38 champions, 5 moves in 2 quarters · warn: n 1 (gaps #8) | <Op verb="Metric.query" /> on `champion-new-orgs`; it fills Before in Your number | 1 min | none |
| <a id="check-domain-authenticated"></a>`domain-authenticated` · pass | <Op verb="Domain.authenticate" /> | 0 min | none |
| <a id="check-approved-pages"></a>`approved-pages` · fail (gaps #8) | <Op verb="Site.publish" /> your Solo plan Page | 10 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · warn (gaps #8): 6 champions are Contacts Priya owns | <Op verb="Role.staff" />, or leave it: privacy replies come to you, and Priya’s 6 get drafts in her queue | 0 min | none |

`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
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| A champion who kept their setup verifies a work address at a new company | `personal-plan-landing` | `event` on `Credential.verified` where a passport holder on the personal plan verifies a work address on a new company’s domain | 30d | your sign-in calls <Op verb="Credential.verify" /> |
| A public page names them in a role at a new company | `public-move-confirm` | `event` on `Monitor.checked` where a public page names the champion in a role at a new company, with its URL and date | 120d | <Op verb="Monitor.check" /> on each open move check |
| Their seat ends and they sign in nowhere else | `seat-ended` | `state` on `MemberDirectory.deprovisioned` where the seat ended and the champion signs in nowhere else | 60d | directory sync calls <Op verb="MemberDirectory.deprovision" /> |
| + 5 more for move kits started, bounces, departure replies, licensed records and claims (`?lanes=all`) | | | | |

```json title="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
  }
}
```

```bash title="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.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Offer it where they landed · Keep their setup | It does it, you can stop it | 1 of 1 · 2 of 2 | met on day 61 (the first 3 offers) | an offer fails a Check, or `wrong-person` fires → You approve each one | <Op verb="Action.cancel" /> inside the hold |
| Offer it at the new team | You approve each one | 2 of 2 | at 10 approved with no `not me` | — | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| Tell the old account’s CSM · Checked, no move | It does it | 4 of 4 · 9 of 9 | — | a destination written to the old record → You approve each one | <Op verb="Action.redirect" /> |
| Your own note | To a person, every time | 1 drafted, 1 written by you | never | — | <Op verb="Task.claim" /> |
| Change the move sources or the 30-day window | You approve each one | 0 merged | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: the old company’s data, clients or colleagues; a word to the old company about where they went | Refused, every time | 1 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 <Op verb="Meeting.book" />, <Op verb="Task.assign" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="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
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| Offer it where they landed `offer-at-landing` | a kept setup, a new work address verified | Your rule (line 5) | `landing-offer`, one reminder at day 23 if a claim started | the champion’s own claim | the same |
| Offer it at the new team `offer-at-new-team` | a move announced, or confirmed by 2 sources; day 30 after the start date | Agent’s call, with its reason | `new-org-offer` | you approve it · Take this one | the same |
| Your own note `founder-note` | over 120 units, or they met you | Agent’s call, with its reason | `founder-move-note` from your Mailbox → <Op verb="Meeting.book" /> | you write it, due 1 business day · Take this one | the same |
| Keep their setup `keep-their-setup` | a seat end, bounce or departure reply, no move confirmed | Your rule (move-watch) | `keep-setup-note`, once | nobody | the same |
| Tell the old account’s CSM `tell-the-old-csm` | the company they left is a Customer | Your rule (line 5) | <Op verb="Task.assign" />: the departure, by date only | CSM · your agent, due 1 business day | you |
| Checked, no move `no-move` | they sign in again, or one source only | Your rule (move-watch) | nothing; the move check holds them, weekly for 8 weeks | nobody | the same |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | “Yes, set it up for Oakmont.” | the claim link provisions their Tenant, pre-loaded; a Lead opens on the new company | the champion’s own press | — | <Op verb="Tenant.provision" /> |
| Send me pricing | “What would Oakmont pay after Solo?” | the Pricing Page’s list Prices for Pro and Team, and one next step | SDR · your agent | 5 min | <Op verb="Conversation.answer" /> |
| Not now | “Settling in. Ask me next month.” | the reminder cancels; the claim link stands until its expiry date | nobody | at once | <Op verb="Conversation.close" /> |
| Wrong person | “Not me. Wrong Jo.” | nothing else sends to that address, and the source’s `not me` count rises | nobody | at once | <Op verb="Contact.suppress" /> |
| Out of office | an auto-reply until Oct 28 | the reminder waits for the return date, inside the link’s expiry | nobody | the return date | <Op verb="Message.schedule" /> |
| Question it can’t answer | “Can I bring my old company’s templates?” | To a person: the old company’s data never moves | you | 1 business day | <Op verb="Conversation.escalate" /> |
| Stop | “Please stop emailing me.” | nothing else sends to them, from any of your Startups | nobody | at once | <Op verb="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).

```json title="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 <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason, or <Op verb="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 <Op verb="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:** <Op verb="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) | Refuses | Fix | Then |
| --- | --- | --- | --- |
| <a id="check-owned-by-a-person"></a>`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 owns | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| <a id="check-old-employer"></a>`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 offer | Cut the line about the old company; the kit is their own setup. | <Op verb="Content.draft" /> |
| <a id="check-admin-lock"></a>`admin-lock` (the record’s Admin lock guard) | a kit holding an item an admin locked | Leave the locked item out; the kit rebuilds without it. | <Op verb="File.generate" /> |
| <a id="check-customer-collision"></a>`customer-collision` (Not live yet, gaps #1) | an offer to a champion whose new company is already a Customer | Send it to that company’s CSM instead. | <Op verb="Lead.assign" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-bounce"></a>`bounce` | bounces over 2 % of a day’s sends | that Mailbox pauses |
| <a id="stop-complaint"></a>`complaint` | complaints near 0.1 % | email pauses on every Mailbox |
| <a id="stop-stop-line"></a>`stop-line` | stop clicks over 2 % of a template’s last 100 | that template returns to You approve each one |
| <a id="stop-claim-floor"></a>`claim-floor` | claims plus positive replies under 3 per 100, after 60 delivered offers | the run stops |
| <a id="stop-wrong-person"></a>`wrong-person` | 2 `not me` replies in the last 30 work-address sends | the work-address route returns to You approve each one |
| <a id="stop-source-accuracy"></a>`source-accuracy` | a source’s moves marked `not me` or contradicted over 5 % of 40 | that source stops firing until you sign it again |
| <a id="stop-leak"></a>`leak` | a kit, Page or import holds company data | the Play pauses, every open claim link voids, and the task comes to you |
| <a id="stop-privacy"></a>`privacy` | 2 replies in 90 days objecting to how the move was known | the new-team offer pauses |
| <a id="stop-person-promise"></a>`person-promise` | a started claim waits past 1 business hour for a person | new fires pause; you are notified |
| <a id="stop-holdout-integrity"></a>`holdout-integrity` | a held-back champion is touched; over 5 % voids the cohort’s readout | <Op verb="Task.assign" /> names the Play that sent it |
| <a id="stop-spend-limit"></a>`spend-limit` | month-to-date model or lookup spend reaches its Limit | that part pauses until the month turns |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every 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.

```json title="The captured refusal · sample"
{
  "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"
    }
  ]
}
```


```json title="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 <Op verb="Metric.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`

| Node | Now (140 days) | Before (the 140 days before) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `champion-new-orgs` | 7.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 champion | 1 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` · `arr` | carried from `new-arr` | carried | — | — | 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.

```json title="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 option | Decisions | Delivered or done | Claimed · paying (Booked: credited, not all caused by this Play) |
| --- | --- | --- | --- |
| Offer it where they landed | 1 | 1 offer | 1 · Oakmont on Pro, $348 |
| Offer it at the new team | 2 | 2 offers, 1 rewritten after `old-employer` | 1 · Cobalt Rentals on Team, $948 |
| Your own note | 1 | 1 note, 1 Meeting | 1 · Summit, a $2,400 Deal still deciding |
| Keep their setup · Tell the old account’s CSM · Checked, no move | 2 · 4 · 9 | 2 notes · 4 Tasks · — | — |
| At 30 champions (the Use it when volume) | about 2 moves a quarter | before-after, not proof | Other Startups’ results: +3.1 per 100 champions a year, ■■■□ Likely, n 41 |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_610` Campaign.created | the three steps; the dry run fails `approved-pages` | 20 min |
| 0 | `event_612` Site.published | the Solo plan Page, with its Limits | 10 min |
| 1–14 | `event_640` Message.scheduled, first of 38 | the one ask to keep a setup: 15 of 38 said yes | — |
| 61 | `event_902` Role.updated | promoted: landing offers send after a 2-minute hold | — |
| 64 | `event_918` Monitor.checked | Marco’s public move confirmed; your note went Sep 3 and booked a Meeting | 25 min |
| 89 | `event_1012` Action.refused | `old-employer` refused the first draft to Lee Park; the rewrite sent | — |
| 105 | `event_1307` Credential.verified | Ana verified her Oakmont address; she claimed the kit at 11:30 | — |
| 106 | `event_1322` Campaign.paused | `person-promise`: Ana’s started claim waited 1 h 40 min; you answered it | 10 min |
| 1–140 | `event_661` Approval.created, first of 2 | you approved 2 offers and wrote 1 note; weekly reviews, from the <Op verb="Task.next" /> log | 30 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.

```diff title="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 <Op verb="Meeting.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
```mdx title="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 | <a id="tactic-setup-passport"></a>`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 | <a id="tactic-move-watch"></a>`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 | <a id="tactic-move-kit-build"></a>`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 | <a id="tactic-champion-follow-compose"></a>`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 | <a id="tactic-champion-follow-send"></a>`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 | <a id="tactic-setup-claim"></a>`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 | <a id="tactic-old-side-handoff"></a>`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 | <a id="tactic-champion-readout"></a>`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 | <a id="tactic-send-gate-check"></a>`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 | <a id="tactic-reply-matrix"></a>`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 | <a id="trigger-setup-move-started"></a>`setup-move-started` | Setup move started: `event` on `Collection.exported`, window 14d. |
| Trigger | <a id="trigger-personal-plan-landing"></a>`personal-plan-landing` | Personal plan landing: `event` on `Credential.verified`, window 30d. |
| Trigger | <a id="trigger-work-address-bounce"></a>`work-address-bounce` | Work address bounce: `state` on `Message.bounced`, window 60d. |
| Trigger | <a id="trigger-departure-auto-reply"></a>`departure-auto-reply` | Departure auto-reply: `event` on `Conversation.answered`, window 60d. |
| Trigger | <a id="trigger-seat-ended"></a>`seat-ended` | Seat ended: `state` on `MemberDirectory.deprovisioned`, window 60d. |
| Trigger | <a id="trigger-licensed-move"></a>`licensed-move` | Licensed move: `event` on `Contact.enriched`, window 120d. |
| Trigger | <a id="trigger-public-move-confirm"></a>`public-move-confirm` | Public move confirm: `event` on `Monitor.checked`, window 120d. |
| Trigger | <a id="trigger-setup-claimed"></a>`setup-claimed` | Setup claimed: `event` on `Tenant.provisioned`, window 30d. |
| Sequence | <a id="sequence-landing-offer"></a>`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 | <a id="sequence-keep-setup-note"></a>`keep-setup-note` | Keep setup note: 1 steps; it ends on A reply; A move started; A stop; 30 days. |
| Sequence | <a id="sequence-new-org-offer"></a>`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 | <a id="sequence-founder-move-note"></a>`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. |