Skip to content

feat(content,pipeline): false-citations content type + Proverbs 3:13 / pseudo-Enoch seeds #1826

@CraigBuckmaster

Description

@CraigBuckmaster

Strategic context

Viral religious content consistently uses two fabrication patterns that are categorically distinct from existing proof-text-guards coverage:

  1. Misquoted canonical verses — a real verse cited with words that are not in the verse. Recent example: "Proverbs 3:13: Blessed are those who seek wisdom, for they will not be deceived. Blessed are those who know the enemy, for they will escape his snares." Proverbs 3:13 actually reads "Blessed are those who find wisdom, those who gain understanding" (NIV) — the rest is fabricated.

  2. Misattributed extrabiblical quotations — words attributed to 1 Enoch / Jasher / Gospel of Thomas / Dead Sea Scrolls that do not appear in any extant text. Recent example: "Enoch wrote: They will lead many astray, and the truth will be hidden from the children of men." Not present in 1 Enoch (Ge'ez, Aramaic, or Greek).

proof-text-guards.json covers real verses misapplied through reading. It does not cover fabricated wording or false attribution. The schemas differ enough that conflation would erode the proof-text-guards entries' usefulness.

This card adds a new content type — false-citations — with the schema, two seed entries, build-pipeline wiring, and a SQLite landing table.

Parent epic: #1536
Related cards: #1817, #1819, #1820, #1821 (Divine Council / cosmic-conflict content) — those cards may want to cross-reference false-citations entries

Deliverables

  1. New metadata file: content/meta/false-citations.json
  2. Two seed entries: misquoted Proverbs 3:13; pseudo-Enoch "children of men"
  3. Schema-validator coverage in _tools/schema_validator.py
  4. SQLite loader in _tools/build_sqlite_loaders.py + table DDL in _tools/build_sqlite_schema.py
  5. SQLite validator check in _tools/validate_sqlite.py

All deliverables ship in the same PR.


Deliverable 1 — Schema

File created: content/meta/false-citations.json

Top-level type: JSON array (match difficult-passages.json and proof-text-guards.json convention).

Entry schema:

{
  "id": "string-kebab-case",                          // unique, required
  "category": "misquoted-canonical | misattributed-extrabiblical | fabricated-no-source",
  "alleged_text": "the wording as it circulates",     // required
  "claimed_source": "human-readable source string",   // e.g. "Proverbs 3:13" or "1 Enoch"
  "claimed_source_book_id": "proverbs | null",        // null for non-canonical sources
  "claimed_source_chapter": 3,                          // null if not applicable
  "claimed_source_verse": 13,                           // null if not applicable
  "status": "fabricated | misquoted | misattributed",
  "actual_text": "the real verse, or null if no source exists", // null for fabricated
  "actual_text_translation": "NIV | ESV | original",
  "actual_text_book_id": "proverbs | null",
  "actual_text_chapter": 3,
  "actual_text_verse": 13,
  "what_is_wrong": "1-3 sentence explanation",        // required
  "why_it_circulates": "1-3 sentence pastoral note",  // required, charitable framing
  "related_difficult_passage_ids": ["ethiopian-bible-true-canon"], // optional cross-refs
  "tags": ["string"]                                    // optional
}

Schema rules:

  • id must be unique across the file
  • category enum strict; reject any other value
  • claimed_source_* fields all required to be either populated or null together (no partial population)
  • actual_text_* fields all required to be either populated or null together
  • If status == "fabricated", actual_text and all actual_text_* MUST be null
  • If status == "misquoted", actual_text MUST be populated
  • If status == "misattributed", actual_text is typically null but may be populated if the misattribution swaps a real quote between sources

Deliverable 2 — Seed entries

Entry 1 — fabricated Proverbs 3:13

{
  "id": "proverbs-3-13-seek-wisdom-deceived",
  "category": "misquoted-canonical",
  "alleged_text": "Blessed are those who seek wisdom, for they will not be deceived. Blessed are those who know the enemy, for they will escape his snares.",
  "claimed_source": "Proverbs 3:13",
  "claimed_source_book_id": "proverbs",
  "claimed_source_chapter": 3,
  "claimed_source_verse": 13,
  "status": "misquoted",
  "actual_text": "Blessed are those who find wisdom, those who gain understanding.",
  "actual_text_translation": "NIV",
  "actual_text_book_id": "proverbs",
  "actual_text_chapter": 3,
  "actual_text_verse": 13,
  "what_is_wrong": "Proverbs 3:13 commends finding wisdom and gaining understanding. It does not contain the words 'deceived,' 'enemy,' or 'snares.' The circulating wording appears to be a free composition styled to fit conspiracy-adjacent content.",
  "why_it_circulates": "The fabricated wording functions rhetorically — it lets a viral post close on a 'biblical' note that endorses the post's framing about hidden truth and enemies. Readers who have not opened a Bible to Proverbs 3 in some time will not catch the swap.",
  "related_difficult_passage_ids": [],
  "tags": ["fabricated", "viral-content", "wisdom-literature"]
}

Entry 2 — pseudo-Enoch

{
  "id": "pseudo-enoch-children-of-men",
  "category": "misattributed-extrabiblical",
  "alleged_text": "They will lead many astray, and the truth will be hidden from the children of men.",
  "claimed_source": "Book of Enoch",
  "claimed_source_book_id": null,
  "claimed_source_chapter": null,
  "claimed_source_verse": null,
  "status": "fabricated",
  "actual_text": null,
  "actual_text_translation": null,
  "actual_text_book_id": null,
  "actual_text_chapter": null,
  "actual_text_verse": null,
  "what_is_wrong": "These words do not appear in any extant text of 1 Enoch — neither in the Ge'ez full text, the Aramaic Qumran fragments (4QEn^a-g), nor the Greek fragments (Codex Panopolitanus, Chester Beatty). 1 Enoch's actual treatment of the Watchers' end (1 En. 10, 16) describes their binding and the judgment of their offspring's spirits, not their continuing rule over humanity.",
  "why_it_circulates": "The line is styled to sound like 1 Enoch — biblical cadence, 'children of men' phrasing, generic apocalyptic warning. It lets a viral post claim Enoch endorses a hidden-truth / leading-astray framing the actual text does not support. Few readers can verify against the real Ge'ez or Aramaic text.",
  "related_difficult_passage_ids": ["jude-quotes-enoch", "ethiopian-bible-true-canon"],
  "tags": ["fabricated", "viral-content", "extrabiblical", "1-enoch"]
}

Deliverable 3 — Schema validator

File modified: _tools/schema_validator.py

Add a validate_false_citations() function following the existing pattern (modelled on the closest existing validator — likely validate_difficult_passages or validate_proof_text_guards). Enforce:

  • File parses as JSON array
  • Each entry has required fields per the schema above
  • id values are unique
  • category and status enum values are valid
  • The conditional-population rules: claimed_source_* fields populated-together-or-all-null; same for actual_text_*
  • status == "fabricated"actual_text is null
  • status == "misquoted"actual_text is non-null
  • claimed_source_book_id, when non-null, resolves in books.json
  • actual_text_book_id, when non-null, resolves in books.json
  • All related_difficult_passage_ids resolve in difficult-passages.json
  • All tags are non-empty strings

Add the validator to the main validation runner so it executes by default.

Deliverable 4 — SQLite loader and schema

Files modified: _tools/build_sqlite_loaders.py, _tools/build_sqlite_schema.py

Table DDL (in build_sqlite_schema.py):

CREATE TABLE IF NOT EXISTS false_citations (
  id TEXT PRIMARY KEY,
  category TEXT NOT NULL,
  alleged_text TEXT NOT NULL,
  claimed_source TEXT NOT NULL,
  claimed_source_book_id TEXT,
  claimed_source_chapter INTEGER,
  claimed_source_verse INTEGER,
  status TEXT NOT NULL,
  actual_text TEXT,
  actual_text_translation TEXT,
  actual_text_book_id TEXT,
  actual_text_chapter INTEGER,
  actual_text_verse INTEGER,
  what_is_wrong TEXT NOT NULL,
  why_it_circulates TEXT NOT NULL,
  tags_json TEXT
);

CREATE TABLE IF NOT EXISTS false_citation_related (
  false_citation_id TEXT NOT NULL REFERENCES false_citations(id),
  difficult_passage_id TEXT NOT NULL,
  PRIMARY KEY (false_citation_id, difficult_passage_id)
);

CREATE INDEX IF NOT EXISTS idx_false_citations_status ON false_citations(status);
CREATE INDEX IF NOT EXISTS idx_false_citations_book ON false_citations(claimed_source_book_id);

Loader (in build_sqlite_loaders.py):

  • Add load_false_citations(conn, content_root) following the pattern of existing loaders (load_difficult_passages is the closest precedent)
  • Reads content/meta/false-citations.json
  • Inserts one row per entry into false_citations
  • Serialises tags as JSON into tags_json
  • Inserts one row per related_difficult_passage_ids element into false_citation_related
  • Wire the new loader into the main pipeline in build_sqlite.py

Deliverable 5 — SQLite validator

File modified: _tools/validate_sqlite.py

Add an integrity check that:

  • false_citations table exists and has the expected column set
  • All rows in false_citation_related.difficult_passage_id resolve to a row in difficult_passages (assuming that table name — verify against existing loader output)
  • Both seed entries are present after build

Acceptance criteria

  • content/meta/false-citations.json exists with the two seed entries
  • schema_validator.py runs clean against the file
  • schema_validator.py rejects deliberately-broken test cases (verify by running locally with a temporary invalid entry — do not commit the broken case)
  • build_sqlite.py runs clean; false_citations table populated with 2 rows; false_citation_related table populated with 1 row (from the pseudo-Enoch entry's cross-refs)
  • validate_sqlite.py passes including the new integrity check
  • No new image URLs introduced
  • PR description includes a one-line note on the schema decision (why this is not folded into proof-text-guards) for future-Craig-reading-the-archaeology

Out of scope

  • App-side UI rendering for false_citations — separate card once content density justifies it (after we have ~10 entries, this surfaces as a "How to spot fabricated citations" Explore card; that is a future deliverable, not this one)
  • Bulk-seeding additional false-citation entries — this card establishes the infrastructure and two seeds; subsequent enrichment is its own backlog
  • Cross-linking from app screens (chapter views, panels) into false-citations — separate cards once the table is populated

Future cards this enables

Once this infrastructure ships, the following become small (XS) content-only cards:

  • Pseudo-Jasher quotes (multiple in circulation)
  • Misquoted Jeremiah 1:5 ("I knew you in your mother's womb" — actual: "Before I formed you in the womb I knew you")
  • Pseudo-Gospel of Thomas sayings used in spiritual-but-not-religious content
  • Misattributed C. S. Lewis / Bonhoeffer / Spurgeon quotations (out-of-canon but a known pattern)

Each subsequent entry uses the schema established here without further infrastructure work.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions