3 Commits

Author SHA1 Message Date
Fabio 1beeaab2db Graph: national county↔district↔legislator authority layer
The first edges in the repo. Every US county now links to the districts it
sits in, weighted by area overlap, and every legislator links to the district
they represent — county → district → representative, traversable.

Data (PostGIS, no Atlas dependency — computed directly from geometry):
- data/county_district_edges.jsonl — 16,328 weighted edges. area_weight =
  ST_Area(ST_Intersection(county, district))/ST_Area(county) over ST_MakeValid
  Census TIGER 2024 geometries, overlaps <0.5% dropped. Uses area-intersection,
  NOT centroid-in-polygon, so urban districts that carve through counties
  (e.g. GA CD-5 / Atlanta across Clayton+DeKalb+Fulton) are captured, not
  silently dropped. Per-county weights sum to ~1.0 per district type.

build.py:
- ~6,896 new district nodes: 435 CD (ACS demographics where available; sparse
  for the 8 states missing from acs_cd) + 4,927 state-house + 1,897 state-senate
  (geometry-only). GEOID/number-keyed, stable.
- county index.md gains a `districts:` block (frontmatter) + a ## Districts
  section (body links, so link-integrity checks them).
- legislators + US House members gain `represents:` pointing at their district
  node; edge stored once on the person, inverse left to the view.
- schemas/jurisdiction: classification enum + chamber/districts fields.

Honest gaps (logged, not hidden): ID + NH have no state-house geometry, so
their house districts get nodes (represents resolves) but no county edges;
CD nodes for acs_cd-missing states are demographically sparse.

Deterministic (byte-identical rebuild); validate.py passes 26,617 records,
link-integrity clean (every district/represents link resolves).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 22:28:08 -04:00
Fabio 7a2cc64362 Sync: officeholders v3 — fresh export from live Atlas DB (13,329 tenures)
Re-exported directly from Postgres (10.0.0.116), not Atlas's introspection,
which under-reported the roster (its v3 export had 11,473, missing the
restored Florida League of Cities municipal set). Live DB current tenures:
state 7,561 · municipal 4,009 · county 1,217 · federal 542.

- build.py now reads officeholders-v3.jsonl (was v2); dataset vintage 2026-07-04
- fixed one corrupt start_date at source-export (21021-12-03 -> 2021-12-03,
  Lorraine Borowski, Mayor of Decorah IA)
- scripts/build_viz.py: committed, deterministic generator for the Board's
  county_data.json / county_detail.json (previously built ad-hoc)
- generate_changelog.py: ignore files whose only change is the vintage stamp,
  so the diff reflects government change, not re-export bookkeeping

Person files 11,285 -> 13,329. Non-FL municipal officials (1,903) are in the
tree but not yet county-mappable (place->county crosswalk still NULL).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 18:56:37 -04:00
Fabio 1545fcf5ca Raw JSONL to structured tree: 11,285 entity files
One record, one file. The jurisdiction tree is now real:

  us/people/                          542 federal
  us/states/<xx>/people/            7,561 state
  us/states/fl/counties/<c>/people/ 1,058 county
  .../municipalities/<m>/people/    2,124 municipal (67 FL counties)

Each file is OKF markdown + YAML frontmatter: fixed key order,
field-level source provenance, Atlas UUIDs for round-tripping,
deterministic paths and slugs. Converter passes the determinism
test: two runs, byte-identical tree.

Generated by scripts/convert_officeholders.py from
data/officeholders-v2.jsonl (unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 18:08:31 -04:00