Inspiration

ContinuityCI — Project Story

Inspiration

Every engineering team calculates infrastructure reliability — uptime, error budgets, failover plans — but almost nobody measures whether the knowledge behind the code is reliable. Documentation can exist and still be stale, incomplete, or trapped in one person's head. The question that started this project was simple: if the person who understands this codebase best vanished tomorrow, could anyone else actually recover it?

That's not a hypothetical for most teams. People quit, get sick, go on leave, or just get pulled onto something else mid-crisis. Bus-factor dashboards already try to flag this risk, but they stop at a risk score — they don't verify anything. I wanted to build something that behaves less like a report and more like a fire drill: point it at a real repository and get back evidence, not an opinion.

What it does

ContinuityCI reads a public GitHub repo's real signals — README clarity, CODEOWNERS, CI configuration, test coverage, license, recent activity, and commit ownership concentration — and turns them into one deterministic recovery readiness score:

$$ S = \sum_{i=1}^{7} w_i \cdot p_i \,, \qquad \sum_{i=1}^{7} w_i = 100 $$

where each $p_i$ is a pass/fail (or partial, for ownership spread) signal and $w_i$ its weight. No LLM invents the number — the score has to be reproducible and defensible, the same way a real reliability metric would be.

From there, you can simulate a specific top contributor going dark and see exactly how much of the repo's institutional knowledge was riding on them — cross-checked against CODEOWNERS when one exists.

How I built it

I scoped this deliberately small for the timeline: no backend, no database, no auth. index.html, style.css, and script.js — the browser calls the public, unauthenticated GitHub REST API directly (/repos, /contributors, /contents, /readme) and a fixed rules engine does the scoring client-side. That constraint turned out to be a feature, not just a shortcut: the tool works instantly on any public repo, with nothing to install and no API key to manage.

The build order was:

  1. Nail the scoring rubric first, on paper, before writing any UI — so the number would mean something instead of being reverse-engineered from whatever data happened to be easy to fetch.
  2. Wire up the live GitHub calls and get real signals rendering.
  3. Build the "blackout simulation" — pick a contributor, compute their share of indexed commits, cross-reference CODEOWNERS if present.
  4. Pass over the UI for clarity and pacing, so a judge could read the result in seconds without needing me to narrate it.

Challenges I ran into

The scope temptation. The original concept included an actual sandboxed drill — installing, building, and running tests inside a container to prove recoverability, not just infer it. That's the right long-term answer, but it needs a backend and a safe execution environment, and pretending I'd built that under a same-day deadline would've been a claim I couldn't back up under questioning. I cut it and said so directly in the UI instead of hiding the gap — a clearly labeled scope line held up better than a vague implication would have.

A live demo that silently died. Late in the build, the preview environment I was testing in blocked outbound network calls entirely, so every GitHub API request failed with a generic Failed to fetch — the kind of error that would have killed the demo mid-pitch with no explanation on screen. Rather than trust that judges would always be on a network that allowed the live call, I added a deterministic offline fallback: if the live API is unreachable, the app generates repeatable demo data from a hash of the repo name and labels it plainly as demo data. The same repo name always produces the same numbers, so even the fallback behaves predictably in front of an audience.

Saying "no backend" without it sounding like an excuse. It came up more than once: where are the backend files? The honest answer — there isn't one, because read-only public data doesn't need one — only works if you say it plainly instead of dodging the question. I ended up treating it as part of the pitch rather than something to explain away.

What I learned

The most useful lesson wasn't technical — it was that a scoped-down, honest MVP beats an ambitious, hand-wavy one. It was tempting to chase the full "sandboxed recovery drill" vision because it's the more impressive sentence to say out loud. But a judge asking one follow-up question exposes the gap between what you built and what you're implying you built. Naming the boundary — "this analyzes signals; it doesn't yet execute a drill" — did more for credibility than trying to imply more than the code actually does.

On the technical side: building the fallback path taught me to stop assuming a live network call will succeed just because it works on my machine — especially for anything that has to survive a live demo in front of people whose environment I don't control.

What's next

The natural next step is the piece I scoped out: a sandboxed execution service that actually runs install → test → rollback against a real snapshot of the repo, so the score reflects a verified drill instead of static signals. From there, it's a short path to a GitHub App that runs the drill automatically on a schedule or before a release, so teams get an early warning before the person who understands the payments module actually leaves.

What it does

How I built it

Challenges I ran into

Accomplishments that I'm proud of

What I learned

What's next for ContinuityCI

Built With

Share this project:

Updates