Protocol Spec · v0.1

Proof-of-Outcome

What Proof-of-Work was to Web3, Proof-of-Outcome is to Web7.

What PoO Proves

Given an Intent I and an Outcome O, Proof-of-Outcome asserts:

  • O was produced by a specific agent A
  • A used a specific model / code M with attested weights / hash
  • M(input) = output — verified by ZK-ML proof
  • A was authorised by the principal's signed delegation
  • O was attested under a specified policy P
  • Settlement S follows deterministically from O
"This outcome is verifiably what you asked for, produced by an accountable party, under agreed rules."

Why Not PoW / PoS?

PoWPoSPoO
Securesblock orderingblock orderingintent → outcome
Costcomputestakereputation + stake
Slashingn/aequivocation only6 failure modes
Relevant to user✓ Direct
AI-aware✓ ZK-ML

PoW/PoS make the chain honest. PoO makes the agent honest.

The PoO Formula

PoO(I, O) = verify {
  σ_principal(I)              // principal signed the intent
  ∧ σ_prime(D)                // Prime signed the delegation from I
  ∧ σ_agent(Inf)              // agent signed the inference envelope
  ∧ σ_agent(O)                // agent signed the outcome
  ∧ lineage(O.parent == Inf.id) // AIG parent chain is intact
  ∧ zk_ml(M, input, O)        // model produced this output (or attestor fallback)
  ∧ policy_check(P, A, O)     // org policy satisfied
  ∧ stake(A) ≥ required(I)    // agent had sufficient stake
}

All checks must pass. Any failure triggers slashing and escrow refund.

Verification Checks

🔍 PoO check matrix
intentSig
Principal's ed25519 signature over the intent envelope is valid.
boolean
delegationSig
Prime's signature over the delegation envelope is valid.
boolean
inferenceSig
Agent's signature over the inference envelope is valid.
boolean
outcomeSig
Agent's signature over the outcome envelope is valid.
boolean
lineage
outcome.parent === inference.id. AIG causal chain is unbroken.
boolean
inference
ZK-ML proof OR k-of-n attestor bundle verifies the inference.
boolean
policy
Policy engine allows this action for this agent in this context.
boolean
stake
Agent's staked reputation meets the minimum required by the intent.
boolean

TypeScript implementation

import { PoOVerifier } from "@hyperbridge/forge/poo";

const verifier = new PoOVerifier({ requiredAttestors: 2, minStake: 10 });

const result = await verifier.verify({
  intent, delegation, inference, outcome,
  zkmlProof: { model: "did:w7:model/tax-v2@sha256:abc", inputHash, outputHash, proof },
  attestors: ["did:w7:attestor/a1", "did:w7:attestor/a2"],
});

// result.ok === true means all required checks passed
// result.checks: { intentSig, delegationSig, inferenceSig, outcomeSig,
//                  lineage, inference, policy, stake }
// result.reasons: { [check]: string } — explains any failure
// result.score: number — weighted 0–1 across all 8 checks

Common PoO Failure Modes

When result.ok === false, inspect result.checks and result.reasons to pinpoint which check failed. The table below maps each failure to its root cause and fix.

CheckWhat failedLikely causeHow to fix
intentSig Principal's signature over the intent envelope is invalid Intent was mutated after signing, or wrong key used Re-sign with amp.sign(intentEnv, principalKey) after all fields are final
delegationSig Prime's signature over the delegation envelope is invalid or absent Delegation was created without a key, or auth.sig field missing Confirm Prime signs the delegation before returning it; check delegation.auth.sig is non-null
inferenceSig Agent's signature over the inference envelope is missing or invalid Agent emitted the inference without signing it Call amp.sign(inferenceEnv, agentKey) before attaching to the PoO context
outcomeSig Settling party's signature over the outcome envelope is invalid Outcome was assembled by a different process than the one holding the key Ensure the agent that produced the outcome signs it; do not reconstruct the envelope after signing
lineage AIG causal chain is broken — parent IDs don't match across envelopes Envelopes were assembled out of order, or parent field was omitted Verify: delegation.parent === intent.id, inference.parent === delegation.id, outcome.parent === inference.id
inference Neither a valid ZK-ML proof nor sufficient attestors were provided Attestor list too short (default minimum: 2) or zkml proof malformed Add attestors up to requiredAttestors threshold, or provide a well-formed zkmlProof object
policy Policy engine rejected the outcome for this agent/context Domain not in allowlist, token budget exceeded, or custom rule violated Read result.reasons.policy for the specific constraint; adjust intent payload or agent permissions
stake Agent's domain reputation stake is below the configured minimum New agent with no history, or wrong domain scoping Raise agent stake via the reputation module, or lower minStake in the verifier config for low-value intents
💡
Checks marked required: true in CHECKS (intentSig, delegationSig, inferenceSig, outcomeSig, lineage, policy) block result.ok. Checks marked required: false (inference, stake) reduce result.score but do not block settlement when running in v0.1 fallback mode.

Custom Policy Engine

Pass a policyEngine function to PoOVerifier to enforce any business rule — domain allowlists, token budgets, rate limits, compliance flags. The function receives the raw intent and outcome envelopes and returns { ok, reason }.

import { PoOVerifier } from "@hyperbridge/forge/poo";

// Policy engine factory — returns a policyEngine function
function buildPolicyEngine(
  allowedDomains: string[],
  maxTokenBudget: number,
  blockedAgents: string[] = [],
) {
  return (intent: any, outcome: any): { ok: boolean; reason: string } => {
    const domain = intent?.payload?.domain ?? "";
    if (!allowedDomains.includes(domain))
      return { ok: false, reason: `domain '${domain}' not in allowlist` };

    const agentDid = outcome?.from ?? "";
    if (blockedAgents.includes(agentDid))
      return { ok: false, reason: `agent ${agentDid} is blocked` };

    const tokensUsed = outcome?.payload?.usage?.totalTokens ?? 0;
    if (tokensUsed > maxTokenBudget)
      return { ok: false, reason: `token usage ${tokensUsed} exceeds budget ${maxTokenBudget}` };

    return { ok: true, reason: "policy satisfied" };
  };
}

// Wire it into a verifier
const verifier = new PoOVerifier({
  policyEngine: buildPolicyEngine(["tax-filing", "invoice-gen"], 50_000),
  requiredAttestors: 2,
  minStake: 10,
});

const result = await verifier.verify({ intent, delegation, inference, outcome, attestors });

if (!result.ok) {
  const failed = Object.entries(result.checks)
    .filter(([, v]) => !v)
    .map(([k]) => `${k}: ${result.reasons[k]}`);
  console.error("PoO failed:", failed);
  // → e.g. ["policy: domain 'crypto-trading' not in allowlist"]
}

console.log("PoO score:", result.score.toFixed(2));
// → "PoO score: 0.94" (weighted across all 8 checks)

Settlement Under PoO

RailPoO passPoO fail
amp-escrowMilestone funds releasedEscrow forfeit → slash + refund
amp-outcomeFull payout to agentFull refund to principal
amp-subscriptionCycle billing proceedsCancel + partial refund
amp-splitSplit distributed per %Pro-rata reduction per failed agent

Slashing Rules

CauseSlash %Distribution
Bad ZK-ML proof100%50% → principal, 50% → treasury
Signature forgery100%50% → principal, 50% → treasury
Policy violation50%50% → principal, 50% → treasury
Missed SLA10–30%100% → principal compensation
Failed attestation25%50% → principal, 50% → treasury
Unavailability5–15%100% → principal compensation

Reputation Effect

// On verified PoO (success)
reputation(A) += outcome_value × principal_stake × domain_match × age_decay

// On failed PoO
reputation(A) -= severity × 2 × base_score

// Properties:
// - Non-transferable (cannot be sold or delegated)
// - Domain-scoped (tax-filing rep ≠ medical-coding rep)
// - Exponential decay: half-life = 6 months
// - Slashable (floor: 0)

Minimum Viable PoO (v0.1)

v0.1 ships without production ZK-ML. The inference check accepts either:

  • ZK-ML proof stub — well-formed struct, proof field present. Full circuit verification at mainnet.
  • k-of-n attestor bundle — N attestors sign the inference payload; k must verify (k=2 default, N=3 default).
💡
This means apps can deploy PoO today using the attestor fallback and upgrade to ZK-ML transparently when L0 mainnet ships — no code changes required.