rossoctl / rossoctl/serverless-harness
ST: the gRPC transport has no persistent fast channel — file ops pay a round trip and a process each
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 7
- Avg merge
- 12h 59m
- Merged PRs (30d)
- 71
Description
Problem
k8sSandboxExtension deliberately runs a two-tier transport (extension.ts:30-34):
fastTransport—persistentExecInPod, ONE long-livedbashwith nonce-framed commands, serving the small request/response ops (read/write/edit/ls/find).streamTransport— per-call exec, for the ops that needonData/ abort / long-running semantics (bash,grep, user!).
But opts.transport overrides both (extension.ts:38, :49-51), and run-leaf.ts:786 passes exactly that for a leased gRPC presence record:
k8sSandboxExtension({ config: selected?.config ?? null, transport: selected?.transport })
So on the gRPC path the fast tier does not exist. Every file op becomes a full SandboxExec.Exec round trip through the relay, ending in a fresh bash -c in the sandbox. On the kubectl path the same op is one framed line on an already-running bash.
This is a silent asymmetry between transports of the kind ADR-0024 and transport.ts's conformance battery exist to prevent — the battery pins the output cap and the exec-timeout ceiling across all three implementations, but nothing pins whether the fast tier is available, so a caller above the seam cannot see or control the difference.
Why it matters more now
File ops are the highest-frequency tool calls in a coding agent. Under P6 (#244) a single host runs W workers × S multiplexed sessions against K sandbox containers, so per-op process churn concentrates: what is one extra round trip at 1:1 becomes W×S round trips and W×S bash spawns against K containers.
E6/E7 measured per-sandbox duty at 2–8% of leaf wall-clock, and E7 validated mixed-ref converge correctness at 6 concurrent refs on one pod. P6's rungs go well past that, so whether duty holds under this load is an open question rather than a settled one. P6 §5.2 records per-file-op latency and sandbox-container CPU precisely so a sandbox-bound run is not misreported as a harness density limit.
Why this is not P6's to fix
The fix lifts both substrates equally. Folding it into P6 would improve the VM arm and the Knative arm at the same time, while adding transport surface to a slice whose job is to measure the deployment tier. P6 instead stays correct without it by pinning both E9 arms to the relay + gRPC transport (§5.3), so the comparison varies the deployment tier and nothing else.
Shape of the fix
Two independent pieces; the first is small.
1. Let the extension take the two tiers separately. Today opts.transport means "both". Either add an optional fast override, or accept { fastTransport?, streamTransport? } with transport kept as the both-tiers shorthand for back-compat. Purely a signature change; no protocol involved.
2. Give the remote path a persistent channel. persistent-exec.ts is transport-agnostic almost everywhere — framing (framing.ts, wrapCommand, nonce matching), producer-side cap, transparent fallback and timeout handling are all generic. It is kubectl-specific in exactly two places:
- the binary name at
:84—spawnFn('kubectl', …) buildPersistentKubectlArgsat:12—exec -i -n <ns> <pod> -- bash
So a container-exec variant (docker exec -i <container> bash, or podman) is a parameterized argv rather than a new protocol, and it declares the same producer-side-cap truncation mechanism the conformance battery already knows.
A relay-mediated persistent channel is the larger alternative: it needs a long-lived shell concept on the wire (sandbox.proto), since Exec is currently one command per RPC. Worth considering only if the local-container variant proves insufficient — it is the option that would also serve a genuinely remote worker.
Suggested acceptance
- The extension can be given a fast tier and a stream tier independently.
- A container-exec persistent channel exists and passes the shared conformance battery (
test/conformance.ts) declaringproducer-side-cap. - A test pins fast-tier availability per transport, so a fourth transport cannot silently ship without one — the same discipline
transport.ts:24-32applies totruncated. - Measured: per-file-op latency before/after on the gRPC path, at a P6-style concurrency rung.
References
- P6 spec §3.1a, §5.2, §5.3, §8 — #244
- ADR-0024 · ST design
packages/k8s-sandbox/src/extension.ts:30-51,persistent-exec.ts:12,:84,harness/src/run-leaf.ts:786
🤖 Generated with Claude Code
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/k8s-sandbox/src/extension.ts:30-51 and persistent-exec.ts:12,84 to understand the separate transport tiers and the kubectl-specific pieces. Read test/conformance.ts and transport.ts:24-32 before deciding how the container-exec variant should declare its capabilities. Done means independent fast and stream overrides, a persistent container-exec channel passing the shared battery, a test pinning fast-tier availability, and the requested latency measurements.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- grpc, kubernetes, typescript
- Domain
- backend-api-design, infrastructure, performance, testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100