● Zion Boggan zionboggan.com ↗

Foundation: plan, brand system, neutrality doctrine, data + architecture specs

eeaf689   Zion Boggan committed on Jun 26, 2026 (1 month ago)
.gitignore +32 -0
@@ -0,0 +1,32 @@
+# deps / build
+node_modules/
+.next/
+dist/
+build/
+out/
+.turbo/
+
+# env / secrets
+.env
+.env.*
+!.env.example
+*.key
+*.pem
+
+# python
+__pycache__/
+*.pyc
+.venv/
+venv/
+
+# data / db (local ingest)
+*.sqlite
+*.sqlite-*
+data/cache/
+*.log
+
+# os / editor
+.DS_Store
+.exectest.sh
+.vscode/
+.idea/
PLAN.md +170 -0
@@ -0,0 +1,170 @@
+# DOCKET - Neutral Government Activity Tracker
+### Product & Brand Plan (v0, planning only - nothing built)
+
+*Name: **Docket** (LOCKED). A "docket" is the official register of proceedings - it inherits TreeTrace's evidence/record DNA while reading as civic, not forensic-security.*
+
+Date: 2026-06-26 · Status: PLAN ONLY · Method: overseer (Opus synth + Sonnet/Haiku research)
+
+### Locked decisions (2026-06-26)
+- **Name:** Docket
+- **Accent:** Brass/amber `#E0A53B`
+- **Scope:** Federal **+ state** from day one (OpenStates in the MVP - see cost note in §4)
+- **Summaries at launch:** Structured fields first (title/status/$/votes from official data); LLM prose added later
+
+---
+
+## 1. The Idea in One Line
+
+> The only app that shows you what the federal government **actually did this week** - bills passed or stalled, dollars moved, programs cut or funded - in plain English, with **zero spin**, every fact sourced directly to an official government record.
+
+The emotional hook is the user's own reaction: *"Wait - this was happening and I had no idea."* (e.g., the CBS Texas clip: a Trump-backed election bill stalling on a House conservative blockade - a real, consequential floor event most people never hear about.)
+
+The product's entire job is to convert **official legislative/spending actions** into **calm, neutral, glanceable awareness** - and to do it without ever picking a side.
+
+---
+
+## 2. Why Now / The Market Gap (validated by research)
+
+The civic-data space is structurally empty at the consumer-awareness level:
+
+| Player | What it is | Why it leaves the gap open |
+|---|---|---|
+| **GovTrack** | Deepest federal bill/vote data, since 2004 | Dated dense UI, for engaged watchers; no spending; jargon summaries; no push |
+| **USAFacts** (Ballmer) | Gold-standard neutral govt data | Static macro data, no bill-by-bill, no alerts, academic UX |
+| **Ballotpedia** | Neutral encyclopedia | Reference tool, not a real-time "what changed" feed; not mobile-first |
+| **Countable / ProPublica Represent** | Were the consumer apps | **Both dead.** Audience now unserved |
+| **FiscalNote / Quorum / Plural** | Enterprise intel | $10k+/yr, locked behind paywalls, not consumer |
+| **FastDemocracy / LegiScan / BillTrack50** | Power-user trackers (+ some AI) | Built for policy staff; jargon; no spending; no emotional hook |
+| **2025 DOGE trackers** | Spending-cut trackers | **Nearly all carry partisan valence** (pro- or anti-) |
+
+**The empty slot:** a consumer product that combines (1) federal **bills + spending in one feed**, (2) **push-alert awareness for normal people** who aren't already tracking politics, (3) **genuinely neutral** framing, and (4) **plain-English "here's what it does"** with no opinion. Nobody owns this.
+
+---
+
+## 3. Neutrality Doctrine - the non-negotiables
+
+This is the whole product. If it leans, it dies. Five rules to **hard-code into the codebase**, not just the style guide:
+
+1. **Government-source-only.** Every displayed fact links to an official URL (Congress.gov, USAspending.gov, GPO/GovInfo, CBO, Treasury). No secondhand, no think tanks, no media.
+2. **No adjectives.** Strip all qualitative modifiers from generated text before display. Never "slashed/gutted/expanded/massive" - only "reduced by $X," "added $Y," with the number and the source. (USAFacts' rule: *adjectives are partisan.*)
+3. **Surface by official action, never by virality.** Ranking = date of legislative action (introduced → markup → floor vote → signed) × dollar magnitude × people affected (per CBO/agency estimate). **Never** by news coverage or social engagement - that just imports media's agenda.
+4. **No comment sections, ever.** The single biggest bias-injection point. If engagement is needed, allow reactions on **summary clarity only** (was this clear? yes/no), never on the bill itself.
+5. **LLM summaries use extraction templates, not free-form generation.** Pull structured fields from official bill text. Free-form summarization is where documented LLM political lean creeps in (AAAI 2025: models skew pro-Democratic on health/guns). Test high-salience summaries against a Polarization Index before they go live.
+
+**Standing risks to monitor:** (a) LLM bias *drifts* as models update - needs ongoing automated checks, not a one-time test; (b) **topic-selection** is soft bias - proportional, dollar-and-action-weighted surfacing, not editorial "what matters" calls; (c) **partisan co-option** - if one base adopts it heavily it gets socially coded as "their tool"; mitigate with a visible bipartisan advisory board + dual-side launch outreach.
+
+**Visualization neutrality note:** when showing party splits (sponsor party / vote breakdown *is* factual data, so it's allowed), **never use saturated red-vs-blue** - the eye codes that as "teams." Use muted/desaturated party tones of equal visual weight, or a neutral yea/nay encoding.
+
+---
+
+## 4. Data Architecture
+
+### Primary stack (the backbone - all free, all official)
+1. **Congress.gov API** (`api.congress.gov/v3/`) - canonical bill status, actions, members, votes. Free api.data.gov key, 5,000 req/hr, same-day freshness. *Poll with `?sort=updateDate&fromDateTime=…` every 15-30 min.*
+2. **GovInfo API** (`api.govinfo.gov`) - full bill text, Congressional Record, public laws, appropriations docs. Same key, **36,000 req/hr** (most generous). `/published/{start}/{end}` for delta polling.
+3. **USAspending.gov API** (`api.usaspending.gov/v2/`) - award-level contracts/grants/loans, agency outlays. **No auth.** 10k-result cap per call → use bulk download for completeness.
+4. **Treasury Fiscal Data API** (`fiscaldata.treasury.gov`) - debt, deficit, daily cash flows (DTS T+1), monthly outlays by agency (MTS). No auth.
+
+### Supplements
+- **Roll-call votes, fastest path:** House Clerk XML (`clerk.house.gov/evs/`) + Senate roll-call XML - posted within hours, no key. Faster than the API for "a vote just happened."
+- **CBO cost estimates:** no API - scrape `cbo.gov/cost-estimates` by bill; macro projections via the `us-cbo` GitHub CSVs.
+- **Voteview.com** - bulk vote CSV + ideology scores (use scores internally for QA, not as user-facing labels).
+- **OpenStates v3** - 50-state + DC/PR coverage, standardized schema, JSON. **IN MVP SCOPE (decision: federal + state from day one).** Free tier is only 500 q/day, 10 req/sec - far too tight for production; **a paid tier is required** (Bronze 5k/day, Silver 50k/day; pricing not public - contact OpenStates). This is the one place the data stack stops being free. State ingest is also messier: freshness and schema completeness vary by state. Budget for: (a) the paid tier, (b) per-state polling cadence tuning, (c) a "coverage map" so the UI is honest about which states lag.
+
+### Real-time / change detection
+No government API offers webhooks - **everything is polling.** Build a change-detection layer: store last `updateDate` per bill, diff on each poll, emit an event on change → that event drives the feed + push notifications. Congress.gov website RSS (`congress.gov/rss/`) is a cheap pre-check before a full pull.
+
+### Biggest data-engineering risk
+**Congress.gov reliability.** It had a multi-day silent outage in Aug 2025 (redirect loop, key signup broke, zero comms). It's the only live bill-status source. **Mitigation:** fall back to the community `unitedstates/congress` scraper (pulls GovInfo bulk XML, LoC-independent); design ingest to tolerate 24-72h of Congress.gov downtime without going stale.
+
+---
+
+## 5. Product Surfaces
+
+**MVP (federal only):**
+- **The Feed** - reverse-chronological stream of official actions: "House passed HR ___ (vote 218-210)," "Senate cloture failed on S ___," "$2.1B contract awarded to ___ by DoD." Each card: plain-English what-it-does, status, dollar figure, **source link**.
+- **Bill page** - extraction-template summary, sponsor (name/party/state, factual), status timeline, CBO score if any, full-text link, vote breakdown (muted colors).
+- **Spending page** - agency outlays, notable awards, debt/deficit at a glance from Treasury, all with baselines and % context.
+- **Alerts** - push/email on: a bill changing status, a vote happening, spending over a threshold, or topics the user follows (by policy area or agency - **not** by party).
+- **"How we pick what to show"** + **"Who pays for this?"** transparency pages (core trust signals).
+
+**v1:** topic follows, personalized digest ("your weekly government recap"), "find my representatives + their actual votes," saved bills, share-as-image (factual card, no social-comment import).
+
+**In MVP (decision):** state-level via OpenStates, with an honest per-state coverage map.
+**Later:** historical trends, "where did the money actually go" award drilldowns, civics-educator/library partnerships.
+
+---
+
+## 6. Brand Pack - adapted from the TreeTrace pattern
+
+We **inherit TreeTrace's system architecture** (dark-first, forensic/record aesthetic, rationed accent, monospace data, custody-stamp mark, multi-page functional site) but **deliberately diverge on the accent color** - because the brand color itself must be politically neutral.
+
+**Key divergence: drop cobalt blue.** Blue reads Democrat, red reads Republican. The neutral, "official record / Capitol brass / parchment ledger" choice is **amber/brass on ink**. It evokes seals, the dome, and the public record - and belongs to neither side.
+
+### Color tokens (proposed)
+| Token | Hex | Role |
+|---|---|---|
+| `--dk-ink` | `#0B0C0E` | Page background (near-black) |
+| `--dk-surface` | `#121316` | Cards, terminal chrome |
+| `--dk-graphite` | `#23262B` | Raised/hover |
+| `--dk-paper` | `#F2EFE9` | Primary text (warm bone) |
+| `--dk-ash` | `#9BA0A6` | Secondary / mono labels |
+| `--dk-line` | `rgba(155,160,166,.18)` | Hairlines |
+| **`--dk-signal`** | **`#E0A53B`** | **Brass/amber - PRIMARY accent (rationed)** |
+| `--dk-signal-dim` | `#B07F25` | Hover/pressed |
+| `--dk-signal-tint` | `rgba(224,165,59,.08)` | Active-row wash |
+| `--dk-yea` | `#7FA88C` (muted sage) | Vote "yea" / funded - *not vivid green* |
+| `--dk-nay` | `#B98A8A` (muted clay) | Vote "nay" / cut - *not vivid red* |
+| party tones | desaturated, equal weight | only when party is the factual datum |
+
+*Alt accent if brass feels too warm: a neutral teal `#2BB3A3`. Avoid any dominant red or blue.*
+
+### Typography (same skeleton as TreeTrace)
+- **Display:** Archivo 800-900, uppercase, tight tracking - for headlines/numbers.
+- **Data / labels / nav:** JetBrains Mono, uppercase, tracked - vote counts, dollar figures, bill numbers, timestamps. (Reinforces "this is a record, not an op-ed.")
+- **Prose:** Fraunces for the rare lead sentence / plain-English summary.
+
+### Visual signature (adapted)
+- **Mark:** a **custody-stamp/seal frame** like TreeTrace's `[TT]`, but civic - a registration frame around a monogram (`[D]` / docket tick) reading as an *official stamp on the record*, not a forensic crosshair. Flat strokes, no gradient, no eagle/flag clichés (those carry valence).
+- **Hero:** TreeTrace uses a live CLI terminal; here, a **live "register" / ticker** - official actions materializing in real time as stamped record-lines ("14:02 ET - H.R. ___ - FAILED - 209-214"). Same "real thing happening live" energy, civic skin.
+- **Rationed accent:** one brass signal per view (a live dot, an active filter, a "just happened" flag). Never large fills. Calm, sealed, authoritative.
+- **Light mode:** parchment `#F6F4EF` bg, ink text - reads like an official document.
+
+### Philosophy line
+> *Record the action, not the argument - every entry sealed to its source.*
+
+---
+
+## 7. Tech Stack & Deployment (homelab-aware)
+
+- **Frontend:** Next.js (multi-page functional site, matches TreeTrace pattern), Tailwind with the token set above, dark-first. Mobile-first PWA so push works without app-store friction at MVP.
+- **Backend/ingest:** Python or Node workers polling the four APIs on cron; a change-detection table keyed by `updateDate`; Postgres for bills/actions/awards; a normalized "event" table that powers feed + alerts.
+- **Summaries:** extraction-template pipeline. Can run **locally on the 3060 (Ollama)** for cost-free draft extraction, with a Polarization-Index QA gate before publish - but **prefer deterministic field extraction over generation** wherever possible.
+- **Push:** ntfy (already in the homelab) for MVP; web-push for PWA.
+- **Hosting:** Cloudflare Pages for the static/edge front (same as zionboggan.com / treetrace.dev), workers/CT for the ingest service. Could live on a CT in the cluster.
+- **Costs:** all primary data is free; main cost is compute for ingest + summary QA. Fits the "no paid services until first payout" rule.
+
+---
+
+## 8. Build Phases
+
+- **Phase 0 - Brand + spike (this plan + a clickable shell):** lock name/colors/mark; stand up the token set + a static feed mockup with fake data.
+- **Phase 1 - Ingest spine:** Congress.gov + USAspending + Treasury pollers → events table → real feed (read-only, no auth). Source links on every card.
+- **Phase 2 - Summaries + bill pages:** extraction templates + Polarization-Index gate; full bill pages.
+- **Phase 3 - Alerts + accounts:** topic follows (policy area/agency), push via ntfy/web-push, weekly digest.
+- **Phase 4 - Trust + polish:** transparency pages, advisory board outreach, dual-side launch.
+- **Phase 1.5 - State spine:** OpenStates ingest (paid tier) + per-state coverage map, folded in alongside federal.
+- **Later:** reps lookup, historical trends, award drilldowns.
+
+---
+
+## 9. Decisions - RESOLVED (2026-06-26)
+1. **Name:** ✅ **Docket**
+2. **Accent:** ✅ **Brass/amber `#E0A53B`**
+3. **Scope of MVP:** ✅ **Federal + state** (OpenStates in MVP; paid tier required)
+4. **Summaries:** ✅ **Structured fields first** (LLM prose later)
+5. **Domain style:** OPEN - `.org` reads most neutral/non-commercial for a civic-trust product; `docket.org` likely taken, so candidates like `docket.vote`, `getdocket.org`, `docket.gov`-adjacent, or `ondocket.org` need a availability check. *(Only remaining open item.)*
+
+---
+
+*Research basis: 3 subagents - federal data-source map (Sonnet), competitive + neutrality playbook (Sonnet), TreeTrace brand-pack extraction (Haiku). All findings folded in above.*
README.md +25 -0
@@ -0,0 +1,25 @@
+# Docket
+
+**See what the government actually did this week - bills, votes, and dollars - in plain English, with zero spin, every fact sourced to an official record.**
+
+Docket is a neutral, non-partisan civic-awareness app. It turns official US legislative and spending activity (federal + state) into a calm, glanceable, alert-driven feed for people who aren't already glued to politics. The whole product is built around one reaction: *"this was happening and I had no idea."*
+
+## The one rule that defines everything
+**Zero political lean.** If Docket reads as left- or right-leaning, it has failed. Neutrality is not a tone we aim for - it is enforced in code (see [`docs/NEUTRALITY.md`](docs/NEUTRALITY.md)).
+
+## Status
+Planning → build (started 2026-06-26). MVP = federal + state.
+
+## Repo map
+- [`PLAN.md`](PLAN.md) - full product & brand plan (the source of truth for *what* and *why*)
+- [`docs/BRAND.md`](docs/BRAND.md) - design system, tokens, components (the *look*)
+- [`docs/NEUTRALITY.md`](docs/NEUTRALITY.md) - the enforceable neutrality doctrine (the *guardrails*)
+- [`docs/DATA_SOURCES.md`](docs/DATA_SOURCES.md) - API contracts for every data source
+- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) - system design, services, data model
+- [`docs/ORCHESTRATION.md`](docs/ORCHESTRATION.md) - who builds what (Opus / GLM / Codex) and how
+
+## Stack (target)
+Next.js (PWA, dark-first) · Tailwind w/ Docket tokens · Postgres · Python/Node ingest workers · ntfy + web-push · Cloudflare front + homelab CT backend.
+
+## Decisions (locked 2026-06-26)
+Name **Docket** · accent **brass `#E0A53B`** · scope **federal + state** · summaries **structured-fields-first**.
docs/ARCHITECTURE.md +52 -0
@@ -0,0 +1,52 @@
+# Docket - Architecture
+
+## Shape
+```
+ POLLERS (Codex) API + WEB (GLM)
+ Congress.gov ─┐ ┌─ Next.js app (PWA, dark-first)
+ GovInfo ──────┤ │ /register (feed) /bill/[id]
+ USAspending ──┤→ normalize → Postgres ──→│ /spending /states
+ Treasury ─────┤ (actions, bills, │ /how-we-pick /who-pays
+ House/Senate ─┤ awards, members, │
+ OpenStates ───┘ votes, raw_events) └─ /api (read) → events feed
+ │ │
+ └── change-detection ──→ events ──→ alerts (ntfy + web-push)
+```
+
+## Services
+1. **ingest** (Codex-owned, Python) - one poller module per source (`pollers/congress.py`, `usaspending.py`, `treasury.py`, `govinfo.py`, `votes_house.py`, `votes_senate.py`, `openstates.py`), each idempotent, rate-budget aware, with Congress.gov scraper fallback. A scheduler (cron/APScheduler) runs them at the cadences in `DATA_SOURCES.md`.
+2. **change-detection** - diffs each poll against stored `updateDate`/hash, writes normalized `actions` + emits `events`.
+3. **summaries** (Phase 2) - extraction-template pipeline; local Ollama (3060) draft; banned-words + Polarization-Index gate before publish. MVP ships structured fields only.
+4. **web/api** (GLM-owned, Next.js) - read API over Postgres for the feed + entity pages; the brand-pack UI.
+5. **alerts** - topic/agency/threshold subscriptions → ntfy + web-push. No party-based subscriptions.
+
+## Data model (Postgres, draft)
+- `bills` (id, source, externalId, congress/session, number, title, sponsor_id, status, policy_area, updated_at, source_url)
+- `actions` (id, bill_id?, source, action_type, action_date, chamber, text, dollar_amount?, affected_estimate?, source_url) - the spine of the feed
+- `votes` (id, bill_id, chamber, date, yea, nay, present, result, source_url) + `vote_positions` (vote_id, member_id, position)
+- `members` (id, name, party, state, chamber, source_url)
+- `awards` (id, source, externalId, agency, recipient, amount, action_date, program, source_url)
+- `fiscal` (metric, date, value, source_url) - debt/deficit/outlays
+- `states` (code, name, openstates_coverage_level, last_seen) - powers the coverage map
+- `events` (id, ref_type, ref_id, action_date, dollar_amount, affected_estimate, action_type) - the ranked feed source (rule #3: ONLY these fields feed ranking)
+- `raw_events` (source, externalId, payload jsonb, fetched_at) - provenance
+- `subscriptions` (user_id, kind[topic|agency|threshold|bill], value)
+
+**Hard constraint:** every user-facing row exposes a non-null `source_url` whose host is in the allowlist (neutrality rule #1, enforced by test).
+
+## Ranking (neutrality rule #3)
+`score(event) = f(actionDate, dollarAmount, affectedEstimate, actionType)` - no engagement/news/social inputs. Pure function, unit-tested to reference only those four fields.
+
+## Build/run hosts
+- **Frontend (GLM):** build + dev in place on **CT247** (`/shared/projects/docket`, ext4 exec confirmed). `npm`/Next dev server runs there.
+- **Backend (Codex):** Python ingest on **CT241** (verify exec on its mount at dispatch; fall back to a venv in a CT-local dir if its share is noexec).
+- **Postgres:** dedicated CT or container (decide at Phase 1; SQLite acceptable for the Phase 0/1 spike).
+- **Canonical source tree:** `/shared/projects/docket` (RAG/cbm-indexed, git). Deploy target later: Cloudflare front + homelab CT API.
+
+## Phases (see PLAN.md §8 for detail)
+0. Brand + clickable shell (fake data) - GLM
+1. Federal ingest spine → real feed (read-only) - Codex
+1.5. State spine (OpenStates) + coverage map
+2. Extraction summaries + bill pages + neutrality CI
+3. Alerts + accounts
+4. Trust pages + launch
docs/BRAND.md +87 -0
@@ -0,0 +1,87 @@
+# Docket - Brand & Design System
+
+Adapted from the TreeTrace "evidence/record" pattern, with a deliberate divergence: **the accent is brass, not cobalt** - because the brand color itself must be politically neutral (blue reads Democrat, red reads Republican; brass reads "official record / seal / ledger" and belongs to neither side).
+
+> **Philosophy:** *Record the action, not the argument - every entry sealed to its source.*
+
+Dark-first. Forensic-calm. Monospace data. Rationed accent. The UI should feel like an **official register being kept in real time**, not an op-ed and not a news app.
+
+---
+
+## 1. Color tokens
+
+Define as CSS custom properties on `:root` and mirror into the Tailwind theme.
+
+```css
+:root {
+ /* base - dark-first */
+ --dk-ink: #0B0C0E; /* page background, near-black */
+ --dk-surface: #121316; /* cards, register chrome */
+ --dk-graphite: #23262B; /* raised / hover */
+ --dk-paper: #F2EFE9; /* primary text, warm bone (NOT pure white) */
+ --dk-ash: #9BA0A6; /* secondary / mono labels */
+ --dk-ash-2: #6E7480; /* tertiary text */
+ --dk-line: rgba(155,160,166,.18); /* hairline borders */
+
+ /* signal - brass, RATIONED (one per view) */
+ --dk-signal: #E0A53B; /* primary accent */
+ --dk-signal-dim: #B07F25; /* hover / pressed */
+ --dk-signal-tint: rgba(224,165,59,.08); /* faint active-row wash */
+
+ /* semantic - MUTED, never vivid (neutrality) */
+ --dk-yea: #7FA88C; /* yea / passed / funded - muted sage, NOT vivid green */
+ --dk-nay: #B98A8A; /* nay / failed / cut - muted clay, NOT vivid red */
+ --dk-hold: #C9A66B; /* stalled / pending / in-committee */
+
+ /* party tones - desaturated, EQUAL visual weight, only when party is the datum */
+ --dk-party-d: #6E86A8; /* muted slate-blue */
+ --dk-party-r: #A87E6E; /* muted clay-brown */
+ --dk-party-i: #8A8F96; /* muted grey */
+}
+```
+
+**Light mode** (reads like an official document): `--dk-light-bg: #F6F4EF` (parchment), `--dk-light-text: #0B0C0E`, brass darkens to `#B07F25` for contrast.
+
+### Color rules (hard)
+- **On solid brass, text/glyphs are INK `#0B0C0E`** (brass is light - dark text reads cleanly). *(Inverse of TreeTrace, where cobalt is dark and text is white.)*
+- Brass is **rationed**: one signal per view (a live dot, the active filter pill, a "just happened" flag). **Never** large brass fills or brass body text.
+- **Never** use saturated red vs saturated blue for vote/party viz. Use the muted party/semantic tokens at equal weight. The eye must not read "teams."
+- No gradients on logo/marks. Flat strokes and fills only.
+
+---
+
+## 2. Typography
+
+- **Display:** `Archivo` 800-900, uppercase, tracking −0.02 to −0.04em, line-height 0.85-0.92. Headlines, big numbers, vote tallies.
+- **Data / labels / nav:** `JetBrains Mono`, uppercase, tracked. Bill numbers, dollar figures, timestamps, status pills, nav. This is the workhorse - it sells "this is a record."
+- **Prose:** `Fraunces` (+ italic) for the rare plain-English lead sentence / summary. One per surface, max.
+- **Wordmark:** "Docket" - Archivo 800, sentence case.
+
+---
+
+## 3. Visual signature
+
+- **Mark / logo:** a **custody-stamp seal** - a registration frame (outer rule + inner offset rule) around a `[D]` monogram with a small brass record-tick, reading as an *official stamp on the record*. Flat. **No eagle, no flag, no dome, no scales** - those cliches carry political valence or legal-tool connotations. Favicon: solid brass tile, ink "D" monogram (drop the inner rule below 24px).
+- **Hero - the live Register:** the signature element. A real-time stamped ledger of official actions materializing line by line, e.g.:
+ ```
+ 14:02 ET US HOUSE H.R. 22 FAILED 209-214 ·
+ 13:47 ET US SENATE S. 1582 CLOTURE OK 62-38 ·
+ 13:31 ET USASPENDING DoD AWARD $2.1B ·
+ ```
+ Mono, hairline-separated rows, one brass live-dot pulsing at the top. Same "real thing happening live" energy as TreeTrace's CLI hero, civic skin.
+- **Cards:** `--dk-surface` on `--dk-ink`, hairline border, raised 1 stop on hover (`--dk-graphite`). Status as a mono pill. Dollar figures right-aligned in mono.
+- **Liquid-glass accent:** faint brass radial wash on hero / OG cards only. Rationed.
+
+---
+
+## 4. Layout
+- **Multi-page functional site** (each nav item is a real page, not a scroll-monolith): The Register (feed) · Bill · Spending · States · How We Pick · Who Pays.
+- Mobile-first PWA (push without app-store friction).
+- Generous whitespace, hairline dividers, left-aligned data tables. Calm, not busy. Authoritative, not loud.
+
+---
+
+## 5. Voice (copy)
+- Declarative, factual, no adjectives. "The House failed to pass H.R. 22, 209-214." Never "narrowly failed," "controversial," "key."
+- Push copy: "The Senate voted on S. 1582 - cloture passed 62-38." Never "Politicians just voted to…"
+- See `docs/NEUTRALITY.md` §Copy for the banned-words list - it is enforced by a lint rule.
docs/DATA_SOURCES.md +52 -0
@@ -0,0 +1,52 @@
+# Docket - Data Source Contracts
+
+All primary sources are free + official. State (OpenStates) is the one paid tier. No source offers webhooks → **everything is polling + change-detection.**
+
+## Primary (the backbone)
+
+### Congress.gov API - federal bills, votes, members · PRIMARY
+- Base: `https://api.congress.gov/v3/`
+- Auth: free api.data.gov key, `?api_key=` · **5,000 req/hr** · 250 records/call max
+- Freshness: same-day for actions/status
+- Change detection: `GET /bill?sort=updateDate&fromDateTime={ISO}` every 15-30 min; store last `updateDate` per bill, diff.
+- Covers: bills (101st+), amendments, summaries, members, committees, nominations; **House roll-call vote endpoints (beta, 118th+)**.
+- ⚠️ **Reliability risk:** multi-day silent outage Aug 2025. **Fallback:** `unitedstates/congress` scraper (GovInfo bulk XML, LoC-independent). Ingest must tolerate 24-72h Congress.gov downtime.
+
+### GovInfo API - full bill text, Congressional Record, public laws · PRIMARY
+- Base: `https://api.govinfo.gov/` · same api.data.gov key · **36,000 req/hr** (most generous)
+- Delta poll: `GET /published/{start}/{end}` hourly. Collections: `BILLS`, `CREC`, `PLAW`, appropriations, `CHRG`, `FR`, `CFR`.
+- Use for: full text, public-law text, appropriations docs. 1-2 business-day lag.
+
+### USAspending.gov API - federal spending (awards, outlays) · PRIMARY
+- Base: `https://api.usaspending.gov/api/v2/` · **no auth**
+- Awards: `POST /search/spending_by_award/` (10k-result cap/call → use `/bulk_download/` for completeness). Agency: `/agency/`, accounts: `/federal_accounts/`.
+- Change detection: filter by `action_date`, poll daily (agencies have 2-business-day reporting SLA).
+
+### Treasury Fiscal Data API - debt, deficit, cash flows · PRIMARY
+- Base: `https://api.fiscaldata.treasury.gov/services/api/fiscal_service/` · **no auth**
+- Datasets: Debt to the Penny (daily), Daily Treasury Statement (T+1), Monthly Treasury Statement (outlays by agency, ~3wk lag), Historical Debt.
+- Poll daily ~6pm ET.
+
+## Vote-speed supplements
+- **House Clerk XML** `https://clerk.house.gov/evs/` - votes within hours, no key. Poll 10-30 min during session.
+- **Senate roll-call XML** `https://www.senate.gov/legislative/LIS/roll_call_lists/` - no key.
+- **Voteview** `https://voteview.com/data` - bulk CSV + ideology scores. **Internal QA only** (never user-facing labels).
+
+## State · IN MVP (paid)
+### OpenStates API v3 - 50 states + DC/PR
+- Base: `https://v3.openstates.org/` · **API key required**
+- Tiers: Free 500/day·10rps (too tight) → **Bronze 5k/day / Silver 50k/day (paid, contact for pricing)**. Production needs paid.
+- JSON, standardized schema. Freshness varies by state.
+- **Ship an honest per-state coverage map** - surface which states lag so the UI never implies completeness it doesn't have.
+
+## CBO (cost estimates) · USEFUL, no API
+- Scrape `cbo.gov/cost-estimates` by bill for per-bill scores; macro CSVs at `github.com/us-cbo`. Dollar figures only, no characterization.
+
+## Source allowlist (neutrality rule #1)
+`*.gov`, `api.congress.gov`, `govinfo.gov`, `usaspending.gov`, `fiscaldata.treasury.gov`, `cbo.gov`, `clerk.house.gov`, `senate.gov`, OpenStates official-record links (→ state `.gov`).
+
+## Ingest principles
+- One poller per source, each writes normalized `actions` rows + raw payload to `raw_events`.
+- Idempotent: dedupe on `(source, externalId, updateDate)`.
+- A poll never blocks the feed; change-detection table is the single source of "what's new."
+- Rate-budget aware; exponential backoff; Congress.gov fallback wired from day one.
docs/NEUTRALITY.md +59 -0
@@ -0,0 +1,59 @@
+# Docket - Neutrality Doctrine (enforceable)
+
+Neutrality is the product. This file turns "be non-partisan" into **engineering constraints, lint rules, and tests** that ship in the codebase. Every PR is checked against it. Opus (overseer) owns this gate; GLM and Codex must build to it.
+
+---
+
+## The 5 hard rules
+
+### 1. Government-source-only
+Every user-facing fact MUST carry a `sourceUrl` pointing to an official government domain. No exceptions, no secondhand sources.
+- **Allowed source hosts:** `congress.gov`, `api.congress.gov`, `govinfo.gov`, `usaspending.gov`, `fiscaldata.treasury.gov`, `cbo.gov`, `gpo.gov`, `clerk.house.gov`, `senate.gov`, `*.gov`, and OpenStates' official-record links (which point to state `.gov` legislatures).
+- **Enforcement:** `Fact` / `Action` types REQUIRE a non-null `sourceUrl`; a test rejects any record whose host is not in the allowlist. No card renders without a visible "Source" link.
+
+### 2. No adjectives
+Generated/display text contains **no qualitative modifiers**. Numbers, status, dates, names only.
+- **Banned-words lint** (`lint/neutrality.ts`) - fails the build if any appear in generated copy, summaries, or push text:
+ `slashed, gutted, slammed, blasted, massive, tiny, huge, sweeping, radical, extreme, controversial, popular, unpopular, landmark, historic, devastating, crippling, generous, stingy, bloated, wasteful, common-sense, partisan, bipartisan(as praise), key, crucial, vital, narrowly, barely, overwhelmingly, finally, surprisingly`
+ (List lives in code; extend over time.)
+- "Reduced by $X" / "added $Y" - yes. "Cut" / "slashed" - no.
+
+### 3. Surface by official action, never by virality
+Feed ranking = **(a) date of official legislative/spending action → (b) dollar magnitude → (c) people affected (per CBO/agency estimate)**.
+- **Forbidden inputs to ranking:** news mention counts, social shares, click engagement, "trending," editorial pinning.
+- **Enforcement:** the ranking function takes ONLY `{actionDate, dollarAmount, affectedEstimate, actionType}`. A test asserts no engagement/news field is referenced. Topic selection is proportional to official-action volume + dollar magnitude, not editorial judgment.
+
+### 4. No comment sections, ever
+No free-text user comments on bills, votes, or spending - anywhere. The single largest bias-injection surface.
+- Permitted engagement: a single **"Was this summary clear?" yes/no** on summary *clarity* (never on the bill's merit). No reactions, votes, ratings, or emoji on legislation itself.
+- No social-share buttons on individual bills (sharing imports outside political discourse). Share-as-image (factual card) only, later.
+
+### 5. LLM summaries = extraction templates, not free-form
+When prose summaries land (Phase 2+; MVP is structured-fields-only), they are produced by **field extraction into a fixed template**, not open-ended generation.
+- Template: (1) official title + number, (2) sponsor name/party/state - factual, uncharacterized, (3) what the text authorizes (extracted clauses, plain language), (4) CBO score if any (dollar figure only), (5) current status.
+- Every summary passes the banned-words lint + a **Polarization-Index check** before publish (generate D-leaning and R-leaning variants, assert the default sits statistically between them). High-salience bills (100+ media mentions) get human review before push.
+- LLM runs locally on the 3060 (Ollama) for drafting; extraction is preferred over generation wherever a field can be pulled deterministically.
+
+---
+
+## Visualization neutrality
+- Party affiliation and vote splits ARE factual data and may be shown - but with **muted, equal-weight tones** (`--dk-party-d/r/i`, `--dk-yea/nay`). Never saturated red-vs-blue. Equal saturation, equal area, alphabetical or by-count order (not party order).
+- Default sort of any member/vote list: **by vote, then alphabetical** - not grouped by party (grouping primes partisan reading).
+
+## Trust surfaces (must ship)
+- **/how-we-pick** - plain explanation of the ranking algorithm (rule #3), public.
+- **/who-pays** - funding/ownership transparency.
+- **Source link on every fact** (rule #1).
+- No political-campaign or advocacy ads, ever.
+
+## Standing risks (monitor, not one-time)
+1. **LLM bias drift** - re-run the Polarization-Index suite on every model change; it's CI, not a launch checklist item.
+2. **Topic-selection soft bias** - audit feed composition periodically against official-action volume; if it skews, the ranking inputs are wrong, not the world.
+3. **Partisan co-option** - bipartisan advisory board + dual-side launch outreach; track which communities adopt.
+
+## CI gate (definition of done for any user-facing text feature)
+- [ ] banned-words lint passes
+- [ ] every fact has an allowlisted `sourceUrl`
+- [ ] ranking references only the 4 permitted fields
+- [ ] no comment/reaction-on-bill component present
+- [ ] (Phase 2+) Polarization-Index check passes on sample summaries
docs/ORCHESTRATION.md +39 -0
@@ -0,0 +1,39 @@
+# Docket - Build Orchestration
+
+Overseer method. Opus 4.8 coordinates; GLM-5.2 and Codex do the heavy app code. Pull out all the stops, don't settle.
+
+## Division of labor
+| Agent | Host / driver | Owns |
+|---|---|---|
+| **Opus 4.8** (overseer) | CT215 (this) | Architecture, brand system, the **neutrality gate**, data-source contracts, task specs, integration, review/synthesis, final correctness sign-off |
+| **GLM-5.2** | CT247 `agent3` - `opencode run -m zai/glm-5.2` | **Frontend**: Next.js app, brand-pack implementation (tokens→Tailwind, components), the live Register hero, feed, bill/spending/states pages, trust pages, PWA |
+| **Codex** | CT241 `codex-cli` - `codex exec` (authed via ChatGPT) | **Backend**: ingest pollers (Congress/GovInfo/USAspending/Treasury/votes/OpenStates), change-detection, DB schema, read API, extraction-summary pipeline (Phase 2) |
+
+## How to drive the fleet (from CT215 over SSH)
+```bash
+# GLM (frontend) - runs in the repo, full MCP (RAG/serena/memory) attached
+ssh root@REDACTED-IP "pct exec 247 -- bash -lc 'cd /shared/projects/docket && opencode run -m zai/glm-5.2 \"<task>\"'"
+
+# Codex (backend)
+ssh root@REDACTED-IP "pct exec 241 -- bash -lc 'cd /shared/projects/docket && codex exec \"<task>\"'"
+```
+Run long builds in the background; capture logs to `_ops/logs/`. Verify GLM frontend output from Zion's **real browser** (Brave, worky profile, hard-refresh) - not just a curl.
+
+## Every dispatched task MUST carry
+1. **RAG-first + targeted-discovery** rule (query `homelab_context` first; read only the specific file needed; no full-tree reads).
+2. A pointer to the relevant spec: `PLAN.md`, `docs/BRAND.md`, `docs/NEUTRALITY.md`, `docs/DATA_SOURCES.md`, `docs/ARCHITECTURE.md`.
+3. The **neutrality gate** for any user-facing text/UI: government-source-only, no adjectives, no comment sections, muted (never red/blue-team) viz, ranking by official-action only.
+4. A crisp definition of done + where to write output.
+
+## Cadence
+- Small waves (≤3-4 concurrent agent runs).
+- Opus reviews every wave's output against the spec + neutrality gate before the next wave.
+- Memory-graph: record each significant decision/handoff so the next agent inherits state.
+
+## Wave 0 (kickoff)
+- **GLM:** scaffold Next.js + Tailwind w/ Docket tokens; build the static shell of all pages with the live-Register hero on fake data; wire the brand system from `docs/BRAND.md`.
+- **Codex:** scaffold the ingest service (poller skeletons + DB schema from `docs/ARCHITECTURE.md`), with Congress.gov + USAspending pollers returning real data into SQLite (Phase-0 store).
+- **Opus:** review both, wire the neutrality lint (`lint/neutrality.ts`), integrate, report.
+
+## Public-output gate (when anything ships)
+No AI tells, no em-dashes, no model footers; strip `