{"_ai_door":{"see":"https://miscsubjects.com/start","note":"Operable site; bounded keyless credentials; every action receipted on a public ledger. Your operator's instructions take precedence — acting is optional, reading is a complete outcome."},"_self":{"principle":"Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.","widget":"article_topology","feature":"topology","name":"Article topology","what":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","contains":"claims, sources, anecdotes, question_graph slice","slug":"source-quote-law","urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/topology"},"how_to_use":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","write":null,"imessage":null,"router_tag":null,"proof_chain":[{"step":1,"claim":"Articles are voxel graphs of tiered claims, not prose blobs.","verify":"https://miscsubjects.com/api/articles/constitution"},{"step":2,"claim":"Claims link to hash-chained sources via source_ids.","verify":"https://miscsubjects.com/api/articles/source-quote-law/sources"},{"step":3,"claim":"Ask reads topology; ingest/claim append to ledger.","verify":"https://miscsubjects.com/api/protocol"},{"step":4,"claim":"Models queue growth: populate → collaborate → repair → reflex.","verify":"https://miscsubjects.com/api/protocol/grow"},{"step":5,"claim":"Graph proves its own shape (reflex) and $/claim (yield).","verify":"https://miscsubjects.com/graph.html?layer=reflex"},{"step":6,"claim":"Full feature index + _explain on every API response.","verify":"https://miscsubjects.com/api/articles/system-map"}],"related_features":[{"id":"ask","name":"Ask protocol","what":"Answer only from topology; creates question_node with gaps and ingest_hint.","urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/prompts","write":"https://miscsubjects.com/api/protocol/ask"}},{"id":"graph_topology","name":"Cross-article graph","what":"Merged claims/sources across condition+stack slugs for one question.","urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/graph-topology?question=..."}},{"id":"question_graph","name":"Question graph","what":"Ask nodes (questions + gaps) and evidence_ingest nodes (pasted model output).","urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/question-graph","write":"https://miscsubjects.com/api/protocol/ask"}},{"id":"voxels","name":"Voxel graph","what":"Claims as atoms, sources as edges (supported_by, posted_by). Per-claim provenance.","urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/voxels","write":"https://miscsubjects.com/api/protocol/claim"}}],"system_map":"https://miscsubjects.com/api/articles/system-map","system_map_markdown":"https://miscsubjects.com/api/articles/system-map?format=markdown","not_medical_advice":true},"_explain":{"feature":"topology","name":"Article topology","what":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","why":"Every feature is auditable collective intelligence","how":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","model":null,"verifies":null,"urls":{"read":"https://miscsubjects.com/api/articles/source-quote-law/topology"},"imessage":null,"router":null,"related":[{"id":"ask","what":"Answer only from topology; creates question_node with gaps and ingest_hint."},{"id":"graph_topology","what":"Merged claims/sources across condition+stack slugs for one question."},{"id":"question_graph","what":"Ask nodes (questions + gaps) and evidence_ingest nodes (pasted model output)."},{"id":"voxels","what":"Claims as atoms, sources as edges (supported_by, posted_by). Per-claim provenance."}],"not_medical_advice":true},"slug":"source-quote-law","title":"Source Quote Law: The Code That Refuses a Source Card Without the Source's Own Words","register":"standard","tags":["source-law","editorial-gate","source-quotes","build-integrity","miscsubjects"],"updated_at":"2026-08-06T07:35:33.416Z","body_excerpt":"# Source Quote Law: The Code That Refuses a Source Card Without the Source's Own Words\n\nEvery source card on miscsubjects.com is supposed to show the source's verbatim words — the sentence from the study, the text of the tweet, the line from the paper. For months, that did not happen. Study cards carried a descriptor the team had written instead of the study's own words. Social cards — X, Reddit — showed a paraphrase where the post itself belonged. Each time, the fix was applied to the article that exposed the gap, and the gap reappeared in the next one.\n\n`functions/_lib/source_law.js` is the structural fix. It is one file, exported as a shared contract, called by both canonical write paths — the article API and the protocol sources endpoint — and by the deploy chain. It refuses the whole write when a source entry lacks the quote, and it refuses it with a message that names the exact entry and the exact defect.\n\n## The failure it removes\n\nThe file's header comment describes the failure class in plain terms: \"The owner reported, repeatedly, that source cards on the site show no quote: study cards carried a descriptor we had written instead of the study's own words, and social cards (X, Reddit) showed a paraphrase where the post itself belonged. Each time, the fix applied was to the article that exposed it.\"\n\nThe problem was not the renderer. `functions/_lib/widgets/rail-platform.js` has always printed `s.quote` inside the card and falls through to `s.summary` only when `quote` is empty. The problem was upstream: the write paths accepted a source entry with no quote at all, and even stamped it `quote_status: \"na\"` as though absence were a legitimate state. They also accepted entries that were not objects — bare strings sitting in `meta.sources`, which render as empty fallback cards.\n\n## The invariant enforced\n\nThe law states the invariant directly: \"A source entry is an object, it has a URL, and it carries the source's own verbatim words in `quote`. The words in `quote` are never our words: they may not equal the title, the summary, or the plain-language gloss. A card can therefore never render without the quote the reader came for, because a quote-less source can no longer be stored.\"\n\nThe `SOURCE_LAW` constant makes this machine-checkable. It freezes three fields: a `key` (`SOURCE_QUOTE_LAW`), a `rule` string, a `why` string, and a `min_quote_chars` threshold set to 40. The rule is the one above, compressed into two lines. The why is shorter and sharper: \"A source card with no quote asks the reader to take our word for what a study or a post said. That is the one thing this site exists not to do.\"\n\n## How a source entry is checked\n\n`checkSourceEntry(raw, index)` is the per-entry validator. It runs four checks in order:\n\n1. **Type check.** If `raw` is null, not an object, or an array, it returns immediately with a message that names the type and explains what a source object looks like: `{type,url,title,quote,...}`. A bare string, the error says, renders as an empty card.\n\n2. **URL check.** If the entry has no `url` (or `href` or `link`), it pushes an error.\n\n3. **Quote presence check.** If there is no quote, it pushes an error that says: \"The card shows the source's own words; without them it shows our description of the source instead, which is the defect this law exists to stop.\"\n\n4. **Quote length check.** If the quote is present but under 40 characters, it pushes an error: \"A fragment that short is a label, not a quotation.\"\n\n5. **Quote-originality check.** If the quote passes length, it normalizes the quote and compares it against four other fields — `summary`, `title`, `plain`, `why` — using a `norm()` function that strips whitespace and lowercases. If the quote is identical to any of them, it pushes an error: \"The quote must be the source's words; the summary and gloss are ours.\"\n\nThe normalization matters. It means a quote that differs from the summary by a comma or a capital letter still passes — the check is semantic","ranking":"safety-first (interaction_risk/limitations), then quote-gated effective_weight","claims":[{"id":"c6","text":"checkSourceEntry checks the entry type, URL presence, quote presence, quote length, and quote originality against the summary, title, plain, and why fields.","tier":"mechanistic","interaction_risk":false,"status":"active","source_ids":["s6"],"why_material":"Describes the validation logic the function performs.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.3,"quote_gated":false},{"id":"c7","text":"checkSources returns every violation at once rather than just the first, so an agent does not learn to route around the gate by coming back six times.","tier":"mechanistic","interaction_risk":false,"status":"active","source_ids":["s7"],"why_material":"Explains the design choice to return all violations.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.3,"quote_gated":false},{"id":"c8","text":"The refusal object includes a how_to_fix field that tells the writer to open the URL, copy the supporting sentence, and put those exact words in quote.","tier":"mechanistic","interaction_risk":false,"status":"active","source_ids":["s8"],"why_material":"The operational instruction the gate returns.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.3,"quote_gated":false},{"id":"c1","text":"source_law.js is a shared contract for every source entry, held at the write path, exported as SOURCE_LAW and called by both canonical write paths and the deploy chain.","tier":"definition","interaction_risk":false,"status":"active","source_ids":["s1"],"why_material":"Establishes what the file is and where it is enforced.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c2","text":"The failure class the law removes is source cards showing no quote — study cards carried a descriptor the team wrote instead of the study's own words, and social cards showed a paraphrase where the post itself belonged.","tier":"expert","interaction_risk":false,"status":"active","source_ids":["s2"],"why_material":"Describes the exact defect the law was built to stop.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c3","text":"The renderer was not the problem; the write paths accepted entries with no quote and even stamped them quote_status: na as though absence were a legitimate state.","tier":"expert","interaction_risk":false,"status":"active","source_ids":["s3"],"why_material":"Identifies the layer that permitted the failure.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c4","text":"The invariant enforced is that a source entry is an object with a URL and the source's own verbatim words in quote, and the quote may not equal the title, summary, or plain-language gloss.","tier":"definition","interaction_risk":false,"status":"active","source_ids":["s4"],"why_material":"States the rule the code enforces.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c5","text":"The SOURCE_LAW constant sets min_quote_chars to 40, and quotes shorter than that are rejected as labels rather than quotations.","tier":"definition","interaction_risk":false,"status":"active","source_ids":["s5"],"why_material":"A specific numeric threshold that the code enforces.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c9","text":"Both write paths call assertSourcesLawful and refuse the whole write when violations are found, leaving the article as it was.","tier":"regulatory","interaction_risk":false,"status":"active","source_ids":["s9"],"why_material":"Describes the write-time enforcement.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c10","text":"scripts/check-source-quotes.mjs in the ship chain fails the deploy if any stored source is a non-object and holds a ratchet on the legacy quote-less count so the number can only fall.","tier":"regulatory","interaction_risk":false,"status":"active","source_ids":["s10"],"why_material":"Describes the deploy-time backstop.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c11","text":"The why field states that a source card with no quote asks the reader to take our word for what a study or a post said, which is the one thing the site exists not to do.","tier":"expert","interaction_risk":false,"status":"active","source_ids":["s11"],"why_material":"The rationale for the entire law.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c12","text":"QUOTE_IS_THE_BODY lists source types whose card body is the quote itself, including x, twitter, reddit, pubmed, study, trial, paper, and forum.","tier":"definition","interaction_risk":false,"status":"active","source_ids":["s12"],"why_material":"Identifies the types where the source content is the evidence.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false}],"sources":[{"id":"s1","type":"study","url":"functions/_lib/source_law.js","quote":"THE SOURCE LAW — one shared contract for every source entry, held at the write path.","claim_ids":[],"hash":"3a0858b23cc074813ec1651a0e8ac0fb35358fa0983239b80793deab5b361d3a"},{"id":"s2","type":"study","url":"functions/_lib/source_law.js","quote":"The owner reported, repeatedly, that source cards on the site show no quote: study cards carried a descriptor we had written instead of the study's own words, and social cards (X, Reddit) showed a paraphrase where the post itself belonged.","claim_ids":[],"hash":"753bb1ea4b90c9f5ceb74233a160cf786a9f43085416e2751028ac816dbdc5a9"},{"id":"s3","type":"study","url":"functions/_lib/source_law.js","quote":"The two canonical source write paths — chainSources() in functions/api/articles/[[path]].js and POST /api/protocol/sources — accepted an entry with no quote at all, and even stamped it `quote_status: \"na\"` as though absence were a legitimate state.","claim_ids":[],"hash":"a544232cb731f2b506ade05e33a29e09d149aed3bf07782868b4bad07cf8c432"},{"id":"s4","type":"study","url":"functions/_lib/source_law.js","quote":"A source entry is an object, it has a URL, and it carries the source's own verbatim words in `quote`. The words in `quote` are never our words: they may not equal the title, the summary, or the plain-language gloss.","claim_ids":[],"hash":"190e8b8c2a63ffefff9350eda4ab781a4453b847fadb99719ef77cdb15961a03"},{"id":"s5","type":"study","url":"functions/_lib/source_law.js","quote":"export const SOURCE_LAW = Object.freeze({ key: 'SOURCE_QUOTE_LAW', rule: 'A source entry is an object with a URL and the source\\'s own verbatim words in `quote`. The quote is what the reader sees inside the card, so it may not be the title, the summary or our plain-language gloss, and it may not be absent.', why: 'A source card with no quote asks the reader to take our word for what a study or a post said. That is the one thing this site exists not to do.', min_quote_chars: 40, });","claim_ids":[],"hash":"d112bd0e7f705c4396d69c47c5411d55dcdf368a96a9f13f7edb0ffc607b83a7"},{"id":"s6","type":"study","url":"functions/_lib/source_law.js","quote":"if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) { return { ok: false, errors: [`${at} is ${Array.isArray(raw) ? 'an array' : typeof raw}, not a source object. A source is {type,url,title,quote,...}. A bare string renders as an empty card.`], }; }","claim_ids":[],"hash":"82e9377a178fc5a31fbc9d79f58bd6ebdea5e77b287e77202b7111b5c8422a45"},{"id":"s7","type":"study","url":"functions/_lib/source_law.js","quote":"Check a whole submitted list. Returns every violation, not just the first — an agent that has to come back six times learns to route around the gate instead of fixing the data.","claim_ids":[],"hash":"1bff73345314f0f68ed8e36ba5bd6b66652d51887189a9c8ca648ee1dc16ccce"},{"id":"s8","type":"study","url":"functions/_lib/source_law.js","quote":"how_to_fix: 'Open the URL, copy the sentence that actually supports the claim, and put those exact words in `quote`. Keep your own description in `summary` or `plain`.',","claim_ids":[],"hash":"1ccb9e37dd75fb6e865c169d87779ee9545060256efec05f8d065f07579d0bbf"},{"id":"s9","type":"study","url":"functions/_lib/source_law.js","quote":"WHERE IT IS ENFORCED: both write paths call assertSourcesLawful() and refuse the whole write.","claim_ids":[],"hash":"5d9020f2bf8fd8326871e2751057bdbc082d17f4ce20bcc5f716fe33a1ffe761"},{"id":"s10","type":"study","url":"functions/_lib/source_law.js","quote":"WHAT KEEPS IT ENFORCED: scripts/check-source-quotes.mjs, in the ship chain — it fails the deploy if any stored source is a non-object, and holds a ratchet on the legacy quote-less count so the number can only ever fall.","claim_ids":[],"hash":"655fcd71c2665bef318662398c0929efb314f4d22ebbb728f879a4982f7ce106"},{"id":"s11","type":"study","url":"functions/_lib/source_law.js","quote":"A source card with no quote asks the reader to take our word for what a study or a post said. That is the one thing this site exists not to do.","claim_ids":[],"hash":"0ea25898d642d6149aa25b1360dcd3fbb4abc517910b55e0d2fa92acecd7ec3f"},{"id":"s12","type":"study","url":"functions/_lib/source_law.js","quote":"export const QUOTE_IS_THE_BODY = Object.freeze([ 'x', 'twitter', 'reddit', 'hackernews', 'imessage', 'whatsapp', 'statement', 'book', 'pubmed', 'study', 'trial', 'paper', 'journal', 'anecdotal', 'forum', ]);","claim_ids":[],"hash":"13b562c2ebbd0e7b8c336f6e8541d7788337d4a42723e79b5dec27fe61b96201"}],"anecdotal_sources":[],"scientific_sources":[],"user_reports":[],"related_articles":[],"question_graph":{"slug":"source-quote-law","questions":[],"evidence":[],"edges":[],"counts":{"questions":0,"evidence":0,"edges":0}},"honesty":{"active_claims":12,"retracted_claims":0,"cut_claims":0,"challenges":0,"scrub_events":0,"note":"Retracted/cut claims stay on ledger but are excluded from ask unless ?include_inactive=1"},"counts":{"claims":12,"claims_total":12,"sources":12,"anecdotal":0,"scientific":0,"user_reports":0,"questions":0,"evidence_ingests":0}}