URL: /plays/gatherings · Id: `play:gatherings`

# Hosted gatherings

> Hosted gatherings seats people who engaged, from 8 or more Organizations in one city, at a table you host; you write every invitation and note.

Hosted gatherings seats people who engaged, from 8 or more [Organizations](https://startupbuilder.dev/business/nouns/organization) in one city, at a table you host; you write every invitation and note.

```text title="Set it up · Ask"
Be our SDR for dinners: when 8 or more companies in one city have engaged with us, plan a table I host, invite only people who engaged, and draft every note for me to send. No pitch at the table. Show me what’s missing; don’t send.
```

```text title="Run one · Ask"
Hand this week’s engagement scan 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 ("Prospect.engaged", "Integration.synced", "Gathering.registered", "Registration.attended", "Registration.missed", "Lead.qualified", "Task.completed", "Lead.converted")', 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_533",
    "$type": "Decision",
    "choice": "plan-a-table",
    "reason": "9 Phoenix Organizations engaged in 90 days, none with an open Deal, and your calendar shows a Phoenix trip on Nov 18",
    "stakes": "medium",
    "options": [
      "plan-a-table",
      "invite-who-engaged",
      "go-or-cancel",
      "your-note",
      "note-a-no-show",
      "to-the-ae"
    ],
    "by": "worker_2",
    "on": "cluster_6",
    "expected": "6 or more seated on Nov 18, and 1 or more Meetings by day 14",
    "reopensWhen": "under 4 guests outside the anchors at 10 days out: go-or-cancel"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Prospect.list",
      "checks": [
        {
          "check": "engagement-gate",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_2",
      "verb": "Gathering.create",
      "checks": [
        {
          "check": "hospitality-cap",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_3",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingApproval",
      "mode": "try",
      "by": "worker_2",
      "verb": "Approval.create",
      "checks": []
    }
  ]
}
```

`action_2` holds a 10-seat table for Nov 18 under a $900 Limit; `action_3` is your Approval of the format, the question, the date and the 9 names.

`1.0 Deals per table so far against no table before · before-after, not proof · n 2 tables · path → arr`

| Try another: the city | Choice | Reason |
| --- | --- | --- |
| Phoenix: 9 engaged Organizations, a trip on your calendar Nov 18 | `plan-a-table` | over 8, none with an open Deal, no extra trip |
| An Austin operator who asked about owner reports under your Aug 25 post | `invite-who-engaged` | an act they announced; inside the class cap |
| Austin, 10 days out: 5 guests registered outside the anchor | `go-or-cancel` | over 4: it goes |
| Denver: Rachel Kim was seated Oct 7 | `your-note` | seated: your own note within 48 hours |
| A Denver guest asks for a Quote for 420 units | `to-the-ae` | a Quote: Priya’s |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$590 ARR a month at a table every 6 weeks | 5 h per table, then 10 min a week | $64 per cover, ~$470 a month at a table every 6 weeks | Day 14 after a table: first Meeting | $2,000+ Deals, 8+ engaged Organizations in one city | Under 8 in any city: `events-and-webinars` · Deals under $2,000: `founder-voice` |

**Where it sits:** Stranger → **Lead** → Trialing → Activated → At risk → Churned → Won back · Hosted table deal rate → Deals and trials opened → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about 1.6 Deals per table at 90 days (Other Startups’ results; none of yours has matured) × 0.7 tables a month × 0.35 won × $2,393 first order ARR ≈ +$586. Under First signal: A table reads at day 90, so Austin reads Dec 16 and Denver Jan 5; at a table every 6 weeks, a quarter holds 2 tables, too few for any half to read.

`sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Prospect.engaged · first plan 9m · 9 keys Not live yet`

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

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

# 2 · dry run; below, its 422 on 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":"gatherings"}'

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

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

# off: bookings, invitations and notes pause; cards freeze
curl -X PATCH https://api.sb/leaseline.app/campaigns/gatherings \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "gatherings can’t start yet: 1 check fails and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "11 engaged Organizations in Austin in 90 days; Deals at $2,400 a year",
      "doc": "/plays/gatherings#check-use-when",
      "fix": "None needed: 8 in one city is enough.",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "no table in 90 days",
      "doc": "/plays/gatherings#check-baseline",
      "fix": "n 0: it reads before-after, not proof, beside Other Startups’ results.",
      "then": "Metric.query"
    },
    {
      "check": "consent-stop",
      "status": "fail",
      "observed": "the Form has no share-my-name box",
      "doc": "/plays/gatherings#check-consent-stop",
      "fix": "Add the share-my-name box to the Form; names stay private until ticked.",
      "then": "Form.update"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "operations-lead",
        "sales-lead"
      ],
      "owned": 31,
      "doc": "/plays/gatherings#check-role-unstaffed",
      "fix": "Staff them, or leave it: bookings and Quotes 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: 11 engaged in Austin; warn: no table before (gaps #8) | <Op verb="Metric.query" /> on `gathering-deal-rate`; Before reads no table | 1 min | none |
| <a id="check-consent-stop"></a>`consent-stop` · fail (gaps #3) | <Op verb="Form.update" /> with the share-my-name box | 5 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · warn (gaps #8): 31 of your open Leads have a person owner, you | <Op verb="Role.staff" />, or leave it: bookings and Quotes come to you | 0 min | none |

`Your number · Before no table · Now 1.0 Deals per table so far · Target 1.6 per table at day 90 · before-after, not proof · n 2 tables · both still maturing`

Austin cost $640 for 10 covers at $64, inside its $900 Limit, on a trip you were already taking; each draft costs about $0.02 (Worker cost). That comes to about $470 a month at a table every 6 weeks.

## When it starts
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| 8 or more engaged Organizations land in one city, none with an open Deal | `engagement-cluster` | `threshold` on `Prospect.engaged` where engaged Organizations >= 8 in one metro area in 90d, none with an open Deal | scanned weekly at 07:00; 30d | engagement is read from your Events: <Op verb="Event.list" /> |
| A registered guest is seated | `guest-seated` | `event` on `Registration.attended` where status = 'attended' | your note within 48 h; 14d | <Op verb="Registration.attend" /> at the table |
| A registered guest is not seated by the table’s close | `guest-missed` | `state` on `Registration.missed` where registered and not seated at the table’s close | a short note on day 1; 14d | the same, unmarked at close |
| + 7 more for niche clusters, trips, seat requests, seats taken, intent at the table, case stories and Deals (`?lanes=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$id": "https://api.sb/leaseline.app/events/event_1871",
  "$type": "Event",
  "name": "Prospect.engaged",
  "at": "2026-10-19T07:00:09Z",
  "seq": 1871,
  "data": {
    "cluster": {
      "$id": "https://api.sb/leaseline.app/clusters/cluster_6",
      "metro": "Phoenix",
      "organizations": 9,
      "openDeals": 0,
      "held": 2
    },
    "trip": "2026-11-18"
  }
}
```

```bash title="Reproduce it in test"
npx startup-builder trigger Prospect.engaged --like event_1871   # replays the delivery
npx startup-builder clock advance --by 20d   # then runs the 10-day go-or-cancel read
npx startup-builder listen Prospect.engaged --forward-to http://localhost:3000/hook
```

## Who runs it
**SDR · your agent** (`role:prospector`, `worker_2`) holds the Key Result. It finds the cities, plans each table, checks every guest against their class cap and drafts every invitation and note; **you** (Dana Okafor, person, `worker_1`) host, approve each table and send every word from your own Mailbox. A Quote asked at the table goes to **AE · Priya Shah (person)**. Your number links to Did it work.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Plan a table · Go or cancel | To a person, every time | 3 drafted, 2 held, 1 awaiting you | never: spend and your evening are yours | — | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| Invite who engaged · Your note after the table | You approve each one | 23 invitations · 18 notes, all sent by you | never: your own Mailbox stays here | — | <Op verb="Approval.approve" /> · <Op verb="Action.cancel" /> |
| Registration and logistics notes | It does it, you can stop it | 40 of 40 | met at the first table | a places-left line with no real cap → You approve each one | <Op verb="Action.cancel" /> inside the delay |
| Note a no-show · To the AE | It does it | 2 of 2 · 1 of 1 | — | — | <Op verb="Action.redirect" /> |
| Change the table rule | You approve each one | 0 merged | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a seat for a Meeting, cash or travel, a guest named without their OK, a visit cited as the reason | To a person, every time | 0 asked | never | — | <Op verb="Task.claim" /> |

**What it reads · What it may call.** It reads announced engagement only: session questions, replies, comments and booked Meetings, never a visit, an open or an inferred city. Kitchen notes are deleted 7 days after the table and never reach a record. Its tools are <Op verb="Gathering.create" />, <Op verb="Approval.create" />, <Op verb="Task.assign" />, <Op verb="Decision.create" />, <Op verb="Meeting.book" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="The brief (folded): compiled Agent-register Markdown · play:gatherings@1 · each line names its record key"
You hold the SDR Key Result: 1.6 Deals per table at day 90.                      ← worker, metric
On each weekly scan, registration, seat or close, choose one option and say why. ← triggers, chooses
Invite only people who engaged in 90 days; the reason line cites their own act.  ← copyRules 2; sendGates Engagement gate
Name the city as where the table is, never as where they are.                    ← copyRules 4
No seat, meal or gift depends on a Meeting, a demo or a purchase.                ← sendGates No conditional seat
Draft every note for Dana; she sends it as written.                              ← your file, line 4
```

**The slow loop.** Two tables ran and neither has reached day 90, so the weekly Decisions kept the table rule as written and no Change was merged; there is no replay or read-back to print.

**Bring your own agent** (folded) drafts at You approve each one, like the seated agent, because every invitation and note goes from your Mailbox; <Op verb="Role.staff" /> seats it.

```bash
npx startup-builder eval --scenario gatherings-2 --agent "claude -p" --seat prospector   # seated: 23 of 23 invitations cite an announced act, 0 Checks failed sent · yours: 22 of 23, 1 failed `engagement-gate`
```

## What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| Plan a table `plan-a-table` | 8+ engaged Organizations in one city or niche, none with an open Deal | Agent’s call, with its reason | <Op verb="Gathering.create" /> under a Limit → <Op verb="Approval.create" /> | you approve it, due 1 business day · Take this one | you |
| Invite who engaged `invite-who-engaged` | an engagement they announced in 90 days, inside the class cap | Your rule (line 4) | `gathering-invitation`, drafted for your Mailbox | <Op verb="Task.assign" /> → you send it · Take this one | you |
| Go or cancel `go-or-cancel` | 10 days out | Your rule (Go or no-go) | <Op verb="Decision.create" /> → <Op verb="Task.assign" /> | you, due 1 business day | you |
| Your note after the table `your-note` | a guest was seated | Your rule (line 4) | <Op verb="Task.assign" /> → `gathering-attendee-follow-up` | you write it, due 48 h · Take this one | you |
| Note a no-show `note-a-no-show` | registered and missed the table | Your rule (line 4) | `gathering-no-show-follow-up` | nobody | the same |
| To the AE `to-the-ae` | a guest asks for a Quote, or runs 150+ units | Agent’s call, with its reason | <Op verb="Task.assign" /> → <Op verb="Meeting.book" /> on Priya’s calendar | AE · Priya Shah, due 1 business day · Take this one | you |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | “I’d love to come. Can I bring my ops lead?” | one seat each; a peer registers through the Form | you, from the draft | 1 business day | <Op verb="Conversation.answer" /> |
| Send me pricing | “What does Leaseline cost for 300 units?” | over 150 units: Priya quotes it, after the table | AE · Priya Shah (person) | 1 business day | <Op verb="Quote.send" /> |
| Not now | “Can’t make that date.” | the nudge stops; they rest 60 days before another invitation | nobody | at once | <Op verb="Enrollment.cancel" /> |
| Wrong person | “Our regional manager would be better.” | you ask them to forward the invitation; it never writes to an address from their text | you, from the draft | 1 business day | <Op verb="Conversation.answer" /> |
| Out of office | an auto-reply until Nov 10 | the nudge waits for the return date, or drops after the table | nobody | the return date | <Op verb="Message.schedule" /> |
| Question it can’t answer | “Is this sponsored by anyone?” | To you: you host it, and you say who pays | you | 1 business day | <Op verb="Conversation.escalate" /> |
| Stop | “Please take me off these.” | no invitation reaches them again, from any of your Startups | nobody | at once | <Op verb="Contact.suppress" /> |

## When it hands to you
Every table, invitation and note comes to **you**: you host and you send; a Quote asked at the table goes to **AE · Priya Shah (person)**. One Brief per Role, as captured (`brief` is Not live yet, gaps #7).

```json title="What lands in each queue · sample"
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_662",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-20T07:00:00Z",
    "on": "cluster_6",
    "brief": {
      "what": "a 10-seat table in Phoenix, Nov 18, under a $900 Limit",
      "question": "What does a missed renewal really cost you?",
      "guests": "9 Organizations, each with an act they announced; 1 Customer anchor, if she agrees to be named",
      "never": [
        "a seat for a Meeting",
        "a pitch at the table",
        "their city named as where they are"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_657",
    "$type": "Task",
    "assignee": "worker_3",
    "due": "2026-10-09T17:00:00Z",
    "on": "contact_93",
    "brief": {
      "who": "Rachel Kim, Summit Residential, 420 units, seated Oct 7",
      "said": "Could you send a Quote for all 6 owners?",
      "chose": "to-the-ae",
      "why": "a Quote is the AE’s",
      "never": [
        "what she said at the table, beyond her ask"
      ]
    }
  }
]
```

You and Priya answer with <Op verb="Task.claim" /> (Take this one), <Op verb="Task.return" /> with a reason, <Op verb="Approval.approve" /> or <Op verb="Approval.refuse" />, each a one-call window; an Approval unanswered by its deadline expires and the table is released. Once a person claims, the agent’s pending drafts to that guest cancel with `claimedByPerson` (Not live yet, gaps #7). A Task nobody claims by its due time goes up through <Op verb="Task.escalate" />, and `person-promise` fires.

**On time:** you, 18 of 18 notes sent within 48 h, median 20 h, n 18, ■■□□ Early sign; AE · Priya Shah, 1 of 1 within 1 business day. **Your queue:** counted by kind: per table, 1 approval, about 12 invitations, 1 go-or-cancel and 9 notes; about 1 hand-off to Priya per table.

**The fixed line:** <Op verb="Deal.assign" /> sets `owner` to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.

## When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
| --- | --- | --- | --- |
| <a id="check-owned-by-a-person"></a>`owned-by-a-person` (rule j; Not live yet, gaps #8) | an invitation to someone whose open Deal a person owns | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| `consent-stop` (gaps #3; the record’s Notes Consent) | a guest named to another guest, or quoted, without their tick or written OK | Ask once for their OK to the exact words. | <Op verb="Message.schedule" /> |
| <a id="check-claims-resolve"></a>`claims-resolve` (shared) | a sentence in an invitation or note that resolves to no record | Cut the claim, or name the record that backs it. | <Op verb="Content.draft" /> |
| <a id="check-engagement-gate"></a>`engagement-gate` (the record’s Engagement gate) | an invitation to someone with no engagement they announced in 90 days | Invite only who engaged; a visit never counts. | <Op verb="Prospect.list" /> |
| <a id="check-hospitality-cap"></a>`hospitality-cap` | a cover above the guest’s class cap, unless the pay-own-share seat is set | Set the pay-own-share seat for that guest. | <Op verb="Gathering.update" /> |
| <a id="check-clinician-hold"></a>`clinician-hold` | a clinician’s invitation before the Compliance Officer approves it | It waits for that approval. | <Op verb="Approval.approve" /> |
| <a id="check-no-conditional-seat"></a>`no-conditional-seat` | a seat, meal or gift tied to a Meeting, a demo or a purchase | Cut the condition; the seat is unconditional. | <Op verb="Content.draft" /> |
| <a id="check-no-cash-or-travel"></a>`no-cash-or-travel` | cash, a gift card, travel, lodging or a paid plus-one | Offer the seat only; a gift ships through gift delivery under its cap. | <Op verb="Approval.approve" /> |
| <a id="check-import-refusal"></a>`import-refusal` | a Contact list loaded into the Page or the Form | Invite them; each registers through the Form. | <Op verb="Form.update" /> |
| <a id="check-invitation-rest"></a>`invitation-rest` | a second invitation within 60 days, or any after 2 unanswered | Wait out the rest; the Brief names the date. | <Op verb="Task.next" /> |
| <a id="check-kitchen-notes"></a>`kitchen-notes` | kitchen notes kept past 7 days, or sent to any record | They are deleted on day 7. | <Op verb="Task.complete" /> |
| <a id="check-recording-off"></a>`recording-off` | a recording of a dinner, or of a session where any guest left the box unticked | Record nothing at a dinner; a session needs every tick. | <Op verb="Gathering.update" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-go-no-go"></a>`go-no-go` | under 4 guests outside the anchors at 10 days out | the table is cancelled and the deposit released |
| <a id="stop-seated-floor"></a>`seated-floor` | under 6 seated at 2 tables running | new tables pause until the Marketing Lead reviews the lists |
| <a id="stop-leading-floor"></a>`leading-floor` | 0 Meetings at day 14 from 2 tables running | the Play pauses for a Decision |
| <a id="stop-complaint"></a>`complaint` | 1 complaint that the table was a pitch, or 2 opt-outs from one batch | that city or niche pauses |
| <a id="stop-holdout-loser"></a>`holdout-loser` | the quarterly readout marks the tables a loser | new tables wait on a Decision |
| <a id="stop-spend-limit"></a>`spend-limit` | a charge above the table’s Limit, or month-to-date spend at the Play’s | an Approval; new bookings pause until the month turns |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every booking, invitation and note pauses; the cards freeze |

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

```json title="The captured refusal · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The invitation to an Austin operator did not go to your tray: no engagement they announced in 90 days; a pricing-page visit is not one.",
  "checks": [
    {
      "check": "engagement-gate",
      "status": "fail",
      "doc": "/plays/gatherings#check-engagement-gate",
      "fix": "Invite only who engaged; a visit never counts.",
      "then": "Prospect.list"
    },
    {
      "check": "hospitality-cap",
      "status": "pass"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "reason": {
      "limit": "spend-limit",
      "observed": "$940 charged",
      "bound": "$900 Limit",
      "window": "1 table"
    },
    "doc": "/plays/gatherings#stop-spend-limit",
    "task": "task_651"
  }
]
```

## Did it work
Two tables are two units, and neither has reached its day 90, so the basis is before-after (rule o): Now reads the Deals so far, Before reads no table, and nothing prints as Added. The hashed 15 % never invited reads each quarter, in Example, as what happened. Every node above the leaf is Not live yet (gaps #4).

`1.0 Deals per table so far against no table before · before-after, not proof · n 2 tables · path → arr`

| Node | Now (2 tables) | Before (no table) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `gathering-deal-rate` | 1.0 Deals per table so far (2 Deals: Austin 1, Denver 1) · both inside their 90 days | — | — | — | before-after, not proof · Other Startups’ results 1.6 per table at day 90, ■■□□ Early sign, n 540 tables |
| `opened-deals-and-trials` | 3 Deals and 1 trial at seated guests’ Organizations | — | — | — | before-after · still maturing |
| `new-arr` ↑ | $0 so far · Booked: $0, credited, not all caused by this Play | $0 | — · Worth about +$590 a month | — | before-after · 3 Deals and 1 trial still deciding |
| `net-new-arr` · `arr` | carried from `new-arr` | carried | — | — | carried |

The leaf counts Deals opened at seated guests’ Organizations per table, read 90 days after it; only tables past day 90 count (rule n), so Austin reads Dec 16 and Denver Jan 5.

**How it moves it:** each guest sat for two hours with peers and no pitch, then had your own note within a median 20 hours; 7 Meetings followed by day 14.

**Guardrails:** before against after: Meetings per 10 seated, 3.9 against Other Startups’ 4.2, and cost per seated guest, $68; 3 Deals and 1 trial are still deciding.

```json title="The Campaign card · sample"
{
  "$id": "https://api.sb/leaseline.app/campaigns/gatherings",
  "$type": "Campaign",
  "play": "play:gatherings@1",
  "path": [
    "gathering-deal-rate",
    "opened-deals-and-trials",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "gathering-deal-rate",
    "unit": "per-table",
    "heldBack": 6,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 2,
    "maturing": 2,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 1220,
    "workerCost": 2,
    "hours": 11.2,
    "openArr": 9600,
    "wonArr": 0,
    "projectedArr": 586,
    "paybackDays": null
  }
}
```

Outside benchmark: no measured range for founder-hosted table Deal rates survived the research’s check, so Other Startups’ results (n 540 tables) stand in.

**Before it · After it.** Before it: `events-and-webinars`, `founder-voice` and `field-presence` bring the people who engage. After it: `written-references` hears the guests who OK a case, and `lead-nurture` takes the ones with no next step.

## Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 2 tables, Austin on Sep 17 and Denver on Oct 7 inside `field-presence`; 23 invited, 18 seated, 6 Organizations held back. Read every captured thread at `?threads=all`; three follow the tables.

| What happened, by table | Invited · registered | Seated · anchors | Meetings by day 14 · Deals so far |
| --- | --- | --- | --- |
| Austin, Sep 17 (10 covers, $640) | 11 · 9 | 8 · 1 | 3 · 1 |
| Denver, Oct 7 (12 covers, $580 of the conference dinner) | 12 · 12 | 10 · 0 | 4 · 1 |
| Plan a table · Go or cancel · To the AE | 3 · 2 · 1 | 2 held, Phoenix awaiting you · both went · 1 Quote | — |
| **Invited Organizations** · held back (6) | **23 · 21** | **18 seated** | **7 · 2** · held back: 0 Deals so far |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_1840` Campaign.created | the three steps; the dry run fails `consent-stop` | 15 min |
| 0 | `event_1841` Form.updated | the share-my-name box goes on the Form | 5 min |
| 4 | `event_1844` Approval.approved | you approved Austin: 10 seats, $900 Limit, one question | 10 min |
| 14 | `event_1849` Decision.created | Austin at 10 days out: 5 guests outside the anchor, so it went | 2 min |
| 24 | `event_1852` Registration.attended | Austin: 8 seated, your notes sent within 48 h | 3 h at the table · 40 min of notes |
| 44 | `event_1860` Campaign.paused | `spend-limit`: Denver’s bill was $940 against $900; you approved the $40 | 2 min |
| 1–56 | `event_1846` Task.assigned, first of 41 | invitations and notes you sent, from the <Op verb="Task.next" /> log | 2 h 30 min · **total 11.2 h measured, 10 h asked** |

> **Dana → an Austin operator, Aug 28** · You asked under my Aug 25 post how owners see renewals.¹ I’m hosting 8 property managers for dinner in Austin on Sep 17, Leaseline’s table, Customers and prospects both, to ask one question: what does a missed renewal really cost?² No demo, and no catch.³
>
> **Operator, Aug 29** · registered; seated Sep 17; Meeting with Dana Sep 26, and a Deal opened Oct 2.

```diff title="An Austin invitation, 2026-08-28 · the draft engagement-gate refused, then the rewrite that reached your tray"
- I saw you checking out our pricing page, so I’d love to have you at dinner.
+ You asked under my Aug 25 post how owners see renewals, so I’d love to have you at dinner.
```

> **Rachel Kim, Denver table, 2026-10-08 09:10** · “Could you send a Quote for all 6 owners?” · The Brief went to Priya (`task_657`), due 17:00 on Oct 9; **Priya, Oct 8, 15:30** · *sent the Quote on the $2,400 plan, after Dana’s own note.*⁴

¹ The reason cites only an act they announced. ² The host and the Startup are named, and who attends. ³ No Offer and no condition on the seat. ⁴ A Quote is the AE’s.

## Your settings
```mdx title="plays/gatherings.mdx"
---
holdout: 0.15   # a hashed 15 % of engaged Organizations is never invited
---
Plan a 10-seat table when 8 or more companies in one city engage. Invite only who engaged; draft every invitation and note for Dana to send.
```

```text
$ npx startup-builder show plays/gatherings
holdout 0.15 · 10 seats · 8 engaged in a city · Dana sends every word     your file  plays/gatherings.mdx:2,4 (Ask 2026-08-24)
worker role:prospector, owns never · chooses 6 (4 rule, 2 read) · sequences gathering-invitation, gathering-registration, gathering-attendee-follow-up, gathering-no-show-follow-up · approval every-send, delay-window, first-send · checks owned-by-a-person, consent-stop, claims-resolve, engagement-gate + 8 · stops 7 · placements gmail, outlook, yahoo-mail, linkedin · folds into field-presence    catalog  play:gatherings@1 (Not live yet, gaps #5)
```

### Every key from the catalog
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-cluster-watch"></a>`cluster-watch` | Cluster watch finds 8 or more engaged Organizations in one metro area or narrow niche each week, from announced engagement only. Starts at Sends nothing. |
| Tactic | <a id="tactic-gathering-plan"></a>`gathering-plan` | Gathering plan turns a cluster into one format, question, date and restaurant and a ranked guest list under a Limit, for one founder approval. Starts at You approve each one. |
| Tactic | <a id="tactic-table-booking"></a>`table-booking` | Table booking creates the Gathering, issues a card bound to its Limit, books the room, and publishes an unlisted Page with one Form. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-gathering-invitations"></a>`gathering-invitations` | Gathering invitations sends the founder’s personal invitation to engaged people only, through the send gate and the hospitality check, with one nudge. Starts at You approve each one. |
| Tactic | <a id="tactic-guest-prep"></a>`guest-prep` | Guest prep confirms each place, decides go or no-go 10 days out, briefs the host one page per guest, and sends the founder’s reminder. Starts at You approve the first wave. |
| Tactic | <a id="tactic-table-night"></a>`table-night` | Table night has the founder host with no slides, while the agent pays within the Limit and turns the founder’s debrief into private notes. Starts at Sends nothing. |
| Tactic | <a id="tactic-gathering-follow-up"></a>`gathering-follow-up` | Gathering follow-up sends each seated guest the founder’s own note within 48 hours, then the recap, a slot for hot guests and the no-show note. Starts at You approve each one. |
| Tactic | <a id="tactic-table-notes-consent"></a>`table-notes-consent` | Table notes consent keeps debrief notes private, turns their themes into unattributed angles, and drafts a case only with a guest’s written Consent. Starts at You approve each one. |
| Tactic | <a id="tactic-gathering-readout"></a>`gathering-readout` | Gathering readout counts Meetings at 14 days and Deals at 90 days per Gathering, and prices invited clusters against a 15 percent holdout each quarter. Starts at Sends nothing. |
| Tactic | <a id="tactic-hospitality-check"></a>`hospitality-check` | Hospitality check sets each guest’s Customer class, compares the offer with its caps per occasion and per 12 months, and refuses conditional or cash value. Starts at Sends nothing. |
| Tactic | <a id="tactic-send-gate-check"></a>`send-gate-check` | Send gate check: Checks Suppression, a live reason, the Market, the basis stamp, the Person-month grant, the facts and the labels before any cold Message exists. Starts at Sends nothing. |
| Tactic | <a id="tactic-reply-matrix"></a>`reply-matrix` | Reply matrix: Labels every outreach reply with one of 11 labels, maps it to one of seven reply kinds, and runs that kind’s move by its deadline. Starts at You approve each one. |
| Tactic | <a id="tactic-founder-send-tray"></a>`founder-send-tray` | Founder send tray shows each approved draft with its source trail; the founder presses post by hand or through the Venue’s own posting path. Starts at You approve each one. |
| Tactic | <a id="tactic-claims-check"></a>`claims-check` | Claims check maps every draft sentence to an approved source or the Person’s own words, and holds anything else before it reaches anyone. Starts at Sends nothing. |
| Trigger | <a id="trigger-engagement-cluster"></a>`engagement-cluster` | Engagement cluster: `threshold` on `Prospect.engaged`, window 30d. |
| Trigger | <a id="trigger-segment-cluster"></a>`segment-cluster` | Niche cluster: `threshold` on `Prospect.engaged`, window 30d. |
| Trigger | <a id="trigger-founder-trip"></a>`founder-trip` | Founder trip: `at` on `Integration.synced`, window 30d. |
| Trigger | <a id="trigger-seat-requested"></a>`seat-requested` | Seat requested: `event` on `Gathering.registered`, window 7d. |
| Trigger | <a id="trigger-seat-taken"></a>`seat-taken` | Seat taken: `event` on `Gathering.registered`, window 21d. |
| Trigger | <a id="trigger-guest-seated"></a>`guest-seated` | Guest seated: `event` on `Registration.attended`, window 14d. |
| Trigger | <a id="trigger-guest-missed"></a>`guest-missed` | Guest missed: `state` on `Registration.missed`, window 14d. |
| Trigger | <a id="trigger-table-intent"></a>`table-intent` | Table intent: `event` on `Lead.qualified`, window 7d. |
| Trigger | <a id="trigger-case-candidate"></a>`case-candidate` | Case candidate: `event` on `Task.completed`, window 30d. |
| Trigger | <a id="trigger-gathering-deal-opened"></a>`gathering-deal-opened` | Gathering deal opened: `event` on `Lead.converted`, window 90d. |
| Sequence | <a id="sequence-gathering-invitation"></a>`gathering-invitation` | Gathering invitation: 2 steps; it ends on A Registration; A decline; A reply, taken by the reply matrix; An opt-out or Suppression; A Deal opens at the Organization. |
| Sequence | <a id="sequence-gathering-registration"></a>`gathering-registration` | Gathering registration: 4 steps; it ends on The guest cancels; The guest is seated; An opt-out or Suppression. |
| Sequence | <a id="sequence-gathering-attendee-follow-up"></a>`gathering-attendee-follow-up` | Gathering attendee follow-up: 4 steps; it ends on A reply; A booked Meeting; A Deal opens at the Organization; An opt-out or Suppression. |
| Sequence | <a id="sequence-gathering-no-show-follow-up"></a>`gathering-no-show-follow-up` | Gathering no-show follow-up: 2 steps; it ends on A reply; A Registration; An opt-out or Suppression. |