Skip to content

feat: support optional resource config IDs - #457

Open
joshblack wants to merge 3 commits into
mainfrom
support-optional-config-id
Open

joshblack wants to merge 3 commits into
mainfrom
support-optional-config-id

Conversation

@joshblack

@joshblack joshblack commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

This PR adds optional IDs to benchmark, experiment, and scenario configs. Explicit IDs stay unchanged; omitted IDs depend on the resource's path relative to its configured directory.

Filename and directory selectors continue to work. Since default IDs change, the migration guide explains how to pin existing IDs to preserve plans and result history.

Changelog

New

  • Add an optional nonblank id to benchmark, experiment, and scenario configs.
  • Add a minor changeset and a migration guide for preserving existing resource identity.

Changed

  • Derive omitted IDs by hashing Benchmark:<relative-path-without-extension>, Experiment:<relative-path-without-extension>, or Scenario:<relative-directory>, using / separators.
  • Resolve resources by ID or their existing filename/directory selector, prioritizing IDs so saved plans remain unambiguous.
  • Reject duplicate resource IDs, including collisions between distinct inline scenario directories.
  • Give string and inline references to the same scenario a consistent identity. Inline name no longer overrides identity.
  • Keep CLI report labels readable while using resolved IDs for grouping and saved results.
  • Focus documentation on public behavior and ID stability rather than hashing mechanics, and record that distinction in the writing guidance.
  • Pin the changeset's migration link to a full commit SHA and require commit-pinned links in changeset authoring guidance.

Removed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 526126fc-97a2-4353-93c1-807497ff8960
Copilot AI balanced review requested due to automatic review settings October 24, 2026 16:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved identity-handling regressions affect saved-plan restoration, result discovery, capability output validity, and Docker image operations.

5 open issues
What changed in this PR

This PR separates resource identity from filenames and directories, allowing benchmark, experiment, and scenario configs to pin IDs across renames.

Changes:

  • Add optional nonblank IDs, with namespaced hashes of relative paths as defaults.
  • Resolve selectors by ID first, detect duplicate identities, and retain readable report labels.
  • Add regression tests, migration guidance, and a minor changeset.
File Description
packages/​agent-eval/​src/​scenario/​scenario.ts Add scenario ID hashing and collision detection.
packages/​agent-eval/​src/​scenario/​scenario.test.ts Test hashed IDs and selector precedence.
packages/​agent-eval/​src/​scenario/​load.ts Resolve explicit or root-relative scenario IDs.
packages/​agent-eval/​src/​scenario/​load.test.ts Test identity stability and invalid IDs.
packages/​agent-eval/​src/​scenario/​list.ts Pass the configured root and detect collisions.
packages/​agent-eval/​src/​scenario/​list.test.ts Update ID expectations and test collisions.
packages/​agent-eval/​src/​scenario/​get.ts Support ID-first directory selection.
packages/​agent-eval/​src/​scenario/​config.ts Accept optional nonblank IDs.
packages/​agent-eval/​src/​path.ts Add normalized relative-path helpers.
packages/​agent-eval/​src/​experiment/​report.ts Separate scenario labels from grouping IDs.
packages/​agent-eval/​src/​experiment/​plan.test.ts Test pinned IDs in benchmark experiments.
packages/​agent-eval/​src/​experiment/​list.ts Resolve resource IDs and detect collisions.
packages/​agent-eval/​src/​experiment/​list.test.ts Cover identity, selectors, and plan restoration.
packages/​agent-eval/​src/​experiment/​get.ts Support ID-first filename selection.
packages/​agent-eval/​src/​experiment/​experiment.ts Add namespaced experiment ID hashing.
packages/​agent-eval/​src/​experiment/​config.ts Accept IDs for both experiment types.
packages/​agent-eval/​src/​benchmark/​report.ts Display directory labels instead of scenario IDs.
packages/​agent-eval/​src/​benchmark/​plan.test.ts Update plan expectations for hashed IDs.
packages/​agent-eval/​src/​benchmark/​list.ts Resolve IDs and check resource collisions.
packages/​agent-eval/​src/​benchmark/​list.test.ts Cover pinned IDs, selectors, and collisions.
packages/​agent-eval/​src/​benchmark/​get.ts Support ID-first filename selection.
packages/​agent-eval/​src/​benchmark/​config.ts Accept optional nonblank IDs.
packages/​agent-eval/​docs/​references/​scenarios.md Document scenario identity and selectors.
packages/​agent-eval/​docs/​references/​plans.md Explain identity preservation for saved plans.
packages/​agent-eval/​docs/​references/​experiments.md Document experiment IDs and selection.
packages/​agent-eval/​docs/​references/​benchmarks.md Document benchmark IDs and references.
packages/​agent-eval/​docs/​migrations/​resource-identity.md Explain how to preserve existing identities.
packages/​agent-eval/​docs/​migrations/​README.md Index the resource identity migration.
packages/​agent-eval/​docs/​AGENTS.md Link the identity migration guidance.
docs/​scenarios.md Explain optional scenario IDs.
docs/​experiments.md Explain optional experiment IDs.
docs/​benchmarks.md Explain optional benchmark IDs.
.changeset/​cool-readers-glow.md Declare the minor release and migration link.

Review effort: Balanced

Comment on lines +45 to +48
}) ??
benchmarks.find(candidate => {
return getConfigPath(benchmarksDirectory, candidate.filepath) === name
})

benchmarks.push({
id: getBenchmarkId(filename),
id: config.id ?? getBenchmarkId(getConfigPath(benchmarksDirectory, filepath)),
Comment on lines +95 to +99
assertUniqueScenarioIds(
capabilities.flatMap(capability => {
return capability.scenarios
}),
)
Comment on lines +72 to +76
z.string().check(
z.minLength(1),
z.refine(value => {
return value.trim().length > 0
}),

const scenario: Scenario = {
id: name,
id: config.id ?? getScenarioId(getRelativePath(scenariosDirectory, directory)),
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 526126fc-97a2-4353-93c1-807497ff8960
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 526126fc-97a2-4353-93c1-807497ff8960
Copilot AI balanced review requested due to automatic review settings October 24, 2026 16:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +31 to +33
experiments.find(candidate => {
return getConfigPath(experimentsDirectory, candidate.filepath) === name
})
...values,
capability,
scenario: trial.scenario.id,
scenarioName: path.basename(trial.scenario.directory),

This branch has not been deployed

No deployments
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.

2 participants