Built in the open

Opus Populi is open source under AGPL-3.0. Every line of code is public, every decision is transparent, and every contribution is a civic act.

Architecture

A modular system designed so communities can customize and deploy independently.

Opus Populi is built as a set of independent, loosely coupled services behind a GraphQL Federation gateway. The backend runs four domain microservices — users, documents, knowledge (RAG), and regions (civic data) — each with its own schema, deployed independently. 16 pluggable provider packages abstract every external dependency behind swappable interfaces.

The frontend is a React 19 + Next.js 16 application with Apollo Client for state management, passkey authentication, and offline support as a progressive web app. AI runs entirely locally — Transformers.js for embeddings, pgvector for similarity search, and Ollama for LLM inference. Never as an external dependency.

This modularity is deliberate. Region-specific configuration lives in its own repository — a community in Texas can add their data sources without ever touching platform code, while both Texas and California benefit from shared pipeline improvements. The boundary is clean: open-source pipeline framework, declarative config per jurisdiction.

Repository structure

opuspopuli/                        # Core platform (monorepo)
├── apps/
│   ├── frontend/                  # React 19 + Next.js 16
│   └── backend/                   # NestJS microservices (4 services + gateway)
├── packages/                      # 16 pluggable provider packages
│   ├── region-provider/           # Declarative civic data plugin loader
│   ├── scraping-pipeline/         # AI-powered schema-on-read extraction
│   ├── prompt-client/             # Prompt service (circuit breaker + HMAC)
│   ├── llm-provider/              # Ollama LLM abstraction
│   ├── embeddings-provider/       # Transformers.js vector embeddings
│   ├── vectordb-provider/         # pgvector similarity search
│   ├── relationaldb-provider/     # Prisma database layer
│   ├── ocr-provider/              # Tesseract.js OCR processing
│   ├── auth-provider/             # Supabase Auth (passkeys + magic links)
│   ├── storage-provider/          # File storage abstraction
│   ├── email-provider/            # Transactional email
│   ├── logging-provider/          # Audit logging with PII masking
│   ├── extraction-provider/       # URL + PDF content extraction
│   ├── secrets-provider/          # Vault integration
│   ├── config-provider/           # Runtime configuration
│   └── common/                    # Shared types and HTTP pooling
├── docs/                          # Architecture and guides
├── observability/                 # Prometheus, Grafana, Loki configs
└── docker-compose.yml             # Local development (one command)

opuspopuli-regions/                # Region configs (separate repo)
├── regions/
│   ├── california.json            # California civic data sources
│   └── federal.json               # Federal campaign finance (FEC)
├── schema/
│   └── region-plugin.schema.json  # JSON Schema for validation
└── __tests__/                     # Schema + connectivity tests

The platform lives in a monorepo. Region configs live in a separate repository, published as an npm package — so civic domain experts can add regions without touching platform code.

Pluggable by design

Every external dependency — database, AI model, vector store, embedding engine, auth, email, storage — is abstracted behind a pluggable provider interface. 16 provider packages mean communities can swap implementations without changing application code. Run a different LLM, use a different database, or switch vector stores — all through configuration, not code changes.

How to contribute

01

Fork and clone

Fork the repository on GitHub and clone it to your machine.

02

Set up your environment

One command gets everything running locally with Docker Compose.

03

Pick an issue

Browse issues labeled "good first issue" for a guided starting point.

04

Submit a PR

Open a pull request. We review promptly and help you get it merged.

Where to start

Contributions come in many forms — not just code.

Region Configs

Add your jurisdiction's data sources to the regions repo — JSON files with URLs and content goals, no code required. CI validates and publishes automatically.

Frontend

React components, accessibility improvements, responsive design, and user experience.

Backend

NestJS services, GraphQL resolvers, data pipelines, and API development.

AI / ML

RAG pipeline tuning, document chunking strategies, embedding model evaluation, and LLM prompt optimization.

Infrastructure

Terraform modules, Docker configuration, CI/CD, and deployment tooling.

Documentation

Guides, API documentation, tutorials, translations, and onboarding materials.

Development principles

Privacy by default

No external API calls for AI. No tracking. Every feature must work without compromising user privacy.

Accessible first

WCAG 2.2 AA compliance. Keyboard navigation. Screen reader support. Civic tools must be usable by everyone.

Test everything

Unit tests, integration tests, end-to-end tests. Civic infrastructure must be reliable.

Document as you build

If it isn't documented, it doesn't exist. Every feature needs a guide for the next contributor.

Open code, private prompts

If you believe in transparency, why aren't the prompts open source too?

What's open

Open source code means anyone can verify:

  • What data the system collects
  • How documents are processed
  • What analysis results look like
  • That no backdoors or data exfiltration exists

What's private

Private prompts ensure:

  • Consistent analysis quality across all nodes
  • No one can game the system by studying prompt internals
  • Continuous improvement without network disruption
  • Every node in the network is equally trustworthy

What IS transparent about prompts

Methodology — what kinds of analysis are performed and what questions they answer

Design principles — neutrality, completeness, source attribution, and balance

Version history — when prompts changed, even if not exactly what changed

Integrity verification — cryptographic hashing proves prompts aren't tampered with

Think of it like a restaurant inspection system. The inspection criteria are public — what we look for. The training manual for inspectors is not — how we train them to look. Both serve the public interest. Open source alone isn't enough — a bad actor could fork the code and modify analysis. Private prompts alone isn't enough — users need to verify the system is honest. The combination gives users verifiable integrity with consistent quality.

Join the community

Building civic infrastructure is a collective effort. Whether you write code, documentation, or region configs — every contribution strengthens the network.