From workflows
Expands section outlines into prose using a parallel write-agent workflow with domain-specific style rules and source verification. Activates after outline review approval.
How this skill is triggered — by the user, by Claude, or both
Slash command
/workflows:writing-draftWrite|Edit|Agent|WorkflowGATE_ARTIFACT=.planning/OUTLINE_REVIEWED.md GATE_STATUS=APPROVED GATE_BLOCKED_TOOLS=Write,Edit,Agent,Workflow GATE_DESCRIPTION="Outline review" GATE_REMEDY="Return to writing-outline and run the outline reviewer before drafting" uv run python3 ${CLAUDE_PLUGIN_ROOT}/hooks/phase-gate-guard.pyWriteuv run python3 ${CLAUDE_PLUGIN_ROOT}/hooks/writing-outline-guard.pyEdit|Writeuv run python3 ${CLAUDE_PLUGIN_ROOT}/hooks/writing-suggest-verify.pyuv run python3 ${CLAUDE_PLUGIN_ROOT}/hooks/writing-claim-id-guard.pyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Expand detailed section outlines into prose via the `writing-draft` ultracode workflow — one write-agent per section, in parallel — applying domain-specific style rules. The skill owns the gate, the `/goal` loop, and the mandatory source-verify; the workflow owns the per-section fan-out + JS gate.
Expand detailed section outlines into prose via the writing-draft ultracode workflow — one write-agent per section, in parallel — applying domain-specific style rules. The skill owns the gate, the /goal loop, and the mandatory source-verify; the workflow owns the per-section fan-out + JS gate.
Prerequisites: PRECIS.md, OUTLINE.md, ACTIVE_WORKFLOW.md, and at least one section outline in outlines/ must exist.
Auto-load all constraints matching applies-to: writing-draft (includes constraint-loading-protocol, source-anchored-citations, no-bold-lead, topic-sentences, and all shared writing constraints):
!uv run python3 ${CLAUDE_SKILL_DIR}/../../scripts/load-constraints.py writing-draft
You MUST have these constraints loaded before proceeding. No claiming you "remember" them.
CRITICAL: The constraint-loading-protocol above requires loading the domain skill (writing-legal/econ/general) and ai-anti-patterns before writing any prose — see Step 2 below.
Drafting is a ultracode TRANSFORM workflow, not hand-drafting. The skill keeps the gate, the /goal loop, and the mandatory source-verify; the writing-draft workflow owns the per-section fan-out (one write-agent per section, in parallel) and computes the gate in JS. The outline is the spec; each write-agent EXPANDS its section's outline into prose — adding only local prose craft, citations from real sources, and the bridges to neighbors.
START (all section outlines in outlines/ exist, OUTLINE_REVIEWED.md APPROVED)
│
├─ Step 1: Load context (PRECIS, OUTLINE, ACTIVE_WORKFLOW) + constraints
│
├─ Step 2: Run the writing-draft WORKFLOW (discover → transform → verify → gate)
│ ├─ Discover: enumerate sections; STRUCTURE gate (paragraph-granular? else bounce to outline)
│ ├─ Transform: one write-agent per section — expands outline → prose, cites REAL sources
│ │ (never fabricates; honest [CITE-NEEDED] when unsourceable), writes bridges from
│ │ the adjacent OUTLINES (no dependency on sibling drafts)
│ ├─ Verify (read-only): coverage (every point) + fidelity (every cite resolves) + transitions
│ └─ Gate (JS): result.overallPass = every section drafted + substrate clean
│
├─ Step 3: Read the gate, drive the /goal loop
│ ├─ underGranular non-empty → STOP, bounce those outlines to writing-outline
│ ├─ overallPass=false → /goal loop: re-invoke (onlyChecks=sectionsThatFailed) + fix findings
│ └─ overallPass=true → proceed
│
├─ Step 4: MANDATORY full source-verify (deep quote-fidelity; resolve every [CITE-NEEDED])
│
└─ GATE: workflow overallPass=true AND source-verify clean?
├─ NO → keep the /goal loop running (no pause)
└─ YES → write DRAFT_COMPLETE.md → Load writing-validate → /writing-review
If text and flowchart disagree, the flowchart wins.
## The Iron Law of DraftingNO PROSE WITHOUT OUTLINE. Every section must have a detailed outline in outlines/ BEFORE you write prose for it. This is not negotiable.
If you find yourself drafting without a matching outline file:
Writing without an outline produces incoherent, wandering prose that requires complete rewriting.
## The Iron Law of Draft CompletenessReporting sections complete without verifying every outline point was expanded is NOT HELPFUL — the user publishes a draft with gaps that reviewers catch.
Before claiming a section is drafted:
If ANY point or evidence is missing, the section is NOT complete. Saying "draft done" when outline points were skipped wastes the user's time — they discover gaps during review that should never have survived drafting. The outline is a contract; the draft must fulfill it.
## The Iron Law of DepthEACH SECTION DESERVES FULL ATTENTION. Do not rush through sections to "finish" the draft. This is not negotiable.
The failure mode: a single agent writes cursory 2-paragraph versions of every section to reach "draft complete" as fast as possible. This is reward hacking - optimizing for the appearance of completion without the substance.
Each section must:
If you catch yourself writing a section significantly shorter than the outline implies, STOP. You are being cursory. Go back to the outline and expand every point.
Before starting, check for an existing handoff:
.planning/HANDOFF.md existsRead(".planning/ACTIVE_WORKFLOW.md")
Read(".planning/PRECIS.md")
Read(".planning/OUTLINE.md")
The workflow's write-agents apply the domain style rules per-section (the workflow resolves the domain skill itself). Load it here too so you can judge the /goal loop's output and enforce the export template (legal .docx). Based on style in ACTIVE_WORKFLOW.md, load the domain skill (relative to this skill's base directory):
| Style | Action |
|---|---|
| legal | Read("${CLAUDE_SKILL_DIR}/../../skills/writing-legal/SKILL.md") |
| econ | Read("${CLAUDE_SKILL_DIR}/../../skills/writing-econ/SKILL.md") |
| general | Read("${CLAUDE_SKILL_DIR}/../../skills/writing-general/SKILL.md") |
When style: legal is detected:
MUST Read the full skill file:
Discover path: ${CLAUDE_SKILL_DIR}/../../skills/writing-legal/SKILL.md, then Read() the output.
MUST use template for .docx export:
${CLAUDE_SKILL_DIR}/../../skills/writing-legal/templates/law_review_template.docx
Iron Laws from writing-legal:
If you create a legal docx without reading the skill and using the template, DELETE IT and START OVER.
### Econ Domain: MUST Load Full SkillWhen style: econ is detected:
MUST Read the full skill file:
Discover path: ${CLAUDE_SKILL_DIR}/../../skills/writing-econ/SKILL.md, then Read() the output.
Iron Laws from writing-econ:
Delete & Restart triggers:
If you write boilerplate in an econ paper, DELETE THE SECTION and START OVER with a hook.
Skill(skill="workflows:ai-anti-patterns")
You MUST load ai-anti-patterns before drafting. Domain skills catch domain-specific issues; ai-anti-patterns catches AI writing smell (hedging, filler, false balance, weasel words). Both layers are required — see constraints/constraint-loading-protocol.md for why.
Drafting is the writing-draft ultracode workflow — do NOT hand-draft sections in this session, and do NOT spawn your own per-section agents. Invoke it once over the whole document:
Workflow(name="writing-draft", args={
"projectDir": "<absolute path to the writing project root (cwd)>",
"pluginRoot": "<absolute path to this plugin's workflows/ dir — resolve ${CLAUDE_SKILL_DIR}/../../workflows>",
"outputSubdir": "drafts"
})
It discovers the sections, asserts each outline is paragraph-structured, fans out one write-agent per section (each EXPANDS its outline → prose, cites real sources, writes bridges from the adjacent outlines), verifies coverage + citation-resolvability + transitions, and returns { overallPass, substratePass, verdict, scoreTable, sections, findings, underGranular, sectionsThatFailed, reviews }. The gate is computed in JS from raw counts — never self-report it.
Read the result and act:
underGranular non-empty → STOP. Those outlines lack paragraph-level structure (or are placeholders like "TBA"). Do NOT draft them conversationally as a workaround — return to writing-outline, deepen them to paragraph level, re-run the outline reviewer, then re-invoke this workflow. (This is the executable-spec gate: an under-detailed outline is fixed in outlining, not papered over at draft time.)
overallPass=false (sections drafted but failing coverage / citation-resolvability / transitions) → drive convergence with the native /goal primitive. A separate evaluator gates exit on result.overallPass, so the agent that drafts isn't the one that judges:
/goal The writing-draft workflow returns result.overallPass=true (every OUTLINE section drafted, coverage clean, every citation resolves to a real source with no [CITE-NEEDED] left, transitions connect) AND source-verify is clean. Stop after 8 turns.
Each turn under the active goal: read the latest findings, fix them (resolve a [CITE-NEEDED] by finding the real source or cutting the claim; expand a cursory section; repair a seam), then re-invoke the workflow with onlyChecks: result.sectionsThatFailed + priorReviews: result.reviews (re-drafts only the failed sections, carries the rest). End the turn so the evaluator re-checks. Do NOT pause to ask "continue?" — the evaluator decides.
overallPass=true → proceed to Step 4.
The JS gate is authoritative. Do not hand-wave it to true; fix a finding and let the next run recompute. Per-section minor prose nits are advisory here — document-quality polish is /writing-review's job, not the draft gate's.
The workflow's verify stage confirms each citation resolves (the source exists / the cite is well-formed). It does NOT confirm the quoted text actually appears in the source. Before declaring the draft complete, run the deep check:
Skill(skill="workflows:source-verify")
source-verify checks every citation against the bibliography and verifies quotes against the source documents — resolving any remaining [CITE-NEEDED], catching mis-attribution and quote drift. A draft is not complete until BOTH result.overallPass=true AND source-verify is clean. If source-verify surfaces an unresolved or mis-attributed citation, feed it back into the Step-3 /goal loop (re-draft that section with the correct source) — never write DRAFT_COMPLETE.md with an unverified citation.
After the workflow returns overallPass=true, record state in .planning/ACTIVE_WORKFLOW.md (phase: draft, sections_drafted: [...], edits_since_verify: 0).
Before proceeding to edit/verify (see constraints/gate-function-standard.md for the full 6-step gate including SUMMARY):
IDENTIFY: The writing-draft workflow result (Step 3) + the source-verify result (Step 4)
RUN: Re-read result.overallPass and the source-verify outcome — do not re-derive by hand; the workflow already listed drafts/, checked coverage, and resolved citations in JS
READ: Confirm result.underGranular is empty (no outline bounced) and result.findings has no unresolved blocking entry
VERIFY: result.overallPass === true (every section drafted, coverage + citation-resolvability + transitions clean) AND source-verify is clean (quotes match sources, no [CITE-NEEDED] left)
CLAIM: Only if steps 1-4 pass, write the gate artifact, THEN proceed to writing-validate. writing-validate's PreToolUse hook blocks until this file exists — the artifact certifies every OUTLINE section has a substantive, citation-verified draft:
mkdir -p .planning && cat > .planning/DRAFT_COMPLETE.md <<EOF
---
status: APPROVED
gate: draft
sections: ${SECTION_COUNT:-all}
---
Draft gate passed: every OUTLINE.md section has a drafts/ file with substantive content covering all outline points (not cursory stubs).
EOF
Gate type: human-verify — auto-advance to writing-validate. Do not write status: APPROVED while any section is a cursory stub — the artifact is the contract that drafting is genuinely complete.
SUMMARY: Append phase summary to .planning/PHASE_SUMMARY.md (see constraints/phase-summary-frontmatter.md):
Reporting "all sections drafted" without checking each file is NOT HELPFUL — the user moves to review with missing sections that force a return to drafting. You must verify every draft exists and has real content.
These govern how the Step-3 /goal loop responds to the workflow's per-section findings — the workflow drafts and verifies; this loop fixes and re-invokes. Map each finding to an action, then re-invoke with onlyChecks: result.sectionsThatFailed:
| Finding type | Action on re-invoke |
|---|---|
| Coverage (missing/cursory outline points) | The outline point wasn't expanded. Re-invoke that section; if it keeps coming back cursory, the outline point may lack substance → R2/R4. |
Fidelity ([CITE-NEEDED] / unresolvable cite) | Find the real source (bib / Paperpile / a search) and supply it, or cut the claim. NEVER let the loop "resolve" it by inventing a cite. |
| Transition (seam, dangling reference) | The adjacent-outline bridge broke. Re-invoke the section; if two sections genuinely don't connect, that's an outline-order issue → R4. |
Structureless (underGranular) | Not fixable in the loop — STOP and bounce the outline to writing-outline. |
Re-invoke WITHOUT pausing — the /goal evaluator re-checks result.overallPass and refires until clean or the turn budget elapses.
The workflow's coverage check enforces depth mechanically — a 2-paragraph section under a 5-subsection outline fails coverage and the gate won't pass. You do not need a separate per-section self-check; the JS gate is the check.
If 5+ iterations on the same section without meaningful progress, STOP and escalate to the user for scope adjustment.
Signs you are stuck:
When escalating, present:
Spinning without progress is anti-helpful. Five iterations is the threshold for asking the user if scope needs adjustment.
When drafting reveals unplanned issues, follow this 4-rule system:
| Rule | Trigger | Action | Permission |
|---|---|---|---|
| R1: Factual Error | Wrong fact, misattribution, incorrect citation, anachronism, wrong date/name | Fix → verify against source → track [Rule 1 - Factual] | Auto |
| R2: Missing Evidence | Claim without citation, unsupported assertion, missing example, evidence gap | Add evidence/citation → track [Rule 2 - Evidence] | Auto |
| R3: Structural Blocker | Missing section referenced by another, broken cross-reference, orphaned footnote, missing transition | Fix blocker → track [Rule 3 - Structural] | Auto |
| R4: Argument Restructuring | Claim order needs changing, thesis angle needs adjustment, major section add/remove, argument flow fundamentally broken | STOP → present to user → may require .planning/OUTLINE.md revision → track [Rule 4 - Restructuring] | Ask user |
Priority: R4 (STOP) > R1-R3 (auto) > unsure → R4.
Edge cases:
Tracking format per section: Each section's draft summary should include: Deviations: N auto-fixed (R1: X, R2: Y, R3: Z). R4 escalations: [list or "none"].
After all sections are drafted:
Read ${CLAUDE_SKILL_DIR}/../../skills/writing-validate/SKILL.md and follow its instructions. Follow its instructions to validate claim coverage before review.
npx claudepluginhub edwinhu/workflows --plugin workflowsCreates detailed section outlines in a progressive writing workflow, enforcing outline-before-prose. Evaluates section structure against PRECIS claims and gates prose drafting until review is passed.
Constructs clear prose section by section from approved outlines or blueprints. Use for drafting articles, essays, guides, or long-form content.
Orchestrates multi-agent writing of academic papers or proposals from research artifacts, with evidence-grounded prose, MAGI cross-review, and quality validation.