Files
republic-os/docs/board.md
Fabio 246d014a4e Docs: sync pass — match the validator + current architecture
The docs drifted as the project moved fast. Fixed:
- Counts to the validator (canonical): 105,743 records, Jurisdiction 29,905
  (README had 105,746/29,908 — the exact-GEOID backfill dropped 3 city nodes
  and only the commit message was updated, not the docs).
- sources.md: officeholders-v2 → v3 (13,329); added the inputs that landed
  since — municipal GEOID backfill, place/district crosswalks, the complete
  U.S. Code corpus, the executive offices, and the authority edges.
- board.md: it described income/population/poverty only; now names the
  partisan-lean lens, zoom/pan, and the district+representative drill-down.
- data-model.md: stale '17,506 files' → 105,743.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 13:02:48 -04:00

61 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The Board
`viz/board.html` is the Board — a rebuilt *view* of the canonical tree, never a
source. It is a nationwide county choropleth with four lenses — **income,
population, poverty, and partisan lean** (the head-count D/R balance of each
county's covering state + federal representatives) — that is **zoomable and
pannable** (scroll to zoom 1×–16× toward the cursor, drag to pan, double-click to
reset). Any county opens a drill-down of its officeholders, its demographics, and
the **districts + representatives** that cover it (congressional, state senate,
and state house, each with the share of the county it covers).
## Pipeline
```text
data/officeholders-v3.jsonl ─┐
data/acs_county.jsonl ├─ scripts/build_viz.py ─> viz/board.html (inlined)
data/place_county_crosswalk ┤ └> viz/county_*.json (companions)
data/fec_candidates, acs_cd ─┘
```
`build_viz.py` resolves each official to a county with the **same**
`build.place_resolver` + `county_slug` the tree uses, so the Board and the tree
agree by construction. It then does two things:
1. Writes `viz/county_data.json` and `viz/county_detail.json` — human-readable,
diffable companions.
2. **Injects** the fresh data straight into `board.html`, rewriting three marked
lines: `const D` (per-county summary), `const CDETAIL` (per-county rosters),
and `const TOTALS` (the header counts).
## Why the data is inlined
The Board is deployed as a **self-contained Artifact**, and the Artifact CSP
blocks every external request — no `fetch`, no external scripts, styles, or
fonts. So the county data cannot be loaded at runtime; it must live inside
`board.html`. That is why `build_viz.py` writes into the file rather than letting
the page read the JSON companions (nothing reads them — they exist for diffs).
The header totals (officeholders, candidates, counties, districts) read from the
injected `const TOTALS` object — never hardcoded — so they cannot drift out of
sync on the next rebuild.
## Rebuild
```bash
make board # regenerate board.html + the JSON companions from the tree
```
`board.html` is deterministic: two runs are byte-identical.
## Redeploy the Artifact
Editing `board.html` in the repo does **not** update a live Artifact — the
deployed copy is a snapshot. After `make board`, the Board must be **republished**
to its existing Artifact URL for the change to appear on claude.ai.
Republishing to the *same* URL requires passing that URL back to the publish step
(`Artifact url=<existing-url>`); publishing without it mints a new URL. Keep the
current Board Artifact URL in the team's deployment record so redeploys stay in
place instead of scattering new links.