{
 "sources": [
  {
   "id": "outlet-seattle-times",
   "name": "Seattle Times",
   "url": "https://www.seattletimes.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-spokesman-review",
   "name": "Spokesman-Review",
   "url": "https://www.spokesman.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-columbian",
   "name": "The Columbian",
   "url": "https://www.columbian.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-everett-herald",
   "name": "Everett Herald",
   "url": "https://www.heraldnet.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-tri-city-herald",
   "name": "Tri-City Herald",
   "url": "https://www.tri-cityherald.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-wa-state-standard",
   "name": "Washington State Standard",
   "url": "https://washingtonstatestandard.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-kuow",
   "name": "KUOW",
   "url": "https://www.kuow.org/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-cascade-pbs",
   "name": "Cascade PBS",
   "url": "https://www.cascadepbs.org/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-the-stranger",
   "name": "The Stranger",
   "url": "https://www.thestranger.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-deseret-news",
   "name": "Deseret News",
   "url": "https://www.deseret.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-cascadia-daily",
   "name": "Cascadia Daily News",
   "url": "https://www.cascadiadaily.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-komo",
   "name": "KOMO",
   "url": "https://komonews.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-king5",
   "name": "KING 5",
   "url": "https://www.king5.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-kiro7",
   "name": "KIRO 7",
   "url": "https://www.kiro7.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-kxly",
   "name": "KXLY",
   "url": "https://www.kxly.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-fox13",
   "name": "Fox 13 Seattle",
   "url": "https://www.fox13seattle.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-axios-seattle",
   "name": "Axios Seattle",
   "url": "https://www.axios.com/local/seattle",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-krem",
   "name": "KREM",
   "url": "https://www.krem.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-center-square",
   "name": "The Center Square",
   "url": "https://www.thecentersquare.com/washington/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-seattle-red",
   "name": "Seattle Red/KTTH",
   "url": "https://seattlered.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-mynorthwest",
   "name": "MyNorthwest/KIRO Newsradio",
   "url": "https://mynorthwest.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-wpc",
   "name": "Washington Policy Center",
   "url": "https://www.washingtonpolicy.org/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "advocacy",
    "interest": "none",
    "note": "Free-market think tank that argued for I-645 (repeal); its staff are quoted as Yes-side sources. Its own I-645 posts are coded rows (opinion)."
   }
  },
  {
   "id": "outlet-daily-wire",
   "name": "The Daily Wire",
   "url": "https://www.dailywire.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-lynnwood-times",
   "name": "Lynnwood Times",
   "url": "https://lynnwoodtimes.com/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "news",
    "interest": "none",
    "note": "News publisher whose coverage is the subject of the coding; its I-645 stories (June 1 to Oct 21, 2026) are rows in the stories table. It has no stake in the counts beyond its own coverage."
   }
  },
  {
   "id": "outlet-npi",
   "name": "NPI Cascadia Advocate",
   "url": "https://www.nwprogressive.org/weblog/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "partyToDispute",
    "interest": "none",
    "note": "Northwest Progressive Institute, part of the coalition opposing I-645; it published the No coalition's legal memo. Its blog posts are coded rows (opinion)."
   }
  },
  {
   "id": "outlet-the-stand",
   "name": "The Stand",
   "url": "https://www.thestand.org/",
   "retrievedAt": "2026-10-21",
   "role": "Publisher of coded I-645 stories. Each story's exact URL is in the stories table (column url); the publisher's site is listed here.",
   "licenseName": "All rights reserved (publisher copyright)",
   "licenseUrl": null,
   "redistribution": "Story text is not redistributed. The dataset holds coding, story metadata and quotes of 25 words or fewer.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "partyToDispute",
    "interest": "none",
    "note": "News site of the Washington State Labor Council, AFL-CIO, which opposes I-645 and whose president debated for the No side. Its posts are coded rows."
   }
  },
  {
   "id": "wrc-i645-brief",
   "name": "Washington Research Council, \"New brief: I-645: Repealing the State Individual Income Tax\" (Sept. 22, 2026)",
   "url": "https://researchcouncil.org/new-brief-i-645-repealing-the-state-individual-income-tax/",
   "retrievedAt": "2026-10-21",
   "role": "Anchor for facts O3b (no current appropriation relies on the tax) and O4 (the 2027-29 outlook assumes the revenue).",
   "licenseName": "All rights reserved",
   "licenseUrl": null,
   "redistribution": "Linked only.",
   "artifactId": null,
   "readUrl": "https://researchcouncil.org/wp-content/uploads/Initiative645.pdf",
   "reliability": {
    "publisherKind": "other",
    "interest": "none",
    "note": "Business-funded nonpartisan fiscal research group. Its brief states both that no current appropriation relies on the tax and that the four-year outlook assumes $2.698 billion from it in 2027-29."
   }
  },
  {
   "id": "sos-voters-pamphlet",
   "name": "Washington Secretary of State, 2026 General Election Voters' Pamphlet (Edition 10, Spokane)",
   "url": "https://www.sos.wa.gov/sites/default/files/2026-10/Voters%20Pamphlet%202026%20-%20Edition%2010%20-%20Spokane.pdf",
   "retrievedAt": "2026-10-21",
   "role": "Anchor for fact O1 (the Attorney General's explanatory statement says the tax relief would remain in place) and for the ballot sentence text.",
   "licenseName": "Washington State government publication",
   "licenseUrl": null,
   "redistribution": "Linked only.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "government",
    "interest": "none",
    "note": "Official state publication. The explanatory statement and ballot disclosure are written by the Attorney General's office; the statewide text is the same in every edition."
   }
  },
  {
   "id": "erfc-outlook-apr-2026",
   "name": "Economic and Revenue Forecast Council, enacted 2026 supplemental budget outlook (Apr. 22, 2026)",
   "url": "https://erfc.wa.gov/sites/default/files/2026-04/20260422_Enacted_Sup_BO_Adopted.pdf",
   "retrievedAt": "2026-10-21",
   "role": "Anchor for fact O4: the outlook counts ESSB 6346 revenue in 2027-29.",
   "licenseName": "Washington State government publication",
   "licenseUrl": null,
   "redistribution": "Linked only.",
   "artifactId": null,
   "readUrl": null,
   "reliability": {
    "publisherKind": "government",
    "interest": "none",
    "note": "State council that adopts the official four-year balanced-budget outlook; lists ESSB 6346 at +$2,309.18 million (net) for 2027-29."
   }
  }
 ],
 "tables": [
  {
   "id": "stories",
   "title": "Coded I-645 stories",
   "description": "One row per story about I-645 published June 1 to Oct 21, 2026 by 26 Washington and national outlets, coded with one codebook (media_coding_codebook.md).",
   "artifactId": "stories-csv",
   "unitOfObservation": "One news story, explainer, broadcast write-up, opinion piece or editorial",
   "fields": [
    {
     "name": "story_id",
     "type": "string",
     "description": "Row identifier assigned by the coder (stable within this release).",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "outlet",
     "type": "string",
     "description": "Publishing outlet (masthead), one of 26.",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "outlet_detail",
     "type": "string",
     "description": "Outlet as recorded by the coder, e.g. \"Seattle Times via Spokesman-Review\" for a syndicated copy.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "outlet_group",
     "type": "string",
     "description": "mainstream, conservative or progressive, assigned by the audit design before coding (not by our judgment of each outlet).",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "date",
     "type": "date",
     "description": "Publication date (YYYY-MM-DD).",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "author",
     "type": "string",
     "description": "Byline as published.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "headline",
     "type": "string",
     "description": "Headline as published.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "url",
     "type": "string",
     "description": "Story URL. Copies used to read blocked pages are listed in notes.",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "read_status",
     "type": "string",
     "description": "full or partial (paywall). No row is unread in this release.",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "type",
     "type": "string",
     "description": "news, explainer, fact_check, broadcast (counted as news), opinion or editorial.",
     "units": null,
     "nullable": false,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "yes_sources",
     "type": "integer",
     "description": "Distinct Yes-side (repeal) advocates quoted or paraphrased.",
     "units": "count",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "no_sources",
     "type": "integer",
     "description": "Distinct No-side advocates quoted or paraphrased.",
     "units": "count",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "neutral_sources",
     "type": "integer",
     "description": "Neutral sources (agencies, courts, pollsters, nonpartisan analysts).",
     "units": "count",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "first_word",
     "type": "string",
     "description": "Side of the first advocate quoted: yes, no, neutral or none.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "last_word",
     "type": "string",
     "description": "Side of the last advocate quoted.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "rebuttal",
     "type": "string",
     "description": "Y if the other side responds to the story's lead claim; N if not; NA for opinion.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "headline_term",
     "type": "string",
     "description": "How the headline names the tax.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "loaded_terms",
     "type": "string",
     "description": "Loaded words; Q: prefix = only inside a quotation.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "no_claims_unchecked",
     "type": "string",
     "description": "Semicolon list of No-campaign claim codes repeated with no context on that claim (codebook).",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "yes_claims_unchecked",
     "type": "string",
     "description": "Semicolon list of Yes-campaign claim codes repeated with no context.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "claims_checked",
     "type": "string",
     "description": "Claim codes the story itself contextualized or checked.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O1",
     "type": "integer",
     "description": "1 if the story says the tax relief survives repeal (AG statement); 0 if not.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O2",
     "type": "integer",
     "description": "1 if it says the revenue goes to the general fund / is not dedicated to K-12.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O3a",
     "type": "integer",
     "description": "1 if it says collections start in 2029.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O3b",
     "type": "integer",
     "description": "1 if it says no current appropriation relies on the tax (in any voice; see O3b_voice).",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O4",
     "type": "integer",
     "description": "1 if it says the 2027-29 budget outlook counts on the revenue (in any voice; see O4_voice).",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O5",
     "type": "integer",
     "description": "1 if it says lawmakers, not voters, could lower the $1 million threshold.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O6",
     "type": "integer",
     "description": "1 if it says the revenue estimate is static or the revenue volatile.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O7",
     "type": "integer",
     "description": "1 if it reports the No side's union funding or that No outraised Yes.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O8",
     "type": "integer",
     "description": "1 if it mentions Heywood's (or Yes donors') personal financial interest.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O9",
     "type": "integer",
     "description": "1 if it mentions the legal risk I-645's text poses to the capital gains tax.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "O3b_voice",
     "type": "string",
     "description": "fact (reporter or neutral source) or advocate (only in a campaign side's quote) when O3b = 1.",
     "units": null,
     "nullable": true,
     "valueType": "derived",
     "derivation": "Voice re-pass of every news text, recorded in media_coding_overrides.json.",
     "sourceIds": []
    },
    {
     "name": "O4_voice",
     "type": "string",
     "description": "fact or advocate when O4 = 1.",
     "units": null,
     "nullable": true,
     "valueType": "derived",
     "derivation": "Voice re-pass of every news text, recorded in media_coding_overrides.json.",
     "sourceIds": []
    },
    {
     "name": "has_error",
     "type": "integer",
     "description": "1 if the coder recorded a factual error in reporter or outlet voice, minor ones included.",
     "units": "0/1",
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "errors",
     "type": "string",
     "description": "The error, the correct fact, and whether a correction was found.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "ballot_sentence",
     "type": "string",
     "description": "none, mentioned, quoted or critiqued.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "dhm_poll",
     "type": "string",
     "description": "Y if the story reports the DHM poll's with/without-sentence result; partial; N.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "key_quote",
     "type": "string",
     "description": "Verbatim passage of 25 words or fewer illustrating the coding.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "sources_detail",
     "type": "string",
     "description": "Who was counted on each side.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    },
    {
     "name": "notes",
     "type": "string",
     "description": "Coder notes.",
     "units": null,
     "nullable": true,
     "valueType": "observed",
     "derivation": null,
     "sourceIds": []
    }
   ]
  },
  {
   "id": "omission-rates",
   "title": "How often stories included each key fact",
   "description": "For each group of stories and each fact (O1-O9, plus the voice split for O3b and O4), how many stories included it.",
   "artifactId": "omission-csv",
   "unitOfObservation": "Story group by fact",
   "fields": [
    {
     "name": "group",
     "type": "string",
     "description": "Story group, e.g. \"Mainstream news\" (news, explainer, fact check and broadcast stories from mainstream outlets).",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "fact_code",
     "type": "string",
     "description": "Codebook fact code; -fact / -advocate suffix = voice split.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "fact",
     "type": "string",
     "description": "Plain-language fact.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "rebuts_claims_of",
     "type": "string",
     "description": "Which campaign's claims the fact rebuts.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_including",
     "type": "integer",
     "description": "Stories that included the fact.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_coded",
     "type": "integer",
     "description": "Stories coded for the fact.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "share_including",
     "type": "number",
     "description": "stories_including / stories_coded.",
     "units": "fraction",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    }
   ]
  },
  {
   "id": "claim-checks",
   "title": "Campaign claims: unchecked vs contextualized",
   "description": "For each story group and graded campaign claim, how many stories repeated it with no context and how many contextualized it.",
   "artifactId": "claims-csv",
   "unitOfObservation": "Story group by campaign claim",
   "fields": [
    {
     "name": "group",
     "type": "string",
     "description": "Story group.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "claim_code",
     "type": "string",
     "description": "Codebook claim code.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "claim_side",
     "type": "string",
     "description": "Yes or No campaign.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "claim",
     "type": "string",
     "description": "The claim.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_unchecked",
     "type": "integer",
     "description": "Stories repeating it with no context.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_contextualized",
     "type": "integer",
     "description": "Stories that contextualized or checked it.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "share_contextualized",
     "type": "number",
     "description": "Contextualized share.",
     "units": "fraction",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    }
   ]
  },
  {
   "id": "sourcing-balance",
   "title": "Sourcing balance by story group",
   "description": "Average sources per side, first and last word, missing rebuttals, unchecked-claim counts and claim-check rates by story group.",
   "artifactId": "sourcing-csv",
   "unitOfObservation": "Story group",
   "fields": [
    {
     "name": "group",
     "type": "string",
     "description": "Story group.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories",
     "type": "integer",
     "description": "stories.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "avg_yes_sources",
     "type": "number",
     "description": "avg yes sources.",
     "units": "sources per story",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "avg_no_sources",
     "type": "number",
     "description": "avg no sources.",
     "units": "sources per story",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "first_word_yes",
     "type": "integer",
     "description": "first word yes.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "first_word_no",
     "type": "integer",
     "description": "first word no.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "last_word_yes",
     "type": "integer",
     "description": "last word yes.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "last_word_no",
     "type": "integer",
     "description": "last word no.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "no_rebuttal",
     "type": "integer",
     "description": "no rebuttal.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_with_unchecked_no_claim",
     "type": "integer",
     "description": "stories with unchecked no claim.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_with_unchecked_yes_claim",
     "type": "integer",
     "description": "stories with unchecked yes claim.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "no_claim_instances",
     "type": "integer",
     "description": "no claim instances.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "no_claim_instances_contextualized",
     "type": "integer",
     "description": "no claim instances contextualized.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "yes_claim_instances",
     "type": "integer",
     "description": "yes claim instances.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "yes_claim_instances_contextualized",
     "type": "integer",
     "description": "yes claim instances contextualized.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories_with_error",
     "type": "integer",
     "description": "stories with error.",
     "units": "count",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    }
   ]
  },
  {
   "id": "coder-agreement",
   "title": "Agreement between the first coding and a blind second coder",
   "description": "Percent agreement and Cohen's kappa on a stratified random sample of 20 news stories (14 mainstream, 6 conservative; seed 645).",
   "artifactId": "agreement-csv",
   "unitOfObservation": "Coded field",
   "fields": [
    {
     "name": "field",
     "type": "string",
     "description": "Coded field; O3b and O4 shown before and after the voice re-pass.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "stories",
     "type": "integer",
     "description": "Stories compared.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "agree",
     "type": "integer",
     "description": "Stories where both coders agreed.",
     "units": "stories",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "percent_agreement",
     "type": "number",
     "description": "Agreement.",
     "units": "percent",
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "cohens_kappa",
     "type": "number",
     "description": "Cohen's kappa (blank when one category only).",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    },
    {
     "name": "disagreements",
     "type": "string",
     "description": "story_id:first→second for each disagreement.",
     "units": null,
     "nullable": false,
     "valueType": "derived",
     "derivation": "Computed from the stories table by media_audit_derived.js.",
     "sourceIds": []
    }
   ]
  }
 ],
 "headline": [
  {
   "group": "Mainstream news",
   "fact_code": "O3b-fact",
   "fact": "No current appropriation relies on it (stated as fact)",
   "rebuts_claims_of": "No side",
   "stories_including": 2,
   "stories_coded": 58,
   "share_including": 0.034
  },
  {
   "group": "Mainstream news",
   "fact_code": "O3b",
   "fact": "No current appropriation relies on it",
   "rebuts_claims_of": "No side",
   "stories_including": 7,
   "stories_coded": 58,
   "share_including": 0.121
  },
  {
   "group": "Mainstream news",
   "fact_code": "O1",
   "fact": "Tax relief survives repeal",
   "rebuts_claims_of": "No side",
   "stories_including": 9,
   "stories_coded": 58,
   "share_including": 0.155
  },
  {
   "group": "Mainstream news",
   "fact_code": "O2",
   "fact": "Revenue not dedicated to K-12",
   "rebuts_claims_of": "No side",
   "stories_including": 8,
   "stories_coded": 58,
   "share_including": 0.138
  },
  {
   "group": "Mainstream news",
   "fact_code": "O4-fact",
   "fact": "2027-29 budget outlook counts on it (stated as fact)",
   "rebuts_claims_of": "Yes side",
   "stories_including": 6,
   "stories_coded": 58,
   "share_including": 0.103
  },
  {
   "group": "Mainstream news",
   "fact_code": "O4",
   "fact": "2027-29 budget outlook counts on it",
   "rebuts_claims_of": "Yes side",
   "stories_including": 7,
   "stories_coded": 58,
   "share_including": 0.121
  },
  {
   "group": "Mainstream news",
   "fact_code": "O8",
   "fact": "Heywood's personal financial interest",
   "rebuts_claims_of": "Yes side",
   "stories_including": 1,
   "stories_coded": 58,
   "share_including": 0.017
  },
  {
   "group": "Conservative news",
   "fact_code": "O3b-fact",
   "fact": "No current appropriation relies on it (stated as fact)",
   "rebuts_claims_of": "No side",
   "stories_including": 1,
   "stories_coded": 16,
   "share_including": 0.063
  },
  {
   "group": "Conservative news",
   "fact_code": "O3b",
   "fact": "No current appropriation relies on it",
   "rebuts_claims_of": "No side",
   "stories_including": 4,
   "stories_coded": 16,
   "share_including": 0.25
  },
  {
   "group": "Conservative news",
   "fact_code": "O1",
   "fact": "Tax relief survives repeal",
   "rebuts_claims_of": "No side",
   "stories_including": 5,
   "stories_coded": 16,
   "share_including": 0.313
  },
  {
   "group": "Conservative news",
   "fact_code": "O2",
   "fact": "Revenue not dedicated to K-12",
   "rebuts_claims_of": "No side",
   "stories_including": 7,
   "stories_coded": 16,
   "share_including": 0.438
  },
  {
   "group": "Conservative news",
   "fact_code": "O4-fact",
   "fact": "2027-29 budget outlook counts on it (stated as fact)",
   "rebuts_claims_of": "Yes side",
   "stories_including": 0,
   "stories_coded": 16,
   "share_including": 0
  },
  {
   "group": "Conservative news",
   "fact_code": "O4",
   "fact": "2027-29 budget outlook counts on it",
   "rebuts_claims_of": "Yes side",
   "stories_including": 2,
   "stories_coded": 16,
   "share_including": 0.125
  },
  {
   "group": "Conservative news",
   "fact_code": "O8",
   "fact": "Heywood's personal financial interest",
   "rebuts_claims_of": "Yes side",
   "stories_including": 1,
   "stories_coded": 16,
   "share_including": 0.063
  }
 ]
}