runtime: implement the path hand-written adapters use, ported from nightseam v0.6.0 - #9
Merged
Merged
Conversation
Byte-identical copies from github.com/Bitspark/nightseam at 5cc9723a24646c40ed1861f892b2b23eb6d785d7 (tag v0.6.0), placed at their bitruntime destinations so later commits show every adaptation as a diff. This commit does not build; the next commits adapt it to Bitwire 0.3.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…velope Move Nightseam's duplex seam into transports/go and its WebSocket adapter into transports/websocket/go, and the envelope codec, canonical path encoding and Unicode guard into internal/profile/go. Carrier-contract rules the port adds (Bitwire carrier draft, research R26 and R27): - one closed classification: transports.ErrClosed, which a remote CloseError and a dropped WebSocket also satisfy; - Sendable separates sendable close codes from observe-only 1005, 1006 and 1015, which Close refuses with ErrUnsendableCode before any library sees them; - a frame over the receive limit ends the pipe with 1009 on both sides, and ends a WebSocket promptly instead of leaving a half-closed socket. The envelope accepts and refuses exactly what v0.6.0 does. The bitwire/1 tables are vendored byte for byte under vectors/bitwire-1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
core/go gains the addressed operators (At, Mount, Forward), the local pair (NewPair, with its own PairOptions), the invocation lifecycle, Respond, publication evidence, meta and trace propagation. dispatch/go holds the Dispatcher and the Call/Emit/Handle/Register helpers. engine/go is the bitwire/1 peer, presented only through its root Endpoint; engine/websocket/go sets up connections (Accept, NewHandler, Dial). Received context stays private to bitruntime in internal/delivery/go, which Bitwire 0.3 permits for Go. Fixed rather than ported: - nightseam#722: a closing pair answers every queued refusal, and the peer's root answers queued requests instead of dropping them (R28); - nightseam#658: a pair response frees its call's slot before the caller can hold the answer; - R26: every ended carrier's error satisfies transports.ErrClosed and keeps its cause, so a forwarded closed or overloaded destination answers disconnected rather than internal; - research 0001 row 14: Forward fails only the refused message instead of detaching both directions; - R27: an observe-only close code aborts the peer instead of being sent. Removed: the raw method-name API (Handle, Call, Emit on the peer), the observer hooks and family labels, pending their design with Bitwire's received-context revision. bitwire/1 frames are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s verbatim Byte-identical copies from github.com/Bitspark/nightseam at 5cc9723a24646c40ed1861f892b2b23eb6d785d7 (tag v0.6.0), placed at their bitruntime destinations. This commit does not build; the next commits adapt it to Bitwire 0.3.0. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ckets A scenario every implementation serves and calls (conformance/interop): echo of awkward JSON, slash and empty segments, method_not_found, public errors with data, events both ways, cancellation reaching the server, meta, a reverse call, a 3 MiB frame under a 4 MiB budget and twenty concurrent calls. Programs for bitruntime Go and for Nightseam v0.6.0 Go and TypeScript, each pinned in its own test-only module; the Nightseam ones compile against Bitwire 0.2.0 and never enter a published package. A raw recorder replays fixed envelopes and captures what each server sends. bitruntime Go's transcript equals Nightseam v0.6.0 Go's byte for byte, masking only random span identifiers. node scripts/interop.mjs: all nine pairings pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
NOTICE names Nightseam v0.6.0 (5cc9723) as the only source of the ported files, maps each to its bitruntime destination and records the vendored bitwire/1 tables. The changelog gains the missing 0.1.0 heading. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Research 0001 row 28: v0.6.0's Go carriers validated a caller's frame and then copied it, so a concurrent mutation during Send could admit bytes that were never validated. The pair, the root and the call helper's reply now copy first and validate the copy. The byte-level interop transcript is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ported from Nightseam 5cc9723a (v0.6.0) runtime/go: dispatcher_test.go, dispatcher_ownership_test.go, wire_test.go, wire_event_context_test.go, wire_namespace_test.go, wire_options_test.go, wire_validation_test.go and bitwire_test.go, with names translated per docs/port-from-nightseam.md. What used the removed raw peer API goes through the root Endpoint: a dispatcher over peer.Wire() with Handle/Register, and Call/Emit through peer.Wire(). Raw non-path method names are sent as raw bitwire/1 frames over a pipe and must be answered method_not_found, "ordinary" included, now that no raw handler can take it; a canonical encoding reaches the root namespace. Observer assertions are dropped (HandlerPanic, RequestEnded) or re-instrumented where they checked traffic rather than the hook: FrameSent order and the ConnectionClosed code/reason are read from a recording pipe connection. The pure ForwardWire test stays with core. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ported from Nightseam 5cc9723a (v0.6.0) runtime/go/wire_send_test.go. The raw Emit that filled the destination's queue is the root's Emit; since the root admits asynchronously, a propagator marks when the root has taken each frame so the queue is where v0.6.0's synchronous Emit left it. The observer's Backpressure count is dropped, and so is the raw, paced call that was withdrawn before admission: a root call is never paced. The earlier admitted call now reaches its caller through the root as a public error, so it is asserted disconnected (R26) rather than ErrBackpressure. It is answered cancelled instead: the root's waiter runs under a context derived from the peer's own, which the peer's end cancels before releasing it. That is an engine/go defect, as in v0.6.0's root; the test skips on exactly that answer and fails on any other. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ported from Nightseam 5cc9723a (v0.6.0) runtime/go/wire_cancel_reservation_test.go. The tests build a peer whose root alone runs, read its outgoing queue and complete its pending calls directly, so they are internal to engine/go rather than beside the dispatcher. The root is started explicitly, as v0.6.0's Wire() started it lazily; pending results are request.Result. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d the close code Two defects the ported tests found, both present in Nightseam v0.6.0: - A request the root had handed to the peer waited under a context derived from the peer's, which the peer's end cancels before releasing waiters, so its caller was answered cancelled instead of disconnected (R26). The waiter now prefers the peer's terminal error and owes no cancellation. - Peer.end cancelled the reader's context before closing the connection. A WebSocket whose pending read is cancelled drops the socket, so a peer ended from another goroutine let the far side observe 1006 instead of its code. The connection now closes first. TestAClosingPeerDeliversItsCodeOverAWebSocket fails on the first of 50 runs without the fix and passes all of them with it; the send test's skip is removed and now requires disconnected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The fresh consumer now also calls through a local pair, a dispatcher and a WebSocket peer, installing the pushed commit or tag from the public proxy. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port duplex/go/wire_test.go from Nightseam v0.6.0 (5cc9723a) to core/go/addressed_test.go. Names follow docs/port-from-nightseam.md: duplex.At and Mount are core.At and Mount, ErrNoRoute and ErrPath are core.ErrMissingPath and ErrInvalidPath, ErrClosed is transports.ErrClosed, and the canonical path encoding is internal/profile's. Every assertion is kept as it was. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/wire_pair_test.go from Nightseam v0.6.0 (5cc9723a) to core/go/pair_test.go as an external test. NewWirePair is core.NewPair; HandleWire, CallWire and EmitWire are dispatch.Handle, Call and Emit; the unexported wireDispatchContext and callWire are internal/delivery.Context and internal/request.Call; sendWireResponse is core.Respond. TestLocalWirePairStalledEventDeadlineIsObserved drops its one assertion on the removed Observer hook: the Backpressure event with Stalled set and a Deadline of 15ms. The stall is still observed as the pair's ending and a closed carrier afterwards. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Regression tests for the three pair behaviors docs/port-from-nightseam.md records as fixed rather than ported: - nightseam#722: with the receiving side's delivery held, a refusal still queued when the pair closes is answered busy at once instead of at the caller's deadline, and the call the pair held is answered disconnected. - nightseam#658: a return capability that issues the next request while it is handed the answer finds the pending slot free at a limit of one, and 500 sequential calls at that limit are never refused busy. - R26: the send that overflows a pair reports both ErrBackpressure and transports.ErrClosed, the ended pair is closed on both ends, and a request core.Forward hands into the overflow is answered disconnected, not internal. Each fails against the v0.6.0 behavior it guards: completing a call after the hand-off, dropping queued refusals at close, or returning a bare ErrBackpressure. TestLocalWirePairRetainsPendingUntilResponse passes with -race -count=200. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/invocation_test.go and invocation_experiment_test.go from Nightseam v0.6.0 (5cc9723a), complete: the two independently implemented lifecycle participants (one composing core.Invocation, one answering the vocabulary from its own ledger), the opaque forwarding wrapper, the pure conduit route, and every assertion. They use public facilities only: core's vocabulary and helpers, dispatch.NewDispatcher, Handle and Register, and core.Forward for ForwardWire. Path-taking duplex.Wire sinks are wire.AddressedWire. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/publication_test.go and trace_test.go from Nightseam v0.6.0
(5cc9723a). The raw peer API they used is removed (R20), so handlers are
attached with a dispatcher in engine.Options.Prepare and calls and events go
through dispatch.Call and dispatch.Emit on peer.Wire(). Frames a test
writes or reads name the canonical path encoding ("5:outer").
Changed, with the reason in each test:
- TestQueuedWriteFailureHasNoUnpublishedProof and
TestReadFailureHasNoNestedUnpublishedProof: a call through the root is
answered with a public error, so the transport cause (and the nested
context.Canceled) is asserted on Peer.Err, which keeps it (R26); the
no-proof assertions stay on the call and are added for Peer.Err.
- TestACustomPropagatorSeesTheMembersVerbatim: the outgoing trace is
injected by the call's CallOptions.Propagator, as v0.6.0's root did.
- TestRefusedReverseReplyCannotProveDeliveredCallUnpublished runs with a
250ms client RequestTimeout: the root refuses the oversized reply and its
fallback at the return capability and leaves the request to its deadline.
Two v0.6.0 assertions the root Endpoint does not meet are kept, skipped,
in tests of their own: TestCallerBoundRefusalIsUnpublished (the pending
bound's busy refusal is not unpublished through the root) and
TestOversizedReverseReplyFallbackEndsTheCarrier (the carrier does not end).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port the two ForwardWire tests of Nightseam v0.6.0's runtime/go/wire_namespace_test.go (5cc9723a) to core/go/forward_test.go; the rest of that file concerns the dispatcher. TestForwardWirePreservesMessagesAndOwnsOnlyRegistrations asserts the documented forwarding change (research 0001, row 14) in its last section: a refused request is answered busy and forwarding goes on, where v0.6.0 detached both directions. A new test holds a request refused by an ended or overflowed destination to the disconnected answer R26 requires. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… caller The ported publication tests showed that a reply to a request the engine admitted, when neither it nor its bounded fallback fit the frame limit, was refused at the reply capability and left the remote caller waiting for its deadline. v0.6.0's raw response path failed the connection instead. The reply now settles as the bounded internal error, which the engine's response path sends or fails the connection over. The test's skip is removed. Also tidy go.mod: coder/websocket and go-json-experiment are direct dependencies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/peer_test.go, backpressure_test.go, peer_pacing_test.go
and unicode_peer_test.go from Nightseam v0.6.0 (5cc9723a). The raw
method-name API is removed, so each handler is a dispatcher route at
[name] attached in Prepare, and calls and events go through the root
with the dispatch helpers. Pairs run over transports.Pipe; the delayed
TCP writes become a gate on the pipe's Send. Hand-written frames name
paths canonically ("5:outer"), and a new test holds that a raw method
name is answered method_not_found without ending the connection.
Dropped: OnEvent's listener and idempotent unsubscribe (raw API), and
the pacing of the raw Emit and Call with its observer events; what
remains of that rule is held instead: a response waits for a full
queue and resumes, and root traffic ends the carrier at once, as
v0.6.0's root did. The authentication, origin, subprotocol and dial
tests move to engine/websocket/go with the connection setup.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/carriage_test.go and serial_test.go from Nightseam v0.6.0 (5cc9723a). Every row of vectors/bitwire-1/frames.json and serials.json is sent as raw text over a pipe to a peer of each role, and the far side holds that the peer ended with 4011 or served on: a request after the row, above every row's serial, is answered. A row addressed to the server reaches a client with its id prefixes swapped; a row addressed to either reaches both unchanged. v0.6.0's decode-level judgement of frames.json is kept beside it. The meta tests decode with internal/profile and send through the root; the refused-meta test reads 4011 at the far side instead of the removed observer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port runtime/go/seam_test.go and the pipe half of prepare_test.go from Nightseam v0.6.0 (5cc9723a). How a peer ends a connection is held at the far side's reading, since observers are removed; a far side's abort is held on the peer's error instead. An ended peer's error is a closed carrier that keeps its cause (R26), so the oversized-frame refusal is the error's suffix, and the far side reads 4011 with it. The tunnel installed in Prepare becomes a dispatcher at the root, which meets a request already waiting on the pipe when the peer is made. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
R27: the root asked to close with 1005, 1006 or 1015 aborts, and the far side reads 1006 with no reason; a sendable code travels with its reason. R28: with the root held inside the answer to a refusal, a request it admitted and never handed on, a call through the dispatch helper, and a queued busy refusal are each answered when the peer ends (disconnected, disconnected, busy) and none reaches the wire. The request already in flight is answered cancelled or disconnected at random: its waiter's context derives from the peer's, which ends with it. v0.6.0's root derived it the same way; the test accepts either. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Port the authentication, origin, subprotocol, dial-deadline and Prepare tests of runtime/go/peer_test.go and prepare_test.go from Nightseam v0.6.0 (5cc9723a). What a peer serves is a dispatcher attached in Prepare; the tunnel whose first channel.open met it becomes a first request over 3000 dials (250 with -short). A new test reads the close frame over a real WebSocket: 4011 and the refusal for a refused frame, and no close frame at all for 1005 and 1006 (R27). The rows for a sendable code chosen outside the read loop (Wire().Close(1008), Close()) are skipped: Peer.end cancels the peer's context before the close handshake, coder/websocket drops the socket when a pending Read's context ends, and the close frame is often lost. v0.6.0's end and WebSocket transport do the same with the same library. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The ported engine tests skipped the WebSocket close of a peer ended from outside and accepted cancelled for a call the peer's end cut off, both inherited from v0.6.0. With the peer now closing its connection before cancelling its context and answering such a call disconnected, the tests require exactly that: 20 runs under -race deliver the chosen code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
README, charter and layout name the delivered components, the Go packages of the one root module and the TypeScript package's subpaths, why they are released together, and the interoperability evidence. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…me to Bitwire 0.3.0 One package, @bitspark/bitruntime 0.2.0, built at the repository root, replaces core/ts's own manifest. It exports the subpaths ./core, ./transports, ./engine and ./dispatch; sources stay under <component>/ts/src and import each other by relative path. The received context, frame validation, the envelope codec, path encoding, the request primitive and the Unicode guard live in core/ts/src/internal, which no subpath exports, so received context stays unforgeable. - transports: the seam, pipe and WebSocket adapter, the close-code constants and sendable; close refuses an observe-only code (R27). - core: at, mount, forward, pair (PairOptions of its own), the invocation lifecycle, PublicError (was DuplexError), UnpublishedError, respond, trace propagation; MissingPathError, InvalidPathError and ReceiverExistsError replace the duplex wire error codes. - dispatch: call, emit, handle, register, onEvent, Dispatcher, SelectedEndpoint; handler contexts no longer reach the carrier. - engine: Peer, presented only through wire(); a name that encodes no path is answered method_not_found, as a v0.6.0 peer without that handler answers. bitwire/1 frames are unchanged. Fixed rather than ported, as in Go: nightseam#722 (a closing pair and the peer's root answer queued refusals), nightseam#658 (a pair response frees its slot before the caller holds it), R26 (every ended carrier reports PublicError 'disconnected' with its cause), research 0001 row 14 (forward fails only the refused message). Since every request now takes the root, local frames omit empty trace members and the root forwards the trace a request arrived with; v0.6.0's root refused its own answer to a request carrying a tracestate alone. Removed: the peer's raw handle/onEvent/call/emit and options.dispatch, context.peer, observers and family labels. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ported from Nightseam v0.6.0 at 5cc9723a: duplex's pipe and WebSocket adapter tests with their conformance suite, at/mount and path encoding, wire-pair, invocation, invocation-experiment (two independent lifecycle integrations and an opaque wrapper, public facilities only), dispatcher, dispatcher-ownership, wire, wire-forward, wire-event-context, peer, peer-pacing, serial (vectors/bitwire-1/serials.json), carriage (every row of vectors/bitwire-1/frames.json), unicode (vectors/bitwire-1/unicode.json), trace and publication. Raw-API tests go through wire() and the dispatch helpers, or raw frames whose names are path encodings. Not ported: observer and family assertions, the tests of the observer alone, the pacing of the removed raw emit and call, the 'peer' route of the cancellation matrix and the validator rows of the unicode test. Each changed expectation is a documented change, noted where it stands. Added: regressions of nightseam#722 and #658 (200 chained calls), the queued-cancellation slot, R26, R27, forward's row 14, R28 on the peer's root, a request cut off by its peer's end answering disconnected, close codes transmitted on every ending, method names that encode no path, and two peers over a real socket (Node's WebSocket against a ws server) calling, emitting and cancelling both ways. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…om the root CI and the release workflow run npm ci, check, build and test at the repository root and pack the root package. The package smoke installs the packed @bitspark/bitruntime into a fresh consumer, runs the tree smoke through /core, a pair and dispatcher call through /core and /dispatch and a peer over a pipe through /engine and /transports, and holds that no import reaches the private internals. RELEASING.md, docs/RELEASE.md, the READMEs and LAYOUT.md record the one package and its subpaths; nothing is released. docs/port-from-nightseam.md gains the TypeScript names and the TypeScript-specific behavior changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The bitruntime TypeScript program joins the scenario. All sixteen pairings of bitruntime and Nightseam v0.6.0, Go and TypeScript, pass over real WebSockets, and bitruntime TypeScript's transcript equals Nightseam v0.6.0 TypeScript's byte for byte, as Go's equals Go's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The wait handler now emits a waiting event first, and the recorder sends
its cancellation only after it. A cancellation that raced the handler's
start was answered with the runtime's own message in TypeScript
("Request was cancelled.") and the handler's otherwise, in Nightseam v0.6.0
as in bitruntime, so the TypeScript transcripts could differ by timing.
Three consecutive runs of all sixteen pairings and both byte comparisons
pass.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g its caller As in Go: a reply to a request a carrier admitted that cannot travel, not even as its bounded fallback, now settles as the bounded internal error, and the peer's own response path fails the connection when that does not fit. The delivered call ends with the connection at once instead of at its deadline; the updated test fails after 10 s without the fix. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… found - A failed Prepare left the root unstarted, so what Prepare attached was never told the peer ended (v0.6.0 started the root when Prepare selected it). The root now runs before Prepare. - A peer ended by the context it was made with could answer a call its root had handed on as cancelled; Respond now classifies a closed carrier before a context error, and the waiter reads the peer's end. - Malformed-frame close reasons use v0.6.0's decoding type names again, and the pre-profile refusal keeps its v0.6.0 wording; the remaining difference is documented. - An invalid path from a pair or the root is core.ErrInvalidPath, and a transport that ends itself on an over-limit frame, an unknown message kind or a write past its context reports a closed carrier. Regression tests fail without the engine fixes. Interoperability and both byte-level comparisons are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Apply the organization's naming rule (Bitspark/.github NAMING.md): bitwire, nightseam, bitstore, deixis and the other projects are written exactly as their repositories are named in prose. Code spans, identifiers and protocol names (bitwire/1) are unchanged. Checked with the organization's naming.mjs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…Script port found - A close code the browser WebSocket API refuses (anything but 1000 and 3000-4999) threw inside the peer's close and left the socket open; the connection now closes without the code instead. - A connected peer whose connection is closing refused sends with not_connected, and an emit racing the close ended the peer and lost the far side's close code; it now reports disconnected and leaves the close to arrive. - A reply a pair admitted but its caller's return capability refused, such as one over a smaller frame limit before a forwarder, stranded the caller until its deadline, in Go and TypeScript; the caller now gets the bounded internal error. - A handler could reach the endpoint behind its dispatcher through a TypeScript-private field; it is now #private. Each has a regression test that fails without its fix. The Go lifecycle test waiting on onRetired now waits for the callback, which runs after Retired reports true outside the lock (a race inherited from v0.6.0's test). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 26, 2026
This was referenced Sep 27, 2026
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.
Current delivery status — 2026-09-26
Merged as
e28bb1adefbc8a5cb1b03f172b4e7212584bd7a2and published in v0.2.0. The description below records the candidate implementation and its evidence at review time; candidate tests are not proof that every downstream released-consumer gate has completed. See #1 for those remaining gates.Delivers bitruntime#1: the path hand-written adapters use, in Go and TypeScript, over the public bitwire 0.3.0 contract, speaking
bitwire/1. Release candidate for v0.2.0.What it adds
At,MountandForward(addressed operators onAddressedWire); the local pair (NewPair/pair); the public invocation lifecycle;Respond,PublicError, publication evidence, meta and trace propagation. All of this sits beside v0.1.0's tree core.ErrClosed, the one classification of a closed carrier;Sendable, which separates sendable close codes from observe-only ones.bitwire/1peer, presented only through its root Endpoint, and WebSocket setup (Accept/NewHandler/Dial;Peer.connect/Peer.attach).NewDispatcher/createDispatcherwith selected endpoints, plusCall/Emit/Handle/Register(call,emit,handle,register,onEvent).@bitspark/bitruntime, with subpaths/core,/transports,/engineand/dispatch. The received context shared across components stays private (a Gointernalpackage, a TS module no subpath exports). This follows the pending maintainer decision on the TS package layout.Provenance
Ported from nightseam v0.6.0 only, commit
5cc9723a24646c40ed1861f892b2b23eb6d785d7; none of its 41 unreleased commits is included.NOTICEmaps each source file to its destination.docs/port-from-nightseam.mdlists every name mapping, every behavior change and what was kept as it was.Fixed rather than ported
Each fix has a regression test that fails without it.
ErrClosedand keeps its cause, and forwarding answersdisconnected, notinternal. Also, a call cut off by the peer's end, or by its parent context, isdisconnected, notcancelled.Preparereleases what it attached.peer(R19/R23).Evidence
-race, and TypeScript runs 221 tests.node scripts/interop.mjs, new CI job): all 16 pairings of bitruntime and nightseam, Go and TypeScript, pass over real WebSockets. A raw recorder shows each bitruntime server's transcript is byte-identical to nightseam's in the same language.bitwire/1tables. v0.6.0's tables, vendored byte for byte invectors/bitwire-1, are judged by a running peer of each role.Mount: 20 conform, and the other 19 match nightseam v0.6.0's recorded gaps exactly.Tracks #1. This merged source change does not close its remaining released-artifact acceptance and bitsystem3 #7 consumer gate. Those are verified separately through bitwire PR52.
🤖 Generated with Claude Code