comet eval works out of the box to evaluate built-in tasks and any local Skill — evaluating your own Skill takes just one command, comet eval ./your-skill --html (see Quickstart). If you only need stable acceptance conditions for a local Skill, prefer declaring an inline task in that Skill package’s comet/eval.yaml, or reference a package-local task with source. Only create and register a task under eval/local/tasks/ when you are extending Comet’s built-in harness. This article walks you through the complete customization path: defining a task, configuring an evaluation profile, and running a report.
This article is advanced customization. If you just want to evaluate an
existing Skill, you don’t need to read it — just use
comet eval ./your-skill —html. For a Skill-specific inline task,
edit comet/eval.yaml under the Skill root. This article assumes
you can already run comet eval ./your-skill —collect
successfully.The Big Picture of Eval Configuration
A complete eval is assembled from three parts, and understanding their division of labor is the foundation of customization:
Task decides what to test, Treatment decides what to inject, Profile and Rubric decide how to score
Let’s explain each one below.
Define a Task
Each task is a directory underlocal/tasks/ containing four files:
local/tasks/my-task/
task.toml
instruction.md
environment/
Dockerfile
validation/
test_my_task.py
For an ordinary local Skill, put inline tasks in
comet/eval.yaml
under that Skill’s root, or use source for a task package stored
in the Skill package. The directory convention in this section comes from the
eval harness (eval/), not your business repo: tasks under
eval/local/tasks/ are for extending the Comet repository’s
built-in harness and must be registered in
eval/local/tasks/index.yaml.1. Write task.toml
task.toml is the core configuration of a task, divided into four sections:
Key fields in [evaluation]
These fields directly determine the scoring result and deserve separate explanation:
2. Write instruction.md
This is the task instruction for the agent, supporting template variables like {run_id}:
3. Write the validation script
The validation script runs inside Docker and writes results to_test_results.json. This is the source of truth for “did this run get it right”:
failed list reported by the validation script is empty. Both pass@k and pass^k are based on this judgment.
4. Write the Dockerfile
The Dockerfile provides the runtime and dependencies needed for validation. A minimal example:5. Register the task
Finally, register it inlocal/tasks/index.yaml:
--task my-task.
Configure Treatment
Treatment answers “which Skills to inject in this run”. Located atlocal/treatments/:
Choose a Profile
The profile determines which rubric to score with. Choosing the wrong profile makes the dimension scores meaningless:Profile resolution priority:
—profile override > manifest’s
skill.profile > task’s evaluation.profile >
generic. Comet-type tasks (category = “comet”) are
automatically inferred as comet-workflow.Configure LLM-as-judge
LLM-as-judge is an optional quality coverage layer. It does not replace rule-based[RUBRIC] scores and does not directly change weighted_score. It lets an independent judge model read the run artifacts and append [RUBRIC-JUDGE] scores, helping you catch cases where rule checks miss whether the artifact has real substance.
Use it when:
- You evaluate documents, plans, code explanations, designs, or other artifacts that are hard to judge completely with scripts.
- You already have validation scripts, but want to know whether the artifact is empty, shallow, or template-like.
- You want comparison reports to show the gap between rule scores and judge scores.
Judge configuration is isolated from the subject Agent configuration. The
subject Agent can keep using
ANTHROPIC_MODEL,
ANTHROPIC_BASE_URL, and its own token. The judge must explicitly
set BENCH_JUDGE_MODEL so the same configuration does not silently
act as both contestant and judge.1. Enable judge in eval/.env
Add judge variables to the Comet repository’s eval/.env:
BENCH_LLM_JUDGE=1 is the switch. BENCH_JUDGE_MODEL is required. If you enable the switch without setting a model, the report records a skipped status:
2. Choose judge authentication
If the local hostclaude CLI is already authenticated, you can set only BENCH_JUDGE_MODEL. The harness calls the host claude CLI for judge runs.
If you want the judge to use an independent Anthropic-compatible proxy, configure a dedicated endpoint and token:
If both
BENCH_JUDGE_AUTH_TOKEN and BENCH_JUDGE_API_KEY are set, the auth
token wins. The judge subprocess clears inherited main ANTHROPIC_* provider
variables before mapping BENCH_JUDGE_*, so do not expect it to reuse the
subject Agent provider configuration automatically.3. Add custom judge criteria for generic tasks
Generic Skills (generic / authoring-skill) make the judge output three default dimensions:
If your task has task-specific quality criteria, put them in
[evaluation] in task.toml:
custom_0, custom_1. They only affect the [RUBRIC-JUDGE] coverage layer and do not replace your validation scripts.
The comet-workflow profile uses a different judge dimension set: artifact_quality, spec_drift, and main_flow. These dimensions review workflow artifact depth, whether the spec drifted, and whether the five-phase main flow completed.
4. Run and confirm judge output
First use--collect to confirm tasks, manifests, and paths can be discovered:
Report path and look for [RUBRIC-JUDGE] lines in each run’s checks. A successful run looks like this:
Multi-turn interaction: auto_user mode
A single-turn task (mode: none) runs only once, suitable for simple scenarios of “give an instruction and see the result”. But workflow-type Skills need to pause at decision points, ask the user, and continue after receiving a reply — single-turn can’t test this.
auto_user mode solves this: it uses two Agents interacting automatically — one runs the Skill under test (subject), the other simulates the user replying at decision points (simulator).
The simulator’s behavior is controlled by a prompt file. It reads eval/simulator-instruction.md by default, and you can point BENCH_SIMULATOR_PROMPT_FILE to your own version to simulate “a more demanding user” or “a user who asks for clarification”:
max_turns controls the loop limit (comet-workflow typically 12 outer round-trips, authoring-skill typically 8 outer round-trips). It is not the number of internal messages or tool calls of the Agent under test; one outer round-trip means the Agent under test reaches a decision point, the user simulator replies, and the Agent under test continues with --resume. Hitting a “complete” signal (such as archive complete) ends the loop early.
A complete custom evaluation from scratch
Putting the above steps together, to evaluate your own Skill from scratch:pass@1andpass^k: capability ceiling vs reliability floor. See Scoring Metrics.- Rubric dimension scores: which dimension dragged you down?
- Failure attribution (
harness/workflow/task/model): is the failure a Skill problem, or a task/environment problem?
Evaluating /comet-any generated bundles
A Skill bundle generated by /comet-any comes with its own comet/eval.yaml manifest, so you don’t need to hand-write a task.toml. Just run with the manifest:
authoring-skill profile, injects recommended tasks and quality gates. For the complete manifest format, see Evaluation System Overview.
Next steps
- Scoring Metrics and Dual-Agent Evaluation — dimensions, weights and pass@k/pass^k of the three rubrics
- Evaluation System Overview — manifest format, profile system and task system
- comet eval command — complete command-line argument reference

