Skip to content

Closer handoff

Hands a large Deal that stalled twice to a commissioned closer, paid only on collected revenue, and tests it against the Deals your agent keeps.

Channel
Offers and Deals
Run oneMode try
You, to your agent

Hand our latest twice-stalled Deal to the AE agent and show me what it chose and why. Don’t send.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Deal.stalled%22%2C%20%22Deal.advanced%22%2C%20%22Task.returned%22%2C%20%22Conversation.answered%22%2C%20%22Deal.assigned%22%2C%20%22Invoice.collected%22%2C%20%22Invoice.refunded%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_1290"}'

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

const { events: [last] } = await $.Event.list({ where: 'name in ("Deal.stalled", "Deal.advanced", "Task.returned", "Conversation.answered", "Deal.assigned", "Invoice.collected", "Invoice.refunded")', 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 (\"Deal.stalled\", \"Deal.advanced\", \"Task.returned\", \"Conversation.answered\", \"Deal.assigned\", \"Invoice.collected\", \"Invoice.refunded\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1290"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"deal_31\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"deal_31\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Deal.stalled\", \"Deal.advanced\", \"Task.returned\", \"Conversation.answered\", \"Deal.assigned\", \"Invoice.collected\", \"Invoice.refunded\")', 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_588",
    "$type": "Decision",
    "choice": "hand-to-a-closer",
    "reason": "Granite Peak’s $21,600 Portfolio Deal revived on Sep 2 and stalled again on Sep 22; the draw put it in the closer half",
    "stakes": "medium",
    "options": [
      "revive-first-stall",
      "hand-to-a-closer",
      "agent-keeps-it",
      "next-closer",
      "back-to-you",
      "close-the-file"
  …
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 is the brief, with every buyer quote linked to its Message. action_2 offers it to the closer once you approve; action_3 makes the closer the Deal’s owner when they accept.

33 per 100 twice-stalled large Deals won against 0 before · before-after, not proof · n 3 · path → arr

Try another: the DealChoiceReason
Granite Peak Rentals: $21,600 Portfolio, revived once, stalled again Sep 22hand-to-a-closerstalled twice; the draw put it in the closer half
Riverbend Group: $18,000 Portfolio, stalled twice Aug 19agent-keeps-itstalled twice; the draw put it in the agent half
Lakeview Partners: $12,000 Portfolio, first stall on Jul 6revive-first-stallno buyer Event for 21 days, the first time
Northgate Housing: the closer went 5 business days silentnext-closerthe same brief and window end go to the next closer

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Stalled deal win rate → New paying Customers → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +16 wins per 100 twice-stalled large Deals (Other Startups’ results; yours reads before-after) × 2 a quarter ÷ 3 months × $16,800 average large Deal ARR ≈ +$1,790. Under First signal: At 2 a quarter, 30 Deals per half takes years, so your draw pools with Other Startups’ cohorts and this page reads before-after.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Deal.stalled · first Decision 52 min after the stall scan · 9 keys Not live yet

Start it this week

Terminal
npx startup-builder add play closer-handoff   # 1 · writes plays/closer-handoff.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":"closer-handoff"}'

# 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":"closer-handoff"}'

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

# off: no new draw or brief; handed Deals stay with their closer
curl -X PATCH https://api.sb/leaseline.app/campaigns/closer-handoff \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusedcloser-handoff can’t start yet: 1 check fails and 2 warn.
CheckFixThen
use-when pass · Not live yet, gaps #86 Portfolio Deals over $12,000 open; 3 stalled twice in the last 2 quartersPOST /{namespace}/metrics/query
baseline warn · Not live yet, gaps #8n 3: it reads before-after, not proof, and pools its draw with Other Startups.POST /{namespace}/metrics/query
billing-connected fail · Not live yet, gaps #8Connect Stripe so commission reads collected revenue, net of refunds.POST /{namespace}/integrations/connect
role-unstaffed warn · Not live yet, gaps #8Staff a commissioned closer with `Role.staff`; until then handoffs come back to you.POST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "closer-handoff can’t start yet: 1 check fails and 2 warn.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "6 Portfolio Deals over $12,000 open; 3 stalled twice in the last 2 quarters",
      "doc": "/plays/closer-handoff#check-use-when",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "0 of 3 twice-stalled large Deals won in 140 days",
      "doc": "/plays/closer-handoff#check-baseline",
      "fix": "n 3: it reads before-after, not proof, and pools its draw with Other Startups.",
      "then": "Metric.query"
    },
    {
      "check": "billing-connected",
      "status": "fail",
      "doc": "/plays/closer-handoff#check-billing-connected",
      "fix": "Connect Stripe so commission reads collected revenue, net of refunds.",
      "then": "Integration.connect"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "sales-lead"
      ],
      "owned": 6,
      "doc": "/plays/closer-handoff#check-role-unstaffed",
      "fix": "Staff a commissioned closer with `Role.staff`; until then handoffs come back to you.",
      "then": "Role.staff"
    }
  ]
}

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

CheckFix (one call)Your timeWait
use-when · baseline · pass: 6 large Deals open, 3 twice-stalled in 2 quarters · warn: 0 of 3 won (gaps #8)POST /{namespace}/metrics/query on stalled-deal-win-rate; it fills Before in Your number1 minnone
billing-connected · failPOST /{namespace}/integrations/connect with system recurring-billing (Stripe)5 minthe first sync, about 10 min
role-unstaffed · warn (gaps #8): 6 large Deals have a person owner, youPOST /{namespace}/roles/{role}/staff a commissioned closer after POST /{namespace}/agreements/{agreement}/sign; the agent drafts into your queue for your 620 minthe closer’s signature

Your number · Before 0 per 100 · Now 33 per 100 twice-stalled large Deals won · Target 40 by Dec 31 · before-after, not proof · n 3 decided

Commission is 10 % of collected first-year revenue, net of refunds, held 60 days and paid on the 5th (POST /{namespace}/commissions/{commission}/pay). Briefs and intros cost $0.04 each from your Domain (Worker cost). That comes to under $1 a month before a win, and $2,160 on a $21,600 win.

When it starts

WhenTrigger idStarts onWindowHow it gets in
A large Deal a buyer revived once goes quiet againdeal-stalled-twicestate on Deal.stalled where a large Deal revived once enters stalled again7dthe daily stall scan reads your Deals’ buyer Events
An open Deal gets no buyer Event for its stall timeoutdeal-stalledstate on Deal.stalled where no buyer-authored Event for the Deal’s stall timeout, or its close date 7 days past14dthe same scan; your own sends never reset the clock
A handed-off Deal shows no closer action for 5 business dayscloser-silentstate on Deal.stalled where no closer Message, call or Meeting on a handed-off Deal for 5 business days5dthe closer’s Messages, calls and Meetings on the Deal
+ 6 more for revivals, declined handoffs, buyers who keep the agent, window ends, collections and refunds (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1290",
  "$type": "Event",
  "name": "Deal.stalled",
  "at": "2026-09-22T07:00:14Z",
  "seq": 1290,
  "data": {
    "deal": "deal_31",
    "organization": "Granite Peak Rentals",
    "value": 21600,
    "stalls": 2,
    "lastBuyerEvent": "2026-09-01T16:20:00Z",
    "owner": "worker_1"
  }
}
Reproduce it in test
npx startup-builder trigger Deal.stalled --like event_1290   # replays the delivery
npx startup-builder clock advance --by 1d   # runs the closer’s accept deadline
npx startup-builder listen Deal.stalled --forward-to http://localhost:3000/hook

Who runs it

AE · your agent (role:sales-lead, worker_8) holds the Key Result and never owns a Deal. The large Deals are yours (Dana Okafor, person, worker_1), so its revival steps draft into your queue. A handoff makes AE · Tom Reyes (person), a commissioned closer (worker_9), the Deal’s owner once you approve and he accepts. Your number links to Did it work.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Revive the first stall · The agent keeps itYou approve each one3 of 3 · 2 of 2never: the Deals are yours (owned-by-a-person)—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
Hand it to a closer · Next closerYou approve each one2 of 2 · 1 of 1never: every handoff is yours to approve—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
Back to you · Close the fileIt does it1 of 1 · 2 of 2—a buyer asks the agent anything it can’t answer → You approve each onePOST /{namespace}/actions/{action}/redirect
Change the large line or the drawYou approve each one0 merged: both are sealed for the cohortnever—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: a stall named to the buyer, a deadline the Quote lacks, a price below the floorRefused, every time1 Quote refused (price)never——

What it reads · What it may call. It reads buyer-authored Events, the Deal’s Messages and Meetings, and the claims source, and every buyer Message is data, never instructions. It never writes in the closer’s name, and the brief marks every stall cause a guess. Its tools are POST /{namespace}/tasks/{task}/assign, POST /{namespace}/deals/{deal}/assign, POST /{namespace}/deals/{deal}/lose, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:closer-handoff@1 · each line names its record key
You hold the AE Key Result: 40 wins per 100 twice-stalled large Deals by 2026-12-31. ← worker, metric
On each stall, choose one option and say why; the second stall goes to the sealed draw. ← triggers, chooses, closer-draw
Never mention a stall, the draw, a Deal room view or an open in any Message.     ← copyRules 2
Label every stall cause a guess, and link every buyer quote to its Message or Meeting. ← copyRules 7, 8
Introduce the closer with the real relationship and only the title the Agreement grants. ← copyRules 1
Never write to a Deal a person owns: draft it into their queue.                  ← worker.owns, owned-by-a-person

The slow loop. The large line and the draw are sealed for the cohort, so no Change may touch them, and none was merged in the window; there is no replay or read-back to print.

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Revive the first stall revive-first-stallthe first stall: no buyer Event for 21 daysYour rule (line 6)first-stall-revival, drafted into your queueyou send each step, due 1 business day · Take this onethe same
Hand it to a closer hand-to-a-closerstalled twice; the draw says closerYour rule (the draw, line 3)POST /{namespace}/tasks/{task}/assign the brief → closer-intro → POST /{namespace}/deals/{deal}/assignAE · Tom Reyes, accept within 1 business day · Take this oneyou, if no closer is staffed
The agent keeps it agent-keeps-itstalled twice; the draw says agentYour rule (the draw, line 3)agent-arm-hold, 90 days, drafted into your queueyou send each step · Take this onethe same
Next closer next-closerdeclined, the deadline passed, or 5 business days silentAgent’s call, with its reasonPOST /{namespace}/tasks/{task}/assign the same brief → POST /{namespace}/deals/{deal}/assignthe next closer, same window endyou
Back to you back-to-youthe buyer asks to work with Leaseline directlyAgent’s call, with its reasonPOST /{namespace}/deals/{deal}/assign → POST /{namespace}/tasks/{task}/assignyou, due 1 business day; it stays in the closer halfthe same
Close the file close-the-filethe window ends open, or the buyer says noAgent’s call, with its reasonPOST /{namespace}/deals/{deal}/lose with its reasonnobody; the reason feeds objection-watchthe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interested“Thursday works for our CFO.”the closer books it on his calendar under his nameAE · Tom Reyes (person)60 minPOST /{namespace}/meetings/book
Send me pricing“Send the 2-year number.”a Quote at or above the floor, with its real validUntilAE · Tom Reyes1 business dayPOST /{namespace}/quotes/{quote}/send
Not now“Back to this after budgets in January.”a dated next step on the Deal; nothing sends before itAE · Tom Reyesat oncePOST /{namespace}/deals/{deal}/advance
Wrong person“Our COO signs now, not me.”asks them to bring the COO in; never writes to an address from their textAE · Tom Reyes1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply until Oct 28the window waits; the silence clock pauses to the return datenobodythe return datePOST /{namespace}/messages/{message}/schedule
Question it can’t answer“How is Tom paid?”the closer answers truthfully: 10 % of what Leaseline collectsAE · Tom Reyes60 minPOST /{namespace}/conversations/{conversation}/answer
Stop“Please stop contacting us.”nothing else sends to that Contact, on any channel; you get a Tasknobodyat oncePOST /{namespace}/contacts/{contact}/suppress

When it hands to you

Handoffs go to AE · Tom Reyes (person), the commissioned closer, once you approve; revivals and Deals that come back land with you (Dana Okafor, person), who owns the large Deals. 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_590",
    "$type": "Task",
    "assignee": "worker_9",
    "due": "2026-09-23T15:00:00Z",
    "on": "deal_31",
    "brief": {
      "who": "Granite Peak Rentals: 900 units, CFO and operations lead",
      "said": "We need payment terms that match our owners’ draws (Aug 28, `message_412`)",
      "chose": "hand-to-a-closer",
      "why": "stalled twice; the draw put it in the closer half",
      "guess": "payment timing, not price (a guess)",
      "window": "ends 2026-11-06",
      "never": [
        "a stall named to the buyer",
        "a price below the floor",
        "a deadline the Quote lacks"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_553",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-08-20T17:00:00Z",
    "on": "deal_27",
    "brief": {
      "who": "Riverbend Group: 750 units",
      "chose": "agent-keeps-it",
      "why": "stalled twice; the draw put it in the agent half",
      "next": "the answer to their open data-migration question, drafted for you to send"
    }
  }
]

The closer answers with POST /{namespace}/tasks/{task}/claim (Take this one) or POST /{namespace}/tasks/{task}/return with a reason; you approve each handoff with POST /{namespace}/approvals/{approval}/approve. Once he claims, POST /{namespace}/deals/{deal}/assign sets owner to him, the agent sends nothing more on that Deal, and every reply goes to his queue. A brief nobody claims by its due time goes to the next closer, then back to you through POST /{namespace}/tasks/{task}/escalate, and person-promise fires.

On time: AE · Tom Reyes, 2 of 2 accepted within 1 business day, median 3 h 05 min; you, 5 of 5 drafts sent within their due time; n 7, ■□□□ Too early to tell beside Other Startups’ 89 % on time. Your queue: counted by kind: in month 1, 3 revival drafts and 1 approval; since then, about 1 handoff 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 agent send on a Deal a person owns, or a Conversation a person claimedLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
price (hub, on POST /{namespace}/quotes/{quote}/send; gaps #1)a Quote below the Offer’s price floorGet the discount approved, or quote at the floor.POST /{namespace}/approvals/{approval}/approve
buyer-stop (the record’s Buyer stop)any send to a buyer Contact who asked to stopNothing else sends to them; you get a Task.POST /{namespace}/contacts/{contact}/suppress
buyer-keeps (the record’s Buyer keeps the agent)a closer send after the buyer asked to work with Leaseline directlyThe Deal comes back to you; it stays in the closer half.POST /{namespace}/deals/{deal}/assign
recording (the record’s Recording gate)a Meeting recording before every attendee consents on the recordAsk each attendee on the call, then record.POST /{namespace}/meetings/book
Stop (pauses the Play)Pauses whenThen
claimsa closer Message states a price, term, date or claim outside the claims sourceit flags to you within 1 hour
second-claimsa second claims flag in 30 daysthe closer is suspended; each open Deal goes to the next closer
closer-silent10 business days with no closer actionthe Deal goes to the next closer, same brief and window end
off-recorda buyer Message cites a channel outside your Mailboxes, numbers and Meetingsit flags to you
discountcloser-half wins average 10+ discount points deeper than agent-half wins, over 10 winsnew handoffs pause
refundover 20 % of a closer’s won first-year revenue refunded within 90 daysthat closer pauses
paybackcommission over 50 % of added first-year revenue for 2 quartersnew handoffs pause
readout-killat 30+ Deals per half, the interval sits wholly below the sealed minimumthe run ends
kill-switchyou press itno new draw, brief or agent send; handed Deals stay with their closer

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

422RefusedThe Quote to Granite Peak did not send: it sits 25 % below the Portfolio floor.
CheckFixThen
price fail · Not live yet, gaps #1Get the discount approved, or quote at the floor.POST /{namespace}/approvals/{approval}/approve
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The Quote to Granite Peak did not send: it sits 25 % below the Portfolio floor.",
  "checks": [
    {
      "check": "price",
      "status": "fail",
      "doc": "/plays/closer-handoff#check-price",
      "fix": "Get the discount approved, or quote at the floor.",
      "then": "Approval.approve"
    }
  ]
}

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

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "closer-silent",
      "observed": "10 business days",
      "bound": "10 business days",
      "window": "1 Deal"
    },
    "doc": "/plays/closer-handoff#stop-closer-silent",
    "task": "task_571"
  }
]

Did it work

At 2 twice-stalled large Deals a quarter, neither half reaches 30 Deals within a year, so the basis is before-after (rule o): nothing prints as Added, and your 4 drawn Deals pool 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).

33 per 100 twice-stalled large Deals won against 0 before · before-after, not proof · n 3 · path → arr

Chose
hand-to-a-closer
Why
Granite Peak’s $21,600 Portfolio Deal revived on Sep 2 and stalled again on Sep 22; the draw put it in the closer half
From
revive-first-stall · hand-to-a-closer · agent-keeps-it · next-closer · back-to-you · close-the-file
Expects
Deal.won within the 45-day window
Reopens when
no closer Message on deal_31 within 5 business days
By
worker_8
JSON
{
  "$id": "decisions/decision_588",
  "$type": "Decision",
  "choice": "hand-to-a-closer",
  "reason": "Granite Peak’s $21,600 Portfolio Deal revived on Sep 2 and stalled again on Sep 22; the draw put it in the closer half",
  "stakes": "medium",
  "options": [
    "revive-first-stall",
    "hand-to-a-closer",
    "agent-keeps-it",
    "next-closer",
    "back-to-you",
    "close-the-file"
  ],
  "by": "worker_8",
  "on": "deal_31",
  "expected": "Deal.won within the 45-day window",
  "reopensWhen": "no closer Message on deal_31 within 5 business days"
}
NodeNow (140 days, both halves)Before (the 140 days before)AddedConfidenceBasis
stalled-deal-win-rate33 per 100: 1 of 3 decided won (closer half 1 of 2, agent half 0 of 1) · 1 still deciding0 per 100 (0 of 3)— · Worth about +$1,800 a month—before-after, not proof · Other Startups’ results: closer half +16 per 100 over the agent half, ■■□□ Early sign, n 212 Deals pooled
new-paying-customers ↑+1 (Granite Peak)0——before-after
new-arr$21,600, 1 Customer · Booked $21,600: credited, not all caused by this Play$0——before-after · Riverbend’s $18,000 still deciding
net-new-arr · arrcarried from new-arrcarried——carried

The leaf counts twice-stalled large Deals won per 100 drawn, by the half each was drawn into (intention to treat), read quarterly. A verdict needs 30 Deals per half, so a cohort pools across Startups.

How it moves it: the closer had the buyer’s own words in a brief within 1 business day of the second stall, and booked the CFO 9 days later.

Guardrails: before against after: discount points on won large Deals, 6 against a trailing 8, and refunds on closer-won revenue, $0 in 90 days; commission is 10 % of added first-year revenue, under the 50 % payback Stop.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/closer-handoff",
  "$type": "Campaign",
  "play": "play:closer-handoff@1",
  "path": [
    "stalled-deal-win-rate",
    "new-paying-customers",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "stalled-deal-win-rate",
    "unit": "per-100",
    "heldBack": 2,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 3,
    "maturing": 1,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 2160,
    "workerCost": 3,
    "hours": 1.4,
    "pipelineArr": 18000,
    "wonArr": 21600,
    "projectedArr": 1790,
    "paybackDays": 37
  }
}

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

Before it · After it. Before it: buying-committee and instant-response open the large Deals, and revenue marks a stall from buyer Events. After it: won Deals go to onboarding, and lost Deals go to objection-watch by their reason.

Example

Leaseline ran it from 2026-06-01 to 2026-10-19 (140 days): 6 large Deals open, 5 first stalls revived by drafts in your queue, and 4 second stalls drawn at random, 2 to each half. Read every captured thread at ?threads=all; three follow the tables.

What happened, by optionDecisionsDoneWon (credited, not all caused by this Play)
Hand it to a closer · Next closer2 · 12 accepted, 1 reassigned after 10 silent days1 · Granite Peak, $21,600; Northgate lost
The agent keeps it22 held 90 days, drafted into your queue0 · Riverbend still deciding; Lakeview lost
Revive the first stall · Back to you · Close the file5 · 1 · 25 drafts sent by you · 1 · 2 lost with reasons—
At 2 a quarter (the Use it when volume)about 8 drawn a yearbefore-after, not proofOther Startups’ results: +16 per 100, ■■□□ Early sign, n 212
DayEventWhat happenedYour time
0event_610 Campaign.createdthe three steps; the dry run fails billing-connected15 min
0event_611 Integration.connectedStripe connected for collected revenue5 min
9event_655 Agreement.signedTom Reyes signs the closer Agreement; POST /{namespace}/roles/{role}/staff seats him20 min
79event_1011 Deal.stalledRiverbend stalls twice; the draw keeps it with the agent—
113event_1290 Deal.stalledGranite Peak stalls twice; you approve the handoff; Tom accepts at 13:055 min
119event_1312 Action.refusedprice refused Tom’s 25 %-off Quote; the 2-year Quote at the floor sent—
128event_1371 Deal.wonGranite Peak signs: +$21,600 ARR; commission held to Dec 6—
1–140event_640 Approval.created, first of 8you sent 5 revival drafts, approved 2 handoffs and 1 reassignment1 h · total 1.4 h measured, 2 h asked

AE · your agent → Granite Peak’s CFO and operations lead, in their own thread, Sep 23, 10:05 · Tom Reyes is joining this thread: he closes multi-owner portfolio setups for Leaseline as a commissioned partner.¹ He has the 900-unit plan and your question about payment timing.² *Signed with the Role’s disclosure line.*³

Tom, 10:41 · booked the CFO for Thursday, then traded a 2-year term for net-45 payment inside the discount Limit. Signed Oct 7: Deal.won, +$21,600 ARR.

Granite Peak, 2026-09-28 · the Quote price refused, then the Quote that sent
- $16,200 a year (25 % off) if you sign this week.
+ $21,600 a year on a 2-year term, with net-45 payment; this Quote is valid until Oct 31.

Riverbend Group, 2026-10-14 09:20 · “Before anything else: can someone walk us through moving 750 units off our old system?” · AE · your agent, 09:21 · drafted into your queue with the Brief, due 2026-10-15 17:00 (task_602). · Dana, Oct 15 11:10 · sent her own answer and two times for a migration call.

¹ The real relationship and only the title the Agreement grants. ² The buyer’s own question; no stall, open or view is named. ³ The fixed signature line, compiled from the Role’s disclosure Setting.

Your settings

plays/closer-handoff.mdx
---
large: 12000      # Portfolio Deals at $12,000 a year and up; never under $10,000
draw: 0.5
commission: 0.10  # of collected first-year revenue, held 60 days
---
Draft every revival into my queue. On a second stall, half go to a commissioned closer and half stay with the agent; I approve every handoff.
Text
$ npx startup-builder show plays/closer-handoff
large 12000 · draw 0.5 · commission 0.10     your file  plays/closer-handoff.mdx:2-4,6 (Ask 2026-06-01)
family sale · worker role:sales-lead, owns never · chooses 6 (3 rule, 3 read) · sequences first-stall-revival, closer-intro, agent-arm-hold · checks owned-by-a-person, price, buyer-stop, buyer-keeps, recording · stops 9 · placements gmail, outlook, linkedin (the closer’s own)    catalog  play:closer-handoff@1 (Not live yet, gaps #5)

Every key from the catalog

Key Id What it is
Tactic stall-watch Stall watch computes each open Deal’s stalls from its buyer-authored Events and passes a large Deal’s second stall to the draw. Starts at Sends nothing.
Tactic agent-revival Agent revival is the agent’s own attempt on a stalled Deal, run on a first stall and for 90 days in the agent arm. Starts at Sends nothing.
Tactic closer-bench Closer bench seats commissioned closers through a paid work trial, a signed Agreement and verified payout details before any Deal needs one. Starts at Sends nothing.
Tactic closer-draw Closer draw checks a twice-stalled large Deal’s eligibility and a closer’s capacity, then randomizes it to the handoff arm or the agent arm. Starts at Sends nothing.
Tactic handoff-brief Handoff brief compiles a Deal’s full record for the closer, so no buyer repeats themselves, and offers it with a deadline. Starts at You approve each one.
Tactic closer-handoff-run Closer handoff run gives one closer ownership of the Deal for one window, has the agent introduce them in thread, and closes by record only. Starts at You approve each one.
Tactic closer-assist Closer assist drafts for the closer and sends scheduling and document deliveries in the closer’s name, under a Mandate that ends with the window. Starts at You approve the first wave.
Tactic closer-commission Closer commission earns a rate on a won Deal’s collected first-year revenue, net of refunds, and remits it monthly after a clawback hold. Starts at Sends nothing.
Tactic closer-readout Closer readout compares the handoff arm with the agent arm each quarter, beside its guardrails and payback, and records the verdict. 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 deal-stalled Deal stalled: state on Deal.stalled, window 14d.
Trigger deal-revived Deal revived: event on Deal.advanced, window 7d.
Trigger deal-stalled-twice Deal stalled twice: state on Deal.stalled, window 7d.
Trigger handoff-declined Handoff declined: event on Task.returned, window 1d.
Trigger closer-silent Closer silent: state on Deal.stalled, window 5d.
Trigger buyer-declines-closer Closer declined by the buyer: event on Conversation.answered, window 1d.
Trigger handoff-window-end Handoff window end: at on Deal.assigned, window 1d.
Trigger handoff-collected Handoff collected: event on Invoice.collected, window 30d.
Trigger handoff-refunded Handoff refunded: event on Invoice.refunded, window 1d.
Sequence closer-intro Closer intro: 4 steps; it ends on The closer sends a first Message; A buyer Contact asks to stop; A buyer asks to keep the agent.
Sequence agent-arm-hold Agent arm hold: 6 steps; it ends on Any buyer reply, routed to reply-matrix; The Deal is won or lost; A Contact opts out.
Sequence first-stall-revival First stall revival: 4 steps; it ends on A buyer-authored Event revives the Deal; A Contact opts out.

Compiled, not written: edit the Play record closer-handoff 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.