File formats and schemas
Every file a run produces, who owns it, and how to print the contract it validates against.
A run directory is the interface. Every file in it is schema-validated, and the schema module in the package is the single source of truth for all of them — it generates the JSON Schema, the contract documentation the agent reads, and the error messages you get when validation fails.
research-scan schema --name EvidencePacket # one model, as JSON Schemaresearch-scan schema --md # every model, as MarkdownThe run directory, in pipeline order
research/scans/<YYYY-MM-DD>-<slug>/
| File | Owner | What it is |
|---|---|---|
brief.md | input | The brief, or the question. |
queries.json | agent | The query plan: queries, sub-criteria, must_not, anchors. |
candidates.json | CLI | The retrieved pool, deduped, filtered and capped. |
screen-batches/NN.json | CLI | Candidates handed out for screening. |
screen.json | agent | A 0–3 score per candidate, with reason and criteria hit. |
expanded.json | CLI | Citation-graph additions. |
expanded-round2.json | CLI | Gap-round additions. |
coverage.json | CLI | Per sub-criterion coverage, one snapshot per round. |
shortlist.json | CLI | Ordered and cut for the reranker, split in-window / outside-window. |
ranked.json | agent | The rerank. |
evidence.json | CLI | The deliverable. One EvidencePacket per paper. |
evidence.md | CLI | The same list, rendered for a human. |
evidence.bib | CLI | BibTeX. Suppress with --no-bib. |
manifest.json | CLI | The audit trail: every drop, every source failure. |
retrieval.log.jsonl | CLI | Per-call retrieval log. |
expansion.log.jsonl | CLI | Per-call expansion log. |
verify.log.jsonl | CLI | Per-call verification log. |
Gap-round variants carry a suffix: retrieval-r2.log.jsonl,
expansion-r2.log.jsonl.
Neither half edits the other’s files.
Screening batch names
| Prefix | Origin |
|---|---|
01, 02, … | Retrieved candidates |
x01, … | Citation-graph expansion |
r01, … | Gap round, retrieved |
xr01, … | Gap round, expansion |
EvidencePacket
The shippable unit: a candidate, plus its rerank, plus its verification, plus why it was selected.
From the candidate: cid, title, abstract, tldr, authors[], year,
publication_date, venue, type, ids (doi, arxiv, pmid, openalex,
s2), citation_count, influential_citation_count, is_retracted, oa_url,
origins[], outside_window.
From the rerank: criteria, overall, evidence_level, relation, flags,
key_finding, methodology, why_it_matters, limitations[],
relevance_reason.
From emit: verification (required — emit exits 2 without it), rank,
selection_reason, url.
cid is a stable content id: the first twelve hex characters of a hash of the
highest-priority identifier available, preferring DOI, then arXiv id, then PMID,
then a normalised title and year.
Enumerations
relation — how a paper stands to the brief: design-changing,
plan-influencing, closely-related, contradicting, foundational.
Discovery origin — how it was found, recorded separately on each origin:
query, references, citations, recommendations, anchor.
selection_reason — why it made the list: score, foundational, review,
contradicting, diversity, backfill.
evidence_level — systematic-review, meta-analysis, rct, prospective,
observational, experimental, computational, qualitative, other.
query_type — direct, terminology, mechanism, method, adjacent,
contradictory, review, emerging, gap.
profile — quick, standard, deep.
domain — behavioral, cs, biomed, general.
source — openalex, s2, arxiv, pubmed.
work_type — article, preprint, review, book-chapter, other.
verified_by — crossref, openalex, arxiv, s2.
mismatch — doi_unresolved, title, year, author, retracted,
no_record.
Validation rules
Unknown keys are rejected everywhere. A misspelled field is not a field that defaulted; it is an error naming the path.
Exit 2 lists every offending path, not just the first.
Constraints are not loosened. limitations requires at least one entry; a
packet without one does not validate.
Reading a run without the tool
Nothing here needs Research Scan to interpret.
# the shortlist, with verification statusjq '.[] | {rank, title, relation, verified: .verification.verified}' evidence.json
# anything that failed verificationjq '.[] | select(.verification.verified | not) | {title, mismatches: .verification.mismatches}' evidence.json
# what was dropped, and whyjq '.drops' manifest.jsonLast updated Aug 21, 2026