research-report
Two-mode research workflow. Same engine, two output destinations.
When to use
Trigger on:
$workbench:research-report official <topic> — Codex official mode (files written, persistent)
$workbench:research-report scan <topic> — Codex scan mode (chat reply only, ephemeral)
/workbench:research <topic> — official mode (files written, persistent)
/workbench:scan <topic> — scan mode (chat reply only, ephemeral)
- Natural language: "research X", "deep dive on Y", "give me a quick read on Z", "scan W", "what's the state of V", "write up findings on U"
Skip when:
- Quick fact lookup → use WebSearch directly
- Single-link extraction → use WebFetch directly
- Code question about a known library → use docs lookup
- Anything where the answer is one paragraph → just answer inline
The two modes
Official mode (/workbench:research)
Full pipeline: research, write notes, synthesize report, render HTML, open in browser.
End state: exactly two files in research/<umbrella>/<title>/:
notes.md — consolidated raw research dump (one file even if many sources covered)
report.html — polished, designed, render-ready
Hidden in .build/ subdirectory: report.qmd source, quarto cache. Never visible to user.
Scan mode (/workbench:scan)
No files. Replies in chat with structured markdown:
## Key findings
- Bullet 1 (the punchline, not the setup)
- Bullet 2
- Bullet 3
## Sources
- [Link with one-liner of why it's relevant]
- [Link with one-liner of why it's relevant]
## Caveats / what I didn't check
- Honest one-liner about gaps
---
*Want me to save this as an official research report? Reply yes and I'll promote.*
If user confirms, transition to official mode using the same findings (write notes.md, synthesize report.qmd, render).
The convergence rule (official mode)
Final state, no exceptions:
<project-root>/research/<umbrella>/<title>/
notes.md ← single consolidated raw dump
report.html ← rendered polished read
.build/ ← hidden: qmd source, cache (gitignored)
Title = lowercase-kebab-case slug from the topic. "Replaydeck Reddit Positioning" → replaydeck-reddit-positioning.
If the project has a .gitignore, ensure /research is in it. Add it if missing.
Umbrella domains
Pick the closest match. If two could fit, ask the user. If none fit, ask them to add a new one to this list.
| Umbrella |
When to use |
marketing |
Competitive analysis, positioning, channel research, audience mapping, launch planning |
uiux |
UI patterns, design references, interaction studies, accessibility, design system research |
engineering |
Library evaluation, architecture choices, build tooling, infra, framework comparison |
product |
Feature scope, user needs, market sizing, pricing |
design |
Brand, visual systems, typography, iconography, motion |
ml |
Model evaluation, datasets, papers, benchmarks |
ops |
Deployment, monitoring, performance, scaling, oncall |
legal |
IP, licensing, ToS, compliance, GDPR |
competitive |
Direct competitor deep-dives across categories |
research-meta |
Fallback when no other category fits |
Workflow
Phase 0: Bootstrap (official mode only)
Run scripts/bootstrap.sh from this skill's directory. It checks for Quarto at ~/.local/share/quarto/bin/quarto and installs if missing. Skip silently if already installed.
Portability constraint — do not regress. The template at templates/_quarto.yml and templates/report.qmd both set embed-resources: true. This is required: the rendered report.html is a single self-contained file (CSS, JS, fonts, images all inlined as base64). Without this, Quarto produces report.html plus a sibling report_files/ directory of assets — and the moment the user shares just the HTML over chat, email, or any single-file channel, every stylesheet and script 404s on the recipient's machine. If you ever modify the template format block, keep embed-resources: true. To verify after a render: grep -cE '(src|href)="https?://' report.html should return 0 (or only return content links, not asset deps).
Phase 1: Plan
- Parse the topic from
$ARGUMENTS when invoked through a Claude command, or from the user's current message when invoked in Codex or natural language.
- Pick the umbrella domain. Ask if ambiguous.
- Slugify the title: lowercase, kebab-case, no special chars, ~3–6 words max.
- Decide which sources to cover based on the topic. Examples:
- Marketing/competitive → Reddit (if Reddit MCP available), web search, ProductHunt, IndieHackers, HackerNews
- Engineering → GitHub, npm/PyPI/crates, package docs, web search
- UIUX → web search, Mobbin/Dribbble references, design blogs
- ML → arXiv, paperswithcode, GitHub, web search
- Always include web search as a baseline
- State the plan to the user in 2–3 sentences before starting (umbrella, slug, sources). Don't ask permission unless ambiguous — just proceed.
Phase 2: Research (maximum surface area)
For each source, use the appropriate tool. Be exhaustive — depth before breadth. Capture:
- Primary findings (what you actually learned)
- Quotes with attribution
- Direct links to sources
- Numerical data where available (engagement, dates, counts)
- Caveats (rate limits hit, paywalls, sources missed)
If a Reddit MCP is available and the topic is Reddit-relevant: respect the 10 req/min rate limit (7-second pacing), sequential calls only, plan each call with a specific question.
When parallel reporter agents become available (Phase 2 of skill development), dispatch them here. For now, do the research inline.
Phase 3: Consolidate (official mode)
Run scripts/new.sh <umbrella> <slug>. This:
- Creates
research/<umbrella>/<slug>/.build/
- Copies templates (
_quarto.yml, styles.scss, report.qmd) into .build/
- Stubs
notes.md at the top level
- Adds
/research to project .gitignore if missing
Fill in notes.md with the structure:
# Research notes — <Topic Title>
> Raw data dump, blog format. Source for the polished report.
**Date:** YYYY-MM-DD
**Umbrella:** <umbrella>
**Sources covered:** <list>
---
## From <source 1>
[everything found from this source — links, quotes, raw data, screenshots referenced]
## From <source 2>
[same]
...
One section per source. Be generous with raw data — this is the source of truth for the report.
Phase 4: Synthesize (official mode)
Edit .build/report.qmd. The template provides:
- Frontmatter (theme, layout, TOC config)
- Section scaffolds you fill in
- Visual primitives (badges, stat-grid, bar-chart, callouts)
Sections to populate, adapting to the topic:
- Report metadata strip — window, sources, method, author
- Executive summary — 3–5 sentence overview, then a
.callout-tip with the one-line recommendation
- Headline numbers — 3–4 stat cards in a
.stat-grid (the most important numbers)
- Methodology — short paragraph: window, sources, queries
- Findings sections — one section per major finding theme. Use:
- Markdown tables for comparison data
.bar-chart for engagement/score comparisons
- Mermaid diagrams (
flowchart, gantt, graph) for flows and timelines
.callout-warning / .callout-important for risks
.callout-tip / .callout-note for opportunities
<span class="badge badge-..."> for status labels (avoid/wait/medium/post/clean/blocked)
- Recommendations / action plan — concrete steps with timing
- Methodology notes —
.methodology block with detailed query log
Design rules:
- No emojis. Use text labels, badges, and styled spans only.
- Confident, declarative tone. Past tense for what was found, present for recommendations.
- Tables are first-class data viz. Use them generously.
- Mermaid for any graph/flow/timeline.
- Keep paragraphs tight; favor lists when there are >3 items.
Phase 5: Render (official mode)
Run scripts/render.sh <umbrella> <slug>. This:
- Runs
quarto render on .build/report.qmd
- Moves the output to
research/<umbrella>/<slug>/report.html (top level of project)
- Opens
report.html in the default browser
If render fails, surface the error to the user with the relevant lines.
Phase 6: Reply (scan mode only)
Skip Phases 3–5 entirely. Reply in chat with the structured markdown shown above. End with the promote prompt.
Project root detection
Use the current working directory's git root if present:
git rev-parse --show-toplevel 2>/dev/null
Otherwise use the current directory. If neither makes sense (e.g., in ~), ask the user where to save, or default to ~/research-reports/<umbrella>/<title>/.
Re-runs
If research/<umbrella>/<slug>/ already exists, ask: "This research project exists. Update it (re-render with new findings appended) or replace (start fresh)?"
For updates: append to notes.md under a new dated section, update report.qmd, re-render.
For replaces: archive the old folder to .archive-<timestamp>/ first, then start fresh.
Templates and scripts
All assets live in this skill's directory:
skills/research-report/
templates/
_quarto.yml ← Quarto config (theme, TOC, layout)
styles.scss ← Typography, badges, bar-chart, callouts
report.qmd ← Section scaffolding for the report
scripts/
bootstrap.sh ← Verify/install Quarto
new.sh ← Scaffold a new research project folder
render.sh ← quarto render + open
Scope guards
- Never write files in scan mode unless the user confirms promotion.
- Never proliferate beyond
notes.md + report.html at the top level of the topic folder.
- Never put files outside
research/<umbrella>/<title>/ (no top-level scratch files).
- Never commit research —
/research is gitignored automatically.
- Always use existing umbrella domains unless the user explicitly adds a new one.
1---2name: research-report3description: Run a deep research dive on any topic and either produce a polished Quarto HTML report (official mode — files written to research/<umbrella>/<title>/) or reply with structured findings inline (scan mode — no files). Use when the user invokes $workbench:research-report, /workbench:research, /workbench:scan, or says "research X for me", "do a deep dive on X", "give me a quick read on X", "what's the state of X", "scan X for me", "write up findings on X". Covers maximum surface area across web, Reddit, GitHub, ProductHunt, docs, papers, and any other available sources. Always converges output to exactly notes.md + report.html (official mode) or a structured chat reply (scan mode). Never proliferates files.4---56# research-report78Two-mode research workflow. Same engine, two output destinations.910## When to use1112Trigger on:13- `$workbench:research-report official <topic>` — Codex official mode (files written, persistent)14- `$workbench:research-report scan <topic>` — Codex scan mode (chat reply only, ephemeral)15- `/workbench:research <topic>` — official mode (files written, persistent)16- `/workbench:scan <topic>` — scan mode (chat reply only, ephemeral)17- Natural language: "research X", "deep dive on Y", "give me a quick read on Z", "scan W", "what's the state of V", "write up findings on U"1819Skip when:20- Quick fact lookup → use WebSearch directly21- Single-link extraction → use WebFetch directly22- Code question about a known library → use docs lookup23- Anything where the answer is one paragraph → just answer inline2425## The two modes2627### Official mode (`/workbench:research`)2829Full pipeline: research, write notes, synthesize report, render HTML, open in browser.3031End state: exactly two files in `research/<umbrella>/<title>/`:32- `notes.md` — consolidated raw research dump (one file even if many sources covered)33- `report.html` — polished, designed, render-ready3435Hidden in `.build/` subdirectory: `report.qmd` source, quarto cache. Never visible to user.3637### Scan mode (`/workbench:scan`)3839No files. Replies in chat with structured markdown:4041```markdown42## Key findings43- Bullet 1 (the punchline, not the setup)44- Bullet 245- Bullet 34647## Sources48- [Link with one-liner of why it's relevant]49- [Link with one-liner of why it's relevant]5051## Caveats / what I didn't check52- Honest one-liner about gaps5354---55*Want me to save this as an official research report? Reply yes and I'll promote.*56```5758If user confirms, transition to official mode using the same findings (write `notes.md`, synthesize `report.qmd`, render).5960## The convergence rule (official mode)6162Final state, no exceptions:6364```65<project-root>/research/<umbrella>/<title>/66 notes.md ← single consolidated raw dump67 report.html ← rendered polished read68 .build/ ← hidden: qmd source, cache (gitignored)69```7071Title = lowercase-kebab-case slug from the topic. "Replaydeck Reddit Positioning" → `replaydeck-reddit-positioning`.7273If the project has a `.gitignore`, ensure `/research` is in it. Add it if missing.7475## Umbrella domains7677Pick the closest match. If two could fit, ask the user. If none fit, ask them to add a new one to this list.7879| Umbrella | When to use |80|---|---|81| `marketing` | Competitive analysis, positioning, channel research, audience mapping, launch planning |82| `uiux` | UI patterns, design references, interaction studies, accessibility, design system research |83| `engineering` | Library evaluation, architecture choices, build tooling, infra, framework comparison |84| `product` | Feature scope, user needs, market sizing, pricing |85| `design` | Brand, visual systems, typography, iconography, motion |86| `ml` | Model evaluation, datasets, papers, benchmarks |87| `ops` | Deployment, monitoring, performance, scaling, oncall |88| `legal` | IP, licensing, ToS, compliance, GDPR |89| `competitive` | Direct competitor deep-dives across categories |90| `research-meta` | Fallback when no other category fits |9192## Workflow9394### Phase 0: Bootstrap (official mode only)9596Run `scripts/bootstrap.sh` from this skill's directory. It checks for Quarto at `~/.local/share/quarto/bin/quarto` and installs if missing. Skip silently if already installed.9798> **Portability constraint — do not regress.** The template at `templates/_quarto.yml` and `templates/report.qmd` both set `embed-resources: true`. This is required: the rendered `report.html` is a single self-contained file (CSS, JS, fonts, images all inlined as base64). Without this, Quarto produces `report.html` plus a sibling `report_files/` directory of assets — and the moment the user shares just the HTML over chat, email, or any single-file channel, every stylesheet and script 404s on the recipient's machine. If you ever modify the template format block, keep `embed-resources: true`. To verify after a render: `grep -cE '(src|href)="https?://' report.html` should return `0` (or only return content links, not asset deps).99100### Phase 1: Plan1011021. Parse the topic from `$ARGUMENTS` when invoked through a Claude command, or from the user's current message when invoked in Codex or natural language.1032. Pick the umbrella domain. Ask if ambiguous.1043. Slugify the title: lowercase, kebab-case, no special chars, ~3–6 words max.1054. Decide which sources to cover based on the topic. Examples:106 - Marketing/competitive → Reddit (if Reddit MCP available), web search, ProductHunt, IndieHackers, HackerNews107 - Engineering → GitHub, npm/PyPI/crates, package docs, web search108 - UIUX → web search, Mobbin/Dribbble references, design blogs109 - ML → arXiv, paperswithcode, GitHub, web search110 - Always include web search as a baseline1115. State the plan to the user in 2–3 sentences before starting (umbrella, slug, sources). Don't ask permission unless ambiguous — just proceed.112113### Phase 2: Research (maximum surface area)114115For each source, use the appropriate tool. Be exhaustive — depth before breadth. Capture:116- Primary findings (what you actually learned)117- Quotes with attribution118- Direct links to sources119- Numerical data where available (engagement, dates, counts)120- Caveats (rate limits hit, paywalls, sources missed)121122If a Reddit MCP is available and the topic is Reddit-relevant: respect the 10 req/min rate limit (7-second pacing), sequential calls only, plan each call with a specific question.123124When parallel reporter agents become available (Phase 2 of skill development), dispatch them here. For now, do the research inline.125126### Phase 3: Consolidate (official mode)127128Run `scripts/new.sh <umbrella> <slug>`. This:1291. Creates `research/<umbrella>/<slug>/.build/`1302. Copies templates (`_quarto.yml`, `styles.scss`, `report.qmd`) into `.build/`1313. Stubs `notes.md` at the top level1324. Adds `/research` to project `.gitignore` if missing133134Fill in `notes.md` with the structure:135136```markdown137# Research notes — <Topic Title>138139> Raw data dump, blog format. Source for the polished report.140141**Date:** YYYY-MM-DD142**Umbrella:** <umbrella>143**Sources covered:** <list>144145---146147## From <source 1>148149[everything found from this source — links, quotes, raw data, screenshots referenced]150151## From <source 2>152153[same]154155...156```157158One section per source. Be generous with raw data — this is the source of truth for the report.159160### Phase 4: Synthesize (official mode)161162Edit `.build/report.qmd`. The template provides:163- Frontmatter (theme, layout, TOC config)164- Section scaffolds you fill in165- Visual primitives (badges, stat-grid, bar-chart, callouts)166167Sections to populate, adapting to the topic:1681691. **Report metadata strip** — window, sources, method, author1702. **Executive summary** — 3–5 sentence overview, then a `.callout-tip` with the one-line recommendation1713. **Headline numbers** — 3–4 stat cards in a `.stat-grid` (the most important numbers)1724. **Methodology** — short paragraph: window, sources, queries1735. **Findings sections** — one section per major finding theme. Use:174 - Markdown tables for comparison data175 - `.bar-chart` for engagement/score comparisons176 - Mermaid diagrams (`flowchart`, `gantt`, `graph`) for flows and timelines177 - `.callout-warning` / `.callout-important` for risks178 - `.callout-tip` / `.callout-note` for opportunities179 - `<span class="badge badge-...">` for status labels (avoid/wait/medium/post/clean/blocked)1806. **Recommendations / action plan** — concrete steps with timing1817. **Methodology notes** — `.methodology` block with detailed query log182183Design rules:184- **No emojis.** Use text labels, badges, and styled spans only.185- Confident, declarative tone. Past tense for what was found, present for recommendations.186- Tables are first-class data viz. Use them generously.187- Mermaid for any graph/flow/timeline.188- Keep paragraphs tight; favor lists when there are >3 items.189190### Phase 5: Render (official mode)191192Run `scripts/render.sh <umbrella> <slug>`. This:1931. Runs `quarto render` on `.build/report.qmd`1942. Moves the output to `research/<umbrella>/<slug>/report.html` (top level of project)1953. Opens `report.html` in the default browser196197If render fails, surface the error to the user with the relevant lines.198199### Phase 6: Reply (scan mode only)200201Skip Phases 3–5 entirely. Reply in chat with the structured markdown shown above. End with the promote prompt.202203## Project root detection204205Use the current working directory's git root if present:206207```bash208git rev-parse --show-toplevel 2>/dev/null209```210211Otherwise use the current directory. If neither makes sense (e.g., in `~`), ask the user where to save, or default to `~/research-reports/<umbrella>/<title>/`.212213## Re-runs214215If `research/<umbrella>/<slug>/` already exists, ask: "This research project exists. Update it (re-render with new findings appended) or replace (start fresh)?"216217For updates: append to `notes.md` under a new dated section, update `report.qmd`, re-render.218For replaces: archive the old folder to `.archive-<timestamp>/` first, then start fresh.219220## Templates and scripts221222All assets live in this skill's directory:223224```225skills/research-report/226 templates/227 _quarto.yml ← Quarto config (theme, TOC, layout)228 styles.scss ← Typography, badges, bar-chart, callouts229 report.qmd ← Section scaffolding for the report230 scripts/231 bootstrap.sh ← Verify/install Quarto232 new.sh ← Scaffold a new research project folder233 render.sh ← quarto render + open234```235236## Scope guards237238- **Never write files in scan mode** unless the user confirms promotion.239- **Never proliferate beyond `notes.md` + `report.html`** at the top level of the topic folder.240- **Never put files outside `research/<umbrella>/<title>/`** (no top-level scratch files).241- **Never commit research** — `/research` is gitignored automatically.242- **Always use existing umbrella domains** unless the user explicitly adds a new one.