defineEvalis pass/fail. It answers “was it done this time”, and you read the pass rate. It suits tasks that are only meaningful when everything holds, such as tests that must pass or keys that must not leak.defineScoreEvalis scored. It answers “how much was done”, and you read the accumulated score. It suits tasks with partial progress, such as step-by-step installation or several quality requirements.
niceeval check, --dry, and normal runs all reject mixing them before starting the Agent or Sandbox; when you need both readings, split them into two Experiments.
Use defineEval for what must be done
matched goes into the Verdict; mismatched makes the final Verdict failed, but does not stop other Assertions from being registered and settled. When later code must depend on this result, await handle.orStop().
Continuous quality thresholds
Matches such assimilarity(...) produce a measurement in [0, 1]. It computes character-level Levenshtein edit similarity and does not judge meaning. A pass/fail eval sets a quality gate on the handle with .gate(minimum):
t.diagnostic(...); do not register a measurement nobody consumes.
Three steps done should still earn three points
Step-by-step tasks suitdefineScoreEval. An Assertion only saves its evaluation by default and does not score; only .score(n) makes it contribute points. A Boolean matched contributes n and mismatched contributes 0; a measurement m contributes m * n.
t.score(n) registers a contribution directly. n must be finite and not less than zero, and the returned handle can only configure key and label. A Judge or other measurement can call .gate(minimum) and .score(n) on the same handle in either order, and the evaluator runs only once.
When test returns normally, NiceEval computes the final score automatically. Having no scoring items is also a valid result and yields a formal score: 0; it means the eval successfully produced a zero, not an execution failure or missing evidence.
Results of the two kinds
A complete score in a scored eval can be 0.
passed + complete 0 means the eval successfully produced a zero, which is not an execution failure or missing evidence; failed + complete must still show as a failure and cannot be rewritten as success just because the value is complete.
The Judge is a measurement too
defineJudge declares a managed Judge Match. The author assembles the values needed for the judgment into material with semantic fields.
The Judge can be passed straight to t.judge without registering it on the eval. The model defaults to the project’s judgeProvider; to switch only the model for one eval, set judge: "judge-model".
.gate(minimum) and .score(points) on the same Judge;
the measurement times points gives the contribution, and the gate decides the Verdict. The same Judge runs only once.
Accept code tasks with real commands
loadText. Changing the file triggers a rerun of the matching evals; see Hidden Test Scoring.
Practical advice
- Register each condition that must hold as a Boolean Assertion, so one Attempt collects complete failure information.
- Split open-ended standards that can fail independently, be weighted independently, or need separate diagnosis into several Judges.
- Use one Judge’s measurement times a single weight only for an indivisible overall quality dimension.
- When later steps depend on a result,
await handle.orStop(). - Use
defineScoreEvalwhen a task has meaningful partial completion; it wraps up automatically whentestreturns normally. - Use the Judge for open-ended meaning; prefer deterministic Matches for files, commands, and structured output that can be checked exactly.