feat(ocap-kernel): add IO kernel service for vat I/O streams#840
Open
feat(ocap-kernel): add IO kernel service for vat I/O streams#840
Conversation
2380261 to
95e5017
Compare
Add IO channels as kernel services with read()/write() methods, configured via a new `io` property on ClusterConfig. IO channels are ephemeral, created at subcluster launch and destroyed at termination. MVP implements socket type (Unix domain socket) with line unit only. - Add IOSpec/IOConfig types and ClusterConfig.io field - Add IOChannel/IOChannelFactory interfaces (platform-agnostic) - Add makeIOService() exo factory with direction enforcement - Add IOManager for per-subcluster channel lifecycle - Add KernelServiceManager.unregisterKernelServiceObject() - Add makeSocketIOChannel() Unix domain socket implementation (Node.js) - Integrate IOManager into Kernel and SubclusterManager - Wire makeIOChannelFactory into nodejs makeKernel() - Add unit tests for io-service, IOManager, socket-channel, unregister - Add integration test vat and test (io-vat, io.test.ts) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
95e5017 to
453ff26
Compare
Contributor
Coverage Report
File Coverage |
| await this.#ioManager.createChannels(subclusterId, config.io); | ||
| } | ||
|
|
||
| this.#validateServices(config, isSystem); |
There was a problem hiding this comment.
Failed launch leaves orphaned IO resources
Medium Severity
launchSubcluster now persists the subcluster and creates IO channels before service validation, but has no rollback path if validation or vat bootstrap fails. A failed launch can leave config persisted and IO channels/services still allocated, causing later duplicate-service errors and resource leaks.
| // Destroy IO channels before terminating vats | ||
| if (this.#ioManager) { | ||
| await this.#ioManager.destroyChannels(subclusterId); | ||
| } |
There was a problem hiding this comment.
Early IO unregister can halt kernel queue
High Severity
terminateSubcluster now unregisters IO services before vat termination. If queued messages still target those service krefs, invokeKernelService hits an unregistered target and throws, which can stop the run loop and leave the kernel non-functional.
Additional Locations (2)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Implements IO kernel services (#831) that enable piping data from the outside world into and out of vats via configurable IO channels.
IOChannel/IOChannelFactoryabstractions andIOManagerfor per-subcluster channel lifecycle managementmakeSocketIOChannel) in the Node.js package with line-delimited framing and single-client acceptanceKernel,SubclusterManager, andKernelServiceManager(including newunregisterKernelServiceObject)ioconfig property toClusterConfigfor declaring named IO channels, wired as kernel services to bootstrap vatsinoutChanges
packages/ocap-kernel/src/types.ts—IOSpec,IOConfigtypes andiofield onClusterConfigStructpackages/ocap-kernel/src/io/— NewIOManager,makeIOService,IOChannel/IOChannelFactorytypespackages/ocap-kernel/src/KernelServiceManager.ts—unregisterKernelServiceObject()methodpackages/ocap-kernel/src/Kernel.ts—ioChannelFactoryoption,IOManagercreationpackages/ocap-kernel/src/vats/SubclusterManager.ts— IO channel create/destroy in launch/terminatepackages/nodejs/src/io/—makeSocketIOChannel(Unix domain socket),makeIOChannelFactorypackages/nodejs/src/kernel/make-kernel.ts— Accepts and defaultsioChannelFactoryTest plan
makeIOService(9 tests) — direction enforcement, read/write delegationIOManager(6 tests) — create/destroy lifecycle, rollback on failure, error handlingunregisterKernelServiceObject(5 tests) — cleanup of krefs, KV entries, pinsmakeSocketIOChannel(12 tests) — connection, line framing, disconnect, cleanup@chainsafe/libp2p-quicmissing package issue)Closes #831
🤖 Generated with Claude Code
Note
Medium Risk
Touches kernel/subcluster lifecycle and service registration, so mis-ordering or cleanup bugs could leak resources or break service availability. The behavior is guarded by injection/optionality and has broad test coverage, reducing risk.
Overview
Adds a new IO kernel service layer that lets subclusters expose named IO endpoints to vats via standard kernel services. Cluster configs can now declare
iochannels with direction/unit metadata; the kernel creates per-subcluster channels at launch, registers them as services (wrapped bymakeIOService), and tears them down on subcluster termination.Introduces a Node.js implementation backed by Unix domain sockets (
makeSocketIOChannel) plus a dispatchingmakeIOChannelFactory, wires this factory intomakeKernelby default, and expandsKernelServiceManagerwithunregisterKernelServiceObjectfor lifecycle cleanup. Adds unit tests for IO manager/service/socket behavior and an end-to-end kernel/vat integration test exercising read/write over a socket channel.Written by Cursor Bugbot for commit 453ff26. This will update automatically on new commits. Configure here.