zkzkMCP
Policies

Private numeric limits

Prove that an action stays inside hidden numeric limits, with optional approval escalation, without publishing the threshold values.

Private numeric limits are useful when the authorization rule itself is sensitive.

An organization may want an agent to prove:

requestedAmount <= privateMaximum

without publishing the actual maximum to every verifier or observer.

The current payments.transfer branch demonstrates two private numbers:

maxPaymentAmount
paymentApprovalThreshold

Gateway mapping

A payment tool may receive:

{
  "amount": 2750,
  "recipient": "client-settlement-account",
  "memo": "Thompson settlement disbursement"
}

The current normalizer validates amount as a non-negative safe integer and converts it to a bigint for the authorization envelope:

{
  agent: "LegalAgent",
  tool: "payments.transfer",
  amount: 2750n,
  approved: false
}

The recipient and memo remain application arguments but are not currently part of the numeric policy statement.

Hard maximum

The first payment constraint is absolute:

requestAmount <= policy.maxPaymentAmount

Approval cannot override it.

For the demo:

maxPaymentAmount = £5,000

so an £8,000 request fails even when approved == true.

Approval threshold

The second constraint provides an escalation zone:

requestAmount <= paymentApprovalThreshold
OR approved == true

The demo uses:

paymentApprovalThreshold = £4,000

The resulting policy has three regions:

0                           £4,000                     £5,000
├─────────────────────────────┼───────────────────────────┼────────→
│                             │                           │
│ allow without approval      │ approval required         │ deny
│                             │                           │ even with approval

Example outcomes

AmountTrusted approvalResultWhy
£2,750absentauthorizedbelow approval threshold and hard maximum
£4,500absentdeniedbelow hard maximum but approval required
£4,500verifiedauthorizedapproval satisfies escalation rule
£8,000verifieddeniedexceeds hard maximum

The caller does not receive the exact private reason for a denial. Public policy failures collapse to policy.AUTHORIZATION_DENIED.

What the verifier learns

A successful public receipt can prove that the authorization branch completed under the committed policy without exposing:

requested amount
private maximum
approval threshold
approval token

The local gateway/prover still knows the request amount and its own private policy. Zero knowledge is being used to separate the private authorization environment from the public verification state.

Why a random policy secret is included

A numeric policy alone can be low entropy.

If the commitment were simply:

hash(maximum = 5000, threshold = 4000, ...)

an observer might enumerate plausible small values and compare hashes.

The policy commitment therefore includes a random private 32-byte secret in addition to the numeric rules.

Numeric representation

The Compact contract uses:

Uint<64>

for the current amount fields.

The TypeScript gateway currently accepts safe non-negative JavaScript integers and converts them to bigint before the Midnight call.

For real financial systems, amount representation needs a stricter domain model:

minor currency units (e.g. pence/cents)
currency code
asset/token identifier
rounding rules
maximum precision

A production proof should not rely on ambiguous floating-point monetary values.

Stronger numeric policies

The same pattern can express more than payments.

Examples:

API cost <= private budget
compute request <= private resource quota
trade size <= private risk limit
discount <= private sales authority
refund <= private approval limit
data export rows <= private threshold

The important part is defining the requested quantity and private threshold in a deterministic circuit-friendly representation.

Current coverage boundary

The payment policy does not currently constrain:

recipient
currency
memo
matter/client context
payment rail

Therefore the current receipt should be read precisely:

the requested numeric amount satisfied the committed payment-limit rules for this authorized agent/tool branch.

It is not yet a proof that the exact full financial transfer payload was permitted.

See Circuit constraints for the complete branch predicate and Authorization envelope for how application arguments become proof facts.

On this page