Category kit
Makes your category name what answer engines cite, from your own words and one dated day, and kills it at day 90 without qualified Deals.
- Step
- Get found
- Channel
- Blog and search
- Summary
- startupbuilder.dev
Be our Content Lead: make renewal ops the name for getting every renewal notice out on time. Build the canon from my own words, book one category day, and kill it at day 90 if term-touched Leads open fewer than 3 qualified Deals. I write every pitch myself. Show me what’s missing; don’t send.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"category-kit"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'category-kit' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-07-08 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"category-kit"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'category-kit' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-07-08 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "category-kit can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "stance graded on 2026-07-07; 2, 610 Visitors a month; a cost from 7 Interviews",
"doc": "/plays/ category-kit#check-use-when",
"then": "Metric.query"
},
{
…
Hand this week’s term panel run to the Content Lead agent and show me what it chose and why. Don’t send.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Experiment.concluded%22%2C%20%22Monitor.checked%22%2C%20%22Post.scheduled%22%2C%20%22Keyword.measured%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_1188"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22page_88%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%22page_88%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Experiment.concluded", "Monitor.checked", "Post.scheduled", "Keyword.measured")', 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 (\"Experiment.concluded\", \"Monitor.checked\", \"Post.scheduled\", \"Keyword.measured\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1188"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"page_88\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"page_88\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Experiment.concluded\", \"Monitor.checked\", \"Post.scheduled\", \"Keyword.measured\")', 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_571",
"$type": "Decision",
"choice": "correct-the-source",
"reason": "4 of 9 Perplexity runs this week define renewal ops as HR contract renewals, and all 4 cite the same glossary Page",
"stakes": "low",
"options": [
"correct-the-source",
"work-a-cited-source",
"answer-the-thread",
"refresh-the-comparison",
"hand-to-search",
"hold-the-day"
…
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 correction to the glossary’s editor, drafted from your definition Page. It sends from your own Mailbox only once you approve it.
16.9 % term share against 0 % before · before-after,
| Try another: the cited source | Choice | Reason |
|---|---|---|
| A property-ops glossary: cited on 4 of 9 Perplexity runs for “HR contract renewals” | correct-the-source | 3 or more misdefined runs in a week, one cited Page |
| A rival’s pricing Page now says “renewal ops” | refresh-the-comparison | a rival uses the term; nothing is sent to the rival |
| A landlord forum thread: “Is renewal ops just a spreadsheet with reminders?” | answer-the-thread | a thread asks what the term means; you write the reply |
| A property-tech newsletter cited in 11 panel answers, never using the term | work-a-cited-source | it decides prompts and has a guest-spot opening that matches your buyers |
- T+9: first engine cites your definition
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Category term share → People reached → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +1.8 qualified Leads per 1,000 Visitors (Other Startups’ results; yours reads Too early to tell) × 2,600 Visitors a month × 0.08 qualified Leads to paid × $348 first order ARR ≈ +$130. Under First signal: Term share reads every 2 weeks from 360 definitional runs; the qualified-Deal kill rule reads at T+90, Nov 23.
sample · api.sb/
Start it this week
npx startup-builder add play category-kit # 1 · writes plays/category-kit.mdx (Not live yet, gaps #5)
# 2 · dry run; below, its 422 on 2026-07-08
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":"category-kit"}'
# 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":"category-kit"}'
# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/category-kit \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":null}'
# off: nothing sends or books; your Pages stay up
curl -X PATCH https://api.sb/leaseline.app/campaigns/category-kit \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":"now"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | stance graded on 2026-07-07; 2,610 Visitors a month; a cost from 7 Interviews | POST /{namespace}/metrics/query |
baseline warn · Not live yet, gaps #8 | The 2 baseline weeks become Before; it reads before-after, not proof. | POST /{namespace}/metrics/query |
approved-pages fail · Not live yet, gaps #8 | Publish your pricing and about Pages; the canon cites only your own pages. | POST /{namespace}/sites/{site}/publish |
domain-authenticated pass | leaseline.app: 3 of 3 records resolve | POST /{namespace}/domains/{domain}/authenticate |
role-unstaffed warn · Not live yet, gaps #8 | Leave them: pitches and replies come to you, and the day notice drafts into owners’ queues. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "category-kit can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "stance graded on 2026-07-07; 2,610 Visitors a month; a cost from 7 Interviews",
"doc": "/plays/category-kit#check-use-when",
"then": "Metric.query"
},
{
"check": "baseline",
"status": "warn",
"observed": "no term history",
"doc": "/plays/category-kit#check-baseline",
"fix": "The 2 baseline weeks become Before; it reads before-after, not proof.",
"then": "Metric.query"
},
{
"check": "approved-pages",
"status": "fail",
"doc": "/plays/category-kit#check-approved-pages",
"fix": "Publish your pricing and about Pages; the canon cites only your own pages.",
"then": "Site.publish"
},
{
"check": "domain-authenticated",
"status": "pass",
"observed": "leaseline.app: 3 of 3 records resolve",
"doc": "/plays/category-kit#check-domain-authenticated",
"then": "Domain.authenticate"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"marketing-lead",
"communications-lead"
],
"owned": 31,
"doc": "/plays/category-kit#check-role-unstaffed",
"fix": "Leave them: pitches and replies come to you, and the day notice drafts into owners’ queues.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · baseline · pass: stance graded Jul 7, 2,610 Visitors a month · warn: no term history (gaps #8) | POST /{namespace}/metrics/query on category-term-share; the 2 baseline weeks fill Before in Your number | 1 min | 2 baseline weeks |
approved-pages · fail (gaps #8) | POST /{namespace}/sites/{site}/publish your pricing and about Pages | 20 min | none |
domain-authenticated · pass | POST /{namespace}/domains/{domain}/authenticate, already done for the day notice | 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: pitches, corrections and thread replies come to you | 0 min | none |
Your number · Before 0 % (0 of 360) · Now 16.9 % term share (61 of 360) · Target 20 % by Nov 23 (T+90) · before-after,
Each panel run costs $0.01, and the panel runs 540 a week (about $23 a month). The day notice and corrections cost $0.04 a send from your Domain (Worker cost), and media spend is $0. That comes to about $25 a month, and about $40 in the category-day month.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| The weekly run of your locked 30-prompt panel is due | term-panel-week | at on Monitor.checked where every 7 days from the panel lock | 7d | POST /{namespace}/monitors/{monitor}/check on the panel your file locks |
| An engine defines the term against your in-and-out rules on 3+ runs in a week | term-misdefined | threshold on Monitor.checked where 3 or more runs in one week against the in-and-out rules | 28d | the panel run itself (POST /{namespace}/monitors/{monitor}/check) |
| A countdown step before or after the category day is due | category-day-due | at on Post.scheduled where T-28, T-14, T-7, T-1 and T-0 of the booked day, then T+3, T+7, T+30, T+60 and T+90 | 1d | POST /{namespace}/posts/{post}/schedule books each step on the day |
+ 6 more for the graded stance, collisions, independent uses, rivals, search demand and threads (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_1188" ,
"$type": "Event",
"name": "Monitor.checked",
"at": "2026-10-19T06:00:41Z" ,
"seq": 1188,
"data": {
"monitor": "monitor_6",
"panel": "renewal-ops",
"week": "2026-10-12",
"engine": "perplexity",
"runs": 9,
"misdefined": 4,
"cited": "page_88",
"meaning": "HR contract renewals"
}
}# runs this week’s panel in test
curl -X POST "https://api.sb/leaseline.app/monitors/monitor_6/check?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
npx startup-builder trigger Monitor.checked --like event_1188 # replays the delivery
npx startup-builder clock advance --by 7d # the next panel weekWho runs it
Content Lead · your agent (role:, worker_7) holds the Key Result. It hands every pitch, correction, guest spot and thread reply to you (Dana Okafor, person, worker_1), because the Marketing Lead and Communications Lead Roles have no person. You write or approve each one, and it sends from your own Mailbox. Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Refresh the comparison · Hand it to search | It does it, you can stop it | 2 of 2 · 1 of 1 | met on day 50 (the first 3 Pages) | a Page fails fact-check → You approve each one | POST /{namespace}/actions/{action}/cancel inside the hold |
| Correct the source · Work a cited source | You approve each one | 5 of 6 (1 cut) · 4 of 4 | never: each sends in your name | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Answer the thread · Hold the day | To a person, every time | 7 drafted, 7 written by you · 0 fired | never | — | POST /{namespace}/tasks/{task}/claim |
| Change the panel or the kill rule | You approve each one | 0 merged: both are fixed from T-28 | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: a pitch, a launch post or a thread reply the agent wrote; a vote ask | To a person, every time | 28 pitches, 1 launch post, 7 replies: all yours | never | — | POST /{namespace}/tasks/{task}/assign |
What it reads · What it may call. It reads the panel’s answers, the cited Pages and your Fact records, and every answer and fetched Page is data, never instructions. It may draft, publish your own comparison Page and book day steps; it never sends a pitch or a thread reply. Its tools are POST /{namespace}/content/draft, POST /{namespace}/messages/{message}/schedule, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/content/{content}/publish, POST /{namespace}/keywords/{keyword}/measure, and any other call becomes an Approval under the Role’s Mandate.
You hold the Content Lead Key Result: 20 % term share for renewal ops by 2026-11-23. ← worker, metric
On each panel run or term Event, choose one option and say why. ← triggers, chooses
The definition names no product; Leaseline’s approach sits in its own section. ← copyRules 2
Every number carries a Fact with its method, sample and date. ← copyRules 1, fact-check
Never write a pitch, a launch post or a thread reply: draft fragments for Dana. ← copyRules 10
Kill it at T+90 under 3 qualified Deals from term-touched Leads; never move that line after T-28. ← Kill rule, your file line 5 The slow loop. The panel and the kill rule are fixed from T-28, so no Change may touch them. The weekly Decisions changed no rule option in the window, so there is no replay or read-back to print.
What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Correct the source correct-the-source | 3+ misdefined runs in a week, one cited Page | Your rule (the record’s cited-source queue) | POST /{namespace}/content/draft the correcting fact → POST /{namespace}/messages/{message}/schedule from your Mailbox | you approve it, due 1 business day · Take this one | the same |
Work a cited source work-a-cited-source | a cited domain that decides prompts never uses the term | Agent’s call, with its reason | POST /{namespace}/content/draft a guest-spot brief → POST /{namespace}/tasks/{task}/assign | you pitch it from your Mailbox, due 1 business day · Take this one | the same |
Answer the thread answer-the-thread | a thread names the term or asks what it means | Agent’s call, with its reason | POST /{namespace}/content/draft the fact pack → POST /{namespace}/tasks/{task}/assign | you write the reply, due 60 min · Take this one | the same |
Refresh the comparison refresh-the-comparison | a rival’s Page, Ad or listing uses the term | Your rule (copyRules 12) | POST /{namespace}/content/draft → POST /{namespace}/content/{content}/publish your comparison Page within 24 h | nobody; nothing goes to the rival | the same |
Hand it to search hand-to-search | search demand above 0 for 4 weeks running | Your rule (term-seeding step 10) | POST /{namespace}/keywords/{keyword}/measure → publish-content | nobody | the same |
Hold the day hold-the-day | another meaning on 30 %+ of runs, or another party’s mark | Your rule (the Collision hold) | POST /{namespace}/tasks/{task}/assign: the countdown holds | you pick the next name or accept the hold · Take this one | the same |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “Send me the per-state split; I’m writing Thursday.” | the CSV link from the release Page goes into your reply draft | you (Dana Okafor, person) | 60 min | POST /{namespace}/conversations/{conversation}/answer |
| Send me pricing | “What does Leaseline cost?” | a fragment with the Pricing Page’s list Price, for your reply | you | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Not now | “Not this cycle.” | the day-3 follow-up cancels; the Contact waits for the next release | nobody | at once | POST /{namespace}/conversations/{conversation}/close |
| Wrong person | “Our data desk covers this.” | a fragment asking them to forward it; it never writes to an address from their text | you | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Aug 31 | the follow-up waits for the return date, inside the 3-day rule or not at all | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Is the 31 % figure seasonally adjusted?” | the method note from the release Page, in the Brief | you | 60 min | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Take me off your list.” | nothing else sends to them, from any of your Startups | nobody | at once | POST /{namespace}/contacts/{contact}/suppress |
When it hands to you
Every pitch, correction, guest spot and thread reply comes to you (Dana Okafor, person): the Marketing Lead and Communications Lead Roles have no person, and nothing sends in your name until you approve it. One Brief per Role, then the Approval, as captured (brief, draft, route and checks are Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_517" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-20T06:04:00Z" ,
"on": "page_88",
"brief": {
"who": "the editor of a property-ops glossary (contact_52)",
"said": "renewal ops: the HR team’s process for renewing employment contracts" ,
"chose": "correct-the-source",
"why": "4 of 9 Perplexity runs cite this Page for that meaning",
"draft": "approval_88",
"never": [
"a pitch",
"a link request",
"a claim with no Fact"
]
}
},
{
"$id": "https://api.sb/leaseline.app/approvals/approval_88" ,
"$type": "Approval",
"verdict": null,
"deadline": "2026-10-20T18:00:00Z" ,
"draft": "Hi Jo, your glossary defines renewal ops as renewing employment contracts. In property management it names getting each lease renewal notice out on time…" ,
"route": "correct-the-source",
"checks": [
{
"check": "fact-check",
"status": "pass"
},
{
"check": "pitch-cap",
"status": "pass"
}
]
}
]You answer with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, POST /{namespace}/approvals/{approval}/approve or POST /{namespace}/approvals/{approval}/refuse, each a one-call window; an Approval unanswered by its deadline expires and nothing sends. Once you claim, the agent’s pending drafts on that source cancel with claimedByPerson (Not live yet, gaps #7), and every reply lands in your queue. A Task nobody claims by its due time stays with you, the last Role, and person-promise fires.
On time: you, 14 of 15 claimed within their due time, median 3 h 10 min, n 15, ■■□□ Early sign beside Other Startups’ 91 % on time (the 15th, task_402, a thread reply on Sep 6, waited 26 h). Your queue: counted by kind: in the category-day week, 28 pitches to write, 6 approvals and 3 thread replies; since then, about 2 approvals and 1 thread 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) | a day notice or correction to a Contact whose Lead, open Deal or Conversation a person owns | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
fact-check (hub, on POST /{namespace}/content/{content}/publish) | a Page, Post or Message with a number or claim no Fact backs | Cut the claim, or name the Fact that backs it. | POST /{namespace}/content/draft |
embargo (the record’s Embargo hold) | a dataset number on any Page or Post before the release lifts | Hold the number until lift at T-0. | POST /{namespace}/posts/{post}/schedule |
pitch-cap (the record’s Pitch cap) | a 41st pitch on the day, a second exclusive, or a pitch off the release and the term | Cut the pitch, or keep the Contact for the next release. | POST /{namespace}/tasks/{task}/assign |
readiness (the record’s Readiness gate) | a start with no graded stance, a closed proof gate or no lease on the name | Grade the stance in positioning-tournament first. | POST /{namespace}/experiments/{experiment}/conclude |
problem-cost (the record’s Problem cost floor) | a canon with no cost Fact from an Interview or Customer record | Record the cost from 5 Interviews first. | POST /{namespace}/tasks/{task}/assign |
| Stop (pauses the Play) | Pauses when | Then |
|---|---|---|
collision | another meaning on 30 %+ of baseline runs, or another party’s mark | the countdown holds; hold-the-day hands it to you |
hostile-reply | 2 hostile replies to pitches in one day | the pitch waves pause; each sender goes to POST /{namespace}/contacts/{contact}/suppress |
meaning-drift | meaning fidelity under 60 % for 3 weeks running | term seeding pauses; a canon review Task opens |
common-ownership | a Page of one of your other Startups recommends Leaseline without stating common ownership | house placements pause until it does |
iterate | at T+45, term share under 10 % with no independent use | one second release angle and one 45-day extension, once |
kill-rule | at T+90, term-touched Leads opened under 3 qualified Deals | the Story reverts to the runner-up; the canon stays up as a glossary |
holdout-harm | at T+90, the category headline trails the runner-up beyond the interval | the same as kill-rule |
kill-switch | you press it | every step pauses with no approval; your Pages stay up |
+ 2 more for the launch lane: the release floor and the deploy freeze (?lanes=) |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that posted is the LinkedIn thread in Example.
| Check | Fix | Then |
|---|---|---|
embargo fail | Hold the number until lift at T-0. | POST /{namespace}/posts/{post}/schedule |
fact-check pass · Not live yet, gaps #1 | — | POST /{namespace}/content/draft |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The LinkedIn Post did not schedule: it shows a dataset number 5 days before lift.",
"checks": [
{
"check": "embargo",
"status": "fail",
"doc": "/plays/category-kit#check-embargo",
"fix": "Hold the number until lift at T-0.",
"then": "Post.schedule"
},
{
"check": "fact-check",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "meaning-drift",
"observed": "55 %, 58 %, 57 %",
"bound": "60 %",
"window": "3 weeks"
},
"doc": "/plays/category-kit#stop-meaning-drift" ,
"task": "task_431"
}
]Did it work
An answer engine cannot be split, so the leaf reads before-after (rule o). The 80/20 headline split on Visitors with no term touch is random, so the rows above the leaf read treated against held back. Each figure’s call is POST /{namespace}/metrics/query by node, and every node above the leaf is Not live yet (gaps #4).
16.9 % term share against 0 % before · before-after,
- Chose
- correct-the-source
- Why
- 4 of 9 Perplexity runs this week define renewal ops as HR contract renewals, and all 4 cite the same glossary Page
- From
- correct-the-source · work-a-cited-source · answer-the-thread · refresh-the-comparison · hand-to-search · hold-the-day
- Expects
- meaning fidelity on Perplexity back over 60 % within 28d
- Reopens when
- term-misdefined fires again for page_88 within 28d
- By
- worker_7
JSON
{
"$id": "decisions/decision_571",
"$type": "Decision",
"choice": "correct-the-source",
"reason": "4 of 9 Perplexity runs this week define renewal ops as HR contract renewals, and all 4 cite the same glossary Page",
"stakes": "low",
"options": [
"correct-the-source",
"work-a-cited-source",
"answer-the-thread",
"refresh-the-comparison",
"hand-to-search",
"hold-the-day"
],
"by": "worker_7",
"on": "page_88",
"expected": "meaning fidelity on Perplexity back over 60 % within 28d",
"reopensWhen": "term-misdefined fires again for page_88 within 28d"
}| Node | Category headline (80 %) | Runner-up headline (20 %, held back) | Added | Confidence | Basis |
|---|---|---|---|---|---|
category-term-share | Now: 16.9 % (61 of 360 definitional runs, Oct 5–18) | Before: 0 % (0 of 360, Jul 13–26) | — (no halves on the leaf) | — | before-after, not proof · Other Startups’ results +12 per 100 runs by T+60, ■■□□ Early sign, n 14 |
icp-reached ↑ | 9.4 qualified Leads per 1,000 Visitors (37 of 3,920) | 7.1 (7 of 980) | +2.3 [−3.0, +7.6] | ■□□□ Too early to tell | held back at random · n 4,900 Visitors · reads to T+90 |
new-arr ↑ | $1,044, 3 Customers · Booked $1,392: credited, not all caused by this Play | $0, 0 Customers | +$266 per 1,000 Visitors [−$190, +$720] · Worth about +$130 a month | ■□□□ Too early to tell (3 vs 0 Customers) | the same assignment · 2 qualified Deals and 4 trials still deciding |
net-new-arr · arr | +$1,044 | $0 | carried: it moves no other bridge term | ■□□□ Too early to tell | carried from new-arr |
Term share counts the definitional runs whose answer cites a canon Page or names Leaseline as the term’s source, per engine, 2 weeks at a time. The headline split reads qualified Leads per 1,000 Visitors with no term touch until T+90, Nov 23.
How it moves it: answer engines cite your definition Page (page_61) on 61 of 360 definitional runs, where before the day no run cited any source for renewal ops.
Guardrails: on the path: term-touched Leads opened 2 qualified Deals against the kill rule’s 3 by Nov 23 (still deciding), and the category headline stays above the runner-up, so holdout-harm has not fired.
{
"$id": "https://api.sb/leaseline.app/campaigns/category-kit" ,
"$type": "Campaign",
"play": "play:category-kit@1" ,
"path": [
"category-term-share",
"icp-reached",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "category-term-share",
"unit": "percent",
"heldBack": 980,
"decision": null
},
"readout": {
"value": null,
"n": 360,
"maturing": 0,
"interval": null,
"readability": "inadmissible",
"basis": "before-after",
"pooled": false
},
"ledger": {
"spend": 0,
"workerCost": 71,
"hours": 11.5,
"pipelineArr": 4800,
"wonArr": 1392,
"projectedArr": 130,
"paybackDays": null
}
}Outside benchmark: journalists picked 33 % of human-written pitches against 10 % of fully AI-generated ones (1,394,740 pitches answering 42,392 requests, a pitch-marketplace detection study, 2026-09-23).
Before it · After it. Before it: positioning-tournament grades the stance and hands over the name (Experiment.concluded). After it: aeo folds the term panel into its own on ship, editorial-seo and paid-search hear search demand once it appears, and community-answers takes open threads after T+7.
Example
Leaseline ran it from 2026-07-08 to 2026-10-19 (103 days; T-0 was Tue 2026-08-25, so asOf is T+55). The panel ran 30 prompts on 6 engines, 3 samples each: 540 runs a week, 180 of them definitional. 25 Decisions followed term Events. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Sent or published | So far |
|---|---|---|---|
| Correct the source | 6 | 5 corrections from your Mailbox, 1 cut | 3 Pages changed their definition |
| Work a cited source | 9 | 4 guest-spot pitches, 2 listings | 2 guest spots given, 3 independent uses |
| Answer the thread | 7 | 7 replies, each written by you | 2 term-touched Leads |
| Refresh the comparison · Hand it to search · Hold the day | 2 · 1 · 0 | 2 Pages within 24 h · 1 hand-off · — | — |
| The category day, Aug 25 | 28 pitches, 1 exclusive | 9 replies, 4 pieces published | 1,206 release Page visits on the day |
| At 1,000 Visitors a month (the Use it when volume) | about 400 held back by T+90 | the parent reads Too early to tell | Other Startups’ results: +1.8 qualified Leads per 1,000 Visitors, ■■□□ Early sign, n 14 |
| Day | Event | What happened | Your time |
|---|---|---|---|
| T-48 · Jul 8 | event_402 Campaign.created | the dry run fails approved-pages; you publish your pricing and about Pages | 25 min |
| T-43 to T-30 | event_418 Monitor.checked, first of 2 | baseline: 22 of 360 definitional runs give another meaning (6 %), under the 30 % hold | — |
| T-28 · Jul 28 | event_477 Post.scheduled | the day drawn at random from Aug 25, Aug 26 and Sep 1; you accepted it | 5 min |
| T-7 · Aug 18 | event_560 Content.published | definition, point-of-view, glossary, comparison and origin Pages up, unannounced | 2 h on your point of view |
| T-5 · Aug 20 | event_571 Action.refused | embargo held a LinkedIn Post with the 31 % finding | — |
| T-0 · Aug 25 | event_602 Post.published | the release lifts; you send 28 pitches in 3 waves; 9 reply | 3 h 20 min |
| T+9 · Sep 3 | event_655 Monitor.checked | first cited definition: Perplexity cites page_61 on 2 of 9 runs | — |
| T+21 · Sep 15 | event_701 Campaign.paused | meaning-drift at 55, 58 and 57 %; you tightened the in-and-out rules on Sep 17 | 40 min |
| T+45 · Oct 9 | event_811 Decision.created | the iterate rule reads 15.8 % and 3 independent uses, so no second angle | — |
| T-48 to T+55 | event_431 Approval.created, first of 15 | you approved 14 corrections and pitches, cut 1, and wrote 7 thread replies | 4 h · total 11.5 h measured, 13 h asked |
Dana → Morgan at a property-trade newsletter, Aug 25, 07:12 · Across 1,212 leases at 38 small property managers, 31 % of renewal notices went out under 60 days before the lease ended.¹ We call getting them out on time renewal ops, and the definition is here.² The dataset and method are on the release Page.³ *Written and sent by Dana from her own Mailbox.*⁴
Morgan, 09:40 · “Send me the per-state split; I’m writing Thursday.” · Dana, 10:05 · the CSV link from the release Page. The piece ran Aug 27, citing the definition Page.
- 31 % of renewal notices go out late. Here’s what we found across 1,212 leases.
+ Renewal ops: getting every renewal notice out on time. Our definition, in plain words. A landlord forum thread, 2026-10-02 08:14 · “Is renewal ops just a spreadsheet with reminders?” · Content Lead · your agent, 08:16 · drafted the fact pack (the definition, the 3 in-and-out rules and the dataset link) into your queue, due 09:14 (
task_488). · Dana, 08:51 · posted her own reply, linking the definition Page.
¹ From the release’s stored query, with its n and interval. ² The definition Page, which names no product. ³ The method, sample and date, on the release Page. ⁴ The agent built the list and the brief; it never writes a pitch.
Your settings
---
term: renewal ops
holdout: 0.2 # 20 % of Visitors with no term touch see the runner-up headline
day: 2026-08-25
kill: 3 qualified Deals from term-touched Leads by T+90
---
Make renewal ops the name for getting every renewal notice out on time. I write every pitch, the launch post and every thread reply. $ npx startup-builder show plays/category-kit
term renewal ops · holdout 0.2 · day 2026-08-25 · kill 3 qualified Deals your file plays/category-kit.mdx:2-5,7 (Ask 2026-07-08; day by event_477, 2026-07-28)
family demand · worker role:content-lead, owns never · chooses 6 (4 rule, 2 read) · sequences category-press-countdown, category-day-notice · checks owned-by-a-person, fact-check, embargo, pitch-cap, readiness, problem-cost · stops 10 · placements 6 answer engines, google-search, product-hunt, hacker-news, linkedin, x, youtube, gmail, outlook catalog play:category-kit@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record category-kit 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.