EDlabsEDcheck

Read the result

safeParse returns success, data, and issues. This is how you use them on a form.

safeParse does not throw if the data is bad. It returns an object so you can decide what to show.

const result = await UserSemantic.safeParse(input); if (!result.success) {  return Response.json(result, { status: 400 });} // result.data is typed as the output of your Zod schemasaveUser(result.data);

The three parts

FieldWhat it means
successfalse only if some issue has severity: "error".
dataThe data already checked by Zod. It is there if the shape passed, even if a semantic rule failed.
issuesEvery problem in one array. Zod first, then EDcheck.

If Zod rejects the shape, data is missing. If Zod passed and EDcheck added a warning, data is there and success can still be true.

What an issue looks like

{  path: ["fullName"],  code: "semantic",  severity: "error",  message: "Semantic rule \"fullName\" failed",  outcome: "fail",  ruleId: "fullName",  probability: 0.18,  thresholds: { pass: 0.7, fail: 0.7 },}
FieldWhat it is for
pathWhich field should show the error. Use it to paint the input red.
codesemantic if meaning failed. semantic_unavailable if the AI did not answer.
severityerror, warning, or info.
messageText for the user or for your logs.
ruleIdWhich rule fired. Useful so you do not show the same error twice.
probabilityHow sure the AI was (yes/no rules).

Show errors on the form

Group issues by the first value in path. Then each input can show its own message.

function messagesByField(issues: { path: Array<string | number>; message: string }[]) {  const map = new Map<string, string[]>();   for (const issue of issues) {    const key = String(issue.path[0] ?? "");    const list = map.get(key) ?? [];    list.push(issue.message);    map.set(key, list);  }   return map;}

Thresholds (how strict the AI is)

The AI does not say a hard yes or no. It gives a number between 0 and 1. EDcheck cuts it like this:

  • p >= pass → pass (no issue)
  • fail <= p < pass → warning
  • p < fail → fail

By default pass and fail are 0.7. That means: 70% or more passes, below 70% fails. There is no warning band unless you open one.

const edcheck = createEDcheck({  provider,  thresholds: { pass: 0.8, fail: 0.4 },});

With that: 0.8 or more passes, between 0.4 and 0.8 is a warning, below 0.4 fails.

You can set thresholds on the instance, the schema, or one rule. The most specific one wins: rule > schema > instance > the default.