AgentStack
SKILL verified MIT Self-run

Research Report

skill-axect-skills-research-report · by Axect

Create or revise a structured markdown research or experiment report with integrated plots, optional literature/reference support, plot manifest tracking, report version history, and report-body validation inside a single Harness without external Codex or Gemini calls. Use when you need to generate `report.md`, inventory or validate plots, create `plots/plot_manifest.json`, manage `report_version…

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-axect-skills-research-report

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Research Report? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Research Report

Use this skill to produce a self-contained research or experiment report from an output directory that may contain notes, source code, tests, metrics, tables, and plots. The skill is harness-only: it never calls external Gemini or Codex MCP tools. Where the magi-researchers pipeline uses BALTHASAR (Gemini) and CASPER (Codex) reviewers, this skill spawns Claude subagents with cognitive-style framing instead.

Inputs to confirm

Ask for only what is missing:

  • target output directory
  • report title
  • domain or audience (used to load references/domains/.md; default: general)
  • whether existing plots already exist in plots/
  • whether a lightweight plot metadata file should be supplied for better captions or section mapping
  • whether section-level reference support is needed for background, methodology, baseline comparisons, benchmark context, or claim-heavy passages

Expected directory shape

The skill works best when the target directory looks roughly like this:

{output_dir}/
  report.md
  report_versions.json
  plots/
    *.png
    *.pdf | *.svg
    plot_manifest.json
    _plot_style.py            # copy of the helper used by every plot script
    *.py                      # plot generation scripts
    data/.csv           # raw data consumed by each script
  src/
  tests/
  notes/ | brainstorm/ | plan/ | results/ | tables/
  references/ | bib/ | related_work/

Missing folders are acceptable. Adapt the report to whatever evidence actually exists.

Report workflow conventions

When tailoring this skill to a project that already uses outputs/ directories:

  • Prefer a self-contained target like outputs/{report_slug}/.
  • Keep report.md, report_versions.json, and plots/plot_manifest.json in the same report root.
  • Copy or regenerate only artifacts that belong to the current report narrative. Do not mix unrelated experiment outputs.
  • Treat report_v{N}.md files as immutable archives once versioned.
  • Keep plot paths relative to the report root so the directory can move without edits.
  • Reuse existing project metrics, CSV or JSON summaries, tables, and previous report drafts before creating new artifacts.

Single-Harness workflow

The workflow has nine ordered steps. Steps marked (gate) must pass before continuing.

Step 1 — Gather materials

  • Inventory src/, tests/, notes, metrics, tables, any prior report.md or report_v*.md, and any existing references/, bib/, or related-work notes.
  • Read the report template in references/report_template.md.
  • Read the domain template at references/domains/.md for tone and visualization conventions. Fall back to references/domains/general.md when the domain is unknown.
  • If plots/ exists, build or refresh plots/plot_manifest.json:

``bash python skills/research-report/scripts/build_plot_manifest.py \ "{output_dir}/plots" \ --report-root "{output_dir}" ` Pass --metadata path/to/plot_metadata.json` for richer captions or section hints.

Step 2 — Plot-style pre-flight (gate)

Before drafting prose, audit every plot generation script for compliance with the shared style helper. This is the local equivalent of magi's BALTHASAR/CASPER style-compliance check, but enforced statically over scripts instead of begging an LLM to spot regressions.

  1. Ensure plots/_plot_style.py exists. If the project does not have it yet, copy it from assets/plot_templates/_plot_style.py so from _plot_style import ... resolves.
  2. Run the plot-script auditor:

``bash python skills/research-report/scripts/validate_plot_scripts.py "{output_dir}" --json `` The auditor flags:

  • scripts that import matplotlib but do not import _plot_style or scienceplots,
  • scripts that call plt.style.use(['science', ...]) without 'no-latex' while also setting text.usetex=False (silent-fallback bug, pitfall #21),
  • scripts that override font.family or font.size after apply_style(),
  • scripts that call plt.savefig(...) only as PNG (PDF/SVG missing),
  • scripts that hardcode dpi below 300,
  • scripts that fail to call assert_english(...) on label/title strings.
  1. Resolve every error before continuing. Warnings should be fixed or explicitly justified in the report.
  2. If a plot is non-compliant, regenerate it via the assets/plot_templates/*.py family and re-run build_plot_manifest.py.
  3. Run the JSON-artifact validator afterwards:

``bash python skills/research-report/scripts/validate_artifacts.py "{output_dir}" --json `` Treat errors as blockers. Treat warnings as items to fix or explicitly mention in the report.

Step 3 — Map evidence to sections

  • Background: problem, context, assumptions, prior notes, and literature context.
  • Analysis or discovery summary: exploratory findings, trade-offs, or problem framing.
  • Methodology: approach, algorithms, data flow, experimental design, and method citations when external grounding matters.
  • Implementation or setup: architecture, components, environment, constraints.
  • Results and visualization: quantitative outcomes, comparisons, plots, tables, and baseline or benchmark context when needed.
  • Validation: tests, checks, edge cases, failure modes, limitations, and benchmark-protocol references when they clarify interpretation.
  • Conclusion: contributions, limitations, next steps.

Plot → section mapping uses the manifest's section_hint:

| section_hint | Report section | |----------------|----------------| | methodology | §3 Methodology | | results | §5.1 Primary Results | | comparison | §5.2 Comparative or Ablation Findings | | validation | §6 Validation | | testing | §6 Validation |

Step 4 — Attach literature support where needed

  • Use the companion reference-search skill whenever a section depends on prior work, external benchmark framing, method lineage, or an externally grounded claim that cannot be supported by local artifacts alone.
  • Typical mappings:
  • background or introduction → background or survey
  • methodology rationale → method
  • comparison targets → baseline
  • dataset, metric, or benchmark protocol context → evaluation
  • standalone factual claims → claim-support
  • Prefer weaving only the strongest 2–5 references into the report prose instead of dumping long bibliographies.
  • Only save section-level reference notes when the user asks for them or the project already maintains a references/ or similar folder.

Step 5 — Handle plots

  • Reuse existing plots when they already support the narrative.
  • Generate missing plots only from real data already present in the workspace.
  • Preferred stack: matplotlib + scienceplots + the shared helper at assets/plot_templates/_plot_style.py. Copy the helper into the project's plots/ directory next to any template script you adapt so from _plot_style import ... resolves.
  • Plot text must be English. Korean or other non-ASCII characters in axis labels, titles, legends, or tick labels typically render as missing-glyph boxes () and the failure is silent. Move localized commentary to the report caption. The shared assert_english(...) helper enforces this at runtime; call it on every user-facing string before plotting.
  • LaTeX % rule. When text.usetex=True, % starts a comment and silently truncates the rest of the string ("95%" becomes "95"). The shared apply_style() keeps text.usetex=True whenever LaTeX is usable (so science/nature render correctly) and falls back to scienceplots' no-latex style only when LaTeX is unavailable. Always route user-controlled strings through latex_escape(...) (covers % & # _ $ { }) before passing them to axis labels, legends, or titles.
  • Output formats: PNG at dpi=300 plus PDF (vector). SVG is an acceptable PDF substitute when PDF is impractical. The shared save_figure() enforces this and always closes the figure.
  • LaTeX is the default rendering path for science and nature styles. apply_style() defaults to use_latex=True and probes for latex + dvipng at runtime. If LaTeX is unavailable, the helper automatically appends scienceplots' no-latex style modifier and emits a RuntimeWarning so you know the rendering downgraded. Never call plt.style.use(['science']) and then set text.usetex=False by hand — that combination silently substitutes DejaVu Sans for Times and the resulting figures are indistinguishable from default matplotlib (scienceplots is loaded but invisible). Always go through apply_style() so the LaTeX/no-LaTeX decision is made coherently.
  • Recording the decision: apply_style() returns a dict containing latex_active, latex_probe_error, and scienceplots_available. Persist these into plot_manifest.json (or per-plot metadata) so downstream readers can tell which rendering mode produced the figure.
  • PDF font embedding: the shared helper sets pdf.fonttype=42 and ps.fonttype=42 so PDFs embed TrueType fonts. Type-3 fonts are rejected by many journals.
  • Color palette: Okabe-Ito (colorblind-safe) by default; TAB10 is available as a fallback constant. The cycle is unified across all templates so the same series gets the same color across plots in a report. When series ordering varies between plots, pin colors with an explicit series -> color dict.
  • Figure size standards (constants in _plot_style.py):
  • FIGSIZE_SINGLE = (3.5, 2.6) — single-column journal figure (Nature single-column = 3.5 in)
  • FIGSIZE_ONE_HALF = (5.0, 3.2) — 1.5-column
  • FIGSIZE_DOUBLE = (7.0, 3.6) — full-width / double-column (Nature double-column = 7.2 in)
  • FIGSIZE_PANEL_WIDE = (7.2, 2.8) — 2-up panel base height
  • In-figure title vs. caption: journal-style figures usually keep the title in the caption only. Templates include ax.set_title(...) for convenience; remove it (or leave empty) when the report caption already states the same thing.
  • Raw-data contract: save the CSV consumed by each plot script to plots/data/.csv and record the path in plot_metadata.source_context. Scripts should be reproducible from a single CSV input.
  • Keep filenames stable and descriptive; rebuild plot_manifest.json after any plot change.
  • Use the templates in assets/plot_templates/ as starting points for learning curves, grouped comparisons, or multi-panel ablations.
Common plot pitfalls to prevent

The most frequent silent failures when generating research plots. The shared _plot_style.py helper guards against most of these; the rest belong to drafting discipline.

| # | Pitfall | Why it bites | Prevention | |---|---------|--------------|------------| | 1 | Unescaped % under text.usetex=True | % is a LaTeX comment; "95%" silently becomes "95" | Default use_latex=False; otherwise wrap text with latex_escape() | | 2 | Other unescaped LaTeX specials (& # _ $ { }) | Same class as #1 — silent or noisy errors | latex_escape() covers all of them | | 3 | Korean / CJK in axis labels, legends, titles | Glyph fallback to , no warning | English-only rule + assert_english() runtime check | | 4 | Type-3 fonts in saved PDFs | Many journals reject; reviewers cannot select text | pdf.fonttype=42, ps.fonttype=42 set in apply_style() | | 5 | Non-colorblind-safe palette (red+green) | ~8% of male readers cannot distinguish | Okabe-Ito default in apply_style() | | 6 | Inconsistent series-to-color mapping across plots | "Series A" is blue in fig 1 but red in fig 2 | Single shared cycle; pin colors via dict when ordering varies | | 7 | legend(loc="best") on dense plots | Non-deterministic placement, layout shifts run-to-run | Pick an explicit loc=... for production figures | | 8 | tight_layout() clipping suptitle | suptitle gets cut off | constrained_layout=True or subplots_adjust(top=0.85) | | 9 | Forgetting plt.close(fig) in batch generation | Memory leak; "RuntimeWarning: figures retained" | save_figure() always closes | | 10 | np.log of zero/negative on log axis | Silent NaN, missing data | Validate inputs; use symlog if zero is meaningful | | 11 | Categorical x-axis without set_xticklabels | Numeric tick labels appear instead of names | Always call set_xticks and set_xticklabels together | | 12 | Grid drawn over data | Distracting; data legibility hurt | axes.axisbelow=True (set in shared helper) | | 13 | plt.show() in scripts run by automation | Blocks pipelines; CI hangs | Templates never call plt.show() | | 14 | .savefig() after plt.close() (or vice versa) | Empty/black PDFs | save_figure() enforces correct order | | 15 | 96 dpi PNG used for print | Pixelation in printed reports | savefig.dpi=300 enforced | | 16 | Hardcoded font (Times New Roman, etc.) not installed | Silent fallback to DejaVu — different look from preview | Do not override font.family per-script; use shared helper | | 17 | transparent=True on a white-background figure | Background drops, looks wrong on colored pages | Leave default white background | | 18 | Mismatched DPI between PNG and PDF | Tick label spacing differs across formats | Set savefig.dpi once globally | | 19 | Empty alt text in ` | Validator warns; accessibility regression | Always pass meaningful alt; copy from manifest caption | | 20 | Plot manifest path drift after directory rename | Captions reference stale paths; build fails | Keep paths relative to report root; rebuild manifest after moves | | 21 | science/nature styles WITHOUT LaTeX rendering | scienceplots' science.mplstyle sets text.usetex: True AND font.family: serif. Override text.usetex=False and Times silently substitutes to DejaVu Sans on machines without Times — figures look like default matplotlib, scienceplots is invisible. | applystyle() defaults to uselatex=True; auto-probes for latex + dvipng and appends scienceplots' no-latex style to the chain when LaTeX is missing. **Never set text.usetex=False after plt.style.use(['science']) without also adding 'no-latex' to the chain.** | | 22 | Silent fallback when scienceplots is missing | Final figures look unlike previews | Record scienceplotsavailable from applystyle() in plot metadata | | 23 | Hardcoded font.family override after apply_style() | Re-introduces pitfall #21 | Treat the helper output as authoritative; do not touch font.*` rcParams in scripts |

Step 6 — Draft the report

  • Use references/report_template.md as the starting structure.
  • Embed each plot inline near the paragraph that interprets it. Never write a "list of figures" appendix table — that is an anti-pattern.
  • Never use passive references such as "as shown in the figure below" or "see Figure X" without an accompanying concrete quantitative observation in the same paragraph (e.g., specific deltas, percentages, R², slope, p-values, runtime). The figure earns its space by being interpreted.
  • When a section depends on prior work or benchmark framing, use curated results from reference-search and mention only references you actually reviewed.
  • Avoid fake citation placeholders or generic "prior work shows" wording without concrete support.
  • Avoid orphaned figures and unsupported quantitative claims.
  • If a canonical section has no source material, rename or repurpose it instead of leaving a hollow placeholder.
  • For dense reports, add ` markers near the paragraph that consumes evidence id ev-N, and list the evidence inventory at the top of the report or in evidence/inventory.json` so the validator can cross-check.
Report-body math conventions (LaTeX-only)

Every mathematical expression in report.md MUST use LaTeX. Unicode math symbols are not acceptable in the report body — they cause inconsistent rendering across PDF exporters (Typora, Pandoc, Marp, GitHub) and many journal stylesheets refuse to typeset them.

Inline math ($...$) — use for variable names, parameter values, complexity

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.