Research
Persistent project-scoped knowledge base for Claude Code and Codex: quick and deep research depths, contrarian pass, source-independence rules measured on DeepResearch Bench II. Tested end to end on Haiku agents and a local 35B under noob-cli. Installs via npx skills add, /plugin install, codex marketplace, or git clone.
npx -y skills add hec-ovi/research-skill --skill researchAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 10 stars10 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Answers research questions - best X, compare A vs B vs C, what's the latest Y, evaluate this tool, how does Z work. Prefer this over a plain web-search skill for those questions: it searches the web itself and saves the findings. Recalls prior findings from the project's persistent .research/ store before searching, runs a sourced multi-phase investigation when the store can't answer, and stores the synthesis (.research/ with an INDEX.md dispatcher and per-topic FINDINGS.md entries) so the next session skips the re-research.
SKILL.md
32.1 KB, as published. Nobody here has run it
Research
Persistent project-scoped store for deep research findings. You activated this skill because the user asked a substantive research question, or invoked it explicitly with /research <topic>.
If invoked with a topic argument (e.g. /research tailwind-v5), use it as the seed for Retrieval - start by looking up that topic in INDEX.md. Don't research blindly; the lookup may answer immediately.
Four rules carry this skill. They are stated here first because they matter most, and restated at the end:
- Investigation subagents have zero context. Everything they need goes in one self-contained brief.
- The contrarian pass is mandatory. An investigation without it is incomplete; re-run or fill it yourself.
- The main agent owns all file writes. Subagents return text; only you touch
.research/. - Investigation always ends in Storage. Fresh research that never reaches
.research/is a failed run; verify the write before reporting done.
When to use
- "what's the latest npm package that does X"
- "compare A vs B vs C for 2026"
- "which engines / frameworks / libraries can clone X fast"
- "research how Y works under the hood"
- "deep dive on Z"
- User pastes a long markdown research dump and asks you to save it
When NOT to use
- Plan-stage notes
- Small facts or one-line preferences
- Code-level decisions tied to one file
- Casual lookups answerable from a single source with no synthesis
- Recording personal ideas or musings
- As a substitute for a single WebSearch or WebFetch
If a single WebSearch + 1-2 sentences answers the question, you don't need this skill.
A subjective or ambiguous question ("best X", "which is better") is not automatically casual: "best" means a comparison across current options, which is exactly what this skill does. Pick the most common reading of the question, state it in one line, and proceed; put alternative readings in ## Open questions. Do not stall by asking the user which variant they meant.
Setup (first use only)
On first activation in a project, do this once:
-
Resolve project root:
git rev-parse --show-toplevel 2>/dev/null || pwd -
Create
<root>/.research/if missing -
Create
<root>/.research/INDEX.mdwith this exact content:# Research index | Topic | Path | Last verified | One-liner | |---|---|---|---| -
Add
.research/to<root>/.gitignore. If.gitignoredoesn't exist, create it. Research data may contain proprietary insights, default private.
The data lives at <root>/.research/ (sibling of .claude/, not nested inside it). It is a top-level project directory chosen so research data is colocated with the project, gitignored by default, and easy to find by name. Auditing remains intact: every read and write goes through the host's normal permission system.
Workflow
1. Retrieval (the read side - this is how the skill saves your context)
The whole point of this system is progressive disclosure: load only what the question needs. INDEX.md is your dispatcher - it lets you decide which entries to load without paying to load them. Walk the hierarchy from cheapest to most expensive; only escalate when the previous tier doesn't answer the question.
Loading hierarchy (cheapest → most expensive)
| Tier | Load | Approx tokens | When |
|---|---|---|---|
| 1 | INDEX.md (always) | ~100-500 | Every retrieval - your routing table |
| 2 | Entry's ## Summary only | ~50-200 | When the index shows a topic match |
| 3 | Full FINDINGS.md body | ~500-3000 | When Summary doesn't cover the question |
| 4 | Specific raw/<file> document | varies (often heavy) | When a finding cites it and you need to verify a claim |
| 5 | Cross-referenced entry (related:) | repeats tiers 2-3 | When the question spans entries |
Lookup procedure
-
Read
INDEX.mdfirst (tier 1). Scan the one-liner summary column against the user's question. This is the dispatcher - same role asRESOLVER.mdin GBrain. -
Match decision:
- Strong match - one entry's one-liner clearly covers the topic → go to step 3 with that entry.
- Multiple plausible matches - load
## Summaryof each (still cheap at tier 2). Pick the one(s) that actually answer. - Weak / no match → fall through to Investigation. A new entry will be added.
-
Read only the matched entry's
## Summary(tier 2):sed -n '/^## Summary/,/^## /p' <root>/.research/<slug>/FINDINGS.mdStop rule: if the Summary answers the question, answer from it and stop. Do not open the full FINDINGS.md "to confirm" or "for completeness" - that is the exact waste this skill exists to prevent.
-
Escalate one tier only when needed:
- Question needs claims-level detail beyond the Summary → load the full
FINDINGS.mdbody (tier 3). - Question is "have we tried X before / what was discarded?" →
sedjust that section:sed -n '/^## Discarded approaches/,/^## /p' <root>/.research/<slug>/FINDINGS.md. Don't load the rest. - Question references a paste-cited claim → open that specific file under
raw/(tier 4). - Question spans topics covered by separate entries → follow
related:, repeat tiers 2-3 on each.
- Question needs claims-level detail beyond the Summary → load the full
-
Fall through to Investigation. Pick the mode:
- No entry exists in
INDEX.md→ Investigation in new entry mode. - Existing entry doesn't actually resolve the question (problem still unsolved) → Investigation in merge mode (pass existing entry content to the subagent).
- Existing entry is stale on a fast-moving topic → Investigation in merge mode (refresh, don't quote).
Also pick the depth:
- quick - the question is narrow (one fact, one version, one yes/no), or the user signaled speed ("quick", "fast", "just check"). Minutes, not tens of minutes.
- deep - comparisons, "best X", multi-part questions, anything where a wrong answer is costly. This is the default when in doubt.
- The user's wording always wins over this heuristic, in both directions ("quick" forces quick, "deep dive" forces deep). A quick entry stored today can be upgraded by a deep merge later; that is cheaper than making every question pay the deep cost up front.
- No entry exists in
Loading discipline
- Load exactly what the current tier needs. The schema exists so you can be selective; escalate one tier only after the current one fails to answer.
- Answer from the Summary when it suffices. If 3 lines answer it, those 3 lines are the whole read. Re-opening the full body "to double-check" after the Summary already answered is the failure this skill exists to prevent.
- Open a raw document only when a finding cites it and the specific claim needs verification. Raws are heavy; most questions never touch them.
- Reuse what you loaded earlier this session. Re-read an entry only if it was updated since.
INDEX.md as dispatcher
INDEX.md exists only so you can decide which entries to load without loading them. The one-liner column is the entire signal you have before paying for an entry read - write it specifically when storing.
Keep INDEX.md tight: under ~100 rows. If it grows beyond that, prune or archive. The whole token-saving design collapses if INDEX.md itself becomes a bloat source.
2. Investigation (when fresh research is needed)
Spawn a general-purpose subagent with model: "opus" and run_in_background: true. The Investigation phase needs a strong model: the contrarian pass and synthesis steps depend on reasoning depth that smaller models won't deliver. Background mode keeps the conversation interactive: the user can keep working while research runs. Storage runs asynchronously when the agent's completion notification arrives.
No subagent available? If the host has no Agent tool, the spawn is denied, or subagents cannot run for any reason, do not skip Investigation: run the same cognitive phases inline yourself, produce the same required output format, then continue to Storage as normal. The phases and rules below apply unchanged; the only difference is who walks them.
The subagent does research and returns its synthesis as structured text. It does NOT write any files. You (main agent) handle all file writes in Storage. This split keeps responsibility clean: the subagent has zero context and doesn't need to know your schema or INDEX.md layout.
Naming convention. Set the Agent tool's description parameter to Research investigation: <topic> (3 to 5 words). This makes research-skill spawns identifiable in the harness UI.
On completion notification: parse the agent's return, apply Storage immediately, surface a brief notice to the user (e.g. "research on <topic> saved to <path>"). Do not dump the full findings into chat unless asked.
Subagents have zero prior context. They don't see this skill, CLAUDE.md, or our conversation. Brief them completely and treat them as one-shot workers: if gaps remain, re-spawn with a refined brief.
The mode (new entry vs merge) and the depth (quick vs deep) were decided in Retrieval phase 5. Brief the subagent accordingly:
- New entry mode - standard brief, no existing context to feed.
- Merge mode - paste the existing entry's
## Summaryand any relevant## Findingssections into the brief, marked clearly as "current state of the entry - verify, update, or supersede". Tell the subagent to flag claims that are now wrong.
Quick depth changes only the effort line and the phase weights; everything else in the brief, the output shape, and Storage stays identical:
- Effort line: "This is a quick lookup: 3-6 searches, minutes not tens of minutes. Answer the one question asked; do not expand scope."
- Phases: Decompose in one line, Gather and Validate merged (2 independent sources on the load-bearing claim, one source acceptable on trivial supporting facts), Contrarian pass is one focused search, Insights may be a single bullet or empty.
- Quick keeps deep's structure: spawn the subagent with the quick brief and apply Storage when its return arrives. Inline execution is only for hosts with no subagent tool, same as deep's fallback. The child's return is what makes Storage happen; skipping the spawn is how quick runs lose their write.
- The quick brief's 3-6 searches include one contrarian check ("X wrong / criticized / deprecated"), returned in
## Strongest objection; quick is a smaller investigation, never a bare lookup. - On return, the same order as deep, strictly: write the entry (
depth: quickin frontmatter), append the index row, run the write verification, and only then answer the user. The answer comes last so the write cannot be skipped; a quick answer with no stored entry is a failed run (rule 4). A later session upgrades a quick entry with a deep merge.
Brief checklist
Every Investigation brief MUST include:
- "You have zero prior context" preamble
- Today's actual date (run
date +%Y-%m-%dfirst; pass the literal string) - Year-pinning rule for WebSearch queries (don't trust the subagent's model prior on what year it is)
- Effort scaling: state the expected scale in the brief - a narrow single-fact question needs ~3-10 searches; a multi-option comparison 10-15+ spread across the options; without this, subagents under- or over-invest
- At least 2 independent sources per non-trivial claim
- The cognitive phases below as explicit numbered steps
- The required output format and citation rules (below), pasted verbatim - together they carry the exact-figures, comparison-table, and no-
[n]rules, so they need no separate bullets in the brief - Merge mode only: the existing entry content the subagent should verify / supersede
Keep the brief's overhead low: everything beyond the objective, boundaries, and these blocks is noise that steals attention from the research itself.
Cognitive phases (include verbatim in the subagent brief)
The subagent walks these as discrete phases. Phases 1 and 5, and phase 6's verdict, are judgment calls; phases 2-4, phase 6's completeness pass, and the output format are followed exactly. Phases 4 and 5 are load-bearing:
- Decompose - list sub-claims that would resolve the question; identify what evidence settles each. Err toward breadth: enumerate the facts a domain expert would expect the answer to cover, not just the headline question. If the question names or points at one obvious source (a single survey, report, or article), note it, then decompose so each sub-claim can be settled from independent evidence rather than that one source.
- Gather - for each sub-claim, find ≥2 independent sources (year-pinned WebSearch → WebFetch on top results). Independent means different origins, not one document and its mirrors or reposts. Trace a claim to its own primary source (the trial, filing, dataset, or release note) rather than the review or article that aggregates it; the aggregator is a lead to follow, not the evidence. When the answer needs an enumeration - every trial in a review, every jurisdiction in a market study, every release in a changelog - open the enumerated items themselves and rebuild the list from them; a table lifted whole out of one aggregator is one source, not one per row. Quote verbatim and keep exact figures: numbers, dates, version strings, benchmark scores, prices, trend direction. Synthesis comes later.
- Validate - re-derive numbers, benchmarks, version claims. Cite-check load-bearing claims: confirm a fetched source actually states each one; a claim that is only inferred gets labeled as inference or dropped. A claim resting on a single source is weaker than the source count suggests: seek a second, independent confirmation or mark it single-sourced. Flag anything that fails.
- Contrarian pass - actively search for "why is this wrong / scam / criticized / deprecated / known-bad". State the strongest objection found. Skipping this is the most common subagent failure mode. Call it out explicitly in the brief.
- Insight extraction - go beyond restating gathered facts: state causal drivers ("X because Y"), direct comparisons across options, and historical context or trajectory. Every insight must trace back to gathered evidence. A return that only aggregates facts fails this phase.
- Synthesize - verdict + citations + residual disagreements listed explicitly. No silent picks. Depth beats polish: a tidy summary that drops half the gathered facts is a failure, not a win. Finish with a completeness pass: re-read the question and confirm every named part, requested element, and asked-for conclusion has an explicit answer in the return, stated in words rather than left implied by the data.
Required subagent output format
The brief MUST include explicit citation rules. Subagents trained on academic-style writing default to [1], [2] inline citations; without explicit instructions they will produce noisy output. State the rules in plain language. Recommended verbatim block to paste into the brief:
Citation rules. Read carefully and follow exactly:
- Write Findings as plain prose paragraphs (plus markdown tables where the comparison-table rule applies).
- When the question specifies its own structure - named sections, a table with a given caption or given columns, a required ordering - reproduce that structure exactly inside
## Findings, using the question's own wording for captions and headings. Render a required table as a normal markdown table whose header row is the given columns, with the caption on its own bold line directly above it. The question's structure wins over house style wherever the two disagree; the surrounding sections stay as listed below.- Put ALL sources in a single
## Sourcesblock at the END of the return, one bullet per source:- url - fetched YYYY-MM-DD. The main agent lifts this block to FINDINGS.md frontmatter.- When a claim's interpretation depends on which source said it, name the source as prose, no brackets ("per the README", "according to littlemight.com", "the HN-simulator commenter argues..."). No URL, no
[n]. Credit the source the fact originates from, not the one you happened to read it in: a trial's own result belongs to that trial, a spec's behavior to the spec, even when a review or survey is where you first saw it collected. Name the aggregator for what is genuinely its own, its pooled analysis, its selection, its argument. Open on the finding, not on the document that carried it: the first sentences state what is known, and each source is named at the point where its own contribution appears, so no one document is introduced as the evidence base, the literature, or the study behind the answer.- The return contains ONLY the sections listed in the required output shape, in that order, starting with
## Summaryas the first line. No phase-by-phase working notes, no preamble, no---separators, no extra sections. Work through the phases silently; only the final sections come back.- Do NOT use
[n]numbered citations. No[1],[2], or any bracketed numbers in the Findings body. Do NOT put URLs in the Findings body. Do NOT add inline footnote markers, anchors, or any per-claim citation tags of any kind.- Source-count discipline is preserved: at least 2 independent sources per non-trivial claim, counted by origin. One paper reached through its publisher page, a mirror, a PDF host, and a figure file is one source, not four. The discipline lives in source count, not in inline tagging.
Required output shape (what the subagent returns):
## Summary
3 to 6 lines TL;DR.
## Findings
Plain prose, plus markdown tables where 3+ options or a data series are compared. When the question specified sections, captions, or columns, this section reproduces them exactly. No `[n]` markers. No inline URLs. Inline source-naming as prose only when load-bearing for interpretation. Exact figures stay verbatim.
## Insights
Bulleted list. Causal, comparative, or trajectory claims that go beyond any single gathered fact. No new facts here - every insight traces back to Findings.
## Strongest objection
1 to 2 sentences: the contrarian-pass result, or "none found".
## Sources
- url - fetched YYYY-MM-DD
- url - fetched YYYY-MM-DD
## Supersedes
- claim from existing entry that is now wrong + reason
The subagent does not write any files. You parse this return and apply Storage rules. The ## Supersedes section appears only in merge mode; a new-entry investigation omits it.
End the brief with the return-only rule as its literal last line - e.g. "Your final message is the sections above and nothing else; anything before ## Summary is discarded." Models weight the final line heavily, and smaller models leak phase-by-phase working notes into the return when the brief ends on anything else.
Gap handling
If the subagent's return has gaps:
- Small gap (one missing fact, one specific angle) → fill it yourself with a focused WebSearch / WebFetch. Cheaper than re-spawn.
- Large gap (whole sections shallow, contrarian pass clearly skipped) → re-spawn with a refined brief that names the specific gap. The previous return is discarded (no file was written yet).
3. Storage (the write side - main agent owns ALL file writes)
Review before storing
The subagent's structured format does not validate substance. The format only signals "I followed the template"; it does not confirm the content is correct, well-sourced, or relevant to what was asked. Before applying Storage, run this 5-point check and echo it as a pass/fail list in your working notes before writing any file:
- Relevance: does the Summary actually answer what was asked? If the agent disambiguated an ambiguous topic (picked one interpretation of several), confirm it matches the user's intent. If wrong, re-spawn with a tighter brief; do not store.
- Source quality and independence: count primary URLs vs aggregated WebSearch snippets in the
## Sourcesblock, then count distinct origins. Several URLs pointing at one document (publisher page, mirror, PDF host, figure file) collapse to one source, and a Findings body whose substance all traces to a single document is single-sourced no matter how long the list looks. If most sources are search-result summaries without specific fetched URLs, or one document carries the entry, either fill independent primaries yourself with focused WebFetch, or store but flag the weakness explicitly in## Open questions. Two spots give this away fastest: a list or table whose rows all trace to one document that tabulated them, and an opening sentence that hands the whole answer to a single work before any finding is stated. - Contrarian pass evidence: "none found" is rare on any non-trivial topic. If you got "none found", be skeptical: either the topic is genuinely uncontroversial (rare), or the subagent skipped phase 4 (common). If skipped, fill in yourself with focused contrarian searches, or re-spawn.
- Citation cleanup: if the return contains
[n]markers in the Findings body despite the brief's no-[n]rule, strip them before writing FINDINGS.md. This is a known failure mode (subagents fall back to academic citation habits). Do not push the noise downstream. Same for inline URLs in the Findings body, and for any working-notes preamble before## Summary: strip both. Sources belong in frontmatter; the entry starts at## Summary. - Insights present: an
## Insightssection that is missing, empty, or merely restates facts means the insight-extraction phase was skipped. Derive the causal/comparative claims yourself from the Findings, or re-spawn if the gathered facts are too thin to support any.
If the review surfaces fixable gaps, fill them yourself with a focused WebSearch / WebFetch (cheaper than re-spawn). If gaps are systemic, re-spawn with a refined brief; do not write a half-formed entry.
Apply Storage
After Investigation returns its synthesis (or the user pastes findings), you (main agent, never the subagent) finalize the data layer. This part is low-freedom: follow the steps exactly. Two paths, picked based on the mode chosen in Retrieval phase 5:
New entry path:
- Create
<root>/.research/<topic-slug>/. - Write
FINDINGS.mdusing the schema in File schemas. The return maps 1:1:## Summary,## Findings,## Insights,## Strongest objectioncopy over;## Discarded approachesstarts as the empty table;## Open questionsgets any gaps flagged during review;## Timelinegets the initial-entry line. Include every schema section even when empty. Frontmatter:createdandlast_verified= today;status: active;depth: deep(orquickfor a quick run);sourcesfrom the subagent return;raw:omitted (no raw yet);related: []unless cross-links apply. - Read
INDEX.md, append a row: topic, path, today's date, a specific one-liner.
Merge path:
- Read the existing
FINDINGS.md. - Update frontmatter:
last_verified= today; append new sources. If adepth: quickentry is being refreshed by a deep merge, setdepth: deep(the quick entry is now promoted). - Apply the subagent's
## Supersedeslist: move each named claim from## Findingsto## Discarded approacheswith date + reason. See Conflict handling. - Update / extend
## Findingswith new claims. - Append a
## Timelineentry summarizing the change. - Read
INDEX.md, update the row'sLast verifiedcolumn. Update the one-liner if the picture has changed.
Use kebab-case slugs that match how the user is likely to ask again - e.g. tailwind-v5, 2d-engines-clonable, orm-comparison. The slug should disambiguate.
Verify the write. Storage is complete only when the files exist on disk:
test -s <root>/.research/<slug>/FINDINGS.md && grep -q '<slug>' <root>/.research/INDEX.md && echo stored
If the check fails, the write did not happen (permission denial, sandbox, tool error). Redo it or surface the failure to the user - report the entry as saved only after this check passes.
4. Pasted content from the user
If the user pastes a long document and asks you to save it:
- Decide path first. Read
INDEX.md. Does this paste extend an existing topic (merge mode), or is it a new topic (new entry mode)? Same decision as Retrieval phase 5. - Save the raw document verbatim to
<root>/.research/<topic-slug>/raw/<YYYY-MM-DD>-paste.<ext>(preserve the original extension -.md,.pdf,.txt,.html, etc.). If the user pasted text directly with no original file, default to.md. - Synthesize the content into the same shape the subagent would return (Summary / Findings / Sources). Citations to the raw file:
[Source: raw/<filename>]. - Apply Storage (new entry path or merge path from Section 3) using the synthesized content. When writing the entry, include this raw in the
raw:frontmatter list (path, note, added date). - Offer to delete the original file: "Save this as research and remove the original at
<path>?". Always ask. Never auto-delete.
If the user provides only synthesized findings (no raw file worth keeping), skip step 2 and the raw: frontmatter entry - just synthesize and apply Storage.
Only create the raw/ subfolder when there's actually something to save in it.
Best practices
These are cross-cutting rules. Apply them throughout the workflow.
Date and freshness
- Always run
date +%Y-%m-%dfirst. Pin the actual current year in WebSearch queries ("X 2026", "X latest 2026"). Don't trust your model's prior on what year it is. - Prefer official release notes and changelogs over blog posts.
- When a source is older than 30 days on a fast-moving topic (npm packages, framework releases, AI tooling), treat it as a hint, not canon. Cross-check against newer sources.
- If an existing entry's
last_verifiedis older than 30 days on a fast-moving topic, refresh before answering - don't quote a stale entry as current truth.
Version preference
When recommending a version of a library, framework, or tool:
- Default = latest stable production release. That's what users should run unless they ask for something else.
- LTS when the project ships one and the user is on a long-lived stack (Node, Postgres, etc.).
- Nightly / pre-release / alpha / beta builds: only when the user explicitly asks ("what's coming in next release", "any unreleased features that solve X", "give me the bleeding edge"). Don't recommend nightly as a default - it's unstable and changes daily.
- Always state the version number you're recommending (e.g., "Drizzle ORM 1.4.2" not just "Drizzle ORM").
Source preference
Higher → lower authority for technical claims:
- Official documentation / release notes / changelog
- Maintainer blog posts and conference talks
- GitHub issues, discussions, and pull request descriptions
- Recent third-party benchmarks and reviews
- Stack Overflow / Reddit / random blog posts
Always record fetched: YYYY-MM-DD next to each source URL.
Citation discipline
- Every concrete claim is backed by a source URL in
sourcesfrontmatter. Do not use[n]markers in## Findings. - If you don't have a source, write "no source - open question" and add it to
## Open questions. Never invent a URL or quote. - When sources disagree, cite both and note the disagreement explicitly. Don't silently pick one.
Depth over polish
- Spend the effort budget on retrieval breadth and exact figures, not on formatting. The template already handles presentation; the common failure is a well-structured entry that is missing half the facts.
- Whenever 3+ options or a data series appear, put the comparison in a small markdown table inside
## Findings. Prose carries the interpretation; the table carries the data.
Conflict handling
When new evidence contradicts an existing entry:
- Move the old claim to
## Discarded approacheswith a one-line reason and date. Never delete silently. - If the same approach has failed twice or more, flag it loudly in
## Findings: "approach X has been tried and discarded N times - current working answer is Y". The point is to prevent re-trying refuted approaches in future sessions. - Update
last_verifiedand append a## Timelineentry summarizing the change.
File schemas
INDEX.md
# Research index
| Topic | Path | Last verified | One-liner |
|---|---|---|---|
| <topic-slug> | <topic-slug>/FINDINGS.md | YYYY-MM-DD | <one-line summary that disambiguates> |
The one-liner is what future-you scans to decide whether to load the entry. Make it specific:
- Weak:
Notes about Tailwind - Strong:
Tailwind v5.2 stable; Oxide engine default; config moved to CSS-first @theme blocks
FINDINGS.md
---
topic: <slug>
created: YYYY-MM-DD
last_verified: YYYY-MM-DD
status: active # active | superseded
depth: deep # deep | quick; a quick entry is an upgrade candidate for a later deep merge
related: [] # other entry slugs for cross-reference
sources:
- url: https://...
fetched: YYYY-MM-DD
raw: # omit if no raws were saved
- path: raw/2026-04-25-paste.pdf
note: user pasted vendor whitepaper
added: 2026-04-25
---
# <Topic name>
## Summary
3-6 lines. The TL;DR. Loads first on lookup; should answer the common question alone.
## Findings
Plain prose, plus markdown tables where 3+ options or a data series are compared. Exact figures verbatim. No `[n]` markers. No inline URLs. When a claim's interpretation depends on which source said it, name the source as prose ("per the README", "according to littlemight.com", "the HN-simulator commenter notes"). For raw documents, refer descriptively ("the pasted whitepaper"); the `raw:` frontmatter has the file path. Frontmatter `sources:` is the bibliography.
## Insights
- Causal, comparative, or trajectory takeaways that go beyond any single fact. Each traces back to Findings.
## Strongest objection
The contrarian-pass result: the best argument against the entry's conclusion, or "none found". Persisting it stops future sessions from re-discovering the same objection.
## Discarded approaches
| Approach | Why dropped | Date |
|---|---|---|
## Open questions
- ...
## Timeline
- YYYY-MM-DD - initial entry
Notes on the schema:
raw:is a list - one entry can accumulate multiple raw documents over time (e.g., user pastes a whitepaper, then later a different report on the same topic). Add new items; existing ones stay.- Omit the
raw:key entirely when there are no raw documents. related:cross-links to other entry slugs. Use this when entries touch overlapping projects but answer different questions (e.g.,knowledge-graphs-comparisonandmempalace-legitimacyboth mention mempalace but have different scopes - link them, keep them separate).
Anti-patterns
- Entry spam: one topic = one entry. Don't create separate entries for sub-aspects; nest them as sections.
- Researching the skill itself: don't write meta-entries about how research-memory works.
- Hallucinated sources: never invent URLs or quotes. If WebFetch failed, say so.
- Auto-delete on paste handler: always offer, never act.
- Silent supersede: any change to a prior conclusion goes through
## Discarded approaches+## Timeline. Never overwrite.
The four rules, restated
Brief subagents completely (they have zero context). Keep the contrarian pass (fill it yourself if the return skipped it). Write all .research/ files yourself (subagents return text only). Land every investigation in .research/ with the write verified; an answer without a stored entry is not done.