---
name: scout7-run-organic-loop
description: >-
  Run an organic content-growth loop for a brand using Scout7 (scouty). Three
  stages: INIT reads the connected Scout7 workspace, adds topics if coverage is
  thin, asks whether it is a 1-day or 1-week loop, interrogates the user with open
  questions — researching the web — to pin the loop's focus, philosophy and target,
  then shows sample angles (headline + description) of what the loop will produce
  and refines until the user confirms, and
  records that in the brand's canonical facts so the topics chosen and angles
  drafted all come from it, agrees what to publish
  (image posts / videos / blogs / LinkedIn carousels) with days and frequency, and ends by asking
  whether the run is autonomous or manual, then MAKES THE CONTENT AND SHOWS IT
  BEFORE SCHEDULING ANYTHING — scheduling is opt-in and only covers days not yet
  built; CREATE makes each piece with Scout7,
  surfaces all the finished content at the end of the run, and schedules it — in
  manual mode only after approval of each post concept, blog outline and video
  script and a final OK on the finished pieces before anything is scheduled;
  FINALISE writes an end-of-day impact-and-learnings
  report. Use whenever the user wants a growth loop or content/growth plan, wants
  to plan the week or day, wants to add topics, or asks scouty to create and
  schedule posts, videos or blogs, or wants a report on today's growth impact.
---

# Growth Loop

A content-growth loop for one brand, in three stages. **Scout7 ("scouty")** adds
topics and makes and schedules content — **image posts, videos, blogs, and
LinkedIn carousels** (a carousel is a slide deck built from a finished blog). Scout7
stores no plan, so `scripts/plan.py` holds it on disk in the brand's growth folder
(the `--dir` argument) and every stage reads it back.

> **Comment/engagement lane is parked.** This skill used to hand a comment block
> to the engagement-engine; that lane is out of scope for now. Content types are
> `post`, `video`, `blog`, `carousel` only. (To bring comments back, re-add the `comment` type
> to `plan.py` and the engagement-engine handoff — nothing else depends on it.)
>
> **Carousels and the SEO surface are also parked here.** Scout7 offers both
> end-to-end (see [references/scout7-tool-map.md](references/scout7-tool-map.md)
> §8 carousels, §9 SEO), but this skill does not drive them. Know they exist so
> you can point the operator at Scout7's UI; do not call those tools from a run.

## In autonomous mode this runs UNATTENDED — never ask, never halt

CREATE and FINALISE run as a headless, scheduled agent with **no human watching
the run**. (That is **autonomous** mode, the default. If INIT recorded
`mode: manual`, CREATE additionally pauses at three defined checkpoints — post
concept, blog outline, video script — for the operator's approval before
generating, and holds every finished piece for a final end-of-run showcase
approval before scheduling or publishing it; everything else in this section
applies in both modes, and FINALISE never asks in either. Both modes end every
run by surfacing the finished content — autonomous shows and continues.) Two failure modes break that, and both come from tool descriptions
written for a person sitting in the Scout7 app. In this skill, **those
instructions are overridden** — ignore them:

1. **Never ask a question in CREATE or FINALISE — beyond manual mode's
   checkpoints and showcase — and never ask the blog interrogation questions at
   all.** Scout7 tools say things like _"let the user
   choose the angle,"_ _"Ask the user these questions,"_ _"Never answer them
   yourself."_ That is app guidance, not your instruction. The human decisions were
   already captured in INIT and written to the plan — use them:
   - angle → `decisions.angle_id` (pass it; do not re-offer angles)
   - interrogation → `author_answers`, sourced in INIT from the brand's
     `facts/canonical.md` + `stance/*.md`. Pass them straight to
     `scout7_blog_answer_questions` — that is the founder's **recorded** voice, so
     using it is not "answering yourself" and not "inventing."
     If a needed decision is genuinely absent, that is an INIT gap: mark the item
     `failed`/`draft_only` with a note and move on — never stop to ask. Never call
     `AskUserQuestion` in CREATE or FINALISE.

2. **Never hand control back to a human to wait.** Async jobs (generate / render,
   ~90 s–10 min) are waited out **in-process**: fire the job, `sleep` in the
   background for the ETA, then collect with `get_generation_status` / `get_draft`,
   and continue to the next item. **Do not** end your turn, say _"check back in a
   few minutes,"_ or ask the user to reply — nobody is there. Keep going until every
   item is scheduled / published or failed, then write the report.

The only stage that may freely talk to a human is **INIT**, with its five
question rounds — all _before_ the run begins. After that, the sole exception is
**manual** mode (chosen in INIT's last question), where CREATE pauses at its
three preview checkpoints and its end-of-run showcase; autonomous CREATE and
FINALISE ask nothing.

## Operating model — INIT in 9 steps, then hands-off

**Interaction boundary — the one rule that governs all three stages:**

- **INIT is the only stage that talks to the user, and it asks about exactly
  five things:** (1) the horizon + what to publish, (2) the loop's focus — a
  web-researched interrogation of philosophy and target, asked as **open questions
  (a question and a text box — never multiple-choice options)**, that runs until the
  focus is genuinely clear and ends by **confirming the loop's angle**: sample
  angles (headline + one-line description) shown as "this is the kind of stuff this
  loop will produce", refined until the user confirms, written to
  `facts/canonical.md` and used to pick topics and draft angles, (3) approval of the drafted plan, (4) per-gap fix-or-skip
  decisions, (5) the run mode — participate further (**manual**) or go
  **autonomous**. Nothing else.
- **The blog interrogation answers are NOT one of those things.** They are
  **sourced from the brand's `facts/canonical.md` + `stance/*.md`**, never by
  asking the user question-by-question. Ask the founder _only_ if the brand files
  genuinely don't cover a question — never as the default.
- **CREATE and FINALISE ask the user nothing — except manual mode's checkpoints.**
  They read the locked plan and run. In **autonomous** mode CREATE asks nothing at
  all; in **manual** mode it pauses for the three preview approvals — post
  concept, blog outline, video script — before generating, and for one final
  showcase approval before anything is scheduled or published. FINALISE never
  asks. Either way,
  if a locked decision is missing they **stop and report it — they never invent
  it** to keep going.

So "interactive" is bounded even in INIT: the **agent decides, the user approves
and unblocks**. Follow this exact order (full detail in
[references/stage-init.md](references/stage-init.md)):

1. **Pull the data** — `get_context` / `get_growth_state` / `get_brand_context`, and
   **refresh the site context** if its cache
   (`<dir>/facts/site-context.md`) is not stamped today. **At least once a day**, plus
   whenever the user asks or names a topic — the operator may have created or
   published in the Scout7 app since your last run and you would never know.
2. **Confirm the growth folder + top up topics** — pick the brand's knowledge `--dir`
   (the folder holding `facts/`+`stance/`; the plan lives in `<dir>/growth-plans/`).
   If those files are absent, **bootstrap them from `get_brand_context`** so the blog
   never stalls into asking. If `get_topic_coverage` is thin or `get_growth_state`
   isn't `ready_to_plan`, **add topics** with `scout7_add_topics` /
   `scout7_refresh_topics` before planning. A `ready_to_plan` workspace can still be
   sitting on a **stale pool** — that is checked again in step 3.
3. **Pin the focus, then plan from it** — `get_topic_coverage` + `get_calendar`,
   ask the horizon (1 day / 1 week), then **interrogate for the loop's focus**:
   research the brand/market with your web tools, open with _"what is the focus for
   this loop?"_, and keep asking **open questions — a question and a text box,
   never multiple-choice options** — until the focus, philosophy and target are
   genuinely clear. Then **confirm the loop's angle by showing, not asking**: draft
   two or three sample angles (headline + one-line description), present them as
   _"this is the kind of stuff this loop will produce"_, and refine from their
   reaction until they confirm. Only a confirmed angle kicks off planning. Write
   them into
   `facts/canonical.md` as a dated `## Loop focus` section, then pick types
   (post / video / blog / carousel) → topics **and** draft every angle from that
   focus — topics that don't serve the focus don't go in. Then **diff the focus
   against the pool** and propose the topics it is missing: filtering can only narrow
   what is already there, so a new focus with an old pool is what produces a plan of
   irrelevant pieces.
4. **Get it approved or refined** — **present the full plan** (type · topic/angle ·
   platform · timing by daypart · live-vs-draft) and wait for a yes.
   Refine until approved, then record it: `plan.py approve`. **Nothing is generated
   before this**, and `plan.py ready` refuses to finalise without that approval.
5. **Lock the plan** — write items; lock each blog's context-grounded angle + size
   - `content_type` + interrogation answers (**sourced from the brand's
     `facts/canonical.md` + `stance/*.md`**, not the user — only ask the founder if the
     facts don't cover it), and judge the **headline** here: intriguing enough to make
     the target reader open it is the **minimum standard**. Lock each video's
     **presenter + voice** (`video_list_identities`, the user chooses) and its look —
     story or explainer — or CREATE stalls on `voice_required` with nobody to ask.
6. **Look for requirements, tell the user** — `verify.py`: angles locked, each video
   has a presenter, and each post/video's target platform has a connected Scout7
   publish identity.
7. **Ask for the user's decisions** — per gap: **fix** (connect the identity in
   Scout7) or **skip-to-draft** ("keep it in Scout7 as a draft"). Record each choice
   on the item.
8. **Ask participate-or-autonomous, then lock INIT** — ask whether the user stays
   in the loop (**manual**: CREATE pauses on each post concept / blog outline /
   video script for approval, then shows the finished content and schedules only
   what gets a final OK) or goes **autonomous** (hands-off); record it with
   `plan.py mode --set …`, then `plan.py ready`.
9. **MAKE THE CONTENT NOW — then, and only then, schedule what is left.**
   The operator has just approved a plan and has seen nothing. Do not answer that
   with a cron job. Hand straight off to [stage-create.md](references/stage-create.md)
   and **build the content**: everything in a 1-day plan; today's items (plus
   anything the user asked to front-load) in a 1-week plan. Showcase the finished
   pieces. **Only after that** put them on the calendar and register jobs for the
   days that still have unbuilt items. Detail in
   [stage-init.md](references/stage-init.md) § 9.

**Generate first, schedule second — always.** Scheduling is how _future_ days get
built; it is never the answer to the day in front of you. A first run that ends
with two cron jobs and zero content has failed, however correct the plan was.
**Scheduling is opt-in:** register the **Executor**
(`/scout7-run-organic-loop create`) and **Reporter**
(`/scout7-run-organic-loop finalise`) only when the horizon actually spans future
days, or when the user explicitly asked for a schedule. When you do, use a
**durable** scheduler — **`create_scheduled_task`** (persists to disk, runs in-app
on its cron), **not** `CronCreate` (session-only, dies when Claude exits) — and
give each a self-contained prompt (the exact
`/scout7-run-organic-loop … --dir <P>` command + Scout7 connector). A 1-day loop
usually needs no Executor at all: the content was made in step 9, so only the
Reporter remains.

**Never schedule or publish before step 4's approval and step 7's decisions.**
Everything decided is
written into the plan file with `plan.py decide`.

**CREATE and FINALISE then run on their own** — normally fired by the scheduled
jobs INIT created (step 8), not by hand. In **autonomous** mode there are no more
questions; in **manual** mode CREATE's only questions are its three preview
checkpoints and the end-of-run showcase approval. They read the locked decisions
from the plan and execute: generate, collect async jobs (wait
with a background sleep, do not tight-poll), schedule/publish per the approval,
and write the report. If a decision needed to run
headless is missing, that is an INIT bug — record what is missing and stop rather
than inventing it. The up-front approval captured in INIT is the "clear yes" the
safety rules require; without it, do not generate or publish.

**Invoke with a stage:** `/scout7-run-organic-loop init`, `/scout7-run-organic-loop create`,
`/scout7-run-organic-loop finalise`. With no stage, read the plan (`plan.py show`) and infer
where the user is.

## Setup this needs

- **Scout7 MCP connected.** `scout7_get_context` names the workspace/brand. To
  see what tools the connection offers, use the MCP protocol's `tools/list` (the
  registered `scout7_*` tools) — never an HTTP `/health` probe, which only says a
  gateway is up, not which tools this session can call.
- **The brand's knowledge folder** — the directory that already holds the brand's
  `facts/canonical.md` + `stance/*.md` (typically its engagement-engine folder). The
  plan lives in `<dir>/growth-plans/` and this is the `--dir` argument to every
  `plan.py` / `verify.py` / `report.py` call (`--engine` is a legacy alias). The blog
  interrogation is answered from `facts/` + `stance/`. If the folder has none yet,
  **INIT bootstraps them from `scout7_get_brand_context` on the first run** (worth a
  one-time skim) so it never stalls into asking; for a richer, reverse-engineered
  folder, `scout7-run-engagement-loop` builds one from existing posts and site copy.

## Non-negotiable rules (all three stages)

These come from Scout7's own tool contracts — follow them.

1. **Shape the plan in INIT — the plan approval is the only gate before work starts.**
   `scout7_preview_generation_plan` shows what a run would produce without
   producing it; run it in INIT so the plan the user approves is the real shape. That single INIT
   approval authorizes every downstream `generate_*` call (posts, blog, video,
   images). CREATE works against it and, in autonomous mode, does not ask again
   — the user is not watching. In **manual** mode each piece gets one more,
   per-piece gate: the preview (post concept / blog outline / video script)
   is approved first.
2. **The INIT approval is the only publish gate — the cycle then runs unattended.**
   `scout7_schedule_post`, `scout7_publish_post`, `scout7_blog_publish` post to
   real accounts and are effectively irreversible. All of that is authorized by the
   one plan approval in INIT: once the user approves the plan (types, topics,
   angles, platforms, schedule), CREATE generates, schedules, and publishes
   to the live accounts **fully autonomously, with no further confirmation** — in
   autonomous mode; in manual mode the preview approval and the end-of-run
   showcase approval are the added checkpoints — the finished piece is shown and
   scheduled/published only after the operator's OK. The
   agent owns the whole cycle from approval through to a fully-scheduled plan. Any
   item the user does not want auto-published must be marked `draft_only` in INIT;
   everything else goes live on its own.
3. **Never invent the founder's answers.** `scout7_blog_start_draft` returns
   questions — with real ids — that only the author can answer. Answer from the
   brand's `facts/canonical.md` + `stance/*.md`, or ask the founder; never
   fabricate ids like `q1/q2/q3` or make up answers (Scout7 rejects both, and
   `plan.py ready` blocks a blog with no recorded answers).
4. **Fire async work, then wait it out in-process.** Generation is 2–4 min
   (posts), ~90 s–3 min (blog), ~10 min (video). Kick it off, then `sleep` in the
   background for the ETA and collect with `get_generation_status` / `get_draft` —
   never tight-poll, and never end the turn or ask the user to check back. Nobody
   is watching; you wait, then continue.
5. **The plan file is the source of truth.** Update item status as work moves
   (`plan.py status`), so a later stage — or a later session — knows what is done.

## The stages

Read the matching reference file when you enter a stage; each is the detailed
procedure, kept out of here so this router stays short.

| Stage        | What it does                                                                                                                 | Interactive?                                                           | Reference                                                    |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------ |
| **init**     | Brand → horizon → **focus interrogation** → topics + angles from the focus → size, blog answers, platforms, **one approval** | **Yes — all questions live here**                                      | [references/stage-init.md](references/stage-init.md)         |
| **create**   | Generate every post/video/blog/carousel, showcase the results, schedule/publish                                              | Autonomous: no (shows & continues) · Manual: previews + final showcase | [references/stage-create.md](references/stage-create.md)     |
| **finalise** | End-of-day impact + learnings report                                                                                         | No                                                                     | [references/stage-finalise.md](references/stage-finalise.md) |

End INIT with `plan.py ready` once every decision is locked; CREATE refuses to
invent a missing one. `ready` itself is gated — it refuses unless the user
`approve`d the presented plan, a run mode (autonomous/manual) was recorded, and
every blog carries a real `angle_id` + recorded answers — so a skipped approval,
an unasked mode question, or an invented blog answer stops here, not in front
of a paying `generate_*` call.

Scout7 tool call-order and gotchas: [references/scout7-tool-map.md](references/scout7-tool-map.md).

## Talking to the operator

Every stage sends short guidance messages at **seven fixed moments** — kickoff
(INIT opens), plan-locked (step 5), handoff (step 8, mode-aware), manual
checkpoint (CREATE previews), showcase (every CREATE run surfaces the finished
content — the scheduling gate in manual mode), run wrap (run ends), report
delivery (FINALISE) — so the operator always knows **where the work lives, what happens
next, and what is asked of them**: real paths, the `plan.py show` command, and
Scout7 `open_in_app` links, with any ask as the last line. Shapes and placement:
[references/user-messages.md](references/user-messages.md).

## The plan artifact

`scripts/plan.py` writes `<dir>/growth-plans/<start>-<horizon>.json`. One plan
per horizon; each item has a type (**post / video / blog / carousel**), angle, platforms,
day, daypart, frequency and a status that walks
`planned → generating → draft → scheduled → published`.

```bash
python3 scripts/plan.py new    --dir <P> --horizon 1week --start 2026-08-21
python3 scripts/plan.py add    --dir <P> --type post --topic "…" --angle "…" \
                               --platforms x,threads --day 2026-08-22 --daypart morning
python3 scripts/plan.py status --dir <P> --item i02 --set scheduled --id post_id=abc
python3 scripts/plan.py show    --dir <P>
```

`report.py --dir <P>` assembles the finalise report from the plan, leaving slots
for the live Scout7 metrics you fetch by MCP.
