Draft Piece (starter blueprint)
Slug:
draft-pieceType:agent_blueprintSource: code-defined; appears in every tenant'sagent_blueprint://listautomatically. Fork viaagents.fork_blueprintto customize. Outputs: the new draft version number on the piece + the count ofcontent_groundingchildren attached.
The single-piece drafter. Loads a content_piece, chases its FK references to pull author + voice + pillar, gathers substrate grounding evidence, writes the draft inline via prompt-fragment composition, attaches citation children, and writes the new draft as a new version on the piece. Drafts live as versions on the piece rather than as separate draft records.
When to use it
- A user wants the AI to produce a full draft for a
content_pieceplaceholder created byplan_and_draft_window(which inlines the planner) or byartifacts.createdirectly. - You want a single-shot LinkedIn post / blog draft / newsletter section grounded in your voice + pillar + substrate evidence.
- You're invoking it as a sub-blueprint from
plan_and_draft_windowto back-fill drafts after the planner lands.
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 (this surface) there is no one-shot run-blueprint tool: the calling LLM IS the runner — read the recipe and walk it. Each step description below is written as an instruction you can act on directly via the named primitives. (A separate headless SDK runner can also drive this blueprint to completion unattended — manual "Run now" (REST), schedule/event/webhook triggers, replay, and backtest sweeps; see docs/blueprint-runner-sdk.md. You cannot one-shot-run a blueprint from this MCP surface, but you CAN register an unattended run from it via the blueprints tool's create_schedule.)
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:
-
draftBodyRequired— pieces in statusdrafting | ready | publishedmust carry a non-emptycontent_json.draft_markdown. Placeholder + archived are exempt. This blueprint's terminalupdate_piecestep writes the body in the SAME patch as the status bump, so the rule is satisfied structurally; there is no intermediate state where the piece exists in drafting status with an empty body. -
calendarPlanGate(OPT-IN) — gatesdrafting | ready | publishedtransitions on an approvedcontent_calendar_planparent, but ONLY when the piece carriescontent_json.metadata.requires_approval_gate = true. Default behavior (flag missing or false): pass-through. This blueprint never opts in; agent-driven / ad-hoc drafting is the default path. Editorial flows that want batch approval should fork this starter and add the flag to theupdate_piecestep's metadata.
What it produces
The blueprint writes a new version of the supplied content_piece artifact with:
content_json.draft_markdown— the full body in markdown.content_json.status— bumped to'drafting'.metadata.auto_generated—true.metadata.review_status—'pending_review'.metadata.variant_key— set to the inputvariant_keyif supplied.
It also attaches one or more content_grounding children to the piece (parent_artifact_id = piece_id). Each citation child carries:
{
"schema_version": "1.0.0",
"quote": "<the quoted line>",
"speaker": "<who said it>",
"company": "<company name or null>",
"source": "<conversation id / cluster id>",
}The Calendar page detail panel renders citations beneath the draft body so the reader can see what the AI grounded each claim against.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
piece_id | artifact_ref(content_piece) | yes | The piece to draft. Must already exist; create via plan_and_draft_window (which inlines the planner) or artifacts.create. |
variant_key | string | no | Optional variant key tagged on the new draft version. Useful for producing multiple variants of the same piece (long, short, punchy). |
How it runs
8 top-level steps:
- load_piece —
tool.read_resource artifact://<piece_id>. The read returns an envelope withreferencesresolved sopillar_idandauthor_idarrive as{ id, title, artifact_type, status }envelopes alongside the raw uuids. - load_author —
tool.read_resource author_profile://<piece.author_id>. The author profile carriesvoice_profile_id. - load_voice —
tool.read_resource voice_profile://<author.voice_profile_id>. The voice rules embed into the draft prompt so the body matches workspace voice. - gather_evidence —
tool.data.cluster_searchkeyed onpiece.content_json.topic. Returns conversation themes the draft can quote and cite. - assert_evidence —
assert. Halts withevidence_missingpause when zero clusters returned. The calling LLM surfaces a confirm pause: proceed without grounding (mark draftmetadata.grounding_status='ungrounded') or pause until the substrate has data. - write_draft —
llm. Authors the draft body inline. Composesprompt://content_writer/grounding_rules,audience_scoping,channel_budget,cta_synthesis,hook_patterns. Outputsdraft_markdownplus a citations array. - attach_citations —
loop. Per cited evidence chunk, attaches acontent_groundingchild to the piece viaartifacts.create_child. - update_piece —
tool.artifacts.updatewrites the new draft body intocontent_json.draft_markdown. The update appends a new version row inplatform_artifact_versionsand bumpscurrent_versionautomatically.
Pause types and resume contract
| Pause type | Triggered by | Resume requires |
|---|---|---|
evidence_missing | assert_evidence step (zero clusters) | confirm action: continue (proceed without grounding) or stop |
When evidence_missing fires, the chat panel offers two buttons: "Proceed without grounding" (resumes with action='continue'; the resulting draft is marked metadata.grounding_status='ungrounded' so reviewers know it's an opinion piece) and "Pause until data ingestion catches up" (resumes with action='stop' to abort).
Reading and walking it
There is no run tool — read the recipe and walk its steps yourself. Via MCP from an external Claude Desktop:
read_resource agent_blueprint://draft-pieceThen gather the inputs (piece_id: '5b2a...8e1d', variant_key: 'long') and perform each step with your own primitive tools. For variant production: walk the recipe once per variant key with the same piece_id and a different variant_key. Each walk appends a new version, so the piece's version history is the variant history.
Forking it
agents.fork_blueprint source=draft-piece new_slug=<your-fork>Common forks:
- Channel-specific drafting — fork to a Twitter-only or LinkedIn-only variant with hardcoded channel + tighter word budgets.
- Skip research by default — drop
gather_evidenceandassert_evidencefor opinion-heavy publishing. - Custom evidence layer — extend
gather_evidenceto call your CRM tool, intercom search, or other tenant-specific source before the synthesis step. - Multi-source citations — replace the single
data.cluster_searchwith a parallel fan-out to substrate + KB + a custom index, then merge before the draft step.
Limits
- Reads are not cost-bounded server-side in v1.
- The piece, author, and voice references all resolve within the calling API key's workspace; cross-tenant references fail at the operation registry boundary.
- The drafter expects the piece to already have
pillar_idandauthor_idpopulated (placeholder pieces created byplan_and_draft_window's inlined planner always do; pieces created manually viaartifacts.createmay not — the blueprint will halt atload_authorifauthor_idis null). - Each invocation produces ONE draft. For variant generation, run the blueprint multiple times with different
variant_keyinputs.