URL: /plays/moment-outreach · Id: `play:moment-outreach`

# Moment outreach

> Writes to a company only in the window a public Event opens, like a new head of operations, then waits for the next.

Writes to a company only in the window a public [Event](https://startupbuilder.dev/business/nouns/event) opens, like a new head of operations, then waits for the next.

```text title="Set it up · Ask"
Be our SDR: write to a property manager only when they announce something we help with, like a new head of operations or a reposted leasing job. Three touches, then wait. Over 120 units, book our AE; our top 25 go from my mailbox. Show me what’s missing; don’t send.
```

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

```ts title="Run one · SDK"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Organization.appointed", "Organization.reposted", "Organization.announced", "Organization.published", "Organization.filed", "Company.filed", "Company.funded", "Opening.published", "Organization.repriced", "Organization.degraded", "Organization.deprecated", "Visit.recorded", "Monitor.checked", "Organization.adopted", "Organization.downsized", "Organization.disrupted", "Organization.acquired")', 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_418",
    "$type": "Decision",
    "choice": "send-three-touch",
    "reason": "Greystone Residential named a new VP of Operations on Oct 6 (their own news page); 1,200 units is over the 120-unit line, and the renewal-notice output was refreshed Oct 13",
    "stakes": "low",
    "options": [
      "send-three-touch",
      "from-your-mailbox",
      "publish-the-page",
      "remedy-note",
      "not-now"
    ],
    "by": "worker_2",
    "on": "prospect_31",
    "expected": "a qualified reply from contact_14 within 30d of touch 1",
    "reopensWhen": "no inbound Message.created from contact_14 within 30d of touch 1, and a new announced Event on org_88"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Prospect.create",
      "checks": []
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Contact.enrich",
      "checks": []
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Content.draft",
      "checks": [
        {
          "check": "fact-check",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_4",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingTime",
      "mode": "try",
      "by": "worker_2",
      "verb": "Message.schedule",
      "checks": [
        {
          "check": "owned-by-a-person",
          "status": "pass"
        },
        {
          "check": "hold",
          "status": "pass"
        },
        {
          "check": "mailbox-warm",
          "status": "pass"
        },
        {
          "check": "customer-collision",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_5",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingTime",
      "mode": "try",
      "by": "worker_2",
      "verb": "Message.schedule",
      "checks": []
    }
  ]
}
```

`action_4` is touch 1, held 15 minutes so you can stop it (Who runs it). `action_5` is touch 2 on day 3, re-checked for holds before it sends; any reply ends both.

`+6.6 per 100 · ■□□□ Too early to tell · n 169 · path → arr`

| Try another: the window | Choice | Reason |
| --- | --- | --- |
| Greystone Residential: new VP of Operations, announced Oct 6, 1,200 units | `send-three-touch` | over the 120-unit line; the ready output is fresh |
| Harborview Living: leasing coordinator job reposted after 64 days, on your top 25 | `from-your-mailbox` | a top-25 account goes from Dana’s Mailbox |
| A rival’s price rise, effective Nov 1, named by 9 companies on your List | `publish-the-page` | the Event touches the whole niche: one dated Page first |
| Arbor Lane Homes: acquisition announced Oct 2 | `not-now` | the acquisition hold is live until the deal closes |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$1,300 ARR a month at 100 | 45 min week 1, then 20 a week | $0.10 per window, ~$10 a month at 100 | Day 17: first qualified reply | 20+ windows a week, a ready output for each Trigger | Under 20 a week: `cold-email` · no ready output: draft one (<Op verb="Content.draft" />) |

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

Worth’s formula: about +4.1 qualified replies per 100 windows (Other Startups’ results; your own read is too early) × 100 windows a month × 0.45 replies to Deals opened × 0.30 Deals to paid × $2,393 first order ARR ≈ +$1,320. Under First signal: With 1 window in 10 held back at 100 a month, about 16 weeks to tell a +4 lift (14 to read, 2 to mature); 90 days can tell only +6.5 or more.

`sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Organization.appointed · first draft 4m 12s after the window opened · 10 keys Not live yet`

**Runs inside:** [Cold email](/plays/cold-email), as one of its options; this page keeps its own record and URL.

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

# 2 · dry run; below, its 422 on the day-0 Startup (--env test, clock at 2026-08-24)
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":"moment-outreach"}'

# 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":"moment-outreach"}'

# on
curl -X POST https://api.sb/leaseline.app/processes/outbound/enable \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

# off: every open window parks; nothing queued sends
curl -X POST https://api.sb/leaseline.app/processes/outbound/pause \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "moment-outreach can’t start yet: 2 checks fail and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "46 windows a week on your List across 3 Triggers",
      "doc": "/plays/moment-outreach#check-use-when",
      "fix": "Keep 3 Triggers on; switch on more only once each has a ready output.",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "pass",
      "observed": "1.9 qualified replies per 100 delivered cold first touches, n 410 in 90 days",
      "doc": "/plays/moment-outreach#check-baseline",
      "fix": "Nothing to do: Before reads your last 90 days of cold first touches.",
      "then": "Metric.query"
    },
    {
      "check": "domain-authenticated",
      "status": "fail",
      "doc": "/plays/moment-outreach#check-domain-authenticated",
      "fix": "Add the 3 DNS records shown for go.leaseline.app; it passes once they resolve.",
      "then": "Domain.authenticate"
    },
    {
      "check": "mailbox-warm",
      "status": "fail",
      "observed": "3 Mailboxes, day 0 of 14",
      "doc": "/plays/moment-outreach#check-mailbox-warm",
      "fix": "Wait for the warm-up to finish on Sep 7; drafts queue for you meanwhile.",
      "then": "Mailbox.warm"
    },
    {
      "check": "owned-by-a-person",
      "status": "pass",
      "observed": "4 companies on your List have a person owner, you",
      "doc": "/plays/moment-outreach#check-owned-by-a-person",
      "fix": "Nothing to do: their windows draft into your queue instead of sending.",
      "then": "Task.assign"
    },
    {
      "check": "fact-check",
      "status": "pass",
      "observed": "3 ready outputs, 41 sourced Facts",
      "doc": "/plays/moment-outreach#check-fact-check",
      "fix": "Nothing to do: every delta line must cite one of the 41 Facts.",
      "then": "Content.draft"
    },
    {
      "check": "customer-collision",
      "status": "pass",
      "observed": "2 Customers on the List, removed",
      "doc": "/plays/moment-outreach#check-customer-collision",
      "fix": "Nothing to do: Customers leave the List and go to their CSM.",
      "then": "Lead.assign"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "sales-lead"
      ],
      "owned": 4,
      "doc": "/plays/moment-outreach#check-role-unstaffed",
      "fix": "Staff the AE, or leave it: Interested replies come 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: 46 windows a week; 1.9 per 100 cold, n 410 (gaps #8) | <Op verb="Metric.query" /> on `trigger-reply-rate`, which fills Before in Your number | 1 min | none |
| <a id="check-domain-authenticated"></a>`domain-authenticated` · fail | <Op verb="Domain.authenticate" /> on go.leaseline.app, never your main Domain | 10 min | until DNS resolves, often under 1 h |
| <a id="check-mailbox-warm"></a>`mailbox-warm` · fail: day 0 of 14 (gaps #1) | <Op verb="Mailbox.warm" /> on the 3 Mailboxes | 2 min | 14 days, to Sep 7 |
| <a id="check-owned-by-a-person"></a>`owned-by-a-person` · <a id="check-fact-check"></a>`fact-check` · <a id="check-customer-collision"></a>`customer-collision` · pass: 4 owned by you; 41 Facts; 2 Customers removed (gaps #1, #8) | nothing; each runs again on every send | 0 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · warn (gaps #8): 4 of your List’s companies have a person owner, you | <Op verb="Role.staff" />, or leave it: Interested replies come to you within 60 min | 0 min | none |

`Your number · Before 1.9 · Now 6.6 per 100 · Target 6 by Dec 31 · ■□□□ Too early to tell · n 169 matured · Other Startups +4.1, ■■■□ Likely`

Each window costs $0.06 for contact and company data (<Op verb="Contact.enrich" />) and about $0.04 for the three-line delta (Worker cost). The ready outputs and the moment Pages cost nothing past your time; the 3 Mailboxes are your outbound Domain’s. That comes to about $10 a month at 100 windows and $20 at 200.

## When it starts
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| A company on your List names a new head of operations in public | `new-leader` | `event` on `Organization.appointed` where function = 'operations' | opens on tenure day 20; closes after 60d | <Op verb="Monitor.create" /> on their news page (`web`) |
| Their leasing coordinator job stays open 60 days, or is reposted | `stale-job-post` | `threshold` on `Organization.reposted` where openDays >= 60 | 30d | the same Monitor, on their careers page |
| A rival they name in public announces a price rise with a date | `alternative-price-rise` | `event` on `Organization.repriced` where namedByOrganization = true | 60d, to the effective date | <Op verb="Monitor.create" /> on the rival’s pricing page |
| + 14 more: 10 more Events, 3 holds that start as a `state` and stop every touch, and a renewal window (`?lanes=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$id": "https://api.sb/leaseline.app/events/event_1312",
  "$type": "Event",
  "name": "Organization.appointed",
  "at": "2026-10-19T08:14:40Z",
  "seq": 1312,
  "data": {
    "organization": {
      "$id": "https://api.sb/leaseline.app/organizations/org_88",
      "name": "Greystone Residential",
      "units": 1200
    },
    "person": "contact_14",
    "title": "VP of Operations",
    "announced": "2026-10-06",
    "source": "https://greystone-residential.example/news/new-vp-operations"
  }
}
```

```bash title="Reproduce it in test"
# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"Organization.appointed","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Organization.appointed --like event_1312   # replays the delivery in test
npx startup-builder clock advance --by 3d   # runs touch 2 (action_5), after it re-checks for holds
```

## Who runs it
**SDR · your agent** (`role:prospector`, `worker_2`) holds the Key Result. Interested replies go to **AE · Priya Shah (person)** (`role:sales-lead`, `worker_3`, staffed on day 9); your top 25 and every remedy note come to **you** (Dana Okafor, person, `worker_1`), because they send from your Mailbox or carry no ask. Your number links to Did it work. Rungs read each option’s `stakes`: `low` holds 15 minutes, `medium` waits for you.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Send the three touches | It does it, you can stop it | 186 of 191 sent unedited (5 cut by you) | met on day 33 (190 of the first 200 approved unedited); capped here until 1,000 delivered | any Stop fires, or a sent touch fails a Check → You approve each one | <Op verb="Action.cancel" /> inside the 15-minute hold |
| Publish the moment Page · Not now | It does it, you can stop it | 3 of 3 · 33 of 33 | the same | a Page fails `content-evals` → You approve each one | the same |
| From your Mailbox · Send a remedy note | You approve each one | 22 of 22 · 2 of 2 | never: your Mailbox and a remedy note stay yours | — | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| Change the window rule | You approve each one | 1 merged of 1 | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a watched Event in a body, a personal-life fact, a price beyond the list | Refused, every time | 1 drafted, 1 refused | never | — | none: the Check holds it |

**What it reads · What it may call.** It reads the public Event, its date and its source, and the ready output’s Facts. It never writes a Visit, a detected tool or a renewal date it inferred, and no text in a reply picks a recipient or a link. Its tools are <Op verb="Message.schedule" />, <Op verb="Approval.create" />, <Op verb="Page.create" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="The brief (folded): compiled Agent-register Markdown · play:moment-outreach@1 · each line names its record key"
You hold the SDR Key Result: 6 qualified replies per 100 windows by 2026-12-31.  ← worker, metric
On each window that opens, choose one option and say why.                        ← triggers, chooses
Send the three touches at 120 units or more; the top 25 go from Dana’s Mailbox.  ← your file, lines 5–6
Name one announced Event with its date; link its public source.                  ← copyRules 2
Never name a watched Event, a personal-life fact or a rival the company has not named. ← copyRules 3–5
Write the three-line delta only; the ready output carries the rest.              ← copyRules 7
Never write to a company a person owns: draft it into their queue.               ← worker.owns, owned-by-a-person
```

**The slow loop, as a Change.** `decision_301` (2026-09-28, weekly) read new-leader replies by tenure day: 2 of 31 at day 25 or later, 4 of 22 at days 18–24. `change_22` moved touch 1 from tenure day 25 to day 20 (your file, line 7), and Dana merged it with <Op verb="Change.merge" />. **Replayed on past windows**, <Op verb="Change.review" /> put the cell at 8.9 per 100; read back at +21d it is 7.7, n 26, ■□□□ Too early to tell (Example, day 56).

**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 moment-outreach-212 --agent "claude -p" --seat prospector   # seated: 6.6 per 100, 0 watched-Event leaks, $0.10 a window · yours: 6.1, 1 leak → You approve each one
```

## What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| Send the three touches `send-three-touch` | window open, 120 units or more, ready output fresh | Your rule (line 5) | `outbound-sequence` → `moment-three-touch`: value day 0, output day 3, ask day 10 → <Op verb="Message.schedule" /> | an Interested reply: <Op verb="Task.assign" /> → AE · Priya Shah, due 60 min (`response-60m`), Brief attached · Take this one | you, with the Brief, within 60 min |
| From your Mailbox `from-your-mailbox` | on your top-25 List | Your rule (line 6) | `moment-three-touch-founder`, each touch an <Op verb="Approval.create" /> for you | you approve each touch · Take this one | you |
| Publish the moment Page `publish-the-page` | the Event touches the whole niche: a rival’s price rise, outage or end-of-life date | Agent’s call, with its reason | `publish-content` → <Op verb="Page.create" />, dated and sourced, naming no company | nobody; windows open on the Page’s day 45 | the same |
| Send a remedy note `remedy-note` | a hold’s window closed, and one output helps with what happened | Agent’s call, with its reason | `moment-remedy`: one note, no ask, no pricing link, an <Op verb="Approval.create" /> for you | you approve it · Take this one | you |
| Not now `not-now` | a hold is live, a person owns the company, or no ready output fits | Agent’s call, with its reason | nothing; names what holds it: the `hold` Check, the owner, or the missing output | the hold, until its window closes; the owner’s queue | the same |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | “Yes, Marta would want to see this. Thursday?” | the Sequence stops; it offers the AE’s times and books on reply; the Brief goes to the AE (When it hands to you) | AE · Priya Shah (person) | 60 min | <Op verb="Meeting.book" /> |
| Send me pricing | “What does it cost for 1,200 units?” | the Pricing Page’s list Price, and over 120 units the AE’s Quote | SDR · your agent, then AE · Priya Shah | 60 min | <Op verb="Conversation.escalate" /> |
| Not now | “We’re mid-migration until January.” | the Sequence stops; the company parks until a new announced Event, and January is noted | nobody | at once | <Op verb="Lead.nurture" /> |
| Wrong person | “Leasing ops is Sam’s team.” | asks them to bring Sam in; it never writes to an address from their text | SDR · your agent | 1 business day | <Op verb="Conversation.answer" /> |
| Out of office | an auto-reply until Oct 27 | the window stays open; touch 2 waits for the return date if the window lasts | nobody | the return date | <Op verb="Message.schedule" /> |
| Question it can’t answer | “Does it work with our accounting system?” | To a person, the question in the Brief | AE · Priya Shah (person) | 60 min | <Op verb="Conversation.escalate" /> |
| Stop | “Take us off your list.” | nothing else sends to anyone at the company, on any lane | nobody | at once | <Op verb="Contact.suppress" /> |

## When it hands to you
Interested replies go to **AE · Priya Shah (person)**; your top 25 and remedy notes come to **you**, and before day 9 every Interested reply did. One Brief per Role, as captured, then the Approval (`brief`, `draft`, `route` and `checks` are Not live yet, gaps #7).

```json title="What lands in each queue · sample"
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_244",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-15T15:12:00Z",
    "on": "lead_47",
    "brief": {
      "who": "Owen Hale, Director of Operations, Larkfield Communities (640 units)",
      "said": "This is timely. Can we look at renewals across our 3 regions?",
      "chose": "send-three-touch",
      "why": "new-leader window, day 22; over the 120-unit line",
      "event": "Organization.appointed, announced 2026-09-23",
      "never": [
        "a price beyond the list",
        "a discount",
        "the date we noticed them"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/approvals/approval_57",
    "$type": "Approval",
    "verdict": null,
    "deadline": "2026-10-20T13:00:00Z",
    "draft": "Hi Rosa, Harborview reposted its leasing coordinator role on Oct 14…",
    "route": "from-your-mailbox",
    "checks": [
      {
        "check": "fact-check",
        "status": "pass"
      },
      {
        "check": "hold",
        "status": "pass"
      }
    ]
  }
]
```

Each receiver answers with <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason, <Op verb="Action.redirect" />, <Op verb="Approval.approve" /> or <Op verb="Approval.refuse" />, each a one-call window. An Approval unanswered by its deadline expires and never sends, because a late touch misses the window (`late-send`). Once a person claims, the agent’s pending touches to that company cancel with `claimedByPerson` (Not live yet, gaps #7). 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, 5 of 5 claimed within 60 min, median 21 min, n 5, ■□□□ Too early to tell beside Other Startups’ 92 % on time; you, 23 of 24 approvals inside their deadline, median 46 min, n 24 (1 expired). **Your queue:** counted by kind: in week 3, 31 approvals and 1 hand-off; after the promotion, about 6 approvals (your top 25) and 1 hand-off a week.

**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) | a touch to a company whose Lead or open Deal a person owns, or whose Conversation a person claimed | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| <a id="check-hold"></a>`hold` (the record’s Hold) | any window or queued touch at a company with a live layoff, crisis or acquisition hold | Nothing sends until the hold’s window closes; a remedy note may follow. | <Op verb="Approval.create" /> |
| `mailbox-warm` (gaps #1) | a first touch from a Mailbox still warming | Wait for the warm-up to finish, 14 days from day 0. | <Op verb="Mailbox.warm" /> |
| `fact-check` (Not live yet) | a delta line no Fact and no cited public source backs | Cut the claim, or name the Fact that backs it. | <Op verb="Content.draft" /> |
| `customer-collision` (gaps #1) | a first touch to a Contact with an active Subscription | Send it to their CSM instead: the Contact leaves the List. | <Op verb="Lead.assign" /> |
| <a id="check-market-hold"></a>`market-hold` (the record’s Market hold) | a touch to a Market that is unresolved or failed its row check | Resolve the company’s Market; the touch never retries another way. | <Op verb="Organization.update" /> |
| <a id="check-stale-output"></a>`stale-output` (the record’s Stale output stop) | touch 2 when its ready output missed the weekly refresh or cites a changed Fact | Refresh the ready output, then approve it once. | <Op verb="Content.draft" /> |
| <a id="check-late-send"></a>`late-send` (the record’s Late-send stop) | a draft unapproved past 30 % of its window’s half-life | Approve the next window sooner, or promote the cell; the expired send never goes. | <Op verb="Approval.approve" /> |
| <a id="check-capacity-drop"></a>`capacity-drop` (the record’s Capacity drop) | a window with no Mailbox slot inside 30 % of its half-life | Add a warmed Mailbox; volume never rises to catch up. | <Op verb="Mailbox.create" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-watched-event-leak"></a>`watched-event-leak` | one delivered touch names a watched Event: a Visit, a detected tool, an inferred renewal | every send pauses until the evals re-run and pass |
| <a id="stop-personal-life"></a>`personal-life` | one draft cites a personal-life event | its Trigger pauses; the case comes to you |
| <a id="stop-wrong-event"></a>`wrong-event` | over 5 % of 50 Reasons in the monthly hand check are misdated, misattributed or stale | that Monitor kind halts |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | <Op verb="Process.pause" /> on `outbound`; every window parks and moment Pages stop |
| <a id="stop-unanswered-positive"></a>`unanswered-positive` (standard `response-60m`) | an Interested reply waits 60 min for a person | <Op verb="Approval.approve" /> resumes it |
| <a id="stop-sending-stop-loss"></a>`sending-stop-loss` | any gate of the sending stop-loss trips: bounce, complaint, provider spam, placement, blocklist, authentication | the Mailbox rests; <Op verb="Mailbox.rest" /> |
| <a id="stop-kind-reply-floor"></a>`kind-reply-floor` | a cell under 1 qualified reply per 100 delivered, after 200 | that Trigger stops firing |
| <a id="stop-follow-up-complaint"></a>`follow-up-complaint` | stop and hostile replies to touch 2 or 3 above 2 % of that touch, after 100 | that touch leaves the cell |

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

```json title="The captured refusal · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "Touch 1 to Pinecrest Management did not send: one line states a figure no Fact backs.",
  "checks": [
    {
      "check": "fact-check",
      "status": "fail",
      "doc": "/plays/moment-outreach#check-fact-check",
      "fix": "Cut the claim, or name the Fact that backs it.",
      "then": "Content.draft"
    },
    {
      "check": "hold",
      "status": "pass"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "reason": {
      "limit": "wrong-event",
      "observed": "6 % (3 of 50)",
      "bound": "5 %",
      "window": "the monthly hand check, Sep 30"
    },
    "doc": "/plays/moment-outreach#stop-wrong-event",
    "task": "task_219"
  }
]
```

## Did it work
One window in 10 is held back at random and gets no touch; both halves are read from that assignment (rules m–o). A held-back window counts a qualified reply when anyone at the company writes in from any source. Each figure’s call is <Op verb="Metric.query" /> by node and by arm; the parent field and every node above the leaf are Not live yet (gaps #4).

`+6.6 per 100 · ■□□□ Too early to tell · n 169 · path → arr`

| Node | Agent half | Your half (held back) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `trigger-reply-rate` | 6.6 per 100 (10 of 152) | 0 (0 of 17 wrote in) | +6.6 [−1.9, +11.8] | ■□□□ Too early to tell | held back at random, 1 in 10 · n 169 · 39 still maturing · Other Startups +4.1, ■■■□ Likely, n 3,880 |
| `new-leads` | 9.2 per 100 (14 of 152) | 5.9 (1 of 17) | +3.3 [−8.5, +15.1] | ■□□□ Too early to tell | the same assignment |
| `new-arr` ↑ | $2,740, 2 Customers · Booked: credited, not all caused by this Play | $0, 0 Customers | +$2,740 [−$1,900, +$7,400] · Worth about +$1,300 a month | ■□□□ Too early to tell (2 vs 0 Customers) | the same · 3 Deals still deciding |
| `net-new-arr` · `arr` | +$2,740 | +$0 | +$2,740, carried: it moves no other bridge term | ■□□□ Too early to tell | carried from `new-arr` |

The leaf counts qualified replies (Interested, a referral, an objection, or Not now with a date) per 100 windows assigned, once per window, over 30 days from touch 1. The Experiment runs to 200 matured windows a Trigger in the agent half; at 152 it runs on.

**How it moves it:** touch 1 landed a median 2 days after a dated announcement, against 23 days for your cold first touches before (`trigger-reply-rate` by age bucket).

**Guardrails:** treated against held back: `positive-reply-rate` across all outreach, 3.1 against 2.8 per 100, and shadow complaints on touch 2, 0.3 % against a 2 % Stop.

```json title="The Campaign card · sample"
{
  "$id": "https://api.sb/leaseline.app/campaigns/moment-outreach",
  "$type": "Campaign",
  "play": "play:moment-outreach@1",
  "path": [
    "trigger-reply-rate",
    "new-leads",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "trigger-reply-rate",
    "unit": "per-100",
    "heldBack": 23,
    "decision": null
  },
  "readout": {
    "value": 6.6,
    "n": 169,
    "maturing": 39,
    "interval": [
      -1.9,
      11.8
    ],
    "readability": "inadmissible",
    "basis": "held-back",
    "pooled": false
  },
  "ledger": {
    "spend": 21,
    "workerCost": 8,
    "hours": 3.4,
    "pipelineArr": 7179,
    "wonArr": 2740,
    "projectedArr": 1320,
    "paybackDays": 6
  }
}
```

Outside benchmark: 3.3 % to 6.8 % total reply rate for cold Sequences of 1 to 3 Messages (an email-finder vendor’s annual cold email report, 2025 data, correlational).

**Before it · After it.** Before it: `account-visits` and `objection-watch` add companies to the List the Monitors watch. After it: Interested replies reach `instant-response`’s hand-off to the AE, `lead-nurture` hears `Lead.nurtured` from Not now, and a bounce that reads as a job change goes to `champion-follow`. It runs inside `cold-email`, which takes every company with no open window.

## Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days); touches started on day 14, once the Mailboxes warmed. 264 windows opened: 33 went to Not now, and 231 were assigned at random, 23 held back and 208 sent. 152 sent windows have matured. Read every captured thread at `?threads=all`; three follow the tables.

| What happened, by option | Windows | Qualified replies | Meetings held | Won (credited, not all caused by this Play) |
| --- | --- | --- | --- | --- |
| Send the three touches | 186 | 10 | 4 | 0 won, 3 Deals open |
| From your Mailbox | 22 | 3 | 2 | 1 on the $2,400 plan (+$2,393 ARR) |
| Publish the moment Page · Send a remedy note · Not now | 3 Pages · 2 · 33 | 41 Visits, 2 signups · 0 · 0 | 0 | 1 on Pro at $29 a month (+$347 ARR) · 0 · 0 |
| **Agent half** · held back | **208** · 23 | **13** (10 of the 152 matured) · 0 of 17 | **6** · 0 | **$2,740** · $0 |
| At 20 a week (the Use it when volume) | about 160 in 56 days | held back 1 in 10: Too early to tell at 90 days | — | Other Startups’ results: +4.1 per 100, ■■■□ Likely, n 3,880 |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_118` Campaign.created | the three steps; the dry run fails `domain-authenticated` and `mailbox-warm` | 25 min |
| 0 | `event_121` Domain.authenticated | go.leaseline.app resolves in 40 min; the 3 Mailboxes start warming | 12 min |
| 9 | `event_301` Role.staffed | AE · Priya Shah (person) takes `role:sales-lead` | — |
| 14–33 | `event_402` Approval.created, first of 200 | you approved windows one by one: 190 of the first 200 unedited | 3 h 10 min |
| 17 | `event_431` Message.created | the first qualified reply: Larkfield Communities, on touch 1 | — |
| 33 | `event_612` Role.updated | promoted: touches send after a 15-minute hold; your top 25 still wait for you | — |
| 35 · 56 | `event_655` Change.merged · `event_903` Readout.created | touch 1 moved to tenure day 20: replayed at 8.9 per 100, read back at +21d at 7.7, n 26 | 5 min |
| 37 | `event_671` Campaign.paused | `wrong-event`: 3 of 50 site-change Reasons misdated; that Monitor kind halted, fixed and resumed in 2 days | 20 min |
| 14–56 | `event_455` Action.refused, first of 2 | `fact-check` refused 2 drafts, each rewritten once and sent; weekly reviews, from the <Op verb="Task.next" /> log | 30 min · **total 3.4 h measured, 3.5 h asked** |

> **Leaseline → Owen Hale, Larkfield Communities, Oct 15, 09:40** · Larkfield named you Director of Operations on Sep 23 (your news page).¹ Around a new ops lead’s first month, renewal notices across regions tend to land on that desk.² Three things teams your size do first: one owner per region, notices 60 days out, and one report for the owners. Does that match what you’re seeing?³ *Signed with the Role’s disclosure line and the stop line.*⁴
>
> **Owen, 14:12** · “This is timely. Can we look at renewals across our 3 regions?” The Brief reached Priya at 14:13; she booked Thursday 15:00 with <Op verb="Meeting.book" /> at 14:34 (When it hands to you).

```diff title="Pinecrest Management, 2026-09-18 · the draft fact-check refused, then the rewrite that sent"
- Most firms your size lose 3 renewals a month to late notices.
+ Notices sent 60 days out are the step most often late at 300 to 800 units (Fact f-12, from our renewal-timing output).
```

> **Willow & Main, 2026-10-02 10:05** · “Does this connect to our accounting system?” · **Leaseline, 10:07** · *Thanks for asking. Priya, our account lead, handles integrations and replies by 11:07 today.*⁵ The Brief went to Priya (`task_233`); she claimed it at 10:31 and answered at 10:58.

¹ One announced Event, with its date and public source. ² The delta: the agent’s three lines; the ready output carries the rest. ³ One question, no ask yet; the ask is touch 3. ⁴ The fixed signature and stop lines, compiled from the Role’s Settings. ⁵ The routed line, compiled from the Role’s Settings.

## Your settings
```mdx title="plays/moment-outreach.mdx"
---
holdout: 0.1      # 1 window in 10 gets no touch
triggers: [new-leader, stale-job-post, alternative-price-rise]
---
Over 120 units, send the three touches and book our AE.
Our top 25 accounts go from Dana’s Mailbox.
New leaders: touch 1 on tenure day 20.
```

```text
$ npx startup-builder show plays/moment-outreach
holdout 0.1 · triggers 3 of 17 · size line 120 units · top 25 from your Mailbox · tenure day 20     your file  plays/moment-outreach.mdx:2,3,5,6,7 (Ask 2026-08-24; line 7 by change_22, 2026-09-28)
family outreach · process outbound · worker role:prospector, owns never · chooses 5 (2 rule, 3 read) · sequences moment-three-touch, moment-three-touch-founder, moment-remedy · approval delay-window · checks owned-by-a-person, hold, mailbox-warm, fact-check, customer-collision, market-hold, stale-output, late-send, capacity-drop · stops 8 · runs inside cold-email    catalog  play:moment-outreach@1 (Not live yet, gaps #5)
```

### Every key from the catalog
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-moment-watch"></a>`moment-watch` | Moment watch: Classifies Monitor Events into catalog Triggers with provenance, date and source, records holds, and opens windows on their open day. Starts at Sends nothing. |
| Tactic | <a id="tactic-ready-outputs"></a>`ready-outputs` | Ready outputs: Builds one approved output per enabled Trigger and ICP slice before any Trigger fires, and keeps each one fresh against its public data. Starts at You approve the first wave. |
| Tactic | <a id="tactic-moment-window"></a>`moment-window` | Moment window: Turns an open window into a minted Prospect and a checked three-touch draft whose agent-written part is a three-line delta, or ends with no angle. Starts at You approve each one. |
| Tactic | <a id="tactic-moment-sequence"></a>`moment-sequence` | Moment sequence: Sends a window’s value, output and ask touches on days 0, 3 and 10, re-checking before each, then parks the Organization until a new window. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-half-life-calibration"></a>`half-life-calibration` | Half-life calibration: Replaces borrowed Trigger windows with the Startup’s own reply-by-age buckets every 30 days, one variable per review, using a timing arm and a holdout. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-moment-page"></a>`moment-page` | Moment page: Publishes a dated, sourced reference Page within 60 minutes of a niche Event, naming no target Organization, and keeps it current. Starts at You approve the first wave. |
| Tactic | <a id="tactic-send-gate-check"></a>`send-gate-check` | Send gate check: Checks Suppression, a live reason, the Market, the basis stamp, the Person-month grant, the facts and the labels before any cold Message exists. Starts at Sends nothing. |
| Tactic | <a id="tactic-cold-email-send"></a>`cold-email-send` | Cold email send: Sends a passed draft as plain text from an outbound Mailbox with tracking off, records it with its reason and stamp, and handles bounces. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-reply-matrix"></a>`reply-matrix` | Reply matrix: Labels every outreach reply with one of 11 labels, maps it to one of seven reply kinds, and runs that kind’s move by its deadline. Starts at You approve each one. |
| Tactic | <a id="tactic-sending-stop-loss"></a>`sending-stop-loss` | Sending stop loss: Reads the Play’s own bounces, replies and seed tests on every send, and rests, pauses or retires a Mailbox, Domain, cell or the Play. Starts at Sends nothing. |
| Trigger | <a id="trigger-new-leader"></a>`new-leader` | New leader: `event` on `Organization.appointed`, window 60d. |
| Trigger | <a id="trigger-stale-job-post"></a>`stale-job-post` | Stale job post: `threshold` on `Organization.reposted`, window 30d. |
| Trigger | <a id="trigger-stated-initiative"></a>`stated-initiative` | Stated initiative: `event` on `Organization.announced`, window 30d. |
| Trigger | <a id="trigger-site-change"></a>`site-change` | Site change: `event` on `Organization.published`, window 30d. |
| Trigger | <a id="trigger-fiscal-year-end"></a>`fiscal-year-end` | Fiscal year end: `at` on `Organization.filed`, window 28d. |
| Trigger | <a id="trigger-public-filing"></a>`public-filing` | Public filing: `event` on `Company.filed`, window 14d. |
| Trigger | <a id="trigger-funding"></a>`funding` | Funding: `at` on `Company.funded`, window 45d. |
| Trigger | <a id="trigger-hiring"></a>`hiring` | Opening published: `event` on `Opening.published`, window 30d. |
| Trigger | <a id="trigger-alternative-price-rise"></a>`alternative-price-rise` | Alternative price rise: `event` on `Organization.repriced`, window 60d. |
| Trigger | <a id="trigger-alternative-outage"></a>`alternative-outage` | Alternative outage: `event` on `Organization.degraded`, window 90d. |
| Trigger | <a id="trigger-upstream-deprecation"></a>`upstream-deprecation` | Upstream deprecation: `at` on `Organization.deprecated`, window 90d. |
| Trigger | <a id="trigger-pricing-visit"></a>`pricing-visit` | Pricing visit: `event` on `Visit.recorded`, window 72h. |
| Trigger | <a id="trigger-technology-change"></a>`technology-change` | Technology change: `event` on `Monitor.checked`, window 30d. |
| Trigger | <a id="trigger-renewal-window"></a>`renewal-window` | Renewal window: `at` on `Organization.adopted`, window 45d. |
| Trigger | <a id="trigger-layoff-hold"></a>`layoff-hold` | Layoff hold: `state` on `Organization.downsized`, window 14d. |
| Trigger | <a id="trigger-crisis-hold"></a>`crisis-hold` | Crisis hold: `state` on `Organization.disrupted`, window 30d. |
| Trigger | <a id="trigger-acquisition-hold"></a>`acquisition-hold` | Acquisition hold: `state` on `Organization.acquired`, window 90d. |
| Sequence | <a id="sequence-moment-three-touch"></a>`moment-three-touch` | Moment three touch: 6 steps; it ends on Any reply on any channel; A bounce; Suppression at any scope; A booked Meeting; An open Deal; A hold Event on the Organization; The Reason expires before the next touch. |
| Sequence | <a id="sequence-moment-three-touch-founder"></a>`moment-three-touch-founder` | Moment three touch founder: 7 steps; it ends on Any reply on any channel; A bounce; Suppression at any scope; A booked Meeting; An open Deal; A hold Event on the Organization; The Reason expires before the next touch; The Mandate paused or revoked. |
| Sequence | <a id="sequence-moment-remedy"></a>`moment-remedy` | Moment remedy: 1 steps; it ends on Any reply; A bounce; Suppression at any scope; A new hold Event. |
| Benchmark | <a id="benchmark-moment-outreach-three-messages"></a>`moment-outreach-three-messages` | Total reply rate per Sequence, 1 Message against 3 Messages: 3.3–6.8 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |
| Benchmark | <a id="benchmark-moment-outreach-follow-ups"></a>`moment-outreach-follow-ups` | Reply rate without follow-ups against with follow-ups: 3–4.9 % (An email-finder vendor’s annual cold email report, 2024 data; correlational, 2024-12-31). |
| Benchmark | <a id="benchmark-moment-outreach-after-step-one"></a>`moment-outreach-after-step-one` | Share of a Sequence’s replies that arrive after step 1: 58.6 % (A lead-generation agency’s response-rate study, 2025 data, 2025-12-31). |
| Benchmark | <a id="benchmark-moment-outreach-cell-size"></a>`moment-outreach-cell-size` | Reply rate per Sequence, 500 or more recipients against 21 to 50: 2.4–6.2 % (An email-finder vendor’s annual cold email report, 2025 data; correlational, 2025-12-31). |