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.

Log in or sign up for Devpost to join the conversation.