Docs

Draft Piece (starter blueprint)

Slug: draft-piece Type: agent_blueprint Source: code-defined; appears in every tenant's agent_blueprint://list automatically. Fork via agents.fork_blueprint to customize. Outputs: the new draft version number on the piece + the count of content_grounding children 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_piece placeholder created by plan_and_draft_window (which inlines the planner) or by artifacts.create directly.
  • 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_window to 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:

  1. draftBodyRequired — pieces in status drafting | ready | published must carry a non-empty content_json.draft_markdown. Placeholder + archived are exempt. This blueprint's terminal update_piece step 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.

  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. 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 the update_piece step'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_generatedtrue.
  • metadata.review_status'pending_review'.
  • metadata.variant_key — set to the input variant_key if supplied.

It also attaches one or more content_grounding children to the piece (parent_artifact_id = piece_id). Each citation child carries:

jsonc
{
  "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

NameTypeRequiredDescription
piece_idartifact_ref(content_piece)yesThe piece to draft. Must already exist; create via plan_and_draft_window (which inlines the planner) or artifacts.create.
variant_keystringnoOptional 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:

  1. load_piecetool. read_resource artifact://<piece_id>. The read returns an envelope with references resolved so pillar_id and author_id arrive as { id, title, artifact_type, status } envelopes alongside the raw uuids.
  2. load_authortool. read_resource author_profile://<piece.author_id>. The author profile carries voice_profile_id.
  3. load_voicetool. read_resource voice_profile://<author.voice_profile_id>. The voice rules embed into the draft prompt so the body matches workspace voice.
  4. gather_evidencetool. data.cluster_search keyed on piece.content_json.topic. Returns conversation themes the draft can quote and cite.
  5. assert_evidenceassert. Halts with evidence_missing pause when zero clusters returned. The calling LLM surfaces a confirm pause: proceed without grounding (mark draft metadata.grounding_status='ungrounded') or pause until the substrate has data.
  6. write_draftllm. Authors the draft body inline. Composes prompt://content_writer/grounding_rules, audience_scoping, channel_budget, cta_synthesis, hook_patterns. Outputs draft_markdown plus a citations array.
  7. attach_citationsloop. Per cited evidence chunk, attaches a content_grounding child to the piece via artifacts.create_child.
  8. update_piecetool. artifacts.update writes the new draft body into content_json.draft_markdown. The update appends a new version row in platform_artifact_versions and bumps current_version automatically.

Pause types and resume contract

Pause typeTriggered byResume requires
evidence_missingassert_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:

code
read_resource agent_blueprint://draft-piece

Then 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

code
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_evidence and assert_evidence for opinion-heavy publishing.
  • Custom evidence layer — extend gather_evidence to call your CRM tool, intercom search, or other tenant-specific source before the synthesis step.
  • Multi-source citations — replace the single data.cluster_search with 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_id and author_id populated (placeholder pieces created by plan_and_draft_window's inlined planner always do; pieces created manually via artifacts.create may not — the blueprint will halt at load_author if author_id is null).
  • Each invocation produces ONE draft. For variant generation, run the blueprint multiple times with different variant_key inputs.