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

@typedstandards/produce-core

v0.4.0

Published

Portable, I/O-free producer core for Typed Standards record packages — format-neutral envelope and attestation assembly, the Ed25519ph signing mechanism, and pure external-proof codecs, sharing one canonicalization/hash chain with @typedstandards/verify-c

Readme

@typedstandards/produce-core

The portable, I/O-free producer core for Typed Standards record packages — envelope and attestation assembly (spec §8.1, §8.12), the Ed25519ph signing mechanism (§8.3.1), pure external-proof codecs (RFC 3161 TimeStampReq, Rekor hashedrekord), the §8.8.1 commitment view, and generic PROV-O helpers. Its verification counterpart is @typedstandards/verify-core — a load-bearing runtime dependency (joined only by @noble/curves, the curve suite both packages use): producer and verifier share a single canonicalization/hash implementation, so both sides compute one envelope hash by construction.

Extracted from the reference application's producer path (Q59, resolved via option (a)): an independent implementation can emit packages that verify under spec §9.2 without depending on the reference application. A byte-golden fixture suite in this package pins the extraction to the reference implementation's exact output.

The format/domain line

This core knows the format: envelope shapes, key order, conditional-spread byte discipline, the §8.2 dual-chain hashing rules, and the signing mechanism. Everything domain-shaped — capture vocabulary, profile derivations, source registries, provenance graph walking — is the caller's: derived values arrive as explicit inputs (dataSources, provenance, producerProfile, extensions, …) and the core assembles them under the reference byte rules.

The verify-core primitives a producer-side layer consumes (sha256Hex, isBlobRef, the canonicalization-rule URIs, the Q32 captureMethod vocabulary table) are re-exported here, so such a layer needs a single declared dependency.

Vocabulary (2026-08-19 settlement)

The artifact this core builds is a record package. "Evidence" is retired from the artifact/infrastructure brand role — a signed record shows how an answer was produced, not that it is correct — and retained only for the epistemic Question/Evidence/Claim role (spec §6.3, Appendix J).

Nothing existing breaks:

| Prior-era name | Canonical name | Status | |---|---|---| | EvidencePackage (type) | RecordPackage | EvidencePackage remains a deprecated type alias of RecordPackage — interchangeable in every position; removed no earlier than the next MAJOR. | | verifyEvidence (verify-core) | verifyRecord | Still exported as a deprecated alias of the same function object. |

buildCommitmentView emits the §8.8.1 version field under its settlement-era key, protocolVersion. Views published before a producer adopted this version carry the same value under evidenceProtocolVersion, and that key stays valid forever — it is frozen inside already-signed artifacts, where rewriting it would invalidate the signature. Conformant verifiers accept either key, so a mixed corpus verifies uniformly.

Install

npm install @typedstandards/produce-core

I/O-free contract

This package depends on no Node built-ins and performs no I/O: no network, no filesystem, no environment reads, no clock, no RNG (an ESLint no-restricted-imports rule plus a browser-safety/determinism test enforce it). It runs unchanged in a browser, on the edge, and in Node.

  • Determinism inputs are caller-suppliedpackageId, createdAt, and signingKeyId are arguments, which is what makes byte-golden testing (and reproducible pipelines) possible.
  • Key custody is the caller'ssignEnvelopeHash takes the private key (raw 32-byte seed or PKCS8 DER) and the kid as arguments. There is no environment probe and no default identity.
  • Not signing is first-classbuildEnvelope returns a complete package plus its envelope hash with no signature; nothing in this package labels an unsigned result sealed/public or anything else.
  • Submission stays caller-side — the RFC 3161 / Rekor codecs build request bytes and parse responses; POSTing them to a TSA or transparency log is the caller's I/O.

Independent-producer walkthrough

A prospective adopter can emit a conformant, verifiable package with the two published packages alone — no reference-application imports. The sequence below builds a package, signs it with a locally held key, carries the proofs in a §8.8.1 commitment view, and passes verify-core's §9.2 checks offline.

import crypto from 'node:crypto'; // the CALLER's key custody, outside the core
import {
  buildEnvelope,
  signEnvelopeHash,
  buildCommitmentView,
} from '@typedstandards/produce-core';
import { verifyRecord } from '@typedstandards/verify-core';

// 1. The adopter's key and identity (custody is yours; the core never reads
//    an environment or embeds a default).
const seed = crypto.randomBytes(32); // Ed25519 seed
const kid = 'adopter:key-2026-07';
const signer = {
  bindingTier: 'organization',
  identifier: 'adopter:example-publisher',
  displayName: 'Example Publisher',
};

// 2. Assemble the envelope from your pipeline's data. Derived values
//    (dataSources, provenance, extensions, …) are yours to compute; the core
//    assembles them under the reference byte rules and hashes the result.
const { pkg, envelopeHash } = buildEnvelope({
  packageId: crypto.randomUUID(),
  createdAt: new Date().toISOString(),
  signingKeyId: kid,
  prompt: 'How many service requests were filed last year?',
  promptVisibility: 'full_text',
  // A rejected call stays a rejected call: an entry MAY carry `failed: true`
  // and a short `failureKind` label, and their absence means only that the
  // call was not recorded as failed.
  queries: [
    {
      tool: 'get_data',
      operationType: 'query',
      arguments: { select: 'count(*)', dataset_id: 'abcd-1234' },
      datasetId: 'abcd-1234',
      portal: 'data.example.gov',
    },
  ],
  dataSources: [
    {
      sourceId: 'open-data-portal',
      catalogType: 'catalog',
      portalUrl: 'https://data.example.gov',
      datasetId: 'abcd-1234',
      accessTimestamp: new Date().toISOString(),
    },
  ],
  cost: { promptTokens: 100, completionTokens: 20, totalTokens: 120, model: 'example/model-1' },
  skillMetadata: {},
  output: 'Around 400,000.',
  trace: { resourceSpans: [] },
  captureMethod: 'chat-flow-stream',
  producerProfile: 'ai-assisted-analysis/example-adopter',
  type: 'content/analysis/v1',
  signer,
});

// 3. Sign — or don't. Skipping this step leaves a complete unsigned package.
const signed = signEnvelopeHash(envelopeHash, seed, kid);

// 4. Publish your trust registry (an HTTPS JSON document you host) and carry
//    the proofs in the commitment view.
const registry = {
  keys: [
    {
      kid,
      publicKey: signed.publicKey,
      status: 'active',
      activatedAt: new Date().toISOString(),
      deprecatedAt: null,
      revokedAt: null,
      signerIdentity: signer,
    },
  ],
};
const sidecar = buildCommitmentView({
  packageHash: envelopeHash,
  signature: { ...signed },
  // Required, and never defaulted: the view is what a verifier resolves, so
  // the core will not assert a disclosure state you did not supply.
  visibility: 'public',
  captureMethod: 'chat-flow-stream',
  producerProfile: pkg.producerProfile,
  type: pkg.type,
  signer: pkg.signer,
  contentHash: pkg.contentHash,
  contentCanonicalization: pkg.contentCanonicalization,
  trustRegistryUrl: 'https://your-host.example/.well-known/typed-publisher.json',
});

// 5. Verify — any consumer runs the same §9.2 checks offline.
const result = await verifyRecord(
  { package: JSON.parse(JSON.stringify(pkg)), packageHash: sidecar.packageHash, signature: sidecar.signature },
  { registry },
);
console.log(result.hashMatch, result.signatureValid, result.keyTrust.status);
// -> true true active

Optional external proofs use the pure codecs the same way: POST buildTimestampRequest(envelopeHash) to your TSA and store the token; POST JSON.stringify(buildRekorProposal(envelopeHash, signed.signature, signed.publicKey)) to a transparency log and keep parseRekorResponse's fields in the commitment view so inclusion verifies offline.

Non-goals

  • No key custody — keys are arguments, never stored, generated, or probed.
  • No storage — nothing is persisted; the caller owns rows, blobs, hosting.
  • No submission I/O — no fetch anywhere; TSA/transparency-log submission is caller-side (the codecs are pure request/response builders/parsers).
  • No domain vocabulary — profile labels, capture methods, and namespaces are opaque strings/values here; their vocabularies live in profiles (spec §8.6) and in the caller's domain layer.

License

MIT © Nathan Storey