| 1 | version: 1
|
| 2 | suite: agent_workflow
|
| 3 | suite_version: 2026-06-09
|
| 4 | description: >-
|
| 5 | End-to-end agent workflow benchmark definitions for comparing VCS-backed
|
| 6 | coding tasks across Git and Oak without assuming a specific model provider.
|
| 7 |
|
| 8 | runner_contract:
|
| 9 | row_schema: scripts/agent_metrics_schema.py
|
| 10 | row_granularity: one result row per scenario, agent, subject, vcs_mode, and run
|
| 11 | comparison_policy: >-
|
| 12 | Compare the same agent adapter and task prompt across VCS modes first. Cross-agent
|
| 13 | comparisons must report provider-reported tokens separately from normalized text
|
| 14 | and tool I/O metrics.
|
| 15 | setup_excluded_from_timing:
|
| 16 | - fixture_generation
|
| 17 | - subject_binary_build
|
| 18 | - dependency_cache_population
|
| 19 | timed_phases:
|
| 20 | - task_setup
|
| 21 | - prompt_delivery
|
| 22 | - agent_work
|
| 23 | - tool_wait
|
| 24 | - vcs_operations
|
| 25 | - tests
|
| 26 | - merge_or_cleanup
|
| 27 |
|
| 28 | vcs_modes:
|
| 29 | git_single_checkout:
|
| 30 | subject_kind: git
|
| 31 | description: One mutable checkout per run. Parallel scenarios must run serially in this mode.
|
| 32 | git_worktree_per_task:
|
| 33 | subject_kind: git
|
| 34 | description: One Git worktree or clone per task branch, with merge back to the run root.
|
| 35 | oak_single_mount:
|
| 36 | subject_kind: oak
|
| 37 | description: One Oak mount for the run, with branches created inside that mount.
|
| 38 | oak_mount_per_task:
|
| 39 | subject_kind: oak
|
| 40 | description: One Oak mount per task branch, without the higher-level Oak space template flow.
|
| 41 | oak_space_per_task:
|
| 42 | subject_kind: oak
|
| 43 | description: One Oak space subdirectory per task, using the agent-oriented mount lifecycle.
|
| 44 |
|
| 45 | mode_sets:
|
| 46 | single_task_modes: &single_task_modes
|
| 47 | - git_single_checkout
|
| 48 | - git_worktree_per_task
|
| 49 | - oak_single_mount
|
| 50 | - oak_mount_per_task
|
| 51 | - oak_space_per_task
|
| 52 | isolated_parallel_modes: &isolated_parallel_modes
|
| 53 | - git_worktree_per_task
|
| 54 | - oak_mount_per_task
|
| 55 | - oak_space_per_task
|
| 56 | cleanup_modes: &cleanup_modes
|
| 57 | - git_single_checkout
|
| 58 | - git_worktree_per_task
|
| 59 | - oak_single_mount
|
| 60 | - oak_mount_per_task
|
| 61 | - oak_space_per_task
|
| 62 |
|
| 63 | metric_groups:
|
| 64 | token_metrics: &token_metrics
|
| 65 | - input_tokens_reported
|
| 66 | - output_tokens_reported
|
| 67 | - reasoning_tokens_reported
|
| 68 | - cache_read_tokens_reported
|
| 69 | - cache_write_tokens_reported
|
| 70 | - total_tokens_reported
|
| 71 | - normalized_input_chars
|
| 72 | - normalized_output_chars
|
| 73 | - transcript_chars
|
| 74 | - context_truncation_events
|
| 75 | - token_budget
|
| 76 | - token_source
|
| 77 | tool_call_metrics: &tool_call_metrics
|
| 78 | - tool_calls_total
|
| 79 | - tool_calls_by_kind
|
| 80 | - terminal_commands_total
|
| 81 | - file_read_calls
|
| 82 | - file_write_calls
|
| 83 | - search_calls
|
| 84 | - edit_calls
|
| 85 | - vcs_commands_total
|
| 86 | - test_commands_total
|
| 87 | - network_calls_total
|
| 88 | - privileged_calls_total
|
| 89 | - parallel_batches_total
|
| 90 | - max_concurrency
|
| 91 | failed_command_retry_metrics: &failed_command_retry_metrics
|
| 92 | - failed_tool_calls_total
|
| 93 | - failed_commands_total
|
| 94 | - failed_vcs_commands_total
|
| 95 | - failed_test_commands_total
|
| 96 | - retry_attempts_total
|
| 97 | - retry_chains_total
|
| 98 | - same_command_retries_total
|
| 99 | - retry_after_failure_ms
|
| 100 | - recoverable_failures_total
|
| 101 | - unrecoverable_failures_total
|
| 102 | wall_clock_metrics: &wall_clock_metrics
|
| 103 | - total_ms
|
| 104 | - setup_ms
|
| 105 | - agent_active_ms
|
| 106 | - tool_wait_ms
|
| 107 | - vcs_ms
|
| 108 | - test_ms
|
| 109 | - merge_ms
|
| 110 | - cleanup_ms
|
| 111 | - idle_ms
|
| 112 | - timeout_ms
|
| 113 | bytes_read_hydrated_metrics: &bytes_read_hydrated_metrics
|
| 114 | - workspace_logical_bytes
|
| 115 | - workspace_materialized_bytes
|
| 116 | - bytes_read_by_agent
|
| 117 | - bytes_written_by_agent
|
| 118 | - bytes_hydrated
|
| 119 | - files_hydrated
|
| 120 | - hydration_events
|
| 121 | - large_file_bytes_scanned
|
| 122 | - binary_bytes_touched
|
| 123 | - command_output_bytes
|
| 124 |
|
| 125 | scenarios:
|
| 126 | - id: one_line_bug_fix
|
| 127 | title: One-line bug fix
|
| 128 | category: small_edit
|
| 129 | prompt_shape: >-
|
| 130 | Fix the failing unit test by making the smallest reasonable code change.
|
| 131 | expected_fixtures:
|
| 132 | fixture_id: agent_one_line_bug_fix
|
| 133 | repo_shape: Small text application with one intentionally wrong conditional or operator.
|
| 134 | required_files:
|
| 135 | - src/calculator.py
|
| 136 | - tests/test_calculator.py
|
| 137 | - README.md
|
| 138 | seeded_state:
|
| 139 | - Exactly one deterministic failing test identifies the behavior.
|
| 140 | - Neighboring files contain plausible but irrelevant code.
|
| 141 | expected_change_shape:
|
| 142 | files_changed_min: 1
|
| 143 | files_changed_max: 2
|
| 144 | binary_assets: false
|
| 145 | allowed_vcs_modes: *single_task_modes
|
| 146 | task_success_criteria:
|
| 147 | - The targeted test suite passes.
|
| 148 | - The broken behavior is fixed for the asserted edge case.
|
| 149 | - No unrelated source, docs, lockfile, generated, or asset files change.
|
| 150 | - The final VCS state is clean and snapshotable.
|
| 151 | token_metrics: *token_metrics
|
| 152 | tool_call_metrics: *tool_call_metrics
|
| 153 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 154 | wall_clock_metrics: *wall_clock_metrics
|
| 155 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 156 | metric_focus:
|
| 157 | - Baseline overhead for tiny tasks where VCS setup can dominate agent work.
|
| 158 | - Ratio of useful file reads to exploratory reads.
|
| 159 |
|
| 160 | - id: docs_edit
|
| 161 | title: Docs edit
|
| 162 | category: documentation
|
| 163 | prompt_shape: >-
|
| 164 | Update the user-facing documentation for a changed command or option without
|
| 165 | changing executable code.
|
| 166 | expected_fixtures:
|
| 167 | fixture_id: agent_docs_edit
|
| 168 | repo_shape: Medium repo with README, docs pages, and nearby stale examples.
|
| 169 | required_files:
|
| 170 | - README.md
|
| 171 | - docs/usage.md
|
| 172 | - docs/reference.md
|
| 173 | - src/cli/options.py
|
| 174 | seeded_state:
|
| 175 | - Source code already implements the behavior.
|
| 176 | - At least two docs files contain outdated wording.
|
| 177 | expected_change_shape:
|
| 178 | files_changed_min: 1
|
| 179 | files_changed_max: 3
|
| 180 | binary_assets: false
|
| 181 | allowed_vcs_modes: *single_task_modes
|
| 182 | task_success_criteria:
|
| 183 | - Documentation reflects the fixture's current command behavior.
|
| 184 | - Code and generated files remain unchanged.
|
| 185 | - Markdown formatting checks pass when the fixture provides them.
|
| 186 | - Final status reports no dirty files after snapshot.
|
| 187 | token_metrics: *token_metrics
|
| 188 | tool_call_metrics: *tool_call_metrics
|
| 189 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 190 | wall_clock_metrics: *wall_clock_metrics
|
| 191 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 192 | metric_focus:
|
| 193 | - Cost of inspecting source only enough to verify docs facts.
|
| 194 | - Avoiding broad repo scans after the relevant docs are found.
|
| 195 |
|
| 196 | - id: cross_file_refactor
|
| 197 | title: Cross-file refactor
|
| 198 | category: refactor
|
| 199 | prompt_shape: >-
|
| 200 | Rename or reshape a public helper used across implementation, tests, and docs
|
| 201 | while preserving behavior.
|
| 202 | expected_fixtures:
|
| 203 | fixture_id: agent_cross_file_refactor
|
| 204 | repo_shape: Text-heavy application with shared modules, tests, examples, and docs references.
|
| 205 | required_files:
|
| 206 | - src/core/serializer.py
|
| 207 | - src/api/client.py
|
| 208 | - src/cli/main.py
|
| 209 | - tests/test_serializer.py
|
| 210 | - docs/api.md
|
| 211 | seeded_state:
|
| 212 | - The old symbol appears in code, tests, comments, and docs.
|
| 213 | - Similar symbol names exist and must not be changed.
|
| 214 | expected_change_shape:
|
| 215 | files_changed_min: 4
|
| 216 | files_changed_max: 12
|
| 217 | binary_assets: false
|
| 218 | allowed_vcs_modes: *single_task_modes
|
| 219 | task_success_criteria:
|
| 220 | - All runtime references use the new API name or shape.
|
| 221 | - Tests and type checks pass for the fixture language.
|
| 222 | - Similar but unrelated symbols are untouched.
|
| 223 | - Docs examples compile or match the new public API.
|
| 224 | token_metrics: *token_metrics
|
| 225 | tool_call_metrics: *tool_call_metrics
|
| 226 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 227 | wall_clock_metrics: *wall_clock_metrics
|
| 228 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 229 | metric_focus:
|
| 230 | - Search and edit breadth needed for a correct multi-file change.
|
| 231 | - Retry behavior after tests expose a missed reference.
|
| 232 |
|
| 233 | - id: dependency_upgrade
|
| 234 | title: Dependency upgrade
|
| 235 | category: dependency_management
|
| 236 | prompt_shape: >-
|
| 237 | Upgrade one pinned dependency to the requested version and fix any API or lockfile fallout.
|
| 238 | expected_fixtures:
|
| 239 | fixture_id: agent_dependency_upgrade
|
| 240 | repo_shape: Small service with a package manifest, lockfile, cached dependency artifacts, and tests.
|
| 241 | required_files:
|
| 242 | - package.json
|
| 243 | - package-lock.json
|
| 244 | - src/server.js
|
| 245 | - tests/server.test.js
|
| 246 | seeded_state:
|
| 247 | - A local fixture cache or registry provides the target dependency version.
|
| 248 | - The upgraded dependency requires a small source or test adjustment.
|
| 249 | expected_change_shape:
|
| 250 | files_changed_min: 2
|
| 251 | files_changed_max: 5
|
| 252 | binary_assets: false
|
| 253 | allowed_vcs_modes: *single_task_modes
|
| 254 | task_success_criteria:
|
| 255 | - Manifest and lockfile agree on the requested dependency version.
|
| 256 | - The package manager runs without reaching an uncontrolled network source.
|
| 257 | - Tests pass after any required API adjustment.
|
| 258 | - Unrelated dependencies are not upgraded.
|
| 259 | token_metrics: *token_metrics
|
| 260 | tool_call_metrics: *tool_call_metrics
|
| 261 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 262 | wall_clock_metrics: *wall_clock_metrics
|
| 263 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 264 | metric_focus:
|
| 265 | - Lockfile churn and command retries caused by package-manager behavior.
|
| 266 | - Fair treatment of network-disabled or cache-only runners.
|
| 267 |
|
| 268 | - id: generated_file_churn
|
| 269 | title: Generated-file churn
|
| 270 | category: generated_outputs
|
| 271 | prompt_shape: >-
|
| 272 | Change a schema or template, run the generator, and commit the resulting deterministic output.
|
| 273 | expected_fixtures:
|
| 274 | fixture_id: agent_generated_file_churn
|
| 275 | repo_shape: Project with source schema, generator script, and hundreds of generated text files.
|
| 276 | required_files:
|
| 277 | - schema/events.yaml
|
| 278 | - scripts/generate_events.py
|
| 279 | - src/generated/events/
|
| 280 | - tests/test_generated_events.py
|
| 281 | seeded_state:
|
| 282 | - Generated files are stale relative to the requested schema change.
|
| 283 | - A fixture test fails until generation is rerun.
|
| 284 | expected_change_shape:
|
| 285 | files_changed_min: 20
|
| 286 | files_changed_max: 400
|
| 287 | binary_assets: false
|
| 288 | allowed_vcs_modes: *single_task_modes
|
| 289 | task_success_criteria:
|
| 290 | - Source schema reflects the requested change.
|
| 291 | - Generated files match a clean generator run.
|
| 292 | - Tests pass without hand-editing generated output to hide generator drift.
|
| 293 | - VCS snapshot handles high file-count churn correctly.
|
| 294 | token_metrics: *token_metrics
|
| 295 | tool_call_metrics: *tool_call_metrics
|
| 296 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 297 | wall_clock_metrics: *wall_clock_metrics
|
| 298 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 299 | metric_focus:
|
| 300 | - File-status and snapshot cost under many changed files.
|
| 301 | - Distinguishing agent reads from generator-written bytes.
|
| 302 |
|
| 303 | - id: binary_asset_update
|
| 304 | title: Binary asset update
|
| 305 | category: binary_assets
|
| 306 | prompt_shape: >-
|
| 307 | Replace or update a binary asset and adjust the metadata that validates it.
|
| 308 | expected_fixtures:
|
| 309 | fixture_id: agent_binary_asset_update
|
| 310 | repo_shape: App with small source files, binary images, and checksum or dimension metadata.
|
| 311 | required_files:
|
| 312 | - assets/logo.png
|
| 313 | - assets/[email protected]
|
| 314 | - src/assets_manifest.json
|
| 315 | - tests/test_assets.py
|
| 316 | seeded_state:
|
| 317 | - Replacement binary assets are provided inside the fixture inputs directory.
|
| 318 | - Metadata is stale until the asset update is applied.
|
| 319 | expected_change_shape:
|
| 320 | files_changed_min: 2
|
| 321 | files_changed_max: 4
|
| 322 | binary_assets: true
|
| 323 | allowed_vcs_modes: *single_task_modes
|
| 324 | task_success_criteria:
|
| 325 | - The requested binary asset bytes are installed exactly.
|
| 326 | - Checksums, dimensions, or manifest entries are correct.
|
| 327 | - Binary files are not corrupted by text editing tools.
|
| 328 | - Asset validation tests pass.
|
| 329 | token_metrics: *token_metrics
|
| 330 | tool_call_metrics: *tool_call_metrics
|
| 331 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 332 | wall_clock_metrics: *wall_clock_metrics
|
| 333 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 334 | metric_focus:
|
| 335 | - Bytes hydrated and copied for binary-heavy changes.
|
| 336 | - Whether the agent avoids dumping binary content into context.
|
| 337 |
|
| 338 | - id: large_file_inspection
|
| 339 | title: Large-file inspection
|
| 340 | category: large_files
|
| 341 | prompt_shape: >-
|
| 342 | Inspect a large structured data file to answer a targeted question, then update
|
| 343 | a small verification file or test expectation.
|
| 344 | expected_fixtures:
|
| 345 | fixture_id: agent_large_file_inspection
|
| 346 | repo_shape: Repo containing a large NDJSON or CSV file plus small indexes and tests.
|
| 347 | required_files:
|
| 348 | - data/events.ndjson
|
| 349 | - data/events.index.json
|
| 350 | - tests/test_event_fixture.py
|
| 351 | - docs/event-fixture-notes.md
|
| 352 | seeded_state:
|
| 353 | - The target record is discoverable by a stable key.
|
| 354 | - The large file is too large to read fully into the agent transcript.
|
| 355 | expected_change_shape:
|
| 356 | files_changed_min: 1
|
| 357 | files_changed_max: 3
|
| 358 | binary_assets: false
|
| 359 | allowed_vcs_modes: *single_task_modes
|
| 360 | task_success_criteria:
|
| 361 | - The answer or expectation matches the targeted record in the large file.
|
| 362 | - The agent does not modify the large fixture unless the task explicitly requires it.
|
| 363 | - Tests or verification commands pass.
|
| 364 | - The transcript does not contain a bulk dump of the large file.
|
| 365 | token_metrics: *token_metrics
|
| 366 | tool_call_metrics: *tool_call_metrics
|
| 367 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 368 | wall_clock_metrics: *wall_clock_metrics
|
| 369 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 370 | metric_focus:
|
| 371 | - Logical bytes read versus bytes hydrated from storage.
|
| 372 | - Effectiveness of range reads, search, and indexes.
|
| 373 |
|
| 374 | - id: find_the_right_file_exploration
|
| 375 | title: Find-the-right-file exploration
|
| 376 | category: navigation
|
| 377 | prompt_shape: >-
|
| 378 | Resolve a vague bug report by locating the responsible file in a broad repo.
|
| 379 | expected_fixtures:
|
| 380 | fixture_id: agent_find_right_file
|
| 381 | repo_shape: Wide source tree with many plausible modules and one localized bug.
|
| 382 | required_files:
|
| 383 | - src/features/
|
| 384 | - src/shared/
|
| 385 | - tests/integration/test_user_flow.py
|
| 386 | - docs/architecture.md
|
| 387 | seeded_state:
|
| 388 | - The failing behavior is described at product level, not by filename.
|
| 389 | - Several files contain similar terms to create realistic search noise.
|
| 390 | expected_change_shape:
|
| 391 | files_changed_min: 1
|
| 392 | files_changed_max: 4
|
| 393 | binary_assets: false
|
| 394 | allowed_vcs_modes: *single_task_modes
|
| 395 | task_success_criteria:
|
| 396 | - The correct module is changed and the reported behavior is fixed.
|
| 397 | - Search noise files remain untouched.
|
| 398 | - Integration and targeted tests pass.
|
| 399 | - The agent records enough evidence in tool traces to justify the file choice.
|
| 400 | token_metrics: *token_metrics
|
| 401 | tool_call_metrics: *tool_call_metrics
|
| 402 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 403 | wall_clock_metrics: *wall_clock_metrics
|
| 404 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 405 | metric_focus:
|
| 406 | - Search calls, directory listings, and file reads before first edit.
|
| 407 | - Whether lazy hydration reduces cost for broad exploration.
|
| 408 |
|
| 409 | - id: parallel_independent_tasks
|
| 410 | title: Parallel independent tasks
|
| 411 | category: parallel_work
|
| 412 | prompt_shape: >-
|
| 413 | Run multiple independent agent tasks against the same starting revision and merge them.
|
| 414 | expected_fixtures:
|
| 415 | fixture_id: agent_parallel_independent
|
| 416 | repo_shape: App with three unrelated issues in separate modules and tests.
|
| 417 | required_files:
|
| 418 | - src/payments/
|
| 419 | - src/search/
|
| 420 | - docs/cli.md
|
| 421 | - tests/
|
| 422 | seeded_state:
|
| 423 | - Task A is a source bug fix.
|
| 424 | - Task B is a docs edit.
|
| 425 | - Task C is a small test expectation update.
|
| 426 | expected_change_shape:
|
| 427 | files_changed_min: 3
|
| 428 | files_changed_max: 9
|
| 429 | binary_assets: false
|
| 430 | allowed_vcs_modes: *isolated_parallel_modes
|
| 431 | task_success_criteria:
|
| 432 | - Every subtask succeeds against the shared starting revision.
|
| 433 | - All accepted changes are present after merge or squash.
|
| 434 | - No subtask observes another subtask's unmerged dirty work.
|
| 435 | - Final combined tests pass and the run root is clean.
|
| 436 | token_metrics: *token_metrics
|
| 437 | tool_call_metrics: *tool_call_metrics
|
| 438 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 439 | wall_clock_metrics: *wall_clock_metrics
|
| 440 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 441 | metric_focus:
|
| 442 | - Branch or mount creation overhead under concurrent work.
|
| 443 | - Wall-clock speedup versus serialized task duration.
|
| 444 |
|
| 445 | - id: parallel_overlapping_tasks
|
| 446 | title: Parallel overlapping tasks
|
| 447 | category: parallel_work
|
| 448 | prompt_shape: >-
|
| 449 | Run multiple tasks that touch nearby files or non-conflicting hunks, then merge them.
|
| 450 | expected_fixtures:
|
| 451 | fixture_id: agent_parallel_overlapping
|
| 452 | repo_shape: App with two feature requests touching the same module family.
|
| 453 | required_files:
|
| 454 | - src/config/defaults.py
|
| 455 | - src/config/validation.py
|
| 456 | - tests/test_config.py
|
| 457 | - docs/config.md
|
| 458 | seeded_state:
|
| 459 | - Subtasks overlap in file set but target different symbols or sections.
|
| 460 | - The correct combined result should merge without semantic loss.
|
| 461 | expected_change_shape:
|
| 462 | files_changed_min: 2
|
| 463 | files_changed_max: 8
|
| 464 | binary_assets: false
|
| 465 | allowed_vcs_modes: *isolated_parallel_modes
|
| 466 | task_success_criteria:
|
| 467 | - Both overlapping task intents survive the final merge.
|
| 468 | - Any auto-merge is verified by tests and direct inspection.
|
| 469 | - No last-writer-wins overwrite is accepted.
|
| 470 | - Final status is clean after snapshot or merge.
|
| 471 | token_metrics: *token_metrics
|
| 472 | tool_call_metrics: *tool_call_metrics
|
| 473 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 474 | wall_clock_metrics: *wall_clock_metrics
|
| 475 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 476 | metric_focus:
|
| 477 | - Conflict-free overlap handling and merge verification cost.
|
| 478 | - Extra reads needed to confirm both task intents remain present.
|
| 479 |
|
| 480 | - id: conflict_resolution
|
| 481 | title: Conflict resolution
|
| 482 | category: merge_conflicts
|
| 483 | prompt_shape: >-
|
| 484 | Merge two completed task branches that intentionally edit the same lines, resolve
|
| 485 | the conflict, and preserve both behavioral intents.
|
| 486 | expected_fixtures:
|
| 487 | fixture_id: agent_conflict_resolution
|
| 488 | repo_shape: Small service with two branches or mounts that change the same function.
|
| 489 | required_files:
|
| 490 | - src/routing/rules.py
|
| 491 | - tests/test_routing_rules.py
|
| 492 | - docs/routing.md
|
| 493 | seeded_state:
|
| 494 | - Branch A changes behavior for one route class.
|
| 495 | - Branch B changes behavior for a second route class in the same hunk.
|
| 496 | - The naive conflict choices each break one test.
|
| 497 | expected_change_shape:
|
| 498 | files_changed_min: 1
|
| 499 | files_changed_max: 5
|
| 500 | binary_assets: false
|
| 501 | allowed_vcs_modes: *isolated_parallel_modes
|
| 502 | task_success_criteria:
|
| 503 | - The conflict is detected and resolved deliberately.
|
| 504 | - Tests for both branch intents pass after resolution.
|
| 505 | - Conflict markers are absent from tracked files.
|
| 506 | - Merge metadata or snapshot state is clean and auditable.
|
| 507 | token_metrics: *token_metrics
|
| 508 | tool_call_metrics: *tool_call_metrics
|
| 509 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 510 | wall_clock_metrics: *wall_clock_metrics
|
| 511 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 512 | metric_focus:
|
| 513 | - Failed merge commands, conflict-resolution retries, and verification tests.
|
| 514 | - Whether VCS output gives agents enough context without excessive file reads.
|
| 515 |
|
| 516 | - id: failed_test_then_fix
|
| 517 | title: Failed-test-then-fix
|
| 518 | category: recovery
|
| 519 | prompt_shape: >-
|
| 520 | Make an apparently obvious fix, observe the failing test output, then diagnose
|
| 521 | and apply the correct fix.
|
| 522 | expected_fixtures:
|
| 523 | fixture_id: agent_failed_test_then_fix
|
| 524 | repo_shape: Small application where the first plausible edit leaves a hidden edge case broken.
|
| 525 | required_files:
|
| 526 | - src/parser.py
|
| 527 | - tests/test_parser.py
|
| 528 | - tests/fixtures/parser_cases.json
|
| 529 | seeded_state:
|
| 530 | - The direct symptom points to one line, but the correct fix requires another helper.
|
| 531 | - Test output includes enough detail for recovery.
|
| 532 | expected_change_shape:
|
| 533 | files_changed_min: 1
|
| 534 | files_changed_max: 4
|
| 535 | binary_assets: false
|
| 536 | allowed_vcs_modes: *single_task_modes
|
| 537 | task_success_criteria:
|
| 538 | - At least one failing test command is observed before the final successful run.
|
| 539 | - The final fix handles both the original symptom and the edge case.
|
| 540 | - Tests pass after the recovery edit.
|
| 541 | - Failed intermediate edits are not left as unrelated churn.
|
| 542 | token_metrics: *token_metrics
|
| 543 | tool_call_metrics: *tool_call_metrics
|
| 544 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 545 | wall_clock_metrics: *wall_clock_metrics
|
| 546 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 547 | metric_focus:
|
| 548 | - Command failure handling and useful retries after test output.
|
| 549 | - Additional context cost required for recovery.
|
| 550 |
|
| 551 | - id: abandon_and_cleanup
|
| 552 | title: Abandon and cleanup
|
| 553 | category: lifecycle
|
| 554 | prompt_shape: >-
|
| 555 | Start a task, discover from repository evidence that the requested change should
|
| 556 | not be made, then abandon the branch or mount cleanly.
|
| 557 | expected_fixtures:
|
| 558 | fixture_id: agent_abandon_cleanup
|
| 559 | repo_shape: Project with a misleading request contradicted by policy docs or tests.
|
| 560 | required_files:
|
| 561 | - docs/policy.md
|
| 562 | - src/feature_flags.py
|
| 563 | - tests/test_feature_flags.py
|
| 564 | seeded_state:
|
| 565 | - The requested feature is explicitly disallowed by repository policy.
|
| 566 | - A partial local edit would be easy but incorrect.
|
| 567 | expected_change_shape:
|
| 568 | files_changed_min: 0
|
| 569 | files_changed_max: 0
|
| 570 | binary_assets: false
|
| 571 | allowed_vcs_modes: *cleanup_modes
|
| 572 | task_success_criteria:
|
| 573 | - The agent identifies repository evidence for abandoning the task.
|
| 574 | - No partial edits, commits, branches, mounts, or worktrees are leaked after cleanup.
|
| 575 | - The original checkout or space is clean.
|
| 576 | - The final result records an intentional abandoned outcome rather than a task failure.
|
| 577 | token_metrics: *token_metrics
|
| 578 | tool_call_metrics: *tool_call_metrics
|
| 579 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 580 | wall_clock_metrics: *wall_clock_metrics
|
| 581 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 582 | metric_focus:
|
| 583 | - Lifecycle cleanup cost and correctness.
|
| 584 | - Distinguishing productive abandonment from timeout or crash failure.
|
| 585 |
|
| 586 | - id: history_archaeology
|
| 587 | title: History archaeology
|
| 588 | category: history_read
|
| 589 | prompt_shape: >-
|
| 590 | Answer "what changed recently, what did the last commit touch, when did this
|
| 591 | file last change, and which commit introduced this term" using history
|
| 592 | commands only.
|
| 593 | expected_fixtures:
|
| 594 | fixture_id: agent_history_archaeology
|
| 595 | repo_shape: Small application with several seeded commits carrying meaningful messages.
|
| 596 | required_files:
|
| 597 | - app/pricing.py
|
| 598 | - app/totals.py
|
| 599 | - README.md
|
| 600 | seeded_state:
|
| 601 | - At least three commits after the initial snapshot, each editing a known file.
|
| 602 | - Commit messages name the behavior change so log output is answerable.
|
| 603 | expected_change_shape:
|
| 604 | files_changed_min: 0
|
| 605 | files_changed_max: 0
|
| 606 | binary_assets: false
|
| 607 | allowed_vcs_modes: *single_task_modes
|
| 608 | task_success_criteria:
|
| 609 | - The history questions are answered from command output, not guesses.
|
| 610 | - No working-tree files change.
|
| 611 | - Subjects lacking a capability (file-scoped log, pickaxe, show) run the
|
| 612 | closest available command; the gap is recorded, not hidden.
|
| 613 | token_metrics: *token_metrics
|
| 614 | tool_call_metrics: *tool_call_metrics
|
| 615 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 616 | wall_clock_metrics: *wall_clock_metrics
|
| 617 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 618 | metric_focus:
|
| 619 | - Token cost per answered history question, by subject.
|
| 620 | - Capability gaps where one subject needs extra commands or full-history dumps.
|
| 621 | implemented_by: scripts/workflow_ab.py --workflows history_archaeology
|
| 622 |
|
| 623 | - id: vcs_error_recovery
|
| 624 | title: VCS error recovery
|
| 625 | category: failure_recovery
|
| 626 | prompt_shape: >-
|
| 627 | Recover from common VCS failures: a snapshot with nothing to record and a
|
| 628 | mistyped subcommand, then complete a real change and snapshot it.
|
| 629 | expected_fixtures:
|
| 630 | fixture_id: agent_vcs_error_recovery
|
| 631 | repo_shape: Small clean repository where the first snapshot attempt has nothing to commit.
|
| 632 | required_files:
|
| 633 | - app/pricing.py
|
| 634 | - README.md
|
| 635 | seeded_state:
|
| 636 | - The working tree is clean so the first commit attempt fails or no-ops.
|
| 637 | - The scripted lane also issues one intentionally unknown subcommand.
|
| 638 | expected_change_shape:
|
| 639 | files_changed_min: 1
|
| 640 | files_changed_max: 1
|
| 641 | binary_assets: false
|
| 642 | allowed_vcs_modes: *single_task_modes
|
| 643 | task_success_criteria:
|
| 644 | - The run ends with the real change snapshotted and a clean tree.
|
| 645 | - Error output cost (bytes, estimated tokens) is recorded per failure step.
|
| 646 | - For real-agent rows, turns_to_recovery and tokens_to_recovery are populated
|
| 647 | when the adapter exposes per-call outcomes.
|
| 648 | token_metrics: *token_metrics
|
| 649 | tool_call_metrics: *tool_call_metrics
|
| 650 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 651 | wall_clock_metrics: *wall_clock_metrics
|
| 652 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 653 | metric_focus:
|
| 654 | - Error-message ergonomics, measured as recovery turns and tokens; an error
|
| 655 | message is a prompt.
|
| 656 | - Exit-code clarity and whether a follow-up status call is needed to learn state.
|
| 657 | implemented_by: scripts/workflow_ab.py --workflows vcs_error_recovery
|
| 658 |
|
| 659 | - id: model_familiarity_tax
|
| 660 | title: Model familiarity tax
|
| 661 | category: zero_shot_competence
|
| 662 | prompt_shape: >-
|
| 663 | Run an identical task at three instruction levels (zero-shot, cheat-sheet,
|
| 664 | full-docs) and compare success rate, help/discovery calls, hallucinated
|
| 665 | commands, and tokens to reach parity.
|
| 666 | expected_fixtures:
|
| 667 | fixture_id: agent_one_line_bug_fix
|
| 668 | repo_shape: Reuses an existing small-task fixture; only the instructions vary.
|
| 669 | required_files:
|
| 670 | - app/pricing.py
|
| 671 | - tests/test_pricing.py
|
| 672 | seeded_state:
|
| 673 | - Git is in every model's pretraining data; a new VCS is not. The fixed
|
| 674 | per-session instruction cost and the guessing cost are the measurement.
|
| 675 | expected_change_shape:
|
| 676 | files_changed_min: 1
|
| 677 | files_changed_max: 2
|
| 678 | binary_assets: false
|
| 679 | allowed_vcs_modes: *single_task_modes
|
| 680 | task_success_criteria:
|
| 681 | - Rows record agent.instruction_level and are never aggregated across levels.
|
| 682 | - Zero-shot rows count help_calls_total and unknown_command_failures_total.
|
| 683 | - The headline metric is instruction tokens required to reach git-parity
|
| 684 | success rate, per scenario.
|
| 685 | token_metrics: *token_metrics
|
| 686 | tool_call_metrics: *tool_call_metrics
|
| 687 | failed_command_retry_metrics: *failed_command_retry_metrics
|
| 688 | wall_clock_metrics: *wall_clock_metrics
|
| 689 | bytes_read_hydrated_metrics: *bytes_read_hydrated_metrics
|
| 690 | metric_focus:
|
| 691 | - Success rate and retry chains per instruction level, per subject.
|
| 692 | - Help/discovery tool calls and hallucinated-command failures at zero-shot.
|
| 693 | implemented_by: scripts/agent_workflow.py --instruction-level {zero-shot,cheat-sheet,full-docs}
|