@mcpose/testing

Compliance assertions for @mcpose/audit audit chains. A small set of assertion functions that verify the tamper-evidence guarantees of an mcpose audit trail: chain integrity, Merkle-proof validity, PII redaction, and delegation handling. Each throws a descriptive Error on failure and returns void on success.

Keyless by design

These assertions are deliberately keyless: the signing secret is not available to tests. They catch structural tampering (reordering, renumbering, duplicated or missing entries, doctored roots), but a key-holder forging a consistent chain can only be caught by the keyed verifiers in @mcpose/audit: verifyAuditChain and verifyManifestSignature. See ADR-0003 and ADR-0004 for the signing and canonical-serialization rationale.

Runner-agnostic

These are plain functions with no test-framework dependency. Use them with Vitest, Jest, node:test, or any runner.

Install

terminal
npm install --save-dev @mcpose/testing

mcpose and @mcpose/audit are peer dependencies.

Quick start

testing.test.ts
import { expect, test } from 'vitest'; // or jest, node:test, your choice
import {
  assertAuditChainIntegrity,
  assertReplayManifestValid,
  assertPiiRedacted,
  assertDelegationHonored,
} from '@mcpose/testing';

// Supplied by your test setup:
//   captureAuditEvents: collects the AuditEvents emitted via AuditOptions.onEvent
//   auditHandle: the handle returned by createAuditMiddleware()

test('transfer flow produces a verifiable audit trail', async () => {
  const events = await captureAuditEvents(/* run your scenario */);
  const manifest = await auditHandle.closeSession('session-123');

  assertAuditChainIntegrity(events);            // no insert/delete/reorder
  assertReplayManifestValid(events, manifest!); // every Merkle proof verifies
  assertPiiRedacted(events[0], [/\d{16}/]);     // no card numbers in plaintext
  assertDelegationHonored(events[0]);           // delegated call carries its chain
});

API

FunctionProvesDoes NOT prove
assertAuditChainIntegrity(events)Positions sequential; chainHashes distinct and non-empty; non-empty logHMAC validity (no key): a key-consistent forgery passes
assertReplayManifestValid(events, manifest)Root recomputes from the events; one proof per event; every proof verifies at its indexThe manifest signature: use verifyManifestSignature
assertPiiRedacted(event, patterns)low/medium: no pattern matches plaintext; high: no plaintext fields, encrypted payloads presentAnything about what is inside high-tier ciphertext
assertDelegationHonored(event)delegatedFrom present, non-empty, entries have a subDelegation signatures or chain continuity (v3)

Re-exports AuditEvent and ReplayManifest types from @mcpose/audit for convenience.

Empty chain

assertAuditChainIntegrity throws on an empty chain. A log truncated to zero events must not pass.

mcpose/testing vs @mcpose/testing

Not to be confused with mcpose/testing: the subpath export of the core mcpose package, which provides proxy/middleware mocks (createMockBackendClient, runToolMiddleware). This package is about asserting the audit chain.

References

  • @mcpose/audit: the package these helpers verify
  • ADR-0003: audit subkeys derived from the signing secret via the oracle, not from keyId
  • ADR-0004: audit format v2, canonical serialization, and the full-manifest signature

Next steps