Packages and crates

Every crate and npm package Meant publishes, what each is for, and how to depend on it.

Meant publishes two crates and seven npm packages from one repository, B3Pay/Meant, and keeps three more units deliberately off every registry. This page is the whole inventory: what each one is, who it is for, where its manifest lives, whether you can install it today, and the exact line you write to depend on it.

The short version. For the meaning of a call (amounts, consent, agent tools), you want the @meantjs packages, starting with @meantjs/profile. For a Candid interface as data, you want the meant crate in Rust or @candid-core/schema in TypeScript. Everything else on this page produces one of those, or tests them.

The pipeline in one view#

Every unit sits somewhere on one path. Candid source goes in at the left; a canonical, validated Contract comes out of the middle; a profile bound to the Contract's identity says what its values mean; consumers read the result.

  1. 01

    .did source#

    Your Candid interface and every file it imports. Text, with whitespace, comments and declaration spellings that mean nothing to the wire.

  2. 02

    Contract#

    meant hands the source to the exact-pinned candid_parser, then projects the result into a validated graph with an interface_id, under an explicit resource budget.

  3. 03

    Profile#

    @meantjs/profile binds profiles and packs to that interface_id, merges them and writes the resolved form.

  4. 04

    Consumers#

    @meantjs/format, /consent, /tools and /reconcile read the resolved form; @candid-core/schema validates and encodes the values themselves.

@candid-core/cli is the Rust compiler and generator compiled to WebAssembly, not a reimplementation, so a JavaScript-only project gets steps 01 and 02 with no Rust toolchain. @meantjs/profile uses it for exactly that.

The full inventory#

UnitLayerKindManifestRegistryVersion
meantInterfacesRust libraryCargo.tomlcrates.io0.1.0
meant (binary)InterfacesCLI, same crateCargo.toml [[bin]]crates.io0.1.0
@candid-core/schemaInterfacesnpm packagecrates/candid-core-ts/ts/package.jsonnpm0.5.0; beta: 0.3.0-beta.1; prepared, not yet published: 0.6.0, as @meantjs/schema
@candid-core/cliInterfacesnpm packagecrates/candid-core-wasm/npm/package.jsonnpm0.4.0; beta: 0.2.0-beta.1; prepared, not yet published: 0.5.0, as @meantjs/cli
@meantjs/profileProfilesnpm package, and the candid-profile CLIprofile/packages/resolver/package.jsonnpm0.4.0
@meantjs/formatProfilesnpm packageprofile/packages/format/package.jsonnpm0.4.0
@meantjs/consentProfilesnpm packageprofile/packages/consent/package.jsonnpm0.4.0
@meantjs/toolsProfilesnpm packageprofile/packages/tools/package.jsonnpm0.4.0
@meantjs/reconcileProfilesnpm packageprofile/packages/reconcile/package.jsonnpm0.4.0
meant-formatProfilesRust librarycrates/meant-format/Cargo.tomlcrates.io0.2.0
candid-core-tsInterfacesRust librarycrates/candid-core-ts/Cargo.tomlnone, by publish = false0.0.0
candid-core-wasmInterfacesRust librarycrates/candid-core-wasm/Cargo.tomlnone, by publish = false0.1.0
candid-core-fuzzInterfacesFuzz harnessfuzz/Cargo.tomlnone, by publish = false0.0.0

Two families version independently. The @candid-core pair releases together, with the CLI peering the schema package at one exact version. The five @meantjs packages release together under one version and pin each other exactly. The crates each have their own version. The three units on no registry are tracked, buildable and gated, and each carries a deliberate publish = false.

Everything here is pre-1.0

The crates are meant 0.1.0 and meant-format 0.2.0; the npm packages are @candid-core/schema 0.5.0 and @candid-core/cli 0.4.0 under latest, with the earlier betas 0.3.0-beta.1 and 0.2.0-beta.1 still under beta, and the five @meantjs packages at 0.4.0. Until 1.0, any release may change the public API, the serialized document shapes, the canonical bytes and every identity computed over them, and for the @meantjs packages any change to generated text is breaking. Pin an exact version in both ecosystems. See Status, versions and releases.

Upgrading from an earlier release

The table above shows latest and beta. The sections below describe the packages as the repository builds them, published on 2026-10-27 under the npm latest dist-tag as @candid-core/schema 0.5.0 and @candid-core/cli 0.4.0. The previous stable releases, 0.4.0 and 0.3.0, type decode and decodeArgs values as unknown, lack didToDocAttributes and the identities in gen --json, name the first alias of a blob, record {} or variant {} at every use of that shape, and write envelopes whose producer is candid-core 0.1.0-beta.3, where CLI 0.4.0 embeds meant 0.1.0, the compiler crate published as candid-core before its rename. The sections below mark what they show of those as new in 0.5.0 or 0.4.0; Migrating from 0.4.0 says what the upgrade means. The stable releases before those, 0.3.0 and 0.2.0, also lack WithMode and ModeOf, the CLI's project and check with projectDid and checkCompatible, and generated modules that declare each type under its Candid name and each Actor method with its mode. The sections below mark each of those as new in 0.4.0 or 0.3.0; Migrating from 0.3.0 says what that upgrade means. The stable releases before those differ more: 0.2.0 has two more subpaths and an optional peer, and 0.1.0 emits the old module layout. Migrating from 0.2.0 shows what each break means, and each is recorded in the package changelogs under 0.3.0 and 0.2.0 and the betas before them. The beta dist-tag still names 0.3.0-beta.1 and 0.2.0-beta.1, which lack the changes recorded under 0.3.0 and 0.2.0 and every stable release since. The repository has moved on since: it is prepared as @meantjs/schema 0.6.0 and @meantjs/cli 0.5.0, not yet published, the pair’s code under new names: the CLI’s command becomes meant and its peer @meantjs/schema at exactly 0.6.0, the modules it generates open with a new header and import @meantjs/schema, and every export below keeps its name and its signature. Migrating from 0.5.0 says what the upgrade means.

Which one do I need?#

What you are trying to doReach forWhere to read next
Check a profile, match packs to a service, and write the resolved form@meantjs/profileValidate and resolve profiles
Parse and show amounts, times, accounts, subaccounts and bytes exactly@meantjs/formatParse and display values
Do the amount tag in Rust, in a canister or with no_stdmeant-formatmeant-format (Rust)
Answer icrc21_consent_message for any method, or render an SNS proposal@meantjs/consentGenerate consent messages
Give an agent tools with human units, a confirmed preview and safe retries@meantjs/toolsGive an agent tools
Find out whether a call with an unknown outcome executed@meantjs/reconcileSettle an unknown outcome
Turn a .did file into a validated Contract from Rustmeant, default featuresCompiling Candid sources
Consume Contracts someone else produced, with no Candid parser in your dependency graphmeant, default-features = falseInstall and feature surfaces
Get a Contract document on the command line, no Rust code of your ownthe meant binaryThe meant binary
Validate, encode or decode Candid values from TypeScript@candid-core/schemaQuickstart: TypeScript
Build schemas at runtime from a Contract document, with no code generation step@candid-core/schema, subpath ./contractSchemas at runtime
Emit a TypeScript module from a Contract inside your own Rust toolcandid-core-ts, path or git dependencyThe code generator
Compile a .did or generate TypeScript from a JavaScript-only project@candid-core/cli@candid-core/cli
Drive an untrusted-input boundary with a fuzzercandid-core-fuzzthe section below

The profile packages, @meantjs#

Five npm packages read Candid Profile v0 documents and the resolved form, and turn them into what consumers need. Their source is profile/packages/, a reviewed copy of the project's working repository that each update replaces whole. They are ES modules for Node 22 or later, with hand-written TypeScript declarations for every entry. @meantjs/format, @meantjs/tools, @meantjs/reconcile, the main entry and EVM subpaths of @meantjs/consent, and @meantjs/profile/browser, /address and /evm also run in a browser; the main entry of @meantjs/profile, its CLI, and @meantjs/consent/sns are Node only.

PackageDirectoryWhat it doesDepends on
@meantjs/profileresolver/Validates profiles, matches packs to a service by subtyping, merges layers and emits the resolved form; serves the JSON Schema and the standard packs as subpaths; ships the candid-profile command@candid-core/cli 0.4.0, ajv 8.18.0
@meantjs/formatformat/Exact parse and display for the six value tags: amount, timestamp, duration, account, subaccount and bytes; namesnothing
@meantjs/consentconsent/ICRC-21 consent messages for any method; SNS proposal validators; what a request grants, and the check of it against terms the person confirmed (./terms); for EVM contracts, consent text for calldata and for EIP-712 signing requests, and ERC-7730 files (experimental)@candid-core/schema 0.5.0, @meantjs/format, @meantjs/profile
@meantjs/toolstools/MCP tool definitions, input in human units, a preview the person confirms before every send, and the retry and reconcile rules@meantjs/format
@meantjs/reconcilereconcile/After an unknown outcome and before any new attempt: is the original already in the ledger's ICRC-3 history?@meantjs/format
bash
npm install --save-exact @meantjs/profile@0.5.0 @meantjs/format@0.5.0

Install the ones you use; each pins its @meantjs dependencies at the same version exactly. Releases are published from this repository with npm provenance, under the procedure in profile/docs/releasing.md. Every export, with its signature, is on JavaScript API.

meant-format, the amount tag in Rust#

The amount tag of the profile spec as a Rust crate: AmountFormat parses "1.5 ICP" into the exact base-unit value and displays it back, and refuses rather than rounds, wraps or clamps. It has no dependencies and builds no_std with alloc, so it fits in a canister. For the same input it gives the same answer as @meantjs/format, the same value or the same error code and message, which crates/meant-format/tests/parity.rs checks against vectors generated from the JavaScript reference.

  • Manifest: crates/meant-format/Cargo.toml, a member of the root workspace. Edition 2021, rust-version = "1.78", Apache-2.0.
  • Published: on crates.io: 0.1.0 (2026-10-27) and 0.2.0 (2026-10-29), which adds the EVM integer types uint8 to uint256 and int8 to int256, and with_threshold. It is released by the same Release workflow as meant, dispatched with crate: meant-format. Pin an exact version, as for meant.
  • Features: the default std only implements std::error::Error.
tomlCargo.toml
[dependencies]
meant-format = "=0.2.0"

Its API is on meant-format (Rust).

meant, the Rust library#

The root package of the workspace. It owns the Contract model, validation, canonicalization, the content-addressed identities, the limits and cancellation machinery, and the structured diagnostics. With the compiler feature on, it also owns the projection from Candid source into that model. It is for anyone who needs a Candid interface as data rather than as text: a registry that pins interfaces, a tool that detects drift, a service that accepts .did files it did not write.

  • Manifest: Cargo.toml at the repository root.
  • Published: yes, on crates.io as meant 0.1.0, with API documentation on docs.rs. Until the rename it was published as candid-core, whose versions 0.1.0-beta.1 to 0.1.0-beta.3 and 0.1.0 stay there; meant 0.1.0 is candid-core 0.1.0 under its new name. Code written against it changes use candid_core:: to use meant::, and the binary is meant.
  • Edition 2021, MSRV rust-version = "1.78", licensed Apache-2.0.

Depending on the crate#

tomlCargo.toml
[dependencies]
meant = "=0.1.0"
Pin the exact version

A bare version string such as "0.1" is a caret requirement: it resolves to 0.1.0 and to any later 0.1.x, and before 1.0 any release may change the API, the serialized shapes and the identities. Write the exact requirement "=0.1.0", exactly as above.

To take the model without the Candid engine, turn the defaults off:

tomlCargo.toml
[dependencies]
meant = { version = "=0.1.0", default-features = false }

The four feature surfaces#

One package, four build surfaces. default = ["compiler", "filesystem-compiler", "host-value"], so the dependency line above gives you all of it. The base surface is what remains once default-features = false removes every feature. It is not a named feature; it is the floor.

SurfaceWhat it addsWhat enters your graph
base Contract, ContractDraft, RawContract, validation, canonicalization, the identities, Limits / RuntimeContext, the diagnostics types, ContractEnvelope, artifact_id_with_limits and artifact_id_with_context No Candid engine, no filesystem crate
compiler compile_did, compile_with_resolver, Compilation, SourceInfo, SourceId / SourceResolver / MemoryResolver candid =0.10.30, candid_parser =0.4.0
filesystem-compiler WorkspaceResolver, compile_did_file, and the meant binary. Implies compiler. cap-std =4.0.2, and only on targets that are not target_os = "unknown"
host-value HostValue and validate_host_value ic_principal =0.1.5

A disabled feature removes its API rather than leaving a stub that fails later. The full account, including what feature splitting does and does not bound in a workspace, is on Install and feature surfaces.

meant, the command-line binary#

The same published crate also ships a binary, declared as [[bin]] name = "meant" at src/bin/meant.rs with required-features = ["filesystem-compiler"]. It is for the developer who wants a Contract document on disk and does not want to write Rust to get one. It fits a build step, a CI check, or a drift comparison run by hand.

Because filesystem-compiler is part of the default set, an ordinary install builds it. From the published crate:

bash
cargo install meant --locked --version 0.1.0
meant compile ./service.did

From a checkout of the repository, without installing anything:

bash
cargo run --bin meant -- compile ./service.did
cargo run --bin meant -- compile ./service.did --envelope
cargo run --bin meant -- validate ./contract.json

It accepts exactly this grammar and nothing else:

textsrc/bin/meant.rs
meant compile <path> [--no-source-info | --envelope]
meant validate <path>

Every non-usage outcome is one pretty-printed JSON document on stdout with an empty stderr. A failure is exit 1 and {"ok": false, "diagnostics": …}. Success is exit 0: plain compile and validate print "ok": true alongside the contract, while compile --envelope prints the envelope document itself — {"contract": …, "extensions": …}, with no ok key — so the output can be saved and consumed whole. Anything outside the grammar exits 64, prints the usage text on stderr, and writes nothing to stdout. The meant binary has the full contract.

candid-core-ts, the TypeScript generator#

A Rust library that reads a validated Contract and returns the complete text of one TypeScript module: for every declaration, a hand-readable type alias and a runtime schema object annotated so that tsc itself proves the two agree. It is for whoever is building code generation into their own tool, a build script or a CLI or an editor plugin, rather than shelling out to a binary.

  • Manifest: crates/candid-core-ts/Cargo.toml. A member of the root workspace.
  • Published: no, and not by accident. The manifest carries publish = false because a crates.io crate name is as permanent as a version, and candid-core-ts is a working name, not a decision. The gate stands until the name is chosen deliberately.
  • Version 0.0.0, edition 2021, rust-version = "1.78", Apache-2.0.
  • Depends on meant at version = "=0.1.0" with default-features = false, and a path alongside it so the workspace builds against the sibling. The base surface only, which is the design statement: a generator needs no Candid parser, no filesystem capability and no host-value ABI.

Depending on the generator#

Path or git, or not at all. There is no cargo add line for it and there will not be one until the name question is settled.

tomlCargo.toml
[dependencies]
# Inside a checkout of this repository:
candid-core-ts = { path = "crates/candid-core-ts" }

# Or from git, pinned to a commit:
candid-core-ts = { git = "https://github.com/B3Pay/Meant", rev = "<commit sha>" }

That choice travels. crates.io refuses a package with a git dependency outright, and a path dependency must also carry a version requirement the registry can resolve — which candid-core-ts, having no published version, cannot satisfy. So depending on it this way is fine for an application or an internal tool, and means your own crate cannot go to crates.io either. If you need generated TypeScript without that constraint, run the binary or the WebAssembly CLI instead of linking the generator.

What it exposes#

One entry point plus the two inputs it needs:

rustcrates/candid-core-ts/src/lib.rs
pub fn generate_module(
    contract: &Contract,
    names: &TsNames,
    options: &TsOptions,
) -> Result<GeneratedModule, TsGenError>

TsNames is the table of field and variant-arm spellings, keyed by (container, label id). A Contract stores only the numeric Candid label id, so you supply the spellings yourself. Build it with TsNames::new() (every field renders _N_), TsNames::from_pairs, or TsNames::from_source_info. TsOptions carries one field, principal_import. The result is the module text plus omitted, the declarations and actor methods it had to leave out and why; see The code generator.

FeatureWhat it adds
noneThe default. A pure base-surface consumer of meant. This featureless build is the boundary claim, and CI checks it on its own.
compilerEnables meant/compiler and with it TsNames::from_source_info, the bridge from a compilation's provenance sidecar into the name table.

@candid-core/schema, the npm runtime#

The TypeScript half of the project, and the package most readers will actually install: schema builders with real static inference, structural validation, and a TypeScript-native Candid binary codec. It is for any TypeScript consumer of a canister, with or without a generated module, since the same schemas can be built at runtime from a Contract document.

  • Manifest: crates/candid-core-ts/ts/package.json.
  • Published: yes, on npm. Released versions are 0.0.0-bootstrap, 0.1.0, 0.1.1, 0.2.0, 0.3.0-beta.1, 0.3.0, 0.4.0 and 0.5.0; 0.5.0 is latest, 0.3.0-beta.1 is beta, 0.2.0, 0.3.0-beta.1, 0.3.0 and 0.4.0 all pair with candid-core 0.1.0-beta.3, and 0.5.0 pairs with meant 0.1.0, the crate published as candid-core before its rename. 0.4.0 adds WithMode and ModeOf to 0.3.0, and 0.5.0 types decode and decodeArgs values by their schemas. The manifest is prepared as the next release under a new name, @meantjs/schema 0.6.0, not yet published: 0.5.0’s code, with the same exports (Migrating from 0.5.0).
  • ESM only ("type": "module"), sideEffects: false, Apache-2.0. The tarball ships dist, README.md, CHANGELOG.md and LICENSE.
  • Versions independently of the Rust crate. Its changelog names the compiler crate version each release pairs with: candid-core until 0.4.0, meant from 0.5.0.
bash
npm install --save-exact @candid-core/schema

That is the whole install: no runtime dependencies and no peers. Every module is self-contained, principal typing included, so nothing needs the Internet Computer SDK to exist.

The subpath exports#

Each entry resolves to a .d.ts and a .js under dist/, and nothing outside the map is importable. The map is exactly the four below: the package is the Candid layer only, and calling a canister belongs to the layer built on top of it.

SubpathWhat it is
.The schema core: the c builders, the deliberately invariant Schema<in out T>, Infer, the node interfaces walkers narrow on, plus resolveSchema and serviceMethods for reading a schema back, the Principal type (canonical principal text) with principal and isPrincipal, and OptDomain with isBoxedOpt for the boxed-option rule. See Builders and inference.
./validateStructural validation that never throws on any value. Issues carry stable codes and $-rooted paths, plus isResultSchema and unwrapResult for the variant { ok; err } convention. See Validation.
./contractschemaFromContract: build the same schemas at runtime from a canonical Contract JSON document, or from a one-document ContractEnvelope carrying its field-name table. See Schemas at runtime.
./codecThe Candid binary wire format, schema-directed, with the specification's coercion relation on decode and explicit resource budgets. See Binary codec.

@candid-core/cli, the WebAssembly on-ramp#

bash
npx @candid-core/cli@0.4.0 gen ./service.did -o ./generated

It gives a JavaScript-only project the interface pipeline with no Rust toolchain. The meant compiler surface and the candid-core-ts generator are compiled together into one WebAssembly artifact, wrapped in a Node CLI and a small JS module that also runs in a browser. Every library call is data in, data out: one JSON-serialisable request to the WebAssembly module, its parsed JSON response returned verbatim, no eval, and no filesystem access from the WebAssembly side.

  • Manifest: crates/candid-core-wasm/npm/package.json.
  • Binary name: candid-core-cli, at ./bin/cli.js. The manifest is prepared as the next release under a new name, @meantjs/cli 0.5.0, not yet published, whose one command at the same path is meant and whose peer is @meantjs/schema at exactly 0.6.0 (Migrating from 0.5.0).
  • Exports: "." → ./lib/index.js under a types condition, plus ./package.json. ESM only, Apache-2.0, no runtime dependencies; the single peer, @candid-core/schema at exactly 0.5.0 (exactly 0.4.0 in the published 0.3.0, exactly 0.3.0 in 0.2.0, exactly 0.3.0-beta.1 in 0.2.0-beta.1, ^0.2.0 in 0.1.0), is declared optional. The one devDependency is playwright-core for the browser tests.
  • CLI grammar: candid-core-cli gen <service.did>... [-o <dir>] [--json] [--check] (0.1.0 takes one entry and neither flag), plus project and check, new in 0.3.0 (Projection and compatibility). -o defaults to the current working directory. Output names come from each entry file's stem: service.did writes service.ts and service.envelope.json, and prints the content-addressed identities.
  • Library exports: didToContract(sources) and didToModule(sources), each taking either a string of Candid text or a { entry, files } bundle, plus init(input), which loads the embedded WebAssembly module once and needs no argument under Node; new in 0.3.0, projectDid(sources, methods) and checkCompatible(written, live); and, new in 0.4.0, didToDocAttributes(sources), which reads the @name(…) attributes in doc comments (Doc attributes).

Building it from source#

To work on the package itself, build it from a clone. The wasm/ directory is build output and is not committed, so the first step is always to produce it. wasm-pack 0.14.0 is the version the repository's own workflows install.

  1. Get the toolchain

    bash
    rustup target add wasm32-unknown-unknown
    cargo install wasm-pack --version 0.14.0 --locked
  2. Build the WebAssembly artifact

    bash
    cd crates/candid-core-wasm
    wasm-pack build --target web --out-dir npm/wasm --no-pack --release -- --locked
  3. Run the CLI from the package directory

    bash
    cd npm
    node ./bin/cli.js gen ./service.did -o ./generated

That writes generated/service.ts and generated/service.envelope.json. Details of both, and of the failure shapes, are on @candid-core/cli.

candid-core-wasm, the crate behind the CLI#

The Rust crate that becomes that artifact. It is a wasm-bindgen shim over meant's compiler surface (compile_with_resolver plus MemoryResolver, so no filesystem is ever touched from the WebAssembly side) and the candid-core-ts generator, and it carries two pieces of its own: the projection printer behind projectDid (src/project.rs), which reprints the requested methods and what they reach from the Candid syntax, and the service compatibility check behind checkCompatible (src/compat.rs), which evaluates Candid subtyping on the two compiled Contracts. It exposes four functions, each string in and string out; their request and response documents are on @candid-core/cli:

rustcrates/candid-core-wasm/src/lib.rs
#[wasm_bindgen(js_name = didToContract)]
pub fn did_to_contract(request: &str) -> String

#[wasm_bindgen(js_name = didToModule)]
pub fn did_to_module(request: &str) -> String

#[wasm_bindgen(js_name = projectDid)]
pub fn project_did(request: &str) -> String

#[wasm_bindgen(js_name = checkCompatible)]
pub fn check_compatible(request: &str) -> String
  • Manifest: crates/candid-core-wasm/Cargo.toml. Version 0.1.0, publish = false, Apache-2.0, crate-type = ["cdylib", "rlib"].
  • Its own workspace root. The manifest carries a bare [workspace] table and a tracked Cargo.lock of its own, and the root manifest names it in exclude = ["fuzz", "crates/candid-core-wasm"]. That is the point: wasm-bindgen never enters the main workspace's resolved graph or its feature unification, and cargo metadata over the published crate never sees it.
  • Dependencies: meant and candid-core-ts by path, serde_json =1.0.150, candid_parser =0.4.0 (the version meant itself pins; the projection uses it only to parse and merge the sources), and wasm-bindgen =0.2.108 only under cfg(target_arch = "wasm32"). One dev-dependency, candid =0.10.30, also the version meant pins: the compatibility check's differential tests compare its verdicts with upstream's subtype check.

You do not depend on this crate; you build it. wasm-opt is switched off in the manifest on purpose, so the emitted bytes are a function of the pinned rustc and wasm-bindgen alone with no binaryen download in the build path.

candid-core-fuzz, the fuzz harness#

Internal, and the only unit here that never enters a consumer's build. Each target drives one untrusted-input boundary with arbitrary bytes.

  • Manifest: fuzz/Cargo.toml. Version 0.0.0, publish = false, [package.metadata] cargo-fuzz = true.
  • Its own workspace root with its own tracked fuzz/Cargo.lock, excluded from the root workspace for the same reason as candid-core-wasm. Dependencies are exact-pinned to match the crate under test, libfuzzer-sys =0.4.13 and serde_json =1.0.150, because the library's observable decode behaviour depends on serde_json's recursion limit.
  • Features mirror the library's: default = ["compiler", "filesystem-compiler", "host-value"], each forwarding to the matching meant feature, so a target is only built when the feature owning the API it drives is on.
  • Seven targets: source_parsing, contract_json, canonicalization, resolver_ids, provenance, host_value and envelope_json.

Run one from the repository root, passing the writable corpus directory first so the tracked seeds and regressions stay read-only:

bashfuzz/README.md
cargo +nightly fuzz run contract_json \
  fuzz/corpus/contract_json fuzz/seeds/contract_json fuzz/regressions/contract_json \
  -- -max_total_time=60

What ships and what does not#

The published meant archive is governed by a positive allowlist in the root Cargo.toml, not a growing list of exclusions. A newly tracked file is outside the archive until it is named in include on purpose. What is named: /src/**/*.rs, /examples/**/*.rs, /docs/**/*.md, /README.md, /CHANGELOG.md and /LICENSE.

So tests/, benches/, crates/, fuzz/ and .github/ never reach a consumer's registry download. That means candid-core-ts, candid-core-wasm and candid-core-fuzz are reachable only from a git checkout, whatever their publish setting says. meant-format has an allowlist of its own in its manifest, and profile/ never enters a crate archive; the @meantjs tarballs list what they ship in each package's files, and profile/scripts/package-check/manifest.json holds the exact file list of each, compared on every release. The release and release-candidate workflows run tests/fixtures/packaging/verify_package_manifest.py, which asserts both halves of that policy: every required path present, every forbidden path absent, and no unexplained extra.