Skip to content

Mungbeanbeanie/hackabull2026

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

210 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Civic Info System — PoliDex

Politicians as software running on hardware (donors and networks). PoliDex maps every politician into a 20-dimensional policy space, scores your alignment against them in real time, and exposes the influence networks behind every vote — no party affiliation required.


Table of Contents

  1. The Problem
  2. Technical Architecture
  3. Key Features
  4. How to Run
  5. Tech Stack
  6. Project Structure
  7. AI & Frameworks
  8. What We Learned

The Problem

1. The Decline in Voter Turnout & Engagement

Voter engagement is backsliding — especially among young people. Voter turnout in the 2024 presidential election dropped to 65.3%, a 1.5 percentage point decline from 2020 (U.S. Census Bureau). Young adults under 30 made up 30% of all nonvoters in 2024, up from 25% in 2020, and less than half of eligible 18–24 year olds cast a ballot at all (Pew Research Center, USAFacts). Turnout declined across all racial and ethnic groups; Hispanic voters saw the steepest drop at 3.1 percentage points, reaching a turnout rate of just 50.6%.

Sources: U.S. Census Bureau (2024 Current Population Survey), Pew Research Center (2024 Election Analysis), USAFacts.

2. The Crisis of Trust in Media & Bias

Americans have no reliable, unbiased source for political information. A late-2025 Gallup poll found only 28% of Americans have a "great deal" or "fair amount" of trust in mass media — an all-time low, down from 68% in 1972. For adults under 65, that number falls to 28% or lower across every age group. Trust is now so fractured along political lines that a truly neutral source is more valuable than ever.

Source: Gallup (Media Confidence Trend, 2025).

3. The Epidemic of Misinformation

51% of Americans view made-up news as a "very big problem" (Pew Research Center). Nearly one-third of adults regularly encounter fake news online, and almost one-quarter admit to having shared it — knowingly or not. When social media news consumers were surveyed about their top complaint, "inaccuracy" ranked first.

Source: Pew Research Center (Global Public Concern about Made-Up News; Social Media News Consumer Reports).


PoliDex responds to all three by replacing editorial opinion with verifiable math: publicly available voting records, campaign finance data, and legislative history — scored, ranked, and surfaced in seconds.


Technical Architecture

The Political Math Engine

At the core of PoliDex is a weighted cosine similarity function we derived from scratch to capture policy alignment across 20 independent dimensions:

$$\text{Similarity} = \frac{\sum (w_i \cdot v_{\text{input},i} \cdot v_{\text{poli},i})}{\sqrt{\sum w_i \cdot v_{\text{input},i}^2} \cdot \sqrt{\sum w_i \cdot v_{\text{poli},i}^2}}$$

Where:

  • $v_{\text{input}}$ = the user's 20-dimensional policy vector (generated by the onboarding quiz)
  • $v_{\text{poli}}$ = a politician's 20-dimensional policy vector (LLM-tagged from legislative records)
  • $w_i$ = per-dimension weight, either uniform (stated alignment mode) or adherence-weighted (follow-through mode)

This formula is original to our team. Standard cosine similarity treats all dimensions equally. Our key insight is that weighting each dimension independently lets the system redefine "closeness" based on a politician's consistency — not just their stated position — without any changes to the core calculation.

The 20-Dimensional Policy Space

Every politician is represented as a coordinate in a 20-dimensional space spanning planks like Fiscal Policy, Civil Liberties, Energy, Healthcare, Foreign Policy, and more (defined in shared/taxonomy.json). Each plank is scored on a 1–5 scale. Two vectors are produced per politician:

  • Theoretical Vector — LLM-tagged from stated positions via OpenStates
  • Legislative Vector — derived from actual voting history via Legiscan and Congress.gov

Adherence Scalar

The Adherence Toggle is the system's most original mechanic. It measures Δ(Theoretical Vector, Legislative Vector) and produces per-dimension consistency weights computed as $w_i = 1/\sigma_i$ across a politician's voting history — dimensions where they vote consistently get higher weight.

  • Toggle OFF (default): uniform weights → "who says they agree with you"
  • Toggle ON: adherence weights → "who actually follows through"

The dot representing a politician animates from their stated position to their actual legislative position as the toggle turns on.

Vector Database

The politician library is indexed in a k-d tree spatial index (LibraryIndexer.java) backed by MongoDB. At query time, the inference pipeline runs full-library scoring, neighborhood lookups, or catalog queries depending on request type. The k-d tree enables sublinear nearest-neighbor search across the full 20D space.

Java ↔ Python IPC

The Java chassis orchestrates all system state and HTTP traffic. Stateless math (cosine similarity, weight calculation, constraint discovery) lives in isolated Python workers. Communication flows via stdin/stdout JSON pipes through PythonRunner.java, keeping both runtimes cleanly separated with a strict data contract defined in InferencePayload.java.


Key Features

Policy Match Engine

  • Take a 20-question quiz mapping your positions across all 20 policy planks (1–5 scale)
  • Get a ranked list of politicians sorted by alignment score
  • Flip the Adherence Toggle to re-rank by who votes consistently with their stated positions
  • Cross-party results: the math doesn't know what party anyone is in

Head-to-Head Comparison

  • Pick any two politicians and see a side-by-side radar chart across all 20 dimensions
  • Issue-by-issue overlap graph shows exactly where they agree and diverge
  • Versus mode shows your alignment against both simultaneously

Influence Edge Map

  • Weighted graph: Politicians → Super PACs → Corporate Donors → Kinship ties
  • Edges are verifiable-only (financial, employment, family) — no speculation
  • Radial layout: politician at center (T1), immediate ties (T2), donor networks (T3/T4)
  • Edge thickness encodes influence volume
  • Data sourced from OpenFEC campaign finance records

Profile Import/Export

  • Generate a base64 profile code from your quiz results
  • Import the same code into the Chrome Extension to sync your vector across surfaces

Chrome Extension — Civic Info HUD

  • Double-click any politician name on any webpage to instantly surface their alignment card
  • Card shows: % match vs your vector, top aligned and misaligned policy dimensions, top implemented policies derived from legislative record
  • Extension syncs your profile vector from the main app via a paste-in import field
  • Built on Manifest V3 with a service worker, content script, and popup architecture

How to Run

Prerequisites

Tool Version
Node.js 18+
Java 17+
Maven 3.8+
Python 3.10+
MongoDB 6+ (local or Atlas URI)

Quick Start (one command)

From the repo root:

  • macOS/Linux:
chmod +x ./run-all
./run-all
  • Windows:
.\run-all.cmd

Optional flags:

./run-all --backend-port 8080 --frontend-port 3000 --skip-install

1. Environment Setup

Copy and fill in the environment file:

cp backend/java-chassis/.env.example backend/java-chassis/.env

Required keys:

MONGODB_URI=mongodb://localhost:27017/civicinfo
ANTHROPIC_API_KEY=...
OPENSTATES_API_KEY=...
CONGRESS_GOV_API_KEY=...
GOOGLE_CIVIC_API_KEY=...
LEGISCAN_API_KEY=...
OPEN_FEC_API_KEY=...

Install Python dependencies:

cd backend/inference-engine
pip install -r requirements.txt

2. Start the Backend

cd backend/java-chassis
mvn exec:java

The Java chassis starts on http://localhost:8080. On first boot it seeds the politician database if MongoDB is empty.

3. Start the Desktop App

cd frontend/deskApp
npm install

Option A — Native desktop window (recommended):

npm run electron:dev

Opens the app in an Electron window. Next.js dev server and Electron launch concurrently; Electron waits for the server before opening.

Option B — Browser:

npm run dev

Open http://localhost:3000 in your browser.

4. Load the Chrome Extension

  1. Open Chrome and navigate to chrome://extensions
  2. Enable Developer mode (top-right toggle)
  3. Click Load unpacked and select the frontend/extension/ directory
  4. The Civic Info HUD icon appears in your toolbar

To sync your profile to the extension:

  1. Complete the quiz in the desktop app
  2. Go to Compare → Export to Extension and copy the profile code
  3. Click the extension icon → paste the code → import

Tech Stack

Layer Technology
Desktop Frontend Next.js 16 (App Router), React 19, TypeScript
Styling Tailwind CSS v4, shadcn/ui
Animation Framer Motion
Charts Recharts
Backend Orchestration Java 17, Maven
Database MongoDB (sync driver 5.2), k-d tree RAM index
Inference Engine Python 3, custom stateless math modules
LLM Tagging Gemini 3.0-flash
Chrome Extension Manifest V3, Service Worker, vanilla JS
External APIs OpenStates, Congress.gov, Google Civic Info, OpenFEC, Legiscan, Wikimedia

Project Structure

hackabull2026/
├── backend/
│   ├── java-chassis/                  # System orchestration, HTTP layer, DB, IPC
│   │   └── src/main/java/com/system/
│   │       ├── controllers/           # HTTP gateway (RequestHandler)
│   │       ├── api/                   # Outbound API clients (6 data sources)
│   │       ├── models/                # PoliVector, PoliFigure, UserProfile
│   │       ├── managers/              # LibraryIndexer, SearchController, IngestionRunner
│   │       ├── sampler/               # QuizEngine, userNegPreference
│   │       ├── storage/               # DataManager (MongoDB gateway)
│   │       └── bridge/                # PythonRunner, InferencePayload (IPC)
│   ├── inference-engine/              # Stateless math workers (Python)
│   │   ├── math/                      # cosine_sim.py, weight_calculator.py, constraint_discoverer.py
│   │   ├── tagging/                   # llm_analyst.py, prompt_builder.py, score_validator.py
│   │   └── inference_manager.py
│   └── shared/
│       ├── taxonomy.json              # 20-plank policy space definitions
│       └── vector.schema              # 20D vector JSON schema
├── frontend/
│   ├── deskApp/                       # Next.js desktop app
│   │   └── src/features/polidex/
│   │       ├── components/            # All views: dashboard, compare, quiz, simulator, landing
│   │       ├── data/                  # Politicians seed data, taxonomy mirror
│   │       └── lib/                   # API client, display utils, profile import/export
│   └── extension/                     # Chrome Extension MV3
│       ├── scripts/                   # content.js, background.js, cosine_bridge.js, user_vector_store.js
│       └── ui/                        # card.html, popup.js
└── scripts/
    └── seed_politicians.py            # Politician DB seed script

AI & Frameworks

  • Gemini 3.0-flash — LLM tagging pipeline: converts raw legislative text from OpenStates into validated 20D PoliVectors via llm_analyst.pyscore_validator.py
  • Claude Code — AI-assisted development throughout the build. Commits made with Claude Code assistance are tagged CLAUDE CODE in the commit history.
  • Recharts — radar charts and bar graphs for policy visualization across 20 dimensions
  • Framer Motion — UI transitions and the adherence toggle animation (dot moving from stated → actual position)
  • shadcn/ui + Tailwind CSS v4 — component library and design system
  • MongoDB sync driver 5.2 — politician library persistence and user history

What We Learned

Pre-planning is a force multiplier. Designing data contracts (taxonomy.json, vector.schema) and module boundaries before writing a single line of code let the whole team work in parallel without stepping on each other. That architecture held together even when we were refactoring at 3 AM.

Deriving a custom math equation takes real iteration. The weighted cosine similarity formula wasn't pulled from a paper — we designed it from first principles to fit the constraint that policy dimensions have independent variance. Getting the per-dimension adherence weights ($1/\sigma$) right required working through the math before touching any implementation.

Vector databases are a different mental model. Moving from row-based lookups to spatial nearest-neighbor queries in 20D space required rethinking how retrieval works. Building the k-d tree indexer was one of the harder pieces of the backend.

Modular code is survival at a hackathon. Strict single-responsibility design across every file meant we could hand off a module without a lengthy explanation. That paid off every time we needed to debug or extend something under a time crunch.

Making complex data feel simple is its own hard problem. Computing alignment scores wasn't the challenge — designing a UI where a non-technical user understands what a 20-dimensional vector comparison means was. The radar chart, the adherence toggle animation, and the issue-by-issue overlap graph were each answers to that question.

Desktop-first removes friction. A local app with no accounts and no cloud sign-in means users reach their results immediately. Nothing leaves their machine.

Chrome extensions are their own ecosystem. Manifest V3's service worker model, content script isolation, and the restrictions on what can execute where required a complete context switch from standard web development. Getting the background ↔ content ↔ popup communication right was non-trivial.

Cross-language IPC is unforgiving. Java calling Python via stdin/stdout pipes works, but working directory, path resolution, and the serialization contract all have to be exactly right. One wrong assumption returns empty results with no error — and tracking that down under a deadline is genuinely painful.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors