Class: Kobako::Transport::Run
- Inherits:
-
Data
- Object
- Data
- Kobako::Transport::Run
- Defined in:
- lib/kobako/transport/run.rb,
sig/kobako/transport/run.rbs
Overview
Host-side value object for a single Sandbox#run invocation
(docs/wire-codec.md Invocation channels).
A Run captures the host-layer concept of "a single #run
call": the entrypoint constant name plus its positional and keyword
arguments. Host pre-flight (entrypoint type / name pattern, forged
Handle, kwargs-key type) is enforced at construction so the Value
Object is the single source of truth — anything that passes
Run.new is safe to ship to the guest.
#payload takes the invocation's Catalog::Handles and routes any
non-wire-representable args / kwargs leaf through it as a
Kobako::Handle — the symmetric counterpart of the guest→host wrap
path in the dispatcher. A Kobako::Handle that arrives already
constructed in the caller's args / kwargs is rejected at
construction: legitimate Handles only enter Host App code through
error fields, so a Handle reaching the call site is by definition
smuggled in. Runtime#run frames that payload with the entrypoint
into the Run envelope the __kobako_run command buffer carries.
Built on the class X < Data.define(...) subclass form (the
Steep-friendly shape — see .rubocop.yml for the rationale).
Constant Summary collapse
- NAME_PATTERN =
Ruby constant-name pattern enforced on the
entrypointSymbol. Parallel toKobako::Catalog::Snippets::NAME_PATTERN; the two constants name the same regex but cover distinct surfaces (snippet identity vs. entrypoint resolution) so a future divergence stays local. /\A[A-Z]\w*\z/
Instance Attribute Summary collapse
-
#args ⇒ Array[Kobako::Codec::wire_value]
readonly
Returns the value of attribute args.
-
#entrypoint ⇒ Symbol
readonly
Returns the value of attribute entrypoint.
-
#kwargs ⇒ Hash[Symbol, Kobako::Codec::wire_value]
readonly
Returns the value of attribute kwargs.
Class Method Summary collapse
Instance Method Summary collapse
-
#forged_handle_message(slot) ⇒ String
Single source of truth for the forged-Handle reject message so the args and kwargs branches stay phrased identically.
-
#initialize(entrypoint:, args: [], kwargs: {}) ⇒ Run
constructor
A new instance of Run.
-
#normalize_entrypoint(target) ⇒ Symbol
The target must be a Symbol or String (TypeError, not ArgumentError — the wrong-type case is a Host App programming error before the run reaches the guest).
-
#payload(handler) ⇒ String
Encode this Run's arguments as the codec payload the Run envelope carries —
Runtime#runframes it with the entrypoint. -
#validate_args!(args) ⇒ void
argsmust not contain aKobako::Handle. -
#validate_kwargs!(kwargs) ⇒ void
Reject a non-Symbol kwargs key, and a
Kobako::Handlearriving as a kwargs value (same forged-token principle as theargsbranch).
Constructor Details
#initialize(entrypoint:, args: [], kwargs: {}) ⇒ Run
Returns a new instance of Run.
42 43 44 45 46 47 |
# File 'lib/kobako/transport/run.rb', line 42 def initialize(entrypoint:, args: [], kwargs: {}) entrypoint = normalize_entrypoint(entrypoint) validate_args!(args) validate_kwargs!(kwargs) super end |
Instance Attribute Details
#args ⇒ Array[Kobako::Codec::wire_value] (readonly)
Returns the value of attribute args.
7 8 9 |
# File 'sig/kobako/transport/run.rbs', line 7 def args @args end |
#entrypoint ⇒ Symbol (readonly)
Returns the value of attribute entrypoint.
6 7 8 |
# File 'sig/kobako/transport/run.rbs', line 6 def entrypoint @entrypoint end |
#kwargs ⇒ Hash[Symbol, Kobako::Codec::wire_value] (readonly)
Returns the value of attribute kwargs.
8 9 10 |
# File 'sig/kobako/transport/run.rbs', line 8 def kwargs @kwargs end |
Class Method Details
.new ⇒ Run
10 |
# File 'sig/kobako/transport/run.rbs', line 10
def self.new: (entrypoint: Symbol | String, ?args: Array[untyped], ?kwargs: Hash[untyped, untyped]) -> Run
|
Instance Method Details
#forged_handle_message(slot) ⇒ String
Single source of truth for the forged-Handle reject message so the args and kwargs branches stay phrased identically. Message stays in caller vocabulary: it names the affected slot and the reason without leaking internal SPEC identifiers or self-referential architecture terms — the error is raised BY kobako, so saying "allocated by the Host Gem" reads as third-person about self.
118 119 120 121 |
# File 'lib/kobako/transport/run.rb', line 118 def (slot) "#{slot} must not contain a Kobako::Handle — " \ "Handles are created internally by the Sandbox and cannot be passed in" end |
#normalize_entrypoint(target) ⇒ Symbol
The target must be a Symbol or String (TypeError, not
ArgumentError — the wrong-type case is a Host App programming
error before the run reaches the guest). After .to_s
the value must match NAME_PATTERN (ArgumentError), rejecting
+::+-segmented names and any non-constant form.
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/kobako/transport/run.rb', line 71 def normalize_entrypoint(target) unless target.is_a?(Symbol) || target.is_a?(String) raise TypeError, "entrypoint must be a Symbol or String, got #{target.class}" end target_str = target.to_s unless NAME_PATTERN.match?(target_str) raise ArgumentError, "entrypoint must match #{NAME_PATTERN.inspect} (got #{target.inspect})" end target_str.to_sym end |
#payload(handler) ⇒ String
Encode this Run's arguments as the codec payload the Run
envelope carries — Runtime#run frames it with the entrypoint.
Walks args / kwargs through Codec::HandleWalk.deep_wrap so
any non-wire-representable leaf is allocated into handler and
replaced with a Kobako::Handle; the handler argument is the
invocation's table, sharing the same allocator the guest→host
return path uses. A wrapped leaf rides as ext 0x01 in its
original position (docs/wire/payload-msgpack.md § ext 0x01).
57 58 59 60 61 62 |
# File 'lib/kobako/transport/run.rb', line 57 def payload(handler) Payload::Arguments.new( args: Codec::HandleWalk.deep_wrap(args, handler), kwargs: Codec::HandleWalk.deep_wrap(kwargs, handler) ).encode end |
#validate_args!(args) ⇒ void
This method returns an undefined value.
args must not contain a Kobako::Handle. The Handle
allocator lives inside the Host Gem; legitimate paths surface
Handle objects only through raised error fields, so a Handle
reaching args is a forged or smuggled token. Non-wire-
representable arguments that are not Handles are handled by
auto-wrap inside #payload — the reject path is reserved
for Handle objects specifically.
92 93 94 95 |
# File 'lib/kobako/transport/run.rb', line 92 def validate_args!(args) raise ArgumentError, "arguments must be an Array" unless args.is_a?(Array) raise ArgumentError, ("arguments") if args.any?(Kobako::Handle) end |
#validate_kwargs!(kwargs) ⇒ void
This method returns an undefined value.
Reject a non-Symbol kwargs key, and a Kobako::Handle arriving
as a kwargs value (same forged-token principle as the args
branch). Both checks live here so the Host App sees the
host-side error message before any encode / decode boundary.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/kobako/transport/run.rb', line 101 def validate_kwargs!(kwargs) raise ArgumentError, "keyword arguments must be a Hash" unless kwargs.is_a?(Hash) bad_keys = kwargs.each_key.grep_v(Symbol) unless bad_keys.empty? raise ArgumentError, "keyword argument keys must be Symbols (got #{bad_keys.inspect})" end raise ArgumentError, ("keyword argument values") if kwargs.each_value.any?(Kobako::Handle) end |