packages/evals is a private, code-first customer of
@moltzap/simulator. A bundled case is an immutable TypeScript value with
the exact autonomous peer definitions and policy it needs. At execution time,
each definition becomes one Agent Sandbox application container in the cell’s
RunSpec roster.
Most additions change cases.ts, grading.ts, and their tests. Change
peer.ts only when the required autonomous network behavior is genuinely new.
Change principal.ts only when adding a runtime condition with a new native
principal gateway.
1. Choose stable identities
Pick an unusedEVAL-NNN case identity, a versioned simulator definition
identity, and a versioned criterion identity. They evolve independently:
- change the definition version when the case program or evidence meaning changes;
- change the criterion version when its question or deterministic decision changes; and
- never reuse a persisted identity for new semantics.
2. Declare the exact peer definitions
The target runtime belongs to the OpenClaw or NanoClaw condition. The case owns only the autonomous code peers it needs:context.peers. A case with no social peers
uses an empty record. Do not add idle peers to a shared roster; only the
runtimes in this record are started.
Each peer factory returns an image-independent EvaluationPeerDefinition with
a closed application plan. Evaluation execution binds that definition to the
configured digest-pinned peer image, mounts its bootstrap data, and runs the
plan through peer-application.ts → runEvaluationPeerApplication inside the
peer’s application container.
The application uses its production MoltZap client, so every social send and
receive traverses the protocol and router. Its peer-specific bridge exposes an
EvaluationPeerGateway that reports a completed exchange to the evaluation
controller. It is observation-only and cannot command a social action.
3. Write a policy that returns one selection
AnEvaluationCaseProgram receives native target instruction and peer
observation capabilities:
The program returns exactly one
EvaluationEvidenceId. After successful
completion, the interpreter emits the corresponding
EvaluationEvidenceSelected event. There is no mutable selection registry or
separate completion check.
A social case can ignore the option returned by instruct and select
router-bound peer evidence, as the example does. A case that grades native
principal output must pass that option to selectPrincipalOutput. A runtime
whose gateway cannot correlate terminal output then produces an
EvaluationProgramFailed execution result instead of fabricated evidence.
When a required peer exchange reaches its configured deadline,
selectPeerOutput returns the typed timeout evidence identity. That preserves
bounded absence as gradeable evidence. A peer implementation failure, native
gateway failure, unsupported principal-output selection, target termination,
or overall case timeout remains an execution failure.
4. Define the case and criteria
Add the case beside its neighbors inpackages/evals/src/cases.ts:
decide function has two honest outcomes:
CriterionDecidedfor a conclusivepassedorfailedresult with evidence-ID citations; orNeedsJudgewhen semantic assessment is still required.
5. Add new container peer behavior only at the network boundary
Reuse the focused policies inpeer.ts when they match:
If none fits, add one closed autonomous application plan interpreted inside
the peer container through the production client. Its bridge gateway should
expose only the smallest observation needed by case execution. Do not add a
generic queue of commands, a second request protocol, or a direct social
callback. Arbitrary Effect closures and gateway objects do not cross the
container boundary.
The peer’s
PeerExchange.observations are in protocol order. For a selected
exchange, the final observation is the one returned to case policy; test that
ordering explicitly.
6. Add a principal adapter only for a new runtime
OpenClaw and NanoClaw already have separatePrincipalDriverFactory
implementations. Each factory creates a per-attempt PrincipalDriver, and
drive returns Option<EvaluationEvidenceId>. They preserve their native
contracts instead of normalizing them:
- OpenClaw uses its persistent gateway RPC and records attempted instruction
plus terminal output. Its factory owns the per-attempt native idempotency
sequence and returns
Some(outputEvidenceId). - NanoClaw submits to its owner-local socket, records
NanoClawPrincipalInputSent, and returnsNone. Its output is an uncorrelated multi-frame stream, so the adapter never consumes the next frame or attributes it to the input.
Gateway and failure types, write
a matching PrincipalDriverFactory<Gateway, Failure>, and capture both with
execution.ts → evaluationCondition. Return Some only for output correlation
the native gateway actually guarantees. Keep runtime-specific sessions,
acknowledgments, idempotency, and streaming semantics inside that adapter.
7. Extend the event catalog deliberately
Most new cases reuse the current gateway, social, timeout, and selection events. When a new instrument makes a genuinely new claim:- add a versioned
Schema.TaggedClassinevents.ts; - include it in
events.ts → evaluationEvents; - project and validate it at the ledger boundary; and
- update transcript and report schemas if grading consumes it.
8. Register the case and calibration
Append the definition tocases.ts → evaluationCases. That tuple is the
canonical order for execution plans, reports, and Phoenix dataset examples.
If any response can reach NeedsJudge, add discriminating passing, failing, or
undecided examples to the calibration definitions in grading.ts.
grading.ts → semanticJudgeCalibrationFixtures binds each example back to
the current case, criterion, transcript item kind, selection, and citations.
Include adversarial evidence when the behavior involves disclosure, injected
instructions, attribution, or conversation boundaries.
9. Pin construction and evidence invariants
Update the exact catalog order and peer-key expectations incases.test.ts.
Test the program’s operation order and returned evidence identity.
Use the owning tests for each additional invariant:
peer.test.tsfor production-client behavior and ordered observations;execution.test.tsfor native prelude, one final selection, and timeout selection;events.test.tsfor router corroboration and selection ordering;grading.test.tsfor target identity, selected-output validation, deterministic decisions, judge citations, and calibration coverage; andsweep.test.ts,results.test.ts, orphoenix.test.tsonly when the persisted or materialized contract changes.
Verification
Related
- Code-first evaluations — execution, resume, and Phoenix publication
- Evaluation grading reference — evidence, decisions, assessments, and failure states
- Grading typed ledgers — the simulator evidence boundary