Affinage · Toxoplasma gondii

About Affinage · Toxoplasma gondii

Mechanism-grounded gene annotations for Toxoplasma gondii, written by language models that read the primary literature and nothing else. Every claim traces to a specific paper; nothing comes from the model's prior knowledge.

Models
Claude Haiku 4.5 (organism gate) · Claude Sonnet 4.6 (reading pass) · Claude Opus 4.8 (synthesis pass)
Data source
ToxoDB-68 · strains ME49, GT1, RH88, VEG
Gene key
Locus card id (e.g. TG_205250), displayed under its curated symbol
Last run
09/2026

Pipeline

The pipeline is a deterministic sequence of stages. Each stage writes an on-disk artifact — the assembled corpus, the gated corpus, the database record — so any card can be re-run or audited from any checkpoint, and the same code path serves a single card, an evaluation cohort, and a full-genome run. The genome is processed in chunks of up to 2,000 cards through the Anthropic Message Batches API; a re-run copies forward cards whose corpus has not changed rather than re-annotating them.

Stage 0

Corpus assembly

deterministic · no LLM

For each card, the pipeline builds a list of search terms and queries PubMed in a way that is locked to the target organism, so a same-named gene in another species is never pulled in. It seeds the corpus with the references ToxoDB and UniProt have already curated for the gene, fetches each paper's abstract, attaches an NIH iCite citation count, and ranks the list.

Search terms, anchored on the symbol

The terms are the card's curated symbol, its synonyms and historical names, its locus and gene-model ids, symbol-like tokens taken from the product name, and genus-prefixed variants (TgROP18). Generic product descriptors are dropped, and bare tokens of one or two characters are never searched — on PubMed they match everything and nothing. Cards whose only names are that short recover their literature through the curated seeds and forward citations instead.

Organism-scoped query

Every term is searched as its own query, phrase-quoted in title-and-abstract and combined with the organism filter Toxoplasma[ORGN]. The filter carries the precision, so the term itself can be searched broadly. Up to 500 hits per term are pooled and the corpus is capped at 100 papers, ranked by iCite citations (direct search hits ahead of forward-citation expansions), with 20 slots reserved for the most recent papers so a heavily cited classic never crowds out this year's result.

View code · search_term_scoped() (toxo_corpus.py)
def search_term_scoped(term: str, organism_filter: str, max_results: int) -> list[str]:
    """PMIDs for one card term, organism-scoped to the genus. Thin wrapper over the
    shared esearch primitive."""
    return esearch_pmids(
        build_organism_term_query(term, organism_filter),
        max_results=max_results,
        label=term,
    )
View code · build_organism_term_query() (pubmed.py)
def build_organism_term_query(term: str, organism_filter: str) -> str:
    """Build a single-term, organism-scoped [tiab] esearch query (#88, Phase 3b).

    Used by the card-based corpus path: the organism filter (e.g.
    ``"Toxoplasma[ORGN]"``) provides precision, so the term is searched broadly in
    Title/Abstract. The term is phrase-quoted so multi-word descriptors stay a
    single token. Mirrors the plasmo fork's helper.
    """
    return f'"{term}"[tiab] AND ({organism_filter})'
View code · fetch_citation_counts() (citations.py)
def fetch_citation_counts(pmids: list[str]) -> dict[str, int]:
    """Return {pmid: citation_count} from NIH iCite.

    Missing PMIDs default to 0. Retries on transient network errors.
    Preprints without PMIDs should not be passed — they'll be ignored.
    """
    if not pmids:
        return {}

    counts: dict[str, int] = {pmid: 0 for pmid in pmids}

    for i in range(0, len(pmids), BATCH_SIZE):
        batch = pmids[i : i + BATCH_SIZE]
        params = {"pmids": ",".join(batch)}

        last_err: Exception | None = None
        for attempt in range(MAX_RETRIES):
            try:
                resp = requests.get(ICITE_URL, params=params, timeout=30)
                resp.raise_for_status()
                data = resp.json().get("data", [])
                for entry in data:
                    pmid = str(entry.get("pmid", ""))
                    if pmid in counts:
                        counts[pmid] = int(entry.get("citation_count") or 0)
                last_err = None
                break
            except Exception as e:
                last_err = e
                if attempt < MAX_RETRIES - 1:
                    logger.warning(
                        f"iCite attempt {attempt + 1}/{MAX_RETRIES} failed "
                        f"for batch at index {i}: {e} — retrying in {RETRY_DELAY}s"
                    )
                    time.sleep(RETRY_DELAY)

        if last_err is not None:
            logger.warning(
                f"iCite failed for batch starting at index {i} "
                f"after {MAX_RETRIES} attempts: {last_err}"
            )

    n_with_citations = sum(1 for c in counts.values() if c > 0)
    logger.info(f"Citation counts: {len(counts)} PMIDs queried, {n_with_citations} have citations")
    return counts
Curated seeds and forward citations

Before any search, the references ToxoDB lists for each of the card's strain loci (fetched from the VEuPathDB record service, which requires a registered API key) and the references cited by the reviewed UniProt entry for the symbol are added as seeds. For cards whose only names are the unsearchable one- or two-character tokens, papers that cite those seeds are pulled in as well — a topical signal that does not depend on the gene's name at all, which is what rescues such genes.

Deterministic drops

Two rule-based filters run before any model sees the corpus: dataset-scale papers (genome-wide screens and resource papers, matched by title pattern or a curated denylist) are removed, and an off-taxon collision scan discards papers whose title names a look-alike relative — Plasmodium, Cryptosporidium, Eimeria, Neospora, Babesia, Theileria, Sarcocystis — without naming Toxoplasma. The scan deliberately reads only the title: on six gold-standard genes, scanning abstracts as well cut recall to 0.97 while title-only kept recall at 1.00 and still dropped contamination from 0.97 to 0.31. The sister Plasmodium site measured the opposite on its own corpus and scans title plus abstract; the two deployments diverge on purpose, and the evidence is recorded in the repositories' divergence ledger.

Gate

Organism gate

Claude Haiku 4.5 · three batched rounds

Before the model ever writes a summary, every paper passes a language-model organism check — the second line of defense against wrong-organism collisions, after the deterministic drops above. The gate runs as three sequential rounds through the Batches API over the whole genome, each round checkpointed so a crashed run resumes where it stopped.

Round 1 · organism verdict

The corpus is read in chunks of twenty papers, and each paper is classified as being about this gene in Toxoplasma or about something else. The gate is fail-open — a chunk the model cannot judge, or a request that fails, is kept at low confidence rather than dropped.

Round 2 · recheck

Every low-confidence keep from round 1 is re-read on its own, and the second verdict replaces the first. Only papers whose final verdict is exclude are dropped; each is recorded with the reason wrong_organism, so a curator can audit exactly what was removed and why.

Round 3 · relevance tier

The kept papers are tiered high / medium / low relevance to the gene's mechanism. The tier is advisory — it is recorded on each kept paper for the gate report and audit — and never drops a paper.

Read

Reading pass

Claude Sonnet 4.6

The gated corpus is read by Claude Sonnet in a single extraction call that turns it into a structured timeline of dated mechanistic discoveries — substrates, binding partners, activities, structures, and localization with functional consequence — each with its method, confidence, supporting PMIDs, and a preprint marker. No tools, no database lookups: only the papers themselves. The instructions are composed from a shared, organism-neutral template plus organism-specific inserts — how to classify a paper, and which look-alike organisms to reject. The prompt tags each finding, not each paper, with the strain (RH, ME49, …) the experiment was done in, and leaves the tag empty rather than guessing.

Zero-discovery retry

A card whose reading pass returns no discoveries is retried in two escalating steps. First the same corpus is read once more. If it is still empty and the protein has a specific curated name, a fresh corpus is retrieved by that protein name, pushed back through the organism gate so name-broadened homonyms are dropped, and read again; the card's stored corpus is rewritten to match what was actually read, so provenance stays honest.

View system prompt · reading pass
You are extracting a timeline of mechanistic discoveries from a corpus of papers about a gene.

You will receive a corpus of paper abstracts retrieved for this gene. This is your ONLY source.
No external database summaries are provided — do not reference UniProt, OMIM, or other databases;
ground every claim in an abstract from the corpus.

YOUR TASK: Read the abstracts. Extract only findings where a direct experiment established
something about HOW this protein works. Ignore everything else.

INCLUDE as a Discovery:
  - Identification of a substrate, binding partner, or complex (Co-IP, pulldown, reconstitution)
  - Enzymatic activity or catalytic mechanism (in vitro assay, active-site mutagenesis)
  - Structure (crystal, cryo-EM, NMR with functional validation)
  - Pathway position via genetic epistasis (suppressor screen, double-mutant rescue)
  - Post-translational modification with identified writer/eraser/reader
  - Subcellular localization determined by direct experiment (live imaging, FRAP,
    fractionation) — especially when tied to a functional consequence
  - Defined role in a cellular process (cell division, migration, signaling, actin regulation,
    etc.) established by loss-of-function with a specific phenotypic readout

EXCLUDE — do not create Discovery entries for:
  - Expression correlation, survival analysis, or prognostic biomarker studies
  - IHC, transcriptomics, or GWAS/eQTL associations
  - Pure phenotype descriptions with no molecular mechanism or pathway placement
  - Pan-gene catalog papers: large interactome maps, proteome-scale screens,
    full-length cDNA/sequencing surveys, GO/annotation propagation. They list
    thousands of genes and establish nothing mechanistic about this one.
  - Non-protein products of the same locus: circRNA, lncRNA, antisense
    transcript, or miRNA-host studies (e.g. circ-FAM169A, MYH7B-as1). These are
    NOT the canonical protein and must not enter the protein's discovery set.
  - Hypotheses, proposals, or speculation the paper does NOT experimentally
    confirm ("we hypothesized…", "X may regulate…", "suggests a role for…" with
    no supporting experiment). A proposed-but-untested claim is not a discovery.
  - Results the paper reports as NEGATIVE or rejects ("X does not bind Y", "no
    effect on…", "failed to detect"). Never flip a negative result into a
    positive discovery. If a negative result is itself mechanistically
    informative, record it explicitly AS negative in the finding text.

Many papers in the corpus will be irrelevant — skip them silently.

EPISTEMIC STATUS: extract only what an experiment ESTABLISHED. Hold apart
result vs hypothesis vs speculation, and positive vs negative findings. When
papers CONTRADICT each other, do not average them — prefer the more rigorous or
replicated result and lower the confidence accordingly.

CLASSIFY EACH PAPER BEFORE EXTRACTING. For every paper, first decide: does it
describe the canonical protein-coding gene being queried? If it is an alias
collision (a different gene that shares this symbol or one of its aliases), a
cross-kingdom symbol collision, a non-protein locus product, or a pan-gene
catalog, EXCLUDE it. Extract discoveries only from the papers that pass.

IMPORTANT RULES:
- If the user prompt provides HGNC aliases or previous symbols for this gene,
  those names refer to the SAME gene as the query symbol and are canonical for
  on-target judgments. A paper indexed under an alias should be treated as
  being about the query gene; do not skip it as a collision.
- The query is ALWAYS a Toxoplasma gondii gene. The corpus is organism-scoped to
  Toxoplasma, but a same-named gene in another apicomplexan (Plasmodium,
  Cryptosporidium, Eimeria, Neospora, Babesia, Theileria, Sarcocystis) can still slip in. Distinguish two cases:
    • ORTHOLOG / COMPARATIVE — a paper on the gene's ortholog in another organism
      (a model organism or another apicomplexan) INFORMS mechanism when the
      function, domains, and cellular context are consistent; but every Discovery
      must be attributed to the species/strain the experiment was actually done in
      (see the attribution rules below). Comparative Toxoplasma-vs-Plasmodium
      papers are foundational and INCLUDED.
    • WRONG-ORGANISM COLLISION — a paper solely about the same-named gene in a
      competing organism, with no Toxoplasma content, describes a different protein
      → SKIP it silently. Do not extract discoveries from it.
  Use the preponderance of the corpus as ground truth for what the Toxoplasma gene
  does; outliers about a different organism's gene are collisions, not the target.
- Only include findings about the SPECIFIC GENE being queried, not paralogs or family members.
- Every Discovery MUST cite at least one identifier from the corpus (PMID or paper ID).
  If you cannot link a finding to a specific paper in the corpus, do not include it.

CONFIDENCE — two axes:
  Method quality:
    Tier 1: reconstitution, structure, in vitro assay + mutagenesis
    Tier 2: epistasis, reciprocal Co-IP, MS interactome, clean KD/KO with defined
            cellular phenotype, direct localization experiment with functional consequence
    Tier 3: single Co-IP/pulldown, partial mechanistic follow-up, localization without
            functional link, KD/OE with phenotype but no pathway placement
    Tier 4: computational prediction only, expression-based inference

  Preponderance of evidence:
    Strong:   independently replicated across labs, OR single paper with multiple
              orthogonal methods and rigorous controls (e.g., reconstitution +
              mutagenesis + structural validation in one study)
    Moderate: single lab but ≥2 orthogonal methods
    Weak:     single lab, single method

  IMPORTANT: A single rigorous paper (e.g., with reconstitution, structure, and
  mutagenesis) can warrant High confidence. Three papers copying a weak pulldown
  do NOT warrant High confidence. Evaluate the quality of the evidence, not merely
  the count of papers reporting it.

  Assignment:
    High   = Tier 1–2 + Strong or Moderate
    Medium = Tier 1–2 + Weak, OR Tier 3 + Strong
    Low    = Tier 3 + Weak/Moderate, OR Tier 4

  confidence_rationale: one phrase. E.g. "Tier 1 / Strong — reconstituted in vitro, replicated"

  ENFORCEMENT (be strict — the downstream narrative is gated on these levels):
  - confidence_rationale MUST name BOTH axes — e.g. "Tier 2 / Moderate — reciprocal
    Co-IP, single lab, two orthogonal methods".
  - You are reading ABSTRACTS, not full text. Abstracts compress methods, so when
    the tier is not explicitly stated, assume the LOWER tier — do not infer
    reconstitution/structure/mutagenesis from a vague phrase. Default to the more
    conservative confidence whenever in doubt.
  - High is reserved for genuinely strong evidence (Tier 1–2 with replication OR
    multiple orthogonal methods in one rigorous study). Never assign High to a
    single vague or single-method claim.

CITATION RULE:
- For PMC papers: use the PMID (e.g. "12345678").
- For preprints: use the paper ID exactly as shown (e.g. "bio_4f78753a6feb").
- Never fabricate identifiers. If a paper has no PMID, use its ID: prefix from the corpus.

PAPER PRIORITIZATION:
- Papers are listed MOST GENE-SPECIFIC FIRST (the corpus is pre-ranked by
  specificity, not by citation count). Read from the top.
- Do NOT equate citation count with importance. A pan-gene catalog paper can
  have thousands of citations yet establish nothing mechanistic about this gene;
  a single focused experiment on this gene outweighs any number of surveys that
  merely list it. Weight evidence by what was actually done to THIS protein.
- Preprints (marked "PREPRINT") should be included only when they describe novel
  mechanistic findings not covered by peer-reviewed work.

ORGANISM ATTRIBUTION:
- For each Discovery, set `attribution` to the species/strain the experiment was
  ACTUALLY performed in, taken from the paper (the corpus may show a per-paper
  "Organisms (detected): ..." hint — treat it as candidates, not as truth).
- Attribute PER FINDING, not per paper. A paper that studies more than one strain
  (e.g. RH and ME49) attributes each finding to whichever strain(s) that specific
  result holds in — list every strain a finding was shown in.
- Each entry is {"species": "<e.g. Toxoplasma gondii>", "strain": "<e.g. RH; or
  "" if only the species is specified>"}.
- If the abstract does not specify the strain or species, leave `attribution`
  empty ([]). Do NOT guess. An empty list means "unspecified".

current_model: one sentence stating what is mechanistically established about this protein
right now, based on the discoveries you extracted. If nothing mechanistic was found, write
"No mechanistic findings in the available literature."

Return a single JSON object:
{
  "discoveries": [
    {
      "year": int | null,
      "finding": str,
      "method": str,
      "journal": str,
      "confidence": "High" | "Medium" | "Low",
      "confidence_rationale": str,
      "pmids": [str],
      "is_preprint": bool,
      "attribution": [{"species": str, "strain": str}]
    }
  ],
  "current_model": str
}
Synthesize

Synthesis & attribution

Claude Opus 4.8

A synthesis step (Claude Opus) weaves the individual findings into one coherent account of what the gene does: a mechanistic narrative, a causally ordered discovery history with the open gaps it leaves, and a structured mechanism profile — complexes and partners, each tied to the discoveries that support it. The profile has three further slots for controlled GO and Reactome terms, but those vocabularies were never built for this organism, so the prompt offered the model no terms to choose from and every card reports none. Every claim cites the supporting finding, and the synthesis uses only the gathered evidence. The cardinal rule of this stage is that findings from different strains are never merged into a single undifferentiated statement. Where two strains genuinely disagree, that divergence is recorded as a distinct, structured strain conflict rather than blended away.

View system prompt · synthesis pass
You are a molecular biology reviewer synthesizing a mechanistic narrative for a gene.

Your job is to SYNTHESIZE the discovery timeline into a coherent mechanistic narrative —
connect the findings with sound biological reasoning so the result reads as one unified
picture rather than a list. The synthesis is yours to construct; the evidence is not.
You may reason about how the findings fit together, but every citation and every
gene-specific factual claim must come from the timeline — never introduce a
gene-specific fact, mechanism, or citation the timeline does not contain.

You will receive a discovery timeline (already filtered to direct experimental evidence
and extracted from the primary literature). This is your ONLY input. No UniProt, OMIM,
HPA, DepMap, or OpenCell summaries are provided — do not invoke them as if you had them.
Ground every claim in the timeline.

EVIDENCE-ONLY (governing principle — overrides all other rules):
The provided timeline IS the gene's knowledge boundary. Every mechanistic claim
in your output — function, partners, substrates, localization, pathway, cellular
role — MUST trace to a specific discovery entry in the timeline, cited by PMID.
Do NOT draw on:
  - prior knowledge of the gene's general biology or canonical function
  - taxonomy, protein family, or domain relationships not stated in the timeline
  - textbook biochemistry or pathway context not introduced by a cited finding
  - any information from training data about this specific gene
The timeline may be short. A short timeline produces a short, citation-dense
narrative. A sparse timeline is not a license to fill gaps with background knowledge.
Gap statements ("X has not been characterized in the available corpus") are the
correct way to handle absent evidence — they are factual coverage assertions,
not prior-knowledge injections, and do not require a PMID.

CONTAMINATION CHECK — do this first.
The timeline came from a retrieved corpus that can occasionally be dominated by
papers about a DIFFERENT gene (a symbol collision or a paralog). Judge the
timeline's INTERNAL COHERENCE: do the discoveries collectively describe one
coherent protein, or do they fragment into two or more unrelated proteins?
- Refuse — do NOT fabricate a narrative — ONLY if the timeline is empty, has a
  single low-confidence discovery, or is genuinely incoherent (the discoveries
  describe fundamentally unrelated proteins, signalling a contaminated corpus).
  In that case output exactly:
    mechanistic_narrative = "Insufficient on-target evidence to synthesize a narrative."
    teleology = []
    mechanism_profile = empty arrays for every category.
- Do NOT refuse because the timeline is merely terse, concise, or built on
  model-organism orthologs, and do NOT compare it against any external notion of
  what the gene "should" be — you only have the timeline. A coherent timeline,
  even a small one, MUST be synthesized. Refuse on emptiness or incoherence, never
  on brevity.

STRAIN/SPECIES ATTRIBUTION (non-negotiable):
- Each timeline discovery carries an `attribution` list (the strain/species it was
  shown in). NEVER merge findings from different strains/species into one
  undifferentiated claim.
- When discoveries diverge across strains, attribute explicitly in prose, e.g.
  "In RH, ROP18 phosphorylates IRGs [#2]; in ME49, the kinase is pseudogenized [#5]".
- Carry each teleology step's `attribution` from the discoveries it rests on.
- `current_model` stays one sentence, but note strain-divergence when the evidence
  itself diverges across strains.
- Discoveries with empty `attribution` are strain-unspecified — do not invent a
  strain for them.
- CROSS-STRAIN CONFLICTS: when >=2 strains/species show DIVERGENT results for the
  SAME mechanistic aspect (e.g. RH has an active ROP18 kinase but ME49 has a
  pseudogenized one), record them in `strain_conflicts` — one entry per aspect, each
  with a `claims` list giving each strain's `attribution`, its `claim` (the result), and
  the `supporting_discovery_ids` it rests on. Emit `strain_conflicts: []` when there is
  no genuine divergence; never invent a conflict, and never list a single strain as a
  conflict (that is just attribution).

Produce two outputs.

--- OUTPUT 1: mechanistic_narrative ---
A synthesized functional summary answering: what does this gene do?
Tone: authoritative, declarative — like a UniProt function comment or textbook entry.

Rules:
- The mechanistic_narrative is the COMPRESSED overview. The timeline, teleology,
  and mechanism_profile already hold the exhaustive record and are shown to the
  reader separately — do not duplicate that coverage here. Most findings should
  collapse into a few thematic claims. If you find yourself citing a large
  fraction of the discoveries, you are enumerating, not synthesizing — stop and
  distill to the picture a reader needs.
- For a well-evidenced gene, open with ONE synthesis sentence establishing the
  gene's broad biological role at the process level (this sentence synthesizes
  across the evidence; cite at least one representative discovery index), then
  build the mechanistic picture from there.
- CONFIDENCE GATING: if the timeline contains any High- or Medium-confidence
  discoveries, build the narrative from THOSE and exclude Low-confidence findings
  from it — Low findings remain represented in teleology/gaps. Only when the
  timeline is entirely Low-confidence may Low findings carry the narrative.
- CITE BY DISCOVERY INDEX, NOT BY PMID. Each timeline discovery has an `idx`.
  Support every claim by citing the index/indices it rests on, grouped at the end
  of the claim: "[#3]" or "[#3, #7]". Do NOT write raw PMID numbers — the system
  fills in the PMIDs from the indices you cite, so you never need to recall or copy
  a PMID. Every factual mechanistic claim needs at least one discovery index; one
  well-chosen index is better than listing every supporting one.
- For the claims you DO include (per the confidence gating above), the filter is
  on LANGUAGE, not further inclusion. State them as facts; the citation
  communicates the source and its strength. Never add epistemic hedges.
- BANNED language: "though X awaits confirmation", "remains to be confirmed",
  "requires further study", "is controversial", "has not been independently
  replicated", "may/might/could", "suggested to", "proposed to", "reportedly",
  "preliminary evidence", "some studies suggest". Delete the claim instead.
- Include cellular processes and functional roles, not just molecular interactions.
- If the mechanism is largely uncharacterized, say so directly and briefly — one
  factual sentence.
- Exception: if the timeline itself contains a discovery linking the gene to a named
  Mendelian disease via direct evidence (causative mutation, rescue, family study),
  include ONE declarative sentence stating the disease connection. This counts toward
  the length budget. Do not add prognosis, prevalence, or treatment. Do NOT invent
  disease links from prior knowledge — require a timeline entry.
- Do NOT restate metadata already shown elsewhere in the viewer (protein size, kDa,
  localization, DepMap essentiality, interactor lists). These appear in separate
  viewer panels sourced from databases, not from this narrative.

EVIDENCE GROUNDING (strict, do not violate):
- Every declarative sentence about the gene's function, mechanism, partners,
  substrates, or phenotype MUST be supported by at least one discovery-index
  citation in inline `[#idx]` form, pointing at the timeline discovery it rests
  on. No exceptions for opening sentences — the opening synthesis sentence must
  cite at least one representative discovery index.
- DO NOT add canonical textbook biochemistry, enzymology background,
  pathway summaries, or general gene-function statements that are not
  introduced by a specific discovery in the timeline. If the timeline
  is sparse, the narrative MUST be sparse — write 1–3 cited sentences plus
  an explicit gap statement ("Beyond [#0], no further mechanistic detail
  has been characterized in the available corpus.").
- A body sentence that asserts a gene-specific mechanism without a discovery-index
  citation is not acceptable: either cite the discovery it rests on, or omit the claim.

CITATION FIDELITY (strict, do not violate):
- Cite ONLY discovery indices that exist in the provided timeline. An index you cite
  must point at a real discovery; do not invent indices.
- NEVER write a raw PMID number. You do not recall, copy, or generate PMIDs — you cite
  the discovery's index and the system resolves the PMID from the timeline. This makes
  a wrong or invented citation impossible: if you can point at the supporting discovery,
  cite its index; if you cannot, delete the claim.

--- OUTPUT 2: teleology ---
A causally-ordered story of how mechanistic understanding was built.

Each step = a moment when a specific mechanistic question was answered or partially answered.
Frame each claim as: what was unknown → what the experiment showed → what this established.

For each step:
  - claim: what mechanistic question this answered and why it mattered (one sentence).
    Do NOT just restate the finding — frame the advance.
  - evidence: the method and system in one clause
  - pmids: REQUIRED for every step that has a year. Carry directly from the timeline discoveries.
    Only the final open-question step (year=null) may have an empty pmids list.
  - confidence: carry from the timeline (High / Medium / Low)
  - gaps: 1–3 things this finding does NOT settle. Be concrete.
    For Low-confidence steps, the first gap must state the specific limitation
    (e.g. "awaits reconstitution", "not independently confirmed", "single Co-IP
    without reciprocal validation"). Do NOT editorialize about whether findings
    "should be treated as established" — just state the gap concretely.

PREPRINT HANDLING:
- If the timeline contains >=8 High or Medium confidence discoveries from
  peer-reviewed journals, do NOT cite preprints in mechanistic_narrative. Preprints may
  appear in teleology with "(preprint)" noted in the evidence field.
- For poorly characterized genes (<4 discoveries total), preprints are acceptable
  sources for mechanistic_narrative.

If there are >10 discoveries, consolidate related findings into fewer teleology steps.
Group findings that address the same mechanistic question.

Order chronologically. If a major question remains open, add a final step with
year=null stating what is still unknown.

teleology.gaps must describe what the MECHANISM LITERATURE has not established
(e.g. "no substrate identified", "no structural model", "mechanism of recruitment
unknown", "single Co-IP without reciprocal validation"). Do NOT reference what
external databases show or do not show — you do not have access to them. Gaps are
strictly about unresolved questions in the primary literature captured in the
timeline.

Return a single JSON object:
{
  "mechanistic_narrative": str,
  "teleology": [
    {
      "year": int | null,
      "claim": str,
      "evidence": str,
      "pmids": [str],
      "confidence": "High" | "Medium" | "Low",
      "gaps": [str],
      "attribution": [{"species": str, "strain": str}]
    }
  ],
  "mechanism_profile": {
    "molecular_activity": [{"term_id": str, "supporting_discovery_ids": [int], "attribution": [{"species": str, "strain": str}]}],
    "localization":       [{"term_id": str, "supporting_discovery_ids": [int], "attribution": [{"species": str, "strain": str}]}],
    "pathway":            [{"term_id": str, "supporting_discovery_ids": [int], "attribution": [{"species": str, "strain": str}]}],
    "complexes":       [str],
    "partners":        [str],
    "other_free_text": [str]
  },
  "strain_conflicts": [
    {
      "aspect": str,
      "claims": [
        {"attribution": [{"species": str, "strain": str}], "claim": str, "supporting_discovery_ids": [int]}
      ]
    }
  ]
}
R1–R11

Concordance detector & QC

no LLM, no API

After a summary is written, a deterministic safety net re-reads it — pure regex-and-SQL rules, no AI involved, fully reproducible from the database alone. A card that trips a rule is shown with an audit chip and a banner naming the rule, so a reader knows to treat it with care. The rules fall into three buckets:

  • Identity (wrong gene or wrong product) — R1 the corpus or narrative is dominated by a different gene's name; R2 the opening sentences frame the protein in another organism; R3 the narrative opens on a paralog rather than this gene; R4 the narrative is about a non-coding or alternative product.
  • Grounding (the narrative under-extracts or misuses its evidence) — R5 a refusal or empty result despite rich curated experimental evidence; R6 the narrative's papers are disjoint from the literature NCBI links to the gene; R7 a cited PMID that was not in the corpus the model read; R8 a claim with no citation; R11 a mechanism-profile term with too little support or absent from the narrative.
  • Behavior (a generation fault) — R9 the memorization probe found the model willing to write about the gene from an empty or wrong corpus; R10 a synthesis-stage refusal or parse failure, which suppresses the other flags because there is nothing to audit.

Output-level QC additionally checks the reading and narrative stages for schema violations, ungrounded claims, and collapsed strain attribution.

Eval

Evaluation

planned · not yet run

Not yet run on Toxoplasma. The evaluation will run once the corpus amendments now in progress are finished, so its scores describe the corpora this site actually serves; until then no evaluation scores are shown here. Quality will be scored by a Prometheus rubric model: faithfulness grades each cited narrative claim against the abstract the model read, catching contradictions and invented specifics, and a blind pairwise comparison pits each Affinage summary against the curated ToxoDB / UniProt entry, run in both orderings so a verdict only counts when it survives the position swap. The rubrics below are the ones that will be used.

View rubric · Prometheus faithfulness
[Is this single factual claim about the gene consistent with the cited reference abstract? The claim may synthesize across its cited sources and use standard gene nomenclature — judge consistency, not verbatim overlap. Penalize ONLY a direct contradiction, or a specific invented detail (a named binding partner, substrate, or mechanism) that the abstract does not contain.]
Score 1: Contradicted: the abstract asserts the opposite of the claim, or the claim describes a different gene or paralog.
Score 2: Unsupported: the claim introduces a specific mechanistic assertion (a named binding partner, substrate, catalytic activity, or causal mechanism) that the abstract neither states nor implies.
Score 3: Supported: the abstract is consistent with the claim, though it may state it more narrowly, as background, or as one part of a broader synthesis.
Score 4: Supported: the abstract clearly states the claim.
Score 5: Supported: the abstract states the claim fully and precisely.
View rubric · Prometheus pairwise
Which response is the more reliable functional annotation of the gene — that is,
which more accurately and specifically describes what the protein does and how it
works, without asserting anything unsupported?

Judge on substance, NOT style or length. A shorter answer is not worse; a longer
answer is not better.

Judge MECHANISM ONLY — molecular and cellular function. Do NOT reward or penalize
clinical/disease-association content, prevalence, prognosis, or therapeutic
relevance; that is out of scope for this comparison. If one response spends text
on disease while the other describes mechanism, that does not make it better.

Reward:
  - Factual accuracy: claims that are correct for this specific gene.
  - Mechanistic specificity: named substrates, binding partners, complexes,
    catalytic activities, pathways, and defined cellular roles — over vague
    generalities.
  - Coverage of the gene's PRINCIPAL established function.

Penalize heavily:
  - Any claim that is wrong, or that overreaches beyond what is established (a
    confident-but-unsupported statement is worse than an honest gap).
  - Conflating this gene with a paralog or a different gene of the same name.
  - Vague filler that conveys no mechanism.

TIEBREAKER (apply BEFORE any preference for detail): if both responses are
factually accurate, prefer the one that asserts LESS beyond what is established. A
confident claim that overreaches is a DEFECT, not richness. Do NOT prefer a
response merely because it is longer, names more entities, or reads as more
detailed; extra detail only counts if it is accurate AND mechanistic.

Prefer the response a careful molecular biologist would judge the more accurate
and informative description of THIS gene.

Data source

Gene models, ortholog assignments, and amino-acid sequences are sourced from ToxoDB-68 (toxodb.org). Pairwise identity values are computed from global protein alignments within each ortholog group. Curated references are seeded from the ToxoDB bibliography and reviewed UniProt entries.

Limitations

Authorship

This site is a modification of the Affinage pipeline built by Matteo Di Bernardo in the Cheeseman lab, Whitehead Institute (source at github.com/cheeseman-lab/affinage). The Toxoplasma adaptation was built in the Lourido lab, Whitehead Institute, by Ana Karla Cepeda Diaz and Zachary Sanchez, as a team at an Anthropic hackathon, where most of this work was done. The modified pipeline will be released with the accompanying publication.

Anthropic funded this project by providing API credits as part of the Claude for Science program.