Inventory

Always-on dependency inventory.

Every install captured at the install path, not at PR time. Free, default-on, and the same data the policy engine already collects. When the next CVE drops, "are we affected?" is a search box, not a war room.

Why install-path inventory

Three things change when the inventory comes from the proxy

Captured at the install path

Chainsaw is the proxy. Every npm install, pip install, mvn dependency:resolve hits the same point. We see installs as they happen — not at PR time, not at the next dependency-graph crawl, not when CI feels like updating a lockfile.

Default-on coverage

No 'enable inventory' checkbox. From the first install through Chainsaw, the row exists: package, version, ecosystem, repo, CI job, who pulled it, when. The depgraph is built from the same evidence the policy engine already collects.

Transitive dependents, not just direct

An N-level depgraph walk (default 5, capped at 10) rolls up every transitive dependent. When a CVE drops, you don't get a list of direct importers — you get the full blast radius, with closure size and max depth on every package row.

Workflow demo

"Are we affected by CVE-XXXX?" — answered in seconds, with transitive dependents

The flow below isn't a screenshot pretending to be product. Every step maps to a real surface — /inventory, /reports/ownership, the depgraph closure widget, and the CycloneDX export — already in the dashboard.

A new CVE drops

01

CVE-2025-XXXXX lands on the OSS feed at 09:14 UTC. The CVE database refresh fires within minutes; the inventory index already knows every version of every package every team installed last quarter.

Search the inventory

02

Open /inventory, paste the CVE ID, hit return. The match index resolves package + version ranges affected by the advisory and lists them as rows. No depgraph crawl, no on-demand scan.

Walk the transitive dependents

03

Each affected package expands to show direct dependents and the closure (cycle-safe, capped at depth 10). You get repo names, CI jobs, and last-install timestamps on every row — the team to ping is in the audit trail.

Ship the answer

04

Export the affected list as CycloneDX (per-repo or org-wide), push a one-line policy that quarantines the affected versions everywhere, and the next install of the bad version fails with the CVE in the error message. Audit trail covers the whole loop.

What makes it operational

Inventory you can actually drive incident response from

Coverage floor — and the floor is honest

Inventory shows what flowed through the proxy. Unproxied installs are architecturally invisible until you reach Hardening Level 2+ (admission webhook, MDM enforcement). The /coverage page tells you what's missing, not just what's there.

Owned-by facet

Every row carries a CODEOWNERS-derived owner. When an incident hits a hundred packages, the inventory groups by owning team so you escalate to the right channel — no Slack-archaeology to find who introduced lodash 4.17.20.

Snapshots tied to incidents

When you quarantine a package, the inventory pins a snapshot: the exact set of installs at the moment of decision. Compliance evidence ships with the same export the SBOM page uses.

MCP query tool for agents

chainsaw_inventory_summary(repo?) and chainsaw_query_affected_packages(cve) are exposed to Claude Code, Cursor, and Windsurf. Agents answer 'are we affected?' the same way humans do — same data, same ACLs.

Stop firing on every advisory you read on Twitter

See your inventory in 15 minutes

Free tier captures every install through the proxy. Point one package manager at Chainsaw, run for a week, and the inventory tells you what you actually shipped.