What Proof-of-Work was to Web3, Proof-of-Outcome is to Web7.
Given an Intent I and an Outcome O, Proof-of-Outcome asserts:
O was produced by a specific agent AA used a specific model / code M with attested weights / hashM(input) = output — verified by ZK-ML proofA was authorised by the principal's signed delegationO was attested under a specified policy PS follows deterministically from O| PoW | PoS | PoO | |
|---|---|---|---|
| Secures | block ordering | block ordering | intent → outcome |
| Cost | compute | stake | reputation + stake |
| Slashing | n/a | equivocation only | 6 failure modes |
| Relevant to user | ✗ | ✗ | ✓ Direct |
| AI-aware | ✗ | ✗ | ✓ ZK-ML |
PoW/PoS make the chain honest. PoO makes the agent honest.
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.
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
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.
| Check | What failed | Likely cause | How 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 |
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.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)
| Rail | PoO pass | PoO fail |
|---|---|---|
amp-escrow | Milestone funds released | Escrow forfeit → slash + refund |
amp-outcome | Full payout to agent | Full refund to principal |
amp-subscription | Cycle billing proceeds | Cancel + partial refund |
amp-split | Split distributed per % | Pro-rata reduction per failed agent |
| Cause | Slash % | Distribution |
|---|---|---|
| Bad ZK-ML proof | 100% | 50% → principal, 50% → treasury |
| Signature forgery | 100% | 50% → principal, 50% → treasury |
| Policy violation | 50% | 50% → principal, 50% → treasury |
| Missed SLA | 10–30% | 100% → principal compensation |
| Failed attestation | 25% | 50% → principal, 50% → treasury |
| Unavailability | 5–15% | 100% → principal compensation |
// 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)
v0.1 ships without production ZK-ML. The inference check accepts either:
proof field present. Full circuit verification at mainnet.