npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cvd-policy/core

v0.4.0

Published

Reference implementation of the CVD Policy Format: validation, generation, evaluation, explanation.

Readme

@cvd-policy/core

Reference implementation of the CVD Policy Format. Framework-free, works in the browser and in Node. Every published schema is embedded at build time, so nothing is fetched at runtime.

Format versions 0.1 and 0.2 are both supported: a document is validated against the version it declares, because a released version never changes.

npm i @cvd-policy/core
import { validate, validateReport, generate, evaluate, explain } from "@cvd-policy/core";

const result = validate(JSON.parse(raw));
// { valid: false, issues: [{ level: "error", code: "EXPIRES_PAST", path: "/expires", … }] }

const decision = evaluate(doc, "automated_scanning", "api.example.com");
// { allowed: true, reason: "RULE_ALLOWED", conditions: { max_requests_per_second: 5 } }

const report = validateReport(JSON.parse(incoming));
// { valid: true, issues: [{ level: "info", code: "REPORT_NO_REPRODUCTION", … }] }

What each function does

| Function | Purpose | | -------------------- | ------------------------------------------------------------------ | | validate | Schema for the declared version, plus the semantic rules | | validateReport | An incoming report against the report-0.1 profile | | validateText | Same, for unparsed JSON text | | generate | Builds a document from wizard answers | | answersFrom | Reads a document back into answers, for editing | | evaluate | Decides whether an activity against a target is permitted | | scopeStateFor | Resolves whether a target is in scope | | explain | Display sections, no rating of any kind | | securityTxtLines | The lines to add to a security.txt | | securityTxt | A complete security.txt, for a host that has none yet | | mergeSecurityTxt | Sets CVD-Policy in an existing file, leaving the rest alone | | securityTxtCanonical | Where the security.txt belongs, from canonical | | parseSecurityTxt | Parses a security.txt into fields |

Authority: which hosts a document may speak for

Anyone can list someone else's host in scope or in a rule's conditions.targets, so a claim is not permission. A document has authority over a host when the host is at or under canonical, or when that host pointed at the document itself — which only its owner can arrange.

// No context: authority comes from canonical alone.
evaluate(doc, "manual_testing", "bank.example.com");
// -> { allowed: false, reason: "FOREIGN_TARGET" }   for a doc on blog.example.com

// The host's own security.txt or well-known path produced this document.
evaluate(doc, "manual_testing", "bank.example.com", { discoveredFor: "bank.example.com" });
// -> { allowed: true, ... }

Pass discoveredFor with the host whose discovery produced the document, and never reuse it for another host. This blocks a policy planted on a taken-over subdomain while still supporting one document served centrally, or hosted by a provider for a customer. foreignTargetConfirmed: true remains for the case where you fetched the target's own policy and it agrees.

validate applies the same rule, so its SCOPE_FOREIGN_HOST and TESTING_TARGET_FOREIGN warnings predict what evaluators will do.

Incoming reports

Since format version 0.2 a policy may carry report_requirements.intake: an endpoint that accepts a structured report, the schema it expects, and whether anonymous submission is allowed. validateReport checks a report against the report-0.1 profile.

Three fields are required — title, target, description. Missing steps to reproduce or impact produce info, never an error, because they are not always available and a missing field must never stop someone from reporting. Claimed exploitation without evidence is an error, and exploitation is a three-state value so that an unticked box is never stored as a denial.

This library never sends anything. intake says where a report may go; deciding to send it is a judgement a person makes, and the specification requires the receiving host to be shown first.

Messages are codes, not text

Issues carry a stable code (EXPIRES_PAST, POSTURE_CONTRADICTION, …), a JSON Pointer path and a message that is a translation key. Rendering happens in the consuming application, so the library ships no localised strings.

Licence

Apache-2.0. The specification and schema it implements are CC0-1.0.