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.
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.
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.
- 01GitHub / JUnit reports
- 02Authentication + idempotency
- 03Bounded worker queue
- 04SQLite WAL + analyzer
- 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.
- Workload, hardware & three-run results
- Design decisions
- Analyzer implementation
- Stress harness
- Security boundaries
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.