Skip to content

Launch week

Turns a quarter’s shipped Changes into five dated launch days, each with its own Page and posts, and leaves no claim on your Site false.

Channel
Launches
Run oneMode try
You, to your agent

Hand the latest shipped Change to the Marketing Lead agent and show me what it chose and why. Don’t publish.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Change.merged%22%2C%20%22Flag.evaluated%22%2C%20%22Change.reverted%22%2C%20%22Period.opened%22%2C%20%22Organization.announced%22%2C%20%22Version.deployed%22%2C%20%22Visitor.identified%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_1209"}'

# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22change_41%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%22change_41%22" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Change.merged", "Flag.evaluated", "Change.reverted", "Period.opened", "Organization.announced", "Version.deployed", "Visitor.identified")', 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 (\"Change.merged\", \"Flag.evaluated\", \"Change.reverted\", \"Period.opened\", \"Organization.announced\", \"Version.deployed\", \"Visitor.identified\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1209"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"change_41\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"change_41\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Change.merged\", \"Flag.evaluated\", \"Change.reverted\", \"Period.opened\", \"Organization.announced\", \"Version.deployed\", \"Visitor.identified\")', 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"
  }
}
Response200application/json
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_434",
    "$type": "Decision",
    "choice": "fix-the-claim",
    "reason": "`change_41` ships the owner portal; your comparison Page still says “owners get PDF reports only”, and a comparison row is yours to rewrite",
    "stakes": "medium",
    "options": [
      "write-the-feed-line",
      "fix-the-claim",
      "plan-the-week",
      "run-the-day",
      "swap-in-the-reserve",
      "tell-who-asked",
  …
sample · 4 Not live yetPreview

On PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim

action_1 is the feed line, held until the portal is on for every Customer for 7 days. action_2 sends the comparison row to you; record-copied facts it fixes itself, a comparison row it never does.

462 ICP Visitors in the week’s window against 320 before · before-after, not proof · n 1 · path → arr

Try another: the ChangeChoiceReason
Owner portal shipped Oct 18; the comparison Page says “PDF reports only”fix-the-claima live claim is now false
Sep 1: Q3 holds 8 flag-on units, 90 days since no weekplan-the-weekthe quarter’s third month, 6+ units
Sep 30, day 3: move-out templates, Incident open on POST /{namespace}/messages/{message}/scheduleswap-in-the-reservean open Incident on a Verb the day names
SMS reminders at 40 % rolloutnot-nownot on for every Customer for 7 days

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Launch week ICP visits → People reached → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +150 ICP Visitors per launch week (Other Startups’ results; no lift of your own to read) × 1 week a quarter ÷ 3 months × 0.008 Visitors to paid × $590 first order ARR ≈ +$236. Under First signal: Each week reads at day 5 plus 14; at 1 a quarter it reads before-after against your 12-week baseline, beside Other Startups’ results.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Change.merged · first drift fix 38m · 7 keys Not live yet

Start it this week

Terminal
npx startup-builder add play launch-week   # 1 · writes plays/launch-week.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":"launch-week"}'

# 3 · keep it: you accept every plan and every comparison row
curl -X POST https://api.sb/leaseline.app/campaigns \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"launch-week"}'

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

# off: the week stops; the drift sweep keeps running
curl -X PATCH https://api.sb/leaseline.app/campaigns/launch-week \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endsAt":"now"}'
422Refusedlaunch-week can’t start: 1 check fails and 1 warns.
CheckFixThen
use-when warn · Not live yet, gaps #8Grow the list to 100 by planning day; the recap waits for it.POST /{namespace}/contacts/{contact}/subscribe
baseline pass · Not live yet, gaps #8118 ICP Visitors a week, 12-week baselinePOST /{namespace}/metrics/query
change-feed failConnect your code host so the feed reads each merged Change.POST /{namespace}/integrations/connect
domain-authenticated pass—POST /{namespace}/domains/{domain}/authenticate
mailbox-warm pass · Not live yet, gaps #1the Startup’s Mailbox, warm since JulyPOST /{namespace}/mailboxes/{mailbox}/warm
role-unstaffed pass · Not live yet, gaps #8plans and comparison rows go to the founder, DanaPOST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "launch-week can’t start: 1 check fails and 1 warns.",
  "checks": [
    {
      "check": "use-when",
      "status": "warn",
      "observed": "Q3: 8 visible Changes flag-on; 74 of 100 People who said yes",
      "doc": "/plays/launch-week#check-use-when",
      "fix": "Grow the list to 100 by planning day; the recap waits for it.",
      "then": "Contact.subscribe"
    },
    {
      "check": "baseline",
      "status": "pass",
      "observed": "118 ICP Visitors a week, 12-week baseline",
      "doc": "/plays/launch-week#check-baseline",
      "then": "Metric.query"
    },
    {
      "check": "change-feed",
      "status": "fail",
      "doc": "/plays/launch-week#check-change-feed",
      "fix": "Connect your code host so the feed reads each merged Change.",
      "then": "Integration.connect"
    },
    {
      "check": "domain-authenticated",
      "status": "pass",
      "doc": "/plays/launch-week#check-domain-authenticated",
      "then": "Domain.authenticate"
    },
    {
      "check": "mailbox-warm",
      "status": "pass",
      "observed": "the Startup’s Mailbox, warm since July",
      "doc": "/plays/launch-week#check-mailbox-warm",
      "then": "Mailbox.warm"
    },
    {
      "check": "role-unstaffed",
      "status": "pass",
      "observed": "plans and comparison rows go to the founder, Dana",
      "doc": "/plays/launch-week#check-role-unstaffed",
      "then": "Role.staff"
    }
  ]
}

It says no, says why, and names the fix.

CheckFix (one call)Your timeWait
use-when · baseline · warn: 8 Changes, 74 of 100 who said yes; pass: 118 a week (gaps #8)POST /{namespace}/contacts/{contact}/subscribe from the waitlist form; POST /{namespace}/metrics/query on launch-week-icp-visits fills Before5 minabout a week at 4 a day
change-feed · fail (gaps #8)POST /{namespace}/integrations/connect with your code host5 minthe first feed run, about 10 min
domain-authenticated · mailbox-warm · role-unstaffed · passnothing to do0 minnone

Your number · Before 320 ICP Visitors per 19 days · Now 462 in the week’s window · Target 500 by Dec 31 · before-after, not proof · n 1 week

A launch week costs no cash: day Pages publish on your own Site and posts go from your own Handles. The feed, the drift sweep and the kit cost about $3 a week (Worker cost). Your time is about 3.5 hours per week, plus 15 minutes a week on the feed digest.

When it starts

WhenTrigger idStarts onWindowHow it gets in
A Change merges with a diff Customers can seechange-mergedevent on Change.merged where tier is set and the diff touches a Verb, Noun, Offer, Entitlement, Interface, Page or Product7dPOST /{namespace}/integrations/connect with your code host
A merged or reverted Change makes a live claim falseclaim-driftevent on Change.merged where alters a value a live Page, listing, Ad, fact, Template or Handle bio states1d; found within 1 hthe sweep reads your Site, listings, Ads and bios
The quarter’s third month opens, 90 days after the last weeklaunch-week-dueat on Period.opened where the first weekday of the quarter’s third month, 90 days after the last launch week30dset by your file’s quarter line
+ 5 more for flag-on Changes, reverts, a rival’s launch week, resolved loss reasons and week signups (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1209",
  "$type": "Event",
  "name": "Change.merged",
  "at": "2026-10-18T16:40:03Z",
  "seq": 1209,
  "data": {
    "change": "changes/change_41",
    "title": "Owner portal: each owner signs in to see their renewals",
    "tier": 1,
    "flags": [
      "owner-portal"
    ],
    "rollout": 1,
    "drift": [
      "pages/compare-spreadsheets#row-4"
    ]
  }
}
Reproduce it in test
# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"Change.merged","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Change.merged --like event_1209   # replays the delivery through the drift sweep
npx startup-builder clock advance --by 7d   # reads whether the portal stayed on for every Customer

Who runs it

Marketing Lead · your agent (role:marketing-lead, worker_8) holds the Key Result: it writes the feed, runs the drift sweep, plans the week, builds each day’s kit and runs the day. Each quarter’s plan and every comparison row hand to you (Dana Okafor, person, worker_1, role:founder), and you send your own posts from the tray and write every Hacker News word.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Write the feed line · Tell who askedIt does it24 lines, 6 Messages, 0 Checks failed sentmet on day 14a line before flag-on → You approve each onePOST /{namespace}/actions/{action}/cancel
Fix the claimIt does it, you can stop it, for facts copied from records; You approve each one for comparison rows9 fixed, 3 rows rewritten by younever for a comparison row—POST /{namespace}/actions/{action}/cancel · POST /{namespace}/tasks/{task}/return
Plan the weekYou approve each one1 of 1never—POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/tasks/{task}/return
Run the day · Swap in the reserveIt does it, you can stop it5 days, 1 swapmet after review-all on day 1an outage hold → You approve each onePOST /{namespace}/actions/{action}/cancel inside the hold
Change the day orderYou approve each one1 merged of 1never—POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert
Never: a line before flag-on, a number its Change lacks, a vote askRefused, every time2 drafted, 2 refusednever—the flag-gate and vote-ask Checks

What it reads · What it may call. It reads each Change’s own description, its Flags and Evidence, and the live Site, never a watched Event in what it writes. It may call POST /{namespace}/content/draft, PATCH /{namespace}/pages/{id}, POST /{namespace}/sites/{site}/publish, POST /{namespace}/posts/{post}/publish and POST /{namespace}/posts/{post}/withdraw on your own Site and Handles. Its tools are POST /{namespace}/content/draft, PATCH /{namespace}/pages/{id}, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/sites/{site}/publish, POST /{namespace}/posts/{post}/publish, POST /{namespace}/posts/{post}/withdraw, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:launch-week@1 · each line names its record key
You hold the Marketing Lead Key Result: 500 ICP Visitors per launch week by 2026-12-31. ← worker, metric
On each merged Change, drift or due date, choose one option and say why.         ← triggers, chooses
Name a Change only when every Flag it names is on for every Customer for 7 days. ← flag-gate
Start each line “You can now”, in 20 words or fewer, with no number the Change lacks. ← copyRules 1, 2
Lead the week with the tier 1 unit, then integrations, then templates.           ← your file, line 6
A comparison row goes to the founder; a record-copied fact you fix.              ← chooses.fix-the-claim

The slow loop, as a Change. decision_394 (2026-09-21, weekly, during planning) read Leaseline’s 4 integration Pages bringing 2 times the ICP Visits of its template Pages, so change_30 moved the Ledgerly and Porchlight unit from day 4 to day 2 (your file, line 6), and Dana merged it with POST /{namespace}/changes/{change}/merge. Replayed on Q2’s Pages, POST /{namespace}/changes/{change}/review put the week at about 450; read back at day 5 plus 14 it is 462, n 1 week, ■□□□ Too early to tell (Example, day 53).

Bring your own agent (folded) plans and runs the week at the same rung when it matches or beats the seated agent on the eval suite; plans and comparison rows wait on you either way, and POST /{namespace}/roles/{role}/staff seats it.

Terminal
npx startup-builder eval --scenario launch-week-38 --agent "claude -p" --seat marketing-lead   # seated: 0 false claims left, 0 unflagged lines sent · yours: 1 claim left on a listing, 1 line at 40 % rollout → You approve each one

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Write the feed line write-the-feed-linea merged Change with a diff Customers can seeYour rule (the feed)POST /{namespace}/content/draft the line, held until flag-onnobodythe same
Fix the claim fix-the-claima merged or reverted Change made a live claim falseAgent’s call, with its reasonPATCH /{namespace}/pages/{id} for a fact copied from a record; POST /{namespace}/tasks/{task}/assign for a comparison rowyou rewrite the row, due 1 business day · Take this oneyou
Plan the week plan-the-weekthe quarter’s third month, 6+ flag-on units, 90 days since the last weekYour rule (line 3)POST /{namespace}/content/draft the plan: five days and a reserve → POST /{namespace}/tasks/{task}/assignyou accept it, due 1 business day · Take this oneyou
Run the day run-the-daya launch day’s 09:00 slot, every Change still flag-onYour rule (the plan)POST /{namespace}/sites/{site}/publish the day Page → POST /{namespace}/posts/{post}/publish on Leaseline’s Handles → day 5: launch-week-recapnobody; your own posts wait in the traythe same
Swap in the reserve swap-in-the-reservean open Incident or a revert on a Verb the day namesAgent’s call, with its reasonPOST /{namespace}/sites/{site}/publish the reserve unit → POST /{namespace}/posts/{post}/withdraw any Post on the held unitnobody; you see it in the day line at 18:00the same
Tell who asked tell-who-askeda Person whose words asked for the Change, once it is flag-onYour rule (the Sequence)you-asked-it-shipped: one Messagenobodythe same
Not now not-nownot flag-on for every Customer for 7 days, no visible diff, or another of your Startups holds that weekYour rule (the gates and the caps)nothing; names the Flag, the diff or the other weeknobody; the feed reads it againthe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interesteda recap reply: “The owner reports are what we need. Can we talk?”goes to instant-response as a new Lead, with the week on its AcquisitionSDR · your agent, then AE · Priya Shah (person)5 minPOST /{namespace}/leads
Send me pricing“Is the owner portal on Pro?”answered from the live Pricing Page, as it stands at send timeSDR · your agent5 minPOST /{namespace}/conversations/{conversation}/answer
Not now“Thanks, not for us right now.”nothing more about the week sends to themnobodyat onceGET /{namespace}/decisions
Wrong person“Sending this to our ops lead.”a one-line thanks; it never writes to an address from their textMarketing Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply to the recapnothing: the recap carries no follow-upnobody—GET /{namespace}/decisions
Question it can’t answer“When does SMS ship?”To you: a date for a Change that is not flag-on is never the agent’s to giveyou (Dana, person)1 business dayPOST /{namespace}/conversations/{conversation}/escalate
Stop“Unsubscribe.”no recap, note or newsletter sends to them againnobodyat oncePOST /{namespace}/contacts/{contact}/unsubscribe

When it hands to you

Each quarter’s plan and every comparison row hand to you (Dana Okafor, person); interested recap replies go through instant-response to the AE. As captured, the comparison-row Task in your queue (brief is Not live yet, gaps #7).

What lands in each queue · sample
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_524",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-19T17:00:00Z",
    "on": "change_41",
    "brief": {
      "page": "Leaseline vs spreadsheets, row 4",
      "says": "owners get PDF reports only",
      "now": "each owner signs in to the portal to see their renewals (change_41, flag on for 41 of 41 Customers)",
      "chose": "fix-the-claim",
      "why": "a comparison row is the founder’s to rewrite",
      "never": [
        "a claim about a named rival",
        "a number change_41 lacks"
      ]
    }
  }
]

You answer with POST /{namespace}/tasks/{task}/claim (Take this one) and rewrite the row, POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{action}/redirect; a plan with POST /{namespace}/approvals/{approval}/approve. While the row is open, drift-hold holds any post that links the comparison Page. Nobody else can rewrite a comparison in your name, so nothing goes up a Role.

On time: You: 4 of 4 comparison rows and 1 of 1 plan answered within 1 business day, median 3h 20m, n 5, ■□□□ Too early to tell beside Other Startups’ 87 %. Your queue: counted by kind: per quarter, 1 plan and 5 day lines; between weeks, about 1 comparison row a fortnight and the 15-minute weekly digest.

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)RefusesFixThen
owned-by-a-person (rule j; Not live yet, gaps #8)a recap or Message to a Contact whose Lead or open Deal a person ownsLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
fact-check (copy rule 2)a line with a number the Change’s description, its Evidence or a measured Metric lacksCut the number, or add it to the Change’s description.POST /{namespace}/content/draft
flag-gatea Post, Page, recap or listing naming a Change not on for every Customer for 7 daysWait for full rollout; it joins the next day or the next week.GET /{namespace}/decisions
visible-onlya line, Post or Page for a Change with no diff Customers can seeNone: it stays in the internal changelog.GET /{namespace}/decisions
drift-holda day’s sends while a linked surface holds a false claim; the week’s, for the Pricing or a comparison PageFix the claim; the sends release once it is true.PATCH /{namespace}/pages/{id}
deploy-freezea deploy or a named Flag change from day 1 00:00 to day 5 23:59Ship it after day 5, or ship an approved fix in steps; reverts always run.POST /{namespace}/approvals/{approval}/approve
incident-holda day that names a Verb with an open IncidentThe reserve unit runs instead.POST /{namespace}/incidents/{incident}/resolve
authorshipan agent sentence for Hacker NewsWrite it yourself from the fragments.POST /{namespace}/tasks/{task}/assign
vote-askany Page, Post or Message that asks anyone to vote, upvote or rank anythingCut the ask; say what they can now do.POST /{namespace}/content/draft
portfolio-capsa second launch week for one audience in a calendar week, or your Startups launching togetherTake the next open week.POST /{namespace}/tasks/next
Stop (pauses the Play)Pauses whenThen
revert-withdrawan announced Change is revertedits Posts withdraw within 1 hour and its day Page gains a dated correction
outageerrors over 2 % of requests, or p95 over 3 s for 5 minthe day’s sends and Posts hold
bounce (email)bounces over 2 % of the recap’s sendsthe Mailbox pauses
complaint (email)complaints near 0.1 %the recap pauses on every Mailbox
kill-switchyou press itevery Tactic pauses at once; the freeze lifts and reverts still run
+ 1 more for the ads lane: a drifted Ad pauses at once (?lanes=all)

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

422RefusedThe day 1 Post did not publish: it states a number `change_33` does not hold.
CheckFixThen
fact-check fail · Not live yet, gaps #1Cut the number, or add it to the Change’s description.POST /{namespace}/content/draft
flag-gate pass—GET /{namespace}/decisions
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The day 1 Post did not publish: it states a number `change_33` does not hold.",
  "checks": [
    {
      "check": "fact-check",
      "status": "fail",
      "doc": "/plays/launch-week#check-fact-check",
      "fix": "Cut the number, or add it to the Change’s description.",
      "then": "Content.draft"
    },
    {
      "check": "flag-gate",
      "status": "pass"
    }
  ]
}

It says no, says why, and names the fix.

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "revert-withdraw",
      "observed": "`change_37` reverted at 11:12",
      "bound": "0 announced reverts",
      "window": "day 4"
    },
    "doc": "/plays/launch-week#stop-revert-withdraw",
    "task": "task_441"
  }
]

Did it work

At 1 week a quarter, no held-back half of weeks reads, so the basis is before-after against your 12-week baseline (rule o): the columns read Now and Before, and nothing prints as Added. Each figure’s call is POST /{namespace}/metrics/query by node, and every node above the leaf is Not live yet (gaps #4).

462 ICP Visitors in the week’s window against 320 before · before-after, not proof · n 1 · path → arr

Chose
fix-the-claim
Why
`change_41` ships the owner portal; your comparison Page still says “owners get PDF reports only”, and a comparison row is yours to rewrite
From
write-the-feed-line · fix-the-claim · plan-the-week · run-the-day · swap-in-the-reserve · tell-who-asked · not-now
Expects
the comparison row true within 1 business day
Reopens when
no Page.updated on the comparison Page within 1d
By
worker_8
JSON
{
  "$id": "decisions/decision_434",
  "$type": "Decision",
  "choice": "fix-the-claim",
  "reason": "`change_41` ships the owner portal; your comparison Page still says “owners get PDF reports only”, and a comparison row is yours to rewrite",
  "stakes": "medium",
  "options": [
    "write-the-feed-line",
    "fix-the-claim",
    "plan-the-week",
    "run-the-day",
    "swap-in-the-reserve",
    "tell-who-asked",
    "not-now"
  ],
  "by": "worker_8",
  "on": "change_41",
  "expected": "the comparison row true within 1 business day",
  "reopensWhen": "no Page.updated on the comparison Page within 1d"
}
NodeNow (the week, day 1 to day 5 plus 14)Before (12-week baseline, per 19 days)AddedConfidenceBasis
launch-week-icp-visits462 ICP Visitors whose first Visit came from a day Page, a week Post, the recap or the short link320, from every Source— · Worth about +$240 a month—before-after, not proof · Other Startups’ results +150 per week, ■■■□ Likely, n 380 weeks, 10 % recap holdout
icp-reached1,104 ICP Visitors in the 19 days, every Source320——before-after
new-arr ↑$2,329, 5 week-sourced Customers (4 on Pro, 1 on Team) · Booked: credited, not all caused by this Play$694 per 19 days— · 23 signups activated by day 5 plus 14; 6 trials still deciding—before-after, not proof
net-new-arr · arrcarried from new-arrcarried——carried

Before against after reads ICP Visitors from the week’s outputs, day 1 to day 5 plus 14, against your 12-week baseline scaled to 19 days. It is not proof; Other Startups’ results, read against a 10 % recap holdout, print beside it.

How it moves it: eight small Q3 releases landed as five dated days, each with its own Page and two posts, and the recap reached 187 People who said yes.

Guardrails: before against after: play-sourced-customers, 5 against 2, and false claims left on the Site at day 5, 0 against 3 found by the first sweep.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/launch-week",
  "$type": "Campaign",
  "play": "play:launch-week@1",
  "path": [
    "launch-week-icp-visits",
    "icp-reached",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "launch-week-icp-visits",
    "unit": "count",
    "heldBack": 0,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 1,
    "maturing": 0,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 0,
    "workerCost": 24,
    "hours": 5.5,
    "pipelineArr": 2082,
    "wonArr": 2329,
    "projectedArr": 236,
    "paybackDays": 0
  }
}

Outside benchmark: none measures a startup launch week against its own baseline; Other Startups’ results, +150 ICP Visitors per week, ■■■□ Likely, n 380 weeks, stand in for one.

Before it · After it. Before it: shipped Changes and the drift sweep run every week. After it: a tier 1 Change on a rested site goes to launch-sites, refreshed listings to marketplace-listings, and a resolved loss reason to lead-reactivation.

Example

Leaseline ran its first launch week from 2026-09-28 to 2026-10-02 on Q3’s 38 merged Changes: 14 internal, 16 changelog lines, 7 tier 2 and 1 tier 1, grouped into 5 days and 1 reserve. The drift sweep ran all 56 days. Read every captured thread at ?threads=all; three follow the tables.

What happened, by optionDecisionsPublished or sentICP VisitorsWon (credited, not all caused by this Play)
Write the feed line · Tell who asked24 · 624 lines · 6 Messages—1 Customer from a “you asked” Message
Fix the claim129 facts fixed, 3 rows rewritten by you——
Plan the week · Run the day · Swap in the reserve1 · 5 · 15 day Pages, 10 Handle Posts, 187 recaps4624 Customers
Not now80——
All · 12-week baseline, per 19 days57—462 · 320$2,329 · $694
At 1 week a quarter (the Use it when volume)about 60 a quarter1 weekbefore-after, not proofOther Startups’ results: +150 per week, ■■■□ Likely, n 380
DayEventWhat happenedYour time
0event_130 Campaign.createdthe three steps; dry run fails change-feed20 min
1event_141 Change.mergedthe first drift sweep: 3 false claims, all fixed by day 415 min
8event_270 Approval.approvedyou accepted the plan: 5 days, 1 reserve, freeze Sep 28 to Oct 230 min
28 · 53event_538 Change.merged · event_890 Readout.createdintegrations on day 2: replayed at about 450, read back at day 5 plus 14 at 462, n 15 min
35event_610 Site.publishedday 1: per-owner renewal batches; the first week-sourced signup at 09:4020 min
38event_655 Campaign.pausedrevert-withdraw: change_37 reverted at 11:12; its Post withdrew at 11:31 and the reserve ran—
1–56event_145 Task.assigned, first of 18you accepted 1 plan, rewrote 3 rows and sent 10 of your own posts, from the POST /{namespace}/tasks/next log4.3 h · total 5.5 h measured, 5 h asked

Day 2, Sep 29, 09:00, Leaseline’s LinkedIn · You can now post each signed renewal to Ledgerly or Porchlight the day it signs.¹ The day Page shows both, live.²

Sep 29, 10:12 · a 140-unit manager read the day Page, signed up (first Source: the week’s short link) and activated on Oct 3; paid for Team on Oct 9, +$941 ARR.

Day 1 Post, 2026-09-28 · the draft refused for a number its Change lacks, then the rewrite that published
- Renewals now go out 3x faster with per-owner batches.
+ You can now send each owner their own renewal batch, 60 days out.

Oct 18, 16:41 · change_41 shipped the owner portal, and the sweep found row 4 of the spreadsheets comparison still saying “PDF reports only”. The agent fixed nothing there and sent the row to Dana, due Oct 19, 17:00. · Dana, Oct 19, 09:20 · claimed it and rewrote the row; the hold on posts linking the Page released at 09:21.

¹ “You can now”, 20 words or fewer, from the Change’s own description. ² A screen the live Site serves.

Your settings

plays/launch-week.mdx
---
recapHoldout: 0.1     # 1 in 10 who said yes gets no recap
quarter: third-month
freeze: day-1-to-day-5
---
Lead with the tier 1 unit, then integrations, then templates. Comparison rows are mine.
Text
$ npx startup-builder show plays/launch-week
recap holdout 0.1 · third month · freeze day 1 to day 5 · day order     your file  plays/launch-week.mdx:2,3,4,6 (Ask 2026-08-24; line 6 by change_30, 2026-09-21)
family demand · worker role:marketing-lead, owns never · chooses 7 (5 rule, 2 read) · sequences launch-week-recap, you-asked-it-shipped, week-signup-follow-up · checks owned-by-a-person, fact-check + 8 · stops 5 + 1 on ads · placements site, google-search, x, linkedin, hacker-news, gmail, outlook, yahoo-mail    catalog  play:launch-week@1 (Not live yet, gaps #5)

Every key from the catalog

Key Id What it is
Tactic shipped-code-feed Shipped code feed writes one weekly line per Customer-visible Change, holds it until its Flags are on, and gives each tier its fixed outputs. Starts at You approve each one.
Tactic claim-drift Claim drift finds each live claim a merged or reverted Change made false within 1 hour, then corrects, pauses or routes it. Starts at You approve each one.
Tactic launch-week-plan Launch week plan groups a quarter’s flag-on Changes into day units and a reserve, then picks the week and books the freeze. Starts at It does it, you can stop it.
Tactic launch-week-kit Launch week kit builds each day’s Page, capture, Posts, in-app note and listing fields from the Changes’ own descriptions and the live Site. Starts at You approve each one.
Tactic launch-week-day Launch week day re-checks a day’s Changes an hour before the slot, then publishes its Page, notes and Handle Posts or swaps in the reserve. Starts at You approve each one.
Tactic deploy-freeze Deploy freeze holds every live deploy and named Flag through the launch days, while reverts run at any hour and approved fixes ship in steps. Starts at Sends nothing.
Tactic launch-week-readout Launch week readout counts the Customers a week activates through day 5 plus 14, against a recap holdout and the Startup’s own baseline. Starts at Sends nothing.
Tactic 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.
Tactic 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 first-person-draft First-person draft: Turns a Human's own seed into a draft that passes a voice judge and a fabrication veto, for that Human to approve and send. Starts at You approve each one.
Tactic launch-readiness-gate Launch readiness gate runs nine rule checks on a live Startup and books a launch only when every check passes. Starts at Sends nothing.
Trigger change-merged Change merged: event on Change.merged, window 7d.
Trigger change-flag-on Change flag-on: state on Flag.evaluated, window 90d.
Trigger claim-drift Claim drift: event on Change.merged, window 1d.
Trigger change-reverted Change reverted: event on Change.reverted, window 1h.
Trigger launch-week-due Launch week due: at on Period.opened, window 30d.
Trigger category-launch-week Category launch week: event on Organization.announced, window 30d.
Trigger launchable-change Launchable change: event on Version.deployed, window 30d.
Trigger loss-reason-resolved Loss reason resolved: event on Version.deployed, window 30d.
Trigger week-sourced-signup Week-sourced signup: event on Visitor.identified, window 19d.
Sequence launch-week-recap Launch week recap: 1 steps; it ends on Opt-out; Signup.
Sequence you-asked-it-shipped You asked, it shipped: 1 steps; it ends on Opt-out.
Sequence week-signup-follow-up Week signup follow-up: 4 steps; it ends on Activation; Opt-out; An open Issue from the Person, which Support takes over; Day 5 plus 14 of the week.

Compiled, not written: edit the Play record launch-week 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.