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.

Built for
The people of Calatagan, Batangas — and anyone seeking public records with verified provenance
My role
Creator & Lead Maintainer
When
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

  1. 01Read verified population, income classification, and barangay statistics traced to named government sources
  2. 02Explore the 25 barangays on an interactive 3D map by population, households, or infrastructure projects
  3. 03Browse 14 quarters of municipal finances from DILG filings with 838 internal reconciliation checks, and 179 DPWH projects
  4. 04Ask the grounded AI assistant in English, Filipino, or Taglish, receiving cited answers checked in code against site figures
  5. 05Inspect 232 archived public documents and 156 Full Disclosure filings in the in-site document reader
  6. 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.

  1. STAGE 01Source

    Primary Government Sources

    PSA OpenSTAT, DILG SRE, DPWH contracts & Official Gazette

  2. STAGE 02Zod Schema

    Typed Sourced<T> Envelope

    Structured metadata with cell-level audit citations and tier labels

  3. STAGE 03Vitest Gate

    275 Automated CI Guardrails

    838 arithmetic checks; build fails on unverified claims or future dates

  4. STAGE 04Astro Build

    Zero-JS Static Delivery

    Astro compiles fast, immutable HTML; syncs /ask/corpus.json

Interactive Architecture

The 4-Tier Civic Readiness Model

Verified primary sourceRule: Published directly, zero caveats

Requires verifiable government issuance or database key. Rechecked quarterly.

Tracked Records in this tier:

  • 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)
Technical detail · why negative tests matter for civic datasets

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.

Hybrid Retrieval

D1 FTS5 + Vectorize

Combines BM25 exact keyword search in Cloudflare D1 with 1024-dimension bge-m3 multilingual embeddings in Vectorize via reciprocal rank fusion.

Numeric Guard

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.

Language Model Chain

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.

Technical detail · the streaming numeric guardrail (worker/src/numbers.ts)

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.

3D Barangay Map

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.

Preservation Engine

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.

Technical detail · automated weekly drift detection (scripts/data-report.mjs)

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.

If you're considering working together

How a project actually goes

No jargon, no long contract to decode, and no stage where you are asked to approve something you cannot picture.

  1. 01

    We talk about the problem

    Not the software — the problem. What is slow, what gets forgotten, what people keep having to redo by hand. Usually one call is enough to see the shape of it.

  2. 02

    I write down what I heard

    In plain language, before any building starts, so you can correct me while it is still cheap to correct. You approve it or you don't.

  3. 03

    You see it early and often

    Working pieces, not screenshots or promises. If something is wrong, you say so while there is still time to change it.

  4. 04

    It goes live and stays supported

    Hosting, domain and setup handled. The Valley O'Ville site has been running since 2023 — I don't disappear after launch.

Have something in mind?

Tell me what is not working. If I'm not the right person for it, I'll say so and point you somewhere better.