Docs

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

NameTypeRequiredDescription
date_rangejsonyesObject { start, end } of ISO dates bounding the window.
channelsjsonyesArray of channel slugs the planner is allowed to use.
target_countintegeryesHow many content_piece artifacts to plan + draft. 1-50.
pillar_emphasisjsonnoOptional record { <pillar_slug>: <weight> } to bias distribution.
audiencestringnoAudience 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. bootstrapblueprint. Runs bootstrap-workspace to gate on workspace canon (voice + pillars + authors). Halts with bootstrap_required context if anything is missing.
  2. load_voicetool. read_resource voice_profile://list.
  3. load_pillarstool. read_resource artifact://list?artifact_type=content_pillar.
  4. load_authorstool. read_resource author_profile://list.
  5. gather_evidenceloop (parallel). Per pillar, data.cluster_search for substrate evidence themes.
  6. assert_evidenceassert. Halts with evidence_missing when every pillar returned zero clusters.
  7. distributellm. Distributes target_count pieces across channels + pillars. Composes pillar_selection, cadence_rhythm, theme_variation, channel_budget, audience_scoping fragments.
  8. create_piecesloop. Per spec, artifacts.create a content_piece (auto_generated=true, review_status=pending_review).
  9. extract_piece_idstransform. Extracts the bare ids from the loop output.

Draft phase:

  1. draft_eachloop (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.
  2. assert_draftsassert. 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.
  3. count_draftstransform. Count successful drafts.
  4. sum_citationstransform. Sum citation count across drafted pieces.

Pause types and resume contract

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

Pause typeComes fromResume requires
bootstrap_requiredthe inlined bootstrap stepthe user provides the missing canon item
evidence_missingthe inlined assert_evidence step (per-pillar evidence) OR draft-piece (per-piece evidence)confirm action: continue or stop
draft_failuresthe assert_drafts stepconfirm 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:

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

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

code
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

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