@zanii/constitution
v0.1.0
Published
Machine-checkable behavioral constraints as signed policy - publish an agent's rules (forbid / require_approval / allow over scope patterns), stamp the constitution hash on every receipt via the existing manifest_hash field, then PROVE each action was gov
Readme
@zanii/constitution
Machine-checkable behavioral constraints as signed policy. The walls packages
(fta, walls) each hard-code one vertical's rules; this is the framework: publish
the agent's rules as a signed document, then prove every action was evaluated against
them — and prove they didn't change mid-process.
The mechanism reuses what already exists (zero server changes): a constitution's
canonical hash IS the manifest_hash an agent stamps on its receipts.
npm install @zanii/constitution @zanii/coreimport { createConstitution, constitutionHash, evaluate, verifyGovernance, governanceTrail } from '@zanii/constitution';
const c = createConstitution({
issuer: owner.did,
name: 'support-agent-rules',
rules: [ // FIRST MATCH WINS
{ id: 'no-payments', effect: 'forbid', targets: ['payments.*'] },
{ id: 'gate-outbound', effect: 'require_approval', targets: ['email.send', 'sms.*'] },
{ id: 'crm-ok', effect: 'allow', targets: ['crm.*'] },
],
defaultEffect: 'allow', // 'forbid' = deny-by-default (strict form)
createdAt: now,
}, ownerKey);
// at act time: evaluate + stamp the hash on every receipt
evaluate(c, 'payments.transfer'); // { effect: 'forbid', rule: {...} }
await zanii.record({ target, payload, provenance: { manifestHash: constitutionHash(c) } });
// at audit time: the deterministic governance verdict
const report = verifyGovernance(c, receipts);
report.violations; // 'forbidden' (stamped AND hit a forbid rule — self-incriminating)
// 'ungoverned' (missing/foreign stamp — visible, not silently fine)
report.approvals_required; // demand the owner-signed confirmations for these
governanceTrail(receipts); // which rulebooks governed the stream; interleaving = red flagPython: from zanii.constitution import create_constitution, verify_governance, governance_trail, ...
— byte-identical JCS objects and hashes.
Why this closes the loop
- Prove the rules — issuer-signed, content-addressed: change one rule and every subsequent receipt visibly points at a different rulebook.
- Prove they were followed — a stamped receipt whose target hits a
forbidrule is a provable violation the agent recorded itself. - Prove they held —
governanceTrailflags interleaved rulebooks (A,B,A): the same red flag@zanii/govraises when a state algorithm's rules change mid-process.
The limit, stated up front
The stamp proves an action was recorded as governed — act-time enforcement is
@zanii/runtime/@zanii/policy's job, and require_approval verification
(matching owner-signed confirmations) stays with the runtime; we report which actions
required approval so the auditor can demand the confirmations. An agent holding raw
credentials can still act off the rails entirely — credential custody, unchanged. A
constitution binds only when the verifier demands the stamp.
