← Selected work

Developer infrastructure / Personal project

TriageCIA red build is a symptom. Find the cause.

A self-hosted service that turns test history into explainable flaky-test and regression signals—so developers can investigate the right failure.

TypeScriptNode.jsSQLite WALDockerGitHub Actions
375,000observations · three local stress runs
12,261/smedian observation throughput
0processing failures in those runs

01 / The problem

Why I built it

A failed CI test can mean a broken product, an intermittent test, or infrastructure noise. Retrying until the build turns green hides that distinction. TriageCI retains the evidence across runs and groups recurring failure signatures.

02 / My contribution

What I engineered

I built the ingestion API, report validation, duplicate-delivery protection, bounded worker queue, transactional analyzer, dashboard, and JUnit adapter. The result is an inspectable tool with a complete path from CI report to diagnosis.

03 / Interactive demonstration

See the behavior, not just the claim.

Run sample histories through the actual classification logic, extracted for the browser. No GitHub account or credentials needed.

TriageCIActual analyzer · sample data

ONE RED BUILD. DIFFERENT CAUSES.

Find the signal in the failures.

checkout / applies discount, latest outcomes: passed, passed, failed, passed, failed, passed, failed, passed

Repeated pass/fail transitions indicate an intermittent failure pattern.

Observations
8
Transitions
6
Failure streak
0

Browser extraction of the classification logic. Uses the latest 64 sample observations; displays the last 16. Selecting a test resets its sample. The full-service same-commit evidence, ingestion, storage, and clustering are not running here.

04 / Architecture

Follow the data.

  1. 01GitHub / JUnit reports
  2. 02Authentication + idempotency
  3. 03Bounded worker queue
  4. 04SQLite WAL + analyzer
  5. 05Dashboard / API / metrics

SQLite WAL instead of a distributed data stack

A single-node tool should be easy to deploy and reason about. WAL lets readers coexist with the transactional writer, while materialized statistics keep the dashboard queries simple. Write serialization is an explicit scaling boundary.

Bounded admission instead of unlimited buffering

The API returns 202 after admitting a report and 429 when the queue is saturated. A separate delivery record exposes completion. Accepting a request is deliberately not described as completing its analysis.

An explainable classifier instead of a black box

Pass/fail diversity, transitions, failure streaks, sample size, and same-commit reruns contribute evidence. The service reports a classification; it does not automatically quarantine tests or claim to identify every root cause.

Content-bound replay protection

An idempotency key is bound to the report digest. A matching replay is deduplicated across restarts; different content under the same key is rejected with 409 rather than quietly overwriting history.

05 / Verification

Results you can inspect.

Three clean-database runs each sent 5,000 reports of 25 tests, using 64 clients and four workers. All five seeded flaky tests and three seeded regressions were surfaced in each run; all 300 replayed deliveries were deduplicated.

Measurement context

Recorded environment: Node.js 24.12.0, Windows 11, Intel Core i7-13700K, 32 GB RAM, local loopback, SQLite on local storage. Median throughput was 490.47 reports/s, or 12,261.64 observations/s. The headline truncates to 12,261.

HTTP p95 measures admission, not completed processing. The end-to-end throughput waits for persisted completion. These are synthetic local workloads, not production capacity, customer adoption, or independently audited results.

Evidence pinned to repository revision 244d51eee8b5. Recorded results are from the linked project evidence, not new benchmark runs for this website.

06 / Engineering boundaries

What I would harden next

The queue is in process, so a crash can leave admitted work incomplete. The ledger makes this visible, but automatic leasing and retry need a durable broker. The current design is single-node; multi-node scale would require a different queue and persistence architecture.

07 / Next iteration

Where it goes from here

The next useful validation is a small opt-in pilot with a real team: compare classifications with developer judgment, inspect false positives, and measure investigation effort. No external adoption or time-savings claim is made yet.

Eesher Janda / Software engineering

Let’s build something useful.

Seeking software engineering internships and co-ops.