Printed roll calls of the Board of Supervisors, 1906–1998
x_roll_callsrelease v0.7.1CC0 1.0
About
Every printed roll call ("Adopted by the following vote: Ayes: Supervisors ... Noes: ... Absent: ...") found in the Journal text, 1906-1999.
- Where it comes from
- The printed Journal of Proceedings of the Board of Supervisors, scanned by the San Francisco Public Library and held by the Internet Archive.
- How it was read
- Found in the scanned text by rules (run rollcall-parser-v1): each “Adopted by the following vote: Ayes … Noes … Absent …” is one roll call. The counts as printed are kept beside the names read, and counts_match says when they agree.
- How far to trust it
- The release passed its automatic checks before it was published (what is checked). A hand check by the editor of qipu data is under way: 36 of 38 items checked so far were right, on votes, money, places and the map. A row says what the record states; the scanned page is the authority. Details
- Licence
- CC0 1.0: use it for anything, no permission needed. The scans and other sources keep their own rights.
- Version
- v0.7.1, published 21 October 2026. A published release is never changed; corrections come as a new release.
Technical details
- Table
- x_roll_calls
- Rows
- 171,123
- Columns
- 26
- Parquet
- x_roll_calls.parquet, 16.1 MB
- Version
- v0.7.1, 21 October 2026
- Licence
- CC0 1.0. Sources keep their own rights.
Rows
Rows by corpus
| Value | Rows | Share | |
|---|---|---|---|
| page_text | 47,512 | 27.8% | |
| bos_corpus | 35,225 | 20.6% | |
| resweep_d1970 | 17,090 | 10.0% | |
| resweep_d1980 | 16,427 | 9.6% | |
| resweep_d1950 | 13,593 | 7.9% | |
| resweep_d1960 | 11,579 | 6.8% | |
| resweep_d1990 | 10,831 | 6.3% | |
| resweep_d1940 | 6,980 | 4.1% | |
| resweep_d1910 | 3,406 | 2.0% | |
| resweep_d1920 | 3,177 | 1.9% | |
| resweep_d1930 | 2,415 | 1.4% | |
| resweep_d1911 | 1,747 | 1.0% |
Rows by outcome
Rows by read_from
Method and accuracy
Found in the scanned text by rules (run rollcall-parser-v1): each “Adopted by the following vote: Ayes … Noes … Absent …” is one roll call. The counts as printed are kept beside the names read, and counts_match says when they agree.
| Field | Made by | How well it is known |
|---|---|---|
| x_roll_calls: counts (ayes/noes/absent) | rules (20_rollcalls.py) | Rule check on all 171,123 roll calls: printed counts equal the names parsed in 90.5% (1,402 print no counts). SF gold (decisions_bench/gold.jsonl, written by Opus 5.5, no record of a hand check): counts exact 40/46 (87%) where the roll call is in the item text; 12 of 58 gold roll calls not found (mostly outside the gold text span). |
The release passed its automatic checks before it was published (what is checked). A hand check by the editor of qipu data is under way: 36 of 38 items checked so far were right, on votes, money, places and the map. A row says what the record states; the scanned page is the authority.
Columns 26
| Column | Type | Can be empty | Privacy | Public copy | Description |
|---|---|---|---|---|---|
| rollcall_id | VARCHAR | no | none | as is | Id of the roll call: hash of the item id and the roll call's position in the item. |
| item_id | VARCHAR | no | none | as is | The Board item the roll call is printed in (<volume>|<n>, re-swept <volume>|g<n>); its decision is qipu:sf/decision/<item_id>. |
| corpus | VARCHAR | yes | none | as is | Where the item text came from: bos_corpus (the 2026-09 corpus) or resweep_d<decade> (re-swept items).Values bos_corpus, resweep_d1900, resweep_d1910, resweep_d1911, resweep_d1920, resweep_d1930, resweep_d1940, resweep_d1950, resweep_d1960, resweep_d1970, resweep_d1980, resweep_d1990 ... |
| page_id | VARCHAR | no | none | as is | The archive.org page: <identifier>:<leafNum> (IA's leaf number, the jp2 / IIIF number), or <identifier>:d<n> where only the BookReader index is known, or <url>:<page> for a web document. nopage:<seq> where the source gives no page number (sfbos rows without one): the row is kept, page_url is NULL.Values e.g. journalofproceed30sanfrich:1 |
| page_url | VARCHAR | yes | none | as is | Opens the page: archive.org BookReader link built from the leaf map (audited against IA's scandata), or <pdf url>#page=<n> for a PDF. NULL only where page_id is nopage:<seq>.Values e.g. https://archive.org/details/journalofproceed30sanfrich/page/n1 |
| source_id | VARCHAR | no | none | as is | archive.org identifier of the Journal volume. |
| leaf | BIGINT | yes | none | as is | archive.org BookReader page index (the n in /page/n<k>). |
| hocr_leaf | BIGINT | yes | none | as is | Page index in the OCR (before the leaf map). |
| page_exact | BOOLEAN | yes | none | as is | True when the archive.org page number was converted from the OCR leaf with the per-volume leaf map; false = may be a page or two off. |
| year | BIGINT | yes | none | as is | Year of the Journal volume. |
| date | DATE | yes | none | as is | Meeting date, where the corpus gives one within a year of the volume's year. |
| outcome_text | VARCHAR | yes | free text | private people's names withheld under the embargo | The printed outcome phrase before "by the following vote" (Adopted, Finally passed, ...), up to 120 characters. |
| outcome | VARCHAR | yes | none | as is | passed, failed or unknown, from the words in outcome_text.Values failed, passed, unknown |
| ayes_n | BIGINT | yes | none | as is | Count as printed. |
| noes_n | BIGINT | yes | none | as is | Noes count as printed. |
| absent_n | BIGINT | yes | none | as is | Absent count as printed. |
| ayes_parsed | BIGINT | yes | none | as is | Names parsed. |
| noes_parsed | BIGINT | yes | none | as is | Names parsed after Noes. |
| absent_parsed | BIGINT | yes | none | as is | Names parsed after Absent or Excused. |
| read_from | VARCHAR | yes | none | as is | v0.6.1: page_text (re-read from the Journal page text, across page breaks, with "No:" single dissents) or item_text (the item-based parse kept). |
| duplicate_of | VARCHAR | yes | none | as is | v0.6.1: the rollcall_id of the same printed roll call read from another item (a corpus item and a re-swept one); its votes are not counted twice. |
| counts_match | BOOLEAN | yes | none | as is | True when every printed count equals the names parsed (94% of roll calls). |
| numbers | VARCHAR[][] | yes | none | as is | Resolution / Ordinance / File / Bill numbers printed in the item: [kind, number, series year]. |
| context | VARCHAR | yes | raw text | left out under the embargo | Up to 300 characters of item text before the roll call. Empty (withheld in the public files for records under the privacy embargo (75 years in SF, 92 in Vancouver)). |
| quote | VARCHAR | yes | raw text | left out under the embargo | The roll call as printed, from 60 characters before it (<= 600 characters). Names supervisors, who are public officials. Not published for records under the embargo: the quoted lines carry the item text ("Submitted by ..."), not only the roll. |
| run_id | VARCHAR | no | none | as is | rollcall-parser-v1 (see runs).Values rollcall-parser-v1 |
Privacy: what kind of text the column holds. Public copy: what the published file does with it; the embargo covers records after 1951.
Preview
8 of 26 columns shown. Eight rows sampled at build time, from the years up to 1951. Hover a shortened value for all of it.
Download
| Format | File | Size |
|---|---|---|
| Parquet | x_roll_calls.parquet ↗ | 16.1 MB |
| SQLite (all tables) | qipu_sf.db ↗ | 6.44 GB |
SQL
Run in the SQL console (DuckDB in the browser, over the Parquet file).