kobako 0.13.0-aarch64-linux → 0.14.0-aarch64-linux
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 +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +30 -0
- data/README.md +3 -3
- data/ROADMAP.md +26 -0
- data/crates/kobako-runtime/CHANGELOG.md +7 -0
- data/crates/kobako-runtime/README.md +1 -1
- data/crates/kobako-wasmtime/CHANGELOG.md +7 -0
- data/crates/kobako-wasmtime/README.md +1 -1
- data/data/kobako.wasm +0 -0
- data/lib/kobako/3.3/kobako.so +0 -0
- data/lib/kobako/3.4/kobako.so +0 -0
- data/lib/kobako/4.0/kobako.so +0 -0
- data/lib/kobako/catalog/handles.rb +2 -2
- data/lib/kobako/catalog/namespaces.rb +2 -2
- data/lib/kobako/catalog/snippets.rb +1 -1
- data/lib/kobako/codec/decoder.rb +7 -7
- data/lib/kobako/codec/encoder.rb +2 -2
- data/lib/kobako/codec/error.rb +3 -3
- data/lib/kobako/codec/factory.rb +10 -10
- data/lib/kobako/codec/handle_walk.rb +17 -21
- data/lib/kobako/codec/utils.rb +9 -9
- data/lib/kobako/codec.rb +3 -3
- data/lib/kobako/errors.rb +14 -39
- data/lib/kobako/handle.rb +5 -2
- data/lib/kobako/namespace.rb +3 -3
- data/lib/kobako/outcome.rb +1 -0
- data/lib/kobako/sandbox.rb +10 -12
- data/lib/kobako/transport/dispatcher.rb +17 -14
- data/lib/kobako/transport/request.rb +2 -2
- data/lib/kobako/transport/response.rb +2 -2
- data/lib/kobako/transport/run.rb +1 -1
- data/lib/kobako/transport/yield.rb +3 -3
- data/lib/kobako/transport/yielder.rb +6 -6
- data/lib/kobako/version.rb +1 -1
- data/release-please-config.json +37 -7
- data/sig/kobako/codec/handle_walk.rbs +2 -2
- data/sig/kobako/codec.rbs +11 -0
- data/sig/kobako/handle.rbs +0 -2
- data/sig/kobako/transport/dispatcher.rbs +8 -8
- data/sig/kobako/transport/run.rbs +1 -1
- data/sig/kobako/transport/yielder.rbs +2 -2
- data/sig/kobako/transport.rbs +8 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f52be5d778b482a65c810fb530ac716fd2232d2b54cc98aea60f906aa6959fe9
|
|
4
|
+
data.tar.gz: f537ac1f62dad56b63bbed4456b548495310c6809983765005d54f54ed195e4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b0e38dd483517aa63e12d90e1936ee7f27ea0a3c2c1f7a998f7e475b4351313f170284d56c6b9e33f30d7925659adf5ed509b2c3b3f6eeaa8a8ae75bd25d620d
|
|
7
|
+
data.tar.gz: 2269f4eac755583383a491a9441cd2b30f54e174c7b16187ae0ef9e9520bd69dffd8950061aa59a387e9e91360d9c8bfdc21232f1da746cb3385b831ad723adb
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{".":"0.
|
|
1
|
+
{".":"0.14.0","wasm/kobako-core":"0.8.0","wasm/kobako-mruby":"0.8.0","wasm/kobako-io":"0.8.0","wasm/kobako-json":"0.8.0","wasm/kobako-regexp":"0.8.0","wasm/kobako-baker":"0.8.0","crates/kobako-codec":"0.8.0","crates/kobako-runtime":"0.8.0","crates/kobako-wasmtime":"0.8.0","crates/kobako":"0.8.0"}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.0](https://github.com/elct9620/kobako/compare/v0.13.0...v0.14.0) (2026-07-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **codec:** add the Run invocation envelope to the wire tier ([dbdd760](https://github.com/elct9620/kobako/commit/dbdd760ddc258681669f7f620f63b75f36322687))
|
|
9
|
+
* **crates:** add the kobako host SDK skeleton ([8a99d09](https://github.com/elct9620/kobako/commit/8a99d09ef7068a6738d44f1a735d39516b24156b))
|
|
10
|
+
* **crates:** add the parity runner to the kobako SDK ([998f059](https://github.com/elct9620/kobako/commit/998f059abd308ef921c295658aaf8377febb44e2))
|
|
11
|
+
* **crates:** grow the SDK capability-Handle table ([f93fe8f](https://github.com/elct9620/kobako/commit/f93fe8f3dce2509cfa527229f8f593f4d816b940))
|
|
12
|
+
* **crates:** grow the SDK Member block-yield seam ([4404713](https://github.com/elct9620/kobako/commit/44047130f309a2c935198077fb4f7f86839355e7))
|
|
13
|
+
* **crates:** grow the SDK preload and run invocation seams ([d8d5fe2](https://github.com/elct9620/kobako/commit/d8d5fe268a56d45dad4f8b35a25e942a559dcd5f))
|
|
14
|
+
* **crates:** honor the respond_to_guest narrowing on the SDK Member seam ([0f5eff1](https://github.com/elct9620/kobako/commit/0f5eff16a1e9f2229ad9d9c9316bf94e92035301))
|
|
15
|
+
* **crates:** let a resolved Handle recover its concrete member type ([abd5502](https://github.com/elct9620/kobako/commit/abd55029a44a7631d323c3aec3b625d9692f9c5b))
|
|
16
|
+
* **crates:** mark the SDK Error taxonomy non_exhaustive ([001fc69](https://github.com/elct9620/kobako/commit/001fc69e637d2c046f55cb517f9d9cf931793715))
|
|
17
|
+
* **examples:** add the guest→host dispatch half to the Rust host ([5cdde68](https://github.com/elct9620/kobako/commit/5cdde68824352c5685aaa94ae464e909705a4648))
|
|
18
|
+
* **examples:** assemble a minimal Rust host on the published crates ([6b98680](https://github.com/elct9620/kobako/commit/6b98680bcb625f9790f44df839035427a576e266))
|
|
19
|
+
* **tasks:** add a rails-stats-style rake stats size report ([c02d530](https://github.com/elct9620/kobako/commit/c02d530d43a85594323b7801fdbe75aa95ae7f8c))
|
|
20
|
+
* **tasks:** gate parity coverage over the CORE anchor manifest ([d26972c](https://github.com/elct9620/kobako/commit/d26972c1ad51e05df951643e17d66a6c811ba862))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **crates:** give SetupError a Display so Error::Setup reads cleanly ([bc8b128](https://github.com/elct9620/kobako/commit/bc8b128c9e296319c7fef47441b412d2ce345dff))
|
|
26
|
+
* **crates:** keep the no-timeout epoch deadline within range ([a3255df](https://github.com/elct9620/kobako/commit/a3255df98a77825bb39b571a60fe6ff83d269d19))
|
|
27
|
+
* **crates:** reject trailing bytes on Request and Run decode ([8e4929b](https://github.com/elct9620/kobako/commit/8e4929b64f3ea690f38211888070c2511da84754))
|
|
28
|
+
* **lib:** close the Data #with seam on Handle construction ([c0b50ae](https://github.com/elct9620/kobako/commit/c0b50aec659e32a72c905aaf94c939ac009ad621))
|
|
29
|
+
* **release:** resume the gem push loop past already-live versions ([170ee9b](https://github.com/elct9620/kobako/commit/170ee9bae6da3a65b4016040259e31e4721dfcfb))
|
|
30
|
+
* **release:** treat a yanked-only version as unpublished when publishing ([3111cc0](https://github.com/elct9620/kobako/commit/3111cc072a7c9d18b129fd2762f267d855b48d55))
|
|
31
|
+
* **transport:** fold fault messages to UTF-8 before they ride the wire ([0be8d40](https://github.com/elct9620/kobako/commit/0be8d4068dc5647f86746e80b356b0b9d52051f7))
|
|
32
|
+
|
|
3
33
|
## [0.13.0](https://github.com/elct9620/kobako/compare/v0.12.2...v0.13.0) (2026-07-03)
|
|
4
34
|
|
|
5
35
|
|
data/README.md
CHANGED
|
@@ -302,10 +302,10 @@ sandbox.run(:Greeter, name: "world") # => "hello, world"
|
|
|
302
302
|
|
|
303
303
|
| Form | Signature | Snippet name source | Validation timing |
|
|
304
304
|
|----------|--------------------------------------|---------------------------------------|----------------------------------------------------------------------------|
|
|
305
|
-
| Source | `preload(code: "...", name: :Const)` | The `name:` keyword |
|
|
306
|
-
| Bytecode | `preload(binary: bytes)` | Read from the bytecode's `debug_info` |
|
|
305
|
+
| Source | `preload(code: "...", name: :Const)` | The `name:` keyword | First invocation's replay; compile errors raise `Kobako::SandboxError` |
|
|
306
|
+
| Bytecode | `preload(binary: bytes)` | Read from the bytecode's `debug_info` | First invocation's replay; structural failure raises `Kobako::BytecodeError` |
|
|
307
307
|
|
|
308
|
-
Use the source form for snippets authored in your repo
|
|
308
|
+
Use the source form for snippets authored in your repo; use the bytecode form when snippets ship as build artifacts from a separate `mrbc` pipeline. Both replay through the same per-invocation path, so no snippet content failure surfaces at `#preload` — force the first replay with a no-op invocation (e.g. `sandbox.eval("nil")`) when you want validation before real traffic.
|
|
309
309
|
|
|
310
310
|
## Security
|
|
311
311
|
|
data/ROADMAP.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
kobako is a Ruby gem providing an in-process Wasm sandbox for untrusted mruby
|
|
4
|
+
code: a wasmtime host runs a precompiled `kobako.wasm` guest, with host↔guest
|
|
5
|
+
Transport over a MessagePack wire. Features cover one-shot `#eval`, preload +
|
|
6
|
+
`#run` dispatch, Service injection through Namespaces / Members, opaque
|
|
7
|
+
Capability Handles, block yield re-entry, three-class error attribution,
|
|
8
|
+
output capture, and a warm Sandbox pool.
|
|
9
|
+
|
|
10
|
+
| Feature | Entry Points | Notes |
|
|
11
|
+
|---------|-------------|-------|
|
|
12
|
+
| ✅ [F-01 Sandbox instantiation](docs/behavior/lifecycle.md) | [lib/kobako/sandbox.rb](lib/kobako/sandbox.rb) | B-22 (per-Thread isolation) is exercised only indirectly through the pool contention tests; no test cites it |
|
|
13
|
+
| ✅ [F-02 Namespace declaration](docs/behavior/registration.md) | [lib/kobako/catalog/namespaces.rb](lib/kobako/catalog/namespaces.rb) | — |
|
|
14
|
+
| ✅ [F-03 Member binding](docs/behavior/registration.md) | [lib/kobako/namespace.rb](lib/kobako/namespace.rb) | — |
|
|
15
|
+
| ✅ [F-04 Synchronous mruby source execution (`#eval`)](docs/behavior/lifecycle.md) | [lib/kobako/sandbox.rb](lib/kobako/sandbox.rb) | — |
|
|
16
|
+
| ✅ [F-05 Guest-initiated Transport dispatch](docs/behavior/dispatch.md) | [lib/kobako/transport/dispatcher.rb](lib/kobako/transport/dispatcher.rb) | — |
|
|
17
|
+
| ✅ [F-06 Capability Handle encoding and referencing](docs/behavior/dispatch.md) | [lib/kobako/catalog/handles.rb](lib/kobako/catalog/handles.rb) | — |
|
|
18
|
+
| ✅ [F-07 Three-class error attribution and raising](docs/behavior/errors.md) | [lib/kobako/outcome.rb](lib/kobako/outcome.rb) | E-26 (guest-entry envelope decode failure) has no exercising test — not reachable through the public API |
|
|
19
|
+
| ✅ [F-08 Guest output capture](docs/behavior/lifecycle.md) | [lib/kobako/capture.rb](lib/kobako/capture.rb) | — |
|
|
20
|
+
| ✅ [F-09 Host–guest message codec](docs/wire-codec.md) | [lib/kobako/codec/](lib/kobako/codec/) | — |
|
|
21
|
+
| ✅ [F-10 Reproducible build pipeline](SPEC.md#code-organization) | [tasks/wasm/build.rake](tasks/wasm/build.rake) | Verified by build-time gates (`rake anchors`, double-bake byte-identity, gemspec whitelist), not `test/` |
|
|
22
|
+
| ✅ [F-11 Multi-layer test and benchmark suite](SPEC.md#testing-style) | [test/](test/) | Benchmarks live in [benchmark/](benchmark/) with the gate in `tasks/bench/`; the anchor baseline advances only by deliberate re-bless |
|
|
23
|
+
| ✅ [F-12 Guest block reception and yield re-entry](docs/behavior/yield.md) | [lib/kobako/transport/yielder.rb](lib/kobako/transport/yielder.rb) | — |
|
|
24
|
+
| ✅ [F-13 Snippet preloading (`#preload`)](docs/behavior/invocation.md) | [lib/kobako/catalog/snippets.rb](lib/kobako/catalog/snippets.rb) | — |
|
|
25
|
+
| ✅ [F-14 Synchronous entrypoint dispatch (`#run`)](docs/behavior/invocation.md) | [lib/kobako/sandbox.rb](lib/kobako/sandbox.rb) | — |
|
|
26
|
+
| ✅ [F-15 Warm Sandbox pool checkout (`Kobako::Pool`)](docs/behavior/runtime.md) | [lib/kobako/pool.rb](lib/kobako/pool.rb) | — |
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.0](https://github.com/elct9620/kobako/compare/kobako-runtime-v0.7.0...kobako-runtime-v0.8.0) (2026-07-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **crates:** give SetupError a Display so Error::Setup reads cleanly ([bc8b128](https://github.com/elct9620/kobako/commit/bc8b128c9e296319c7fef47441b412d2ce345dff))
|
|
9
|
+
|
|
3
10
|
## [0.7.0](https://github.com/elct9620/kobako/compare/kobako-runtime-v0.6.1...kobako-runtime-v0.7.0) (2026-07-03)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.0](https://github.com/elct9620/kobako/compare/kobako-wasmtime-v0.7.0...kobako-wasmtime-v0.8.0) (2026-07-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **crates:** keep the no-timeout epoch deadline within range ([a3255df](https://github.com/elct9620/kobako/commit/a3255df98a77825bb39b571a60fe6ff83d269d19))
|
|
9
|
+
|
|
3
10
|
## [0.7.0](https://github.com/elct9620/kobako/compare/kobako-wasmtime-v0.6.1...kobako-wasmtime-v0.7.0) (2026-07-03)
|
|
4
11
|
|
|
5
12
|
|
data/data/kobako.wasm
CHANGED
|
Binary file
|
data/lib/kobako/3.3/kobako.so
CHANGED
|
Binary file
|
data/lib/kobako/3.4/kobako.so
CHANGED
|
Binary file
|
data/lib/kobako/4.0/kobako.so
CHANGED
|
Binary file
|
|
@@ -95,7 +95,7 @@ module Kobako
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
# Guard
|
|
98
|
+
# Guard #alloc against issuing an ID past the cap. Returns +nil+
|
|
99
99
|
# on success; raises +Kobako::HandleExhaustedError+ at exhaustion.
|
|
100
100
|
def ensure_capacity!
|
|
101
101
|
cap = Kobako::Handle::MAX_ID
|
|
@@ -107,7 +107,7 @@ module Kobako
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# Single source of truth for the "unknown Handle id" raise used by
|
|
110
|
-
#
|
|
110
|
+
# #fetch. Returns +nil+ on success; raises +Kobako::SandboxError+
|
|
111
111
|
# when +id+ is not currently bound.
|
|
112
112
|
def require_bound!(id)
|
|
113
113
|
return if @entries.key?(id)
|
|
@@ -71,7 +71,7 @@ module Kobako
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
# Encode the preamble as msgpack bytes for stdin Frame 1 delivery.
|
|
74
|
-
# Routes through
|
|
74
|
+
# Routes through Kobako::Codec::Encoder like every other host-side
|
|
75
75
|
# wire encode so there is a single codec path; the preamble carries
|
|
76
76
|
# only Strings and Arrays, so none of the kobako ext types actually
|
|
77
77
|
# fire. Structure: +[["Namespace", ["MemberA", "MemberB"]], ...]+.
|
|
@@ -106,7 +106,7 @@ module Kobako
|
|
|
106
106
|
self
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
# Returns +true+ when
|
|
109
|
+
# Returns +true+ when #seal! has been called, +false+ otherwise.
|
|
110
110
|
def sealed?
|
|
111
111
|
@sealed
|
|
112
112
|
end
|
|
@@ -43,7 +43,7 @@ module Kobako
|
|
|
43
43
|
#
|
|
44
44
|
# The bytes are memoized — the table is replayed verbatim on every
|
|
45
45
|
# invocation after sealing, so Frame 3 never changes between
|
|
46
|
-
# encodes;
|
|
46
|
+
# encodes; #register drops the memo while the table is still open.
|
|
47
47
|
# Unlike +Catalog::Namespaces#encode+, which gates its memo on the
|
|
48
48
|
# seal, this one can fill eagerly and invalidate in +#register+
|
|
49
49
|
# because every mutation funnels through that single method — there is
|
data/lib/kobako/codec/decoder.rb
CHANGED
|
@@ -12,23 +12,23 @@ module Kobako
|
|
|
12
12
|
# ({docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type Mapping).
|
|
13
13
|
#
|
|
14
14
|
# Translates msgpack gem exceptions into the kobako error taxonomy
|
|
15
|
-
# (
|
|
15
|
+
# (Truncated, InvalidType, InvalidEncoding, UnsupportedType) so
|
|
16
16
|
# callers can pattern-match on the SPEC's wire-violation categories
|
|
17
17
|
# without leaking the gem's internal exception classes.
|
|
18
18
|
#
|
|
19
|
-
# Public API is a single function —
|
|
19
|
+
# Public API is a single function — +.decode+. The decoder is
|
|
20
20
|
# stateless; the +MessagePack::Unpacker+ instance is built per call
|
|
21
21
|
# because callers always decode exactly one wire value at a time.
|
|
22
22
|
module Decoder
|
|
23
23
|
# Decode +bytes+ into one Ruby value and validate transitively
|
|
24
|
-
# against the SPEC type mapping. Raises
|
|
25
|
-
# or
|
|
24
|
+
# against the SPEC type mapping. Raises Truncated, InvalidType,
|
|
25
|
+
# or InvalidEncoding on wire violations.
|
|
26
26
|
#
|
|
27
27
|
# When a block is given, the decoded value is yielded and the block's
|
|
28
28
|
# result is returned — wire Value Objects use this to build themselves
|
|
29
29
|
# from the decoded payload. The block runs inside this method's
|
|
30
30
|
# rescue, so a Value Object's +ArgumentError+ invariant failure
|
|
31
|
-
# surfaces as
|
|
31
|
+
# surfaces as InvalidType without a separate Utils.with_boundary
|
|
32
32
|
# wrapper at the call site.
|
|
33
33
|
def self.decode(bytes)
|
|
34
34
|
value = Factory.load(bytes.b)
|
|
@@ -37,7 +37,7 @@ module Kobako
|
|
|
37
37
|
# msgpack gem raises the format/type errors below; +ArgumentError+
|
|
38
38
|
# comes from our ext-type validators (Handle id range, Exception type
|
|
39
39
|
# whitelist) and from a yielded block's Value Object invariants — both
|
|
40
|
-
# are wire violations, so both map to
|
|
40
|
+
# are wire violations, so both map to InvalidType.
|
|
41
41
|
rescue ::MessagePack::UnknownExtTypeError, ::MessagePack::MalformedFormatError,
|
|
42
42
|
::MessagePack::StackError, ::ArgumentError => e
|
|
43
43
|
raise InvalidType, e.message
|
|
@@ -53,7 +53,7 @@ module Kobako
|
|
|
53
53
|
# Encoding Rules). The msgpack gem returns UTF-8-tagged Strings for
|
|
54
54
|
# str family but does not validate the bytes; +bin+ family decodes
|
|
55
55
|
# to ASCII-8BIT. Walk the tree once and reject invalid UTF-8 in any
|
|
56
|
-
# str-typed leaf via
|
|
56
|
+
# str-typed leaf via Utils.assert_utf8!. Kobako::Fault
|
|
57
57
|
# payloads are validated transitively: +Factory.unpack_fault+
|
|
58
58
|
# feeds the inner ext-0x02 bytes back through this Decoder, so their
|
|
59
59
|
# +str+ fields are already covered by the time control returns here.
|
data/lib/kobako/codec/encoder.rb
CHANGED
|
@@ -14,9 +14,9 @@ module Kobako
|
|
|
14
14
|
# strings, arrays, and maps go through the gem's narrowest-encoding
|
|
15
15
|
# logic; the three kobako-specific ext types (0x00 Symbol, 0x01
|
|
16
16
|
# Capability Handle, 0x02 Exception envelope) are registered on
|
|
17
|
-
# the cached
|
|
17
|
+
# the cached Kobako::Codec::Factory singleton.
|
|
18
18
|
#
|
|
19
|
-
# Public API is a single function —
|
|
19
|
+
# Public API is a single function — +.encode+. The codec is stateless;
|
|
20
20
|
# there is no buffer accumulator and no streaming write API. Callers
|
|
21
21
|
# that need to concatenate multiple encodings build the bytes
|
|
22
22
|
# themselves.
|
data/lib/kobako/codec/error.rb
CHANGED
|
@@ -7,11 +7,11 @@ module Kobako
|
|
|
7
7
|
# The wire codec implements the binary contract pinned in
|
|
8
8
|
# {docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type Mapping.
|
|
9
9
|
# Every wire violation surfaces as a
|
|
10
|
-
# subclass of
|
|
10
|
+
# subclass of Error so callers can pattern-match on the specific
|
|
11
11
|
# fault while still rescuing all codec faults via this base class.
|
|
12
12
|
#
|
|
13
13
|
# Higher layers (e.g. the Sandbox dispatch loop) translate these into
|
|
14
|
-
# the public
|
|
14
|
+
# the public Kobako::SandboxError / Kobako::TrapError taxonomy.
|
|
15
15
|
class Error < StandardError; end
|
|
16
16
|
|
|
17
17
|
# Input ended before the type prefix or payload was fully consumed.
|
|
@@ -21,7 +21,7 @@ module Kobako
|
|
|
21
21
|
# type mapping (e.g. an unknown ext code, or a reserved msgpack tag).
|
|
22
22
|
class InvalidType < Error; end
|
|
23
23
|
|
|
24
|
-
# A msgpack
|
|
24
|
+
# A msgpack +str+ payload was not valid UTF-8, or an ext 0x00 Symbol
|
|
25
25
|
# payload was not valid UTF-8 — both are wire violations per SPEC.
|
|
26
26
|
class InvalidEncoding < Error; end
|
|
27
27
|
|
data/lib/kobako/codec/factory.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Kobako
|
|
|
16
16
|
# § Ext Types).
|
|
17
17
|
#
|
|
18
18
|
# The factory is the single place in the host gem that touches the
|
|
19
|
-
# msgpack API — both
|
|
19
|
+
# msgpack API — both Encoder and Decoder delegate through it, so
|
|
20
20
|
# the three kobako ext codes (0x00 Symbol, 0x01 Capability Handle,
|
|
21
21
|
# 0x02 Exception envelope) are configured exactly once at first use.
|
|
22
22
|
#
|
|
@@ -93,11 +93,11 @@ module Kobako
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
# Validate the ext-0x00 payload as UTF-8 and intern. Raises
|
|
96
|
-
#
|
|
96
|
+
# InvalidEncoding on invalid bytes — SPEC forbids the
|
|
97
97
|
# binary-encoding fallback that msgpack-gem's default unpacker
|
|
98
98
|
# would otherwise apply. The re-tag step lives here because the
|
|
99
99
|
# msgpack ext-type unpacker hands us binary bytes; the assertion
|
|
100
|
-
# itself is shared with
|
|
100
|
+
# itself is shared with Decoder via Utils.assert_utf8!. The
|
|
101
101
|
# +"Symbol"+ label keeps the error message in Ruby vocabulary
|
|
102
102
|
# rather than wire-ext-code vocabulary.
|
|
103
103
|
def unpack_symbol(payload)
|
|
@@ -125,7 +125,7 @@ module Kobako
|
|
|
125
125
|
# Peel off the fixext-4 frame, hand the bytes to the
|
|
126
126
|
# Host-Gem-internal +Kobako::Handle.restore+ factory, and
|
|
127
127
|
# translate the +ArgumentError+ raised by Handle's invariants
|
|
128
|
-
# into a wire-layer +InvalidType+ via
|
|
128
|
+
# into a wire-layer +InvalidType+ via Codec::Utils.with_boundary.
|
|
129
129
|
# The Value Object owns the id-range contract; this method only
|
|
130
130
|
# owns the frame shape.
|
|
131
131
|
def unpack_handle(payload)
|
|
@@ -136,11 +136,11 @@ module Kobako
|
|
|
136
136
|
Codec::Utils.with_boundary { Kobako::Handle.restore(id) }
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
# Encode the inner ext-0x02 map via
|
|
139
|
+
# Encode the inner ext-0x02 map via Encoder (not +factory.dump+) so
|
|
140
140
|
# the embedded payload flows through the same boundary as a top-level
|
|
141
141
|
# encode — nested kobako values (Handle, nested Fault) reach the
|
|
142
142
|
# registered ext-type packers via the cached singleton. A +details+
|
|
143
|
-
# chain nested past
|
|
143
|
+
# chain nested past MAX_EXT_DEPTH has no wire representation and
|
|
144
144
|
# surfaces as +UnsupportedType+.
|
|
145
145
|
def pack_fault(fault)
|
|
146
146
|
within_ext_frame(UnsupportedType) do
|
|
@@ -149,12 +149,12 @@ module Kobako
|
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
# Peel the embedded msgpack map and hand it to +Kobako::Fault.new+
|
|
152
|
-
# inside
|
|
152
|
+
# inside Decoder.decode's block form, so the value-object's
|
|
153
153
|
# +ArgumentError+ invariants surface as +InvalidType+ through the
|
|
154
|
-
# decoder boundary. Inner decode goes through
|
|
154
|
+
# decoder boundary. Inner decode goes through Decoder (not
|
|
155
155
|
# +factory.load+) so the embedded +str+ payloads flow through the
|
|
156
156
|
# same UTF-8 validation as a top-level decode. A nested ext 0x02 in
|
|
157
|
-
# +details+ re-enters this method, so
|
|
157
|
+
# +details+ re-enters this method, so #within_ext_frame bounds the
|
|
158
158
|
# chain depth to keep it from exhausting the native stack.
|
|
159
159
|
def unpack_fault(payload)
|
|
160
160
|
within_ext_frame(InvalidType) do
|
|
@@ -167,7 +167,7 @@ module Kobako
|
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
# Track ext-envelope re-entry depth and refuse a chain past
|
|
170
|
-
#
|
|
170
|
+
# MAX_EXT_DEPTH, raising +over_limit+ so the failure lands in the
|
|
171
171
|
# caller's existing wire-error class. The counter is thread-scoped and
|
|
172
172
|
# balanced by the +ensure+, so a raise mid-chain still unwinds it to
|
|
173
173
|
# its entry value.
|
|
@@ -5,16 +5,16 @@ require_relative "../handle"
|
|
|
5
5
|
module Kobako
|
|
6
6
|
module Codec
|
|
7
7
|
# Substitutes Capability Handles into and out of a Ruby value tree at
|
|
8
|
-
# the host↔guest boundary.
|
|
8
|
+
# the host↔guest boundary. #deep_wrap allocates a +Kobako::Handle+ for
|
|
9
9
|
# each non-wire-representable leaf on the host→guest +#run+ argument
|
|
10
|
-
# path;
|
|
11
|
-
# host object on every guest→host value path.
|
|
12
|
-
# by-value codec-type predicate that decides which leaves
|
|
10
|
+
# path; #deep_restore resolves each wire-decoded Handle back to its
|
|
11
|
+
# host object on every guest→host value path. #representable? is the
|
|
12
|
+
# by-value codec-type predicate that decides which leaves #deep_wrap
|
|
13
13
|
# must wrap: the closed 12-entry wire type set
|
|
14
14
|
# ({docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type
|
|
15
15
|
# Mapping).
|
|
16
16
|
#
|
|
17
|
-
# All helpers are pure except
|
|
17
|
+
# All helpers are pure except #deep_wrap, whose only side effect is
|
|
18
18
|
# allocating new Handle ids into the supplied table.
|
|
19
19
|
module HandleWalk
|
|
20
20
|
module_function
|
|
@@ -24,7 +24,7 @@ module Kobako
|
|
|
24
24
|
# unsigned +uint 64+ maximum
|
|
25
25
|
# ({docs/wire-codec.md}[link:../../../docs/wire-codec.md] § Type
|
|
26
26
|
# Mapping #3, the +fixint+ / +int 8..64+ / +uint 8..64+ union).
|
|
27
|
-
# Anchored as a +Range+ so
|
|
27
|
+
# Anchored as a +Range+ so #primitive_type? stays a single
|
|
28
28
|
# dispatch line. This is the codec's encode domain — not to
|
|
29
29
|
# be confused with the Handle id range, which lives on
|
|
30
30
|
# +Kobako::Handle+ as +MIN_ID+ / +MAX_ID+ (1..2^31 − 1) and
|
|
@@ -41,13 +41,13 @@ module Kobako
|
|
|
41
41
|
# representable. Integers outside the codec's signed-64 /
|
|
42
42
|
# unsigned-64 union are rejected so the predicate agrees with the
|
|
43
43
|
# msgpack gem's encode-time +RangeError+ behaviour the codec
|
|
44
|
-
# already surfaces as
|
|
44
|
+
# already surfaces as UnsupportedType.
|
|
45
45
|
def representable?(value)
|
|
46
46
|
primitive_type?(value) || container_representable?(value)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Deep-walk Array / Hash containers in +value+ and replace every
|
|
50
|
-
# leaf that fails
|
|
50
|
+
# leaf that fails #representable? with a +Kobako::Handle+
|
|
51
51
|
# allocated from +handler+. The
|
|
52
52
|
# walk only descends through representable container shapes
|
|
53
53
|
# (Array, Hash) one structural level at a time; a non-representable
|
|
@@ -61,13 +61,9 @@ module Kobako
|
|
|
61
61
|
# whose leaves are either representable or +Kobako::Handle+
|
|
62
62
|
# tokens.
|
|
63
63
|
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
# inside a block would resolve against the enclosing +self+
|
|
68
|
-
# (still +HandleWalk+ at definition time, but the qualified form
|
|
69
|
-
# keeps the dispatch readable when the recursive call sits inside a
|
|
70
|
-
# Proc captured from elsewhere).
|
|
64
|
+
# Recursive calls spell the +HandleWalk.+ receiver so the dispatch
|
|
65
|
+
# stays valid even when a block is captured and run under a
|
|
66
|
+
# different +self+ (+module_function+ privatizes the instance copies).
|
|
71
67
|
def deep_wrap(value, handler)
|
|
72
68
|
case value
|
|
73
69
|
when ::Array then value.map { |element| HandleWalk.deep_wrap(element, handler) }
|
|
@@ -79,7 +75,7 @@ module Kobako
|
|
|
79
75
|
|
|
80
76
|
# Deep-walk Array / Hash containers in +value+ and replace every
|
|
81
77
|
# +Kobako::Handle+ leaf with the host-side object +handler+ resolves
|
|
82
|
-
# it to. The symmetric inverse of
|
|
78
|
+
# it to. The symmetric inverse of #deep_wrap: that walk allocates objects
|
|
83
79
|
# into Handles on the host→guest argument path; this walk resolves
|
|
84
80
|
# Handles back to their objects wherever a guest→host payload carries
|
|
85
81
|
# one — an invocation result, a yield-block result, or a dispatch
|
|
@@ -107,9 +103,9 @@ module Kobako
|
|
|
107
103
|
end
|
|
108
104
|
end
|
|
109
105
|
|
|
110
|
-
# The non-container branch of
|
|
106
|
+
# The non-container branch of #representable?: returns +true+ for
|
|
111
107
|
# the scalar leaves and an existing Handle. Not part of the
|
|
112
|
-
# public surface; reach for
|
|
108
|
+
# public surface; reach for #representable? instead.
|
|
113
109
|
def primitive_type?(value)
|
|
114
110
|
case value
|
|
115
111
|
when ::NilClass, ::TrueClass, ::FalseClass, ::Float, ::String, ::Symbol, Kobako::Handle then true
|
|
@@ -118,10 +114,10 @@ module Kobako
|
|
|
118
114
|
end
|
|
119
115
|
end
|
|
120
116
|
|
|
121
|
-
# The container branch of
|
|
117
|
+
# The container branch of #representable?: recurses into Array
|
|
122
118
|
# elements and Hash key+value pairs through the public
|
|
123
|
-
#
|
|
124
|
-
#
|
|
119
|
+
# #representable?. Not part of the public surface; reach for
|
|
120
|
+
# #representable? instead.
|
|
125
121
|
def container_representable?(value)
|
|
126
122
|
case value
|
|
127
123
|
when ::Array then value.all? { |element| HandleWalk.representable?(element) }
|
data/lib/kobako/codec/utils.rb
CHANGED
|
@@ -10,18 +10,18 @@ module Kobako
|
|
|
10
10
|
# - UTF-8 assertion at the codec boundary
|
|
11
11
|
# ({docs/wire-codec.md}[link:../../../docs/wire-codec.md]
|
|
12
12
|
# § str/bin Encoding Rules and § Ext Types → ext 0x00). Used by
|
|
13
|
-
#
|
|
13
|
+
# Decoder when walking +str+ family payloads and by Factory
|
|
14
14
|
# when validating the +ext 0x00+ Symbol payload.
|
|
15
15
|
# - +ArgumentError+ translation at the codec boundary
|
|
16
|
-
# (
|
|
17
|
-
#
|
|
16
|
+
# (#with_boundary) so the public taxonomy stays
|
|
17
|
+
# Kobako::Codec::Error.
|
|
18
18
|
#
|
|
19
19
|
# Both helpers are pure — they only inspect inputs, never mutate them.
|
|
20
|
-
# The host↔guest Handle substitution walk lives in
|
|
20
|
+
# The host↔guest Handle substitution walk lives in HandleWalk.
|
|
21
21
|
module Utils
|
|
22
22
|
module_function
|
|
23
23
|
|
|
24
|
-
# Raise
|
|
24
|
+
# Raise InvalidEncoding unless +string+'s bytes are valid under
|
|
25
25
|
# its current encoding tag. +label+ is the caller-supplied prefix
|
|
26
26
|
# for the error message (e.g. +"str payload"+, +"Symbol payload"+).
|
|
27
27
|
def assert_utf8!(string, label)
|
|
@@ -32,13 +32,13 @@ module Kobako
|
|
|
32
32
|
|
|
33
33
|
# Run +block+ at the codec boundary: a value object raises
|
|
34
34
|
# +ArgumentError+ when an invariant is violated at construction, and
|
|
35
|
-
# this helper surfaces that as
|
|
36
|
-
# stays
|
|
35
|
+
# this helper surfaces that as InvalidType so the public taxonomy
|
|
36
|
+
# stays Kobako::Codec::Error and never leaks +ArgumentError+ from
|
|
37
37
|
# the Ruby standard library.
|
|
38
38
|
#
|
|
39
39
|
# Reach for this only where a value object is constructed outside a
|
|
40
|
-
#
|
|
41
|
-
# mapping (worked example:
|
|
40
|
+
# Decoder.decode block, whose rescue already performs the same
|
|
41
|
+
# mapping (worked example: Factory#unpack_handle building
|
|
42
42
|
# +Handle.restore+ from a raw fixext payload). Do not use it for
|
|
43
43
|
# general-purpose validation outside the codec boundary —
|
|
44
44
|
# host-layer +ArgumentError+ values should propagate unchanged.
|
data/lib/kobako/codec.rb
CHANGED
|
@@ -18,12 +18,12 @@ module Kobako
|
|
|
18
18
|
# the kobako root so the codec can register them without depending
|
|
19
19
|
# upward on Transport.
|
|
20
20
|
#
|
|
21
|
-
# Backed by the official +msgpack+ gem via
|
|
22
|
-
#
|
|
21
|
+
# Backed by the official +msgpack+ gem via Factory; Encoder and
|
|
22
|
+
# Decoder are thin wrappers that register the three kobako-specific
|
|
23
23
|
# ext types (0x00 Symbol, 0x01 Capability Handle, 0x02 Exception
|
|
24
24
|
# envelope) on a single +MessagePack::Factory+ instance. The Rust side
|
|
25
25
|
# mirrors this layer as the +codec+ module in the +kobako-codec+ crate;
|
|
26
|
-
# the ext-code constants live as module-private values on
|
|
26
|
+
# the ext-code constants live as module-private values on Factory
|
|
27
27
|
# alongside +codec::EXT_SYMBOL+ / +codec::EXT_HANDLE+ /
|
|
28
28
|
# +codec::EXT_ERRENV+ on that side.
|
|
29
29
|
module Codec
|
data/lib/kobako/errors.rb
CHANGED
|
@@ -4,38 +4,13 @@
|
|
|
4
4
|
module Kobako
|
|
5
5
|
# Error taxonomy.
|
|
6
6
|
#
|
|
7
|
-
# Every
|
|
8
|
-
# exactly one of
|
|
9
|
-
# guest binary returns control to the
|
|
10
|
-
# the outcome-envelope tag.
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# * {TrapError} — Wasm engine layer (trap, OOM, unreachable, or a
|
|
15
|
-
# wire-violation fallback signalling a corrupted
|
|
16
|
-
# guest runtime).
|
|
17
|
-
# * {SandboxError} — sandbox / wire layer (mruby script error,
|
|
18
|
-
# wire-decode failure on an otherwise valid tag,
|
|
19
|
-
# Catalog::Handles exhaustion, output buffer overrun).
|
|
20
|
-
# * {ServiceError} — service / capability layer (a Service capability
|
|
21
|
-
# call that failed and was not rescued inside the
|
|
22
|
-
# script).
|
|
23
|
-
#
|
|
24
|
-
# Two further branches sit outside the invocation taxonomy:
|
|
25
|
-
#
|
|
26
|
-
# * {SetupError} — construction layer. Raised by `Kobako::Sandbox.new`
|
|
27
|
-
# when the wasm runtime cannot be built from the
|
|
28
|
-
# configured +wasm_path+ before any invocation runs.
|
|
29
|
-
# Not an invocation outcome, so it never passes
|
|
30
|
-
# through the two-step attribution decision.
|
|
31
|
-
# * {PoolTimeoutError} — pool checkout layer. Raised by `Kobako::Pool#with`
|
|
32
|
-
# when the checkout wait exceeds +checkout_timeout+.
|
|
33
|
-
#
|
|
34
|
-
# Named subclasses:
|
|
35
|
-
#
|
|
36
|
-
# * {ModuleNotBuiltError} < {SetupError} — Guest Binary artifact absent
|
|
37
|
-
# at +wasm_path+.
|
|
38
|
-
# * {HandleExhaustedError} < {SandboxError} — Handle id cap hit.
|
|
7
|
+
# Every +Kobako::Sandbox+ invocation (+#eval+ or +#run+) either returns a
|
|
8
|
+
# value or raises exactly one of TrapError, SandboxError, or ServiceError.
|
|
9
|
+
# Attribution is decided after the guest binary returns control to the
|
|
10
|
+
# host: first the Wasm-trap layer, then the outcome-envelope tag.
|
|
11
|
+
# SetupError and PoolTimeoutError sit outside the invocation taxonomy and
|
|
12
|
+
# never pass through that attribution decision. Each class below
|
|
13
|
+
# documents its own layer.
|
|
39
14
|
|
|
40
15
|
# Base for all kobako-raised errors so callers that want to ignore the
|
|
41
16
|
# taxonomy can rescue a single class.
|
|
@@ -48,8 +23,8 @@ module Kobako
|
|
|
48
23
|
#
|
|
49
24
|
# Two named subclasses cover the configured per-invocation caps:
|
|
50
25
|
#
|
|
51
|
-
# *
|
|
52
|
-
# *
|
|
26
|
+
# * TimeoutError — wall-clock +timeout+ exceeded.
|
|
27
|
+
# * MemoryLimitError — guest +memory.grow+ would exceed
|
|
53
28
|
# +memory_limit+.
|
|
54
29
|
#
|
|
55
30
|
# Host Apps that only care about "guest is unrecoverable, discard the
|
|
@@ -128,14 +103,14 @@ module Kobako
|
|
|
128
103
|
class HandleExhaustedError < SandboxError; end
|
|
129
104
|
|
|
130
105
|
# BytecodeError is the SandboxError subclass raised when a
|
|
131
|
-
#
|
|
132
|
-
# first invocation's snippet replay against a fresh
|
|
106
|
+
# +#preload(binary:)+ snippet fails structural validation during the
|
|
107
|
+
# first invocation's snippet replay against a fresh +mrb_state+ (RITE
|
|
133
108
|
# version mismatch or corrupt body). Bytecode that loads cleanly and
|
|
134
|
-
# then raises at top level surfaces as plain
|
|
109
|
+
# then raises at top level surfaces as plain +SandboxError+ with the
|
|
135
110
|
# natural mruby class preserved. Inherits from SandboxError so a single
|
|
136
|
-
#
|
|
111
|
+
# +rescue Kobako::SandboxError+ covers both source and bytecode
|
|
137
112
|
# snippet failures while callers wanting bytecode-specific handling
|
|
138
|
-
# can
|
|
113
|
+
# can +rescue Kobako::BytecodeError+ directly.
|
|
139
114
|
class BytecodeError < SandboxError; end
|
|
140
115
|
|
|
141
116
|
# Pool checkout layer. Raised by +Kobako::Pool#with+ when the checkout
|
data/lib/kobako/handle.rb
CHANGED
|
@@ -14,8 +14,10 @@ module Kobako
|
|
|
14
14
|
# The constructor is internal to the Host Gem. +Kobako::Handle.new+ is
|
|
15
15
|
# privatised so Host App code cannot fabricate a Handle from a bare
|
|
16
16
|
# integer; legitimate Handle instances enter Host App code only as
|
|
17
|
-
# fields on raised error objects.
|
|
18
|
-
#
|
|
17
|
+
# fields on raised error objects. +#with+ — Data's copy-with-changes
|
|
18
|
+
# constructor — is removed for the same reason: a legitimate Handle
|
|
19
|
+
# must not derive a sibling with a caller-chosen id. The Host Gem itself constructs
|
|
20
|
+
# Handles through +.restore+, which exists at exactly two call
|
|
19
21
|
# sites: +Kobako::Codec::Factory#unpack_handle+ (wire decode) and
|
|
20
22
|
# +Kobako::Codec::HandleWalk.deep_wrap+ / +Kobako::Transport::Dispatcher#wrap_as_handle+
|
|
21
23
|
# (allocator paths). Both live inside +lib/kobako/+ and are not part
|
|
@@ -41,6 +43,7 @@ module Kobako
|
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
private_class_method :new
|
|
46
|
+
undef_method :with
|
|
44
47
|
|
|
45
48
|
# Host Gem–internal factory. Allocates the Data instance through
|
|
46
49
|
# +Class#allocate+ and dispatches +#initialize+ explicitly so the
|
data/lib/kobako/namespace.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Kobako
|
|
4
4
|
# A named grouping of Members for one Sandbox.
|
|
5
5
|
# Returned by +Sandbox#define+. Each instance owns a flat name→object
|
|
6
|
-
# table of Members; member binding is validated against
|
|
6
|
+
# table of Members; member binding is validated against NAME_PATTERN.
|
|
7
7
|
class Namespace
|
|
8
8
|
# Ruby constant-name pattern shared by Namespace and Member names.
|
|
9
9
|
NAME_PATTERN = /\A[A-Z]\w*\z/
|
|
@@ -11,7 +11,7 @@ module Kobako
|
|
|
11
11
|
attr_reader :name
|
|
12
12
|
|
|
13
13
|
# Build a new Namespace. +name+ is an already-validated Namespace
|
|
14
|
-
# name (must satisfy
|
|
14
|
+
# name (must satisfy NAME_PATTERN; validation is the caller's
|
|
15
15
|
# responsibility).
|
|
16
16
|
def initialize(name)
|
|
17
17
|
@name = name
|
|
@@ -38,7 +38,7 @@ module Kobako
|
|
|
38
38
|
|
|
39
39
|
# Mark this Namespace as sealed. Called by
|
|
40
40
|
# +Kobako::Catalog::Namespaces#seal!+ on the owning Sandbox's first
|
|
41
|
-
# invocation; afterwards
|
|
41
|
+
# invocation; afterwards #bind raises +ArgumentError+. Idempotent;
|
|
42
42
|
# returns +self+.
|
|
43
43
|
def seal!
|
|
44
44
|
@sealed = true
|
data/lib/kobako/outcome.rb
CHANGED
data/lib/kobako/sandbox.rb
CHANGED
|
@@ -120,7 +120,9 @@ module Kobako
|
|
|
120
120
|
# Register a snippet on this Sandbox in one of two forms:
|
|
121
121
|
#
|
|
122
122
|
# * +preload(code: source, name: Name)+ — +source+ is mruby source
|
|
123
|
-
# as a +String+ and +Name+ matches +/\A[A-Z]\w*\z/+.
|
|
123
|
+
# as a +String+ and +Name+ matches +/\A[A-Z]\w*\z/+. Compile
|
|
124
|
+
# failures surface as +Kobako::SandboxError+ on the first
|
|
125
|
+
# invocation's replay. The +name+
|
|
124
126
|
# becomes the snippet's +(snippet:Name)+ backtrace filename and
|
|
125
127
|
# is the dedupe key that rejects a duplicate +code:+ snippet.
|
|
126
128
|
# * +preload(binary: bytes)+ — +bytes+ is precompiled RITE
|
|
@@ -216,7 +218,7 @@ module Kobako
|
|
|
216
218
|
# runtime that cannot honor the request never runs guest code.
|
|
217
219
|
def build_runtime!
|
|
218
220
|
runtime = Kobako::Runtime.from_path(@wasm_path, @options.timeout, @options.memory_limit,
|
|
219
|
-
@options.stdout_limit, @options.stderr_limit, profile)
|
|
221
|
+
@options.stdout_limit, @options.stderr_limit, @options.profile)
|
|
220
222
|
@options.enforce_floor!(runtime.profile)
|
|
221
223
|
runtime
|
|
222
224
|
end
|
|
@@ -257,10 +259,8 @@ module Kobako
|
|
|
257
259
|
# the readout here also covers the trap path, where +Runtime#eval+ /
|
|
258
260
|
# +#run+ raise instead of returning outcome bytes.
|
|
259
261
|
#
|
|
260
|
-
# The ext
|
|
261
|
-
#
|
|
262
|
-
# destructure-then-kwargs handoff below is the explicit
|
|
263
|
-
# positional→keyword conversion point.
|
|
262
|
+
# The ext-side contract is positional: +Runtime#usage+ yields
|
|
263
|
+
# +[wall_time, memory_peak]+ in +Kobako::Usage+ field order.
|
|
264
264
|
def read_usage!
|
|
265
265
|
wall_time, memory_peak = @runtime.usage
|
|
266
266
|
@usage = Usage.new(wall_time: wall_time, memory_peak: memory_peak)
|
|
@@ -283,16 +283,14 @@ module Kobako
|
|
|
283
283
|
|
|
284
284
|
# Read the per-last-invocation output captures from the ext and wrap
|
|
285
285
|
# them as +Kobako::Capture+ value objects. Runs in the +invoke!+
|
|
286
|
-
# +ensure+ block next to
|
|
286
|
+
# +ensure+ block next to #read_usage! for the same reason: the ext
|
|
287
287
|
# stashes the captures on every outcome, so the readout also covers
|
|
288
288
|
# the trap path, where +Runtime#eval+ / +#run+ raise instead of
|
|
289
289
|
# returning outcome bytes — +#stdout+ / +#stderr+ keep the guest's
|
|
290
290
|
# partial output readable after a rescue.
|
|
291
291
|
#
|
|
292
|
-
# The ext
|
|
293
|
-
# +[stdout_bytes, stdout_truncated, stderr_bytes, stderr_truncated]
|
|
294
|
-
# the destructure-then-kwargs handoff below is the explicit
|
|
295
|
-
# positional→keyword conversion point.
|
|
292
|
+
# The ext-side contract is positional: +Runtime#captures+ yields
|
|
293
|
+
# +[stdout_bytes, stdout_truncated, stderr_bytes, stderr_truncated]+.
|
|
296
294
|
def read_captures!
|
|
297
295
|
stdout_bytes, stdout_truncated, stderr_bytes, stderr_truncated = @runtime.captures
|
|
298
296
|
@stdout_capture = Capture.new(bytes: stdout_bytes, truncated: stdout_truncated)
|
|
@@ -306,7 +304,7 @@ module Kobako
|
|
|
306
304
|
# The yielded block must return the invocation's raw outcome bytes —
|
|
307
305
|
# i.e. the value of +Runtime#eval+ / +#run+ — which the success path
|
|
308
306
|
# feeds to +Outcome.decode+. Captures and usage are populated by the
|
|
309
|
-
# +ensure+ readouts (
|
|
307
|
+
# +ensure+ readouts (#read_usage! / #read_captures!) on every
|
|
310
308
|
# outcome, so +#stdout+ / +#stderr+ / +#usage+ stay readable after a
|
|
311
309
|
# rescued trap.
|
|
312
310
|
# The rescue chain is the single trap-translation boundary —
|
|
@@ -27,7 +27,7 @@ module Kobako
|
|
|
27
27
|
# Kobako::Transport::Dispatcher.dispatch(request_bytes, namespaces, handler, yield_to_guest)
|
|
28
28
|
# # => msgpack-encoded Response bytes (never raises)
|
|
29
29
|
module Dispatcher
|
|
30
|
-
# Throw tag for the
|
|
30
|
+
# Throw tag for the Yielder's break unwind back to the
|
|
31
31
|
# dispatcher's +catch+ frame. +private_constant+ is a
|
|
32
32
|
# convention boundary — not a defence.
|
|
33
33
|
BREAK_THROW = :__kobako_break__
|
|
@@ -54,12 +54,12 @@ module Kobako
|
|
|
54
54
|
# Callable gadget types whose own public methods are reflection surface
|
|
55
55
|
# (+Proc#binding+ reaches +Binding#eval+, +Method#receiver+ / +#unbind+
|
|
56
56
|
# hand back the underlying object) rather than Service behaviour. Only
|
|
57
|
-
#
|
|
57
|
+
# CALLABLE_ALLOW is reachable on a target of these types; a bound
|
|
58
58
|
# lambda stays invocable, its reflective surface does not.
|
|
59
59
|
GADGET_OWNERS = [Proc, Method, UnboundMethod, Binding].freeze
|
|
60
60
|
private_constant :GADGET_OWNERS
|
|
61
61
|
|
|
62
|
-
# The sole methods reachable on a
|
|
62
|
+
# The sole methods reachable on a GADGET_OWNERS target: invoking it
|
|
63
63
|
# (+call+ / +[]+ / +yield+) and the harmless +arity+ / +lambda?+
|
|
64
64
|
# describers that aid guest-side debugging.
|
|
65
65
|
CALLABLE_ALLOW = %i[call [] yield arity lambda?].freeze
|
|
@@ -91,7 +91,7 @@ module Kobako
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Resolve positional and keyword arguments off +request+ in one
|
|
94
|
-
# step. Both pass through
|
|
94
|
+
# step. Both pass through #resolve_arg so Capability Handles
|
|
95
95
|
# round-trip back to the host-side Ruby object before the call
|
|
96
96
|
# reaches +public_send+.
|
|
97
97
|
def resolve_call_args(request, handler)
|
|
@@ -101,7 +101,7 @@ module Kobako
|
|
|
101
101
|
|
|
102
102
|
# Map an error caught at the dispatch boundary to a +Response.error+
|
|
103
103
|
# envelope (binary msgpack). +error+ is the +StandardError+ caught by
|
|
104
|
-
#
|
|
104
|
+
# #dispatch's rescue; the +type+ field tells the guest which kind
|
|
105
105
|
# of failure it was so it can raise the matching proxy-side error.
|
|
106
106
|
def encode_caught_error(error)
|
|
107
107
|
case error
|
|
@@ -119,8 +119,8 @@ module Kobako
|
|
|
119
119
|
# reject calls to no-kwarg methods when the wire carries the
|
|
120
120
|
# uniform empty-map shape.
|
|
121
121
|
#
|
|
122
|
-
# +yielder+ is the host-side
|
|
123
|
-
# call site supplied a block; its
|
|
122
|
+
# +yielder+ is the host-side Yielder materialised when the guest
|
|
123
|
+
# call site supplied a block; its Yielder#to_proc
|
|
124
124
|
# rides the +&block+ slot. +&nil+ is a no-op block argument in Ruby,
|
|
125
125
|
# so the same call site handles both cases without an explicit
|
|
126
126
|
# conditional.
|
|
@@ -137,8 +137,8 @@ module Kobako
|
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
# Guard the +public_send+ below against ambient reflection methods.
|
|
140
|
-
# A public method whose owner is a
|
|
141
|
-
# rejected, except
|
|
140
|
+
# A public method whose owner is a META_OWNERS or GADGET_OWNERS module is
|
|
141
|
+
# rejected, except CALLABLE_ALLOW on a gadget target (a bound lambda
|
|
142
142
|
# stays invocable). A name with no concrete public method is allowed
|
|
143
143
|
# only when the target opts into it via +respond_to?+ (dynamic
|
|
144
144
|
# +method_missing+ Services), since the dangerous methods are all
|
|
@@ -159,7 +159,7 @@ module Kobako
|
|
|
159
159
|
# Consult the target's opt-in narrowing predicate. A bound object
|
|
160
160
|
# may define a private +respond_to_guest?(name)+ to restrict which of its
|
|
161
161
|
# methods the guest reaches; a falsy answer rejects the dispatch.
|
|
162
|
-
# The predicate composes beneath
|
|
162
|
+
# The predicate composes beneath #reject_meta_method! — it only narrows,
|
|
163
163
|
# never re-opening the reflection surface the floor rejects — and is
|
|
164
164
|
# consulted with the private surface included so the guest's +public_send+
|
|
165
165
|
# dispatch can never reach +respond_to_guest?+ itself.
|
|
@@ -213,7 +213,7 @@ module Kobako
|
|
|
213
213
|
# Encode +value+ as a +Response.ok+ envelope. When the value is not
|
|
214
214
|
# wire-representable per the codec's type mapping, the
|
|
215
215
|
# +UnsupportedType+ rescue routes it through the
|
|
216
|
-
# Catalog::Handles via
|
|
216
|
+
# Catalog::Handles via #wrap_as_handle and re-encodes with the Capability
|
|
217
217
|
# Handle in place. The happy path encodes exactly once.
|
|
218
218
|
def encode_ok(value, handler)
|
|
219
219
|
response = Kobako::Transport::Response.ok(value)
|
|
@@ -224,15 +224,18 @@ module Kobako
|
|
|
224
224
|
|
|
225
225
|
# Allocate +value+ in the Sandbox's Catalog::Handles and return a +Handle+
|
|
226
226
|
# that the wire codec can carry. Used as the fallback path of
|
|
227
|
-
#
|
|
227
|
+
# #encode_ok when +value+ has no wire representation.
|
|
228
228
|
def wrap_as_handle(value, handler)
|
|
229
229
|
handler.alloc(value)
|
|
230
230
|
end
|
|
231
231
|
|
|
232
|
+
# +message+ folds to UTF-8 first: Ruby core builds some exception
|
|
233
|
+
# messages as ASCII-8BIT (the arity ArgumentError, for one), and
|
|
234
|
+
# the codec would ride those as bin — a shape the guest refuses.
|
|
232
235
|
def encode_error(type, message)
|
|
236
|
+
message = message.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
|
233
237
|
fault = Kobako::Fault.new(type: type, message: message)
|
|
234
|
-
|
|
235
|
-
response.encode
|
|
238
|
+
Kobako::Transport::Response.error(fault).encode
|
|
236
239
|
end
|
|
237
240
|
end
|
|
238
241
|
end
|
|
@@ -13,7 +13,7 @@ module Kobako
|
|
|
13
13
|
# 5-element msgpack array:
|
|
14
14
|
# +[target, method_name, args, kwargs, block_given]+. +target+ is
|
|
15
15
|
# either a +String+ (+"<Namespace>::<Member>"+, e.g. +"MyService::KV"+)
|
|
16
|
-
# or a
|
|
16
|
+
# or a Handle. SPEC pins +kwargs+ map keys to ext 0x00 Symbol;
|
|
17
17
|
# enforced at construction so the Value Object is the single source of
|
|
18
18
|
# truth. +block_given+ is a Boolean signalling whether the guest call
|
|
19
19
|
# site supplied a block; the block body itself never crosses the
|
|
@@ -43,7 +43,7 @@ module Kobako
|
|
|
43
43
|
Codec::Encoder.encode([target, method_name, args, kwargs, block_given])
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
# Decode +bytes+ into a
|
|
46
|
+
# Decode +bytes+ into a Request. Raises +Codec::InvalidType+ when the
|
|
47
47
|
# envelope is not the expected 5-element msgpack array, or when the
|
|
48
48
|
# Value Object's construction invariants reject the decoded fields.
|
|
49
49
|
def self.decode(bytes)
|
|
@@ -20,7 +20,7 @@ module Kobako
|
|
|
20
20
|
#
|
|
21
21
|
# 2-element msgpack array: +[status, value-or-fault]+. +status+ is 0
|
|
22
22
|
# (success) or 1 (fault). For success the second element is the return
|
|
23
|
-
# value; for fault it is a
|
|
23
|
+
# value; for fault it is a Fault (ext 0x02 envelope).
|
|
24
24
|
#
|
|
25
25
|
# Built on the +class X < Data.define(...)+ subclass form so the
|
|
26
26
|
# class body is fully Steep-visible; see +lib/kobako/outcome/panic.rb+
|
|
@@ -58,7 +58,7 @@ module Kobako
|
|
|
58
58
|
Codec::Encoder.encode([status, payload])
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
# Decode +bytes+ into a
|
|
61
|
+
# Decode +bytes+ into a Response. Raises +Codec::InvalidType+ when the
|
|
62
62
|
# envelope is not the expected 2-element msgpack array, or when the
|
|
63
63
|
# Value Object's construction invariants reject the decoded fields.
|
|
64
64
|
def self.decode(bytes)
|
data/lib/kobako/transport/run.rb
CHANGED
|
@@ -51,7 +51,7 @@ module Kobako
|
|
|
51
51
|
# Encode this Run to the msgpack bytes the guest's +__kobako_run+
|
|
52
52
|
# entry point consumes as its command-buffer payload
|
|
53
53
|
# ({docs/wire-codec.md Invocation channels}[link:../../../docs/wire-codec.md]).
|
|
54
|
-
# Walks +args+ / +kwargs+ through
|
|
54
|
+
# Walks +args+ / +kwargs+ through Codec::HandleWalk.deep_wrap so
|
|
55
55
|
# any non-wire-representable leaf is allocated into +handler+ and
|
|
56
56
|
# replaced with a +Kobako::Handle+; the
|
|
57
57
|
# +handler+ argument is the Sandbox's table, sharing the same
|
|
@@ -10,9 +10,9 @@ module Kobako
|
|
|
10
10
|
# First byte of the YieldResponse for the success branch — body is
|
|
11
11
|
# the block's return value encoded as a single msgpack value.
|
|
12
12
|
TAG_OK = 0x01
|
|
13
|
-
# First byte for
|
|
13
|
+
# First byte for +break val+ — body is the break value.
|
|
14
14
|
TAG_BREAK = 0x02
|
|
15
|
-
# Reserved for future
|
|
15
|
+
# Reserved for future +return val+ support; both sides reject this
|
|
16
16
|
# tag as a wire violation (YieldResponse envelope contract).
|
|
17
17
|
TAG_RESERVED = 0x03
|
|
18
18
|
# First byte for an error / fault outcome — body is a
|
|
@@ -58,7 +58,7 @@ module Kobako
|
|
|
58
58
|
[tag].pack("C") + Codec::Encoder.encode(value)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
# Decode +bytes+ into a
|
|
61
|
+
# Decode +bytes+ into a Yield. Rejects empty input, the reserved
|
|
62
62
|
# tag 0x03, and any tag outside +LIVE_TAGS+ by raising
|
|
63
63
|
# +Kobako::Codec::InvalidType+ — these are wire violations per the
|
|
64
64
|
# SPEC's YieldResponse envelope contract.
|
|
@@ -13,7 +13,7 @@ module Kobako
|
|
|
13
13
|
# Each guest call that carries +block_given: true+ gets a Yielder
|
|
14
14
|
# that the Dispatcher hands to the Service method as +&block+. The
|
|
15
15
|
# Service method observes it as an ordinary Ruby Proc through
|
|
16
|
-
#
|
|
16
|
+
# #to_proc; +yield val+ / +block.call(val)+ invokes #yield, which
|
|
17
17
|
# serialises the positional args, re-enters the guest via the injected
|
|
18
18
|
# +yield_to_guest+ lambda, and reifies the +YieldResponse+ into Ruby
|
|
19
19
|
# control flow:
|
|
@@ -24,13 +24,13 @@ module Kobako
|
|
|
24
24
|
# * +tag 0x04+ error — raise the +{class, message}+ payload at the
|
|
25
25
|
# Service's yield site
|
|
26
26
|
#
|
|
27
|
-
# The Dispatcher calls
|
|
27
|
+
# The Dispatcher calls #invalidate! from its +ensure+ block once
|
|
28
28
|
# dispatch completes; any later call to a stashed Yielder then raises
|
|
29
29
|
# +LocalJumpError+ — the observable shape of an escaped Yielder.
|
|
30
30
|
class Yielder
|
|
31
31
|
# +yield_to_guest+ is a +String → String+ callable (the ext's
|
|
32
32
|
# per-dispatch +Kobako::Runtime::GuestYielder+) that
|
|
33
|
-
#
|
|
33
|
+
# #yield invokes to re-enter the guest; +break_tag+ is the +catch+
|
|
34
34
|
# throw tag the Dispatcher matches against to unwind the Service on
|
|
35
35
|
# +tag 0x02+. +handler+ is the Sandbox's +Kobako::Catalog::Handles+,
|
|
36
36
|
# used to restore a Capability Handle in the block's ok value back to
|
|
@@ -44,7 +44,7 @@ module Kobako
|
|
|
44
44
|
|
|
45
45
|
# Re-enter the guest with +args+ and reify the YieldResponse into
|
|
46
46
|
# Ruby control flow. Raises +LocalJumpError+ if called after
|
|
47
|
-
#
|
|
47
|
+
# #invalidate!. The ok value is consumed by the host Service
|
|
48
48
|
# method, so a Capability Handle in it is restored to its host object.
|
|
49
49
|
# The break value unwinds past the Service back to the guest
|
|
50
50
|
# Member call, so it passes through verbatim — a Handle stays a
|
|
@@ -60,14 +60,14 @@ module Kobako
|
|
|
60
60
|
raise yield_failure(response.value, default: "yield error")
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
# The Proc the Dispatcher passes as +&block+, binding
|
|
63
|
+
# The Proc the Dispatcher passes as +&block+, binding #yield so a
|
|
64
64
|
# Service method's +yield+ / +block.call+ drives the round-trip.
|
|
65
65
|
def to_proc
|
|
66
66
|
method(:yield).to_proc
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
# Mark this Yielder dead. Called by the Dispatcher's +ensure+ block
|
|
70
|
-
# when the originating dispatch frame returns; any later
|
|
70
|
+
# when the originating dispatch frame returns; any later #yield
|
|
71
71
|
# call then raises +LocalJumpError+.
|
|
72
72
|
def invalidate!
|
|
73
73
|
@active = false
|
data/lib/kobako/version.rb
CHANGED
data/release-please-config.json
CHANGED
|
@@ -29,28 +29,28 @@
|
|
|
29
29
|
}
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
|
-
"wasm/kobako": {
|
|
33
|
-
"component": "kobako-
|
|
32
|
+
"wasm/kobako-mruby": {
|
|
33
|
+
"component": "kobako-mruby",
|
|
34
34
|
"release-type": "rust",
|
|
35
35
|
"extra-files": [
|
|
36
36
|
{
|
|
37
37
|
"type": "toml",
|
|
38
38
|
"path": "/wasm/Cargo.lock",
|
|
39
|
-
"jsonpath": "$.package[?(@.name=='kobako')].version"
|
|
39
|
+
"jsonpath": "$.package[?(@.name=='kobako-mruby')].version"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"type": "toml",
|
|
43
|
-
"path": "/wasm/kobako/Cargo.toml",
|
|
43
|
+
"path": "/wasm/kobako-mruby/Cargo.toml",
|
|
44
44
|
"jsonpath": "$.dependencies['kobako-core'].version"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"type": "toml",
|
|
48
|
-
"path": "/wasm/kobako/Cargo.toml",
|
|
48
|
+
"path": "/wasm/kobako-mruby/Cargo.toml",
|
|
49
49
|
"jsonpath": "$.dependencies['kobako-codec'].version"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"type": "generic",
|
|
53
|
-
"path": "/wasm/kobako/README.md"
|
|
53
|
+
"path": "/wasm/kobako-mruby/README.md"
|
|
54
54
|
}
|
|
55
55
|
]
|
|
56
56
|
},
|
|
@@ -178,13 +178,43 @@
|
|
|
178
178
|
"path": "/crates/kobako-wasmtime/README.md"
|
|
179
179
|
}
|
|
180
180
|
]
|
|
181
|
+
},
|
|
182
|
+
"crates/kobako": {
|
|
183
|
+
"component": "kobako-sdk",
|
|
184
|
+
"release-type": "rust",
|
|
185
|
+
"extra-files": [
|
|
186
|
+
{
|
|
187
|
+
"type": "toml",
|
|
188
|
+
"path": "/crates/Cargo.lock",
|
|
189
|
+
"jsonpath": "$.package[?(@.name=='kobako')].version"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"type": "toml",
|
|
193
|
+
"path": "/crates/kobako/Cargo.toml",
|
|
194
|
+
"jsonpath": "$.dependencies['kobako-codec'].version"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "toml",
|
|
198
|
+
"path": "/crates/kobako/Cargo.toml",
|
|
199
|
+
"jsonpath": "$.dependencies['kobako-runtime'].version"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"type": "toml",
|
|
203
|
+
"path": "/crates/kobako/Cargo.toml",
|
|
204
|
+
"jsonpath": "$.dependencies['kobako-wasmtime'].version"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"type": "generic",
|
|
208
|
+
"path": "/crates/kobako/README.md"
|
|
209
|
+
}
|
|
210
|
+
]
|
|
181
211
|
}
|
|
182
212
|
},
|
|
183
213
|
"plugins": [
|
|
184
214
|
{
|
|
185
215
|
"type": "linked-versions",
|
|
186
216
|
"groupName": "kobako crates",
|
|
187
|
-
"components": ["kobako-codec", "kobako-core", "kobako-
|
|
217
|
+
"components": ["kobako-codec", "kobako-core", "kobako-mruby", "kobako-io", "kobako-json", "kobako-regexp", "kobako-baker", "kobako-runtime", "kobako-wasmtime", "kobako-sdk"]
|
|
188
218
|
}
|
|
189
219
|
],
|
|
190
220
|
"extra-files": [
|
|
@@ -5,9 +5,9 @@ module Kobako
|
|
|
5
5
|
|
|
6
6
|
def self?.representable?: (untyped value) -> bool
|
|
7
7
|
|
|
8
|
-
def self?.deep_wrap: (untyped value, Kobako::
|
|
8
|
+
def self?.deep_wrap: (untyped value, Kobako::Codec::_HandleTable handler) -> untyped
|
|
9
9
|
|
|
10
|
-
def self?.deep_restore: (untyped value, Kobako::
|
|
10
|
+
def self?.deep_restore: (untyped value, Kobako::Codec::_HandleTable handler) -> untyped
|
|
11
11
|
|
|
12
12
|
def self?.primitive_type?: (untyped value) -> bool
|
|
13
13
|
|
data/sig/kobako/codec.rbs
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
module Kobako
|
|
2
2
|
module Codec
|
|
3
|
+
# The Handle allocator/resolver a wire walk works against: alloc
|
|
4
|
+
# registers a non-wire-representable object and returns its Handle,
|
|
5
|
+
# fetch resolves a wire Handle id back to the live object. The
|
|
6
|
+
# Sandbox's Kobako::Catalog::Handles is the production conformer;
|
|
7
|
+
# modelled structurally so the Codec and Transport tiers need no
|
|
8
|
+
# upward dependency on Catalog.
|
|
9
|
+
interface _HandleTable
|
|
10
|
+
def alloc: (untyped object) -> Kobako::Handle
|
|
11
|
+
|
|
12
|
+
def fetch: (Integer id) -> untyped
|
|
13
|
+
end
|
|
3
14
|
end
|
|
4
15
|
end
|
data/sig/kobako/handle.rbs
CHANGED
|
@@ -12,9 +12,9 @@ module Kobako
|
|
|
12
12
|
|
|
13
13
|
CALLABLE_ALLOW: Array[Symbol]
|
|
14
14
|
|
|
15
|
-
def self?.dispatch: (String request_bytes, Kobako::
|
|
15
|
+
def self?.dispatch: (String request_bytes, Kobako::Transport::_NamespaceRegistry namespaces, Kobako::Codec::_HandleTable handler, Kobako::Transport::_GuestYielder yield_to_guest) -> String
|
|
16
16
|
|
|
17
|
-
def self?.resolve_call_args: (Kobako::Transport::Request request, Kobako::
|
|
17
|
+
def self?.resolve_call_args: (Kobako::Transport::Request request, Kobako::Codec::_HandleTable handler) -> [Array[untyped], Hash[Symbol, untyped]]
|
|
18
18
|
|
|
19
19
|
def self?.encode_caught_error: (StandardError error) -> String
|
|
20
20
|
|
|
@@ -24,17 +24,17 @@ module Kobako
|
|
|
24
24
|
|
|
25
25
|
def self?.reject_unexposed!: (untyped target, Symbol name) -> void
|
|
26
26
|
|
|
27
|
-
def self?.resolve_arg: (untyped value, Kobako::
|
|
27
|
+
def self?.resolve_arg: (untyped value, Kobako::Codec::_HandleTable handler) -> untyped
|
|
28
28
|
|
|
29
|
-
def self?.resolve_target: (String | Kobako::Handle target, Kobako::
|
|
29
|
+
def self?.resolve_target: (String | Kobako::Handle target, Kobako::Transport::_NamespaceRegistry namespaces, Kobako::Codec::_HandleTable handler) -> untyped
|
|
30
30
|
|
|
31
|
-
def self?.resolve_path: (String path, Kobako::
|
|
31
|
+
def self?.resolve_path: (String path, Kobako::Transport::_NamespaceRegistry namespaces) -> untyped
|
|
32
32
|
|
|
33
|
-
def self?.require_live_object!: (Integer id, Kobako::
|
|
33
|
+
def self?.require_live_object!: (Integer id, Kobako::Codec::_HandleTable handler) -> untyped
|
|
34
34
|
|
|
35
|
-
def self?.encode_ok: (untyped value, Kobako::
|
|
35
|
+
def self?.encode_ok: (untyped value, Kobako::Codec::_HandleTable handler) -> String
|
|
36
36
|
|
|
37
|
-
def self?.wrap_as_handle: (untyped value, Kobako::
|
|
37
|
+
def self?.wrap_as_handle: (untyped value, Kobako::Codec::_HandleTable handler) -> Kobako::Handle
|
|
38
38
|
|
|
39
39
|
def self?.encode_error: (String type, String message) -> String
|
|
40
40
|
end
|
|
@@ -11,7 +11,7 @@ module Kobako
|
|
|
11
11
|
|
|
12
12
|
def initialize: (entrypoint: Symbol | String, ?args: Array[untyped], ?kwargs: Hash[untyped, untyped]) -> void
|
|
13
13
|
|
|
14
|
-
def encode: (Kobako::
|
|
14
|
+
def encode: (Kobako::Codec::_HandleTable handler) -> String
|
|
15
15
|
|
|
16
16
|
private
|
|
17
17
|
|
|
@@ -3,10 +3,10 @@ module Kobako
|
|
|
3
3
|
class Yielder
|
|
4
4
|
@yield_to_guest: Kobako::Transport::_GuestYielder
|
|
5
5
|
@break_tag: Symbol
|
|
6
|
-
@handler: Kobako::
|
|
6
|
+
@handler: Kobako::Codec::_HandleTable
|
|
7
7
|
@active: bool
|
|
8
8
|
|
|
9
|
-
def initialize: (Kobako::Transport::_GuestYielder yield_to_guest, Symbol break_tag, Kobako::
|
|
9
|
+
def initialize: (Kobako::Transport::_GuestYielder yield_to_guest, Symbol break_tag, Kobako::Codec::_HandleTable handler) -> void
|
|
10
10
|
|
|
11
11
|
def yield: (*untyped args) -> untyped
|
|
12
12
|
|
data/sig/kobako/transport.rbs
CHANGED
|
@@ -8,5 +8,13 @@ module Kobako
|
|
|
8
8
|
interface _GuestYielder
|
|
9
9
|
def call: (String) -> String
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
# The Service registry a dispatch resolves constant-path targets
|
|
13
|
+
# against. The Sandbox's Kobako::Catalog::Namespaces is the
|
|
14
|
+
# production conformer; modelled structurally so the Transport
|
|
15
|
+
# layer needs no upward dependency on Catalog.
|
|
16
|
+
interface _NamespaceRegistry
|
|
17
|
+
def lookup: (String target) -> untyped
|
|
18
|
+
end
|
|
11
19
|
end
|
|
12
20
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kobako
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Aotokitsuruya
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: msgpack
|
|
@@ -37,6 +37,7 @@ files:
|
|
|
37
37
|
- CHANGELOG.md
|
|
38
38
|
- LICENSE
|
|
39
39
|
- README.md
|
|
40
|
+
- ROADMAP.md
|
|
40
41
|
- SECURITY.md
|
|
41
42
|
- crates/kobako-runtime/CHANGELOG.md
|
|
42
43
|
- crates/kobako-runtime/README.md
|