Plan and Draft Window (starter workflow)
Slug:
plan-and-draft-windowType:agent_blueprintSource: code-defined; appears in every tenant'sagent_blueprint://listautomatically. Fork viaagents.fork_blueprintto customize. Outputs: the array ofcontent_pieceids planned + drafted, the count of successful drafts, and the total citations attached.
The end-to-end content production workflow. Plans a window of placeholder pieces AND drafts each one in parallel — both halves run in a single workflow.
The 2026-04-30 trim inlined what used to be a separate plan-content-window starter directly into this workflow, 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 workflow.
- 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 workflow 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 workflow
On the MCP tool surface you run this workflow interactively: the calling LLM reads this recipe and makes the tool calls itself (see how a workflow runs). Treat the step graph as direct instructions for the named primitives. (The platform can also run it headlessly — Run now, scheduled cron — set up over REST + the Anthropic tool surface; see Workflows over the API. 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 workflow works:
-
draftBodyRequired— pieces in statusdrafting | ready | publishedmust carry a non-emptycontent_json.draft_markdown. Placeholder is exempt, which is why this workflow's planner step is allowed to create pieces atstatus: placeholderwith no body yet. The downstreamdraft-piecesub-blueprint then writes the body in the same patch as the status bump todrafting. -
calendarPlanGate(OPT-IN) — gatesdrafting | ready | publishedtransitions on an approvedcontent_calendar_planparent, but ONLY when the piece carriescontent_json.metadata.requires_approval_gate = true. This workflow does NOT set the flag, so the planner's placeholder pieces transition todraftingfreely. Editorial teams that want batch approval should fork this starter and addrequires_approval_gate: truetocreate_pieces.args.content_json.metadata, then add an approval pause between plan and draft phases that requires the parent to be an approvedcontent_calendar_plan.
What it produces
Three outputs:
piece_ids(array) — everycontent_pieceartifact created by the inlined planner.draft_count(integer) — how many of those pieces were successfully drafted.total_citations(integer) — sum ofcontent_groundingchildren 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):
- bootstrap —
blueprint. Runsbootstrap-workspaceto gate on workspace canon (voice + pillars + authors). Halts withbootstrap_requiredcontext if anything is missing. - load_voice —
tool.read_resource voice_profile://list. - load_pillars —
tool.read_resource artifact://list?artifact_type=content_pillar. - load_authors —
tool.read_resource author_profile://list. - gather_evidence —
loop(parallel). Per pillar,data.cluster_searchfor substrate evidence themes. - assert_evidence —
assert. Halts withevidence_missingwhen every pillar returned zero clusters. - distribute —
llm. Distributestarget_countpieces across channels + pillars. Composespillar_selection,cadence_rhythm,theme_variation,channel_budget,audience_scopingfragments. - create_pieces —
loop. Per spec,artifacts.createacontent_piece(auto_generated=true, review_status=pending_review). - extract_piece_ids —
transform. Extracts the bare ids from the loop output.
Draft phase:
- draft_each —
loop(parallel, capped bypolicy.parallelism_max). Perpiece_id, dispatchesdraft-pieceas a sub-blueprint. Each iteration runs the full draft pipeline: load piece + author + voice, gather evidence, write draft, attach citations, update piece. - assert_drafts —
assert. Halts if anydraft-piecesub-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. - count_drafts —
transform. Count successful drafts. - sum_citations —
transform. Sum citation count across drafted pieces.
Pause types and resume contract
This workflow 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
Via MCP from an external Claude Desktop, read the recipe and walk its steps yourself (the interactive path):
read_resource agent_blueprint://plan-and-draft-windowThen 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_citationssteps 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_eachloop with abranchoninputs.auto_draft. When false, only run the planner; when true, run plan + draft. Lets a single workflow 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_emphasisbefore thedistributestep. Closes the loop on what's working.
Limits
target_countcapped at 50.parallelism_maxof 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 isceil(target_count / parallelism_max)rounds of paralleldraft-pieceruns). - 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.