URL: /plays/video-ladder · Id: `play:video-ladder`

# Video ladder

> Lifts each video idea from free posts to paid ads to a reshoot by a person, spending only on what the rung below proved.

Lifts each video idea from free posts to paid ads to a reshoot by a person, spending only on what the rung below proved.

```text title="Set it up · Ask"
Be our Content Lead: turn each fact our pages back into short videos, label every one as made with AI, and post on our own Handles; draft TikTok and Instagram for me to publish. Promote only what clears the screen with signups, up to $300 a month, and ask me to reshoot only the winners. Show me what’s missing; don’t send.
```

```text title="Run one · Ask"
Hand our latest Post that cleared the screen to the Content Lead agent and show me what it chose and why. Don’t send.
```

```ts title="Run one · SDK"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Fact.recorded", "Experiment.concluded", "Post.published", "Comment.posted", "Monitor.checked")', 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_363",
    "$type": "Decision",
    "choice": "promote-it",
    "reason": "the “renewal calendar in 20 seconds” Short cleared the 72-hour screen: 61 % completion against the Handle’s 38 % median, 9 coded signups from 31,000 views",
    "stakes": "high",
    "options": [
      "draft-the-cut",
      "promote-it",
      "reshoot-it",
      "answer-the-comment",
      "retire-the-format",
      "refresh-the-ad"
    ],
    "by": "worker_8",
    "on": "post_88",
    "expected": "20 coded signups from the promoted cut within 28d",
    "reopensWhen": "the promoted cut’s coded signups per 1,000 fall under the organic rate for 3 days"
  },
  "actions": [
    {
      "$id": "https://api.sb/leaseline.app/actions/action_1",
      "$type": "Action",
      "status": "done",
      "mode": "try",
      "by": "worker_8",
      "verb": "Metric.query",
      "checks": []
    },
    {
      "$id": "https://api.sb/leaseline.app/actions/action_2",
      "$type": "Action",
      "status": "pending",
      "reason": "awaitingApproval",
      "mode": "try",
      "by": "worker_8",
      "verb": "Ad.create",
      "checks": [
        {
          "check": "claims-resolve",
          "status": "pass"
        },
        {
          "check": "disclosure",
          "status": "pass"
        },
        {
          "check": "distinctness",
          "status": "pass"
        }
      ]
    }
  ]
}
```

`action_2` is the promoted cut at $10 a day for 14 days, inside promote-winners; it waits for your approval because it spends.

`0.29 coded signups per 1,000 views against 0.14 before · before-after, not proof · n 61 · path → arr`

| Try another: the Post | Choice | Reason |
| --- | --- | --- |
| The “renewal calendar in 20 seconds” Short: 61 % completion, 9 coded signups | `promote-it` | cleared the screen with signups |
| The YouTube Handle’s 09:00 slot is empty; a new fact: notices now go by text | `draft-the-cut` | an empty slot and a new fact |
| A promoted cut: 14 coded signups, payer rate 1.1 times your baseline | `reshoot-it` | a paid winner at or over your payer rate |
| “Does it send notices in Spanish?” under a Short | `answer-the-comment` | the claims source says yes |
| Photo slideshows: 0.62 times the median on 6 Posts | `retire-the-format` | under 0.8 times on 6 in a row |

| Worth | Your time | Spend | First signal | Use it when | Instead |
| --- | --- | --- | --- | --- | --- |
| ≈ +$530 ARR a month at 115,000 views | 30 min week 1 (claims source and Handles), then 20 a week (you publish 3 drafts) | $0.60 per cut rendered, ~$15 a month at 26; ads under your $300 Limit | Day 4: first coded signup | 2+ Handles, 10+ live facts in your claims source | Under 10 facts: add them (<Op verb="Content.create" />) · no short-video Handle: `founder-voice` |

**Where it sits:** **Stranger** → Lead → Trialing → Activated → At risk → Churned → Won back · Video sign-ups per 1,000 views → New Leads → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +0.11 coded signups per 1,000 views (Other Startups’ results; no lift of your own yet) × 115,000 views a month × 0.12 paid per signup × $347 first order ARR ≈ +$527. Under First signal: At about 33 coded signups a month, 90 days can tell only a doubling against your own before, so it reads before-after.

`sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Post.published · first cut drafted 22 min after the empty slot · 8 keys Not live yet`

## Start it this week
```bash
npx startup-builder add play video-ladder   # 1 · writes plays/video-ladder.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":"video-ladder"}'

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

# on
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/enable \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

# off: no cut renders or posts; live Posts stay up
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/pause \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```


```json title="The dry run’s 422 · 2026-08-24 · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "video-ladder can’t start yet: 1 check fails and 2 warn.",
  "checks": [
    {
      "check": "use-when",
      "status": "pass",
      "observed": "3 Handles connected: YouTube, LinkedIn, X",
      "doc": "/plays/video-ladder#check-use-when",
      "fix": "Nothing to fix: 2 or more Handles.",
      "then": "Metric.query"
    },
    {
      "check": "approved-pages",
      "status": "fail",
      "observed": "4 live facts in the claims source; a cut needs 10 to draw from",
      "doc": "/plays/video-ladder#check-approved-pages",
      "fix": "Add 10 facts your pages back to the claims source; cuts quote only those.",
      "then": "Site.publish"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "2 coded signups from 9 founder videos, 14,000 views in 90 days",
      "doc": "/plays/video-ladder#check-baseline",
      "fix": "n 2: it reads before-after, not proof, against your own videos.",
      "then": "Metric.query"
    },
    {
      "check": "role-unstaffed",
      "status": "warn",
      "roles": [
        "video-producer",
        "paid-media-manager"
      ],
      "owned": 0,
      "doc": "/plays/video-ladder#check-role-unstaffed",
      "fix": "Staff paid media, or leave it: hand publishing and every ad come to you.",
      "then": "Role.staff"
    }
  ]
}
```

| Check | Fix (one call) | Your time | Wait |
| --- | --- | --- | --- |
| <a id="check-use-when"></a>`use-when` · pass: 3 Handles connected (gaps #8) | <Op verb="Metric.query" /> on `video-signups`; <Op verb="Handle.connect" /> adds one | 1 min | none |
| <a id="check-approved-pages"></a>`approved-pages` · fail (Not live yet): 4 live facts of 10 | <Op verb="Site.publish" /> the pages that back 6 more facts, then add them | 20 min | none |
| <a id="check-baseline"></a>`baseline` · warn: 2 coded signups from 14,000 views | <Op verb="Metric.query" />; it fills Before in Your number | 0 min | none |
| <a id="check-role-unstaffed"></a>`role-unstaffed` · warn: no person produces video or runs paid media | <Op verb="Role.staff" />, or leave it: TikTok and Instagram drafts and every ad come to you | 0 min | none |

`Your number · Before 0.14 per 1,000 views · Now 0.29 coded signups per 1,000 views · Target 0.35 by Dec 31 · before-after, not proof · n 61 signups`

Each cut costs about $0.60 to render and check (Worker cost), under a $50 monthly render Limit; ads spend inside promote-winners under your $300 monthly Limit. That came to $29 in renders and $180 in ads over 56 days.

## When it starts
| When | Trigger id | Starts on | Window | How it gets in |
| --- | --- | --- | --- | --- |
| A Handle’s next slot within 24 hours holds no cut | `slot-empty` | `state` on `Post.published` where handle.nextSlotAt < now + 24h and handle.queued = 0 | a state, read each hour | <Op verb="Handle.connect" /> for each Venue |
| A Post’s 72-hour completion clears the screen at its minimum sample | `screen-pass` | `threshold` on `Post.published` where completion72h >= the screen and views >= the minimum sample | 7d | the Venue’s Post analytics through <Op verb="Handle.connect" /> |
| A public comment asks what the claims source answers | `comment-question` | `event` on `Comment.posted` where asks a question the claims source answers | 48h | the Venue’s comments through <Op verb="Handle.connect" /> |
| + 3 more for new facts, won angles and tired ads (`?lanes=all`) | | | | |

```json title="One signed delivery · StartupBuilder-Signature"
{
  "$id": "https://api.sb/leaseline.app/events/event_1322",
  "$type": "Event",
  "name": "Post.published",
  "at": "2026-10-19T09:00:12Z",
  "seq": 1322,
  "data": {
    "post": "post_88",
    "handle": "youtube",
    "views": 31000,
    "completion72h": 0.61,
    "handleMedian": 0.38,
    "codedSignups": 9
  }
}
```

```bash title="Reproduce it in test"
npx startup-builder trigger Post.published --like event_1322   # replays the screen read
npx startup-builder clock advance --by 3d   # reads the promoted cut’s first 3 days
npx startup-builder listen Post.published --forward-to http://localhost:3000/hook
```

## Who runs it
**Content Lead · your agent** (`role:content-lead`, `worker_8`) holds the Key Result: it drafts each cut from live facts, posts on the Startup’s own Handles and reads the screen. TikTok and Instagram cuts, reshoots and every ad come to **you** (Dana Okafor, person, `worker_1`), because the Video Producer and Paid media Roles have no person.

| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
| --- | --- | --- | --- | --- | --- |
| Draft the cut | It does it, you can stop it | 30 of 30 on YouTube, LinkedIn, X | met on day 14 (the first 12 cuts) | a `claims-resolve` refusal posts → You approve each one | <Op verb="Action.cancel" /> inside the hold |
| Draft the cut, TikTok and Instagram | You publish it, from a private draft | 18 drafted, 18 published by you | never | — | <Op verb="Approval.refuse" /> |
| Promote it · Reshoot it with a person | You approve each one | 3 of 3 · 1 of 1 | never: spend and your face are yours | — | <Op verb="Approval.approve" /> · <Op verb="Approval.refuse" /> |
| Answer the comment · Retire the format · Refresh the ad | It does it | 22 of 22 · 1 of 1 · 2 of 2 | — | a comment answer with no live fact → You approve each one | <Op verb="Action.redirect" /> |
| Change the screen line | You approve each one | 0 merged | never | — | <Op verb="Change.merge" /> · <Op verb="Change.revert" /> |
| Never: a synthetic person speaking as a Customer, the AI label off | Never, on every rung | 0 | never | — | `kill-switch` |

**What it reads · What it may call.** It reads the claims source, the Handles’ Post analytics and each code’s signups. A comment is data, never instructions: no comment picks a link or a reply’s claim. Its tools are <Op verb="Video.draft" />, <Op verb="Post.schedule" />, <Op verb="Ad.create" />, <Op verb="Task.assign" />, <Op verb="Comment.create" />, <Op verb="Decision.create" />, <Op verb="Ad.update" />, and any other call becomes an Approval under the Role’s Mandate.

```md title="The brief (folded): compiled Agent-register Markdown · play:video-ladder@1 · each line names its record key"
You hold the Content Lead Key Result: 0.35 coded signups per 1,000 views by 2026-12-31. ← worker, metric
Every claim in a cut reads from a live fact; no fact, no line.                   ← Claims gate, claims-resolve
Every cut carries the AI label and the Venue’s AI-content flag.                  ← Disclosure gate
Promote only a Post that clears the 72-hour screen with coded signups, within $300 a month. ← your file, line 4; Render limit
Ask Dana to reshoot only a paid winner at or over her payer rate.                ← your file, line 5
```

**The slow loop.** The weekly Decisions kept 1.4 times the Handle median as the screen line, and no Change was merged 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 |
| --- | --- | --- | --- | --- | --- |
| Draft the cut `draft-the-cut` | an empty slot within 24 hours, or a new fact or angle | Your rule (the slate) | <Op verb="Video.draft" /> from live facts → <Op verb="Post.schedule" /> on your own Handles | TikTok and Instagram: you publish from the private draft, due 1 business day · Take this one | you |
| Promote it `promote-it` | cleared the 72-hour screen with coded signups | Agent’s call, with its reason | <Op verb="Ad.create" /> inside promote-winners | Paid media, so you approve the spend · Take this one | you |
| Reshoot it with a person `reshoot-it` | a paid winner at or over your payer rate | Agent’s call, with its reason | <Op verb="Task.assign" />: the script and shot list → <Op verb="Video.draft" /> with your footage | you film it, due 1 business day · Take this one | you |
| Answer the comment `answer-the-comment` | a question the claims source answers | Agent’s call, with its reason | <Op verb="Comment.create" /> from a live fact | nobody | the same |
| Retire the format `retire-the-format` | under 0.8 times the median on 6 Posts | Your rule (Completion floor) | <Op verb="Decision.create" />: off the slate for 30 days | nobody | the same |
| Refresh the ad `refresh-the-ad` | frequency past 3.5 while clicks fall 3 days | Your rule (the paid rung) | <Op verb="Ad.update" /> with a new open → <Op verb="Video.draft" /> | nobody | the same |

| When they write back | Fixture reply | What happens | Who answers | By when | Call |
| --- | --- | --- | --- | --- | --- |
| Interested | a comment: “How do I try this?” | answers with the coded signup link | Content Lead · your agent | 1 h | <Op verb="Comment.create" /> |
| Send me pricing | a comment: “How much is it?” | answers with the Pricing Page’s list Price, $29 a month | Content Lead · your agent | 1 h | <Op verb="Comment.create" /> |
| Not now | a comment: “Maybe when we grow.” | nothing more; a public comment gets no follow-up | nobody | at once | <Op verb="Decision.list" /> |
| Wrong person | a comment: “My office manager should see this.” | one answer to the commenter; nothing goes to the person they named | Content Lead · your agent | 1 h | <Op verb="Comment.create" /> |
| Out of office | a comment: “Away until the 28th, remind me.” | no reminder is sent; the Post stays up | nobody | at once | <Op verb="Decision.list" /> |
| Question it can’t answer | a comment: “Does it work with our accounting system?” | To you; nothing is answered in public until you do | you | 1 business day | <Op verb="Task.assign" /> |
| Stop | a comment: “Stop showing me these ads.” | that viewer leaves the paid list | nobody | at once | <Op verb="Audience.update" /> |

## When it hands to you
TikTok and Instagram drafts, reshoots and every ad come to **you**. One Brief per Role, as captured (`brief` is Not live yet, gaps #7).

```json title="What lands in each queue · sample"
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_538",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-16T17:00:00Z",
    "on": "post_81",
    "brief": {
      "who": "the “60 days out, every owner” cut",
      "chose": "reshoot-it",
      "why": "promoted: 14 coded signups, payer rate 1.1 times your baseline",
      "script": "3 lines, 20 seconds, your phone in portrait",
      "never": [
        "a line no live fact backs",
        "a Customer’s words without their Consent"
      ]
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/approvals/approval_63",
    "$type": "Approval",
    "verdict": null,
    "deadline": "2026-10-20T17:00:00Z",
    "draft": "Promote post_88: $10 a day for 14 days, inside promote-winners",
    "route": "promote-it",
    "checks": [
      {
        "check": "claims-resolve",
        "status": "pass"
      },
      {
        "check": "disclosure",
        "status": "pass"
      }
    ]
  }
]
```

You answer with <Op verb="Approval.approve" /> or <Op verb="Approval.refuse" />, or take a Task with <Op verb="Task.claim" /> (Take this one) or hand it back with <Op verb="Task.return" />, each a one-call window. An ad Approval unanswered by its deadline expires, and nothing is spent.

**On time:** you, 18 of 18 private drafts published within 1 business day, median 5 h, and 4 of 4 Approvals answered, n 22, ■■□□ Early sign. **Your queue:** in week 1, 6 facts to add and 4 drafts to publish; then about 3 drafts a week and 1 ad every 2 weeks.

**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-claims-resolve"></a>`claims-resolve` (hub guard on <Op verb="Post.publish" />) | a cut with a claim that reads from no live fact | Cut the claim, or name the record that backs it. | <Op verb="Content.draft" /> |
| <a id="check-disclosure"></a>`disclosure` (the record’s Disclosure gate) | an upload whose AI flag and on-screen labels differ from the cut’s disclosure manifest | Set the Venue’s AI flag and the on-screen label, then upload. | <Op verb="Post.schedule" /> |
| <a id="check-testimonial"></a>`testimonial` (the record’s Testimonial gate) | a first-person experience line from a synthetic speaker, or a person without Consent | Cut the line, or record a person who gave Consent. | <Op verb="Video.draft" /> |
| <a id="check-distinctness"></a>`distinctness` (the record’s Distinctness gate) | a cut too close to one on the same Handle in 90 days | Draft a new open or a new fact. | <Op verb="Video.draft" /> |

| Stop (pauses the Play) | Pauses when | Then |
| --- | --- | --- |
| <a id="stop-strike"></a>`strike` | a Venue strike, label, removal or reach-limit notice | the Play pauses on that Handle; the format is held everywhere within 1 h |
| <a id="stop-suspended-handle"></a>`suspended-handle` | a Handle is suspended | its lanes pause; you are told |
| <a id="stop-completion-floor"></a>`completion-floor` | a format under 0.8 times the Handle median on 6 Posts in a row | the format leaves the slate for 30 days |
| <a id="stop-signup-floor"></a>`signup-floor` | a format with 50,000 views and no coded signup | it stops until a new angle reaches it |
| <a id="stop-payer"></a>`payer` | 20 signups in 7 days with a payer rate under half your baseline | the draft loop pauses; <Op verb="Task.assign" /> an Offer review to you |
| <a id="stop-refund-spike"></a>`refund-spike` | refunds or same-day cancels from video signups at twice your baseline | every ad and the paid list pause |
| <a id="stop-comment"></a>`comment` | comments calling a format fake over 5 %, on 2 Posts in a week | the format returns to You approve each one |
| <a id="stop-drift"></a>`drift` | a live ad differs from its approved cut | the ad pauses on the daily read |
| <a id="stop-spend-limit"></a>`spend-limit` | render and model spend reach the monthly Limit | the batch holds; <Op verb="Limit.raise" /> for you |
| <a id="stop-kill-switch"></a>`kill-switch` | you press it | <Op verb="Process.pause" /> on `content-marketing`; every draft and ad pauses |

The captured refusal, then the Stop that fired as a `Campaign.paused` reason (Not live yet, gaps #2); the rewrite that posted is the “hours a week” thread in Example.

```json title="The captured refusal · sample"
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The cut “hours back every week” did not post: it says property managers save 10 hours a week, and no live fact says so.",
  "checks": [
    {
      "check": "claims-resolve",
      "status": "fail",
      "doc": "/plays/video-ladder#check-claims-resolve",
      "fix": "Cut the claim, or name the record that backs it.",
      "then": "Content.draft"
    },
    {
      "check": "disclosure",
      "status": "pass"
    }
  ]
}
```


```json title="The Stops that fired, as Campaign.paused reasons · sample"
[
  {
    "reason": {
      "limit": "completion-floor",
      "observed": "0.62 times the Handle median on 6 Posts",
      "bound": "0.8 times",
      "window": "6 Posts"
    },
    "doc": "/plays/video-ladder#stop-completion-floor",
    "task": "task_490"
  }
]
```

## Did it work
Organic feeds cannot be split at random, and 61 signups in 56 days is under the volume for alternating weeks, so the basis is before-after (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).

`0.29 coded signups per 1,000 views against 0.14 before · before-after, not proof · n 61 · path → arr`

| Node | Now (56 days) | Before (the 90 days, per 56) | Added | Confidence | Basis |
| --- | --- | --- | --- | --- | --- |
| `video-signups` | 0.29 per 1,000 views: 61 coded signups from 212,000 views, 48 Posts | 0.14: 2 from 14,000 views, 9 founder videos | — | — | before-after, not proof · Other Startups’ results +0.11 per 1,000, ■■■□ Likely, n 6,800 Posts |
| `new-leads` | 61 coded signups | 1.2 (2 in 90 days, per 56) | — | — | before-after |
| `new-arr` ↑ | $2,429, 7 Customers on Pro · Booked: credited, not all caused by this Play | $216 | — · Worth about +$530 a month | — | before-after · 2 trials still deciding |
| `net-new-arr` · `arr` | carried from `new-arr` | carried | — | — | carried |

The leaf counts signups whose Acquisition carries a Post’s link code, or whose first checkout redeems its promotion code, per 1,000 Video views over 30 days. Before against after is not proof, and Other Startups’ results print beside it.

**How it moves it:** each idea earned its next dollar on the rung below: 48 free cuts, 3 promoted for $180, 1 reshot by Dana; the 3 promoted cuts brought 19 of the 61 signups.

**Guardrails:** before against after: payer rate, 11 % of video signups against your 13 % baseline, refunds and same-day cancels from video signups, 0 of 7, and comments calling a format fake, 0.4 % against a 5 % floor.

```json title="The Campaign card · sample"
{
  "$id": "https://api.sb/leaseline.app/campaigns/video-ladder",
  "$type": "Campaign",
  "play": "play:video-ladder@1",
  "path": [
    "video-signups",
    "new-leads",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "video-signups",
    "unit": "per-1000",
    "heldBack": 0,
    "decision": null
  },
  "readout": {
    "value": null,
    "n": 61,
    "maturing": 9,
    "interval": null,
    "readability": "inadmissible",
    "basis": "before-after",
    "pooled": true
  },
  "ledger": {
    "spend": 180,
    "workerCost": 29,
    "hours": 4.2,
    "pipelineArr": 694,
    "wonArr": 2429,
    "projectedArr": 527,
    "paybackDays": 22
  }
}
```

Outside benchmark: short business videos hold a median 34 % of viewers to the end (a video analytics firm’s study of 1.1M Posts, 2026-08-31).

**Before it · After it.** Before it: `signup-interviews` and `editorial-seo` supply the facts and angles that won elsewhere. After it: `promote-winners` runs the paid rung, `paid-social` and `creator-ads` hear the winners, and `instant-response` answers the signups who write in.

## Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): 48 cuts from 14 live facts, 212,000 views, 61 coded signups, 3 cuts promoted for $180 and 1 reshot by Dana. Read every captured thread at `?threads=all`; three follow the tables.

| What happened, by option | Decisions | Views or signups | Won (credited, not all caused by this Play) |
| --- | --- | --- | --- |
| Draft the cut | 48: 30 posted on your Handles, 18 published by you | 212,000 views, 42 coded signups | 4 on Pro (+$1,388 ARR) |
| Promote it · Reshoot it with a person | 3 · 1 | 19 coded signups for $180 · the reshoot runs from Oct 17 | 3 on Pro (+$1,041 ARR) |
| Answer the comment · Retire the format · Refresh the ad | 22 · 1 · 2 | 22 answers from live facts · slideshows off for 30 days · 2 new opens | 2 trials still deciding |
| At 2 Handles (the Use it when volume) | about 30 cuts in 56 days | before-after, not proof | Other Startups’ results: +0.11 per 1,000, ■■■□ Likely, n 6,800 Posts |

| Day | Event | What happened | Your time |
| --- | --- | --- | --- |
| 0 | `event_119` Campaign.created | the three steps; dry run fails `approved-pages`: 4 live facts | 10 min |
| 0 | `event_127` Content.created | you added 10 facts your pages back | 20 min |
| 4 | `event_180` Acquisition.created | the first coded signup, from a YouTube Short | — |
| 14 | `event_402` Role.updated | promoted: cuts on your own Handles post after a 2-minute hold | — |
| 19 | `event_455` Action.refused | `claims-resolve` refused “hours back every week”; rewritten once and posted | 5 min |
| 33 | `event_612` Campaign.paused | `completion-floor`: slideshows off the slate for 30 days | — |
| 1–56 | `event_131` Task.assigned, first of 22 | you published 18 drafts and approved 4; weekly reviews, from the <Op verb="Task.next" /> log | 3.7 h · **total 4.2 h measured, 4.4 h asked** |

> **YouTube Short, Oct 16, 09:00** · “Renewal calendar in 20 seconds”: Leaseline sends every renewal notice 60 days out, per owner.¹ Made with AI, labeled on screen and in the Venue’s AI flag.²
>
> **Oct 19, 09:00** · 61 % completion against a 38 % median, 9 coded signups from 31,000 views; `decision_363` chose Promote it, and the ad waits for your approval (`approval_63`).

```diff title="“Hours back every week”, 2026-09-12 · the cut claims-resolve refused, then the rewrite that posted"
- Property managers save 10 hours a week with Leaseline.
+ Leaseline drafts every renewal notice for you, 60 days out, per owner.
```

> **The “60 days out, every owner” cut, 2026-10-15 16:00** · promoted: 14 coded signups at 1.1 times your payer rate · the reshoot Brief reached Dana (`task_538`) with a 3-line script, due Oct 16 17:00; **she filmed it at 12:30 on Oct 16**, and it runs from Oct 17.

¹ The line reads from a live fact in the claims source. ² The disclosure manifest, matched before upload.

## Your settings
```mdx title="plays/video-ladder.mdx"
---
holdout: 0        # organic feeds cannot be split; it reads before-after
---
Promote only a Post that clears 1.4 times the Handle median with coded signups, up to $300 a month.
Ask me to reshoot only a paid winner at or over my payer rate.
```

```text
$ npx startup-builder show plays/video-ladder
holdout 0 · screen 1.4 times the median · ads $300 a month     your file  plays/video-ladder.mdx:2,4,5 (Ask 2026-08-24)
family demand · process content-marketing · worker role:content-lead, owns never · chooses 6 (3 rule, 3 read) · sequences none · checks claims-resolve, disclosure, testimonial, distinctness · stops 10 · placements tiktok, instagram, facebook, youtube, linkedin, x    catalog  play:video-ladder@1 (Not live yet, gaps #5)
```

### Every key from the catalog
| Key | Id | What it is |
| --- | --- | --- |
| Tactic | <a id="tactic-fact-bound-render"></a>`fact-bound-render` | Fact-bound render turns one distinct premise into a native cut per format, every claim linked to a sourced fact and disclosure compiled from each take. Starts at Sends nothing. |
| Tactic | <a id="tactic-draft-loop"></a>`draft-loop` | Consumer draft loop uploads each cut as a private, labeled draft that a human finishes with a native sound and publishes, then reads it back. Starts at You approve each one. |
| Tactic | <a id="tactic-organic-screen"></a>`organic-screen` | Organic screen posts each cut once, reads completion at 72 hours and coded sign-ups at 7 days, and moves winners one rung up. Starts at It does it, you can stop it. |
| Tactic | <a id="tactic-paid-handoff"></a>`paid-handoff` | Paid hand-off turns a dedicated-Handle winner and its reshoot into a promote-winners hand-off record, and reads each paid verdict back. Starts at Sends nothing. |
| Tactic | <a id="tactic-human-reshoot"></a>`human-reshoot` | Human reshoot gives every winning cut a phone-shot version by the founder, a consenting Customer or a disclosed creator, run as its own Variant. Starts at Sends nothing. |
| Tactic | <a id="tactic-creative-drift-monitor"></a>`creative-drift-monitor` | Creative drift monitor reads every live Ad each day, diffs it against its approved cut and settings, and pauses any Ad that changed. Starts at Sends nothing. |
| Tactic | <a id="tactic-winner-promotion"></a>`winner-promotion` | Winner promotion runs a free-placement winner as a paused, fenced Ad against its control, and judges it on counted conversions from Stripe. Starts at You approve each one. |
| Tactic | <a id="tactic-tier-gate"></a>`tier-gate` | Tier gate holds a winner’s spend at its tier until a holdout shows incremental conversions per $100 clear breakeven, and re-reads every placement each quarter. Starts at You approve each one. |
| Trigger | <a id="trigger-fact-new"></a>`fact-new` | New or changed fact: `event` on `Fact.recorded`, window 14d. |
| Trigger | <a id="trigger-angle-won"></a>`angle-won` | Angle won: `event` on `Experiment.concluded`, window 30d. |
| Trigger | <a id="trigger-slot-empty"></a>`slot-empty` | Empty publishing slot: `state` on `Post.published`, window 24h. |
| Trigger | <a id="trigger-screen-pass"></a>`screen-pass` | Screen pass: `threshold` on `Post.published`, window 7d. |
| Trigger | <a id="trigger-comment-question"></a>`comment-question` | Comment question: `event` on `Comment.posted`, window 48h. |
| Trigger | <a id="trigger-ad-fatigue"></a>`ad-fatigue` | Ad fatigue: `threshold` on `Monitor.checked`, window 3d. |
| Benchmark | <a id="benchmark-ai-ad-click-parity"></a>`ai-ad-click-parity` | Raw click rate of AI-made ads against human-made ads from the same advertiser on the same day: 0.65–0.76 % (Columbia, Harvard, Carnegie Mellon and TU Munich field study on a native-ad network, 2026-01-29). |
| Benchmark | <a id="benchmark-disclosure-purchase-intent"></a>`disclosure-purchase-intent` | Share of young US consumers who say AI disclosure raises or does not change their purchase intent: 73 % (IAB consumer survey The AI Gap Widens, 2026-01-15). |