URL: /plays/paid-pilot · Id: `play:paid-pilot`

# Paid pilot

> Runs your product on the buyer’s own data for a fee, against pass marks no higher than they already saw, signed before it starts.

Runs your product on the buyer’s own data for a fee, against pass marks no higher than they already saw, signed before it starts.

```text title="Set it up · Ask"
Be our SE: when a buyer over 300 units wants to test Leaseline on their own leases, run the free check on 50 of them first, then propose a $400 pilot whose pass marks are no higher than what they saw. Priya owns the Deal and sends every message. A miss ends it with the refund. Show me what’s missing; don’t send.
```

```text title="Run one · Ask"
Hand our latest pilot ask to the SE 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 ("Quote.requested", "Conversation.labeled", "File.uploaded", "Invoice.collected", "Evaluator.scored", "Agreement.signed", "Conversation.answered", "Contact.enriched")', 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_574",
    "$type": "Decision",
    "choice": "propose-a-pilot",
    "reason": "the free check on 50 of Larkfield’s leases read renewal dates right on 48 (96 %) on Oct 12; $2,400 a year is at your median won Deal; Owen named the CFO, Hana Ito, as budget holder; 3 pilots are open, under the cap of 5",
    "stakes": "medium",
    "options": [
      "check-their-sample",
      "propose-a-pilot",
      "check-only",
      "start-the-term",
      "end-on-the-miss",
      "ask-the-budget-holder"
    ],
    "by": "worker_8",
    "on": "deal_21",
    "expected": "the pilot Agreement signed and the $400 fee paid within 10 business days",
    "reopensWhen": "no Agreement.signed for deal_21 within 10 business days of the proposal"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_8",
      "verb": "Quote.create",
      "checks": [
        {
          "check": "price",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_8",
      "verb": "Agreement.create",
      "checks": [
        {
          "check": "mark-cap",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "refused",
      "mode": "try",
      "by": "worker_8",
      "verb": "Message.schedule",
      "checks": [
        {
          "check": "owned-by-a-person",
          "status": "fail"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_4",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingClaim",
      "mode": "try",
      "by": "worker_8",
      "verb": "Task.assign",
      "checks": []
    }
  ]
}
```

`action_3` is refused by design: Priya owns the Deal, so the proposal does not send as the agent. `action_4` drafts it into her queue with the pass sheet and the Quote attached; she sends it from the Deal Thread.

`75 per 100 against 40 before · before-after, not proof · n 4 · path → arr`

| Try another: the Deal | Choice | Reason |
| --- | --- | --- |
| Larkfield Communities (640 units): “Can we test it on our own leases before we sign?” | `propose-a-pilot` | the free check is back at 96 %; at the median; budget holder named |
| Northgate Rentals (260 units): “Can it read our scanned leases?” | `check-their-sample` | a fit doubt: the free check on 50 of their leases first |
| Kestrel Rentals (40 units): “Can we pilot it?” | `check-only` | under the median won value: the free check answers it |
| Greystone Residential pilot, pass date Oct 9: 2 of 3 lines over their marks | `end-on-the-miss` | one deciding line under its mark: it ends that day, with the refund |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$430 ARR a month at 2 pilots | 1 h 30 min week 1, then 1 h a pilot | under 10 % of the $400 fee, ~$30 a pilot | Day 6: first pilot fee paid | 2+ open Deals a month over your median, asking to test | Under 2 Deals won on a buyer’s own data: `closer-handoff` · under your median: `product-led` |

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

Worth’s formula: about +15 technical wins per 100 pilots (Other Startups’ results; no lift of your own yet) × 2 pilots a month × 0.60 wins to a first term × $2,393 first order ARR ≈ +$431; the $400 fees are one-time and left out. Under First signal: At 2 pilots a month, 90 days can tell nothing on its own, so your file reads before-after; the pass-line Variants pool across Other Startups.

`sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Quote.requested · proposal drafted 52m after the ask · 10 keys Not live yet`

## Start it this week
```bash
npx startup-builder add play paid-pilot   # 1 · writes plays/paid-pilot.mdx (Not live yet, gaps #5)

# 2 · dry run; below, its 422 on 2026-07-06
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":"paid-pilot"}'

# 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":"paid-pilot"}'

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

# off: no new pilot is offered; running pilots finish on their signed terms
curl -X PATCH https://api.sb/leaseline.app/campaigns/paid-pilot \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
```


```json title="The dry run’s 422 · 2026-07-06 · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "paid-pilot can’t start yet: 1 check fails and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "3 open Deals a month at or over the $2,400 median; 2 Deals won on a buyer’s own data",
      "doc": "/plays/paid-pilot#check-use-when",
      "fix": "Nothing to do: it counts Deals at or over your median won value.",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "2 technical wins of 5 free proofs in 90 days",
      "doc": "/plays/paid-pilot#check-baseline",
      "fix": "n 5: it reads before-after, not proof; the pass-line Variants pool across Other Startups.",
      "then": "Metric.query"
    },
    {
      "check": "price",
      "status": "fail",
      "observed": "no pilot Offer and no price floor on the $2,400 plan",
      "doc": "/plays/paid-pilot#check-price",
      "fix": "Publish the $400 pilot Offer and the plan’s price floor; no rescue discount.",
      "then": "Offer.publish"
    },
    {
      "check": "owned-by-a-person",
      "status": "pass",
      "observed": "3 open Deals, each owned by a person",
      "doc": "/plays/paid-pilot#check-owned-by-a-person",
      "fix": "Nothing to do: every Deal-thread Message drafts into the owner’s queue.",
      "then": "Task.assign"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "sales-engineer",
        "sales-lead"
      ],
      "owned": 3,
      "doc": "/plays/paid-pilot#check-role-unstaffed",
      "fix": "Staff the AE, or leave it: every Deal and pilot comes to you.",
      "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: 3 Deals a month at the median; warn: 2 of 5 (gaps #8) | <Op verb="Metric.query" /> on `technical-win-rate`, which fills Before in Your number | 1 min | none |
| <a id="check-price"></a>`price` · fail (gaps #1) | <Op verb="Offer.publish" /> the pilot at $400 with the plan’s floor | 15 min | none |
| <a id="check-owned-by-a-person"></a>`owned-by-a-person` · pass: 3 Deals owned by a person | nothing; every Deal-thread send drafts into the owner’s queue | 0 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · warn (gaps #8): 3 open Deals have a person owner, you | <Op verb="Role.staff" />, or leave it: pilots and Deal-thread drafts come to you | 0 min | none |

`Your number · Before 40 per 100 · Now 75 per 100 technical wins · Target 70 by Dec 31 · before-after, not proof · n 4 completed · Other Startups +15, ■■■□ Likely`

Each pilot spends model and compute under 10 % of its $400 fee, about $30, and the free check about $3 on 50 items (Worker cost). The pilot Tenant is deleted 30 days after a miss or a no-decision. That comes to about $60 a month at 2 pilots, paid for by their fees.

## When it starts
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| Someone on an open Deal asks to test it on their own data | `pilot-ask` | `event` on `Quote.requested` where deal.status = 'open' and kind = 'pilot' | a written answer within 1 business hour | a reply in the Deal Thread, labeled by <Op verb="Conversation.update" /> |
| Their sample lands in the pilot Tenant | `sample-uploaded` | `event` on `File.uploaded` where tenant.kind = 'pilot' | free check back within 1 business day | <Op verb="File.create" /> in the pilot Tenant |
| The signed pass date arrives | `pass-date-reached` | `at` on `Agreement.signed` where agreement.passDate | the verdict the same day | the date on the signed pass sheet (<Op verb="Agreement.sign" />) |
| + 5 more: a fit doubt, the fee paid, a line out of reach at half the sample, a silent champion, and a buying-committee change (`?lanes=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$id": "https://api.sb/leaseline.app/events/event_1394",
  "$type": "Event",
  "name": "Quote.requested",
  "at": "2026-10-19T15:48:20Z",
  "seq": 1394,
  "data": {
    "deal": {
      "$id": "https://api.sb/leaseline.app/deals/deal_21",
      "company": "Larkfield Communities",
      "units": 640,
      "owner": "worker_3"
    },
    "contact": "contact_14",
    "text": "Can we test it on our own leases before we sign?",
    "check": {
      "run": "runs/run_33",
      "renewalDates": {
        "right": 48,
        "of": 50
      }
    }
  }
}
```

```bash title="Reproduce it in test"
npx startup-builder trigger Quote.requested --like event_1394   # replays the delivery in test
npx startup-builder clock advance --by 10d   # checks the proposal for a signature (reopensWhen)
npx startup-builder listen Agreement.signed --forward-to http://localhost:3000/hook
```

## Who runs it
**SE · your agent** (`role:sales-engineer`, `worker_8`) holds the Key Result: it runs the free check, drafts the pass sheet, runs the pilot and scores it. **AE · Priya Shah (person)** (`role:sales-lead`, `worker_3`) owns every Deal and sends every Deal-thread Message from its draft; **you** (Dana Okafor, person, `worker_1`) write to the budget holder. Your number links to Did it work.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Run the free check on their data · Stop at the free check | It drafts it for the AE | 7 of 7 checks back within 1 business day | never past the AE: she owns the Deal | — | <Op verb="Task.claim" /> · <Op verb="Task.return" /> |
| Propose a paid pilot · Start the first term | It drafts it; you approve the pass sheet | 5 proposals, 4 signed · 3 Quotes | Messages after 10 pilots with no number corrected by a buyer (4 so far); pass sheets never | a buyer corrects a number → You see each one first | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| End it on the miss | It does it | 1 of 1, same day | — | — | none: a miss ends it, with no extension and no rescue discount |
| Ask the budget holder | You write it | 1 of 1 | never | — | <Op verb="Task.claim" /> |
| Change a pass-line rule | You approve each one | 1 merged of 1 | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a mark over the free check, a second re-run, a pilot fee shown as recurring revenue | Refused, every time | 1 proposed, 1 refused | never | — | none: the Check holds it |

**What it reads · What it may call.** It reads the buyer’s own items, the pinned Evaluator and the signed pass sheet. A readout Page view never appears in a Message, and a pilot company never appears as a Customer or a reference until it pays a first term and says yes in writing. Its tools are <Op verb="Action.evaluate" />, <Op verb="Task.assign" />, <Op verb="Quote.create" />, <Op verb="Agreement.create" />, <Op verb="Content.draft" />, <Op verb="Quote.send" />, <Op verb="Invoice.refund" />, <Op verb="Agreement.terminate" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="The brief (folded): compiled Agent-register Markdown · play:paid-pilot@1 · each line names its record key"
You hold the SE Key Result: 70 technical wins per 100 pilots by 2026-12-31.      ← worker, metric
On each pilot ask, sample, score or date, choose one option and say why.         ← triggers, chooses
Every number comes from an Evaluator run on this buyer’s items, with n and the date. ← copyRules 1
No pass mark above what the free check showed them.                              ← copyRules 2, Mark cap
A miss readout states the miss in its first sentence.                            ← copyRules 3
The AE owns the Deal: draft every Deal-thread Message into her queue.            ← worker.owns, owned-by-a-person
```

**The slow loop, as a Change.** `decision_412` (2026-09-07, weekly) read 2 pilots whose pass sheets had 4 deciding lines, 1 passed, and 2 with 2 lines, both passed. `change_25` capped pass sheets at 3 deciding lines (your file, line 7), and Dana merged it with <Op verb="Change.merge" />. **Replayed on past pilots**, <Op verb="Change.review" /> passed 3 of 4; read back at +30d, 2 of 2 completed, n 2, ■□□□ Too early to tell (Example, day 98).

**Bring your own agent** (folded) starts at It does it, you can stop it when it matches or beats the seated agent on the eval suite, and at You approve each one when it does not; <Op verb="Role.staff" /> seats it.

```bash
npx startup-builder eval --scenario paid-pilot-9 --agent "claude -p" --seat sales-engineer   # seated: 0 numbers corrected, 0 Checks failed sent, 7 % of fee spent · yours: 1 mark over the check → You approve each one
```

## What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| Run the free check on their data `check-their-sample` | a pilot ask or a fit doubt, with 50 of their items | Your rule (line 6) | <Op verb="Action.evaluate" /> on 50 random items → <Op verb="Task.assign" /> the summary to the Deal owner | AE · Priya Shah sends it, due 1 business day · Take this one | you send it |
| Propose a paid pilot `propose-a-pilot` | the check is back; at or over the median; budget holder named; under 5 open | Your rule (line 5) | `pilot-proposal` → <Op verb="Quote.create" /> (with the $400 credit) → <Op verb="Agreement.create" /> (the pass sheet) | AE · Priya Shah sends it; you approve the pass sheet · Take this one | you |
| Stop at the free check `check-only` | under the median, or the check already answers the doubt | Agent’s call, with its reason | <Op verb="Content.draft" /> of the check’s numbers → <Op verb="Task.assign" /> | AE · Priya Shah · Take this one | you |
| Start the first term `start-the-term` | every deciding line at or over its mark on the pass date | Your rule (the pass sheet) | `pilot-decision` → <Op verb="Quote.send" /> for the first term, with the fee credited | AE · Priya Shah, due 1 business day · Take this one | you |
| End it on the miss `end-on-the-miss` | a line under its mark on the pass date, or out of reach at half the sample | Your rule (the Miss stop) | `pilot-miss-notice` → <Op verb="Invoice.refund" /> per your Setting → <Op verb="Agreement.terminate" />; deletion in 30 days | nobody; nothing follows for 90 days | the same |
| Ask the budget holder `ask-the-budget-holder` | the champion is silent 14 days or leaves | Agent’s call, with its reason | `pilot-founder-notes` → <Op verb="Task.assign" />; the run pauses | you write to the budget holder · Take this one | you |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | “Looks fair. Send the Agreement.” | the click-to-sign Agreement with the pass sheet and the $400 fee | AE · Priya Shah (person) | 1 business day | <Op verb="Agreement.sign" /> (theirs) |
| Send me pricing | “What would the first year cost after the pilot?” | the first-term Quote already on the pass sheet: $2,400, less the $400 credit | AE · Priya Shah (person) | 1 business day | <Op verb="Quote.send" /> |
| Not now | “Let’s revisit after our audit in January.” | the Deal stays open with January noted; no pilot is held for them | AE · Priya Shah (person) | at once | <Op verb="Deal.update" /> |
| Wrong person | “Our IT lead has to approve any data upload.” | asks them to bring the IT lead into the thread; it never writes to an address from their text | AE · Priya Shah (person) | 1 business day | <Op verb="Conversation.answer" /> |
| Out of office | an auto-reply until Oct 28 | the 10-day sample clock waits for the return date | nobody | the return date | <Op verb="Message.schedule" /> |
| Question it can’t answer | “Can you guarantee 99 % on our older scans?” | only the free check’s number can be a mark; the question goes to the SE draft and you | AE · Priya Shah, with you | 1 business day | <Op verb="Conversation.escalate" /> |
| Stop | “We’re going another way; delete our data.” | the pilot ends, and the sample and Tenant are deleted with one action, not 30 days | nobody | at once | <Op verb="File.delete" /> |

## When it hands to you
Every Deal-thread Message drafts into **AE · Priya Shah (person)**’s queue, because she owns the Deal; budget-holder notes come to **you**. One Brief per Role, as captured, then the Approval (`brief`, `draft` and `checks` are Not live yet, gaps #7).

```json title="What lands in each queue · sample"
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_477",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-20T15:48:00Z",
    "on": "deal_21",
    "brief": {
      "who": "Owen Hale, Larkfield Communities (640 units)",
      "said": "Can we test it on our own leases before we sign?",
      "chose": "propose-a-pilot",
      "why": "the free check read 48 of 50 renewal dates right; at the median",
      "attached": [
        "quotes/quote_58",
        "agreements/agreement_19"
      ],
      "never": [
        "a mark over 96 %",
        "a rescue discount"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_429",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-09-25T17:00:00Z",
    "on": "deal_17",
    "brief": {
      "who": "Greystone Residential: champion silent 14 days, day 12 of the pilot",
      "chose": "ask-the-budget-holder",
      "why": "a silent champion pauses the run",
      "to": "the budget holder, Marcus Webb, VP of Finance"
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/approvals/approval_93",
    "$type": "Approval",
    "verdict": null,
    "deadline": "2026-10-20T17:00:00Z",
    "draft": "Pass sheet, Larkfield: renewal dates read right ≥ 96 %; notice dates computed right ≥ 95 %; owner statements match ≥ 94 %…",
    "route": "propose-a-pilot",
    "checks": [
      {
        "check": "mark-cap",
        "status": "pass"
      },
      {
        "check": "price",
        "status": "pass"
      }
    ]
  }
]
```

Priya answers with <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason, or <Op verb="Action.redirect" />, and you with <Op verb="Approval.approve" /> or <Op verb="Approval.refuse" />, each a one-call window. <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 her name. A Task nobody claims by its due time goes up a Role through <Op verb="Task.escalate" /> (AE to you), and `person-promise` fires.

**On time:** AE · Priya Shah, 11 of 11 drafts claimed within 1 business day, median 2 h 40 min, n 11; you, 4 of 4 pass sheets approved by their deadline, n 4, ■□□□ Too early to tell beside Other Startups’ 94 % on time. **Your queue:** counted by kind: in week 1, 2 free-check summaries; during a pilot, about 1 pass sheet, 1 progress draft every 5 business days, and the readout.

**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 |
| --- | --- | --- | --- |
| `owned-by-a-person` (rule j; Not live yet, gaps #8) | every Deal-thread send as the agent, because a person owns each open Deal | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| <a id="check-mark-cap"></a>`mark-cap` (the record’s Mark cap) | a pass mark above the free check’s observed value, whoever proposes it | Set the mark at or below what the free check showed them. | <Op verb="Agreement.update" /> |
| <a id="check-pass-sheet-lock"></a>`pass-sheet-lock` (the record’s Pass sheet lock) | any edit to a signed pass sheet; a change is a new version both sign, once | Draft a new version for both sides to sign; the pass date resets. | <Op verb="Agreement.create" /> |
| <a id="check-re-run-cap"></a>`re-run-cap` (the record’s Re-run cap) | a second re-run, or one without a fixed Product defect and the buyer’s written ask | One re-run, on a defect fixed within 5 business days, with no mark changed. | <Op verb="Issue.resolve" /> |
| <a id="check-pilot-cap"></a>`pilot-cap` (the record’s Pilot cap) | a sixth open pilot | Wait in the queue for the dated start, or end a running pilot first. | <Op verb="Task.next" /> |
| `price` (gaps #1) | a Quote below the plan’s price floor, such as a rescue discount after a miss | Get the discount approved, or quote at the floor. | <Op verb="Approval.approve" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-miss"></a>`miss` | a deciding line under its mark on the pass date | the pilot ends that day, refunded per your Setting; no extension |
| <a id="stop-early-miss"></a>`early-miss` | at half the sample, a line’s 90 % upper bound sits under its mark | the pilot ends early, with the same refund |
| <a id="stop-no-sample"></a>`no-sample` | no sample within 10 business days of payment | the pilot is void, the fee refunded in full, the Deal parked 90 days |
| <a id="stop-label-hold"></a>`label-hold` | a hand-check disagrees on more than 2 of 20 items | the run holds; a second hold ends it with a full refund |
| <a id="stop-silence-hold"></a>`silence-hold` | the champion goes silent or leaves | the run pauses until the budget holder confirms |
| <a id="stop-spend-limit"></a>`spend-limit` | model and compute spend reaches 10 % of the fee | the run pauses; an Approval for you |
| <a id="stop-refund-floor"></a>`refund-floor` | miss refunds on over 25 % of pilots in 90 days, at 4 or more | new pilot offers pause; a Product Issue opens |
| <a id="stop-conversion-floor"></a>`conversion-floor` | under 5 of the last 10 passed pilots start a first term | new pilot offers pause until you review the pass lines |
| <a id="stop-contingent-cancel"></a>`contingent-cancel` | a miss on a pilot with a contingent first term | the term cancels before it starts, with nothing for the buyer to do |
| <a id="stop-deletion"></a>`deletion` | 30 days after a miss, a void or a no-decision | the sample and the pilot Tenant are deleted; the buyer can do it sooner |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every Tactic pauses; the AE is told |

The captured refusal, then the Stop that fired as a `Campaign.paused` reason (Not live yet, gaps #2); the rewrite that went out is the Northgate pass sheet in Example.

```json title="The captured refusal · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The Northgate pass sheet did not go out: one mark is above what the free check showed them.",
  "checks": [
    {
      "check": "mark-cap",
      "status": "fail",
      "doc": "/plays/paid-pilot#check-mark-cap",
      "fix": "Set the mark at or below what the free check showed them.",
      "then": "Agreement.update"
    },
    {
      "check": "price",
      "status": "pass"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "reason": {
      "limit": "label-hold",
      "observed": "3 of 20 items disagree",
      "bound": "2 of 20",
      "window": "the day-4 hand-check, Greystone"
    },
    "doc": "/plays/paid-pilot#stop-label-hold",
    "task": "task_421"
  }
]
```

## Did it work
At 2 pilots a month, no held-back half reads, so the basis is before-after (rule o): the columns read Now and Before, and nothing prints as Added. The pass-line experiment draws each eligible Deal into a buyer-sample or a seller-set Variant and pools it across Other Startups. Each figure’s call is <Op verb="Metric.query" /> by node, and every node above the leaf is Not live yet (gaps #4).

`75 per 100 against 40 before · before-after, not proof · n 4 · path → arr`

| Node | Now (105 days) | Before (the 90 days of free proofs) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `technical-win-rate` | 75 per 100: 3 of 4 completed pilots passed · 1 still running | 40 per 100: 2 of 5 free proofs | — · Worth about +$430 a month | — | before-after, not proof · Other Startups’ results +15 per 100, ■■■□ Likely, n 380 pilots |
| `new-paying-customers` | 2 from pilots, 1 still deciding · Booked $4,786: credited, not all caused by this Play | 1 from a free proof | — | — | before-after; pilot fees are one-time and left out |
| `new-arr` ↑ | $4,786, 2 Customers on the $2,400 plan | $2,393, 1 Customer | — | — | before-after; $1,600 of pilot fees roll off as `one-time-rolloff-arr` |
| `net-new-arr` · `arr` | carried from `new-arr` | carried | — | — | carried |

Before against after reads completed pilots in this window against the free proofs of the 90 days before it; it is not proof. Technical win counts a pilot whose every deciding line met its mark on the pass date.

**How it moves it:** each buyer saw your product score their own leases against marks no higher than the free check, and a miss ended the pilot that day; before, a free proof ran on your demo data (`technical-win-rate` by Variant).

**Guardrails:** before against after: passed pilots that started a first term, 2 of 3 against a floor of 5 of 10, and miss refunds, 1 of 4 against a floor of 25 % over 90 days.

```json title="The Campaign card · sample"
{
  "$id": "https://api.sb/leaseline.app/campaigns/paid-pilot",
  "$type": "Campaign",
  "play": "play:paid-pilot@1",
  "path": [
    "technical-win-rate",
    "new-paying-customers",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "technical-win-rate",
    "unit": "per-100",
    "heldBack": 0,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 4,
    "maturing": 1,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 126,
    "workerCost": 6,
    "hours": 7.2,
    "pipelineArr": 2400,
    "wonArr": 4786,
    "projectedArr": 431,
    "paybackDays": 9
  }
}
```

Outside benchmark: the catalog holds none for this Play yet, so Other Startups’ results stand in: +15 technical wins per 100 pilots, ■■■□ Likely, n 380 pilots.

**Before it · After it.** Before it: `instant-response`, `moment-outreach` and `buying-committee` open the Deals whose buyers ask to test. After it: a passed pilot’s first term carries its Tenant into onboarding, a miss reaches `objection-watch` as a dated no, and `run-beside` reports a side-by-side on the buyer’s own items.

## Example
Leaseline ran it from 2026-07-06 to 2026-10-19 (105 days): 9 Decisions on 7 open Deals, 7 free checks and 5 pilots proposed, 4 signed. 4 pilots completed: 3 passed and 1 missed. Read every captured thread at `?threads=all`; three follow the tables.

| What happened, by option | Decisions | Done | Won (credited, not all caused by this Play) |
| --- | --- | --- | --- |
| Run the free check on their data · Stop at the free check | 7 · 2 | 7 checks back within 1 business day · 2 stopped there | 0 |
| Propose a paid pilot | 5 | 4 signed, 4 fees paid ($1,600, one-time) | — |
| Start the first term · End it on the miss · Ask the budget holder | 3 · 1 · 1 | 2 started, 1 deciding · 1 refunded the same day · 1 run resumed | 2 on the $2,400 plan (+$4,786 ARR) · 0 · — |
| At 2 Deals a month (the Use it when volume) | about 7 in 105 days | before-after, not proof | Other Startups’ results: +15 per 100, ■■■□ Likely, n 380 pilots |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_101` Campaign.created | the three steps; the dry run fails `price`: no pilot Offer, no floor | 30 min |
| 0 | `event_104` Offer.published | the $400 pilot, credited to the $2,400 plan’s first term | 15 min |
| 6 | `event_160` Invoice.collected | the first pilot fee paid: Harborview Living | — |
| 58 | `event_640` Campaign.paused | `label-hold` on Greystone’s day-4 hand-check; labels fixed, run resumed in 1 day | 40 min |
| 63 · 98 | `event_702` Change.merged · `event_1015` Readout.created | pass sheets capped at 3 lines: replayed 3 of 4 passed, read back 2 of 2 | 5 min |
| 95 | `event_988` Invoice.refunded | `end-on-the-miss`: Greystone’s owner-statement line at 91 % against a 94 % mark; refunded that day | 10 min |
| 1–105 | `event_133` Task.assigned, first of 26 | Priya sent every Deal-thread draft; you approved 4 pass sheets; weekly reviews, from the <Op verb="Task.next" /> log | 5 h 30 min · **total 7.2 h measured, 7 h asked** |

> **Priya Shah → Rosa, Harborview Living, Jul 29, from the agent’s draft** · Your pilot passed on all 3 lines.¹ Renewal dates read right: 97.2 % (243 of 250, mark 96 %). Notice dates computed right: 98.0 % (mark 95 %). Owner statements match: 96.4 % (mark 94 %), scored Jul 28.² Your first term starts Aug 5 at $2,400 a year, less your $400 credit, unless you cancel before then on the same Page.³
>
> **Rosa, Jul 29, 16:20** · “Great. Go ahead.” <Op verb="Quote.accept" />, and the first term started on Aug 5.

```diff title="Northgate Rentals, 2026-09-14 · the pass sheet mark-cap refused, then the version that went out"
- Scanned leases read right: 98 % or better.
+ Scanned leases read right: 94 % or better (the free check read 47 of 50 on Sep 11).
```

> **Greystone Residential pilot, 2026-09-24** · the champion silent 14 days on day 12 · the run paused (`silence-hold`), and the Brief went to Dana (`task_429`). Dana wrote to the budget holder, Marcus Webb, on Sep 25 at 10:15, inside the due time; he confirmed the pilot the same afternoon and the run resumed.

¹ The verdict first, as the readout requires. ² Every number from the pinned Evaluator on their own 250 leases, with n and the date. ³ The contingent start date and its cancel action in one sentence.

## Your settings
```mdx title="plays/paid-pilot.mdx"
---
fee: 400          # credited to the first term
refund: full-on-miss
---
Over 300 units and at our median Deal, propose the pilot after the free check.
Any fit doubt gets the free check on 50 of their items first.
At most 3 deciding lines on a pass sheet.
Priya owns the Deal and sends every message; I write to the budget holder.
```

```text
$ npx startup-builder show plays/paid-pilot
fee $400 credited · refund in full on a miss · pilot over 300 units after the free check · 3 lines at most · the AE sends     your file  plays/paid-pilot.mdx:2,3,5,6,7,8 (Ask 2026-07-06; line 7 by change_25, 2026-09-07)
family conversion · worker role:sales-engineer, owns never · chooses 6 (4 rule, 2 read) · sequences pilot-proposal, pilot-run-updates, pilot-decision, pilot-founder-notes, pilot-miss-notice · approval every-send · checks owned-by-a-person, mark-cap, pass-sheet-lock, re-run-cap, pilot-cap, price · stops 11    catalog  play:paid-pilot@1 (Not live yet, gaps #5)
```

### Every key from the catalog
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-coverage-check"></a>`coverage-check` | Coverage check: Runs the Product free on 50 random items from the Customer’s sample and returns each Metric’s value, interval and failed items in 1 business day. Starts at You approve each one. |
| Tactic | <a id="tactic-pass-sheet-draft"></a>`pass-sheet-draft` | Pass sheet draft: Turns the Customer’s stated needs and the coverage-check numbers into at most 4 deciding lines, each mark capped at the observed value. Starts at You approve each one. |
| Tactic | <a id="tactic-pilot-signing"></a>`pilot-signing` | Pilot signing: Puts the pilot price, the pass sheet, the first-term Quote and its credit into one click-to-sign Agreement, and collects the pilot fee before the run. Starts at You approve each one. |
| Tactic | <a id="tactic-pilot-run"></a>`pilot-run` | Pilot run: Runs the paid sample inside the pilot Tenant, scores it with the pinned Evaluator, and shows every line’s number on a readout Page each morning. Starts at You approve each one. |
| Tactic | <a id="tactic-pilot-readout"></a>`pilot-readout` | Pilot readout: Freezes scoring on the pass date, reads each deciding line against its mark, and sends the verdict to the champion and budget holder that day. Starts at You approve each one. |
| Tactic | <a id="tactic-pilot-conversion"></a>`pilot-conversion` | Pilot conversion: Starts the first term on the schedule the pass sheet set, applies the pilot fee as a credit, and carries the pilot Tenant into Onboarding. Starts at You approve each one. |
| Tactic | <a id="tactic-pilot-miss-stop"></a>`pilot-miss-stop` | Pilot miss stop: Ends a pilot the day a deciding line misses: cancels any contingent first term, refunds per the Setting, files the Issue and schedules the deletion. Starts at Sends nothing. |
| Tactic | <a id="tactic-pass-line-experiment"></a>`pass-line-experiment` | Pass line experiment: Draws each eligible Deal into a Customer-sample or a seller-set Variant of pass marks, with price and refund fixed, pooled across siblings. 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. |
| Trigger | <a id="trigger-pilot-ask"></a>`pilot-ask` | Pilot ask: `event` on `Quote.requested`, window 1d. |
| Trigger | <a id="trigger-technical-objection"></a>`technical-objection` | Technical objection: `event` on `Conversation.labeled`, window 3d. |
| Trigger | <a id="trigger-sample-uploaded"></a>`sample-uploaded` | Sample uploaded: `event` on `File.uploaded`, window 1d. |
| Trigger | <a id="trigger-pilot-paid"></a>`pilot-paid` | Pilot paid: `event` on `Invoice.collected`, window 1d. |
| Trigger | <a id="trigger-pass-line-at-risk"></a>`pass-line-at-risk` | Pass line at risk: `threshold` on `Evaluator.scored`, window 1d. |
| Trigger | <a id="trigger-pass-date-reached"></a>`pass-date-reached` | Pass date reached: `at` on `Agreement.signed`, window 1d. |
| Trigger | <a id="trigger-champion-silent"></a>`champion-silent` | Champion silent: `state` on `Conversation.answered`, window 14d. |
| Trigger | <a id="trigger-member-role-change"></a>`member-role-change` | Member role change: `event` on `Contact.enriched`, window 30d. |
| Sequence | <a id="sequence-pilot-proposal"></a>`pilot-proposal` | Pilot proposal: 3 steps; it ends on A signed pilot Agreement; A decline; A stop request; A lost Deal; 10 business days of silence. |
| Sequence | <a id="sequence-pilot-run-updates"></a>`pilot-run-updates` | Pilot run updates: 4 steps; it ends on The readout is sent; The miss stop fires; The kill switch. |
| Sequence | <a id="sequence-pilot-decision"></a>`pilot-decision` | Pilot decision: 3 steps; it ends on The first term starts; The Quote is accepted; The contingent term is cancelled; A decline; The replacement Quote expires. |
| Sequence | <a id="sequence-pilot-founder-notes"></a>`pilot-founder-notes` | Pilot founder notes: 3 steps; it ends on The first term starts; A decline; A stop request; The miss stop fires; A lost Deal. |
| Sequence | <a id="sequence-pilot-miss-notice"></a>`pilot-miss-notice` | Pilot miss notice: 1 steps; it ends on The Message is sent. |