Skip to content

Quote layer with provenance scoring #65

Description

@holden

Overview

Add a Quote layer to the dictionary — a first-class entity that attaches illustrative quotations to definitions. The distinguishing feature is provenance tracking: rather than storing quotes naively, we record the full attribution chain and produce a confidence score for how likely the quote is genuinely from the claimed speaker.

This matters because misattributed quotes are endemic on the internet ("The definition of insanity is doing the same thing over expecting different results" — not Einstein; "Be the change" — not quite Gandhi; "Well-behaved women seldom make history" — correctly Laurel Thatcher Ulrich, but almost always stripped of context). The quote layer should be better than Instagram.


Data model

quotes
  id
  body                  :text          -- the quote text
  attributed_to         :string        -- the name as it typically circulates
  author_id             :integer       -- FK → people (nullable; may be unknown)
  source_title          :string        -- book / speech / letter / interview title
  source_url            :string        -- canonical URL if available
  source_year           :integer
  source_context        :text          -- page, chapter, scene, timestamp, etc.
  provenance_notes      :text          -- freeform: known misattribution history
  confidence_score      :float         -- 0.0–1.0 (see scoring below)
  ingestion_source      :string        -- which API/dataset this came from
  ingestion_source_tier :integer       -- quality tier of that source (1 = high)
  verified_at           :utc_datetime  -- when a human or high-trust source confirmed
  inserted_at / updated_at

Join table: definition_quotes (definition_id, quote_id, position) — lets a quote illustrate multiple definitions and lets editors order them.


Confidence score

Score is computed (and can be overridden) from several signals:

Signal Points
Primary source (original text, Gutenberg, archive.org scan) +0.40
Academic citation or fact-check site (Quote Investigator, Snopes) +0.25
High-tier aggregator (Wikiquote with citation) +0.15
Author record in people table with birth/death matching era +0.10
Low-tier aggregator (BrainyQuote, Goodreads, AZQuotes) −0.15
Quote circulates as known misattribution (provenance_notes set) −0.30
No source title or year −0.10

Score is clamped to [0.0, 1.0] and stored; a nightly job can recompute it as source data improves.

Display tiers derived from score:

  • Verified (≥ 0.80) — primary or academic source
  • Plausible (0.50–0.79) — reputable aggregator, consistent attribution
  • Disputed (0.20–0.49) — conflicting sources or known misattribution risk
  • Apocryphal (< 0.20) — widely circulated, origin unclear or debunked

Ingestion sources (rough priority order)

  1. Quote Investigator (quotesinvestigator.com) — the gold standard for debunking; parse their findings as provenance_notes
  2. Wikiquote API — structured, cited, covers major figures
  3. Project Gutenberg / Internet Archive — primary text sources; extract quotes from full texts
  4. Quotable API (theysaidso / similar open APIs) — bulk ingestion, assign low source tier
  5. BrainyQuote / Goodreads scrape — lowest tier, used only for coverage; score penalized
  6. Manual entry — admin UI for adding/verifying quotes by hand

Source tier table:

Tier Sources Trust modifier
1 Quote Investigator, Gutenberg, archive.org +0.40
2 Wikiquote (cited), academic databases +0.25
3 Reputable news, official author estates +0.15
4 Quotable-style APIs, general aggregators 0.00
5 BrainyQuote, Goodreads, AZQuotes, Instagram −0.15

Famous misattribution examples (seed data)

These should ship as seed/fixture data to demonstrate the feature:

  • "The definition of insanity…" — attributed Einstein everywhere; Quote Investigator traces it to Narcotics Anonymous literature, ~1981. Einstein score: 0.02.
  • "Be the change you wish to see in the world" — Gandhi adjacent but not a direct quote from his writings; a paraphrase. Score: 0.35 with provenance note.
  • "Elementary, my dear Watson" — Sherlock Holmes never says this verbatim in Conan Doyle. Score: 0.05 attributed to Doyle.
  • "Float like a butterfly, sting like a bee" — correctly Ali, but actually composed by his cornerman Drew Bundini Brown. Score: 0.60 with context note.
  • "Well-behaved women seldom make history" — correctly Laurel Thatcher Ulrich (1976 article), but almost universally stripped of its ironic scholarly context. Score: 0.85 — correctly attributed, low context score.
  • "May you live in interesting times" — universally attributed to "an ancient Chinese curse/proverb," but no Chinese source has ever been found and no equivalent expression exists in Chinese. Quote Investigator traces it to British politician Joseph Chamberlain (~1898–1901); his son Austen Chamberlain later attached the "Chinese" framing in diplomatic conversation, which is almost certainly how the false attribution stuck. Score attributed to "ancient Chinese proverb": 0.03. Additionally, this is almost always quoted in isolation — it is supposedly the first and mildest of three escalating curses: (1) "May you live in interesting times," (2) "May you come to the attention of those in authority," (3) "May you get what you wish for." The three-part structure is also of uncertain provenance, but it makes the meaning of the first curse clearer: interesting is a threat, not a compliment.

UI integration

  • On a TopicLive page, quotes appear below definitions as illustrative examples — separate visual section, not mixed in with definitions.
  • Each quote shows: body, attribution line, source (linked if available), and a provenance badge (Verified / Plausible / Disputed / Apocryphal) with a tooltip explaining the score.
  • Disputed/Apocryphal quotes show a collapsed "provenance note" users can expand.
  • Users can upvote quotes as useful for understanding the definition (separate from definition votes).
  • Admin/editor interface to link quotes to definitions, set position, and override scores.

Out of scope for this issue

  • Real-time quote ingestion pipeline (that's a separate background-job issue)
  • Full-text search across quotes
  • User-submitted quotes (future)

Acceptance criteria

  • quotes and definition_quotes migrations exist
  • Quote schema with changeset validation
  • Confidence score computed from ingestion source tier + signals
  • Seed data includes ≥ 5 famous misattribution examples
  • At least one ingestion adapter (Wikiquote recommended as first)
  • TopicLive renders attached quotes with provenance badge
  • Provenance badge tooltip explains the score in plain language

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions