@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
npm install --save-dev @mcpose/testingmcpose and @mcpose/audit are peer dependencies.
Quick start
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
| Function | Proves | Does NOT prove |
|---|---|---|
assertAuditChainIntegrity(events) | Positions sequential; chainHashes distinct and non-empty; non-empty log | HMAC 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 index | The manifest signature: use verifyManifestSignature |
assertPiiRedacted(event, patterns) | low/medium: no pattern matches plaintext; high: no plaintext fields, encrypted payloads present | Anything about what is inside high-tier ciphertext |
assertDelegationHonored(event) | delegatedFrom present, non-empty, entries have a sub | Delegation 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