arcbox-connectrpc is a temporary, tracking fork of
connectrpc/connect-rust. It exists
for one reason, and it is meant to be deleted.
ArcBox is on buffa 0.9.x. The newest published connectrpc is 0.8.1, which
requires buffa ^0.8.1 — the move to buffa 0.9 landed upstream in
#233 on 2026-07-20,
eighteen days after v0.8.1 was tagged, and upstream has not cut a release since.
So the only connect-rust that works with ArcBox is unreleased. Depending on a
git revision is fine for building ArcBox, but a crate that does so cannot
express itself on crates.io: cargo publish drops the git source and keeps the
version requirement, which would publish a dependency graph nobody can
resolve. That blocks publishing the ArcBox Rust SDK.
This fork exists to put that unreleased code on crates.io under a name we own, so the SDK can ship. Nothing more.
- Published package names are prefixed:
connectrpc→arcbox-connectrpc, and likewise for-build,-codegen,-health,-reflection. - Each crate carries
[lib] name = "<upstream name>", so the library target keeps its upstream name. Everyuse connectrpc::…— in the 162 code paths the code generator emits, in doc examples, in consumers — resolves unchanged. repositorymetadata points here;NOTICErecords the fork point.
This part is confined to Cargo.toml files. The smaller the delta, the cheaper
the rebase and the cheaper the exit.
Cherry-picked with -x, one commit each, so git rebase upstream/main drops
them by patch-id once upstream merges them unchanged — and conflicts loudly if
upstream revises them. Every one is unreviewed upstream: taking them is a bet
that review will not change their shape.
| PR | Why ArcBox needs it |
|---|---|
| #238 | Dormant today — kept knowingly. It reclassifies post-deadline transport failures as deadline_exceeded, which would matter to the SDK's DeadlineExceeded → ErrorKind::Timeout mapping. But nothing in ArcBox sets CallOptions.timeout, and client_deadline() derives from that alone, so the deadline is always None and the classification never changes. Taken because it is inert and because #262's merge is built on the body-read helper it introduces; it does not meet the "named symptom" bar on its own. Its one live effect is the message wording, handled in arcbox-cli. |
| #262 | Terminal errors dropped response metadata. The SDK's typed errors (code(), suggestion()) are decoded from those details, so they silently degraded. |
| #240 | Client transport failures discarded their source() chain, costing diagnostics the SDK cannot reconstruct. |
| #259 | A descriptor set missing an import generated references to nonexistent types. ArcBox feeds connectrpc-build a descriptor set it builds itself; this turns a silent miscompile into an error. |
Deliberately not absorbed: #260 and #261 change the public API (setter
renames, hidden Limits fields, removed compression surface) — writing call
sites against an API that has not survived review would mean migrating twice.
#264 and #265 rework the decode hot path and come from outside contributors.
#256, #258, #266 and #236 cover ground ArcBox does not exercise.
#238 and #262 conflict with each other: both rewrite the same two
collect_body_bounded call sites, one adding a deadline argument, the other
attaching metadata. Resolved by taking both — see that commit. Upstream will
face the same merge.
Reviewing the four before absorbing them (the two agents in .claude/agents/,
as CLAUDE.md prescribes) turned up two defects. Both are fixed; neither was
caused by the cherry-picking.
- #262 delivers its headline on three of five call sites. The non-2xx
branches of
make_server_streamandparse_connect_client_stream_responsedropped the response headers when reading the error body failed. Fixed here, with tests confirmed to fail without the fix. Carried as a fork-local patch — drop it if upstream lands an equivalent. - #238 renames an error message ArcBox pattern-matches on.
abctl machine execidentifies a dropped connection bymessage.starts_with("error reading response body:"), which this renames to "failed to read response body". Nothing would have failed: the CLI would have silently stopped reporting lost connections, and its regression test hand-builds the old string so it stays green. Fixed in ArcBox, not here — matching both spellings.
The hand-merge of #238 and #262 was reviewed specifically and found correct:
with_response_metadata only writes the response_headers/trailers fields
and never touches code, so a deadline_exceeded classification survives it.
server::tests::max_connection_idle_reaps_quiet_connection is timing-dependent
and fails intermittently — 3 of 4 runs on pristine upstream/main at the fork
point, so it is not ours. Do not read it as a rebase regression.
Alias it back to the upstream name, so no source file has to know:
connectrpc = { package = "arcbox-connectrpc", version = "0.8.1" }Switching back to upstream is then deleting package = "arcbox-connectrpc",
from that line. Aliasing is optional — [lib] name already makes
use connectrpc::… work — but keeping it makes the exit a one-line change.
Carrying an upstream pull request ahead of its release is a bet that review will not reshape it. Lose that bet and ArcBox's call sites are written against an API that never shipped, and the migration happens twice. So the gate is:
- It has to be reviewed. An unreviewed pull request is a proposal, not a change. Where upstream review is the thing we are waiting on, we do the review ourselves — and post it upstream, because a downstream user's review is worth more to that queue than a nudge is.
- ArcBox has to need it. Not "looks useful": a named symptom in ArcBox that the change removes. Anything else is maintenance we pay for nothing.
- It must not move the public API. Renames, removals, and signature changes are the ones that cost twice. Correctness fixes behind a stable surface are the cheap ones.
- It gets cherry-picked with
-x, one commit each, so a rebase can drop it by patch-id the moment upstream merges it unchanged.
Improvements to the library go to connectrpc/connect-rust, not here.
Do not open those pull requests from this repository. GitHub has this repo registered as a fork of connect-rust, so a pull request opened from a branch pushed here defaults its base to upstream — which is how internal work reaches another project by accident. Keep the two roles apart: this repository consumes, a separate fork contributes.
GitHub will not let one organisation fork the same upstream twice, so the
contribution fork lives outside arcboxlabs:
$ gh repo fork connectrpc/connect-rust --clone --remote
$ cd connect-rust && git checkout -b fix/<thing>Upstream requires a DCO sign-off (git commit -s), keeps changes under 250 net
lines excluding tests and generated code, and wants a .changes/unreleased/
fragment for anything user-visible. Its CLAUDE.md also asks for two review
agents to run over the diff before committing — they live in .claude/agents/
and are worth running here too.
$ git fetch upstream
$ git rebase upstream/main # the delta is Cargo.toml-only; conflicts are rareUpstream is landing wire-protocol correctness fixes continuously — envelope flag validation, gRPC-Web trailer gating, trailers-only error metadata, cancellation safety. Falling behind on those is the standing cost of this fork, and the reason it should not outlive its purpose.
When upstream publishes a release containing #233, every consumer drops the
package = … alias, this repository is archived, and the crates are yanked or
left to rot. The live question upstream is not "when is 0.9.0 ready" — the buffa
move is already on main — but whether 0.9.0 can be cut from main now, with
the API-cleanup batch in
#256–#262 deferred to
0.10.0. If that happens, this fork is obsolete immediately.