Skip to content

[feat] evaluation profiles and run stamps - #32

Merged
Thibaut-Fatus merged 5 commits into
mainfrom
feat/evaluation-profiles
Sep 7, 2026
Merged

Thibaut-Fatus merged 5 commits into
mainfrom
feat/evaluation-profiles

Conversation

@Thibaut-Fatus

@Thibaut-Fatus Thibaut-Fatus commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Why

Runs must use the same LLM configuration for every step and document it so others can reproduce them. Until now results only recorded registry slugs, the per-role defaults were hardcoded in cli.ts, nothing recorded prompt versions or the commit, and the restart caches keyed only on scenario id, so re-running with different judges silently reused old results.

What

  • Evaluation profiles (profiles/<name>.json, next to models.json): inline model config for every harness role (seeds, expansion, expansionUser, user, judges, continueUser) plus a content hash. profiles/kora.json reproduces the previous defaults; a test asserts every role matches its models.json entry. Global --profile / KORA_PROFILE.
  • Local profiles for testing: profiles/*.local.json are gitignored, hash-unchecked, marked local in the stamp. cp profiles/example.local.json.example profiles/x.local.json then --profile x.local.
  • kora profile [--check | --print-hash]: prints the resolved configuration; --check pings every model and reports the served id and latency; --print-hash prints the hash to paste after a version bump.
  • CI guards: tests recompute every committed profile hash and the prompts fingerprint and fail with the expected value when either changes without a bump.
  • Overrides: [model], [user-model], --judges still work, resolve through models.json, warn, and produce a different profile hash with overrides: [...] in the stamp.
  • Run stamp on every seed, scenario, per-test result and result header: effective profile, resolved model configs, target reference, prompts fingerprint, code (version, commit, dirty), packs, input SHA-256. Result headers add served. All new fields are optional, so existing records keep parsing.
  • Resume guard: temp dirs hold stamp.json; a command refuses to resume under a different profile, prompts or packs (no bypass flag). Legacy dirs without a stamp resume with a warning.
  • Stamp.run mirrors Packs.run so kora-infra can scope a stamp per run in a shared isolate.

Verification

  • yarn tsbuild, yarn test (330 tests), yarn lint, yarn pretty clean (lint reports only pre-existing issues in a gitignored script under data/).
  • Live: kora profile --check passed for all five models; a one-scenario run gpt-4o produced a stamped result and archive; a seeded temp dir was refused under --judges gpt-5.5:high and resumed cleanly under the same configuration.

Also in this PR

  • scripts/complete-run.mjs / manual-rerun.mjs now load the evaluation profile (KORA_PROFILE), keep JUDGE / USER_MODEL as warned overrides, stamp their results and go through the same resume guard as kora run. Verified live against a scratch run dir.

Follow-ups (not in this PR)

  • kora-infra: store the stamp on the run row, group the leaderboard by stamp hash, wrap runs in Stamp.run, and bump the benchmark package before ingesting stamped CLI output (its strict test-result parser).
  • Tag a release after merge as a human-readable alias for the kora@1 stamp hash.

🤖 Generated with Claude Code

https://claude.ai/code/session_017SeRjc1yMoa617ZR2bxeE8

Pin every harness LLM (seed generation, expansion, user simulator, judges)
in an evaluation profile with inline configs and a content hash, and stamp
every seed, scenario, test result and result header with the effective
profile, resolved model configs, prompts fingerprint, packs, code revision
and input corpus hash.

- profiles/kora.json reproduces the previous hardcoded CLI defaults; a test
  asserts each role matches its models.json entry
- profiles/*.local.json are gitignored scratch profiles for testing a model
  configuration (--profile <name>.local); their hash is not checked
- CI guards: committed profile hashes and the prompts fingerprint must be
  bumped when their content changes (tests print the expected value)
- per-role CLI flags remain as explicit overrides: warned, listed in the
  stamp, and hashed differently from the named profile
- graceful-restart temp dirs hold a stamp.json; resuming under a different
  configuration is refused
- result headers record `served`: the model ids the provider reported
- new `kora profile [--check | --print-hash]` command; `validate` prints the
  profile summary
- Stamp.run mirrors Packs.run so infra can scope a stamp per run

Claude-Session: https://claude.ai/code/session_017SeRjc1yMoa617ZR2bxeE8
…esults

complete-run.mjs and manual-rerun.mjs take judges and the user simulator
from the evaluation profile (KORA_PROFILE) like the CLI; JUDGE / USER_MODEL
remain as warned overrides. complete-run builds the run stamp, goes through
the same resume guard as `kora run` against .kora-run-tmp/stamp.json, and
names the target from the cached stamp (or TARGET). manual-rerun records the
user spec on each transcript entry.

Claude-Session: https://claude.ai/code/session_017SeRjc1yMoa617ZR2bxeE8
Move the evaluation profile schema, hash and role helpers into the benchmark
package next to packs, so kora-infra can build profiles and stamps with the
same formula; the CLI keeps loading files. Stamp roles other than `user` and
`judges` become optional: a harness records the roles it has.

Claude-Session: https://claude.ai/code/session_017SeRjc1yMoa617ZR2bxeE8
@Thibaut-Fatus
Thibaut-Fatus merged commit 518743b into main Sep 7, 2026
4 checks passed
@Thibaut-Fatus
Thibaut-Fatus deleted the feat/evaluation-profiles branch September 7, 2026 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant