Open-source contribution
BetterCalatagan
An independent civic portal for Calatagan, Batangas: every statistic published is backed by a government source, and the build fails automatically if it is not.
- The people of Calatagan, Batangas — and anyone seeking public records with verified provenance
- Creator & Lead Maintainer
- October 2026 – Present
The situation
Local government information in the Philippines is scattered across agency portals — some of them dead — published without sources, and difficult to verify. There was no single place where a resident of Calatagan could read a figure about their municipality and know exactly where it came from.
What I built
I built an independent civic-information portal covering the municipality end to end: 44 pages, profiles for all 25 barangays, and 10 machine-readable datasets spanning PSA census records, DILG fiscal disclosures, DPWH infrastructure contracts, and archived municipal charters.
The defining architectural decision is that no figure ships without evidence. Every civic record carries a typed provenance envelope, guarded by 275 automated tests in CI. If a figure lacks a primary government source, relies on an encyclopaedia or social post, or fails internal arithmetic reconciliation, the build fails.
The portal is built with Astro and plain CSS, delivering static HTML with zero client-side JavaScript by default. For deep exploration, it features an interactive 3D terrain map of the 25 barangays, an in-site document reader for 232 archived public records, and a grounded AI assistant on Cloudflare Workers with code-level numeric verification.
An independent open-source civic project, started in October 2026. Part of the BetterGov.ph / Better LGU open civic-data community. Not the official website of the Municipality of Calatagan.
What it lets people do
- 01Read verified population, income classification, and barangay statistics traced to named government sources
- 02Explore the 25 barangays on an interactive 3D map by population, households, or infrastructure projects
- 03Browse 14 quarters of municipal finances from DILG filings with 838 internal reconciliation checks, and 179 DPWH projects
- 04Ask the grounded AI assistant in English, Filipino, or Taglish, receiving cited answers checked in code against site figures
- 05Inspect 232 archived public documents and 156 Full Disclosure filings in the in-site document reader
- 06See what is withheld and why — the Sources page lists gaps and the exact rationale for omitting each
Chapter 01
Enforcing truth in code, not conventions
Most civic dashboards publish a spreadsheet and trust the visitor to believe it. In the Philippines, official local government numbers frequently live across orphaned portal servers, unstandardized PDF scans, or conflicting agency releases.
When building BetterCalatagan, the starting premise was different: an absence you can see is more useful than a number you cannot check. Every civic record is wrapped in a strict TypeScript + Zod provenance envelope carrying its primary source, exact verification date, data period, and verification tier.
- STAGE 01Source
Primary Government Sources
PSA OpenSTAT, DILG SRE, DPWH contracts & Official Gazette
- STAGE 02Zod Schema
Typed Sourced<T> Envelope
Structured metadata with cell-level audit citations and tier labels
- STAGE 03Vitest Gate
275 Automated CI Guardrails
838 arithmetic checks; build fails on unverified claims or future dates
- STAGE 04Astro Build
Zero-JS Static Delivery
Astro compiles fast, immutable HTML; syncs /ask/corpus.json
The 4-Tier Civic Readiness Model
Requires verifiable government issuance or database key. Rechecked quarterly.
- Municipal identity & PSGC codes (PSA OpenSTAT)
- 2024 Population (60,420) & 15,442 households (Census series)
- 1st Class Income Reclassification (BLGF MC No. 020.2024)
- DTI Competitiveness rankings 2015–2024 (CMCI)
- Official public holidays & emergency hotlines (Gazette)
Good intentions decay over time. In src/data/civic-data.test.ts, the test suite includes deliberate negative assertions: tests that deliberately inject unsourced figures, unverified claims in Tier 1, future verification timestamps, and mismatched population counts to prove the guardrail will break the build. If a future update introduces an unsourced fact, git push is rejected.
Chapter 02
An AI that cannot hallucinate what the site doesn't say
Every page on BetterCalatagan features an “Ask anything” box. Unlike typical LLM chatbots that invent mayoral biographies or speculate on municipality land area from general training data, this assistant is mathematically bound to the site itself.
The assistant runs in an isolated Cloudflare Worker. It draws knowledge exclusively from /ask/corpus.json, an index generated at build time from the exact rendered HTML pages. If a fact is not on the page, the model has no way to know it.
D1 FTS5 + Vectorize
Combines BM25 exact keyword search in Cloudflare D1 with 1024-dimension bge-m3 multilingual embeddings in Vectorize via reciprocal rank fusion.
Code-Level Verification
A streaming output guard parses every number generated by the model. If a figure cannot be mathematically rounded from the retrieved passages, the answer is immediately aborted.
Multi-Model Resilience
Primary routing via NYO (GLM-5.3) for natural Taglish & Filipino nuance, falling back automatically to SEA-LION v4 and Cloudflare Workers AI with zero credential leakage.
The streaming guard holds back the final words of a stream until the scale word (e.g. “thousand”, “pesos”) arrives. If the model says “₱450.2 million” but the source passage says “₱420.5 million”, the stream halts, discards the output, and returns the direct page citation instead. It is impossible for an LLM hallucination to misquote a budget figure to a citizen.
Chapter 03
Interactive 3D cartography and archival preservation
Beyond raw tables, civic understanding requires spatial and historical context. Residents look up their home by place—understanding which barangays neighbor each other and where projects are built.
MapLibre GL + OpenFreeMap
The 25 barangays are rendered in 3D, raised by population, household density, or active DPWH project count over real elevation terrain tiles. Bundled lazily as an npm package with zero third-party tracking, and gracefully falls back to a clean server-rendered SVG outline map if WebGL is unavailable.
In-Site Document Reader
When municipal websites disappear, public transparency dies. An in-site document reader proxies 232 archived documents and 156 DILG Full Disclosure filings directly from the Internet Archive and DILG servers same-origin using PDF.js and fflate, letting readers view historical Citizen's Charters without dead links.
A GitHub Actions workflow runs every Monday morning. It fetches the latest releases from DILG, DPWH, and PSA, extracts spreadsheet cells, runs the 838 reconciliation checks, and generates a plain-language diff report. If and only if a figure genuinely changed upstream, it automatically stages a Pull Request for review.
Under the hood
The tools this is built with. You do not need to know any of them to use it — open one if you are curious what it does.