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

@hermesplant/assurance-guard

v0.1.1

Published

Dependency-light local policy guard and typed client for Hermes Agent Commerce Assurance.

Readme

Hermes Plant Assurance Guard SDK

Dependency-light TypeScript primitives for putting a fail-closed policy gate in front of x402 payments and MCP tool calls. The package can evaluate organization policy locally, hash-bind the exact operation, request signed decisions from the Hermes Plant Agent Commerce Assurance API, verify returned record hashes, and record fulfillment receipts.

The npm registry contains version 0.1.0 (published July 29, 2026). This checkout prepares 0.1.1 with execution-recovery fixes; a source version is not proof of publication. Use the manual protected release workflow and verify the exact registry artifact as described in ../../docs/ASSURANCE_NPM_RELEASE.md.

Guarantees and boundaries

  • Stable hermes-stable-json-v1 canonicalization and SHA-256 record hashing.
  • Exact x402 resource, method, scheme, network, asset, recipient, amount, facilitator, payment identifier, and payload-resource binding.
  • Exact MCP server, URL, tool, and canonical argument-hash binding.
  • Network-free, deterministic organization-policy preflight.
  • Explicit deny and needs_review exceptions; neither is treated as success.
  • Typed calls to /api/assurance/decisions, /api/assurance/receipts, and /api/assurance/history with runtime envelope and record-hash checks.
  • No wallet, signer, payment executor, MCP transport, arbitrary network probe, analytics, or secret persistence.

Local preflight is a safety gate, not a replacement for a signed server decision when an organization needs retained policy history and receipts.

Runtime requirements

  • Node.js 18+ or a modern browser/worker with fetch and globalThis.crypto.subtle. Missing Web Crypto fails deterministically with AssuranceCryptoUnavailableError.
  • TypeScript is optional for consumers; generated ESM and declarations are in dist/ after npm run build.

Build and link locally

cd packages/assurance-guard
npm run verify:release

Then install it from another project using a reviewed local path:

{
  "dependencies": {
    "@hermesplant/assurance-guard": "file:../HermesPlant/packages/assurance-guard"
  }
}

verify:release typechecks production code, examples, and tests; runs the behavior suite; performs a clean declaration build; inspects the packed file list; installs the tarball into an isolated consumer; typechecks that consumer with strict NodeNext settings; and executes the installed ESM exports.

Publishing is a separate manual, protected npm OIDC workflow, not a side effect of a source push or application deployment.

Network-free quickstart

From the repository root:

npm run demo:quickstart --prefix packages/assurance-guard

It builds the package, runs local x402 and MCP policy decisions without credentials or network calls, and prints assurance-v2 verdicts and binding hashes. The clean-consumer release gate enforces a 15-minute maximum; the demo normally completes in seconds.

Installable reference integrations are shipped in examples/generic-x402.ts, examples/generic-mcp.ts, and examples/offline-jwks.ts.

Local x402 preflight

import {
  AssuranceGuard,
  AssuranceDeniedError,
  AssuranceNeedsReviewError,
  type X402AssuranceDecisionRequest,
} from "@hermesplant/assurance-guard";

const request: X402AssuranceDecisionRequest = {
  protocol: "x402",
  idempotencyKey: "run-42:exa-search:1",
  subject: { runId: "run-42", agentId: "research-agent" },
  policy: {
    policyId: "research-spend",
    version: 3,
    maxUsdPerTransaction: 0.25,
    allowedNetworks: ["eip155:8453"],
    allowedHosts: ["api.example.com"],
    requirePaymentIdentifier: true,
  },
  intent: {
    resourceUrl: "https://api.example.com/search",
    method: "POST",
    scheme: "exact",
    network: "eip155:8453",
    asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    amountUnits: "7000",
    payTo: "0x6d6E695b09861467c7d462f5AAF31cF3540B9192",
    facilitatorUrl: "https://api.cdp.coinbase.com/platform/v2/x402",
    paymentIdentifier: "run-42:exa-search:1",
    paymentPayloadResource: "https://api.example.com/search",
    paymentPayloadMethod: "POST",
  },
};

const guard = new AssuranceGuard();

try {
  const approved = await guard.authorize(request, { localOnly: true });
  console.log(approved.bindingHash);
} catch (error) {
  if (error instanceof AssuranceNeedsReviewError) {
    // Route to an actual reviewer; do not execute.
  } else if (error instanceof AssuranceDeniedError) {
    // Reject and retain the findings.
  } else {
    throw error;
  }
}

Undefined safety booleans use fail-closed service defaults: HTTPS, exact x402 scheme, resource binding, and MCP argument binding are required unless the organization policy explicitly disables the corresponding check.

Connected authorization

import { AssuranceClient, AssuranceGuard } from "@hermesplant/assurance-guard";

const client = new AssuranceClient({
  baseUrl: "https://hermesplant.com",
  accessToken: () => process.env.HERMES_AGENT_TOKEN,
  organizationId: "org_example",
});
const guard = new AssuranceGuard({ client });

const decision = await guard.authorize(request);

// Re-verify freshness, record hash, and every bound field immediately before
// handing the operation to your own x402 transport.
await guard.assertX402Executable(decision, request.intent);

// Your payment transport runs here. The SDK never signs or pays.

await guard.recordReceipt(decision, {
  outcome: "fulfilled",
  settlementId: "0x...",
  responseStatus: 200,
  evidenceHashes: ["b".repeat(64)],
});

For browser customer sessions, omit accessToken and use a same-origin baseUrl. For agent access, provide an existing Hermes Bearer token. The SDK does not read .env files or store credentials.

MCP exact-argument binding

const mcpRequest = {
  protocol: "mcp" as const,
  idempotencyKey: "run-77:create-issue:1",
  subject: { runId: "run-77", agentId: "ops-agent" },
  policy: {
    policyId: "mcp-production",
    version: 1,
    allowedMcpServers: ["github"],
    allowedMcpTools: ["create_issue"],
    requireMcpArgumentBinding: true,
    reviewMcpRiskAtOrAbove: "high" as const,
  },
  intent: {
    serverId: "github",
    serverUrl: "https://mcp.example.com",
    toolName: "create_issue",
    toolArguments: { title: "Exact title", labels: ["ops", "agent"] },
    declaredRisk: "low" as const,
  },
};

const decision = await guard.authorize(mcpRequest);
await guard.assertMcpExecutable(decision, mcpRequest.intent);

Raw MCP arguments are sent in the decision request but are not duplicated in the signed decision binding. The binding retains only their canonical SHA-256 hash. If a caller supplies both toolArguments and toolArgumentsHash, a mismatch is denied.

Direct API client

const decision = await client.createDecision(request);
const history = await client.listHistory(25);

The client verifies:

  1. The response has the required assurance-v2 envelope; legacy v1 records remain readable for compatibility.
  2. The SHA-256 hash of the returned record matches integrity.recordHash.
  3. Decision protocol, idempotency key, binding, binding hash, policy hash, and request hash match the submitted request.
  4. Receipt decision, record hash, binding hash, protocol, settlement ID, outcome, response status, response-body hash, evidence hashes, and caller-supplied observation time match the submitted receipt.

HTTP failures throw AssuranceApiError with status, optional service code, validation errors, contactUrl, and the parsed response body. Invalid or mismatched success responses throw AssuranceProtocolError.

Integrity model

Connected decisions and receipts fail closed unless both the canonical SHA-256 record hash and an Ed25519 detached JWS verify against a configured or cached Hermes JWKS. AssuranceClient accepts retained keys or fetches /.well-known/assurance-jwks.json, caches them for five minutes, refreshes once for an unknown key, and rejects redirects, non-JSON responses, unusable keys, unsigned records, and HMAC-only records. Hash equality alone is never treated as server authenticity for execution.

For offline verification, retain a trusted JWKS while online and pass it to verifySignedRecord or AssuranceGuard. The SDK never needs or accepts a server private signing secret. The package includes a PUBLIC TEST-ONLY deterministic Ed25519 vector for cross-consumer interoperability.

Development

npm run typecheck
npm test
npm run build
npm run verify:package

The package has no runtime dependencies. Tests use injected fetch functions and make no live, paid, or wallet-backed calls.

Assurance v2 public verification and execution wrappers

The organization decision API is server-authoritative. Owners/admins activate an immutable policy version at /api/assurance/policies; decision callers cannot install a weaker policy. The SDK's local policy remains an early fail-closed preflight, while the signed server verdict is evaluated against the active organization version.

Production records carry an Ed25519 detached JWS and are verifiable offline:

import { verifySignedRecord, type AssuranceJwks } from "@hermesplant/assurance-guard";

const jwks = await fetch(
  "https://hermesplant.com/.well-known/assurance-jwks.json",
).then((response) => response.json()) as AssuranceJwks;

const verification = await verifySignedRecord(decision, { jwks });
if (!verification.ok) throw new Error("Untrusted assurance decision");

Use the caller-controlled wrappers to check binding immediately before execution:

const completed = await guard.executeX402(
  request,
  (exactIntent) => myX402Client.execute(exactIntent),
  { settlementId: (response) => response.headers.get("x-settlement-id") ?? undefined },
);

const toolResult = await guard.executeMcp(
  mcpRequest,
  (exactArguments, exactIntent) =>
    myMcpClient.callTool(exactIntent.serverId, exactIntent.toolName, exactArguments),
);

Both wrappers deep-clone and freeze the exact operation, verify its binding immediately before the callback, refuse deny/needs_review without invoking the callback, and bind the returned content into an assurance receipt. x402 exact is the production scheme; batch is intentionally unsupported.

Recovery contract (0.1.1)

The successful result shape is unchanged. MCP results with isError: true produce a failed, content-bound receipt rather than a fulfilled receipt.

AssuranceExecutionError preserves the decision, original cause, processing stage, and returned response when available. executionState: "returned" means the callback returned; it does not prove settlement. Hashing, settlement extraction, or receipt-storage failure must not be interpreted as action failure. executionState: "unknown" means the callback rejected and the remote outcome must be reconciled. Neither case writes a fabricated failed receipt.

When receiptInput is present, retry only guard.recordReceipt(error.decision, error.receiptInput, { organizationId }) using the original organization context and a fresh cancellation signal. Keep that exact payload; an earlier write may have committed despite a lost response. Otherwise reconcile the executor outcome and recover its evidence first.

Both wrappers reject replayed decisions and same-guard decision reuse with AssuranceReplayError, including after executor rejection. Calling authorize and then execute* with the same key therefore fails closed; use either the wrapper once or the lower-level explicit authorization/binding/receipt flow. Do not rotate an idempotency key to bypass this protection. An authorization whose response was lost may be blocked despite never having executed.

These checks do not provide universal exactly-once execution. The trusted caller-owned transport must enforce durable operation idempotency, preserve the exact bound intent, and reconcile across crashes and process restarts. Lower-level APIs do not reserve execution. No automatic action retry is safe merely because an HTTP request, callback, or receipt request failed.

MCP policy checks server/tool allowlists, binding, and caller-declared risk; they do not semantically inspect arbitrary arguments or infer malicious intent. Risk assertions must come from trusted host policy, not model self-assessment. Broadly allowlisting a shell, SQL, or general-purpose tool is not an argument safety policy. Narrow capabilities and independent argument validation belong in the trusted execution host before the wrapper.