Class: SkillBench::Execution::Sandbox
- Inherits:
-
Object
- Object
- SkillBench::Execution::Sandbox
- Defined in:
- lib/skill_bench/execution/sandbox.rb
Overview
Manages isolated sandbox environments for running agent evaluations. Handles copying files, initializing git, and capturing diffs.
NOTE: Container isolation is not yet shipped. No Docker build context is
packaged, so docker_available? always returns false and start_container
is never reached — container_id stays nil and commands run on the host
(gated by the allowlist and Config.allow_host_execution). The container
code below is the planned isolation model, retained but currently inactive.
Constant Summary collapse
- GIT_HARDENING =
Global
gitoptions applied to every host-side invocation. They strip the repository's and user's ability to launch external programs during routine git operations on untrusted source:- core.attributesFile=/dev/null no user-level .gitattributes drivers - core.fsmonitor=false no fsmonitor hook program - core.hooksPath=/dev/null no git hooks (pre-commit, etc.) - core.symlinks=false symlinks treated as plain filesCombined with not copying the source
.git, this neutralizes the.gitattributes/config diff & filter driver code-execution vector. [ '-c', 'core.attributesFile=/dev/null', '-c', 'core.fsmonitor=false', '-c', 'core.hooksPath=/dev/null', '-c', 'core.symlinks=false' ].freeze
Instance Attribute Summary collapse
-
#container_id ⇒ Object
readonly
Returns the value of attribute container_id.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
-
.capture_diff(sandbox_dir) ⇒ String
Captures the git diff of changes made within the sandbox.
-
.git_command(*args) ⇒ Array<String>
Builds a hardened
gitargv: the binary, the hardening flags, then the given subcommand and arguments. -
.run(source_dir) {|sandbox| ... } ⇒ Object
Runs a block of code within a temporary, isolated sandbox directory.
Instance Method Summary collapse
-
#initialize(source_dir) ⇒ Sandbox
constructor
A new instance of Sandbox.
-
#run {|sandbox| ... } ⇒ Object
Executes the sandbox environment setup and yields the sandbox instance.
Constructor Details
#initialize(source_dir) ⇒ Sandbox
Returns a new instance of Sandbox.
60 61 62 63 64 |
# File 'lib/skill_bench/execution/sandbox.rb', line 60 def initialize(source_dir) @source_dir = source_dir @path = nil @container_id = nil end |
Instance Attribute Details
#container_id ⇒ Object (readonly)
Returns the value of attribute container_id.
19 20 21 |
# File 'lib/skill_bench/execution/sandbox.rb', line 19 def container_id @container_id end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
19 20 21 |
# File 'lib/skill_bench/execution/sandbox.rb', line 19 def path @path end |
Class Method Details
.capture_diff(sandbox_dir) ⇒ String
Captures the git diff of changes made within the sandbox.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/skill_bench/execution/sandbox.rb', line 93 def self.capture_diff(sandbox_dir) sandbox_path = File.realpath(sandbox_dir) tmp_prefix = File.realpath(Dir.tmpdir) + File::SEPARATOR raise "Sandbox directory #{sandbox_dir} is outside temp directory" unless sandbox_path.start_with?(tmp_prefix) return 'No code changes made.' unless File.directory?(File.join(sandbox_path, '.git')) raise "Failed to stage changes in #{sandbox_path}" unless system(*git_command('add', '.'), chdir: sandbox_path) diff, status = Open3.capture2(*git_command('diff', '--cached'), chdir: sandbox_path) raise "Failed to capture diff in #{sandbox_path}" unless status.success? diff.strip.empty? ? 'No code changes made.' : diff end |
.git_command(*args) ⇒ Array<String>
Builds a hardened git argv: the binary, the hardening flags, then the
given subcommand and arguments. Single source of truth so every git
call in this file is invoked with the same protections.
43 44 45 |
# File 'lib/skill_bench/execution/sandbox.rb', line 43 def self.git_command(*args) ['git', *GIT_HARDENING, *args] end |
.run(source_dir) {|sandbox| ... } ⇒ Object
Runs a block of code within a temporary, isolated sandbox directory. The sandbox is initialized as a git repository and optionally wrapped in a Docker container.
55 56 57 |
# File 'lib/skill_bench/execution/sandbox.rb', line 55 def self.run(source_dir, &) new(source_dir).run(&) end |
Instance Method Details
#run {|sandbox| ... } ⇒ Object
Executes the sandbox environment setup and yields the sandbox instance.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/skill_bench/execution/sandbox.rb', line 72 def run Dir.mktmpdir('evaluator_sandbox_') do |sandbox_dir| @path = sandbox_dir copy_source_files(sandbox_dir) setup_git start_container if docker_available? begin yield self ensure stop_container end end end |