Skip to content

How these records are built

01

Source

Votes are extracted automatically from the official City Council minutes (PDF). Each record links to the page it came from.

02

Named positions

Minutes usually record the tally (“8 yeas, 1 nay”) and name only the members in the minority. Everyone else is shown as “not individually listed”, never as an assumed yes.

Example · Minutes, Sep 8, 2026, p. 5
“On a motion made by Councilor Canuel and seconded by Councilor Pereira, it was voted 2 yeas, 7 nays, that the proposed ordinance be granted leave to withdraw, with Councilors Canuel and Pereira voting in the affirmative, and the motion failed to carry.”

2–7 2 yeas, 7 nays Pereira and Canuel: named yes. The others: not individually listed. Minutes p. 5(PDF, opens in a new tab)

03

Unanimous votes

Most council decisions are recorded simply as passing “unanimously.” That tells you nobody objected. It doesn’t say who was in the room when that motion came up.

Councilors arrive late, step out, and leave early; our attendance comes only from the opening roll call. So when a motion is unanimous, a councilor’s record shows Unanimous · not named instead of a yes. These votes count toward a councilor’s motions, but never toward their named yes or no totals, and they appear under “Not named” in the position filter. If the minutes do name a member on a unanimous motion (for example, recording an abstention or recusal), we show that recorded position instead.

04

Attendance

Attendance counts only meetings with a verified opening roll call.

Attendance is present at opening roll call divided by meetings with usable present/absent records for that councilor in the selected date range. “Verified” means the record passed our source-validation or review process; it does not necessarily mean someone visually checked the PDF. Unverified or unknown attendance is excluded—not counted as absence. Opening attendance does not measure time spent in a meeting. The procedural toggle does not change attendance.

05

Coverage, errors & known gaps

Database counts checked Oct 5, 2026, 10:32 PM Eastern · all indexed dates, including procedural motions. Counts may be cached for up to one minute.

Documents indexed
132
Published motions
3,530
Motions held for review
70
Documents with review flags
106
Attendance records held
822
Documents without a linked video
4

47 documents have held motions; 99 have held attendance. These groups overlap. A flagged record is excluded from public statistics while it awaits review; the rest of its document may still be published. A flag is not a confirmed error, and passing a check is not proof of accuracy or human review.

Known documents not yet indexed

Our archive inventory checked Oct 4, 2026, 12:58 PM Eastern identified 132 PDFs from November 2021 onward, all attempted, plus one Word document. This is a dated inventory—not a guarantee that every meeting or later upload has been found.

0 unresolved PDF processing failures · 1 Word document awaiting processing. Entries below are removed when a matching source is indexed.

Known source-document gaps
Meeting dateFormatWhy it is missing
Apr 11, 2023DOCXWord document awaits separate processing; not indexed.

Why motions are held

Current automated review flags
ReasonMotions
Source excerpt not found on cited pages31
Joint-body motions and council-only roster require operator review12
Named evidence missing or mismatched8
Session type disagrees with inventory8
Procedural classification disagreement6
Individual position wording not recognized5
Meeting date disagrees with inventory3
Councilor identity requires review before publishing2
Candidate election needs a different ballot representation1
Unresolved explicit absence in motion1

One motion can have several reasons, so these counts do not add up to the number of held motions.

What these numbers cannot tell you

The total number of errors or omitted votes is unknown. We have not manually checked every motion against every page and recording. The model can miss a motion entirely, mix up names, or accept incorrect OCR text without raising a flag. Councilor identities are matched to the historical roster below, with known aliases consolidated. That does not certify every attribution; totals may change as records are reviewed.

3,171 published motions have no named individual Yes/No ballots in our index. That is missing attribution, not evidence that no vote occurred. We do not fill gaps by assigning an unnamed majority or a unanimous result to individual councilors. Missing minutes, held records, and missing video links can all limit coverage.

06

From minutes to searchable records

  1. Find and preserve the source. We collect official City Council minutes from the city website and archive the original PDF with its source URL and a file fingerprint. Attached agendas and supporting documents are not themselves proof that a vote occurred.
  2. Read each page. We first extract text already embedded in the PDF. If a page has very little embedded text (currently fewer than 50 characters after trimming leading and trailing whitespace), our reader renders it as an image and uses OCR (optical character recognition) to recognize the printed words. OCR can misread names, numbers, punctuation, and columns; an existing PDF text layer can also be faulty. We retain page numbers, but the current extraction flattens layout into text.
  3. Turn text into structured data. An AI model reads the page-numbered text and produces structured JSON: meeting details, motions, issues, recorded outcomes and tallies, procedural classifications, explicitly named individual positions, and opening attendance. Issue labels and classifications are generated interpretations; source excerpts are retained separately.
  4. Check and flag. Code checks page references, matching excerpts, supported position wording, and tally consistency where possible. A second AI pass looks for omissions and attribution problems. Both passes currently read the same extracted text—not an independent visual inspection—so they can share mistakes. Flagged records remain out of public results until resolved; some clear wording issues can be resolved by tested rules, while others require operator review.
  5. Store and report. Original files and extraction artifacts are stored in R2; structured records are indexed in D1 for search, filters, meeting tables, and councilor statistics. Page views query stored records, rather than rerunning OCR or AI. Corrections retain an audit history, and operational reports, warnings, and errors go to our existing Slack channel.
07

Historical councilor identities

The site’s historical roster was supplied and approved by the project operator on October 4, 2026. Titles, known name variants, and source-checked OCR misspellings resolve to one profile per person. Original excerpts remain unchanged. Unrecognized names and conflicting identities stop an import for review rather than creating another public profile.

These service ranges retain the year or month precision supplied to us; exact transition days are not verified. They are a consistency check—not proof of attendance or an individual vote. “Present” means as of the roster review date. Correcting an identity does not automatically publish its held records.

Service during the archive period
CouncilorServiceOther recorded names
Shawn E. Cadime2021–present—
Joseph D. Camara2022–present—
Michael G. Canuel2026–present—
Michelle M. Dionne2021–present—
Paul B. Hart2024–present—
Bradford L. Kilby2021–2025—
Pamela S. Laliberte2021–2023Pam Laliberte-Lebeau / Pamela S. Laliberte-Lebeau / Pamela Laliberte-Lebeau
Trott Lee2021–June 2022—
Christopher M. Peckham, Sr.2021; returned in 2026Christopher M. Peckham
Leo O. Pelletier2021–2023—
Linda M. Pereira2021–present—
Cliff A. Ponte2021; returned 2024–presentCliff Ponte
Andrew J. Raposo2022–present—
Laura-Jean WashingtonJune 2022–April 2025Laura-Jean Sampson
Ricky T. TithApril/May 2025–December 2025—
08

How statistics are calculated

Each percentage is its column count divided by that councilor’s indexed, published motions in the selected date range and procedural setting—not every vote during their term. Yes and No require an explicitly named individual position. Unanimous result means the motion was unanimous but no individual ballot was listed; it is not an inferred personal Yes. Named positions take precedence. Other / unlisted includes recorded absences, abstentions, recusals, and unassigned split votes. Columns do not overlap; rounding may keep percentages from totaling exactly 100%.

Substantive decisions are shown by default. Procedural votes handle meeting business such as taking items out of order, suspending rules, or adjourning. Classification can be disputed and is subject to review. Votes for competing candidates are not automatically treated as Yes/No ballots.

Attendance source documents (57)

These documents contain at least one usable opening-attendance record, not necessarily a fully verified roster. All dates are shown here, regardless of directory filters.

09

Verify a result or report a correction

Follow a vote’s page link to the cited page of the minutes. Read the surrounding motion, amendments, and recorded outcome—not just the overall tally. Follow the meeting link to watch the recording where available; a vote-specific timestamp may not be available.

If you find a discrepancy, use Report it on the meeting page where available, or email a correction. Include the meeting date, motion, PDF page, video timestamp if known, and what you believe should change. A missing individual vote should remain unassigned unless the source explicitly supports it.