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

@takk/bayesbelief

v1.0.0

Published

BayesBelief: hierarchical Bayes for multi-tenant federated learning without violating privacy. Partial pooling shrinks each tenant toward a calibrated global prior with strength proportional to its sample size, so small and brand-new tenants borrow streng

Readme

BayesBelief

status: stable license version node tests coverage runtime deps

Star History Chart

Universal, zero-runtime-dependency NPM library and CLI for hierarchical Bayes across a fleet of tenants. Partial pooling lets a multi-tenant system learn from every tenant at once, lifting small and brand-new tenants out of the cold start with what the fleet already knows, while only aggregated sufficient statistics ever cross the tenant boundary, for Massive Intelligence (IM) systems.

BayesBelief is the shared-learning layer for multi-tenant Massive Intelligence (IM). A platform serves many tenants: a large tenant has enough data to estimate its own metrics well, a small or newly-onboarded tenant does not. Estimating each tenant in isolation gives noisy, overconfident numbers for the small ones; collapsing everyone into a single global number ignores that tenants genuinely differ. Hierarchical Bayes resolves the dilemma with partial pooling: it fits a global prior across the fleet and pulls each tenant's estimate toward it with strength inversely proportional to how much data that tenant holds. A data-rich tenant keeps its own estimate, a thin tenant borrows the fleet's, and a brand-new tenant cold-starts from the global prior on day one. The global prior is fit by empirical Bayes from sufficient statistics alone, so no tenant's raw observations ever leave the tenant boundary.

Core promise: zero required runtime dependencies, two-line setup, exact closed-form conjugate posteriors with O(1) updates, empirical-Bayes partial pooling that needs no tuning, a privacy boundary where only aggregated sufficient statistics ever cross, a node-free core that runs in Node, edge runtimes, and the browser, ESM plus CJS dual distribution, and a framework-agnostic tool adapter that binds to any MCP server or tool-calling backend with no hard dependency.


Why BayesBelief

Pooling beliefs across a tenant fleet is an estimation problem with a privacy constraint. You want every tenant, including the ones with almost no data, to benefit from what the whole fleet has learned, without ever moving a tenant's raw observations across the boundary that separates it from its neighbours. The two reflexive answers both fail. Estimating each tenant from its own data alone (no pooling) gives wild, overconfident numbers for the many small tenants, a tenant that converted on two of two trials is not converting at 100 percent. Collapsing the fleet into one global rate (complete pooling) throws away the real differences between tenants. BayesBelief uses the correct primitive: a global prior fit across the fleet by empirical Bayes, and a per-tenant posterior that blends the tenant's own evidence with that prior in exactly the proportion the data justify.

What sets it apart from estimating tenants one at a time:

  • Pools partially, not all-or-nothing. Each tenant's posterior mean is a weighted blend of its own rate and the fleet's, with weight equal to the tenant's effective sample size against the prior strength. The pull toward the fleet (shrinkage) is reported for every tenant, so you can see exactly how much was borrowed.
  • Solves cold start by construction. A tenant with zero observations returns the global prior as its starting belief, not a degenerate 0/0 and not a hand-picked default. A new tenant inherits the fleet's knowledge on day one and sharpens as its own data arrives.
  • Keeps raw data inside the tenant. The only thing that crosses the tenant boundary is aggregated sufficient statistics, successes and trials for a rate, count, sum, and sum of squares for a mean, never a raw observation. This is data minimisation by construction, aligned with GDPR and the EU AI Act, not a bolt-on.
  • Refuses to leak a small fleet. A minimum-tenant guard declines to expose a global prior fit from too few tenants, so one tenant's statistics cannot be reverse-engineered from the shared prior. Too few tenants raises a typed PRIVACY error rather than returning a number.
  • Fits the prior with no tuning. The global hyperprior is estimated by empirical Bayes, a method of moments for the Beta-Binomial family and DerSimonian-Laird for the Normal-Normal family, directly from the tenants' sufficient statistics. No hyperparameters to set.
  • Handles rates and continuous metrics. A Beta-Binomial hierarchy for rate metrics in [0, 1], conversion, success, acceptance, and a Normal-Normal hierarchy for unbounded continuous means, latency, score, revenue per account.
  • Measures its own calibration. Credible intervals are only trustworthy if they cover the truth at their nominal rate, so calibration is measured by simulation, drawing tenants from a known global, fitting the hierarchy, and counting coverage, not asserted.
  • Proves what was learned. A tamper-evident SHA-256 hash-chained audit trail of pooling updates and decisions, the evidence a review asks for when a pooled belief is questioned.

Install

pnpm add @takk/bayesbelief
# or: npm install @takk/bayesbelief
# or: yarn add @takk/bayesbelief
# or: bun add @takk/bayesbelief

The core has zero required runtime dependencies. Every @takk sibling is an optional peer; install only what you compose with.


Quickstart

import { BetaHierarchy } from "@takk/bayesbelief";

// A fleet of tenants, each contributing only its sufficient statistics (successes / trials).
const fleet = new BetaHierarchy();
fleet.observe("acme", { successes: 280, trials: 500 });   // rate 0.56, abundant data
fleet.observe("globex", { successes: 329, trials: 470 }); // rate 0.70
fleet.observe("initech", { successes: 74, trials: 90 });  // rate 0.82
fleet.observe("umbrella", { successes: 920, trials: 1000 }); // rate 0.92

// A tenant that signed up a minute ago, with no events yet, cold-starts from the fleet.
const newcomer = fleet.posterior("just-onboarded");
console.log(newcomer.mean, newcomer.credibleInterval, newcomer.source);
// the global mean, a wide credible interval, source "cold-start"

// After its first batch, its estimate moves off the prior toward its own data.
fleet.observe("just-onboarded", { successes: 9, trials: 10 });
const warmed = fleet.posterior("just-onboarded");
console.log(warmed.mean, warmed.shrinkage); // moved toward 0.9; shrinkage in [0, 1]

observe folds a tenant's sufficient statistics in. posterior returns that tenant's partially-pooled mean, credible interval, and shrinkage, fitting the global prior lazily on first use. A tenant the fleet has never seen cold-starts from the global prior.


Pool the whole fleet at once

import { BetaHierarchy, shrinkageProfile } from "@takk/bayesbelief";

const fleet = new BetaHierarchy();
fleet.observe("flagship", { successes: 8200, trials: 10000 }); // abundant data
fleet.observe("midmarket", { successes: 78, trials: 100 });
fleet.observe("startup", { successes: 9, trials: 10 });
fleet.observe("pilot", { successes: 2, trials: 2 });           // two lucky trials

const report = fleet.pool();        // fit the global prior, return every tenant's pooled posterior
report.globalPrior.mean;            // the fleet-wide rate
report.coldStartTenants;            // how many tenants had no data
shrinkageProfile(report);           // observations -> shrinkage, the partial-pooling diagnostic

pool fits the global prior once and returns a posterior for every tenant, plus how many cold-started. The pilot tenant reported a raw rate of 1.0 from two trials; partial pooling refuses that overconfident estimate and reports something sane, while flagship is barely moved.


Continuous metrics, the Normal hierarchy

Not every fleet metric is a rate. Average latency, a quality score, or revenue per account is continuous, so BayesBelief offers a Normal-Normal hierarchy that pools tenant means the same way. Each tenant ships only its count, sum, and sum of squares.

import { NormalHierarchy } from "@takk/bayesbelief";

const fleet = new NormalHierarchy({ credibleMass: 0.9 });
fleet.observe("enterprise", { count: 400, sum: 2803, sumSquares: 20069 }); // data-rich
fleet.observe("team-a", { count: 3, sum: 27.6, sumSquares: 254.6 });
fleet.observe("team-b", { count: 2, sum: 11.1, sumSquares: 62.61 });

const pooled = fleet.posterior("team-a"); // partially-pooled mean, 90% CI, shrinkage
const fresh = fleet.posterior("team-c");  // no data: cold-starts at the global mean

For continuous means use the Normal hierarchy; the Beta hierarchy is for rates confined to [0, 1].


The privacy boundary

The only thing that crosses between tenants is aggregated sufficient statistics, never raw observations, and the global prior is refused when too few tenants contribute.

import { aggregateBetaStats, BetaHierarchy } from "@takk/bayesbelief";

// Each tenant computes its sufficient statistics locally; only these integers leave the tenant.
aggregateBetaStats([
  { successes: 318, trials: 400 },
  { successes: 905, trials: 1100 },
]); // { successes: 1223, trials: 1500 }, fleet-level only, no raw events

const fleet = new BetaHierarchy({ minTenants: 3 });
fleet.observe("solo", { successes: 50, trials: 60 });
fleet.globalPrior(); // throws a typed PRIVACY error: too few tenants to expose a prior

This is data minimisation and aggregation by construction, aligned with GDPR and the EU AI Act. It is not a formal differential-privacy guarantee; it is the boundary discipline that keeps one tenant's data from being reverse-engineered out of a shared prior.


Entry points

Twelve subpath exports, each importable on its own. The core is node-free; only node touches a Node built-in.

| Import | What it gives you | |---|---| | @takk/bayesbelief | The full toolkit barrel: both hierarchies, pooling, privacy, audit, calibration, and the adapter. | | @takk/bayesbelief/hierarchy | BetaHierarchy and NormalHierarchy, the facades most callers use. | | @takk/bayesbelief/beta | The Beta-Binomial primitives: moments, credible interval, conjugate posterior, accumulator. | | @takk/bayesbelief/normal | The Normal-Normal primitives: a streaming sufficient-statistics accumulator and interval. | | @takk/bayesbelief/pooling | Empirical-Bayes global-prior fit and the shrinkage weights for both families. | | @takk/bayesbelief/privacy | Sufficient-statistics aggregation and the minimum-tenant guard. | | @takk/bayesbelief/tenant | The branded TenantId and its guard. | | @takk/bayesbelief/calibration | Simulation-measured coverage and the shrinkage profile diagnostic. | | @takk/bayesbelief/adapter | The framework-agnostic tool descriptor and JSON-safe handler. | | @takk/bayesbelief/audit | Append-only SHA-256 hash-chained audit log of pooling updates, via Web Crypto. | | @takk/bayesbelief/node | JSON and CSV loaders for per-tenant sufficient statistics. | | @takk/bayesbelief/edge | The node-free core, re-exported for edge runtimes and the browser. |


A tool for a non-human entity

The adapter exposes BayesBelief as a framework-agnostic tool a non-human entity can call to pool beliefs across its fleet without ever moving raw data. The descriptor shape, a name, a description, a JSON Schema, and a handler, matches what MCP servers and tool-calling APIs expect, and input arriving from a model is parsed defensively.

import { bayesBeliefTool } from "@takk/bayesbelief/adapter";

// Register bayesBeliefTool with your MCP server or tool-calling API; its name is "bayes_belief".
const result = bayesBeliefTool.handler({
  family: "beta",
  tenants: [
    { tenant: "acme", successes: 30, trials: 100 },
    { tenant: "globex", successes: 8, trials: 10 },
  ],
  query: "acme", // omit to get the full pool report instead of one tenant
});

This is the loop a non-human entity (NHE) closes over a fleet of installations it operates: it never sees a tenant's raw data, it pools only sufficient statistics, and it lifts a new installation's cold start from what the fleet already learned.


Tamper-evident audit trail

import { AuditChain, verifyChain } from "@takk/bayesbelief/audit";

const chain = new AuditChain();
await chain.append({ kind: "pool", globalMean: 0.75, tenants: 12 });
await chain.append({ kind: "decision", tenant: "initech", mean: 0.81 });

await verifyChain(chain.toArray()); // { valid: true }, until any entry is altered

Each pooling update and each decision is recorded append-only and chained to the previous one through a SHA-256 hash of its canonical form. Any later edit, deletion, or reordering breaks the chain and verifyChain reports the first broken entry. The seal is an integrity seal, not a digital signature: it proves the record was not tampered with, not who produced it. The chain uses the Web Crypto API, so the audit surface runs in Node, edge runtimes, and the browser.


CLI

BayesBelief ships a command-line tool that runs the real hierarchy, with every number produced by execution.

# Fit the global prior and print every tenant's pooled posterior from a stats file.
npx @takk/bayesbelief pool tenants.json

# Print one tenant's partially-pooled posterior, at a 90% credible mass.
npx @takk/bayesbelief posterior tenants.json acme --credible-mass 0.9

# Print the fitted global prior and the shrinkage profile.
npx @takk/bayesbelief calibrate tenants.json --family normal

# Verify a sealed audit chain.
npx @takk/bayesbelief audit-verify chain.json

Exit codes are explicit: 0 ok, 2 usage or input error, 30 the privacy guard tripped (too few tenants), 20 a broken audit chain. See examples/ for runnable demos and benchmarks/ for the value benchmark.


The math, in one paragraph

Each tenant in the fleet has a parameter, a rate for the Beta-Binomial model, a mean for the Normal-Normal model, and a global prior sits one level above all the tenants. The global prior is fit by empirical Bayes from the tenants' sufficient statistics: a method of moments matches the mean and the between-tenant variance of the per-tenant rates to a Beta, giving the global Beta(a0, b0) and an effective prior sample size; DerSimonian-Laird estimates the global mean and between-tenant variance for the Normal family under a common within-tenant variance. Each tenant's posterior is then the conjugate update of that prior with the tenant's own evidence, computed in closed form, O(1) per update. The posterior mean is a weighted blend of the tenant's own estimate and the global mean, with weight set by the tenant's sample size against the prior strength, this is the shrinkage, reported per tenant. A tenant with no observations returns the prior itself, the cold start. Credible intervals come from the true Beta and Normal posteriors, the regularized incomplete beta via continued fraction inverted by bisection, and calibration is measured by simulation rather than assumed.


Benchmark

benchmarks/ simulates a realistic multi-tenant fleet, 300 tenants whose true rates are genuinely different and most of whom are small, and scores three estimators against the truth and on a held-out sample: no pooling (each tenant from its own data), complete pooling (one global rate for everyone), and BayesBelief partial pooling. Lower squared error to the truth is better.

| Estimator | Squared error to truth | |---|---| | no pooling (per-tenant MLE) | 6.49 | | complete pooling (one global rate) | 6.07 | | BayesBelief (partial pooling) | 2.40 |

Partial pooling cuts squared error to the truth by 63 percent versus estimating tenants alone and by 60 percent versus collapsing them into one rate, and it also wins held-out predictive log-loss. The win concentrates in the small tenants, exactly where a multi-tenant system needs the help. Numbers are measured, not asserted. Run it yourself: pnpm run build && node --import tsx benchmarks/value.ts.


Quality

  • 84 tests across 14 suites, all passing under Vitest on Node 20, 22, and 24.
  • Coverage: statements 95.37%, branches 85.30%, functions 96.40%, lines 95.34%.
  • Lint clean under Biome.
  • Typecheck clean under TypeScript in maximum strict mode (exactOptionalPropertyTypes, useUnknownInCatchVariables, noUncheckedIndexedAccess, noPropertyAccessFromIndexSignature).
  • publint clean and @arethetypeswrong/cli green across all twelve subpaths.
  • size-limit under budget on every bundle (brotli core 5.04 kB).
  • Distribution smoke test exercising the compiled ESM and CJS artifacts and the compiled CLI spawned as a single Node process.
  • Zero required runtime dependencies; a node-free core that runs in Node, edge runtimes, and the browser; dual ESM plus CJS; TypeScript-first.

See SPEC.md for the formal specification, public surface, and stability promise.


FAQ

Why not just estimate each tenant on its own data? Because most tenants are small, and a small tenant's own data gives a noisy, overconfident estimate, a tenant that succeeded on two of two trials is not succeeding 100 percent of the time. Partial pooling pulls that estimate toward what the fleet has learned, by exactly as much as the thinness of the data justifies, and pulls a data-rich tenant almost not at all.

Why not pool everyone into one global number? Because tenants genuinely differ, and one global rate erases that. Complete pooling is the opposite failure from no pooling. The benchmark shows partial pooling beating both: it keeps the fleet-level signal where a tenant is thin and the tenant-level signal where a tenant is rich.

Does any tenant's raw data leave the tenant? No. Only aggregated sufficient statistics cross the tenant boundary, successes and trials, or count, sum, and sum of squares. A minimum-tenant guard further refuses to expose a global prior fit from too few tenants. This is data minimisation by construction, GDPR and EU AI Act aligned, not a formal differential-privacy guarantee.

What happens to a brand-new tenant? It cold-starts from the global prior. A tenant with zero observations returns the fleet's prior as its starting belief, with the between-tenant spread as its uncertainty, and sharpens toward its own data as observations arrive.

Rates or continuous metrics? Both. The Beta-Binomial hierarchy handles a rate in [0, 1], conversion or success. The Normal-Normal hierarchy handles an unbounded continuous mean, latency, score, or revenue, observed as sufficient statistics.

Does this work in Cloudflare Workers, Vercel Edge, Bun, and Deno? Yes. The core is node-free; the audit seal uses the Web Crypto API, not node:crypto. Import @takk/bayesbelief or @takk/bayesbelief/edge anywhere with Web Crypto. Only @takk/bayesbelief/node requires Node.


Contributing

See .github/CONTRIBUTING.md for the contributor guide. Substantive proposals open a GitHub Issue first; trivial fixes can go straight to a PR. All commits require DCO sign-off (git commit -s). Non-trivial contributions are governed by the Contributor License Agreement.

Community and support

  • Issues and feature requests. Open a GitHub issue at davccavalcante/bayesbelief/issues. Include the package version, a minimal reproduction, expected versus actual behavior, and where relevant the posterior() or pool() output.
  • Security disclosures. Do not open public issues for vulnerabilities. Follow the responsible-disclosure flow in SECURITY.md, contact [email protected] (or [email protected]) with the [SECURITY] prefix.
  • Code of Conduct. This project follows the Contributor Covenant 2.1. Participation in any BayesBelief space implies agreement.
  • Contributions. All non-trivial contributions go through the Contributor License Agreement. Tests, lint, typecheck, and build must be green before review (pnpm verify).

Author

Created by David C Cavalcante, [email protected] (preferred), [email protected] (Takk relay), linkedin.com/in/hellodav, x.com/davccavalcante, takk.ag.

BayesBelief is part of a broader portfolio of NPM packages targeting Massive Intelligence (IM) native infrastructure for 2026-2030, built at Takk Innovate Studio. Privacy-preserving shared learning across a tenant fleet is foundational infrastructure for that era, the layer that lets a fleet of non-human entities learn together without learning about each other.


Related research by the author

The architectural philosophy behind BayesBelief, learning across a fleet while keeping each tenant's data inside its own boundary, echoes the author's research frameworks:

  • MAIC (Massive Artificial Intelligence Consciousness), a systemic intelligence framework designed to coordinate, supervise, and govern large-scale Massive Intelligence ecosystems, providing global context awareness, alignment, and orchestration across multiple models, agents, and decision layers.
  • HIM (Hybrid Entity Intelligence Model), a hybrid intelligence layer that integrates Massive Intelligence systems with human-defined logic, rules, heuristics, and strategic intent, interpreting objectives and structuring decision-making before and after model execution.
  • NHE (Noumenal Higher-order Entity), a non-human cognitive entity with a defined functional identity and operational agency within a Massive Intelligence ecosystem, operating through coordinated intelligence layers while maintaining a non-anthropomorphic identity.

These frameworks are published independently of BayesBelief and are separate works:


Sponsors

Join the journey as the portfolio continues to ship Massive Intelligence (IM) native infrastructure. Your support is the cornerstone of this work.


Privacy

BayesBelief runs entirely inside your own process and infrastructure. It makes no outbound calls to the author, collects no telemetry, and ships no analytics. The only state it holds is the sufficient statistics you feed it. See PRIVACY.md for the full data-handling notice, including how the optional file loaders read tenant statistics from disk.


License

Licensed under the Apache License 2.0. See LICENSE for the full text and NOTICE for attribution and third-party component licenses. You may use, modify, and distribute the code under the terms of that license, including its patent grant and attribution requirements.