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 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Republic OS — repeatable pipeline commands.
|
# Republic OS — repeatable pipeline commands.
|
||||||
# The build is deterministic: `make build` twice yields a byte-identical tree.
|
# 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/
|
build: ## Regenerate the entity tree from raw exports in data/
|
||||||
python3 scripts/build.py
|
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
|
validate: ## Check every entity file: OKF, schema, and link integrity
|
||||||
python3 scripts/validate.py
|
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)
|
changelog: ## What changed in the government since the last commit (BASE/HEAD overridable)
|
||||||
python3 scripts/generate_changelog.py $(BASE) $(HEAD)
|
python3 scripts/generate_changelog.py $(BASE) $(HEAD)
|
||||||
|
|
||||||
|
|||||||
@@ -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 legal-us-code # regenerate the U.S. Code Title 52 legal corpus seed
|
||||||
make validate # OKF + schema + link-integrity checks on all records
|
make validate # OKF + schema + link-integrity checks on all records
|
||||||
make changelog # what changed in the government since the last commit
|
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
|
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
|
- [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
|
- [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
|
- [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
|
- [Roadmap](docs/roadmap.md) — what exists, what's next
|
||||||
- [Contributing](docs/contributing.md) — the disciplines, and how to add a source
|
- [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
|
- [Technical Brief — Government as Software](Technical%20Brief%20—%20Government%20as%20Software.md) — the founding document
|
||||||
|
|||||||
@@ -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=<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.
|
||||||
Reference in New Issue
Block a user