feat(I203/M3): InvocationContext + streaming parity + schema-sync (post-I198/I199) #1
No reviewers
Labels
No labels
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
h-dv/ixt-sdk-go!1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/i203-go-streaming"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Mission I203 / M3 — Go SDK parity with the Rust SDK for InvocationContext (spec 21) + streaming (spec 23). Closes the 13-commit nested-
ixt-publiclag and extends the schema-sync tooling.Phase A — schema sync + post-I198 migration
ixt-publiceaf4205→117319c37e78.sync-schemas.sh(wasipc.capnp-only): now copies + Go-annotatesipc_streaming.capnp+module.capnpand regenerates all bindings (capnp compile -ogo→sdk/ipc/,sdk/streamcapnp/,sdk/modulecapnp/). Idempotent (re-run = zero diff). Two shared-schema accommodations, documented in the script header: drop the unusedModuleContext.servicesfield (module↔services capnp import cycle, never consumed by the SDK) and the unusedinterface IxtModuleRPC block (server collides with capnp'sShutdownerundergo vet).sdk/context.go: full GoInvocationContextmirror (ActorSubject/ActorIdentitywith capabilities + opaquetokenRef,MessageTargetunion, bounded metadata + conventional keys) with capnp encode/decode againstmodule.capnp.sdk.Contextnow carries the decoded*InvocationContext(Actor()/HasCapability());handleMessagedecodesHandlePayload.context. (Go SDK had zeroRequestContext/SecurityContextrefs — itssdk.Contextwas a thin struct.)Phase B — streaming API
sdk/streaming.go:StreamID, 4InteractionKinds,CloseReason/CancelReason/13-codeStreamErrorCode, 6-variantStreamFrameunion withEncode/DecodeStreamFrame(structurally identical to Ruststream_wire.rs).StreamSender(callee):SendDataw/ auto-sequence + credit accounting (ErrRejectedon exhaustion),GrantCredit/Close/Cancel/SendError.StreamHandle+AcceptStream(Phase-2a callee): decodes embeddedInvocationContext, derives acontext.Contexthonoring the spec-21 deadline,Incomingchannel +Feed()routing. No bespoke flow control.Test plan
go build ./...+go test ./...green — 30 streaming tests (all 6 frame variants + full InvocationContext round-trip + sender credit/sequence/lifecycle)go vet ./...clean;gofmt -l .cleansync-schemas.shidempotentLockstep: superproject pin bumps after merge. Schema-pin drift (this SDK) clears. Tier-B cross-runtime e2e candidate (M7).
🤖 Generated with Claude Code
Phase B — Go streaming surface mirroring the Rust SDK (spec 23, I199 part 2). New sdk/streaming.go: * StreamID (16-byte UUID, lowercase-hex String mirroring Rust Display). * InteractionKind (Unary/ClientStream/ServerStream/BidiStream, wire ordinals preserved), CloseReason, CancelReason, StreamErrorCode (full 13-code set) — Go enums whose integer values equal the capnp wire ordinals, so conversion to/from streamcapnp is a direct cast. * StreamData / StreamError / StreamFrame (six-variant tagged union) with EncodeStreamFrame / DecodeStreamFrame Cap'n Proto round-trip via the generated streamcapnp types — structurally identical to Rust stream_wire.rs. * StreamSender (callee side): SendData (auto-sequence + credit-window accounting; returns *StreamSendError{ErrRejected} when credit is exhausted rather than blocking — backpressure is the receiver's credit grant per I203 "no bespoke flow control"), GrantCredit, Close, Cancel, SendError; idempotent terminal state. * StreamHandle + AcceptStream (callee semantics matching Rust Phase 2a): decodes the open frame's embedded InvocationContext, derives a context.Context honoring the spec-21 deadline, exposes Incoming (buffered by bufferCapFrames) and Feed() which routes Data/Credit/Close/Cancel/Error and tears the stream down (closes Incoming, cancels Ctx with cause) on a terminal frame. FrameSink abstracts the reply transport (runtime supplies the real one; tests an in-memory capture). Tests (sdk/streaming_test.go, +15 funcs): all six StreamFrame variants round-trip; StreamID hex + length validation; full InvocationContext round-trip (operator subject, tokenRef, capabilities, metadata, service + reply targets, system actor wildcard); empty-context decode; StreamSender credit/sequence/close-final-sequence; AcceptStream decode + Feed data/credit/close lifecycle. Verification: `go build ./...`, `go test ./...` (sdk: ok, 30 tests), `go vet ./...` clean, `gofmt -l .` empty. sync-schemas.sh idempotent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>