Owned community
Runs your own community room, where people moderate and a labeled agent answers only when asked, from your approved Pages.
- Channel
- Webinars and events
- Kind
- Owned audience
Be our Marketing Lead for a community: open a Discord room for property managers once 20 people I invite say yes. Priya and I moderate. Your agent answers only when someone asks it, from our pages, and any buying question gets a person within 4 hours. Show me what’s missing; don’t invite anyone.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"owned-community"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'owned-community' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"owned-community"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'owned-community' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "owned-community can’t start yet: 2 checks fail and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "fail",
"observed": "340 people a month to invite; 0 of 20 founding members yet",
"doc": "/plays/ owned-community#check-use-when",
"fix": "Send your 20 personal invites; the join Page opens at the 20th yes.",
"then": "Message.schedule"
},
…
Hand the latest question someone asked our community agent to the Marketing Lead agent and show me what it chose and why. Don’t post.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Channel.joined%22%2C%20%22Handle.mentioned%22%2C%20%22Conversation.escalated%22%2C%20%22Thread.created%22%2C%20%22Thread.resolved%22%2C%20%22Message.created%22%2C%20%22Message.flagged%22%2C%20%22Prospect.engaged%22%2C%20%22Customer.created%22%2C%20%22Consent.withdrawn%22)&limit=1" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"like":"event_1371"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22thread_58%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22thread_58%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Channel.joined", "Handle.mentioned", "Conversation.escalated", "Thread.created", "Thread.resolved", "Message.created", "Message.flagged", "Prospect.engaged", "Customer.created", "Consent.withdrawn")', limit: 1 }) // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` }) // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` }) // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
npx startup-builder do Event.list --json '{"where":"name in (\"Channel.joined\", \"Handle.mentioned\", \"Conversation.escalated\", \"Thread.created\", \"Thread.resolved\", \"Message.created\", \"Message.flagged\", \"Prospect.engaged\", \"Customer.created\", \"Consent.withdrawn\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1371"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"thread_58\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"thread_58\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Channel.joined\", \"Handle.mentioned\", \"Conversation.escalated\", \"Thread.created\", \"Thread.resolved\", \"Message.created\", \"Message.flagged\", \"Prospect.engaged\", \"Customer.created\", \"Consent.withdrawn\")', limit: 1 }) // { play } compiled to this Play’s Trigger Events\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` }) // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` }) // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
"mode": "try"
}
}application/json{
"decision": {
"$id": "https: //api.sb/ leaseline.app/ decisions/ decision_553",
"$type": "Decision",
"choice": "answer-from-pages",
"reason": "contact_14 asked the agent directly whether renewal notices send in Spanish; the Notices Page says English and Spanish since Sep 1",
"stakes": "low",
"options": [
"welcome",
"answer-from-pages",
"bring-in-a-person",
"buying-question",
"ask-a-member",
"publish-the-answer"
…
sample · 4 Not live yetPreviewOn PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim
action_2 is the agent’s answer in the thread, waiting for your approval: answers stay at You approve each one until 300 carry at most 3 marked wrong (64 so far).
+2.1 per 100 invited · ■□□□ Too early to tell · n 420 · path → arr
| Try another: the thread | Choice | Reason |
|---|---|---|
| #renewals: “@leaseline-agent, can renewal notices go out in Spanish?” | answer-from-pages | the Notices Page answers it |
| Rosa Lin joined from the newsletter invite | welcome | a new member: the welcome Sequence and her community yes |
| #general: “Is there a discount for 300 units if we switch this quarter?” | buying-question | a buying question: a person answers within 4 business hours |
| #ops: “How do you handle owners who never open the portal?”, 26 h with no reply | ask-a-member | unanswered at 24 h; 2 members listed owner portals as their interest |
| @leaseline-agent: “My card was charged twice” | bring-in-a-person | billing is never the agent’s to answer |
- 3 h week 1, then 2 h a week
- Your time
- Day 9: first member starts a trial
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Community joiners who become Leads → New Leads → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +1.5 Leads per 100 invited (Other Startups’ results; your own read is too early) × 300 invited a month × 0.25 Leads to paid × $347 Pro ARR ≈ +$390. Under First signal: Holding back 1 in 5 invites at 300 a month, about 20 weeks to tell a +1.5 lift; 90 days can tell only +3.4 or more.
sample · api.sb/
Start it this week
npx startup-builder add play owned-community # 1 · writes plays/owned-community.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":"owned-community"}'
# 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":"owned-community"}'
# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/owned-community \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":null}'
# off: the agent goes silent and invitations hold; the room stays open
curl -X PATCH https://api.sb/leaseline.app/campaigns/owned-community \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":"now"}' | Check | Fix | Then |
|---|---|---|
use-when fail · Not live yet, gaps #8 | Send your 20 personal invites; the join Page opens at the 20th yes. | POST /{namespace}/messages/{message}/schedule |
baseline pass · Not live yet, gaps #8 | Nothing to do: Before reads the same invite sources’ last 90 days. | POST /{namespace}/metrics/query |
approved-pages fail · Not live yet, gaps #8 | Approve the Pages the agent may answer from: pricing, notices, owners. | POST /{namespace}/sites/{site}/publish |
owned-by-a-person pass · Not live yet, gaps #8 | Nothing to do: their questions route to your queue. | POST /{namespace}/tasks/{task}/assign |
role-unstaffed warn · Not live yet, gaps #8 | Staff the AE, or leave it: buying questions come to you. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "owned-community can’t start yet: 2 checks fail and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "fail",
"observed": "340 people a month to invite; 0 of 20 founding members yet",
"doc": "/plays/owned-community#check-use-when",
"fix": "Send your 20 personal invites; the join Page opens at the 20th yes.",
"then": "Message.schedule"
},
{
"check": "baseline",
"status": "pass",
"observed": "4.8 Leads per 100 newsletter subscribers in 90 days, n 610",
"doc": "/plays/owned-community#check-baseline",
"fix": "Nothing to do: Before reads the same invite sources’ last 90 days.",
"then": "Metric.query"
},
{
"check": "approved-pages",
"status": "fail",
"observed": "no Pages approved for the agent’s answers",
"doc": "/plays/owned-community#check-approved-pages",
"fix": "Approve the Pages the agent may answer from: pricing, notices, owners.",
"then": "Site.publish"
},
{
"check": "owned-by-a-person",
"status": "pass",
"observed": "31 open Leads have a person owner, you",
"doc": "/plays/owned-community#check-owned-by-a-person",
"fix": "Nothing to do: their questions route to your queue.",
"then": "Task.assign"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"marketing-lead",
"sales-lead"
],
"owned": 31,
"doc": "/plays/owned-community#check-role-unstaffed",
"fix": "Staff the AE, or leave it: buying questions come to you.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · fail: 0 of 20 founding members (gaps #8) | POST /{namespace}/messages/{message}/schedule your 20 personal invites, from your own Mailbox | 30 min | 20 yeses; Leaseline’s took 6 days |
baseline · pass: 4.8 per 100, n 610 | POST /{namespace}/metrics/query on community-member-leads, which fills Before in Your number | 1 min | none |
approved-pages · fail (Not live yet) | POST /{namespace}/sites/{site}/publish the 3 Pages the agent may answer from | 15 min | none |
owned-by-a-person · pass: 31 owned by you | nothing; it runs again on every answer | 0 min | none |
role-unstaffed · warn (gaps #8): 31 of your open Leads have a person owner, you | POST /{namespace}/roles/{role}/staff, or leave it: buying questions and person asks come to you | 0 min | none |
Your number · Before 1.2 per 100 · Now 3.3 per 100 invited · Target 3 by Dec 31 · ■□□□ Too early to tell · n 420 matured · Other Startups +1.5,
Each agent answer costs about $0.01 and each welcome about $0.01 (Worker cost). The Discord server, the join Page and the Q&A Pages cost nothing; your time and Priya’s moderating are the real cost. That comes to about $2 a month at 120 answers.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| A member asks the agent directly | concierge-summoned | event on Handle.mentioned where handle.agent = true | answered within 60 s; a tag waits 15 min for a person first | POST /{namespace}/handles/{handle}/connect with venue discord |
| Someone joins the room from the join Page | member-joined | event on Channel.joined where room = 'leaseline-operators' | 7d of welcome | the join Page posts to POST /{namespace}/consents |
| A member asks about buying, pricing or a call | buying-question | event on Message.created where intent = 'buying' | a person within 4 business hours | the same Discord connection |
+ 7 more: a person asked for, an unanswered question at 24 h, a resolved thread, a moderator flag, a cluster of members, a member who became a Customer, and a withdrawn yes (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_1371" ,
"$type": "Event",
"name": "Handle.mentioned",
"at": "2026-10-19T15:31:40Z" ,
"seq": 1371,
"data": {
"handle": "leaseline-agent",
"room": "leaseline-operators",
"thread": {
"$id": "https://api.sb/leaseline.app/threads/thread_58" ,
"channel": "#renewals"
},
"member": "contact_14",
"text": "Can renewal notices go out in Spanish?"
}
}# 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":"Handle.mentioned","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Handle.mentioned --like event_1371 # replays the delivery in test
npx startup-builder clock advance --by 72h # asks a member who knows if the thread is still unresolvedWho runs it
Marketing Lead · your agent (role:, worker_6) holds the Key Result and answers from the labeled leaseline-agent profile, the only agent in the room. People moderate: you (Dana Okafor, person, worker_1) and AE · Priya Shah (person) (worker_3, staffed on day 9). Buying questions go to Priya; asks for a person, billing, refunds, security and outages come to you. Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Answer from your Pages | You approve each one | 64 posted, 2 marked wrong | at 300 answers with at most 3 marked wrong (64 so far) | 2 marked wrong in 7 days (wrong-answer) → You see each one first | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Welcome the member · Ask a member who knows | It does it, you can stop it | 96 of 96 · 11 of 11 | met on day 14 (the first 20 approved unedited) | 3 complaints about the agent in 14 days (bot-complaint) → You approve each one | POST /{namespace}/actions/{action}/cancel inside the 15-minute hold |
| Publish the answer as a Page | You approve each one | 5 of 5 | never: a member’s words need their yes and yours | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Bring in a person · A person answers the buying question | A person, every time | 9 of 9 · 7 of 7 | never | — | POST /{namespace}/tasks/{task}/claim · POST /{namespace}/tasks/{task}/return |
| Change a room rule | You approve each one | 1 merged of 1 | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: a seeded thread, a second staff profile, an Offer that needs a post or a review | Refused, every time | 0 drafted | never | — | none: the Check holds it |
What it reads · What it may call. It reads the thread it was asked in, the approved Pages and the member’s stated interests. It never refers to what a member did outside the room, and only a person removes, mutes or bans, under a published room rule. Its tools are POST /{namespace}/consents, POST /{namespace}/conversations/{conversation}/answer, POST /{namespace}/conversations/{conversation}/escalate, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/leads, POST /{namespace}/messages/{message}/schedule, POST /{namespace}/pages, and any other call becomes an Approval under the Role’s Mandate.
You hold the Marketing Lead Key Result: 3 Leads per 100 invited by 2026-12-31. ← worker, metric
On each room Event, choose one option and say why. ← triggers, chooses
Answer only when asked, from approved Pages, and link the Page. ← copyRules 1, 3
Your name and bio say you are an agent; never claim to be a person. ← copyRules 2
Billing, refunds, security and outages go to a person. ← chooses.bring-in-a-person.when
Every buying question gets a person within 4 business hours. ← chooses.buying-question, your file line 7 The slow loop, as a Change. decision_389 (2026-09-28, weekly) read 7 questions answered by the agent first with 1 member reply after, and 6 answered by a member first with 5. change_31 made a tag wait 15 minutes for a person or member before the agent answers (your file, line 6), and Dana merged it with POST /{namespace}/changes/{change}/merge. Replayed on past threads, POST /{namespace}/changes/{change}/review put member replies at 71 per 100 threads; read back at +14d it is 64, n 14, ■□□□ Too early to tell (Example, day 49).
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; POST /{namespace}/roles/{role}/staff seats it.
npx startup-builder eval --scenario owned-community-64 --agent "claude -p" --seat marketing-lead # seated: 62 of 64 marked right, 0 Checks failed sent, $0.01 an answer · yours: 59 → You approve each one What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Welcome the member welcome | someone joins from the join Page | Your rule (line 5) | member-welcome: the join email, one message with two matching threads, one digest ask → POST /{namespace}/consents | nobody | the same |
Answer from your Pages answer-from-pages | a member asks the agent a question the approved Pages answer | Agent’s call, with its reason | POST /{namespace}/conversations/{conversation}/answer, labeled, linking the Page | you approve it · Take this one | you |
Bring in a person bring-in-a-person | a person asked for, or billing, refunds, security or an outage | Your rule (line 8) | POST /{namespace}/conversations/{conversation}/escalate → POST /{namespace}/tasks/{task}/assign, with the true wait posted | you, within 4 business hours · Take this one | you |
A person answers the buying question buying-question | a member asks about buying, pricing or a call | Your rule (line 7) | POST /{namespace}/leads → POST /{namespace}/tasks/{task}/assign; one members-only Offer may show | AE · Priya Shah, within 4 business hours · Take this one | you |
Ask a member who knows ask-a-member | unanswered at 24 h, and a member’s stated interest fits | Agent’s call, with its reason | POST /{namespace}/messages/{message}/schedule, at most once a month for each member | nobody | the same |
Publish the answer as a Page publish-the-answer | a thread resolved, and its asker and quoted members said yes | Agent’s call, with its reason | qa-page-consent → POST /{namespace}/pages with only the granted words | you approve it · Take this one | you |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “This is great. How do I try it on our portfolio?” | the trial link, and a person’s offer of a setup call | AE · Priya Shah (person) | 4 business hours | POST /{namespace}/leads |
| Send me pricing | “What’s the price for 300 units?” | the Pricing Page’s list Price; over 120 units, a person follows up | Marketing Lead · your agent, then AE · Priya Shah | 4 business hours | POST /{namespace}/conversations/{conversation}/escalate |
| Not now | “Just here to learn for now.” | nothing follows; the digest keeps arriving if they asked for it | nobody | — | GET /{namespace}/decisions |
| Wrong person | “My colleague Sam would want this thread.” | it suggests they share the join Page; it never invites a name from their text | Marketing Lead · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply to the welcome email | the welcome waits; nothing else sends | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Is my tenants’ data stored in the US?” | security is a person’s: the question goes in the Brief, and the wait is posted | you (Dana Okafor, person) | 4 business hours | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Stop messaging me.” | no more messages or digests; their words come off every Q&A Page within 24 h | nobody | at once | POST /{namespace}/consents/{consent}/withdraw |
When it hands to you
Buying questions go to AE · Priya Shah (person); asks for a person, billing, refunds, security and outages come to you, and before day 9 every hand-off did. One Brief per Role, as captured (brief is Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_463" ,
"$type": "Task",
"assignee": "worker_3",
"due": "2026-10-14T19:10:00Z" ,
"on": "lead_47",
"brief": {
"who": "Owen Hale, Larkfield Communities (640 units), member since Sep 23" ,
"said": "Is there a discount for 300 units if we switch this quarter?" ,
"chose": "buying-question",
"why": "a buying question is a person’s",
"never": [
"a discount the agent offers",
"what he did outside the room"
]
}
},
{
"$id": "https://api.sb/leaseline.app/tasks/task_447" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-07T18:00:00Z" ,
"on": "thread_49",
"brief": {
"who": "a member in #general",
"said": "My card was charged twice",
"chose": "bring-in-a-person",
"why": "billing is never the agent’s",
"posted": "Dana replies here by 14:00 Central"
}
}
]Each receiver answers with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{action}/redirect, each a one-call window. Once a person claims a thread, the agent posts nothing more in it (claimedByPerson, Not live yet, gaps #7). A Task nobody claims by its due time goes up a Role through POST /{namespace}/tasks/{task}/escalate, and three late hand-offs in 7 days pause new invitations (handoff-breach).
On time: AE · Priya Shah, 7 of 7 buying questions answered within 4 business hours, median 1 h 20 min, n 7; you, 9 of 9, median 55 min, n 9, ■□□□ Too early to tell beside Other Startups’ 92 % on time. Your queue: counted by kind: in week 1, 20 personal invites and 12 answer approvals; now about 10 answer approvals, 2 hand-offs and 1 flag a week.
The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.
When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
|---|---|---|---|
owned-by-a-person (rule j; Not live yet, gaps #8) | an agent message to a member whose Lead or open Deal a person owns, or whose thread a person claimed | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
approved-pages (Not live yet) | an agent answer with a sentence no approved Page backs | Cut the sentence, or publish the Page that says it. | POST /{namespace}/sites/{site}/publish |
join-raid (the record’s Join-raid hold) | new invitations after 20 joins in 10 minutes from new profiles | Have a moderator review the joins, then release the hold. | POST /{namespace}/tasks/{task}/claim |
consent-withdrawn (the record’s Consent withdrawal) | a Q&A Page that quotes a member who withdrew their yes | Take their words off the Page within 24 hours; no approval is needed. | PATCH /{namespace}/pages/{id} |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that posted is the #integrations thread in Example.
| Check | Fix | Then |
|---|---|---|
approved-pages fail · Not live yet, gaps #8 | Cut the sentence, or publish the Page that says it. | POST /{namespace}/sites/{site}/publish |
owned-by-a-person pass · Not live yet, gaps #8 | — | POST /{namespace}/tasks/{task}/assign |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The agent’s answer in #integrations did not post: one sentence no approved Page backs.",
"checks": [
{
"check": "approved-pages",
"status": "fail",
"doc": "/plays/owned-community#check-approved-pages",
"fix": "Cut the sentence, or publish the Page that says it.",
"then": "Site.publish"
},
{
"check": "owned-by-a-person",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "moderator-absence",
"observed": "a flag waiting 49 h",
"bound": "48 h",
"window": "1 flag, Oct 3 to Oct 5"
},
"doc": "/plays/owned-community#stop-moderator-absence" ,
"task": "task_452"
}
]Did it work
1 in 5 of each invite source is held back at random and gets no invitation; both halves are read from that assignment, per 100 invited, joined or not (rules m–o). Each figure’s call is POST /{namespace}/metrics/query by node and by arm; the parent field and every node above the leaf are Not live yet (gaps #4).
+2.1 per 100 invited · ■□□□ Too early to tell · n 420 · path → arr
- Chose
- answer-from-pages
- Why
- contact_14 asked the agent directly whether renewal notices send in Spanish; the Notices Page says English and Spanish since Sep 1
- From
- welcome · answer-from-pages · bring-in-a-person · buying-question · ask-a-member · publish-the-answer
- Expects
- the asker marks the answer accepted within 72h
- Reopens when
- no Thread.resolved on thread_58 within 72h: it asks a member who knows
- By
- worker_6
JSON
{
"$id": "decisions/decision_553",
"$type": "Decision",
"choice": "answer-from-pages",
"reason": "contact_14 asked the agent directly whether renewal notices send in Spanish; the Notices Page says English and Spanish since Sep 1",
"stakes": "low",
"options": [
"welcome",
"answer-from-pages",
"bring-in-a-person",
"buying-question",
"ask-a-member",
"publish-the-answer"
],
"by": "worker_6",
"on": "thread_58",
"expected": "the asker marks the answer accepted within 72h",
"reopensWhen": "no Thread.resolved on thread_58 within 72h: it asks a member who knows"
}| Node | Invited (agent half) | Held back | Added | Confidence | Basis |
|---|---|---|---|---|---|
community-member-leads | 3.3 per 100 invited (11 of 336) · 16.4 per 100 joiners (11 of 67) | 1.2 (1 of 84) | +2.1 [−1.1, +5.3] | ■□□□ Too early to tell | held back at random, 1 in 5 · n 420 · 180 still maturing · Other Startups +1.5, ■■■□ Likely, n 22 Startups |
new-leads | 6.0 per 100 invited (20 of 336), from any source | 4.8 (4 of 84) | +1.2 [−3.9, +6.3] | ■□□□ Too early to tell | the same assignment |
new-arr ↑ | $1,388, 4 Customers: $413 per 100 invited · Booked: credited, not all caused by this Play | $347, 1 Customer: $413 per 100 | +$0 per 100 invited [−$720, +$720] · Not carrying up yet | ■□□□ Too early to tell (4 vs 1 Customers) | the same · 6 trials still deciding |
net-new-arr · arr | +$1,388 | +$347 | carried: +$0 per 100 invited | ■□□□ Too early to tell | carried from new-arr |
The leaf counts invited People who were not Customers and who start a trial or reach the activation Event within 30 days of the invitation, per 100 invited (rule m, intent to treat), to 300 matured in each half; at 336 and 84 the held-back half runs on.
How it moves it: a joiner’s question got a person or member reply in a median 3 h 40 min, and every buying question a person within 4 business hours (community-member-leads by first-reply time).
Guardrails: treated against held back: trials to paid, 4 of 11 against 1 of 1, and the newsletter’s unsubscribes after an invite, 0.4 % against 0.3 %.
{
"$id": "https://api.sb/leaseline.app/campaigns/owned-community" ,
"$type": "Campaign",
"play": "play:owned-community@1" ,
"path": [
"community-member-leads",
"new-leads",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "community-member-leads",
"unit": "per-100",
"heldBack": 84,
"decision": null
},
"readout": {
"value": 2.1,
"n": 420,
"maturing": 180,
"interval": [
-1.1,
5.3
],
"readability": "inadmissible",
"basis": "held-back",
"pooled": false
},
"ledger": {
"spend": 0,
"workerCost": 2,
"hours": 14.5,
"pipelineArr": 2400,
"wonArr": 1388,
"projectedArr": 390,
"paybackDays": 30
}
}Outside benchmark: the catalog holds none for this Play yet, so Other Startups’ results stand in: +1.5 Leads per 100 invited, ■■■□ Likely, n 22 Startups.
Before it · After it. Before it: owned-newsletter, community-answers, product-led and events-and-webinars send it the people it invites. After it: a cluster of 8 members in one city goes to gatherings, buying questions reach instant-response’s AE hand-off, and Q&A Pages feed aeo and editorial-seo.
Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days); the room opened on day 6 at the 20th founding yes. 600 people were assigned at random, 480 invited and 120 held back; 420 have matured. 96 joined, and the agent answered 64 asks. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Done | Won (credited, not all caused by this Play) |
|---|---|---|---|
| Welcome the member | 96 | 96 welcomed, 71 asked for the digest | — |
| Answer from your Pages | 64 | 58 accepted, 2 marked wrong | 1 asker on Pro (+$347 ARR) |
| A person answers the buying question | 7 | 7 within 4 business hours, 3 trials | 2 on Pro (+$694 ARR), 1 Deal open on the $2,400 plan |
| Bring in a person · Ask a member who knows · Publish the answer as a Page | 9 · 11 · 5 | 9 · 8 answered by members · 5 Pages | 1 on Pro (+$347 ARR) · 0 · 0 |
| At 300 invited a month (the Use it when volume) | about 560 in 56 days | held back 1 in 5: Too early to tell at 90 days | Other Startups’ results: +1.5 per 100, ■■■□ Likely, n 22 Startups |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_118 Campaign.created | the three steps; the dry run fails use-when (0 of 20 founding members) and approved-pages | 45 min |
| 0–6 | event_120 Message.scheduled, first of 20 | your 20 personal invites; the 20th yes came on day 6 and the join Page opened | 1 h 10 min |
| 9 | event_301 Role.staffed | AE · Priya Shah (person) takes role: and moderates | — |
| 9 | event_305 Offer.trialed | the first member starts a trial, after a person answered her buying question | — |
| 14 | event_388 Role.updated | welcomes and member asks promoted; answers stay with you | — |
| 35 · 49 | event_655 Change.merged · event_802 Readout.created | a tag waits 15 min for a person or member: replayed at 71 member replies per 100 threads, read back at 64 | 5 min |
| 41 | event_702 Campaign.paused | moderator-absence: a flag waited 49 h; invitations resumed once you reviewed it | 10 min |
| 6–56 | event_140 Approval.created, first of 69 | you approved 64 answers and 5 Pages, and moderated with Priya; weekly reviews, from the POST /{namespace}/tasks/next log | 12 h 30 min · total 14.5 h measured, 14 h asked |
contact_14 in #renewals, Oct 19, 15:31 · “@leaseline-agent, can renewal notices go out in Spanish?”
leaseline-agent (agent), 15:32 · Yes: renewal notices send in English and Spanish, chosen per tenant (Notices Page, updated Sep 1).¹ You set it on each lease’s language field. Want a person to show you? Ask and Dana or Priya replies.² *From the Notices Page · I’m Leaseline’s agent.*³
contact_14, 15:58 · marked the answer accepted. She started a trial on Oct 20.
- Yes, Leaseline integrates with every accounting system.
+ The Integrations Page lists one accounting export today, a monthly CSV of owner statements. For anything else, ask and a person replies. Owen Hale in #general, 2026-10-14 15:10 · “Is there a discount for 300 units if we switch this quarter?” · leaseline-agent (agent), 15:11 · *Priya, our account lead, answers pricing here by 19:10 today.*⁴ The Brief went to Priya (
task_463); she claimed it at 15:40 and replied in the thread at 16:25, then booked a call.
¹ Every sentence maps to an approved Page, and the answer links it. ² A person is always offered. ³ The fixed label line, compiled from the Role’s Settings. ⁴ The routed line, compiled from the Role’s Settings.
Your settings
---
holdout: 0.2 # 1 in 5 of each invite source gets no invitation
room: leaseline-operators
---
Welcome every member with two threads that match their interest.
A tag waits 15 minutes for a person or member before the agent answers.
Every buying question gets Priya within 4 business hours.
Billing, refunds, security and outages come to me. $ npx startup-builder show plays/owned-community
holdout 0.2 · room leaseline-operators · 15-minute wait on a tag · buying questions to the AE · billing to you your file plays/owned-community.mdx:2,3,5,6,7,8 (Ask 2026-08-24; line 6 by change_31, 2026-09-28)
family owned-audience · worker role:marketing-lead, owns never · chooses 6 (3 rule, 3 read) · sequences member-welcome, qa-page-consent · approval every-send · checks owned-by-a-person, approved-pages, join-raid, consent-withdrawn · stops 10 · placements discord server and thread replies catalog play:owned-community@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record owned-community and its Leaseline run, then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.