From magi-researchers
Orchestrates multi-agent writing of academic papers or proposals from research artifacts, with evidence-grounded prose, MAGI cross-review, and quality validation.
npx claudepluginhub axect/magi-researchers --plugin magi-researchersThis skill uses the workspace's default tool permissions.
Orchestrates multi-agent collaborative writing from upstream research artifacts. Produces structured documents (papers, proposals) with evidence-grounded prose, MAGI cross-review, and automated quality validation.
Writes publication-ready ML/AI papers for NeurIPS, ICML, ICLR, ACL, AAAI, COLM from research repos. Handles literature reviews, citation verification, related work, and LaTeX templates.
Writes scientific manuscripts in full paragraphs using IMRAD structure, APA/AMA/Vancouver citations, figures/tables, and CONSORT/STROBE/PRISMA guidelines. Two-stage: outlines via research-lookup to prose.
Guides evidence-driven writing for academic Introduction, Related Work, background, and literature synthesis using evidence maps, paragraph blueprints, and citation patterns.
Share bugs, ideas, or general feedback.
Orchestrates multi-agent collaborative writing from upstream research artifacts. Produces structured documents (papers, proposals) with evidence-grounded prose, MAGI cross-review, and automated quality validation.
/research-write --source <output_dir> [--mode paper|proposal] [--audience general-public|high-school|undergraduate|phd-student|researcher|expert|"free text"] [--depth low|medium|high] [--claude-only] [--resume <write_dir>]
$ARGUMENTS — Required and optional flags:
--source <output_dir> — Path to an upstream research output directory containing artifacts from /research, /research-brainstorm, /research-explain, or /research-report. Required unless --resume is provided.--mode — Writing mode (default: paper):
paper — Academic research paper with standard structure (abstract, introduction, methodology, experiments, results, discussion, limitations, conclusion, references)proposal — Grant or funding proposal with persuasive structure (executive summary, problem statement, proposed approach, preliminary results, timeline, budget, broader impact, references)--audience — Target audience (default: researcher):
general-public — No assumed technical backgroundhigh-school — Basic math/science literacyundergraduate — Introductory college-level knowledge in the domainphd-student — Graduate-level domain knowledgeresearcher — Active researcher familiar with the field (default)expert — Deep specialist in the exact sub-field"free text" — Any custom audience description (e.g., "medical doctors learning ML")--depth — Controls review thoroughness (default: medium):
low — Skip MAGI cross-review; Claude reviews alonemedium — Standard MAGI cross-review (Gemini + Codex review in parallel)high — MAGI cross-review + Devil's Advocate adversarial pass on high-stakes sections--claude-only — Replace all Gemini/Codex MCP calls with Claude Agent subagents. Use when external model endpoints are unavailable. See Claude-Only Mode section below.--resume <write_dir> — Resume an interrupted write pipeline from a previous write output directory. See Resume Protocol below.Shared rules: Read
${CLAUDE_PLUGIN_ROOT}/shared/rules.mdbefore starting. §MCP, §Claude-Only, §LaTeX, §Visualization, §Substitute apply to this skill. Inline fallback (if shared rules unavailable): Gemini models: gemini-3.1-pro-preview → gemini-2.5-pro → Claude. Codex: gpt-5.4. All math in LaTeX only (no Unicode: σ₁→$\sigma_1$). Use@filepathfor MCP file refs; subagents useReadtool.
See §MCP, §Visualization, §LaTeX in shared rules. Additionally:
mcp__codex-cli__ask-codex for analysis/review.See §Claude-Only and §Substitute in shared rules.
See §LaTeX in shared rules.
When this skill is invoked, follow these steps exactly:
Parse $ARGUMENTS:
--source <output_dir> (required unless --resume). Validate the directory exists using Glob.--mode (default: paper). Validate against supported modes: paper, proposal.--audience (default: researcher). Store as-is (predefined keyword or free-text string).--depth (default: medium). Validate: low, medium, high.--claude-only (boolean, default: false).--resume <write_dir>: If provided, skip to the Resume Protocol below.Determine the domain by reading upstream artifacts:
brainstorm/weights.json in the source directory — the _meta.domain field contains the domain.brainstorm/personas.md for domain context.Create the write output directory inside the source directory:
{source_dir}/write/
If write/ already exists, announce that existing artifacts will be preserved and new artifacts will be added alongside them.
Announce to the user: source directory, mode, audience, depth, domain, and claude-only status.
Inventory the source directory for available artifacts using Glob:
| Artifact | Path | Required | Purpose |
|---|---|---|---|
| Brainstorm synthesis | brainstorm/synthesis.md | Recommended | Research directions, key findings |
| Research plan | plan/research_plan.md | Recommended | Methodology, objectives |
| Murder board | plan/murder_board.md | Optional | Stress-test results |
| Mitigations | plan/mitigations.md | Optional | Plan revisions |
| Source code | src/**/* | Optional | Implementation details |
| Test results | tests/**/* | Optional | Validation data |
| Plot manifest | plots/plot_manifest.json | Optional | Figures with metadata |
| Report | report.md | Optional | Pre-existing report draft |
| Explain outputs | explain/**/*.md | Optional | Concept explanations |
| Brainstorm personas | brainstorm/personas.md | Optional | Expert persona context |
| Weights | brainstorm/weights.json | Optional | Scoring weights used |
For each artifact found, read the first 5 lines to confirm it is non-empty.
On missing recommended artifacts: Warn the user which recommended artifacts are absent. Ask: "The following recommended artifacts are missing: [list]. The document will have thinner coverage in the corresponding sections. Proceed anyway?" Continue on confirmation.
Claude reads all located upstream artifacts and generates two structured JSON files. This is an LLM extraction task — Claude performs the semantic extraction; Python validates the schema.
Schema reference: Read
references/intake_schemas.mdfor the fullwrite_inputs.jsonandcitation_ledger.jsonschemas and extraction guidelines.
1. Generate write/write_inputs.json using the schema in references/intake_schemas.md.
2. Generate write/citation_ledger.json using the schema in references/intake_schemas.md.
3. Validate with maintained utility:
Determine the plugin root directory by navigating two levels up from this skill's base directory (e.g., if this skill is loaded from .../skills/research-write/, the plugin root is ../../ relative to that path). The Base directory for this skill: header injected by Claude Code provides the absolute path. Then run:
uv run python <plugin_root>/utils/validate_intake.py write/write_inputs.json write/citation_ledger.json
Important: Do NOT generate a validation script at runtime. Use the maintained
utils/validate_intake.pyutility.
If validation fails, Claude fixes the JSON files and re-runs validation. Maximum 2 fix attempts.
Read the mode template from ${CLAUDE_PLUGIN_ROOT}/templates/writing/{mode}.md.
Parse the YAML frontmatter to extract:
sections — ordered list of section definitions with id, required, max_words, evidence_slots, style, narrative_roleexport — target export formatstotal_max_words — overall word budgettone, jargon_budget, formality — style constraintsRead the Markdown body for section dependencies and evidence integration guidelines.
Save a copy of the loaded template to write/mode_template_cache.md before proceeding to Step 1b. This cached copy is referenced by @filepath in subsequent model calls.
Full prompts: Read
references/outline_prompts.mdfor the complete MCP call specifications. Execute both calls simultaneously.
Generate two independent outlines using the mode template, write_inputs.json, and audience context:
write/gemini_outline.md.write/codex_outline.md.If --claude-only: see the Claude-Only Fallback in references/outline_prompts.md.
Claude reads both outlines and synthesizes a canonical outline with per-section contracts:
Merge outlines: For each section, take the stronger content from each outline:
Define the global argument thread: Synthesize both outlines' argument threads into a single 3-5 sentence narrative arc that connects all sections.
Generate write/section_contracts.json using the schema in references/intake_schemas.md.
Determine drafting order: Based on section dependencies from the mode template:
related_work for papers, problem_statement for proposals)abstract for papers, executive_summary for proposals)drafting_order field is a 1-indexed integer reflecting this order.Evidence coverage check: Verify that every high-confidence claim from write_inputs.json appears in at least one section's claim_ids. Verify that every evidence item appears in at least one section's evidence_ids. Report any orphaned claims or evidence.
Save the synthesized outline to write/outline.md (human-readable Markdown) and write/section_contracts.json (machine-readable).
>>> USER CHECKPOINT: Approve outline <<<
Present to the user:
Wait for user approval. The user may:
section_contracts.json accordingly)This is Hard Gate 1 — the most important checkpoint. No drafting begins until the user approves the outline.
Before generating any section prose, Claude pre-assembles evidence blocks for each section. This is the core evidence integration strategy: LLMs write prose AROUND pre-placed evidence, NOT with macros.
For each section (in drafting order):
write/section_contracts.json.evidence_id in the section's evidence_ids, generate the appropriate block:
type == "plot":
<!-- EVIDENCE BLOCK: ev-1 -->

*{caption}*
<!-- END EVIDENCE BLOCK -->
Anti-pattern: Do NOT list figures in a table at the end of the document. Every figure must be embedded inline with
immediately before or after the paragraph that discusses it.
type == "metric":
<!-- EVIDENCE BLOCK: ev-2 -->
**Key metric**: {description} — {value}
<!-- END EVIDENCE BLOCK -->
type == "test_result":
<!-- EVIDENCE BLOCK: ev-3 -->
**Validation**: {description}
<!-- END EVIDENCE BLOCK -->
type == "code":
<!-- EVIDENCE BLOCK: ev-4 -->
See implementation in `{ref}`: {description}
<!-- END EVIDENCE BLOCK -->
ref path exists (Glob check). If missing, mark as <!-- EVIDENCE BLOCK: {id} (MISSING FILE: {ref}) --> and log a warning.write/evidence_blocks/{section_id}.md.Generate each section in the order specified by drafting_order in section_contracts.json. For each section:
Context provided (scoped to prevent context bloat):
section_contracts.json)write/evidence_blocks/{section_id}.md)write_inputs.json (only claims listed in the section's claim_ids)For each section, Claude:
transition_from_previous field)max_words budget (±10%)transition_to_next field)Save each section to write/sections/{section_id}.md.
Save each section summary to write/sections/{section_id}_summary.md.
After all sections are drafted:
write/draft.md.Claude reads the full assembled draft and evaluates the narrative arc:
Save the narrative arc assessment to write/narrative_arc_assessment.md. This feeds into the Phase 3d global coherence pass.
Skip this step if
--depth low. For--depth low, proceed directly to Step 3c (DocCI Validation).
Full prompts: Read
references/review_prompts.mdfor the complete MCP call specifications. Execute both calls simultaneously.
Execute two parallel review calls:
write/gemini_review.md.write/codex_review.md.If --claude-only: see the Claude-Only Fallback in references/review_prompts.md.
Skip this step if
--depth lowor--depth medium. Only execute for--depth high.
Full spec: Read
references/depth_high.mdfor selection criteria, the full adversarial prompt, Claude-Only fallback, and fix application rules.
Identify high-stakes sections (most critical/major issues from Step 3a + required sections with evidence/method/result narrative roles). Apply adversarial review to at most 3 sections. Save each result to write/devils_advocate_{section_id}.md.
Claude reads all review outputs and applies fixes:
Read reviews: write/gemini_review.md, write/codex_review.md, and any write/devils_advocate_*.md files.
Triage issues:
Apply section-level fixes: For each section with issues:
write/sections/{section_id}.md (overwrite)Data integrity: Do NOT fabricate data for illustrative plots. If no data exists for a needed visualization, note the gap textually rather than generating synthetic values.
Escalation trigger: If any fix requires changing a section's scope or adding/removing key points not in the section contract, update section_contracts.json and flag this for the user:
"Section contract for '{section_id}' has been modified during review. Changes: [list]. These will be shown for approval in Phase 4."
Re-assemble the revised draft: write/revised_draft.md.
After all section-level fixes are applied, Claude performs a focused coherence pass:
write/revised_draft.md.write/narrative_arc_assessment.md from Phase 2d.write/revised_draft.md (overwrite).This is NOT a full rewrite. It is a bounded, focused pass that touches only inter-section boundaries. The goal is to eliminate the "Frankenstein" effect of section-by-section generation.
Run the repository-maintained draft validator to perform automated quality checks.
Determine the plugin root directory by navigating two levels up from this skill's base directory. The Base directory for this skill: header injected by Claude Code provides the absolute path. Then run:
uv run python <plugin_root>/utils/validate_draft.py write/revised_draft.md write/section_contracts.json write/write_inputs.json
Important: Do NOT generate a validation script at runtime. Use the maintained
utils/validate_draft.pyutility.
On validation failure: Claude reads the validation report, fixes the identified issues in write/revised_draft.md, and re-runs validation. Maximum 2 fix iterations.
Save the validation report to write/validation_report.json.
Before presenting to the user, scan the draft for any remaining unresolved macros. If MAGI model outputs introduced any {{fig:id}} or {{ref:id}} patterns during review, resolve them now:
write/revised_draft.md for patterns matching {{fig:...}} or {{ref:...}}.references/macro_resolution.md for the full script source, write it to write/resolve_macros.py, then run:
uv run python write/resolve_macros.py write/revised_draft.md write/write_inputs.json write/citation_ledger.json
If unresolved macros remain, Claude manually resolves them by reading the intake data and making inline replacements.>>> USER CHECKPOINT: Approve final document <<<
Present to the user:
write/revised_draft.mdThe user may:
--depth levelThis is Hard Gate 2 — the final publish gate. No export happens until the user approves.
After user approval:
Copy the approved draft to the final document name:
write/{topic}_paper.mdwrite/{topic}_proposal.mdClean up evidence block markers: Remove all <!-- EVIDENCE BLOCK: ... --> and <!-- END EVIDENCE BLOCK --> HTML comments from the final document, leaving only the rendered content.
Generate write/writing_state.json using the schema in references/intake_schemas.md.
Present completion summary to the user:
When --resume <write_dir> is provided, the pipeline skips initialization and infers the current phase from the presence of key artifact files in the write output directory. The artifacts themselves serve as checkpoints — no separate state file is required for resume inference.
Phase inference rules (evaluated top-down; first match wins):
| Condition | Inference | Action |
|---|---|---|
write/writing_state.json exists with status: "complete" | Pipeline complete | Inform user; offer to re-run specific phases |
write/revised_draft.md exists | Phase 3 complete | Resume from Phase 4 (Finalize) |
write/draft.md exists | Phase 2 complete | Resume from Phase 3 (Review) |
write/section_contracts.json exists | Phase 1 complete | Resume from Phase 2 (Draft) |
write/write_inputs.json exists | Phase 0 complete | Resume from Phase 1 (Outline) |
| None of the above | No phase complete | Start from Phase 0 (Setup & Intake) |
Resume procedure:
Glob to check for each artifact in the order above.--source, --mode, and --audience from write/write_inputs.json if it exists. If not, require the user to provide --source.Important: On resume, do NOT re-create the write directory or overwrite existing artifacts from prior phases. Only create artifacts for the resumed phase and beyond.
The write pipeline produces artifacts in the {source_dir}/write/ directory:
{source_dir}/
└── write/
├── write_inputs.json # Canonical intake (claims, evidence, definitions)
├── citation_ledger.json # Claim-source tracking
├── mode_template_cache.md # Cached copy of mode template
├── gemini_outline.md # Gemini's outline proposal
├── codex_outline.md # Codex's outline proposal
├── outline.md # Synthesized canonical outline (human-readable)
├── section_contracts.json # Per-section contracts (machine-readable)
├── evidence_blocks/
│ ├── introduction.md # Pre-assembled evidence for each section
│ ├── methodology.md
│ ├── results.md
│ └── ...
├── sections/
│ ├── introduction.md # Individual section drafts
│ ├── introduction_summary.md # Section summary for context scoping
│ ├── methodology.md
│ ├── methodology_summary.md
│ └── ...
├── draft.md # Assembled first draft
├── narrative_arc_assessment.md # Narrative arc evaluation
├── gemini_review.md # Gemini content quality review
├── codex_review.md # Codex structure & evidence review
├── devils_advocate_*.md # Devil's Advocate reviews (--depth high only)
├── revised_draft.md # Draft after review fixes + coherence pass
├── validation_report.json # DocCI validation results
├── resolve_macros.py # Macro resolution fallback script (if needed)
├── {topic}_paper.md # Final export (paper mode)
├── {topic}_proposal.md # Final export (proposal mode)
└── writing_state.json # Pipeline state manifest
/research pipeline — invoke it separately with --source pointing to a research output directory.validate_intake.py, validate_draft.py) are maintained in the utils/ directory at the plugin root. They are NOT generated at runtime — resolve the plugin root by navigating two levels up from this skill's base directory and use the maintained versions at <plugin_root>/utils/. The resolve_macros.py script is still written by Claude during the pipeline when needed.${CLAUDE_PLUGIN_ROOT}/templates/writing/{mode}.md defines section structure, word budgets, evidence slots, and style constraints. Adding new modes requires only a new template file.