Skip to content

omachat-ctl cannot consume daemon events; the Subscribe/Event path has no client #223

Description

@bulters

Summary

The daemon can push events to a subscribed IPC client, but nothing in the repository can consume them, and the only client that exists fails when it happens.

  • Command::Subscribe { topics: Vec<Topic> } and Event { version, sequence, topic, payload } are defined in crates/omachat-proto/src/ipc.rs, with topics Status, Conversations, Messages, Presence, Delivery.
  • serve_client in crates/omachatd/src/ipc_server.rs (the event = event_receiver.recv(), if subscribed arm) encodes Event lines onto the same stream that carries Response lines.
  • crates/omachat-ctl/src/lib.rs contains no Subscribe or Event handling. Client::request writes one line and reads exactly one line, deserializing it as Response and then checking response.id for correlation.

Event carries neither id nor outcome, so the first event pushed to a subscribed client fails serde_json::from_slice::<Response> and surfaces as ClientError::MalformedResponse. Response correlation is also offset by one line from that point on.

Why it matters

UiModel in omachat-tui already carries conversations, messages, unread counts and delivery state, but nothing populates them — Subscribe/Event is the only source that could. OC-024 (#25) is the first work that needs live topics and will meet this immediately.

Suggested extension

Give omachat-ctl a demultiplexing read path:

  • separate the socket read loop from request(), so every inbound line is classified once
  • correlate Response by id back to the pending request, and deliver Event to a receiver the caller owns
  • keep the existing MAX_LINE_BYTES bound and apply the version check to both shapes
  • expose something along the lines of Client::subscribe(topics) -> Receiver<Event>

Happy to implement this if the shape sounds right — I'd rather check the intended boundary first, since it touches the client contract.

Evidence

  • crates/omachat-proto/src/ipc.rsCommand::Subscribe, Topic, Event
  • crates/omachatd/src/ipc_server.rs:243 — the event write arm
  • crates/omachat-ctl/src/lib.rsrequest() / read_line(), no event handling
  • crates/omachat-proto/tests/ipc.rs — covers the codec, not the client read path

Out of scope

Wiring the TUI to live topics (OC-024 / #25), and the OC-023 (#24) shell work itself.

Maintainer reconciliation — 2026-09-04

Next closure evidence/work: Implement a single bounded demultiplexing reader, response-ID correlation and event receiver; test interleaving, versions, disconnects and backpressure. Coordinate protocol changes with #226.

Baseline reviewed: main 87c3bcb7d65e3e2ab8ae317694b751f8efe9a8ed. Implementation presence is not a live conformance claim.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions