districtry / illinois

How this deployment grew

districtry Illinois began as a Chicago-only explorer and grew outward one county at a time — 91 of the state's 102 counties as of 26 August 2026. The counties that are missing are missing for reasons this project measured and wrote down, not for want of looking, and every one of them is on the record in the app's own data-gaps panel. This page is the deployment's record: what it ships, what it re-reads on a schedule, and the corrections its own machinery has caught.

The numbers below are measured from the app's own shipped data files every time anything changes — they cannot drift from what the map actually serves. The changelog entries are dated snapshots: each was true on its own date, and none is edited after the fact.

41
map layers
12 political · 7 public safety · 9 schools · 13 geography
85
scheduled refresh & audit jobs
each lands as a reviewed change, never silently
600
villages, towns and cities with their own officials named
each read from the county clerk's own published directory, refreshed weekly
598
municipalities whose mayor or village president is named
where a municipality publishes a board without naming who leads it, the card says so rather than guess
101
county clerks' offices, re-read weekly
name, address, phone and e-mail, from the State Board of Elections' own directory of election authorities
118
Illinois House seats with their member, party and both offices
the whole chamber, re-read from the General Assembly's own roster every Monday
59
Illinois Senate seats with their member, party and both offices
refreshed in the same Monday run as the House; a member who leaves is a change a person reviews, never one that ships on its own
101
recorded data gaps
what the publishers withhold, on the record in the app

The changelog

Checked on a schedule

Every scheduled job lands its changes as a reviewed pull request — data about real officeholders never ships without a person looking at the diff.

What it refreshesJobWhen
IL Senate + House rosters (ilga.gov scrape)update-ilga-roster.ymlMon 13:00 UTC
U.S. House roster (unitedstates/congress-legislators)update-congress-roster.ymlMon 13:00 UTC
CPD district info (Cloudflare-challenged scrape via Playwright)update-cpd-roster.ymlTue 13:00 UTC
CCPSA district council rostersupdate-ccpsa-roster.ymlWed 13:00 UTC
Will County Board roster (willcountyboard.com scrape)update-will-county-board-roster.ymlThu 13:00 UTC
Kendall County Board roster (kendallcountyil.gov scrape, Playwright fallback for the Akamai front)update-kendall-county-board-roster.ymlThu 14:00 UTC
McHenry County Board roster (mchenrycountyil.gov scrape, Playwright fallback)update-mchenry-county-board-roster.ymlThu 15:00 UTC
Kane County Board roster (the county's SharePoint list API)update-kane-county-board-roster.ymlThu 16:00 UTC
Lake County Board leadership tags (directory scrape, Internet Archive fallback)update-lake-county-board-roles.ymlThu 17:00 UTC
Board of Review commissioner roster (cookcountyboardofreview.com scrape)update-ccbr-roster.ymlFri 13:00 UTC
Illinois county clerk roster (ISBE election-authority directory scrape)update-county-clerk-roster.ymlSat 13:00 UTC
DuPage County Board roster (dupagecounty.gov directory scrape)update-dupage-county-board-roster.ymlSun 13:00 UTC
Winnebago County Board contact (wincoil.gov board page; base64 e-mails, name-matched to the county GIS)update-winnebago-county-board-roster.ymlWed 15:00 UTC
Sangamon County Board roster (29 per-district member pages on sangamonil.gov)update-sangamon-county-board-roster.ymlTue 15:00 UTC
Livingston County Board roster (livingstoncountyil.gov directory scrape)update-livingston-county-board-roster.ymlTue 14:00 UTC
Municipal governing bodies (Cook Clerk DOEO API, Will Clerk directory, DMMC directory, Kane/McHenry/Kendall/Ogle/Carroll clerk yearbooks, Stephenson county villages page, Lake county GIS contact, LaSalle clerk PDF, Winnebago WinGIS officeholder layers, Freeport city site)update-municipal-officials.ymlWed 14:00 UTC
DeKalb County Board roster (dekalbcounty.org members page; Sucuri-fronted, the scraper retries past the captcha stub)update-dekalb-county-board-roster.ymlFri 14:00 UTC
Ogle County Board roster (oglecountyil.gov staff directory)update-ogle-county-board-roster.ymlSat 14:00 UTC
Stephenson County Board roster (stephensoncountyil.gov board page)update-stephenson-county-board-roster.ymlSun 14:00 UTC
Carroll County Board roster (carrollcountyil.gov board directory)update-carroll-county-board-roster.ymlMon 14:00 UTC
Lee County Board roster (leecountyil.com Member Contact List PDF)update-lee-county-board-roster.ymlTue 16:00 UTC
Rock Island County Board roster (rockislandcountyil.gov board page)update-rock-island-county-board-roster.ymlWed 16:00 UTC
source freshness + redistricting watch (opens/updates one tracking issue)validate-sources.yml1st of month 14:00 UTC
LaSalle County Board roster (county directory scrape)update-lasalle-county-board-roster.ymlSun 15:00 UTC
Henry County precinct polling places (Clerk's own directory)update-henry-precinct-polling.ymlFri 18:00 UTC
Woodford County Board roster (woodford-county.org directory scrape)update-woodford-county-board-roster.ymlMon 16:00 UTC
Logan County Board roster (logancountyil.gov board-page scrape)update-logan-county-board-roster.ymlMon 17:00 UTC
Boone County Board roster (boonecountyil.gov board-page scrape)update-boone-county-board-roster.ymlTue 17:00 UTC
Grundy County Board roster (grundycountyil.gov board-page scrape)update-grundy-county-board-roster.ymlWed 17:00 UTC
Jefferson County Board roster (jeffersoncounty.illinois.gov board-table scrape)update-jefferson-county-board-roster.ymlThu 19:00 UTC
Macon County Board roster (maconcounty.illinois.gov board-members scrape)update-macon-county-board-roster.ymlFri 17:00 UTC
Menard County commissioners roster (menardcountyil.gov board-table scrape)update-menard-commissioners-roster.ymlThu 20:00 UTC
Montgomery County Board roster (montgomerycountyil.gov board-page scrape)update-montgomery-county-board-roster.ymlWed 18:00 UTC
Henry County Board roster (henrycty.com district-keyed directory scrape)update-henry-county-board-roster.ymlThu 18:00 UTC
Peoria County Board roster (GIS roster spine + per-member page contact scrape)update-peoria-county-board-roster.ymlFri 15:00 UTC
Tazewell County Board roster (tazewell-il.gov member-page scrape)update-tazewell-county-board-roster.ymlFri 16:00 UTC
Iroquois County Board roster (county board-page table scrape)update-iroquois-county-board-roster.ymlSat 15:00 UTC
At-large county boards (Monroe, Randolph) rendered on the County cardupdate-county-commissioners-roster.ymlSat 16:00 UTC
De Witt County Board roster + district-composition drift checkupdate-dewitt-county-board-roster.ymlSun 15:00 UTC
Washington County Board roster + township-composition drift checkupdate-washington-county-board-roster.ymlSun 16:00 UTC
Cass County Board roster + seat-count tripwire on the derived boundaryupdate-cass-county-board-roster.ymlSun 17:00 UTC
Marshall County Board roster + township-composition drift checkupdate-marshall-county-board-roster.ymlMon 18:00 UTC
McDonough County Board roster + derived-boundary drift check (mcg.mcdonough.il.us, HTTP-only)update-mcdonough-county-board-roster.ymlMon 19:00 UTC
Fulton County Board roster (fultoncountyil.gov Members page — a district-grouped grid joined by name to hidden per-member popups for the e-mails)update-fulton-county-board-roster.ymlTue 20:00 UTC
Stark County Board roster (starkco.illinois.gov) + drift check on the five boundaries built from the Clerk's archived Google My Maps exportupdate-stark-county-board-roster.ymlTue 19:00 UTC
Mason County Board roster SOURCE watch (scan — transcribed by hand, never scraped)watch-mason-roster-source.ymlTue 18:00 UTC
Shelby County Board roster (shelbycounty-il.gov coboard.aspx scrape, cross-checked against contacts.aspx) + drift check on the composition the derived boundary is dissolved fromupdate-shelby-county-board-roster.ymlWed 19:00 UTC
White County Board roster + precinct polling (whitecounty-il.gov board + elections pages; district join from the certified-canvass table, any unplaceable name fails) + watch on the Elections page's adopted-map linkupdate-white-county-board-roster.ymlSat 17:00 UTC
Jo Daviess County Board roster (jodaviesscountyil.gov board page + 16 member directory pages, paced; seats counted named+vacant = 17, districts 1..17 asserted against the purchased boundary's constant, home addresses never parsed)update-jodaviess-county-board-roster.ymlSat 18:00 UTC
Coles County Board roster (colesco.illinois.gov board page + committees page cross-check; the fetch supplies the intermediate certificate the county's server omits, pinned by hash. Exists because the county's own board-district GIS layer carries a 2022 member column that gets six of twelve names wrong — the app takes geometry from the service and people from here)update-coles-county-board-roster.ymlSun 18:00 UTC
Clark County Board roster (the Clerk's own certified canvasses at il-clark.accessliberty.com — the county's only board document is a scan, so the roster is the election returns; the run also re-checks each district's tabulated precinct list against the shipped dissolve, which is the re-precincting/redistricting tripwire)update-clark-county-board-roster.ymlMon 20:00 UTC
Crawford County Board roster (the county's own board page) + the redistricting tripwire: the same run re-reads the district composition from the Clerk's results feed at il-crawford.pollresults.net and fails if it stops matching the shipped dissolveupdate-crawford-county-board-roster.ymlTue 21:00 UTC
Mercer County Board roster (the county's own board table — party, term, home town, chairman) + the redistricting tripwire: the same run re-reads the district composition from the Clerk's results feed at il-mercer.pollresults.net and fails if it stops matching the shipped dissolveupdate-mercer-county-board-roster.ymlWed 20:00 UTC
Edgar County Board roster (edgarcountyillinois.COM board page — the .gov does not carry it) + the redistricting tripwire: the same run re-reads the district composition from the Clerk's results feed at il-edgar.pollresults.net and fails if it stops matching the shipped dissolveupdate-edgar-county-board-roster.ymlThu 21:00 UTC
Franklin County Board roster (the county's own members page, read as a GRID by cell coordinate — a flattened text read pairs every role with the wrong member, and its Address column is every member's home) + the redistricting tripwire: the same run re-checks the county's live precinct count and each numbered board contest's precinct count against the shipped dissolve, and fails if either movesupdate-franklin-county-board-roster.ymlFri 19:00 UTC
Clinton County Board roster (the county's own board page — 15 members with phone, e-mail and term year, Chairman and Vice Chairman badged by name match) + the redistricting tripwire: the same run re-checks the county's live precinct count and each numbered board contest's precinct count against the shipped dissolveupdate-clinton-county-board-roster.ymlSat 19:00 UTC
Adams County Board roster (certified canvasses on platinumelectionresults.com; also the backfill tripwire for the unread November 2022 canvass)update-adams-county-board-roster.ymlSat 20:00 UTC
Macoupin County Board roster (the County Clerk's elected-officials directory, read from the service its page fills itself from) + a redraw tripwire re-reading the county's own district layer by key and areaupdate-macoupin-county-board-roster.ymlThu 10:00 UTC
Knox County Board roster (roll call of the county's own board minutes on its Revize CMS; its member page is a 403)update-knox-county-board-roster.ymlSun 20:00 UTC
Warren County Board roster (the county's own board page — 15 members with committees, term year, phone and e-mail, Chairman of the Board badged; home addresses seen and dropped) + the strongest drift check in the fleet: the same run re-reads the precinct-map legend the shipped boundary was dissolved fromupdate-warren-county-board-roster.ymlSun 19:00 UTC
Daily watchdog over every roster refresh: reports the ones that are FAILING or have gone longer than their own cadence without a successful run, on one standing issue. Exists because a builder that refuses the write opens no PR and files nothing — the shipped roster silently freezes at its last good runroster-health.ymldaily 23:00 UTC
Hancock County Board roster (county board page scrape)update-hancock-county-board-roster.ymlFri 20:00 UTC
Richland County Board roster (the county's own board page) + the redistricting tripwire: the same run re-reads the board-district and voting-precinct layers from the county's own GIS at richlandil.wthgis.com and fails if either stops matching the shipped dissolveupdate-richland-county-board-roster.ymlMon 21:00 UTC
Jackson County Board roster (the county's own board page, grouped by district heading, plus each member's staff-directory entry for the e-mail); the builder fails if the page's grouping and the directory disagree about a member's districtupdate-jackson-county-board-roster.ymlTue 22:00 UTC
Douglas County Board roster, assembled from the county's annual Yearbook (people and e-mail) and its certified election summary reports (district numbers), joined on surname; the builder fails if the two county documents stop naming the same seven peopleupdate-douglas-county-board-roster.ymlWed 21:00 UTC
Vermilion County Board roster (27 members across 9 districts) from the county's own members page, fetched with the intermediate certificate its server omits supplied by AIA and pinned by hashupdate-vermilion-county-board-roster.ymlThu 22:00 UTC
Wayne County Board roster (14 members across 7 districts) from the county's own board page + the redistricting tripwire: the same run re-reads the per-district precinct list from that page and fails if it stops matching the shipped dissolve (District 7 checked as the known page/canvass subset, since the page never names Fairfield 1 or Fairfield 2)update-wayne-county-board-roster.ymlFri 21:00 UTC
Clay County Board roster (14 members across 14 lettered districts, 14/14 with a phone) from the county's own members page + the redistricting tripwire: the same run re-reads the county-board page's Districts section letter by letter and fails if it stops matching the shipped composition (the village-limits line splitting Clay City between districts A and B came from the Clerk's e-mail, and no page re-read can trip a line the page never draws)update-clay-county-board-roster.ymlSat 21:00 UTC
Boone County's five park and library districts' office and board. The County Clerk's Year Book supplies the office — address, telephone, fax, website and agency head — for all five; every BOARD comes from that body's own published page, because the booklet is an annual snapshot and is short of what two of the five bodies publish (it names four Belvidere Park District commissioners where the district's own page names all five; Ida Public Library's own page lists eight trustees and the word 'Open', which the booklet cannot show). Where both name the same person the booklet's term-expiry year rides along. The builder refuses to write unless the roster's keys are exactly the districts the two boundary files drawupdate-boone-district-officials.ymlWed 22:00 UTC
Peoria County's fire, park and library districts' officers, office and contact details, read from each district's OWN Annual Financial Report filing with the Illinois Comptroller — the county publishes a district name and a website and no officer at all. The filed TITLE decides which list a person joins, because the Chief Executive Officer slot is not reliably an elected officer, and every record carries the fiscal year it was filed for since an AFR is a one-year snapshot. Paced at one request a second against a state site, two pages per district: the landing page for the year that district last filed, then that year's contact block. The builder's floors sit under the measured 18 of 25 districts, so one district going quiet cannot freeze the restupdate-peoria-district-officials.ymlSun 21:00 UTC
Logan County's seven park districts' officers, office and contact details, read from each district's OWN Annual Financial Report filing with the Illinois Comptroller — the Tri-County Regional Planning Commission draws the boundary and carries a name and nothing else, and neither the commission nor the county publishes a trustee. The same route Peoria's job uses, scheduled an hour later so the two are not competing for the same paced state site. ALL SEVEN FILE, two of them under another county because a cross-county district files once (Armington Community in Tazewell, San Jose in Mason), so the join is an explicit table of unit codes rather than a name match — a Warehouse search is a substring match and 'Armington' also returns seven FARMINGTON units. Every row is verified against the Warehouse's own label and county before it is read. The builder's floors sit under the measured seven, so one district going quiet cannot freeze the restupdate-logan-district-officials.ymlSun 22:00 UTC
Woodford County's 25 filing fire, park and library districts' officers, office and contact details, read from each district's OWN Annual Financial Report filing with the Illinois Comptroller — the boundaries are dissolved from the county's parcel fabric and carry a district name and a tax code and nothing else, and the county publishes no officer. The same route Peoria's and Logan's jobs use, scheduled clear of both (Peoria Sun 21:00, Logan Sun 22:00) so the three are not competing for the same paced state site, and after Woodford's own county-board roster at Mon 16:00. EIGHT OF THE 25 FILE UNDER ANOTHER COUNTY because a cross-county district files once — six fire and two library districts serving slivers of Woodford from McLean, Tazewell and LaSalle — so the join is an explicit table of unit codes rather than a name match, verified against the Warehouse's own label, type and county on every run, four requests covering all 25. The 26th, Minonk City Library, is a municipal library filing inside the City of Minonk and has no unit of its own. The builder's floors sit under the measured 25, so one district going quiet cannot freeze the restupdate-woodford-district-officials.ymlMon 22:00 UTC
Grundy County's 20 filing fire, park and library districts' officers, office and contact details, read from each district's OWN Annual Financial Report filing with the Illinois Comptroller — the boundaries are dissolved from the county's parcel fabric and carry a district name and a tax code and nothing else. The county's own Appointed Local Public Entity Report names nine of these bodies and no individual at all, which is why a second publisher was needed. The same route Peoria's, Logan's and Woodford's jobs use, scheduled clear of all three (Peoria Sun 21:00, Logan Sun 22:00, Woodford Mon 22:00) so the four are not competing for the same paced state site, and clear of Grundy's own county-board roster at Wed 17:00. TEN OF THE 21 FILE UNDER ANOTHER COUNTY because a cross-county district files once — five fire, four library and one park district filing from LaSalle, Will and Livingston — so the join is an explicit table of unit codes rather than a name match, verified against the Warehouse's own label, type and county on every run, four requests covering all 21. The 21st, Mazon Fire, has a unit and no readable report this year and ships the run one appears. The builder's floors sit under the measured 20, so one district going quiet cannot freeze the restupdate-grundy-district-officials.ymlFri 22:00 UTC
Kankakee County's 25 filing fire, park and library districts' officers, office and contact details, read from each district's OWN Annual Financial Report filing with the Illinois Comptroller — the county's taxing-district service declares telephone, website and email on every row and populates none of them (0 of 17 fire, 0 of 4 park, 0 of 8 library). The same route Peoria's, Logan's, Woodford's and Grundy's jobs use, scheduled clear of all four (Peoria Sun 21:00, Logan Sun 22:00, Woodford Mon 22:00, Grundy Fri 22:00) so the five are not competing for the same paced state site. IT ALSO READS THE COUNTY'S LIVE SERVICE, because Kankakee's boundaries are fetched at render time rather than committed, so the join key has to come from the same layer the app will read; a name in one and not the other fails the run. Three of the 27 units file under Livingston, Will or Iroquois because a cross-county district files once. The builder's floors sit under the measured 25, so one district going quiet cannot freeze the restupdate-kankakee-district-officials.ymlSat 22:00 UTC
The officers, office and contact details of the 197 district-governed Illinois public libraries that file, read from each library's own Annual Financial Report filing with the Illinois Comptroller. The statewide layer's boundary comes from the Illinois Broadband Office and carries a library's name, how it is governed and no contact of any kind, so all 550 cards named a library and nobody. One job for 72 counties, because the layer clips each library's service area to the county: a district spanning counties draws a card in every county it touches while filing once, so the index is statewide and 198 filings stamp 340 cards. The same route Peoria's, Logan's, Woodford's, Grundy's and Kankakee's jobs use, scheduled clear of all five (Peoria Sun 21:00, Logan Sun 22:00, Woodford Mon 22:00, Grundy Fri 22:00, Kankakee Sat 22:00) so the six are not competing for the same paced state site. It is the longest of the six by an order of magnitude — roughly 480 paced requests, because it indexes all 102 counties and then reads two pages per library — so it takes the one hour band no other weekly job occupies. A partial index is the failure it must never ship: a county missing from it unresolves every library filed there, which reads on the card exactly like a library that files nothing, so each county is retried and the run is abandoned rather than completed short. The builder's floors sit under the measured 197, and it re-measures the card count against the shipped boundary files rather than trusting the scraper, because a library renamed in the boundary layer costs its cards and no key at allupdate-il-library-district-officials.ymlSun 12:00 UTC
The office address, telephone, website and administrator of 365 Illinois public libraries, read from L2, the directory Chicago Public Library, RAILS and Illinois Heartland run together. It is the second publisher for the statewide library layer: the Comptroller filings name the boards of the 197 libraries that file, and this names where the other 173 are, fills the address or telephone the filings leave out, names one administrator per library and links each library's own site. It answers no trustee — the directory's staff lists and its annual certifications are both behind a sign-in, which is not worked around. Roughly 410 paced requests: two to TIGERweb for the Illinois place list that splits the address cell, 41 pages of the rendered directory listing, then one page per matched library, because the listing table carries neither the website nor the administrator. It reads the RENDERED page, because librarylearning.org's robots.txt closes the REST endpoint a Drupal directory of this shape usually serves the same rows from (Disallow: /restapi/*). Scheduled Monday 11:00 UTC, after Sunday 12:00's library-officials run, because this scraper reads that job's output to decide which fields the filings already answer. The builder's five floors each sit about 14% under their measured value (365 libraries, 244 addresses, 223 telephones, 335 websites, 286 administrators), so one library renamed in either publisher cannot freeze the restupdate-il-library-contacts.ymlMon 11:00 UTC
The officers, office and contact details of the fire and park districts of twenty counties, read from each district's own Annual Financial Report filing with the Illinois Comptroller. The app draws fire protection districts in 26 counties and park districts in 18; Peoria, Logan, Woodford, Grundy and Kankakee already name their officers through their own AFR jobs and Boone's park districts come from the county's directory, and everywhere else the card gave a name, a county and nobody. This job covers 29 county/layer pairs: ten whose boundaries ship as GeoJSON here, and nineteen it reads from the county's own ArcGIS service at scrape time because that is where il/index.html reads them at render time; a name in one and not the other fails the run. Roughly 900 paced requests: nineteen service queries for the card names, a Warehouse search per county to verify every unit code in the table still names the district it claims, then two pages per unit. The same route and pacing as the six other AFR jobs and scheduled clear of all of them (library Sun 12:00, Peoria Sun 21:00, Logan Sun 22:00, Woodford Mon 22:00, Grundy Fri 22:00, Kankakee Sat 22:00). The builder's floors sit under the measured 485 cards, and it re-measures every key against the card names the scraper recorded rather than going back to the county services, because its --check runs in CI where an unrelated county outage must not fail the buildupdate-il-special-district-officials.ymlMon 12:00 UTC
Cook County's 17 commissioners and its Board President, from the county's own GIS people table — the same rows il/index.html already renders on the Cook board card. THE APP DOES NOT READ WHAT THIS WRITES: the card fetches that table live on every Cook click, so the roster lands in il/data/source rather than data/app, where validate_index.py would rightly refuse a file index.html does not reference. What it is for is il/county-board/cook.html, which returned 404 until 2026-09-15 — the second most populous county in the United States, with the Illinois hub's own prose naming it — because build_county_pages.py enumerates whatever the roster FILES carry and Cook had none. TWO OTHER SOURCES WERE MEASURED AND REJECTED: the county website publishes no machine-readable members list (its /board-of-commissioners page is a hub of meetings, /service/board-commissioners 404s), and the open-data portal's "Cook County Commissioner Information" seats a member who died in 2018 and gives "next_election: 2018". The GIS table is maintained — District 8's row names the 2025 appointee and was edited four days later — but ONE COLUMN IN IT IS NOT: lastElectedDate says 2018-11-06 for twelve of the seventeen, all of whom were on the 2022 ballot, so no term or election date is carried at all. The per-member office is the SECOND address, because the first is the board's own County Building suite repeated on fourteen rows. One request. The builder gates on exactly 17 districts, a named member in each, a Board President, and floors of 12 e-mails, 12 phones and 9 district offices under a measured 14/15/12update-cook-county-board-roster.ymlWed 23:00 UTC
Chicago's 50 alderpeople, from the City's own Socrata dataset htai-wnw4, with each ward office's address, phone and e-mail. THE APP DOES NOT READ WHAT THIS WRITES: il/index.html calls that dataset live on first toggle of the ward layer, so the card is never a week behind the City. This job exists so the 50 names appear in the served bytes of il/ward.html — measured 2026-09-15, not one of them appeared in any page a crawler, an AI client or a reader with JavaScript off could read, which is the absence build_county_pages.py closed for 2,650 county seats and left open for the city. The roster therefore lands in il/data/source rather than data/app, where validate_index.py would rightly refuse a file the app never fetches, and the job regenerates the page in the same run because build_officeholder_tables.py --check fails a workflow that does not. One request, after robots.txt and the host's stated 1s crawl delay. The builder gates on EXACTLY 50 wards rather than a floor — Chicago elects one alderperson per ward and that number cannot move — with field floors of 45 e-mails, 45 phones and 45 offices under a measured 50 of eachupdate-chicago-ward-roster.ymlTue 23:00 UTC
The Supreme and Appellate Court justices of each of the five Illinois judicial districts, read from illinoiscourts.gov — the seven Supreme Court justices with the district each was elected from and the Chief Justice badged, then each district's appellate branch: its sitting justices each linked to their own page, the courthouse address, the telephone and the Clerk of the court. ONE JOB ANSWERS FOR BOTH COURTS because one set of districts serves both: Const. art. VI, sec. 2 divides the State into five Judicial Districts "for the selection of Supreme and Appellate Court Judges", 705 ILCS 25/1(a) puts a branch of the appellate court in each of them "as such districts are determined by law" and defines none of its own, and 705 ILCS 23 (which IS PA 102-0011, the act the shipped shapefile comes from) determines them county by county. Three paced page reads plus one form postback — the directory is ASP.NET WebForms, so its full roster needs a POST carrying __VIEWSTATE rather than a query string. IT IS ALSO THE REDISTRICTING TRIPWIRE for a layer nobody watches: the builder carries 705 ILCS 23's county lists and refuses to write unless the counties the court's own district pages name are exactly those 102, in those districts, so a redraw or a page rewrite fails the run instead of quietly moving a cardupdate-il-court-justices.ymlWed 12:00 UTC
The SERVICE PROVIDER AGENCY of Chicago's Special Service Areas — the non-profit the city contracts with to run each corridor, with its office address, telephone and site. An SSA elects nobody, so this is the only people source the card has, and the city's boundary dataset carries none of it. The source is ONE HAND-MAINTAINED HTML PAGE reached through Business Assistance rather than the department's landing page, which is why this runs weekly and why the scraper enumerates its traps instead of trusting its shape — above all a PHANTOM BLOCK, where an expired area's notice bolds its replacement's name and a bold-keyed parser invents an empty provider for a live area. Two paced requests. All 58 areas have a provider; every area's Mayor-appointed commission stays recorded in gap chicago-ssa-service-providersupdate-chicago-ssa-providers.ymlTue 11:00 UTC
The Chicago Board of Education's twenty sub-district members and its city-wide President, from the Board's own member index at cpsboe.org. THE FILE IT REBUILDS WAS HAND-CURATED AND HAD DRIFTED: on 2026-09-23 District 9a shipped the bare string VACANT where the Board names its Vice President, and District 10b named a member the Board's own news says resigned in March 2026 — while the card's provenance note claimed no machine-readable roster is published for this board. Twenty-two paced requests: the index, then each member's own bio page, which is the second witness the builder requires to agree on name, office and district before it writes, and which carries the cps.edu address. The join onto the map is read off the shipped geometry's own sub-district labels, so a re-districting fails the run rather than filing a member under a neighbour's districtupdate-chicago-school-board-roster.ymlThu 11:00 UTC
A board of trustees read off each library's OWN website, for the statewide library layer's cards no Annual Financial Report answers for. Only a district-governed library files an AFR, so Sunday 12:00's job reaches the districts and nobody else — a municipal library is covered by its city's or village's report and a township library files as or within a township, whose board is not the library's board — and L2's staff lists and annual certifications are both behind a sign-in that is not worked around. The library itself is the only publisher left. THE POOL IS DERIVED on every run from the shipped boundary files, the filings roster and the directory: every card that names no board and links a site, so a library that starts filing leaves the pool by itself. robots.txt is read through scripts/robots_policy.py as the client that fetches, before each host's first request, with a stated Crawl-delay honoured per host; a refusal is recorded as a refusal and nothing is fetched from that host. Three hops at most per library — the home page, a link on it naming a board, and only where the home page names none at most two same-origin About pages, because a home page with no board link is not a library that publishes no board — around 300 paced requests across 170-odd hosts. NOTHING IS GUESSED: a library ships only where its page yields a board between three and twelve names and the page's own words say the board is that library's, and five hosts carry more than one library, one of them contracting its service to a neighbour. The parser's --selftest runs offline before a single host is asked for a page, and in CI. Monday 10:00 UTC, three hours ahead of the roster wave and clear of the two other library jobsupdate-il-library-trustees.ymlMon 10:00 UTC
Where each layer's shapes come from, fleet-wide (browser probe -> layer-sources.json + the endpoint inventory's table); PR only when a result changesupdate-layer-sources.ymlSun 09:17 UTC
Re-mirror the Census TIGERweb layers the apps draw from vector tiles, fleet-wide (scripts/mirror_tiger_tiles.py -> the archives + tiger-mirror.json); rebuilds and gates only a layer whose fetched set changed, moves the cache name of each app whose archive it replaced, and opens a PR only thenupdate-tiger-tiles.ymlSun 10:41 UTC

Back to the map Sources & data layers Common questions Privacy Why this exists