ruby-skill-bench 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f47976b55f6f8c147adb4ed784ce04ba52ff71f805f8e35d797ba776021641c4
4
- data.tar.gz: c2febaadbdeb7e149041661258ce84e41499121445cf726cefece642e60174a4
3
+ metadata.gz: 60f6da81bf101f4bb1e5a7b86112aa96fa430ca9a1db7f1331a47e51b194ea73
4
+ data.tar.gz: 7f50c1e8a1891a93f0028f98c6a660e1d35ecfaf2104390d94a895ff983d9c93
5
5
  SHA512:
6
- metadata.gz: 5ab3082fa715a0776455a88b28e2d990d3bb7e52fbc5f0cc47176e1d44e76cdc430531bc0401abab350cb4c2321d0b625ce78d381094fe404cdedd7e61b27227
7
- data.tar.gz: 3d5f67b876457691e003e62a8ba57fc04ac21e002bb5c6a84d1ae7954cf7dd7136f05a658d7ee4d416ab2db19cb0ad90e51dd0d920df9ffa998cb8391db65df5
6
+ metadata.gz: a828560ad084e9bd1d3336c9002c8b17d47a12955bed6d53e3dd174ef0e971dab24699ab5da40d3445ece5d06afa29e9354e9d033e5d8a11b5c749872487c1cd
7
+ data.tar.gz: b81d9dc73aa78be923e8fdecbf789aa5078e1f68c40d9330a0e11ca9632579dc8635e647a3f08730e1a478f3ea16a0e5379fae1b008b461f1f48d6d4714a9e3e
data/README.md CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  ![Ruby Skill Bench Logo](https://github.com/user-attachments/assets/056d7ca4-8671-41ec-9efb-e323b73fb135)
4
4
 
5
-
6
5
  ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/igmarin/ruby-skill-bench?utm_source=oss&utm_medium=github&utm_campaign=igmarin%2Fruby-skill-bench&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews)
7
6
 
7
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/igmarin/ruby-skill-bench)
8
+
8
9
  *A high-fidelity evaluation engine for benchmarking AI agent skills across any stack (Rails-first, but extensible).*
9
10
 
10
11
  ## Part of the AI Skill Ecosystem
@@ -92,7 +93,7 @@ By default, no shell commands are permitted. You must configure `allowed_command
92
93
 
93
94
  > **Security:** The agent can only execute commands on this list. Dangerous commands (bash, curl, sudo, etc.) are always blocked regardless of configuration.
94
95
  >
95
- > **Where commands run:** Allowed commands run inside a temporary git **sandbox directory** on the host — a copy of your eval files, not your project. True container isolation (Docker) is **not yet shipped**, so the sandbox directory is the only boundary. Because of this, host execution **fails closed**: it is disabled by default and must be explicitly enabled with `"allow_host_execution": true`. With it disabled (the default), `run_command` refuses to execute and returns an error instead of running un-isolated. Enable it only when you accept that allowed commands run directly on your machine.
96
+ > **Where commands run:** Allowed commands run inside a temporary git **sandbox directory** (a copy of your eval files). When Docker is available and the packaged `evaluator-sandbox` image can start, commands run via `docker exec` with hardened flags (`--network none`, non-root, dropped capabilities). When Docker is **not** available, host execution **fails closed**: it is disabled by default and must be explicitly enabled with `"allow_host_execution": true`. With it disabled (the default), `run_command` refuses to execute on the host. Enable it only when you accept that allowed commands run directly on your machine inside the temp sandbox directory. See [docs/docker.md](docs/docker.md).
96
97
 
97
98
  ### Configuration Hierarchy
98
99
 
@@ -526,7 +527,7 @@ SkillBench creates and manages three files in your project. Understanding them h
526
527
  - Configuration is loaded in this order: **code defaults** → `~/.skill-bench.json` (user-wide) → `./skill-bench.json` (local) → **environment variables**. Later sources override earlier ones.
527
528
  - If `api_key` is `null`, SkillBench looks for the matching environment variable (e.g. `SKILL_BENCH_OPENAI_API_KEY`).
528
529
  - `allowed_commands` is a **safeguard**, not a convenience. By default the agent cannot run *any* shell command. Add only what your evals need.
529
- - `allow_host_execution` (default `false`) gates whether `run_command` may run on the host when no container isolation is active. Since container isolation is not yet shipped, leaving it `false` means `run_command` **fails closed** (refuses to execute). Set it to `true` only if you accept that allowed commands run directly on your machine inside the temporary sandbox directory.
530
+ - `allow_host_execution` (default `false`) gates whether `run_command` may run on the host when no container isolation is active. When Docker starts a container successfully, host execution is not used. When Docker is unavailable, leaving this `false` means `run_command` **fails closed** (refuses to execute). Set it to `true` only if you accept that allowed commands run directly on your machine inside the temporary sandbox directory.
530
531
 
531
532
  ---
532
533
 
@@ -898,7 +899,7 @@ Your eval result depends on **both** conditions. Here is every scenario:
898
899
 
899
900
  ## Reliability & Security
900
901
 
901
- - **Allowlist-Gated Execution**: The agent can only run commands you add to `allowed_commands`; with an empty allowlist it can run nothing. Commands run inside a temporary git sandbox **directory** (a copy of the eval files) on the host container isolation is not yet shipped, so host execution is **disabled by default** and must be explicitly opted into with `allow_host_execution: true`.
902
+ - **Allowlist-Gated Execution**: The agent can only run commands you add to `allowed_commands`; with an empty allowlist it can run nothing. Commands prefer Docker isolation when available (see [docs/docker.md](docs/docker.md)); otherwise they would run on the host inside the temporary sandbox directory so host execution is **disabled by default** and must be explicitly opted into with `allow_host_execution: true`.
902
903
  - **Command Blocklist**: Dangerous commands (`bash`, `sh`, `python`, `curl`, etc.) are always blocked, even if listed in `allowed_commands`.
903
904
  - **Path Validation**: Eval paths are validated to prevent directory traversal attacks.
904
905
  - **Atomic History Writes**: Benchmark history uses file locking to prevent corruption from concurrent writes.
@@ -966,23 +967,24 @@ Ruby Skill Bench is designed with security as a primary concern. The system exec
966
967
  - **Command Allowlist:** Only explicitly allowed commands can be executed
967
968
  - **Dangerous Commands Blocklist:** Dangerous commands (bash, curl, sudo, etc.) are always blocked
968
969
  - **Shell Tokenization:** Commands are tokenized before execution to prevent shell injection
969
- - **Fail-Closed Host Execution:** Container isolation is not yet active, so commands run on the host inside a temporary sandbox directory. To match this reality, `run_command` refuses to execute unless `allow_host_execution: true` is set; it is **disabled by default**.
970
+ - **Fail-Closed Host Execution:** When no container is active, commands would run on the host inside a temporary sandbox directory. `run_command` refuses to execute unless `allow_host_execution: true` is set; it is **disabled by default**. Prefer installing Docker and building the image (`bundle exec rake docker:build`) so isolation activates automatically.
970
971
 
971
972
  > **The allowlist is the only real authorization control — and it only checks the base command.** `run_command` authorizes by the first token of the command (`rake`, `find`, `git`, …); it does **not** inspect arguments. Shell tokenization stops metacharacter injection, but it does **not** sandbox what an allowlisted binary can do. Because many common tools are general-purpose execution wrappers, **allowlisting any one of them is equivalent to granting arbitrary host code execution** — for example `rake -e '...'`, `rspec -e`, `make` (arbitrary recipes), `find . -exec ...`, or `git` (hooks, `-c core.fsmonitor=...`, `! ...` aliases). Combined with the fail-closed model above (`run_command` refuses to run on the host unless `allow_host_execution` is explicitly enabled — see `HOST_EXECUTION_REFUSED` in `run_command.rb`), the practical guidance is: **keep `allowed_commands` as minimal as possible — empty for untrusted skills** — and treat every entry as if you were handing the skill a shell.
972
973
  >
973
974
  > An **optional, default-off** `command_argument_constraints` setting can refuse commands whose arguments contain configured substrings/flags (for example blocking `-e` or `-exec`). It is a defense-in-depth speed bump, **not** a sandbox, and is unset by default; the allowlist remains the control that matters.
974
975
 
975
- #### Docker Security Hardening (Planned — Not Yet Active)
976
+ #### Docker Security Hardening
976
977
 
977
- > **Status:** The container isolation model described below is **planned, not shipped**. No Docker build context is packaged, so containers are never launched today `run_command` runs on the host gated by the allowlist and `allow_host_execution`. The settings below document the intended hardened model for when container isolation lands.
978
+ > **Status:** Container isolation **ships** when a Docker daemon is available and the packaged build context can produce `evaluator-sandbox:<version>`. Build with `bundle exec rake docker:build` (see [docs/docker.md](docs/docker.md)). Without Docker, `run_command` remains fail-closed on the host unless `allow_host_execution` is set.
978
979
 
979
- When container isolation is enabled in a future release, containers are intended to launch with hardened security settings:
980
+ Containers launch with hardened security settings:
980
981
 
981
- - **Non-root User:** Containers run as a non-root user
982
+ - **Non-root User:** Containers run as the host `uid:gid`
982
983
  - **Privilege Prevention:** `--security-opt no-new-privileges` prevents privilege escalation
983
- - **Capability Dropping:** All Linux capabilities are dropped except minimal needed ones
984
+ - **Capability Dropping:** `--cap-drop ALL` with only `CHOWN`/`DAC_OVERRIDE` restored for volume ops
984
985
  - **Network Isolation:** `--network none` disables network access
985
- - **Read-only Root:** Container filesystem is read-only (except for mounted volumes)
986
+ - **Sandbox mount:** Host temp sandbox is bind-mounted at `/sandbox` read-write
987
+ - **Read-only root (future):** Not yet applied; tracked as follow-up hardening
986
988
 
987
989
  #### Resource Limits
988
990
 
@@ -1040,8 +1042,8 @@ private vulnerability reporting (Security tab) or email the maintainer at
1040
1042
  - **Check:** Verify the command isn't hanging or waiting for input
1041
1043
 
1042
1044
  **Problem:** "Command execution refused: no sandbox isolation is active and 'allow_host_execution' is not enabled"
1043
- - **Cause:** Container isolation is not yet shipped, so commands would run on the host. SkillBench fails closed by default rather than run un-isolated.
1044
- - **Solution:** Set `"allow_host_execution": true` in `skill-bench.json` to permit allowed commands to run directly on the host (inside the temporary sandbox directory). Enable it only when you accept that trade-off.
1045
+ - **Cause:** No Docker container was started (daemon missing, image missing, or build failed), so commands would run on the host. SkillBench fails closed by default rather than run un-isolated.
1046
+ - **Solution:** Install Docker and run `bundle exec rake docker:build`, **or** set `"allow_host_execution": true` in `skill-bench.json` to permit allowed commands on the host (inside the temporary sandbox directory). Prefer Docker when possible.
1045
1047
 
1046
1048
  **Problem:** "Context hydration failed"
1047
1049
  - **Solution:** Verify the source path exists and is a directory
data/docs/architecture.md CHANGED
@@ -200,3 +200,10 @@ The eval directory must contain at minimum:
200
200
 
201
201
  - `task.md` — the agent prompt
202
202
  - `criteria.json` — the scoring rules (optional; defaults to empty criteria if missing)
203
+
204
+ ## Command isolation
205
+
206
+ Agent tool commands prefer a Docker container (`evaluator-sandbox`) when available.
207
+ See [docker.md](docker.md) for the image contract and `rake docker:build`.
208
+ Without Docker, `run_command` refuses host execution unless `allow_host_execution` is true.
209
+
data/docs/docker.md ADDED
@@ -0,0 +1,45 @@
1
+ # Evaluator sandbox Docker image
2
+
3
+ Part of milestone **container-isolation-v1**. This document is the image contract
4
+ for `evaluator-sandbox`, the container SkillBench uses for isolated `run_command`
5
+ execution when a Docker daemon is available.
6
+
7
+ ## Contract (MVP)
8
+
9
+ | Item | Value |
10
+ |------|--------|
11
+ | Image name | `evaluator-sandbox` (`Constants::Sandbox::DOCKER_IMAGE_NAME`) |
12
+ | Tags | `evaluator-sandbox:<SkillBench::VERSION>` and `evaluator-sandbox:latest` |
13
+ | Base | `ruby:3.4-bookworm` (aligns with CI Ruby 3.4; 3.3 hosts still run evals via host Ruby for the orchestrator) |
14
+ | Preinstalled | Ruby (from base), `git`, minimal Debian tools from base image |
15
+ | Working directory | `/sandbox` (host sandbox dir is bind-mounted here read-write) |
16
+ | Default process | `sleep infinity` — container stays up for `docker exec` |
17
+ | Network at runtime | **none** (`--network none`) — no `apt`/`bundle install` during evals |
18
+ | User | Host `uid:gid` via `docker run --user` |
19
+ | Privileges | `no-new-privileges`, `cap-drop ALL`, add back `CHOWN` + `DAC_OVERRIDE` only |
20
+
21
+ ## Build
22
+
23
+ From the repo root (or any install that includes the packaged context):
24
+
25
+ ```bash
26
+ bundle exec rake docker:build
27
+ ```
28
+
29
+ This builds from `lib/skill_bench/execution/docker` and tags:
30
+
31
+ - `evaluator-sandbox:<version>` (from `SkillBench::VERSION`)
32
+ - `evaluator-sandbox:latest`
33
+
34
+ ## Multi-arch notes
35
+
36
+ Build on the machine (or CI runner) that will run evals. Docker Desktop on Apple
37
+ Silicon produces arm64 images; GitHub `ubuntu-latest` produces amd64. Do not
38
+ assume a single cached image works across both without multi-platform build.
39
+
40
+ ## Out of scope (MVP)
41
+
42
+ - Full Bundler/dev toolchain prebake
43
+ - Per-eval custom Dockerfiles
44
+ - Read-only root filesystem (documented as future hardening)
45
+ - gVisor / Firecracker
@@ -72,8 +72,14 @@ module SkillBench
72
72
  value == true || value.to_s.strip.casecmp?('true')
73
73
  end
74
74
 
75
+ # Prefer an option when the key is present — including an explicit `nil`,
76
+ # which means "unset" and must not fall through to global Config (a prior
77
+ # `||` treated nil as missing and leaked stored API keys into clients).
75
78
  def fetch_config(key)
76
- @options[key] || @config[key]
79
+ return @options[key] if @options.key?(key)
80
+ return @options[key.to_s] if @options.key?(key.to_s)
81
+
82
+ @config[key] || @config[key.to_s]
77
83
  end
78
84
  end
79
85
  end
@@ -30,6 +30,33 @@ module SkillBench
30
30
  # Sandbox Configuration
31
31
  module Sandbox
32
32
  DOCKER_IMAGE_NAME = 'evaluator-sandbox'
33
+
34
+ # Relative path of the Docker build context as packaged in the gem.
35
+ DOCKER_CONTEXT_RELATIVE = 'lib/skill_bench/execution/docker'
36
+
37
+ # Absolute path to the Docker build context shipped next to the library code.
38
+ # Resolved from this file so gem installs and git checkouts agree.
39
+ #
40
+ # @return [String] absolute path to the docker/ directory
41
+ def self.docker_context_path
42
+ File.expand_path('execution/docker', __dir__)
43
+ end
44
+
45
+ # Versioned image reference used for build and run.
46
+ #
47
+ # @return [String] e.g. "evaluator-sandbox:1.2.0"
48
+ def self.image_ref
49
+ require_relative 'version' unless defined?(SkillBench::VERSION)
50
+
51
+ "#{DOCKER_IMAGE_NAME}:#{SkillBench::VERSION}"
52
+ end
53
+
54
+ # Floating latest tag applied alongside the versioned tag on build.
55
+ #
56
+ # @return [String] e.g. "evaluator-sandbox:latest"
57
+ def self.latest_image_ref
58
+ "#{DOCKER_IMAGE_NAME}:latest"
59
+ end
33
60
  end
34
61
 
35
62
  # Tool Execution Configuration
@@ -0,0 +1,2 @@
1
+ *
2
+ !Dockerfile
@@ -0,0 +1,24 @@
1
+ # SkillBench evaluator-sandbox image contract (MVP)
2
+ #
3
+ # Purpose: long-lived container for `docker exec` of allowlisted agent commands.
4
+ # Runtime flags (from Sandbox#start_container): --network none, non-root uid/gid,
5
+ # --security-opt no-new-privileges, --cap-drop ALL (+ CHOUN/DAC_OVERRIDE).
6
+ #
7
+ # Assumptions:
8
+ # - No package installs or gem fetches during an eval (network is disabled at runtime).
9
+ # - Ruby major tracks CI (3.3/3.4). Bookworm image provides a modern baseline.
10
+ # - git is available for tools that shell out to git inside the sandbox mount.
11
+ # - Multi-arch: build on the host arch (arm64 Mac / amd64 CI) via docker build.
12
+ #
13
+ # See docs/docker.md and milestone container-isolation-v1.
14
+
15
+ FROM ruby:3.4-bookworm
16
+
17
+ RUN apt-get update \
18
+ && apt-get install -y --no-install-recommends git \
19
+ && rm -rf /var/lib/apt/lists/*
20
+
21
+ WORKDIR /sandbox
22
+
23
+ # Keep the container alive so repeated `docker exec` sessions can run commands.
24
+ CMD ["sleep", "infinity"]
@@ -10,11 +10,11 @@ module SkillBench
10
10
  # Manages isolated sandbox environments for running agent evaluations.
11
11
  # Handles copying files, initializing git, and capturing diffs.
12
12
  #
13
- # NOTE: Container isolation is not yet shipped. No Docker build context is
14
- # packaged, so `docker_available?` always returns false and `start_container`
15
- # is never reached `container_id` stays nil and commands run on the host
16
- # (gated by the allowlist and `Config.allow_host_execution`). The container
17
- # code below is the planned isolation model, retained but currently inactive.
13
+ # NOTE: A Docker build context is packaged under execution/docker so gem
14
+ # installs can activate container isolation when a Docker daemon is present.
15
+ # When `docker_available?` is false (no context, no daemon, or docker missing),
16
+ # `container_id` stays nil and commands run on the host only if
17
+ # `Config.allow_host_execution` is enabled (fail closed by default).
18
18
  class Sandbox
19
19
  attr_reader :path, :container_id
20
20
 
@@ -44,6 +44,20 @@ module SkillBench
44
44
  ['git', *GIT_HARDENING, *args]
45
45
  end
46
46
 
47
+ # Absolute path to the packaged Docker build context.
48
+ #
49
+ # @return [String] path to lib/skill_bench/execution/docker
50
+ def self.docker_context_path
51
+ Constants::Sandbox.docker_context_path
52
+ end
53
+
54
+ # Versioned Docker image reference for this gem release.
55
+ #
56
+ # @return [String] image:tag such as evaluator-sandbox:1.2.0
57
+ def self.image_ref
58
+ Constants::Sandbox.image_ref
59
+ end
60
+
47
61
  # Runs a block of code within a temporary, isolated sandbox directory.
48
62
  # The sandbox is initialized as a git repository and optionally wrapped in a Docker container.
49
63
  #
@@ -176,12 +190,13 @@ module SkillBench
176
190
  end
177
191
  end
178
192
 
179
- # Checks if Docker is available and the sandbox Dockerfile exists.
193
+ # Checks if Docker is available and the sandbox Dockerfile context exists.
180
194
  #
181
195
  # @return [Boolean] true if Docker is available, false otherwise.
182
196
  def docker_available?
183
- docker_dir = File.expand_path('docker', __dir__)
197
+ docker_dir = self.class.docker_context_path
184
198
  return false unless File.directory?(docker_dir)
199
+ return false unless File.file?(File.join(docker_dir, 'Dockerfile'))
185
200
 
186
201
  _stdout, _stderr, status = Open3.capture3('docker', 'info')
187
202
  status.success?
@@ -190,23 +205,18 @@ module SkillBench
190
205
  end
191
206
 
192
207
  # Starts a Docker container for isolated command execution.
193
- # Builds the image only if it does not already exist.
208
+ # Builds the image only when the versioned tag is not already present.
194
209
  # Uses hardened security settings for production safety.
195
210
  #
196
211
  # @raise [RuntimeError] when the Docker image cannot be built or the container fails to start.
197
212
  def start_container
198
- image_name = Constants::Sandbox::DOCKER_IMAGE_NAME
199
- docker_dir = File.expand_path('docker', __dir__)
200
-
201
- # Build image (Docker layer cache handles no-op builds)
202
- raise "Failed to build Docker image #{image_name}" unless system('docker', 'build', '-t', image_name, docker_dir, '--quiet')
203
-
204
- # Start a detached container with hardened security settings
205
- # --user $(id -u):$(id -g): Runs as non-root user
206
- # --security-opt no-new-privileges: Prevents privilege escalation
207
- # --cap-drop ALL: Drops all Linux capabilities
208
- # --cap-add CHOWN, DAC_OVERRIDE: Adds back minimal capabilities for git operations
209
- # --network none: Disables network access for additional isolation
213
+ ensure_image
214
+ image = self.class.image_ref
215
+
216
+ # --user uid:gid: non-root
217
+ # --security-opt no-new-privileges: no privilege escalation
218
+ # --cap-drop ALL (+ CHOWN/DAC_OVERRIDE): minimal caps for git volume ops
219
+ # --network none: no network during evals
210
220
  stdout, stderr, status = Open3.capture3(
211
221
  'docker', 'run', '-d', '--rm',
212
222
  '--user', "#{Process.uid}:#{Process.gid}",
@@ -216,7 +226,7 @@ module SkillBench
216
226
  '--cap-add', 'DAC_OVERRIDE',
217
227
  '--network', 'none',
218
228
  '-v', "#{@path}:/sandbox:rw",
219
- image_name
229
+ image
220
230
  )
221
231
 
222
232
  raise "Failed to start Docker container: #{stderr}" unless status.success?
@@ -224,6 +234,35 @@ module SkillBench
224
234
  @container_id = stdout.strip
225
235
  end
226
236
 
237
+ # Ensures the versioned evaluator image exists locally, building only if missing.
238
+ #
239
+ # @raise [RuntimeError] when the image cannot be built.
240
+ # @return [void]
241
+ def ensure_image
242
+ image = self.class.image_ref
243
+ return if image_present?(image)
244
+
245
+ docker_dir = self.class.docker_context_path
246
+ latest = Constants::Sandbox.latest_image_ref
247
+ built = system(
248
+ 'docker', 'build',
249
+ '-t', image,
250
+ '-t', latest,
251
+ docker_dir,
252
+ '--quiet'
253
+ )
254
+ raise "Failed to build Docker image #{image}" unless built
255
+ end
256
+
257
+ # @param image [String] full image reference including tag
258
+ # @return [Boolean] true when docker already has the image
259
+ def image_present?(image)
260
+ _stdout, _stderr, status = Open3.capture3('docker', 'image', 'inspect', image)
261
+ status.success?
262
+ rescue Errno::ENOENT
263
+ false
264
+ end
265
+
227
266
  def stop_container
228
267
  return unless @container_id
229
268
 
@@ -26,6 +26,8 @@ module SkillBench
26
26
  lib/skill_bench/config/store.rb
27
27
  lib/skill_bench/package_verifier.rb
28
28
  lib/skill_bench/execution/source_path_resolver.rb
29
+ lib/skill_bench/execution/docker/Dockerfile
30
+ lib/skill_bench/execution/docker/.dockerignore
29
31
  lib/skill_bench/runner.rb
30
32
  ].freeze
31
33
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module SkillBench
4
4
  # The current gem version.
5
- VERSION = '1.2.0'
5
+ VERSION = '1.3.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-skill-bench
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Marin
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 2.0.0
60
+ version: '1.26'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 2.0.0
67
+ version: '1.26'
68
68
  description: |
69
69
  ruby-skill-bench orchestrates evaluation runs of AI coding agents
70
70
  inside isolated git sandboxes, then scores the results using deterministic
@@ -80,6 +80,7 @@ files:
80
80
  - README.md
81
81
  - bin/skill-bench
82
82
  - docs/architecture.md
83
+ - docs/docker.md
83
84
  - docs/first-eval-guide.md
84
85
  - docs/testing-guide.md
85
86
  - lib/skill_bench.rb
@@ -150,6 +151,8 @@ files:
150
151
  - lib/skill_bench/evaluation/runner.rb
151
152
  - lib/skill_bench/execution.rb
152
153
  - lib/skill_bench/execution/context_hydrator.rb
154
+ - lib/skill_bench/execution/docker/.dockerignore
155
+ - lib/skill_bench/execution/docker/Dockerfile
153
156
  - lib/skill_bench/execution/sandbox.rb
154
157
  - lib/skill_bench/execution/source_path_resolver.rb
155
158
  - lib/skill_bench/history_recorder.rb
@@ -245,7 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
248
  - !ruby/object:Gem::Version
246
249
  version: '0'
247
250
  requirements: []
248
- rubygems_version: 3.6.9
251
+ rubygems_version: 4.0.16
249
252
  specification_version: 4
250
253
  summary: The evaluation engine for AI Agent Skills benchmarking.
251
254
  test_files: []