Module: Rigor::Plugin::Box

Defined in:
lib/rigor/plugin/box.rb

Overview

ADR-39 slice 5 — the isolation boundary for target-library invocation. When Rigor is launched with ‘RUBY_BOX=1` (opt-in; the launcher re-execs only when a project opts in), a target library is loaded and called inside a `Ruby::Box` so its **core-class monkey-patches and gem version cannot contaminate Rigor’s main space**. ‘Ruby::Box` is not a security sandbox (the gem’s code still runs in-process) — it is the contamination boundary the rule needs, which is sufficient because the rule only ever invokes a declared, trusted, pure target library.

**Disabled by default.** Box.enabled? is false unless the experimental ‘Ruby::Box` feature is active, so every consumer keeps a non-box path and the default behaviour (loading the trusted library into the main space, per slices 2/4) is unchanged. The box only ever holds the trusted, project-agnostic target libraries (inflection rules, the Rack status table); per-project / exact-version boxes are a later slice.

Class Method Summary collapse

Class Method Details

.enabled?Boolean

True only when the experimental ‘Ruby::Box` feature is present and active (the process was started with `RUBY_BOX=1`). Any error answers false so a consumer silently keeps its non-box path.

Returns:

  • (Boolean)


28
29
30
31
32
# File 'lib/rigor/plugin/box.rb', line 28

def enabled?
  defined?(::Ruby::Box) && ::Ruby::Box.respond_to?(:enabled?) && ::Ruby::Box.enabled?
rescue StandardError
  false
end

.eval(code) ⇒ Object

Evaluates ‘code` inside the shared box and returns the result across the box boundary. The caller MUST build `code` safely —interpolate value arguments through `String#inspect` (which round-trips as a safe Ruby literal) and only ever interpolate method names from a fixed allow-list, never free user input.



59
60
61
# File 'lib/rigor/plugin/box.rb', line 59

def eval(code)
  shared.eval(code)
end

.require_feature(feature) ⇒ Object

Requires ‘feature` into the shared box exactly once. Returns true when the feature is available in the box, false when it could not be loaded (the caller then declines — never falls back to loading into the main space, which would defeat the boundary).



44
45
46
47
48
49
50
51
52
# File 'lib/rigor/plugin/box.rb', line 44

def require_feature(feature)
  @required ||= {}
  return @required[feature] if @required.key?(feature)

  shared.require(feature)
  @required[feature] = true
rescue StandardError
  @required[feature] = false
end

.sharedObject

The process-shared box for trusted, project-agnostic target libraries. Built lazily on first use.



36
37
38
# File 'lib/rigor/plugin/box.rb', line 36

def shared
  @shared ||= ::Ruby::Box.new
end