The five layers
1 · The circuit
A Noir circuit proves, in zero knowledge: possession of a credential secret, membership of its commitment in the approved root, correct nullifier derivation, and binding to the exact action.
2 · The issuer
Builds the approved-credential Merkle tree, issues membership witnesses, and rotates the root to revoke. (v0 reference issuer — no real KYC.)
3 · The contract
One Soroban contract that registers policies, verifies proofs on-chain, prevents replay, and executes the bound action atomically.
4 · The SDK & CLI
@nullis/sdk submits verify_and_execute in one call; @nullis/cli validates policy manifests and renders receipts.System diagram
The contract modules
| Module | Responsibility | Functions |
|---|---|---|
| Policy | Policy registry, versioning, root rotation | create_policy, publish_root, rotate_root, disable_policy, get_policy |
| Nullifier | Replay prevention | is_spent, mark_spent |
| Verifier | On-chain UltraHonk proof verification | verify |
| Executor | The core primitive | verify_and_execute |
Canonical events
Every decision emits typed events, so the whole flow is inspectable from the ledger:PolicyPublished · RootRotated · ProofVerified · ActionExecuted · ActionRejected(reason) · ReplayBlocked · ReceiptEmitted
The execution adapter
v0 uses an escrow model: the contract holds test tokens and releasescontract balance → recipient on success. This is a reference execution adapter, not the final design — the production path is an authorized transfer (sender → recipient in the same transaction).
The escrow adapter is deliberately labeled and disclosed. See the honesty table for what is real vs. what is a reference implementation.
Next: the atomic primitive
Walk
verify_and_execute step by step — the exact order of checks.