| @@ -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/ |
| @@ -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.* |
| @@ -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**. |
| @@ -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 |
| @@ -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. |
| @@ -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. |
| @@ -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 |
| @@ -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 ` |