# Plan And Draft Window

# Plan and Draft Window (starter blueprint)

> **Slug:** `plan-and-draft-window`
> **Type:** `agent_blueprint`
> **Source:** code-defined; appears in every tenant's `agent_blueprint://list` automatically. Fork via `agents.fork_blueprint` to customize.
> **Outputs:** the array of `content_piece` ids planned + drafted, the count of successful drafts, and the total citations attached.

The end-to-end content production blueprint. Plans a window of placeholder pieces AND drafts each one in parallel — both halves run in a single blueprint.

The 2026-04-30 trim inlined what used to be a separate `plan-content-window` starter directly into this blueprint, so users see ONE end-to-end recipe in the library instead of a planner-only utility they would never run on its own. Drafting still uses `draft-piece` as a sub-blueprint per piece (one per loop iteration) because that recipe IS independently useful (drafting one specific piece by id).

## When to use it

- A founder or marketer wants a complete month of content (planned + drafted) in one invocation.
- The chat panel exposes a "Plan and write content for a month" affordance backed by this blueprint.
- An external MCP client wants the simplest one-shot content production primitive: input the window, output a Calendar full of drafted pieces.

If you want plan-then-review-then-draft as separate user gates, fork this blueprint and split it: keep the inlined planning steps, drop the `draft_each` loop, then invoke `draft-piece` per approved piece in a follow-up run.

## Reading this blueprint

Per the agent blueprint substrate contract: this is a **recipe** the calling LLM reads and walks step-by-step. On the MCP tool surface there is no run tool — the calling LLM IS the runner. Treat the step graph as direct instructions for the named primitives. (Platform-initiated runs — manual "Run now", schedule/event/webhook triggers, replay, backtest sweeps — are driven separately by the headless SDK runner; see `docs/blueprint-runner-sdk.md`. This doc describes the interactive path you walk yourself.)

## Validators that travel with content_piece writes (2026-05-12 relaxation)

Two registry validators run on every content_piece write — knowing them shapes how this blueprint works:

1. **`draftBodyRequired`** — pieces in status `drafting | ready | published` must carry a non-empty `content_json.draft_markdown`. **Placeholder is exempt**, which is why this blueprint's planner step is allowed to create pieces at `status: placeholder` with no body yet. The downstream `draft-piece` sub-blueprint then writes the body in the same patch as the status bump to `drafting`.

2. **`calendarPlanGate` (OPT-IN)** — gates `drafting | ready | published` transitions on an approved `content_calendar_plan` parent, but ONLY when the piece carries `content_json.metadata.requires_approval_gate = true`. This blueprint does NOT set the flag, so the planner's placeholder pieces transition to `drafting` freely. Editorial teams that want batch approval should fork this starter and add `requires_approval_gate: true` to `create_pieces.args.content_json.metadata`, then add an approval pause between plan and draft phases that requires the parent to be an approved `content_calendar_plan`.

## What it produces

Three outputs:

- `piece_ids` (array) — every `content_piece` artifact created by the inlined planner.
- `draft_count` (integer) — how many of those pieces were successfully drafted.
- `total_citations` (integer) — sum of `content_grounding` children attached across every drafted piece.

Each piece carries `metadata.auto_generated=true` and `metadata.review_status='pending_review'` so the user can review, edit, or reject in the Calendar page.

## Inputs

| Name              | Type    | Required | Description                                                         |
| ----------------- | ------- | -------- | ------------------------------------------------------------------- |
| `date_range`      | json    | yes      | Object `{ start, end }` of ISO dates bounding the window.           |
| `channels`        | json    | yes      | Array of channel slugs the planner is allowed to use.               |
| `target_count`    | integer | yes      | How many `content_piece` artifacts to plan + draft. 1-50.           |
| `pillar_emphasis` | json    | no       | Optional record `{ <pillar_slug>: <weight> }` to bias distribution. |
| `audience`        | string  | no       | Audience lens (free-text persona + segment).                        |

## How it runs

13 top-level steps. The planning steps are inlined; the draft phase fans out via `draft-piece` as a sub-blueprint.

**Plan phase (inlined):**

1. **bootstrap** — `blueprint`. Runs `bootstrap-workspace` to gate on workspace canon (voice + pillars + authors). Halts with `bootstrap_required` context if anything is missing.
2. **load_voice** — `tool`. `read_resource voice_profile://list`.
3. **load_pillars** — `tool`. `read_resource artifact://list?artifact_type=content_pillar`.
4. **load_authors** — `tool`. `read_resource author_profile://list`.
5. **gather_evidence** — `loop` (parallel). Per pillar, `data.cluster_search` for substrate evidence themes.
6. **assert_evidence** — `assert`. Halts with `evidence_missing` when every pillar returned zero clusters.
7. **distribute** — `llm`. Distributes `target_count` pieces across channels + pillars. Composes `pillar_selection`, `cadence_rhythm`, `theme_variation`, `channel_budget`, `audience_scoping` fragments.
8. **create_pieces** — `loop`. Per spec, `artifacts.create` a `content_piece` (auto_generated=true, review_status=pending_review).
9. **extract_piece_ids** — `transform`. Extracts the bare ids from the loop output.

**Draft phase:**

10. **draft_each** — `loop` (parallel, capped by `policy.parallelism_max`). Per `piece_id`, dispatches `draft-piece` as a sub-blueprint. Each iteration runs the full draft pipeline: load piece + author + voice, gather evidence, write draft, attach citations, update piece.
11. **assert_drafts** — `assert`. Halts if any `draft-piece` sub-run reported failure. The calling LLM surfaces the failure list as a confirm pause; the user can re-run failed pieces, accept the partial result, or abort.
12. **count_drafts** — `transform`. Count successful drafts.
13. **sum_citations** — `transform`. Sum citation count across drafted pieces.

## Pause types and resume contract

This blueprint can pause on any of the inner blueprints' pauses:

| Pause type           | Comes from                                                                                     | Resume requires                                   |
| -------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `bootstrap_required` | the inlined `bootstrap` step                                                                   | the user provides the missing canon item          |
| `evidence_missing`   | the inlined `assert_evidence` step (per-pillar evidence) OR `draft-piece` (per-piece evidence) | confirm action: continue or stop                  |
| `draft_failures`     | the `assert_drafts` step                                                                       | confirm action: continue (accept partial) or stop |

The chat panel widget registry handles each pause type identically whether it surfaces from this composition or from walking the inner blueprints on their own.

## Reading and walking it

On this MCP surface there is no run tool — read the recipe and walk its steps yourself. Via MCP from an external Claude Desktop:

```
read_resource agent_blueprint://plan-and-draft-window
```

Then gather the inputs and perform each step with your own primitive tools:

```
date_range: { start: '2026-05-01', end: '2026-05-31' }
channels: ['linkedin', 'blog']
target_count: 12
pillar_emphasis: { 'engineering-velocity': 0.5 }
audience: 'B2B SaaS engineering leaders, 50-500 person org'
```

As you walk it, narrate progress in chat: "Researching engineering-velocity pillar... Found 47 conversations. Authoring piece 1 of 12... Drafting piece 3 of 12..." The user watches it happen.

When you finish walking the steps, the chat shows: "12 pieces planned + drafted for May. Open Calendar to review." The user goes to the Calendar page; every piece appears with an `AI` badge and shows in the `Pending review` filter chip.

## Forking it

```
agents.fork_blueprint source=plan-and-draft-window new_slug=<your-fork>
```

Common forks:

- **Plan-only variant** — drop the `draft_each` / `assert_drafts` / `count_drafts` / `sum_citations` steps to recover the old planner-only behaviour. Useful if you want the user to review placeholders before drafting kicks off.
- **Approve-then-draft variant** — replace the parallel `draft_each` loop with a `branch` on `inputs.auto_draft`. When false, only run the planner; when true, run plan + draft. Lets a single blueprint cover both flows.
- **Per-channel concurrency limits** — fork the inner draft loop to chunk by channel and run channels sequentially (when LLM rate limits matter).
- **Performance feedback weighting** — pre-step that reads published-piece performance edges from prior windows and adjusts `pillar_emphasis` before the `distribute` step. Closes the loop on what's working.

## Limits

- `target_count` capped at 50.
- `parallelism_max` of 4 in policy keeps concurrent LLM calls manageable; bump in a fork if your account has higher rate budgets.
- Reads are not cost-bounded server-side in v1.
- Total runtime grows roughly linearly with `target_count` (planning is one batched call; drafting is `ceil(target_count / parallelism_max)` rounds of parallel `draft-piece` runs).
- The composition is one level deep on this version. A future starter could compose plan + draft + schedule (auto-set `status='scheduled'`) once the schedule artifact lands; that's deliberately deferred until pilot reveals demand.
