How this is put together
Every number on these pages should be reproducible by someone who distrusts them. This page exists so that is possible.
Where the records come from
Agendas, resolutions and roll calls are fetched from the Granicus Legistar Web API, which is the same system the city clerk uses. Nothing is transcribed by hand. Each response is hashed when it is retrieved and the source URL is printed beside the claim it supports.
Roll calls come from the eventitems route rather than the matter history, because the documented history route returns empty vote arrays. A tally is rejected outright if it comes back empty or carries more votes than the body has seats — a silently truncated roll call would render as a confident wrong number, and a wrong vote count is both highly quotable and trivially disproved by anyone who was in the room.
How terms are counted
Counts use whole-word matching, never substrings, and every term requested is reported — including the ones that matched nothing. A zero is a finding. Omitting an empty row would quietly turn an absence into silence.
This rule has a specific origin. An earlier analysis of a Saint Paul comment packet reported “ICE mentioned 90 times”. The count had matched the letters ice inside police, service, notice and practice. The whole-word count was 4. Acronyms are matched case-sensitively for the same reason — word boundaries alone still find ice water.
| term | pattern | matching |
|---|---|---|
| Flock | \bFlock\b | case-insensitive |
| Skydio | \bSkydio\b | case-insensitive |
| surveillance | \bsurveillance\b | case-insensitive |
| ALPR | \bALPR\b | case-sensitive |
| ICE | \bICE\b | case-sensitive |
| privacy | \bprivacy\b | case-insensitive |
| Israel | \bIsrael\b | case-insensitive |
| Gaza | \bGaza\b | case-insensitive |
| BDS | \bBDS\b | case-sensitive |
| Palestinian | \bPalestinian\b | case-insensitive |
Counts are always published with a denominator — “103 mentions” means nothing without “across 40 comment units”. The code will not produce a report without one.
Who gets named
Elected officials are named, and only from vote and sponsorship records — people acting in office, on the record.
Residents who speak at public meetings are not named, not indexed, and not tracked between cities. Their arguments are counted and quoted where newsworthy. In Minnesota this material is legally public, so this is an editorial choice rather than a legal requirement — which is the stronger reason for it. Nothing in this reporting needs a database of private residents, and building one would be the fastest way to make the work about the wrong thing.
Contact details are stripped when a document is first read, before anything is stored: email addresses, phone numbers, street addresses and ZIP codes. What was removed is counted and the count is published with the document. Resolution numbers, dollar amounts, dates, vote tallies and the names of officials and organisations are deliberately left intact.
Known limits
- Dates inside attachment filenames were assigned by city staff. They are not verified adoption dates and should not be read as a timeline.
- A term count measures one document. The written comment packet and the spoken hearing are different corpora and can legitimately disagree — a word absent from one may be said aloud in the other.
- Two cities is an anecdote, not a pattern. Claims about how coverage behaves need many more jurisdictions before they are worth stating.
- Legistar status fields are unreliable in isolation: a passed measure can carry the status "Archived". Actions and roll calls are authoritative; status is not.
- Minneapolis records are not available through the API — its tenancy returns bodies but no matters and no events — so anything about Minneapolis here comes from other outlets' reporting and is labelled that way.
Corrections
If something here is wrong, it gets fixed and the change is recorded rather than quietly edited away. Corrections are dated, the original wording is kept, and the record says what changed.
Report an error at the contact form. Please include the page and the specific sentence. Flagged claims are checked before they are defended.