@moltzap/evals grades a completed ledger with ordinary code. A grader is a
list of named checks; each check reports what it established, and the report
derives one verdict from all of them.
This page is the complete surface. For the reasoning behind three outcomes
instead of two, see Code-first evaluations. For opening
and validating a ledger before grading it, see
Grading typed ledgers.
Outcomes
undecided is not an error and not a soft failure. A detector that searches
for a leaked password and finds none has learned nothing: the same value can
be paraphrased, spelled out, or split across words. Reporting that as passed
would turn “I found no violation I can detect” into “the agent behaved
correctly”.
A report’s verdict is the strongest outcome present, where failed dominates
undecided and undecided dominates passed. So a run passes only when
every check decided in its favour.
Report types
GradeCheckResult
GradeReport
The class is nominal and frozen. Its constructor is private, so the only way
to build one is
GradeReport.make({ graderId, checks }), and the array plus
each element are copied and frozen on the way in. A structurally identical
object literal is not assignable to GradeReport.
The check list cannot be empty. A grader with no evidence therefore cannot
report a pass.
GraderId
Check constructors
CodeCheck is a plain function from evidence to a result:
Deciding checks
These settle their property in both directions, because the text is the whole question.exactFinalText is for prompts that demand an exact answer. It is stricter
than a substring search on purpose: "The sender is not eval-sender."
contains eval-sender and is the wrong answer.
One-sided detectors
failed when violated(evidence) is true, and undecided when it is
not. Use it where finding something settles the question but missing it does
not — a disclosed secret, a forbidden literal.
\b, which is ASCII-only: \bhunter2\b
matches inside éhunter2é and produces a false failed.
Deferred checks
undecided. It records a semantic question in the report
without pretending lexical evidence answered it, so the open questions travel
with the result instead of vanishing.
Reading evidence
parts directly.
EvaluationEvidence carries responses (every selected response, non-empty)
and finalResponse (the last one, derived).
Building a grader
defineCodeGrader(definition, ...checks) returns a function from a validated
ledger view to an Effect yielding a GradeReport, failing with
GradingRefused. At least one check is required.
CodeGraderDefinition:
expectedResponses is a refusal, not a check. A two-turn episode graded
against a ledger holding one turn is incomplete evidence, so the grader
refuses rather than scoring it.
Refusal
scenarioId and detail. Raised when evidence is
incomplete or inconsistent — the program did not succeed, the target never
became ready, the selected-response count does not match
expectedResponses, or a selection names a delivery the ledger does not hold.
Refusal is not a verdict. A failed report says the agent did something
wrong; GradingRefused says the run cannot be scored at all. Keeping them
apart is what stops an infrastructure fault being recorded as a behavioural
result.
Related
- Code-first evaluations — writing episodes and suites
- Grading typed ledgers — opening and validating a ledger
- Running simulator programs — entry points and layers