From 6c9990a1152639dcfc00a838deca4037e10a0c3f Mon Sep 17 00:00:00 2001 From: Fabio Date: Sat, 4 Jul 2026 21:12:05 -0400 Subject: [PATCH] Docs: document the Board pipeline + Artifact redeploy step Add `make board` and docs/board.md so the Board's rebuild-and-redeploy flow is a documented step, not tribal knowledge. Covers why the county data is inlined (self-contained Artifact / CSP), that build_viz.py injects it into board.html, and that a live Artifact must be REPUBLISHED (editing the repo file doesn't update a deployed Artifact). README links it in both the make list and the docs index. Co-Authored-By: Claude Opus 4.8 --- Makefile | 9 ++++++++- README.md | 2 ++ docs/board.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 docs/board.md diff --git a/Makefile b/Makefile index 52baa102fe..66a43b39ad 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Republic OS — repeatable pipeline commands. # The build is deterministic: `make build` twice yields a byte-identical tree. -.PHONY: build validate legal-us-code check +.PHONY: build validate board legal-us-code check build: ## Regenerate the entity tree from raw exports in data/ python3 scripts/build.py @@ -9,6 +9,13 @@ build: ## Regenerate the entity tree from raw exports in data/ validate: ## Check every entity file: OKF, schema, and link integrity python3 scripts/validate.py +board: ## Rebuild the Board (inlines fresh data into viz/board.html) + python3 scripts/build_viz.py + @echo + @echo "board.html regenerated. To update the LIVE Artifact you must REPUBLISH" + @echo "viz/board.html to its existing URL — editing the repo file does not" + @echo "update a deployed Artifact. See docs/board.md." + changelog: ## What changed in the government since the last commit (BASE/HEAD overridable) python3 scripts/generate_changelog.py $(BASE) $(HEAD) diff --git a/README.md b/README.md index 1257a97ce1..2ef0dfec82 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ make build # regenerate the entity tree from the raw exports make legal-us-code # regenerate the U.S. Code Title 52 legal corpus seed make validate # OKF + schema + link-integrity checks on all records make changelog # what changed in the government since the last commit +make board # rebuild the Board's inlined data from the tree make check # build, then validate — the full gate ``` @@ -52,6 +53,7 @@ Everything runs on the Python standard library. No dependencies to install. - [Data Model](docs/data-model.md) — entity types, IDs, the file format, the jurisdiction tree - [Sources](docs/sources.md) — where every fact comes from, and how current it is - [Legal Corpus](docs/legal-corpus.md) — deterministic legal text mirroring, raw snapshots, manifests, and checksums +- [The Board](docs/board.md) — the county map view, how its data is rebuilt, and how to redeploy the Artifact - [Roadmap](docs/roadmap.md) — what exists, what's next - [Contributing](docs/contributing.md) — the disciplines, and how to add a source - [Technical Brief — Government as Software](Technical%20Brief%20—%20Government%20as%20Software.md) — the founding document diff --git a/docs/board.md b/docs/board.md new file mode 100644 index 0000000000..901c56506d --- /dev/null +++ b/docs/board.md @@ -0,0 +1,55 @@ +# The Board + +`viz/board.html` is the Board — a rebuilt *view* of the canonical tree, never a +source. It is a nationwide county choropleth (income / population / poverty +lenses) where any county opens a drill-down of its officeholders and demographics. + +## 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=`); 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.