12 KiB
Review 010 — Stub sweep of the published surface (0.8.1)
Status
Open — filed 2026-10-13. Triggered by a downstream finding: alkblobs'
ops-put task hits channel:pub_open_not_implemented when its Sink op
carrying the channel_open marker is invoked, exactly as the code
comments predict. The downstream project is paused on this.
Policy context: shipping stubs to crates.io is now a hard failure per
the repo owner's ruling. Any handler that registers successfully and
returns an error of the form *:not_implemented on every invocation
is a bug, not a documented limitation. The state tracked in OQ-39,
OQ-40, and the C-08 blocker comment is re-classed from "deferred
open question" to "unpublishable stub" by this review. The rationale
previously used to justify shipping them (loud failure, OQ tracking)
was reviewed and rejected: a loud stub is still a stub, and the only
accepted endpoint is implement-or-stop-advertising before the next
published version.
Full sweep of src/ performed: no TODO/FIXME/todo!/
unimplemented! markers exist anywhere; the four findings below are
the complete set of registered-but-always-failing handlers. No other
module (gateway, client, protocol, core) contains an
invocation-time unimplemented path.
Scope
Every handler registered on a public surface — OperationRegistry
(local or per-connection overlay), services/list discovery output,
relay openables — that cannot serve its declared operation type.
Evidence includes pinned tests that assert the stub behavior:
make_open_handler_sink_returns_not_implemented(src/channels/operations.rs:1695)resources_subscribe_handler_returns_not_implementedandresources_subscribe_handler_not_implemented_even_when_empty(src/channels/operations.rs:1303, 1322)control_handler_success_path_returns_not_implemented(src/channels/operations.rs:1439)- relay_tests.rs:113 asserts
pub_open_not_implemented
Findings continue the review numbering with prefix S (stub).
S-01 [critical] Pub-typed open wrapper: registered, advertised, returns INTERNAL on every invocation
Location: make_open_handler_sink, src/channels/operations.rs:1158-1199.
Wired into ChannelCore::register_openable_with_establisher at
src/channels/operations.rs:682 (OperationType::Pub => HandlerKind::Sink(make_open_handler_sink(...))).
Behavior: registration for a Pub-typed open op succeeds. The
spec enters OperationRegistry with the channel_open marker and a
publish_schema, so it is discoverable via services/list /
services/schema and selectable by a consumer's open flow. The first
invocation fails with channel:pub_open_not_implemented: Pub-typed open ops are not yet implemented (requires channel-adoption path, C-08/Unit 5).
Exposure window: introduced 2026-08-13 (commit 8066d08), four
days before the first published version — this stub has shipped in
every release from v0.1.0 through 0.8.1, nine published versions.
Why this one is inexcusable rather than merely incomplete: the entire Sink stack ADR-046/047 call for is implemented and tested in the same crate:
- wire event
call.published(src/protocol/wire.rs:17) - serving-loop sink dispatch, chunk feeding,
publish_schemaper-chunk validation (src/protocol/dispatch.rs:607-643, 1002, 1225) - registry
resolve_sink_handler/invoke_sink(src/registry/registration.rs:428-509) - client-side sink forwarding, initiator→responder
call.publishedstreaming (src/client/from_call.rs:478-496) - gateway sink dispatch (src/gateway/dispatch.rs:160-550)
- discovery advertises per-chunk
publish_schemaon the open op's spec (src/registry/discovery.rs:178)
The only missing piece is the open-op wrapper itself. The stub's
textual justification (data plane must ride the adopted channel's
BiStream, gated on the C-08 adoption path) is in tension with
ADR-047 §1's own semantics, which define the open-op Pub case as
data flowing over channel 0's call plane via call.published —
precisely what the implemented stack does. The comment even admits
the design question is unresolved ("whether that data flows through
the allocated channel's BiStream ... or is consumed directly by the
OpenHandler"), i.e. the C-09-style blocker was asserted, not
established. This is hedges-cured-as-code.
Downstream impact: alkblobs ops-put (/workspace/@alkdev/alkblobs/tasks/ops-put.md)
depends on this exact shape (blobs/put as a Sink spec with the
channel_open marker); the task is paused on the decision. ADR-051
§6 documents the same gap from the relay side, where registration at
least fails loudly.
Remediation options (pick one before the next release):
- Implement the wrapper — allocate the channel id, run the
establishment phase (reply fields carry the offer ack, per ADR-047
§1 and ops-put's acceptance criteria), hand the
OpenHandlerthePublishStreamalready produced by the serving loop along with the channel'sConnection. All plumbing exists; this is wrapper glue, plus deciding the OpenHandler-reads-channel-vs-reads-PublishStream question in an amended ADR-047. - Reject at registration — return an error from
register_openable_with_establisherforOperationType::Pub, mirroringRelayError::PubTypedOpen(src/channels/relay.rs:147-156), which already follows the correct fail-fast pattern. The op never exists, so nothing is advertised that cannot serve. ops-put then re-plans its establishment ack onto a plain Sink op without the marker, or waits for option 1.
Option 2 is the honest minimum for the next release; option 1 unblocks ops-put directly.
S-02 [critical] channel/control: ADR-037 op registered on every channels connection, always fails
Location: make_control_handler, src/channels/operations.rs:242-272.
Registered publicly by ChannelOps::register_on (src/channels/operations.rs:67),
spec exported (channel_control_spec, line 124). OQ-39; and
docs/architecture/channel-operations.md §"channel/control —
out-of-band control on channel 0" documents the request shape as if
the op works.
Behavior: validates channel_id, checks manager.has_channel,
then returns channel:control_not_implemented unconditionally. The
channel-existence check is the only code that does anything — which
perversely means the stub returns not found for unknown channels
but not implemented for real ones.
Exposure window: shipped since the ADR-037 surface landed (0.1.0-era); nine published versions.
Remediation: implement the control-handle surface (the design is
specified in OQ-39: ALPN-crate-registered per-channel control
callbacks, channels-layer registry keyed by channel_id), or remove
channel_control_spec from ChannelOps::register_on until a
consumer needs it. Publishing an op that exists on the wire's
discovery surface but cannot run is the failure mode being outlawed.
S-03 [critical] channel/resources/subscribe: ADR-037 §6 streaming op registered, always fails with a one-shot error
Location: make_resources_subscribe_handler,
src/channels/operations.rs:283-297. Registered by
ChannelOps::register_on; spec exported (line 146). OQ-40.
Behavior: the StreamingHandler emits exactly one
channel:resources_not_implemented error envelope — a fake stream
that terminates after one error, rather than a snapshot or a live
subscription. The doc comment says "callers fail loudly rather than
receiving a fake one-shot snapshot", but the loud failure is the
fake one-shot artifact.
Exposure window: same as S-02.
Downstream note: OQ-40 self-declares this "load-bearing for alktunnels' discovery UI"; a hub or dashboard consumer that discovers this op gets a capability that does not exist.
Remediation: implement the aggregated-enumerator subscription
(ADR-047 §6), or drop the op from ChannelOps::register_on (the
static half — OperationSpec.description on services/list —
remains available, as OQ-40 itself records).
S-04 [major] Peer-announced Sub/Pub ops install invocation-failing stubs on connection overlays
Location: forwarding_stub_for_announced_op,
src/registry/op_register.rs:215-229, called from op_register_handler
(line 184).
Behavior: when a peer announces a Sub- or Pub-typed spec via
op/register, the handler is accepted and registered on the
connection overlay (HandlerKind::Once) with a body that returns
INVALID_OPERATION_TYPE on every invocation. The spec stays
discoverable on the peer-keyed overlay (services/list-peers,
provenance FromCall), and a composing handler that resolves through
ctx.env.invoke hits the error instead of the real op.
Unlike S-01 through S-03 this path has a documented contract
rationale (nested composition is request/response-only; streaming/
sink forwarding should ride from_call in the other direction), and
review 005 discusses the shape. Reviewed and re-classed: the
rationale may justify not implementing nested sink forwarding, but
it does not justify accepting and advertising the announcement. The
observable behavior is identical to a stub.
Remediation: reject the announcement of Sub/Pub op types at
op/register time with a typed error (registration-time loudness, no
overlay entry), or wire them through the existing forwarding shapes
(make_streaming_forwarding_handler / make_sink_forwarding_handler
already exist in src/client/from_call.rs). Minimum-bar is the
rejection.
Non-findings (checked and cleared)
The sweep had to distinguish real stubs from deferred-by-design boundaries and test scaffolding. For the record:
sink_empty_connection(src/protocol/test_support.rs) — test-only helper; every use is under#[cfg(test)]. Not a stub.src/channels/adapter.rs"stream header interpretation deferred to the downstream ALPN crate (OQ-41)" — this is ADR-035's design boundary (the channels layer does not interpret stream contents), not missing functionality on a registered surface.- Early-arrival chunk parking (src/channels/manager.rs:485) — implemented behavior, the log text merely says "not yet adopted".
channels//subsilent-stub shape (review 009 audit N-4) — already fixed in 0.8.0; listed here as the precedent for the correct remedy (loud failure at the boundary), though see the policy note below since even loud invocation-time failure is no longer sufficient for registered surfaces.
Verdict
Four stubs shipped across nine published versions, three of them
reachable by any consumer doing routine discovery. The pinned tests
demonstrate the team knew, documented, tracked open questions for
each, and published anyway. Per the ruling, none may be present in
the next published version. The relay's PubTypedOpen /
UnmarkedSpec errors are the house pattern to generalize: reject
at registration, never at invocation.
Required actions before next release
- Resolve S-01/S-02/S-03 each as implement-or-stop-advertising.
Whichever path is chosen, no
*:not_implementederror string may remain reachable insrc/. - Resolve S-04 at minimum by rejecting Sub/Pub announcements at
op/register; forwarding-through is the better fix and is mechanically trivial given the existing from_call shapes. - Add a guard so this class cannot recur: a test that greps the
source tree for
not_implemented(and a registration-time invariant that a registeredHandlerKindmust be capable of succeeding), wired into the release checklist in AGENTS.md. - Update OQ-39/OQ-40/C-08 entries and channel-operations.md to match the post-fix reality; the "current stub" language in both is now invalid documentation of shipped behavior.
- Amend ADR-047 with the Pub open-op data-plane decision (if
implementing) or mark
channels/<alpn>/pubas not-provided until implemented (if rejecting); either way close the gap between the ADR table (which listschannels/<alpn>/pubas a supported shape) and the code.