16-Agent AI Layer for a Metro Rail Incident System by Omar Shamma16-Agent AI Layer for a Metro Rail Incident System by Omar Shamma

16-Agent AI Layer for a Metro Rail Incident System

Omar Shamma

Omar Shamma

The problem

Ho Chi Minh City Metro Line 1 runs VMMS, a Vietnamese/English system that tracks incidents, FRACAS safety workflows, preventive maintenance, inventory, and asset health across the line. The data was all there — incident logs, PM schedules, stock ledgers, hazard reports — but nobody had time to look back over it. Staff could see the current state of an asset or an incident queue, but nothing surfaced patterns: which failure modes kept recurring, which PM tasks weren't actually preventing failures, which stations were hotspots, which safety hazards were trending.
The system had to work bilingually, with every AI-generated string correct in both Vietnamese and English, not just machine-translated. Every agent had to respect the same per-user view-scope model as the rest of the app — a technician can't see another department's incidents just because an AI agent forgot to filter. The underlying data included FRACAS safety findings and root-cause narratives, so leaking scope was a real safety and liability issue, not a cosmetic one. And this was a live transit maintenance system, not a demo — agents had to compile clean, query the real SQL Server schema without column-name bugs, and be reviewed for whether the analysis was actually sensible before anything shipped.

What I built

VMMS splits its AI layer into two tracks per module: a "Now" agent that reads current state, and a "Rear-view" agent that looks back over history for patterns and recommendations. I built all seven Rear-view agents — Failure-Pattern Analyst (incidents), Fleet Reliability Analyst (assets), PM Effectiveness Analyst (preventive maintenance), Consumption and Demand Analyst (inventory), Hotspot Analyst (stations), Safety and Hazard Trend Analyst (RAMS/safety), and Monthly Performance Review (whole-system). My colleague built the seven "Now" agents on the same shared foundation.
Past that first phase, I also built out further batches of agents on top of the same runtime — the project brief documents an agent-factory workflow for producing new rear-view agents at scale, each one going through a fixed pipeline of automated checks before being registered into the AI hub. I designed and own the shared TypeScript agent runtime that every one of the 16 agents — mine and my colleague's — is built on. On top of the agent work, I ran a full security and code audit of the wider VMMS application: 309 TypeScript files and 32 SQL migrations, covering access control, session handling, dependency CVEs, and data-integrity races.

How it works

Each agent is one self-contained folder with four files: an analyst module that defines the SQL retrieval and scope logic, a server action, a page, and a client component. They all import from the shared runtime rather than reimplementing it. The runtime does permission-scoped SQL retrieval before any data reaches the model — the query is filtered by the user's view scope and role at the database layer, so a technician's agent request can only ever pull rows that technician is already allowed to see. The model never gets a chance to leak scope because it never receives out-of-scope rows in the first place.
Agent output is constrained to a JSON schema with additionalProperties disabled and all fields required, so the UI renders structured findings instead of parsing free text, and a malformed model response fails loudly instead of rendering garbage. Results are cached per scope key so re-running an agent for the same user and filter combination doesn't re-hit the model, and long-running analyses stream so a multi-minute pattern-analysis job stays reliable in the browser instead of timing out.
Every agent that gets built passes four executable checks before it's trusted: the four files exist and are non-empty, the TypeScript compiles clean, the agent's SQL runs against the real schema with zero invalid-column errors, and its route resolves instead of 404ing. Registration into the shared AI hub list and global stylesheet is done serially by a single reviewer, never by whoever's building an individual agent, because those are the only shared-state files and concurrent edits to them had already caused a real collision earlier in the project.
The security audit followed the same rear-view instinct: a multi-lane review of the full codebase, with every finding adversarially re-checked before it was reported — three initial findings were refuted and dropped rather than padded into the report. It confirmed the core application was already disciplined: parameterized SQL throughout, bcrypt password hashing, a working brute-force login throttle, and correct server-side scope enforcement on incident and safety reads. Where it did find gaps, I documented each one with a concrete fix and a suggested remediation order and handed it to the system owner privately. I don't publish the security specifics of a live transit system, and I'd treat your codebase the same way.

Outcome

The rear-view agent layer gave VMMS a look-back capability the current-state screens never had: pattern analysis across incident history, PM effectiveness, station hotspots, and safety-hazard trends, in both Vietnamese and English, scoped correctly to every viewer. The agent-factory pipeline let new agents be produced and verified against the real schema and a live route before anyone trusted them, catching schema-mismatch bugs mechanically instead of in production. The security audit gave the system owner a prioritized, evidence-backed list of what to fix before go-live, ordered by severity.

Stack

TypeScript, Next.js, React, SQL Server (mssql), Docker, Claude API (Anthropic), JSON Schema validation, bcrypt, JWT, Git
Like this project

Posted Aug 5, 2026

Built 11 of 16 agents plus the shared TypeScript runtime for a bilingual rail incident system. Permission-scoped SQL retrieval, schema-validated JSON output.