[v0.1.x/Proto] Give stream opening one phase-correct helper instead of three hand-rolled sequences #199

Closed
opened 2026-09-07 21:21:37 +09:00 by natsukium · 0 comments
Owner

What

Give the three hand-rolled "open a stream" call sites one shared, phase-correct helper so a caller cannot send a StreamOpener arm without its envelope. felis bridge already has a private open_stream(&msg) (crates/felis-cli/src/cli_bridge.rs); cli_notifications.rs (sessions notifications subscribe) and cli_sessions.rs (rows / search streams) each re-derive the same sequence (allocate the next unopened stream id, send_correlated, register the stream with the driver) with the ordering rule repeated inline.

Why it is not part of #196

#196 makes CheckedFrame::encode refuse a StreamOpener sent without an envelope, so the mistake becomes a typed local error instead of a silent EOF. It does not give callers the right way to do it. That helper cannot be a single generic Connection::open_stream: Driver::observing() is Observer-side and Phase::Setup-only (it debug-asserts on the phase), while Region::Rows and Search::Query open streams from Attached. The shape is therefore per surface (or a subscribe_notifications verb on Connection beside the existing attached-phase openers), and hoisting the bridge helper touches three CLI call sites with a control-surfaces/cli doc cascade of its own.

Acceptance criteria

  • One helper (or one per phase) in felis-client-core owns "next unopened stream id + send_correlated + register"; cli_bridge.rs, cli_notifications.rs, and cli_sessions.rs call it and the inline ordering comments disappear.
  • A test proves the helper allocates ids in the driver's expected order from both Setup (Observer) and Attached, and that the raw sequence is no longer reachable from the CLI crate.
  • Docs cascade: docs/reference/ipc.md names the helper where it describes stream opening from the client side; no wire, CLI, or config change, so no CHANGELOG.

Split from #196.

## What Give the three hand-rolled "open a stream" call sites one shared, phase-correct helper so a caller cannot send a `StreamOpener` arm without its envelope. `felis bridge` already has a private `open_stream(&msg)` (`crates/felis-cli/src/cli_bridge.rs`); `cli_notifications.rs` (`sessions notifications subscribe`) and `cli_sessions.rs` (rows / search streams) each re-derive the same sequence (allocate the next unopened stream id, `send_correlated`, register the stream with the driver) with the ordering rule repeated inline. ## Why it is not part of #196 #196 makes `CheckedFrame::encode` refuse a `StreamOpener` sent without an envelope, so the mistake becomes a typed local error instead of a silent EOF. It does not give callers the right way to do it. That helper cannot be a single generic `Connection::open_stream`: `Driver::observing()` is Observer-side and `Phase::Setup`-only (it debug-asserts on the phase), while `Region::Rows` and `Search::Query` open streams from `Attached`. The shape is therefore per surface (or a `subscribe_notifications` verb on `Connection` beside the existing attached-phase openers), and hoisting the bridge helper touches three CLI call sites with a control-surfaces/cli doc cascade of its own. ## Acceptance criteria - [ ] One helper (or one per phase) in `felis-client-core` owns "next unopened stream id + `send_correlated` + register"; `cli_bridge.rs`, `cli_notifications.rs`, and `cli_sessions.rs` call it and the inline ordering comments disappear. - [ ] A test proves the helper allocates ids in the driver's expected order from both `Setup` (Observer) and `Attached`, and that the raw sequence is no longer reachable from the CLI crate. - [ ] Docs cascade: `docs/reference/ipc.md` names the helper where it describes stream opening from the client side; no wire, CLI, or config change, so no CHANGELOG. Split from #196.
Sign in to join this conversation.
No description provided.