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

@protocolwealthos/disclosure-card

v0.3.0

Published

Machine-readable disclosure schema for AI-assisted advisory + research systems. Zod schema + dependency-free JSON Schema (Draft 2020-12) + pre-publish [VERIFY] CI gate. Framework-agnostic; zero runtime deps beyond zod.

Readme

Disclosure card — adoption guide

What: a machine-readable record that describes an AI-assisted system's model, data handling, human oversight, PII handling, audit-trail posture, and the regulatory rules its operator is operating under. Why: so an examiner, a client, or a downstream system can read the system's posture from a single canonical document rather than reverse-engineer it from marketing copy. Honest disclosure is the load-bearing artifact. Status: open standard candidate. Apache 2.0. Use it; fork it; help shape it.

This guide is for adopters — anyone running an AI-assisted advisory, research, or compliance system who needs to publish a public disclosure card. It is deliberately firm-agnostic; the only Protocol Wealth–specific values that appear here are clearly marked as synthetic example placeholders.


Install

pnpm add @protocolwealthos/disclosure-card zod
# or: npm install / yarn add — zod is a peer-grade runtime dep
import {
  type DisclosureCard,
  type HumanOversightTier,
  type PiiHandlingMode,
  parseDisclosureCard,
  safeParseDisclosureCard,
  assertNoVerifyMarkers,
  disclosureCardSchema,
  DISCLOSURE_CARD_JSON_SCHEMA,
  EXAMPLE_DISCLOSURE_CARD,
} from "@protocolwealthos/disclosure-card";

The shape

A disclosure card is a JSON object with twelve top-level fields. Required shape (TypeScript notation, simplified):

interface DisclosureCard {
  systemName: string;
  version: string;
  operator: { firm: string; crd: string };
  generatedAt: string;        // ISO-8601 datetime
  model: { provider: string; name: string; version: string };
  inferenceJurisdiction: string;
  dataRetention: {
    inputRetentionDays: number;     // 0 = not retained
    outputRetentionDays: number;
    trainingUse: boolean;           // false under most ZDR-style contracts
  };
  humanOversight: {
    tier: "human_in_the_loop" | "human_on_the_loop" | "no_human_oversight";
    clientFacingRequiresApproval: boolean;
    scope: string;
  };
  piiHandling: {
    mode: "off" | "warn" | "block" | "redact";
    layerCount: number;
  };
  knownLimitations: string[];
  regulatoryBasis: string[];        // "SEC Rule 204-2", "Reg S-P §248.30", etc.
  auditTrail: {
    rule: "SEC 204-2";              // canonical RIA books-and-records rule
    tamperEvident: boolean;
  };
}

The Zod schema (disclosureCardSchema) enforces this shape at runtime. The hand-rolled JSON Schema (DISCLOSURE_CARD_JSON_SCHEMA, Draft 2020-12) mirrors it for callers that prefer a language-neutral validator.

Field notes

  • auditTrail.rule is hard-pinned to the string "SEC 204-2". That is the books-and-records rule for SEC-registered investment advisers under the Advisers Act. It is not Rule 17a-4 (which is broker-dealer). Other RIA-relevant rules belong in regulatoryBasis[], not here. If your operator is not an RIA (e.g. a CFTC-registered CPO, a broker-dealer, an EU-regulated firm), the canonical rule is different and this schema's auditTrail.rule field will need a future minor-version extension.
  • humanOversight.tier is a small enum. The strictest tier (human_in_the_loop) describes a system where every client-facing deliverable is gated by an explicit human approval. no_human_oversight exists as an honest disclosure category for systems that genuinely operate unattended — do not publish that value unless your production wiring actually permits unattended client-facing actions.
  • piiHandling.mode uses the same vocabulary as the sibling @protocolwealthos/pii-guard package. redact is the strongest mode that still permits the model to see processed data; block refuses to send.
  • regulatoryBasis[] is a free-form citation array. Cite specific rules: "SEC Rule 204-2 (books and records)", "SEC Marketing Rule 206(4)-1", "Reg S-P §248.30(b) (safeguards)". For any citation you cannot independently verify, suffix it with the literal string " [VERIFY]". The CI gate (assertNoVerifyMarkers) refuses to let a card publish while any [VERIFY] marker remains.

How to author a card

Start from the bundled synthetic example, then change every value:

import {
  EXAMPLE_DISCLOSURE_CARD,
  parseDisclosureCard,
  assertNoVerifyMarkers,
  type DisclosureCard,
} from "@protocolwealthos/disclosure-card";

const myCard: DisclosureCard = {
  ...EXAMPLE_DISCLOSURE_CARD,
  systemName: "Acme Advisory Co-pilot",
  version: "2026.05.27",
  operator: { firm: "Acme Advisors, LLC", crd: "100000" }, // your real CRD
  generatedAt: new Date().toISOString(),
  model: {
    provider: "anthropic",
    name: "claude-sonnet-4-6",
    version: "claude-sonnet-4-6",
  },
  inferenceJurisdiction: "us_central",          // your inference region
  dataRetention: {
    inputRetentionDays: 0,                       // your contract
    outputRetentionDays: 0,
    trainingUse: false,
  },
  humanOversight: {
    tier: "human_in_the_loop",
    clientFacingRequiresApproval: true,
    scope: "All client-facing deliverables require explicit advisor approval.",
  },
  piiHandling: { mode: "redact", layerCount: 4 },
  knownLimitations: [
    // operator-supplied; CCO-reviewed; honest about what the system can't do
    "Output is informational; recommendations require advisor review.",
    "No tax advice.",
  ],
  regulatoryBasis: [
    "SEC Rule 204-2 (books and records)",
    "SEC Marketing Rule 206(4)-1",
    "Reg S-P §248.30 (safeguards)",
  ],
  auditTrail: { rule: "SEC 204-2", tamperEvident: true },
};

// Throw on shape violation (TypeScript types + runtime Zod):
parseDisclosureCard(myCard);

// Throw if any regulatoryBasis citation still carries [VERIFY] — CI gate:
assertNoVerifyMarkers(myCard);

How to validate a card you received from somewhere else

Two flavors:

import {
  parseDisclosureCard,
  safeParseDisclosureCard,
} from "@protocolwealthos/disclosure-card";

// 1. Throw on invalid input (good in a build step):
const card = parseDisclosureCard(maybeCard);

// 2. Return a result object (good when you want to render an error):
const result = safeParseDisclosureCard(maybeCard);
if (!result.success) {
  console.error("Disclosure card failed validation:", result.error.issues);
} else {
  doSomethingWith(result.data);
}

Validating without TypeScript / Zod

The package also exports a hand-rolled JSON Schema (Draft 2020-12) so adopters who don't want a TypeScript / Zod dependency can validate cards with any JSON-Schema-compliant validator (ajv, jsonschema, Pydantic in Python via a generated model, gojsonschema, etc.).

import { DISCLOSURE_CARD_JSON_SCHEMA } from "@protocolwealthos/disclosure-card";

// JSON-serializable; safe to publish at a public URL alongside the card:
console.log(JSON.stringify(DISCLOSURE_CARD_JSON_SCHEMA, null, 2));

A typical adopter pattern:

  1. Publish the card at e.g. https://acme-advisors.com/disclosures/ai-copilot.json.
  2. Publish the schema at e.g. https://acme-advisors.com/disclosures/ai-copilot.schema.json, either by serving DISCLOSURE_CARD_JSON_SCHEMA directly or by copying it to a static asset.
  3. Reference the schema from the card via the standard "$schema" field so any client that fetches the card knows where to validate it from.

The [VERIFY] pre-publish gate

The regulatoryBasis[] array is the highest-risk field on the card: a wrong citation is a stronger compliance failure than a missing one. The schema cannot tell whether "SEC Rule 999" exists; only a human can. The convention is:

  • During drafting, suffix any citation you are not 100% sure of with " [VERIFY]".
  • Before publish, run assertNoVerifyMarkers(card). It throws if any citation still carries the [VERIFY] suffix.
  • Wire assertNoVerifyMarkers into your CI pipeline at the point where the card is built into the published artifact.
// In your publish step (a script, a CI job, a pre-deploy check):
import { assertNoVerifyMarkers } from "@protocolwealthos/disclosure-card";
import { myCard } from "./card.js";

assertNoVerifyMarkers(myCard); // throws if any [VERIFY] remains; CI fails closed.

What this package does NOT do

  • Auto-generate the values. The card is operator-authored. Auto-filling the firm/CRD from a system-of-record is fine; auto-filling knownLimitations[] from a model's self-assessment is not — that's the CCO's call.
  • Enforce posture at runtime. Setting humanOversight.clientFacingRequiresApproval: true in your card does not enforce a HITL gate at the tool layer. The sibling package @protocolwealthos/shared/hitl is the runtime enforcement primitive; the card is the disclosure of that posture. Don't publish a card whose claimed posture outruns your production wiring.
  • Provide regulatory advice. Cite the rules you operate under; do not treat this schema as a substitute for your CCO's judgment on which rules apply or how.
  • Translate. All field labels + canonical enum values are English. If you serve the card in a multi-lingual surface, render the labels in your UI layer; do not localize the schema's enum values.

Versioning + back-compat policy

@protocolwealthos/disclosure-card is currently 0.x. The schema is the load-bearing surface in this package (the goal is candidate-standard status), but during the 0.x series breaking changes ARE possible. We follow this discipline:

  • Adding an optional field → minor bump.
  • Adding a required field → minor bump until 1.0, major bump after.
  • Renaming a field, removing a field, narrowing an enum → minor bump until 1.0, major bump after, with at least one deprecation cycle.
  • Hardening a constraint (e.g. tightening a regex) → patch bump if every prior valid card still validates; otherwise minor.

The version field on a specific card is the operator's version of their own card, not the schema version. The schema version lives in @protocolwealthos/disclosure-card's package.json. Adopters who want to pin both should record the package version they validated against in their build artifact alongside the card itself.


Related

License: Apache 2.0. Defensive-patent posture (USPTO #64/034,215; OIN member); the patent grant flows automatically under Apache 2.0.