Making local democracy accessible through AI β because understanding your town council shouldn't require a law degree.
"This year, I will finally understand my local elections and get involved as a citizen." β Our 2026 resolution
Γ Capistaine is an AI-powered civic transparency platform that crawls, processes, and makes accessible 6 years of municipal documents (arrΓͺtΓ©s, dΓ©libΓ©rations, commission reports) for Audierne, France. It serves as a training ground for civic AI agents that help citizens engage with local democracy.
Key Features:
- π€ Forseti 461 Agent: Charter validation, category classification, wording correction
- π PII Anonymization: Regex for transcripts (Speaker_1, Speaker_2...), LLM for general docs
- π Provider Failover: Multi-LLM support (OpenAI, Gemini, Claude, Mistral, Ollama) with automatic failover
- β¨ Contribution Wizard: 5-step guided workflow for citizen contributions
- π Document Intelligence: 4,000+ municipal documents indexed (Firecrawl + OCR)
- π LLM Observability: Full tracing via Opik with cost tracking and scheduled evaluation
- π Multi-channel Integration: Facebook, email, chatbot via Vaettir N8N workflows
- π Bilingual Interface: French/English with real-time switching
The platform supports audierne2026.fr, a real participatory democracy initiative.
New to OCapistaine? Start here:
| Resource | Description |
|---|---|
| Getting Started | Overview of the platform and quick start |
| Judge Trial Guide | Step-by-step guide to test Forseti validation |
Quick Test:
- Open the Streamlit app
- Select OpenAI provider in sidebar
- Go to Batch Validation β Single Contribution Test
- Click Random to load a real contribution (with English translation)
- Click Generate Variations to create test cases
- Validate each to see Forseti in action
| Component | Technology | Purpose |
|---|---|---|
| Data Validation | Pydantic | Schema validation for documents and API models |
| Web Scraping | Firecrawl | Municipal document acquisition with OCR |
| Scheduling | APScheduler | Periodic crawl jobs and data refresh |
| LLM Observability | Opik (cloud) | Tracing, evaluation, and LLM-as-judge |
| API | FastAPI | REST endpoints for N8N integration |
| Orchestration | N8N (Vaettir) | Multi-channel workflows (FB, email, chatbot) |
# Clone with submodules
git clone --recurse-submodules https://github.com/locki-io/ocapistaine.git
cd ocapistaine
# Install dependencies
poetry install
# Configure environment
cp .env.example .env
# Edit .env with your API keys
# Run crawler
python src/crawl_municipal_docs.py --source all --mode scrapeThe primary way to start the OCapistaine interface is via the unified startup script. It handles environment configuration, port management, and optional public access.
# Start the interactive UI
./scripts/run_streamlit.shAccess Point:
- Local: http://localhost:8502
If you need the REST API or N8N/Vaettir webhook integrations, start the FastAPI server in a separate terminal:
# Start FastAPI backend
poetry run uvicorn app.main:app --host 0.0.0.0 --port 8050 --reloadAccess API documentation at http://localhost:8050/docs.
Tasks (Cmd+Shift+P β "Tasks: Run Task"):
| Task | Description |
|---|---|
| π Start OCapistaine (Local) | One-click local startup |
| π Stop OCapistaine | Stop the Streamlit process |
| π Check Status | View running services status |
| π Open in Browser | Open http://localhost:8502 |
Debug Configurations (F5 or Run & Debug panel):
| Configuration | Description |
|---|---|
| Run Uvicorn (Poetry) | Start FastAPI server on port 8050 with debugger |
| Run Streamlit (Debug) | Start Streamlit UI on port 8502 with debugger |
| Full Stack (Uvicorn + Streamlit) | Both services with debugging |
Quick Start:
- Press
Cmd+Shift+Bto run the default build task (starts everything) - Or use the Run & Debug panel to select a configuration
main requires approval
dev no approval but linear history
To keep our history clean (no noisy merge commits on feature branches):
1. Run once:
git config --local pull.rebase true
# (or git config --local pull.rebase merges)
Optional safety layer:
git config --local pull.ff only
β git pull will now rebase by default (clean linear history)
β if it can't fast-forward, it fails instead of auto-merging
This way:
- Your local git pull stays clean
- Main/dev stays perfectly linear
- No more "Merge branch 'feature/ocr-β¦' into dev" spam
ocapistaine/
βββ app/ # Streamlit UI + Forseti agent + services
βββ src/ # Document crawlers (Firecrawl, OCR)
βββ docs/ # Git submodule β docs.locki.io
βββ ext_data/ # 4,000+ scraped municipal documents
For detailed architecture, see docs.locki.io:
- Application β Streamlit UI, Forseti agent, scheduler
- Architecture β System design and data flow
- Orchestration β Docker, N8N, observability
The docs/ directory is a git submodule pointing to locki-io/docs.locki.io.
git clone --recurse-submodules https://github.com/locki-io/ocapistaine.gitgit submodule update --init --recursivegit submodule update --remote docs
git add docs
git commit -m "Update docs submodule"cd docs
npm install
npm start # Dev server at localhost:3000
npm run build# Inside docs/
git add .
git commit -m "Your changes"
git push
# Back in parent repo
cd ..
git add docs
git commit -m "Update docs submodule"
git push| Repository | Status | Description |
|---|---|---|
| Vaettir | β Operational | N8N workflows connecting OCapistaine to audierne2026, Facebook, email |
| docs.locki.io | β Live | Technical documentation + hackathon journey blog |
| audierne2026/participons | β Live | Public participation platform (Jekyll) |
The public instance is password-protected. Configure in .streamlit/secrets.toml:
[auth]
password = "your-secret-password"Setup:
# Copy template
cp .streamlit/secrets.toml.example .streamlit/secrets.toml
# Edit with your password
nano .streamlit/secrets.tomlFor hashed passwords (more secure):
poetry run python -c "from app.auth import hash_password; print(hash_password('your-password'))"
# Then use: password = "sha256:..."Disable authentication (local development): Remove or leave empty the password field.
| Variable | Description | Example |
|---|---|---|
FIRECRAWL_API_KEY |
Firecrawl API key for web scraping | |
OPIK_API_KEY |
Opik API key for LLM observability | |
OPIK_WORKSPACE |
Opik workspace name | |
STREAMLIT_PORT |
Local Streamlit port | 8502 |
DISCORD_INVITE_URL |
Discord invite link for auth page | https://discord.gg/yourserver |
See .env.example for a complete template.
Track progress: github.com/orgs/locki-io/projects/2
Important for Hackathon Participants: Please read CONTRIBUTING.md before submitting code.
This project uses a dual-license structure. By contributing, you agree to the license terms for the component you're working on. See CONTRIBUTING.md for details.
This project uses a dual-license structure:
| Component | License | Files |
|---|---|---|
| Core infrastructure | Apache 2.0 | src/, docs/, utilities |
| Agent workflows & prompts | Elastic License 2.0 | agents/, workflows/ |
- Open source components: Crawlers, utilities, documentation - free to use, modify, distribute
- Source-available components: Agent orchestration, prompts, N8N workflows - visible but commercial use requires license from locki.io
See LICENSE and LICENSE-ELv2 for full terms.
This structure complies with hackathon open-source requirements while protecting locki.io engineering IP for future commercialization.
| Feature | Status | Notes |
|---|---|---|
| Document Crawling | β Operational | 4,000+ docs indexed |
| Forseti 461 Agent | β Operational | Charter validation, classification |
| PII Anonymization | β Operational | Transcript + LLM modes |
| Contribution Wizard | β Operational | 5-step workflow |
| Provider Failover | β Operational | Multi-LLM support |
| RAG (Retrieval) | π§ In Development | Document search pending |
March 2026 - Audierne Elections Sprint
The municipal elections in Audierne start March 18th, 2026. During this period, the dev branch will be pushed to its maximum capacity to support real citizen engagement.
- Firecrawl Integration: Move document crawling into the processors workflow for scheduled updates
- RAG Pipeline: Full retrieval-augmented generation for document Q&A
- Real-time Contribution Tracking: Live dashboard for election period
| Branch | Environment | Purpose |
|---|---|---|
main |
Render (cloud) | Stable demo for hackathon judges |
dev |
Local + ngrok | Active development, election support |
This ensures judges always have access to a stable, running application while development continues at full speed for the elections.
Γ Capistaine was built for the Encode AI Hackathon 2026.
| Resource | Link |
|---|---|
| π¬ Demo Video | youtu.be/EAZiVUMtfp8 |
| π Documentation | docs.locki.io |
| π Hackathon Journey | Blog posts |
| π Project Board | GitHub Project |
Built with β€οΈ for local democracy in Audierne, Brittany, France.