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.
- Step
- Make the sale
- Channel
- Offers and Deals
- Kind
- Conversion
- Summary
- startupbuilder.dev
Be our AE on the big portfolio Deals I run myself: when one goes quiet, draft the revival into my queue. If it stalls a second time, flip a coin: half go to a commissioned closer paid 10 % of what we collect, half stay with you. I approve every handoff. Show me what’s missing; don’t send.
# Not live yet (gaps #2)
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"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'closer-handoff' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-06-01 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"closer-handoff"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'closer-handoff' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-06-01 · Not live yet, gaps #2",
"mode": "try"
}
}application/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"
},
{
…
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"
}
}application/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 yetPreviewOn 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,
| Try another: the Deal | Choice | Reason |
|---|---|---|
| Granite Peak Rentals: $21,600 Portfolio, revived once, stalled again Sep 22 | hand-to-a-closer | stalled twice; the draw put it in the closer half |
| Riverbend Group: $18,000 Portfolio, stalled twice Aug 19 | agent-keeps-it | stalled twice; the draw put it in the agent half |
| Lakeview Partners: $12,000 Portfolio, first stall on Jul 6 | revive-first-stall | no buyer Event for 21 days, the first time |
| Northgate Housing: the closer went 5 business days silent | next-closer | the same brief and window end go to the next closer |
- Day 1: a closer accepts the brief
- First signal
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/
Start it this week
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"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | 6 Portfolio Deals over $12,000 open; 3 stalled twice in the last 2 quarters | POST /{namespace}/metrics/query |
baseline warn · Not live yet, gaps #8 | n 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 #8 | Connect Stripe so commission reads collected revenue, net of refunds. | POST /{namespace}/integrations/connect |
role-unstaffed warn · Not live yet, gaps #8 | Staff 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.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
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 number | 1 min | none |
billing-connected · fail | POST /{namespace}/integrations/connect with system recurring-billing (Stripe) | 5 min | the first sync, about 10 min |
role-unstaffed · warn (gaps #8): 6 large Deals have a person owner, you | POST /{namespace}/roles/{role}/staff a commissioned closer after POST /{namespace}/agreements/{agreement}/sign; the agent drafts into your queue for your 6 | 20 min | the 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,
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
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| A large Deal a buyer revived once goes quiet again | deal-stalled-twice | state on Deal.stalled where a large Deal revived once enters stalled again | 7d | the daily stall scan reads your Deals’ buyer Events |
| An open Deal gets no buyer Event for its stall timeout | deal-stalled | state on Deal.stalled where no buyer-authored Event for the Deal’s stall timeout, or its close date 7 days past | 14d | the same scan; your own sends never reset the clock |
| A handed-off Deal shows no closer action for 5 business days | closer-silent | state on Deal.stalled where no closer Message, call or Meeting on a handed-off Deal for 5 business days | 5d | the 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=) |
{
"$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"
}
}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:, 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.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Revive the first stall · The agent keeps it | You approve each one | 3 of 3 · 2 of 2 | never: the Deals are yours (owned-by-a-person) | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Hand it to a closer · Next closer | You approve each one | 2 of 2 · 1 of 1 | never: every handoff is yours to approve | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Back to you · Close the file | It does it | 1 of 1 · 2 of 2 | — | a buyer asks the agent anything it can’t answer → You approve each one | POST /{namespace}/actions/{action}/redirect |
| Change the large line or the draw | You approve each one | 0 merged: both are sealed for the cohort | never | — | 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 floor | Refused, every time | 1 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.
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
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Revive the first stall revive-first-stall | the first stall: no buyer Event for 21 days | Your rule (line 6) | first-stall-revival, drafted into your queue | you send each step, due 1 business day · Take this one | the same |
Hand it to a closer hand-to-a-closer | stalled twice; the draw says closer | Your rule (the draw, line 3) | POST /{namespace}/tasks/{task}/assign the brief → closer-intro → POST /{namespace}/deals/{deal}/assign | AE · Tom Reyes, accept within 1 business day · Take this one | you, if no closer is staffed |
The agent keeps it agent-keeps-it | stalled twice; the draw says agent | Your rule (the draw, line 3) | agent-arm-hold, 90 days, drafted into your queue | you send each step · Take this one | the same |
Next closer next-closer | declined, the deadline passed, or 5 business days silent | Agent’s call, with its reason | POST /{namespace}/tasks/{task}/assign the same brief → POST /{namespace}/deals/{deal}/assign | the next closer, same window end | you |
Back to you back-to-you | the buyer asks to work with Leaseline directly | Agent’s call, with its reason | POST /{namespace}/deals/{deal}/assign → POST /{namespace}/tasks/{task}/assign | you, due 1 business day; it stays in the closer half | the same |
Close the file close-the-file | the window ends open, or the buyer says no | Agent’s call, with its reason | POST /{namespace}/deals/{deal}/lose with its reason | nobody; the reason feeds objection-watch | the same |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “Thursday works for our CFO.” | the closer books it on his calendar under his name | AE · Tom Reyes (person) | 60 min | POST /{namespace}/meetings/book |
| Send me pricing | “Send the 2-year number.” | a Quote at or above the floor, with its real validUntil | AE · Tom Reyes | 1 business day | POST /{namespace}/quotes/{quote}/send |
| Not now | “Back to this after budgets in January.” | a dated next step on the Deal; nothing sends before it | AE · Tom Reyes | at once | POST /{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 text | AE · Tom Reyes | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Oct 28 | the window waits; the silence clock pauses to the return date | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “How is Tom paid?” | the closer answers truthfully: 10 % of what Leaseline collects | AE · Tom Reyes | 60 min | POST /{namespace}/conversations/{conversation}/answer |
| Stop | “Please stop contacting us.” | nothing else sends to that Contact, on any channel; you get a Task | nobody | at once | POST /{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).
[
{
"$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) | Refuses | Fix | Then |
|---|---|---|---|
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 claimed | Leave 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 floor | Get 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 stop | Nothing 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 directly | The 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 record | Ask each attendee on the call, then record. | POST /{namespace}/meetings/book |
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.
| Check | Fix | Then |
|---|---|---|
price fail · Not live yet, gaps #1 | Get 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.
[
{
"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,
- 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"
}| Node | Now (140 days, both halves) | Before (the 140 days before) | Added | Confidence | Basis |
|---|---|---|---|---|---|
stalled-deal-win-rate | 33 per 100: 1 of 3 decided won (closer half 1 of 2, agent half 0 of 1) · 1 still deciding | 0 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 · arr | carried from new-arr | carried | — | — | 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.
{
"$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=; three follow the tables.
| What happened, by option | Decisions | Done | Won (credited, not all caused by this Play) |
|---|---|---|---|
| Hand it to a closer · Next closer | 2 · 1 | 2 accepted, 1 reassigned after 10 silent days | 1 · Granite Peak, $21,600; Northgate lost |
| The agent keeps it | 2 | 2 held 90 days, drafted into your queue | 0 · Riverbend still deciding; Lakeview lost |
| Revive the first stall · Back to you · Close the file | 5 · 1 · 2 | 5 drafts sent by you · 1 · 2 lost with reasons | — |
| At 2 a quarter (the Use it when volume) | about 8 drawn a year | before-after, not proof | Other Startups’ results: +16 per 100, ■■□□ Early sign, n 212 |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_610 Campaign.created | the three steps; the dry run fails billing-connected | 15 min |
| 0 | event_611 Integration.connected | Stripe connected for collected revenue | 5 min |
| 9 | event_655 Agreement.signed | Tom Reyes signs the closer Agreement; POST /{namespace}/roles/{role}/staff seats him | 20 min |
| 79 | event_1011 Deal.stalled | Riverbend stalls twice; the draw keeps it with the agent | — |
| 113 | event_1290 Deal.stalled | Granite Peak stalls twice; you approve the handoff; Tom accepts at 13:05 | 5 min |
| 119 | event_1312 Action.refused | price refused Tom’s 25 %-off Quote; the 2-year Quote at the floor sent | — |
| 128 | event_1371 Deal.won | Granite Peak signs: +$21,600 ARR; commission held to Dec 6 | — |
| 1–140 | event_640 Approval.created, first of 8 | you sent 5 revival drafts, approved 2 handoffs and 1 reassignment | 1 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.
- $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
---
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. $ 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
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.