Flagship · applied AI product
Building a Civic AI Assistant with Source-Aware Tool Use
2026 · Pre-Alpha
A civic-tech product focused on making politics more legible at the federal and state level, built so every claim cites its source. Ledger is the broader civic product; Vera is the AI assistant surface inside it. I lead the AI, data, and security engineering on a three-cofounder team.
- Next.js
- React
- TypeScript
- Supabase
- Anthropic API
- Vitest
- Playwright
At a glance
- Role
- Cofounder & CTO; lead full-stack, AI, and data engineer
- Team
- Three cofounders · Ledger App, Inc. (Delaware C-corp)
- Year
- 2026
- Status
- Pre-Alpha · federal data foundation built, state-level activating
- Stack
- Next.js 16 · React 19 · TypeScript · Supabase · Upstash · Anthropic Claude · Vercel · Vitest · Playwright
- Contribution
- ~1,200 commits (~54% of all authored); owner of the AI, data, and security layers
- Proof
- 5-class grounded tool agent · 70 Postgres migrations · RLS on all 23 tables · 46 zod-validated API routes · 7 data sources
- Links
- ledger.vote
Why this mattered
Civic information is hard to navigate at scale, and most consumer-grade summaries strip out the provenance that makes a claim defensible. Ledger / Vera is built around source-aware tool use: every assertion in the product is grounded in a citable source, and the UI surfaces that grounding instead of hiding it. The thesis is that a civic AI assistant only earns trust if it can show its work.
My role and ownership
Cofounder and CTO on a three-person founding team. I authored roughly half of all commits and own the parts that make the product defensible end-to-end: Vera (the LLM agent), the Supabase data model and row-level-security posture, the civic-data ingestion layer and FEC adapter, the values-quiz scoring engine, and the pre-launch security program. The user-facing surfaces and the design system are a shared effort; the AI, data, and security engineering are mine.
Core constraints
- Every claim in the product has to cite its source. Provenance is a UX requirement and a type-system invariant, not a debug feature.
- LLM behavior is the primary risk surface: a hallucinated fact, or a leaked address, costs user trust faster than features earn it.
- Public civic-tech invites abuse and cost vectors: jailbreaks, prompt-leak attempts, and cross-user data extraction all have to be handled, not ignored.
- A three-cofounder team and a public shipping cadence that has to stay defensible as the codebase grows.
Architecture and key decisions
Vera: a grounded multi-turn LLM agent
Vera answers only from a closed 5-class grounded tool registry (federal candidates and finance, officeholders, jurisdiction, federal ballot, election calendar). An iteration-capped tool-use loop streams answers over a hand-rolled SSE protocol with inline citations and an explicit information-unavailable contract. No user PII can reach the model by construction: the prompt carries only message text, and the jurisdiction tool exposes an empty input schema, so an address has no channel into model-visible context. A merge-blocking contract test locks the guarantee against regression.
- Anthropic Claude
- TypeScript
- SSE streaming
- Tool use
Governance-as-code for the model
The part most teams never build. A SHA-256 hash gate fails the build closed on any edit to the neutrality prompt surface, forcing a fresh validation log. An 85-fixture LLM-as-judge harness (a Claude Opus judge) replays the real production loop before release. Multi-tier abuse enforcement (tiers 1 to 4) runs regex input and output classifiers and shares one abuse budget across both LLM routes, with per-message prompt-version provenance on every persisted turn.
- CI gates
- LLM-as-judge
- Abuse enforcement
Postgres data model and security
A 70-migration Supabase data layer with mandatory row-level security on every user-linked table (all 23 tables, 100% coverage) and security-definer RPCs for privacy-safe aggregation. Jurisdiction lookups use HMAC-keyed caching so raw addresses never persist. A multi-phase pre-launch audit found and fixed real defects: an RLS auth-bypass, an unauthenticated data-destruction RPC, and an admin privilege-escalation, each closed by a forward-only migration with regression tests.
- Supabase
- Postgres
- Row-level security
- Security audit
Civic-data ingestion with provenance
Multiple government and civic sources (FEC, US Census, OpenStates, MEDSL / Harvard Dataverse, and more) unified under a generic Sourced<T> envelope: a value cannot be constructed without its source label, URL, and as-of date, so an un-cited fact fails the type check. Scheduled pipelines re-ingest rosters and auto-open a drift PR, while a separate liveness watchdog catches the silent failure where the cron itself stops firing.
- FEC
- Census
- Provenance envelope
- GitHub Actions
Execution highlights
- 4,000+ tests across 445 files, 15 real-Supabase RLS round-trip suites, and 28 Playwright specs (9 accessibility); an OpenAPI 3.1 contract derived from zod schemas with a CI drift gate; 19 GitHub Actions workflows including CodeQL and secret-scanning.
- Extended the guarantee to the client: contributed to Ledger's public iOS companion app (Expo / React Native, live on the App Store), where Vera is served entirely from the shared backend so the device never assembles a model prompt, session tokens live in the iOS Keychain, and a CI contract test guards the mobile↔web API seam against drift.
Impact / current state
Pre-Alpha: the federal data foundation is built and ledger.vote is reachable, with state-level coverage activating behind a fail-closed bar. The AI, data, and security layers are settled; broader state surfacing and operator tooling are the next milestones.
What this demonstrates
Applied-AI engineering under public-trust constraints: an LLM agent that earns trust by showing its work, governance-as-code around model behavior, and the database and data-pipeline rigor to keep a civic product defensible as it grows.