A few months ago, I became a Singapore citizen. On paper, it was a milestone; in practice, it was an administrative explosion. As a Permanent Resident, my civic digital footprint was fairly routine: filing taxes via IRAS, renewing my Re-entry Permit with ICA, occasionally checking my CPF balances, booking a polyclinic appointment through HealthHub, and using OneMap to check bus arrival times. But the citizenship journey changes everything.
Suddenly, the process is far more active. First, you check your application status and make appointments on the ICA portal for your new identity card and passport. Next, you complete the mandatory Singapore Citizen Journey onboarding. And then, a whole new world of civic admin opens up—tracking SkillsFuture credits, redeeming CDC vouchers on RedeemSG, and keeping up with HDB BTO launches.
When I sat down to list all the agency sites I needed to access to fulfill my new duties, stay informed, and handle daily life, the count came to 19 separate statutory board and national service portals. Juggling that many bookmarks and browser tabs every week—plus checking SMRT’s Twitter/X feed each morning to see if my MRT line was running smoothly—felt like an endless obstacle course.
I wanted a clean, searchable index that securely verified the links to those essential portals: ICA, ELD, IRAS, CPF, RedeemSG, SP Group, SkillsFuture, Workforce Singapore, MOM, MOH, HDB, MOE, LTA, NEA, Gov.sg, SG Journey, OneMap, HealthHub, and ActiveSG.
So I began by collecting the portals I needed to fulfill my Singaporean duties, stay informed, and enjoy the country’s privileges—all in one place.
The real story of MerlionOS isn't just the destination; it is the journey of how it got built, chunk by chunk, from a local script to a hardened agentic platform.
🎨 From External Links to a Local Dashboard
It started as a weekend hackathon project for the Hack2skill × Google Cloud GenAI Academy APAC Cohort 2. Rather than jumping straight into complex AI agent loops, I wanted to solve my own immediate frustration: building a clean, trustworthy index for the 19 essential Singapore government portals I found myself needing as a new citizen.
In my first iteration, I built a customizable drag-and-drop grid, fetching agency logos directly from official URLs to keep them authentic and up-to-date. But a directory of links only solved half my problem—what I really needed was personal situational awareness before stepping out the door. That realization drove me to build SG Hub, a real-time civic command center embedded right inside my dashboard.
I was tired of opening half a dozen separate apps and websites just to get through my routine. Before heading out or planning my day, I often found myself checking SMRT's Twitter/X feed just to see if my MRT line was delayed, looking up hyper-local rain alerts and regional PSI air quality readings, scrolling through 7 official government Telegram channels for public announcements, and monitoring 15 different community deal channels for local savings. On top of that, keeping track of upcoming HDB BTO launch tables meant manually refreshing the HDB newsroom. With SG Hub, I brought all of these scattered daily feeds together into a single, real-time civic command center right on my dashboard.
📊 Streaming Economic Insights with Google Cloud BigQuery
Beyond daily situational awareness, I wanted to understand broader macro trends affecting citizens and job seekers in Singapore. To track economic signals alongside civic services, I plugged into Google Cloud BigQuery to analyze public data.gov.sg datasets—streaming job market vacancy counts, year-over-year sector growth trends, and Ministry of Manpower (MOM) retrenchment statistics. By combining BigQuery's fast analytical queries with live API fallbacks, I could monitor top affected industries and workforce shifts directly inside MerlionOS.
💬 Breathing Life into the Chatbot
A directory of links is useful, but the ultimate vision was an assistant that could explain the rules and guide citizens through complex processes. In Singapore, nearly every statutory board operates its own isolated chatbot widget on its own website—forcing citizens to jump from portal to portal, repeating context to different agency bots. I wanted to eliminate that fragmentation with a single, unified civic Co-Pilot powered by FastAPI.
I powered the core engine with Google Gemini 2.5 Flash to leverage its native parallel tool-calling—so a single question could fan out to several statutory-board tools at once and come back as one synthesized answer, instead of the citizen hopping between each agency's own chatbot.
To ensure the assistant stays reliable under heavy traffic and prevent service disruptions during peak usage, I built a resilient fallback router: if a 429 rate limit is hit, the engine silently falls back to Gemini 3.1 Flash-Lite with Google Search Grounding, maintaining 100% uptime without sacrificing accurate web-grounded responses.
🛡️ Hardening Security: Protecting Civic Trust
When building a tool that connects citizens to government portals, security and trust are paramount. A single malicious redirect or XSS vulnerability could ruin user confidence, so I built defense-in-depth security directly into the core architecture.
On the client side, I implemented strict XSS sanitization via a custom safeURL utility that filters out dangerous protocols (javascript:, data:, vbscript:) and escapes quotes to prevent HTML breakouts. On the backend, my BeautifulSoup scraper follows redirect chains but enforces domain verification—ensuring final landing pages strictly resolve to .gov.sg or trusted public domains like healthhub.sg, wsg.sg, and cdc.gov.sg.
To safeguard users against phishing, I engineered a strict Anti-Phishing Link Policy: only official .gov.sg domains and approved trusted portals render as clickable links in chat responses. Arbitrary web search results, external blogs, or forum references are rendered as plain non-clickable text with their domain visible, so the assistant never trains users to click unverified links from a chat window. Crucially, any authentication or login URLs (singpass, login, auth, corppass) are strictly non-clickable—even on .gov.sg hosts—and carry a security shield marker advising users to open official portals directly.
singpass.gov.sg themselves and never follow login links from a chat assistant.🏆 Shortlisted in the Top 101
I submitted my initial prototype to the Hack2skill × Google Cloud GenAI Academy APAC Cohort 2 hackathon, and was thrilled when MerlionOS was shortlisted in the top 101 projects out of 1,500+ submissions.
Being shortlisted was the ultimate motivation boost. Receiving $100 in Google Cloud Platform (GCP) credits gave me the perfect opportunity to scale beyond a simple prototype and engineer MerlionOS into a comprehensive, high-fidelity platform.
flowchart TD
User["👤 Citizen User"] -->|Browser / Mobile| FE["💻 Web Frontend & Dashboard"]
FE -->|Preferences| LocalStorage["💾 LocalStorage"]
FE -->|FastAPI SSE / REST| API["🚀 FastAPI Backend (Google Cloud Run)"]
API -->|Parallel Tool Calling| Gemini["🤖 Google Gemini 2.5 Flash"]
API -->|RAG Vector Search| Embed["📚 gemini-embedding-001"]
Gemini -->|429 Rate Limit Fallback| FlashLite["⚡ Gemini 3.1 Flash-Lite + Search Grounding"]
API -->|Economic Analytics| BQ["📊 Google Cloud BigQuery"]
API -->|x-api-key| DataGov["🌐 Data.gov.sg (NEA, LTA)"]
API -->|safeURL Domain Check| GovPortals["🏛️ 93 Statutory Portals"]
API -->|Rule-Based Analysis| WhyEngines["🎯 Why Explanation Engines"]
🚀 Scaling Up: From 19 to 93 Portals & Preference Controls
With GCP credits in hand and momentum building, I decided to research just how many Singapore government portals actually existed. To my surprise, a thorough audit revealed a staggering total of 93 statutory board and agency portals—ranging from health (HPB) and monetary policy (MAS) to urban planning (URA), defense (OneNS), emergency services (SCDF), and the Judiciary.
Expanding the index fourfold meant the interface needed a major UX overhaul. Showing 93 portals all at once would overwhelm anyone, so I built personal preference settings—allowing users to hover over any card to hide it with a quick eye icon toggle. I also built a Manage Portals control panel at the top of the grid with live text search, visible/hidden filters, multi-select checkboxes, and bulk add-or-hide actions, persisting every user's custom layout directly in localStorage. This turned a massive directory into a clean, personalized civic workspace.
🔍 Intent-Based Search & Plain-English Glossary
Navigating public services often fails because citizens don't know official government terminology. To bridge this gap, I built an Intent-Based Search Bar at the top of the portal grid. Instead of requiring users to know exact agency names, it maps plain-language phrasing—like "change shop address", "top up CPF", or "renew passport"—against a curated dictionary of everyday synonyms, complete with quick-task chips. If a search query matches a live SG Hub dashboard tab (e.g., "COE premium"), the search bar intelligently surfaces a direct link straight to that live panel.
To demystify complex policy jargon, I also created an interactive Plain-English Glossary. Any of 26 common civic terms—such as CPF, SRS, COE, BTO, EHG, PSI, or SSOC—rendered anywhere inside the app gets a subtle dashed underline. Hovering on desktop or tapping on mobile displays a clear, one-sentence explanation in a tooltip. A background MutationObserver continuously scans the DOM so newly loaded panel content is annotated automatically.
🧑🤝🧑 Tailoring the Experience: Life-Stage Personas
To make 93 portals and multiple live dashboards feel immediately relevant to different users, I introduced life-stage Demo Personas (New Citizen, Young Family, Fresh Graduate, Retiree)—requiring no real Singpass or identity data.
Selecting a persona tailors the experience across three surfaces simultaneously: the Gemini Co-Pilot receives life-stage context so guidance is prioritized for that person, the portal grid surfaces a "Personalized for X" banner highlighting the most relevant agencies, and SG Hub displays recommended dashboard views—all persisted deterministically in localStorage.
🚕 Daily Mobility & Border Safety
Once the portal grid was under control, I turned my attention back to daily mobility friction. Essential metrics like latest COE bidding premiums across all 5 categories and upcoming HDB BTO launch schedules are usually buried deep inside press releases, PDFs, or separate portal sub-pages, making them hard to track at a glance. I brought live COE premiums directly into the main dashboard alongside an islandwide LTA Taxi Availability map rendered on interactive Leaflet.js paired with an opt-in "Around You" 2km geolocation lookup. Instead of blindly booking expensive ride-hailing services during peak surge hours, surfacing the live 2km taxi radius directly on action buttons lets citizens instantly gauge local taxi density and find cheaper, non-surge transit options.
To support cross-border commuters and daily safety, I integrated live ICA checkpoint delay advisories for Woodlands and Tuas congestion directly from the official ICA Newsroom, and added real-time PUB flood advisory alerts rendered as priority warning banners at the top of the feed.
🏠 Unlocking Data Insights: Housing, Wages & Wealth
To help homebuyers navigate Singapore's housing market, I built an HDB Resale Flat Price Tracker powered by BigQuery over 236,000+ transaction rows. Planning housing as a new citizen requires evaluating which neighborhoods hold long-term investment value without depreciating; querying town-by-town median prices and multi-year trend lines helps citizens judge their property budget with confidence. To give buyers future foresight, I integrated Python OLS linear regression models directly into the analytical tools to compute multi-year price forecasts. Furthermore, because buyers are often caught off guard by cumulative interest rates over a 25-year tenure, I built a deterministic HDB Loan & Concessionary Interest Calculator so citizens can calculate exact monthly installments before committing—eliminating post-payment loan surprises.
Understanding career growth in an AI-driven economy requires data transparency. I built the Occupational Wage Explorer using MOM survey data to track which new roles are emerging due to AI, identify which industries have the highest pay raises vs falls, and allow job seekers to look up wages by specific occupations to verify they are being compensated per industry standards.
For personal financial planning, I built an interactive IRAS Tax & SRS Relief Optimizer alongside live scrapers for official IRAS news and filing deadlines. Because details on CPF SA/MA top-ups and SRS contributions are spread across multiple agency pages, this tool calculates exact tax top-ups so citizens get the absolute most out of eligible tax reliefs before filing deadlines hit.
⚡ Environment Feeds & Acquiring the Data.gov.sg API Key
As I expanded environmental tracking beyond basic PSI readings to include PM2.5 forecasts, 24-hour outlooks, live temperature, humidity, wind direction, and a 5-tier UV Index, the app began making frequent live requests to NEA and data.gov.sg endpoints. Relying on unauthenticated public calls quickly led to API throttling during peak hours.
This friction drove a major infrastructure upgrade: registering an official DATA_GOV_SG_API_KEY (applied via the x-api-key header) across all data.gov.sg requests. This unblocked high-frequency environmental polling, eliminated burst-rate limits, and ensured unthrottled, zero-downtime updates across all weather tiles and government feeds (expanding Telegram broadcasts from 7 to 12 official channels).
🎯 Deterministic "Why" Insights & Structured Data
As the feature set matured, the focus shifted from feature expansion to deep architecture hardening and reliability. While AI models are great for conversation, critical financial and economic trends require 100% deterministic accuracy without hallucination.
I built three rule-based "Why" Explanation Engines that analyze existing datasets without extra network calls: cross-referencing Hiring Pressure against multi-year CAGR trends to explain vacancy acceleration vs churn, comparing COE quota and bids round-over-round to explain supply/demand price moves, and comparing flat-type price changes against islandwide figures to flag broad-based price growth versus flat-mix shifts. All three engines stay silent when data is ambiguous, avoiding forced guesses.
Architecturally, I eliminated fragile text-parsing between the backend and dashboard endpoints. Previously, job stats and COE results were computed once as Gemini text blocks and re-parsed via line splits. I refactored the data tools to return structured dictionaries directly consumed by /api/sg-hub/* endpoints, wrapping them in thin formatting helpers for Gemini, ensuring complete decoupling and zero dashboard breakage when chat prompts change.
📚 Grounding Policy Answers: RAG & gemini-embedding-001
As citizens began asking open-ended policy questions—such as "Should I buy a BTO or resale flat?", "How does CPF LIFE work?", or "Who is required to file income tax?"—I realized a simple link index wasn't enough. To answer these questions accurately without AI hallucinations, I built a Retrieval-Augmented Generation (RAG) knowledge engine (tools/knowledge.py).
I curated a 42-chunk corpus of authoritative Singapore civic facts, each tagged with official government source URLs. Using gemini-embedding-001 (768-dimensional vector embeddings), the engine embeds user queries and document chunks, retrieving relevant facts via pure-Python cosine similarity. Registered as search_knowledge_base in the Co-Pilot tool loop, the assistant retrieves and cites official source links directly instead of relying on parametric memory, degrading gracefully if the embedding API is unavailable.
To handle complex queries, I implemented Multi-Hop Agentic Chaining (up to 3 hops). When a user asks a multi-step question—such as "What tech jobs are in demand right now, what's the median salary, and what SkillsFuture courses can I take?"—Gemini 2.5 Flash executes an initial tool lookup for wage benchmarks, evaluates the returned data, and automatically chains a second tool dispatch for relevant training courses before synthesizing a final answer.
Furthermore, I added Multimodal Vision: citizens can attach a photo or screenshot of a document—an IRAS Notice of Assessment, a benefits notice, or a government form—and Gemini’s vision channel reads its content (the figures, transaction types, and deadlines) to explain what it means and cross-reference statutory caps like the S$80,000 relief limit. Crucially, it works on the substance, not the identity: as I cover in the next section, a hard privacy guardrail refuses to read NRIC, FIN, or passport numbers off an uploaded document and prompts the citizen to redact those identifiers first.
🔧 Production Hardening, Testing & Mobile UX Polish
To protect the public demo against quota exhaustion, I introduced in-memory per-IP rate limiting—a sliding window of 20 requests/minute in production, relaxed to 100 for local development—on /api/chat endpoints, safeguarding our shared Gemini free-tier quota.
To maintain complete data transparency, I added real-time data freshness badges across scraper-backed panels (ICA, IRAS, HDB, Telegram)—displaying a green "Live" pill on success or an amber "Showing last known data" pill if falling back to cache, alongside exponential backoff retries for network resilience.
On the code health front, I centralized TTL caching helpers in tools/core.py and set up pyflakes alongside automated Python and JavaScript unit tests in GitHub Actions CI gates—achieving a comprehensive test suite of 142 automated tests (136 Python + 6 JavaScript) spanning RAG vector math, cosine similarity, decision boundaries, and route-level API endpoints.
Finally, I turned to how responses feel. I upgraded chat replies to a real-time Server-Sent Events (SSE) stream (text/event-stream), so answers now arrive token-by-token behind a blinking cursor (▋) that vanishes on completion, and swapped the old bouncing-dot spinner for real-time tool status lines ("Searching the knowledge base", "Reading gov.sg pages"). On mobile, I rounded it out by fixing CSS grid descendant bugs on onboarding banners, surfacing the 2km taxi radius directly on action buttons, and adding tap-to-tooltip chart interactions.
What started as a local script for 19 portals had evolved into a resilient, fast, and secure civic co-pilot, fully containerized and deployed on Google Cloud Run.
🌐 Data-Layer Scaling: WAF-Proof BigQuery ETL & Live Agency Feeds
As traffic grew and dataset sizes expanded, live scrapers faced a major operational hurdle: government data servers like Ministry of Manpower Stats (stats.mom.gov.sg) and HDB (hdb.gov.sg) enforce strict Web Application Firewall (WAF 403) blocks against cloud datacenter IP ranges (such as GCP Cloud Run IP pools). To solve this without sacrificing live updates, I engineered a dual-cloud hosting strategy—running core web containers on Render (which bypasses datacenter IP blocks) while connecting to Google Cloud BigQuery for heavy analytical datasets.
I extended the BigQuery data architecture beyond job vacancies to cover HDB Resale Prices (sg_housing.hdb_resale_prices, indexing 236,000+ transaction rows) and the MOM Occupational Wage Survey (sg_employment.occupational_wages). Rather than requiring clients to download ~20MB CSV workbooks per request, both datasets now resolve through server-side BigQuery aggregate queries (using APPROX_QUANTILES for median price calculations and GROUP BY roll-ups for multi-year trend charts). Each query operates on a resilient 3-tier fallback pipeline (BigQuery → Live API → Committed Seed Snapshot), backed by startup pre-warm threads and multi-hour TTL memoization so first-time visitors never pay a cold-start query penalty.
To deepen real-time situational awareness, I expanded the Gov Updates hub from 12 to 22 official Telegram channels—integrating live broadcasts from the Elections Department, CPF Board, LTA, SkillsFuture, SWDA, NEA, NLB, URA, and GovTech. For statutory boards without Telegram channels, I built dedicated BeautifulSoup scrapers for CDC / RedeemSG Media Releases (scraped from cdc.gov.sg via a strict trusted-domain allowlist) and IRAS News & Updates for tax filing announcements, each rendering real-time green "Live" vs amber "Last Known Cache" data freshness status badges.
Finally, I expanded the automated test suite to 151 automated tests (145 Python + 6 JavaScript) running on every GitHub Actions push, exercising BigQuery fallbacks, WAF-proof parsers, and live scraping boundaries deterministically.
🛡️ Trust by Design: A Hard PII Guardrail & a Calmer Dashboard
As more citizens leaned on the Co-Pilot for real civic questions, one became unavoidable: what should the system refuse to do? I built the privacy guardrail in two layers. If a citizen types an NRIC, FIN, or passport number straight into the chat, a regex fast-path in tools/security.py catches it and blocks the message before it ever reaches Gemini—a deterministic, hard-coded refusal, not a model that might change its mind. On the vision side, where an uploaded image can't be pattern-matched in advance, the assistant is instructed to refuse to read identity numbers off a document and to ask the citizen to redact them first. Trust in a civic tool is earned by the guardrails citizens cannot accidentally bypass, not just by the features they can access.
On the dashboard side, SG Hub had grown into a dozen live panels—transit, weather, HDB, jobs, tax, gov updates, community deals—and not everyone wants all of them open at once. So I made every panel collapsible: tap any card's title to fold it away, or use Collapse All and Expand All to reshape the whole dashboard in one move. Someone who only follows their MRT line and the weather can tuck everything else out of sight, and it stays that way on their next visit. For a hub this dense, letting people quiet the parts they don't need was the difference between a wall of data and a dashboard they actually come back to.
🔬 Does It Actually Work? A Quiet Audit Before Submission
After weeks of rapid feature development, the last stretch before submission was about a less glamorous question: do the things I already built actually work? In one case, the honest answer was no. The plain-English glossary—those dashed-underline tooltips that quietly explain jargon like CPF, SRS, BTO, and COE as you read—had switched itself off. A single stray line of code had disabled it since launch: not one term was ever being explained, and nothing on the surface gave it away. I tracked it down, fixed it, and watched dozens of acronyms light up across the dashboard again.
The audit also showed me how many real questions the assistant still couldn't answer well. So I more than doubled its knowledge base—from 42 to 109 grounded, cited answers—covering the things people actually ask about: CPF retirement sums, HDB lease buyback, income-tax objections, the Progressive Wage Model, CareShield Life, GST Vouchers, SimplyGo, and PR and long-term-pass applications. Every answer is tied to an official .gov.sg source, so the Co-Pilot points you to the real page instead of guessing from memory—and I added a check that measures whether it actually retrieves the right source, so quality is something I can prove rather than hope for.
Finally, because the app hands out specific tax figures and CPF top-up amounts, I added plain "not financial, tax, or legal advice" notes to the relief optimizer and the Co-Pilot. It's a small thing, but being upfront about the tool's limits felt as important as any feature.
⚡ The Last Stretch: Faster, Tidier, and Open to Everyone
Some panels simply felt slow. The housing dashboard, for one, waited on three separate government sources before it showed anything. I reworked it to pull them together and to remember recent results, so pages that used to stall now snap open—and when a government feed goes down, the dashboard quietly falls back to the last good data behind a small badge instead of freezing on a spinner or dropping you on an error.
Behind the scenes, the front-end had grown into one enormous file that was getting risky to touch. I split it into eight smaller, self-contained files—one for the glossary, one for the charts, one for the chat, and so on—so I could improve a single feature confident I wasn't quietly breaking three others. I also made the dashboard fully keyboard-navigable, so it isn't a mouse-only tool.
None of this shows up on screen, but it's what lets the app keep getting better without getting more fragile. A growing test suite of 186 automated tests (180 Python + 6 JavaScript, 100% pass) runs on every change, so before anything ships I know I haven't broken a part of a tool people rely on.
🌱 Beyond the Hackathon: Evolving into an Active Platform
The hackathon submission deadline came and went, and the prototype refinement phase was officially over—but the journey was far from done. Building a tool that solved my own everyday citizen friction meant I couldn't just walk away when the competition ended. MerlionOS became an active, evolving open-source civic platform.
Operating a live civic engine in the wild brought two critical questions to the surface: What if upstream government agencies update their HTML layouts or API endpoints without notice? And what if new public datasets or statutory rules become available? Answering these required building a system that could monitor its own health and continuously expand its capabilities.
🔍 The Silent Failures: Building a Daily Health Monitoring Sentinel
Before expanding into new features, the first priority for an active platform was operational health. Building against public government websites comes with an invisible risk: statutory boards silently change their HTML layouts, update press release tables, or alter API schemas without warning. A scraper that worked perfectly yesterday can silently break today, leaving citizens with stale data while the dashboard shows no obvious error.
To catch these silent failures before citizens ever encounter them, I built an automated daily Health Monitoring Sentinel (scripts/healthcheck.py) running via GitHub Actions every morning at 09:30 SGT. It executes nine canary checks across three critical layers of the app:
- Scraper Canaries: Five live scrapers—HDB press releases, HDB BTO launch tables, ICA border traffic advisories, IRAS tax due-dates, and IRAS latest updates—run against the real web to verify that their DOM parsers still extract valid structure.
- BigQuery Analytical Datasets: Three dataset monitors check that our BigQuery tables (HDB resale prices, job vacancies by industry, and occupational wages) exist, meet row-count floors, and query
MAX(period)to measure lag against current calendar dates—asserting, for example, that HDB resale data lags by no more than 2 months and flagging when new survey editions or AI-era occupation titles are released upstream. - Policy-Rules Expiration: A dedicated freshness check monitors hand-entered civic policy parameters (like the Benefits Finder rules in
tools.eligibility). The review date of 1 March 2027 was set specifically to align with Singapore's annual National Budget Statement (announced every mid-to-late February by the Minister for Finance), ensuring new statutory tax relief caps, GST Voucher top-ups, and CPF contribution changes are audited immediately after the Budget speech.
When a check encounters broken code or stale data, the workflow doesn't just log an error in CI—it automatically opens or updates a data-monitor GitHub Issue and triggers an email alert straight to my inbox. As long as every feed stays healthy and current, the system remains quietly green.
⚡ Expanding Civic Capabilities: PDF Copilot, Localization & Life-Events
With data integrity safeguarded by the daily sentinel, I turned to expanding the platform's core capabilities:
📄 PDF Document Copilot with "Redact & Proceed" PII Protection: As citizens started asking for help analyzing official PDF documents—such as IRAS Notices of Assessment, CPF Account Statements, or HDB Eligibility Letters—blocking every NRIC-bearing document wasn't practical, because almost every official Singapore government letter carries the recipient's NRIC. To solve this safely, I engineered a server-side text extraction engine using pypdf with deterministic redact-and-proceed PII protection (tools/security.py). The server automatically scrubs NRICs, FINs, passports, phone numbers, and credit card numbers to [REDACTED] while preserving assessable income and tax figures—forwarding only the sanitized text to Gemini. Raw file bytes containing personal identifiers never reach the LLM.
🌐 4-Language Singov Localization & Elderly Accessibility Mode: Singapore is officially quadrilingual. I built a 1-click national localization engine (static/js/translations.js) supporting English, Chinese (中文), Malay (Bahasa Melayu), and Tamil (தமிழ்)—standardizing statutory terms against official Lianhe Zaobao (联合早报) and Berita Harian glossaries (e.g. 预购组屋 BTO, 缴税通知单 NOA, 定心与支援套餐 AP). For senior citizens and visually impaired users, I added a 1-click Elderly Accessibility Mode that scales base typography (16–18px), enlarges touch hit targets, and boosts contrast ratios across the dashboard.
🧭 Multi-Agency Life-Events Journeys: Navigating major life milestones—such as buying a first HDB flat, welcoming a baby, or transitioning into retirement—usually requires jumping across 4 to 5 separate statutory portals. I built the Life-Events Journeys module (tools/life_events.py and static/js/journeys.js), guiding citizens step-by-step through chronological milestones: linking HFE letters, CPF grant calculations, Baby Bonus cash gifts, and retirement sum choices in a single unified view.
🚀 The Next Frontier: Building the Civic Intelligence Co-Pilot
Looking back at how MerlionOS evolved, I realized most civic tools hit a ceiling because they stop at simply displaying information. But the real leap in value happens when an assistant moves beyond passive data display—and starts deciding, warning, and acting on a citizen's behalf. No single government agency can do this alone because each statutory board only sees its own isolated policy slice.
The true vision for MerlionOS is a unified Civic Intelligence (CI) Co-Pilot that bridges these agency silos into personal decision-making. Imagine a single eligibility engine that automatically calculates your "money left on the table"—unifying EHG housing grants, CPF accrued-interest rules, Baby Bonus cash gifts, Workfare payouts, and tax reliefs into one personal financial verdict. Instead of leaving citizens to compute grant eligibility across half a dozen websites, the CI Co-Pilot computes exact dollar opportunities based on a citizen's basic profile.
That same intelligence transforms scattered portal links into complete Life-Event Orchestrations—assembling deadlines, grants, calculators, and checklists from HDB, CPF, IRAS, and MOM into a single seamless journey for major milestones like buying a first home, welcoming a baby, transitioning into retirement, or navigating retrenchment. It turns backward-looking data into forward-looking foresight, answering questions like "Can I afford this flat?" or "Is now the right time to bid for a COE?" using real-time price medians, loan limits, and bidding trends.
By repointing automated background event pipelines directly at citizen preferences, the CI Co-Pilot turns rare site visits into an ongoing habit—delivering proactive Telegram alerts when COE premiums drop, Punggol BTO launches open, or MRT lines experience disruptions. Combined with a community ScamShield pattern checker and multilingual accessibility across Singapore's four official languages (English, 中文, Malay, Tamil), the Co-Pilot becomes not just a sidebar chatbot, but the central intelligence engine for navigating Singapore public life.
💡 Key Takeaways & Lessons Learned
Building MerlionOS taught me that civic tech becomes transformative when developers build tools to solve their own everyday friction. Here are the core lessons I took away from this journey:
- 1. Be Your Own First User: The best product insights come from experiencing the daily frustration yourself. Building to solve my own citizen onboarding friction forced me to sweat the micro-details—from mobile tap targets to 2km taxi lookups.
- 2. Pair AI Fluidity with Deterministic Rigor: Use GenAI (like Google Gemini 2.5 Flash and gemini-embedding-001) where it excels—natural conversations, RAG vector retrieval, and Search Grounding—but build rule-based deterministic engines for financial calculations and economic data where 100% accuracy is non-negotiable.
- 3. Build for Resilience First: A demo breaks when traffic spikes; a production app stays up. Layering fallback routers (Gemini Flash-Lite),
x-api-keyheaders for rate limits, GZip compression, and automated CI test gates turned a weekend hack into a reliable civic platform. - 4. Bridge the Jargon Gap: Citizens shouldn't need to speak government terminology to find help. Plain-language intent search, life-stage personas, and interactive jargon tooltips lower the barrier for everyone to access public services.
- 5. Balance PII Privacy with Practical Analysis: Hard-coded security shouldn't mean rendering a tool useless. Blocking raw image uploads where PII pixels can't be scrubbed protects citizen privacy, while server-side PDF text extraction with deterministic redact-and-proceed sanitization scrubs NRICs and passports while preserving financial figures—giving citizens useful analysis without risking identity leaks.
- 6. Verify Every Line with Automated Rigor: Never declare success without empirical proof. Maintaining a 186-test suite (180 Python + 6 JavaScript, 100% pass) alongside daily GitHub Actions canaries ensures every vector similarity calculation, decision boundary, API route, and live scraper is verified before anything ships.
Building MerlionOS taught me a simple lesson: the best tools are built when you are the first and most critical user of your own code. It's the micro-optimizations—the mobile layout alignments, the stream controllers, and the silent API fallbacks—that turn a demo into an app you trust to use every single day.
Where to find MerlionOS
🔗 Live Demo: merlion-os.onrender.com
📺 Watch Production Demo Video: youtu.be/kMhrFOA_cKI
📼 Watch Initial Prototype Demo Video: youtu.be/BOIK1FvCKEo
💻 Source Code: github.com/leshweyeewin/merlion-os