@permaegis/harness-core
v0.1.0
Published
PermAegis agent-harness core — the two universal seams (OCap gate + Zoe verify) + Merkle receipt verifier, as a zero-dependency TypeScript client (native fetch + node:crypto).
Maintainers
Readme
@permaegis/harness-core
The two universal agent-harness seams — the OCap gate (pre-tool-call) and the Zoe verify (output/action) — plus an independent Merkle receipt verifier, as a zero-dependency TypeScript client (native
fetch+node:crypto).
This is the shared core behind the framework adapters
@permaegis/harness-claude,
@permaegis/harness-openai, and
@permaegis/harness-crewai. Use it
directly if you are wiring your own harness.
npm install @permaegis/harness-core
# or
pnpm add @permaegis/harness-coreRequires Node ≥ 18 (uses the built-in fetch).
Quick start
import { PermAegisHarness } from '@permaegis/harness-core';
const pa = new PermAegisHarness(process.env.PERMAEGIS_API_KEY); // pa_live_…
// 1. PRE-TOOL-CALL gate — is this tool within the agent's CapabilityGrant?
const d = await pa.gate('transfer', { to: '0xabc', amount: '5' }, {
grant: MY_GRANT, // observe-first: the agent holds the codec
tier: 'enforce', // 'observe' (default) never blocks; 'enforce' can deny
});
if (d.denied) throw new Error(d.reason);
// 2. OUTPUT/ACTION verify — does the observed action HONOR the declared want?
const v = await pa.verify(
{ to: TREASURY, outputToken: USDC, outputAtLeast: '1000000' },
observedActionResult,
{ tier: 'enforce' },
);
if (v.refunded) throw new Error(v.reason);A deny / refund is a successful 200 verdict (d.denied / v.refunded), not a
thrown error. HarnessError is thrown only for transport/HTTP failures and the API's own
{error:{code,message}} envelope.
Independent receipt verification
A deny/refund receipt is committed to a Merkle root anchored in the org audit log. Prove a single receipt belongs to that root in O(log N) — without trusting the server:
const r = await pa.verifyReceiptInclusion(receiptDigest, fromSec, toSec);
// { included: true, root, index, count, proofLen }Or verify a proof you already hold, offline:
import { verifyInclusion } from '@permaegis/harness-core';
const ok = verifyInclusion(leafDigest, proof, root); // booleanTesting without a network
The HTTP transport is injectable — pass transport to the constructor to unit-test with no
network:
const pa = new PermAegisHarness('pa_test', {
transport: async () => ({
status: 200,
body: JSON.stringify({ data: { decision: 'allow', tier: 'enforce', reason: 'ok' } }),
}),
});License
MIT
