@taifoon/jev
v0.2.14
Published
Grade AI agent jobs with TypeSafe's Jev and record the verdict on chain: code checks the facts, Jev answers a published rubric, and you get a receipt, the on-chain record and the evaluator call for ERC-8183 and Virtuals ACP. No runtime dependencies, no ke
Maintainers
Readme
@taifoon/jev
Did the AI agent do the work it was paid for? Ask Jev, and get an answer you can check.
- What: a grader for agent jobs. Code checks the facts, TypeSafe's Jev answers four closed questions about the delivery, and code turns the answers into complete, reject or needs review, with a receipt anyone can recompute.
- Why: agents are paid on chain for work nobody reads. A grade with its full probabilities, a published rubric and an appeal path is something a buyer, a seller and a contract can all rely on.
- How: replay a real Base job, graded by Jev, offline and with no key:
npx @taifoon/jev run --demo
Then grade your own with your TypeSafe key from console.typesafe.ai. Installing it also installs Taifoon's other packages (@taifoon/jev-wilson, @taifoon/n8n-nodes-typesafe). No key inside, and it signs nothing. Recording a grade on chain is optional.
Quick start
An agent was hired for a job. The grader answers one question: did it do the work as the task laid it out? You give it the job the way the buyer wrote it, and it does the rest:
import { prepareJob, facts, grade, record } from '@taifoon/jev';
const job = prepareJob({
id: 'job-4711', chainId: 8453,
task: 'Extract the invoice into JSON with invoice_no, total, currency and due_date',
criteria: ['Returns one JSON object with exactly the four fields', 'Every value matches the source invoice'],
source: 'INVOICE INV-20931 · Total due: EUR 1,240.50 · Payment due by 2026-10-01',
delivered: '{"invoice_no":"INV-20931","total":1240.50,"currency":"EUR","due_date":"2026-10-01"}',
checks: [{ kind: 'json', keys: ['invoice_no', 'total', 'currency', 'due_date'] }],
});
const receipt = await grade({ subject: job.subject, evidence: job.evidence, facts: facts(job.facts), key: process.env.TYPESAFE_KEY });
receipt.verdict; // complete | reject | needs_review, with every answer's full distribution
await record(receipt); // the unsigned calls that put it on chainWhat the grader needs, and where it comes from:
| Field | What it is | Who checks it |
|---|---|---|
| task | what the buyer asked for, in their words | Jev reads it |
| criteria | what "done" means, one per line | Jev reads them numbered |
| source | what the delivery must be faithful to (an invoice, a page, a dataset) | Jev compares against it |
| delivered | what the agent handed in | code first, then Jev |
| checks | includes · sources · json · deadline | code; a failed check rejects before Jev is asked |
Four illustrative jobs, written by hand, are in examples/jobs/: a research report that meets the brief, the same report
without its sources (code rejects it), an invoice extraction checked against its source, and a trading signal whose
claims the evidence cannot support. Grade one with your key:
TYPESAFE_KEY=… npx @taifoon/jev run --job-file examples/jobs/invoice-extraction.json
npx @taifoon/jev run --demo # offline, no key: replays the real Base job below and checks it against the chain
npx @taifoon/jev run # a live Base job from the coordination layer's queue (needs TYPESAFE_KEY)A real job, graded
BitAgent job 7287 on Base: a buyer paid
1.5 USDC for equity_research where ticker is 'AAPL'. The seller submitted within seconds, but only a 32-byte digest
reached the chain; the report itself was never shown. Code confirmed the job was funded and delivered, then Jev
(jev-1.13.0) answered on 27 September 2026:
| Question | Jev's answer | |---|---| | spec_met: does the delivery meet the task? | no 0.97 · yes 0.03 | | unsupported_claim | no 0.94 · yes 0.06 | | ending | needs_review 0.93 · complete 0.07 | | cheat_shaped | no 0.56 · yes 0.44 |
Code composed reject (spec_met ≤ 0.40) and the unsigned reject(uint256,bytes32,bytes) for BitAgent's evaluator
seat. The decision is anchored on the Taifoon devnet in
0xffc608f8…c622.
npx @taifoon/jev run --demo replays it from examples/jobs/base-bitagent-7287.recorded.json
with no key and no network, and arrives at the same decision digest.
In Claude Code and other agents
The repository ships a jev-grader skill that teaches an agent to grade a delivery the right way: the job as the buyer
laid it out, your own key from the environment, and needs_review surfaced instead of overruled.
claude plugin marketplace add taifoon-io/jev && claude plugin install jev@taifoon-jev # Claude Code
npx skills add taifoon-io/jev --skill jev-grader # Codex, Cursor, Cline and othersIn n8n
The same grader runs in n8n through @taifoon/n8n-nodes-typesafe,
with twelve ready-to-import judge workflows: grade an agent's delivery, grade a Base job from its record, fact-check a
chatbot answer, settle a refund dispute and more. See its README.
With a Taifoon key: record the grade on Base
examples/n8n/judge-base-job-record.workflow.json grades a Base
job and has the coordination layer write the grade to JevDecisionLog and JevAnswerLog on Base. It needs your TypeSafe
key and a Taifoon relayer key, issued by Taifoon (an n8n HTTP Header Auth credential, header X-API-Key;
GET https://coord.taifoon.dev/v1/relayer/whoami tests it). The output carries the verdict, the decision id and both
Base transactions with basescan links. Base recording is metered by a daily budget; over it the grade still stands and
the output says how to retry. Set record to none to grade without writing on chain.
jev run flags
Safe by default: your own TypeSafe key only, nothing recorded, nothing signed or sent. A typo is refused, never guessed.
| Flag | Default | What it does |
|---|---|---|
| --demo | off | Replays the real Base job above, offline, no key |
| --job <chain>:<id> | first ready job in the layer's queue | Grade one live job, e.g. 8453:bitagent:8453:7287 |
| --job-file job.json | | Grade a job you describe (see examples/jobs/) |
| --evidence pack.json | | Grade your own evidence pack, no layer |
| --answers answers.json | | Answers you already have (e.g. from the n8n node); Jev is not asked |
| --record none\|devnet\|base\|both | none | Opt in to the unsigned calls that record the grade on chain |
| --layer <https url> / --no-layer | https://coord.taifoon.dev | Where jobs and quotes are read |
| --protocol <name> | from the job id | Evaluator seat: virtuals-erc8183, virtuals-memo-acp, bitagent-erc8183, assurance-hook, judge-adapter |
| --price-usdc <n> | the job's budget | Price for the premium quote |
| --seller-record <k>/<n> | read from the layer | Price the premium here from the seller's record (k delivered of n graded) with @taifoon/jev-wilson: the layer's numbers, no request |
| --yes / --json | ask per step / text | Run every step without asking / print the whole trace as JSON |
Environment: TYPESAFE_KEY (your key; without it a job that needs Jev stops and says where to get one, while a job the
code checks reject is still graded). Exit codes: 0 done, 1 a step failed, 2 a flag was refused.
What you must know
- Code decides the facts first. A failed check ends the job as reject, and Jev is never asked.
- Jev answers four atomic questions from RUBRIC_v1: spec_met, unsupported_claim, ending and cheat_shaped. It never gets a holistic "is the job good?".
- Code composes the verdict under THRESHOLDS_v1: complete, reject or needs_review. needs_review ends nothing and leaves room for an appeal. Above 50 USDC a complete is held for review.
- Nothing is signed.
record()andevaluatorCall()return unsigned calls. Whoever holds the seat signs. - Your key. Jev is called with your own TypeSafe key from console.typesafe.ai, directly at TypeSafe. The key is not stored and never appears in a receipt.
- What the result is. Graded against a published rubric by a pinned decision model, with an appeal. It is not "independently verified". An on-chain record is an attestation by whoever sent it, not a proof the answer is right.
The six calls
| Call | What it does |
|---|---|
| prepareJob({ id, task, criteria, delivered, source?, checks? }) | Turns a job as the buyer laid it out into the evidence Jev reads and the code checks |
| grade({ subject, evidence, facts?, rubric?, key \| answers }) | Checks the facts, asks Jev the rubric, composes the verdict, returns the receipt |
| facts({ delivered, checks, priceUsdc? }) | Runs the checks your protocol supplies |
| record(receipt, { network, send? }) | Returns the unsigned JevAnswerLog.record and JevDecisionLog.record calls |
| evaluatorCall(protocol, jobId, verdict, digest) | Returns the one unsigned call that ends the job; null for needs_review |
| verify(receiptOrDigest) | Recomputes every digest and finds the records on chain |
verifyDecision(record, { answers? }) does the same for a decision as the coordination layer serves it at
/v1/judge/decisions/{id}: the input fingerprint, the decision digest, the answers digest and the verdict RUBRIC_v1
composes, all offline. npx @taifoon/jev verify decision-1790522234088-10691d5017 --network base runs it on the
block-proof grade and then finds both entries on Base.
Evaluator seats: assurance-hook, judge-adapter, virtuals-erc8183, virtuals-memo-acp and bitagent-erc8183.
Each is tested against calldata a mined transaction carried.
Documentation
- How grading works: Jev, the pipeline, THRESHOLDS_v1,
npx @taifoon/jev run - API: the six calls, where Jev is reached, your own rubric
- Evaluator seats, with the transactions they are tested against
- On chain: contract addresses on Base and devnet, and one real grade end to end
- The records: receipt, decision.v2, jev.answer.v1
- n8n workflows, and the TypeSafe node's Jev Options
- Develop
npx @taifoon/jev verify <digest> --network base
npx @taifoon/jev verify <decision id> --network base # recompute the served record offline, then find it on chain
npx @taifoon/jev workflows export ./jev-workflowsLicence
Independent project. Jev and TypeSafe are products of TypeSafe AI, Inc., which does not endorse this package.
Built by Taifoon. MIT. Its runtime dependencies are Taifoon's own packages, @taifoon/jev-wilson (the pricing) and @taifoon/n8n-nodes-typesafe; nothing third-party. It contains no key. It calls Jev only with your own TypeSafe key.
