URL: /plays/launch-week · Id: `play:launch-week`

# 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.

Turns a quarter’s shipped [Changes](https://startupbuilder.dev/business/nouns/change) into five dated launch days, each with its own [Page](https://startupbuilder.dev/business/nouns/page) and posts, and leaves no claim on your [Site](https://startupbuilder.dev/business/nouns/site) false.

```text title="Set it up · Ask"
Be our Marketing Lead for launch week: once a quarter, group what we shipped into five dated days, each with a Page and posts, plus a recap to the people who signed up to hear from us. Only things on for every Customer. Fix any Site claim a Change makes false. Show me what’s missing; don’t publish.
```

```text title="Run one · Ask"
Hand the latest shipped Change to the Marketing Lead agent and show me what it chose and why. Don’t publish.
```

```ts title="Run one · SDK"
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 }
```

```json title="Run one · Response · sample"
{
  "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",
      "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"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_8",
      "verb": "Content.draft",
      "checks": [
        {
          "check": "flag-gate",
          "status": "pass"
        },
        {
          "check": "visible-only",
          "status": "pass"
        }
      ]
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingFounder",
      "mode": "try",
      "by": "worker_8",
      "verb": "Task.assign",
      "checks": [
        {
          "check": "owned-by-a-person",
          "status": "pass"
        },
        {
          "check": "drift-hold",
          "status": "pass"
        }
      ]
    }
  ]
}
```

`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 Change | Choice | Reason |
| --- | --- | --- |
| Owner portal shipped Oct 18; the comparison Page says “PDF reports only” | `fix-the-claim` | a live claim is now false |
| Sep 1: Q3 holds 8 flag-on units, 90 days since no week | `plan-the-week` | the quarter’s third month, 6+ units |
| Sep 30, day 3: move-out templates, Incident open on <Op verb="Message.schedule" /> | `swap-in-the-reserve` | an open Incident on a Verb the day names |
| SMS reminders at 40 % rollout | `not-now` | not on for every Customer for 7 days |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$240 ARR a month at 1 a quarter | 3.5 h per week, then 15 min a week | $0 per week; ~$3 a week of Worker cost | Day 1 of the week: first week-sourced signup | 6+ visible Changes a quarter, 100+ People who said yes | Under 6 Changes: `launch-sites` · under 100: `owned-newsletter` |

**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
```bash
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"}'
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "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"
    }
  ]
}
```

| Check | Fix (one call) | Your time | Wait |
| --- | --- | --- | --- |
| <a id="check-use-when"></a>`use-when` · <a id="check-baseline"></a>`baseline` · warn: 8 Changes, 74 of 100 who said yes; pass: 118 a week (gaps #8) | <Op verb="Contact.subscribe" /> from the waitlist form; <Op verb="Metric.query" /> on `launch-week-icp-visits` fills Before | 5 min | about a week at 4 a day |
| <a id="check-change-feed"></a>`change-feed` · fail (gaps #8) | <Op verb="Integration.connect" /> with your code host | 5 min | the first feed run, about 10 min |
| <a id="check-domain-authenticated"></a>`domain-authenticated` · <a id="check-mailbox-warm"></a>`mailbox-warm` · <a id="check-role-unstaffed"></a>`role-unstaffed` · pass | nothing to do | 0 min | none |

`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
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| A Change merges with a diff Customers can see | `change-merged` | `event` on `Change.merged` where tier is set and the diff touches a Verb, Noun, Offer, Entitlement, Interface, Page or Product | 7d | <Op verb="Integration.connect" /> with your code host |
| A merged or reverted Change makes a live claim false | `claim-drift` | `event` on `Change.merged` where alters a value a live Page, listing, Ad, fact, Template or Handle bio states | 1d; found within 1 h | the sweep reads your Site, listings, Ads and bios |
| The quarter’s third month opens, 90 days after the last week | `launch-week-due` | `at` on `Period.opened` where the first weekday of the quarter’s third month, 90 days after the last launch week | 30d | set 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`) | | | | |

```json title="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"
    ]
  }
}
```

```bash title="Reproduce it in test"
# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"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.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Write the feed line · Tell who asked | It does it | 24 lines, 6 Messages, 0 Checks failed sent | met on day 14 | a line before flag-on → You approve each one | <Op verb="Action.cancel" /> |
| Fix the claim | It does it, you can stop it, for facts copied from records; You approve each one for comparison rows | 9 fixed, 3 rows rewritten by you | never for a comparison row | — | <Op verb="Action.cancel" /> · <Op verb="Task.return" /> |
| Plan the week | You approve each one | 1 of 1 | never | — | <Op verb="Approval.approve" /> · <Op verb="Task.return" /> |
| Run the day · Swap in the reserve | It does it, you can stop it | 5 days, 1 swap | met after review-all on day 1 | an `outage` hold → You approve each one | <Op verb="Action.cancel" /> inside the hold |
| Change the day order | You approve each one | 1 merged of 1 | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a line before flag-on, a number its Change lacks, a vote ask | Refused, every time | 2 drafted, 2 refused | never | — | 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 <Op verb="Content.draft" />, <Op verb="Page.update" />, <Op verb="Site.publish" />, <Op verb="Post.publish" /> and <Op verb="Post.withdraw" /> on your own Site and Handles. Its tools are <Op verb="Content.draft" />, <Op verb="Page.update" />, <Op verb="Task.assign" />, <Op verb="Site.publish" />, <Op verb="Post.publish" />, <Op verb="Post.withdraw" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="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 <Op verb="Change.merge" />. **Replayed on Q2’s Pages**, <Op verb="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 <Op verb="Role.staff" /> seats it.

```bash
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
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
| --- | --- | --- | --- | --- | --- |
| Write the feed line `write-the-feed-line` | a merged Change with a diff Customers can see | Your rule (the feed) | <Op verb="Content.draft" /> the line, held until flag-on | nobody | the same |
| Fix the claim `fix-the-claim` | a merged or reverted Change made a live claim false | Agent’s call, with its reason | <Op verb="Page.update" /> for a fact copied from a record; <Op verb="Task.assign" /> for a comparison row | you rewrite the row, due 1 business day · Take this one | you |
| Plan the week `plan-the-week` | the quarter’s third month, 6+ flag-on units, 90 days since the last week | Your rule (line 3) | <Op verb="Content.draft" /> the plan: five days and a reserve → <Op verb="Task.assign" /> | you accept it, due 1 business day · Take this one | you |
| Run the day `run-the-day` | a launch day’s 09:00 slot, every Change still flag-on | Your rule (the plan) | <Op verb="Site.publish" /> the day Page → <Op verb="Post.publish" /> on Leaseline’s Handles → day 5: `launch-week-recap` | nobody; your own posts wait in the tray | the same |
| Swap in the reserve `swap-in-the-reserve` | an open Incident or a revert on a Verb the day names | Agent’s call, with its reason | <Op verb="Site.publish" /> the reserve unit → <Op verb="Post.withdraw" /> any Post on the held unit | nobody; you see it in the day line at 18:00 | the same |
| Tell who asked `tell-who-asked` | a Person whose words asked for the Change, once it is flag-on | Your rule (the Sequence) | `you-asked-it-shipped`: one Message | nobody | the same |
| Not now `not-now` | not flag-on for every Customer for 7 days, no visible diff, or another of your Startups holds that week | Your rule (the gates and the caps) | nothing; names the Flag, the diff or the other week | nobody; the feed reads it again | the same |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | a 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 Acquisition | SDR · your agent, then AE · Priya Shah (person) | 5 min | <Op verb="Lead.create" /> |
| Send me pricing | “Is the owner portal on Pro?” | answered from the live Pricing Page, as it stands at send time | SDR · your agent | 5 min | <Op verb="Conversation.answer" /> |
| Not now | “Thanks, not for us right now.” | nothing more about the week sends to them | nobody | at once | <Op verb="Decision.list" /> |
| Wrong person | “Sending this to our ops lead.” | a one-line thanks; it never writes to an address from their text | Marketing Lead · your agent | 1 business day | <Op verb="Conversation.answer" /> |
| Out of office | an auto-reply to the recap | nothing: the recap carries no follow-up | nobody | — | <Op verb="Decision.list" /> |
| 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 give | you (Dana, person) | 1 business day | <Op verb="Conversation.escalate" /> |
| Stop | “Unsubscribe.” | no recap, note or newsletter sends to them again | nobody | at once | <Op verb="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).

```json title="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 <Op verb="Task.claim" /> (Take this one) and rewrite the row, <Op verb="Task.return" /> with a reason, or <Op verb="Action.redirect" />; a plan with <Op verb="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:** <Op verb="Deal.assign" /> sets `owner` to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.

## When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
| --- | --- | --- | --- |
| <a id="check-owned-by-a-person"></a>`owned-by-a-person` (rule j; Not live yet, gaps #8) | a recap or Message to a Contact whose Lead or open Deal a person owns | Leave it to the person who owns it: the draft waits in their queue. | <Op verb="Task.assign" /> |
| <a id="check-fact-check"></a>`fact-check` (copy rule 2) | a line with a number the Change’s description, its Evidence or a measured Metric lacks | Cut the number, or add it to the Change’s description. | <Op verb="Content.draft" /> |
| <a id="check-flag-gate"></a>`flag-gate` | a Post, Page, recap or listing naming a Change not on for every Customer for 7 days | Wait for full rollout; it joins the next day or the next week. | <Op verb="Decision.list" /> |
| <a id="check-visible-only"></a>`visible-only` | a line, Post or Page for a Change with no diff Customers can see | None: it stays in the internal changelog. | <Op verb="Decision.list" /> |
| <a id="check-drift-hold"></a>`drift-hold` | a day’s sends while a linked surface holds a false claim; the week’s, for the Pricing or a comparison Page | Fix the claim; the sends release once it is true. | <Op verb="Page.update" /> |
| <a id="check-deploy-freeze"></a>`deploy-freeze` | a deploy or a named Flag change from day 1 00:00 to day 5 23:59 | Ship it after day 5, or ship an approved fix in steps; reverts always run. | <Op verb="Approval.approve" /> |
| <a id="check-incident-hold"></a>`incident-hold` | a day that names a Verb with an open Incident | The reserve unit runs instead. | <Op verb="Incident.resolve" /> |
| <a id="check-authorship"></a>`authorship` | an agent sentence for Hacker News | Write it yourself from the fragments. | <Op verb="Task.assign" /> |
| <a id="check-vote-ask"></a>`vote-ask` | any Page, Post or Message that asks anyone to vote, upvote or rank anything | Cut the ask; say what they can now do. | <Op verb="Content.draft" /> |
| <a id="check-portfolio-caps"></a>`portfolio-caps` | a second launch week for one audience in a calendar week, or your Startups launching together | Take the next open week. | <Op verb="Task.next" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-revert-withdraw"></a>`revert-withdraw` | an announced Change is reverted | its Posts withdraw within 1 hour and its day Page gains a dated correction |
| <a id="stop-outage"></a>`outage` | errors over 2 % of requests, or p95 over 3 s for 5 min | the day’s sends and Posts hold |
| <a id="stop-bounce"></a>`bounce` (email) | bounces over 2 % of the recap’s sends | the Mailbox pauses |
| <a id="stop-complaint"></a>`complaint` (email) | complaints near 0.1 % | the recap pauses on every Mailbox |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | every 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.

```json title="The captured refusal · sample"
{
  "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"
    }
  ]
}
```


```json title="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 <Op verb="Metric.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`

| Node | Now (the week, day 1 to day 5 plus 14) | Before (12-week baseline, per 19 days) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `launch-week-icp-visits` | 462 ICP Visitors whose first Visit came from a day Page, a week Post, the recap or the short link | 320, 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-reached` | 1,104 ICP Visitors in the 19 days, every Source | 320 | — | — | 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` · `arr` | carried from `new-arr` | carried | — | — | 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.

```json title="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 option | Decisions | Published or sent | ICP Visitors | Won (credited, not all caused by this Play) |
| --- | --- | --- | --- | --- |
| Write the feed line · Tell who asked | 24 · 6 | 24 lines · 6 Messages | — | 1 Customer from a “you asked” Message |
| Fix the claim | 12 | 9 facts fixed, 3 rows rewritten by you | — | — |
| Plan the week · Run the day · Swap in the reserve | 1 · 5 · 1 | 5 day Pages, 10 Handle Posts, 187 recaps | 462 | 4 Customers |
| Not now | 8 | 0 | — | — |
| **All** · 12-week baseline, per 19 days | **57** | — | **462** · 320 | **$2,329** · $694 |
| At 1 week a quarter (the Use it when volume) | about 60 a quarter | 1 week | before-after, not proof | Other Startups’ results: +150 per week, ■■■□ Likely, n 380 |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_130` Campaign.created | the three steps; dry run fails `change-feed` | 20 min |
| 1 | `event_141` Change.merged | the first drift sweep: 3 false claims, all fixed by day 4 | 15 min |
| 8 | `event_270` Approval.approved | you accepted the plan: 5 days, 1 reserve, freeze Sep 28 to Oct 2 | 30 min |
| 28 · 53 | `event_538` Change.merged · `event_890` Readout.created | integrations on day 2: replayed at about 450, read back at day 5 plus 14 at 462, n 1 | 5 min |
| 35 | `event_610` Site.published | day 1: per-owner renewal batches; the first week-sourced signup at 09:40 | 20 min |
| 38 | `event_655` Campaign.paused | `revert-withdraw`: `change_37` reverted at 11:12; its Post withdrew at 11:31 and the reserve ran | — |
| 1–56 | `event_145` Task.assigned, first of 18 | you accepted 1 plan, rewrote 3 rows and sent 10 of your own posts, from the <Op verb="Task.next" /> log | 4.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.

```diff title="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
```mdx title="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 | <a id="tactic-shipped-code-feed"></a>`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 | <a id="tactic-claim-drift"></a>`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 | <a id="tactic-launch-week-plan"></a>`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 | <a id="tactic-launch-week-kit"></a>`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 | <a id="tactic-launch-week-day"></a>`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 | <a id="tactic-deploy-freeze"></a>`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 | <a id="tactic-launch-week-readout"></a>`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 | <a id="tactic-claims-check"></a>`claims-check` | Claims check maps every draft sentence to an approved source or the Person’s own words, and holds anything else before it reaches anyone. Starts at Sends nothing. |
| Tactic | <a id="tactic-send-gate-check"></a>`send-gate-check` | Send gate check: Checks Suppression, a live reason, the Market, the basis stamp, the Person-month grant, the facts and the labels before any cold Message exists. Starts at Sends nothing. |
| Tactic | <a id="tactic-first-person-draft"></a>`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 | <a id="tactic-launch-readiness-gate"></a>`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 | <a id="trigger-change-merged"></a>`change-merged` | Change merged: `event` on `Change.merged`, window 7d. |
| Trigger | <a id="trigger-change-flag-on"></a>`change-flag-on` | Change flag-on: `state` on `Flag.evaluated`, window 90d. |
| Trigger | <a id="trigger-claim-drift"></a>`claim-drift` | Claim drift: `event` on `Change.merged`, window 1d. |
| Trigger | <a id="trigger-change-reverted"></a>`change-reverted` | Change reverted: `event` on `Change.reverted`, window 1h. |
| Trigger | <a id="trigger-launch-week-due"></a>`launch-week-due` | Launch week due: `at` on `Period.opened`, window 30d. |
| Trigger | <a id="trigger-category-launch-week"></a>`category-launch-week` | Category launch week: `event` on `Organization.announced`, window 30d. |
| Trigger | <a id="trigger-launchable-change"></a>`launchable-change` | Launchable change: `event` on `Version.deployed`, window 30d. |
| Trigger | <a id="trigger-loss-reason-resolved"></a>`loss-reason-resolved` | Loss reason resolved: `event` on `Version.deployed`, window 30d. |
| Trigger | <a id="trigger-week-sourced-signup"></a>`week-sourced-signup` | Week-sourced signup: `event` on `Visitor.identified`, window 19d. |
| Sequence | <a id="sequence-launch-week-recap"></a>`launch-week-recap` | Launch week recap: 1 steps; it ends on Opt-out; Signup. |
| Sequence | <a id="sequence-you-asked-it-shipped"></a>`you-asked-it-shipped` | You asked, it shipped: 1 steps; it ends on Opt-out. |
| Sequence | <a id="sequence-week-signup-follow-up"></a>`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. |