Inspiration

The Supply Chain Observatory was inspired by a string of recent high-profile supply-chain attacks — incidents where malicious or compromised dependencies cascaded into thousands of downstream applications. These events exposed how fragile the modern open-source software ecosystem truly is, and how the gap between "we have a vulnerability list" and "we know what to actually do about it" has become a serious business risk. We built this project to close that gap.

What it does

Supply Chain Observatory is a developer-focused tool that maps a software project's dependency graph, identifies known vulnerabilities (CVEs) across those dependencies, and produces an explainable, risk-prioritized report. Instead of dumping a flat list of CVEs, it answers three practical questions: Which packages are in the dependency graph? Which known vulnerabilities matter in this specific context? And what is the blast radius and recommended action for each high-risk finding? The output combines a deterministic risk score, a contextual exploitability assessment, a visual force-directed dependency graph, and a stakeholder-ready narrative for the most critical findings.

How I built it

The project is built as a Node.js application using Express for the HTTP layer, with a strict architectural separation between deterministic logic and AI-assisted reasoning:

  • A dependency graph resolver performs a bounded breadth-first traversal of the project's dependency tree, with a configurable depth limit, node cap, request timeout, response caching, and per-package failure isolation.
  • A threat analyst queries a public vulnerability database (NVD v2.0) and asks an AI model to evaluate exploitability in context — never the raw severity score on its own.
  • Core modules compute blast radius and a weighted-sum risk score using pure, deterministic JavaScript so the numbers are reproducible and auditable.
  • An advisor invokes the AI model only when the risk score crosses a threshold to generate a business-impact narrative — avoiding unnecessary AI spend.
  • The frontend is a single vanilla HTML file using a force-directed graph library via CDN — no bundler, no transpiler, no frontend framework.
  • Containerized with a slim Docker image, drop-in compatible with serverless container platforms.

The build follows an atomic, prompt-driven workflow where each module is implemented, tested, and committed independently with Conventional Commits.

Challenges I ran into

  • Bounded graph traversal — dependency graphs can explode in size. Hitting the node cap required designing a graceful truncation signal so the UI can warn the user without crashing.
  • AI vs. deterministic boundaries — It was tempting to let the AI "just compute the risk score." Resisting that and keeping scoring in pure JS was a deliberate architectural decision that made the tool auditable and reproducible.
  • Rate-limited upstream APIs — The vulnerability database has a tight rate limit without an API key. Implementing a concurrency cap and request cache was necessary to avoid being throttled mid-analysis.
  • Resilient tests — Tests that hit real network endpoints must succeed-vacuous when offline but never throw. Designing that tier of test suite took careful work.
  • Resisting framework creep — Sticking with vanilla HTML and a CDN-loaded graph library (no React, no Vite) was a constant discipline call, but it kept the UI trivially deployable.

Accomplishments that I'm proud of

  • A clean deterministic-core / AI-bounded-reasoning architecture where the AI is treated as a reasoning layer, never as the source of numeric truth.
  • A stable, documented data-contract layer between every module — explicit input/output shapes with a breaking-change commit policy.
  • Passing micro-tests across multiple tiers (shape, live smoke, resilience) using Node's built-in test runner — zero test-framework dependency.
  • A prompt-driven build workflow that lets each module be implemented as an atomic, reviewable step.
  • A single-Dockerfile, zero-build-step deployment story that's cloud-ready out of the box.

What I learned

  • The hardest part of an AI-assisted product is deciding where AI stops. Constraining the model to contextual reasoning and high-risk narratives — not scoring, not graph traversal — made the system both more trustworthy and easier to debug.
  • Determinism is a feature. When a risk score is a weighted sum in pure JS, a regulator, a CTO, and a CI bot can all reproduce the exact same number. That's worth more than a clever model.
  • Bounded everything wins. Bounded depth, bounded nodes, bounded concurrency, bounded timeouts, bounded AI calls — every guardrail made the tool more demoable and less fragile.
  • Pure JavaScript and standard libraries are enough for a serious backend. No transpiler, no framework, no bundler — and the resulting artifact is small, fast, and trivially auditable.
  • Documentation is a deliverable. Engineering guardrails, contribution policy, and a clear README aren't overhead — they're the contract that makes the project sustainable for both human and AI contributors.

What's next for Supply Chain Observatory

In execution order, scoped to one module per build step:

  • Step 1 — Ship a rate-limited vulnerability-database client and an exploitability evaluator with a concurrency cap.
  • Step 2 — Ship deterministic blast-radius traversal and explainable weighted-sum scoring.
  • Step 3 — Ship an AI-powered advisor that generates narratives only for findings above the risk threshold.
  • Step 4 — Wire the orchestrator route and launch the interactive graph visualization with risk-aware node coloring and a click-to-inspect panel.
  • Beyond the MVP — Lock down the license, add SBOM (CycloneDX) export, support additional dependency ecosystems (Python, Go), integrate with CI for PR-time risk checks, and explore team-oriented features like shared risk dashboards.

Built With

Share this project:

Updates