cmux NEXT: a Chief's silent-turn done marker shows no bubble and is no thread reply

AU
10d ago
+160-2

What

When a Chief turn says nothing but closes open work (for example, a subagent's report arrives and the Chief only calls sleep), optchat-chief posts a done marker: a message under the turn key (turn:optchat:<n>:<stamp>) whose only part is a work part with status done, no preview, named by the turn's acpmux session (optchat-<home id>-<n>). Its answers close the messages the turn answered.

It showed up in Home as an incoming bubble saying only optchat-b902d10e-816, under a faded quote of the user's earlier message, which looked like a duplicate send. The marker was also posted in the thread of the message it closed, and the daemon counts every message of a thread as a reply (conversation_threads.rs stats). So the user's message got a thread reply that opened to nothing.

Fix

  • Home: feat-cmux-next already landed a fix of its own, f3abfd2c4c42 (WorkRef.shownText: a work part whose only text is its session id shows nothing). It draws no bubble for the marker, ends the turn's stream and lets the read cursor reach it. This PR used to add a second filter for that. On the current base that filter is redundant, so it is dropped. The PR keeps its real-view regression test, updated to the base's rule.
  • Chief side (optchat-chief brain/turns.rs): the done marker is posted at the top level, not in the thread of the message it closes. It has no thread_root and no reply_to. Its answers still close the work. The reply ledger and the cmux chief turn waiter read answers, not the thread.

Tests

  • optchat-chief tests/done_marker.rs a_done_marker_closes_its_message_outside_that_messages_thread, run on rbx (cargo test --test done_marker):
    • Red at 2a0087ef854e (test only): no reply in msg_1's thread, left Some("msg_1"), right None.
    • Green at 6b1d7baf9396 and later, with every optchat-chief test (cargo test --tests) passing.
  • HomeDoneMarkerTests runs on the real MessagesLabHomeView over a real HomeStore (HomeChatRig). It checks that the marker, posted at the top level (current Chief) or in the thread of the message it closes (older Chief), shows no bubble, that the turn's stream ends, and that the read cursor reaches the marker's seq. A titled subagent card still shows.
    • Red on the old base ae0085bef4b0 (step 9b21f8fb): rig.bubbles() → ["⟨asked: launch the latest dev build", "⟨optchat-b902d10e-816"], the reported bug.
    • On the current base source (fleet step hdm-probe-82c08b3d): the bubble, stream and read-cursor checks pass. Only two expectations of the old test fail there, both of which the base rule replaced (the content-free row stays in the store, and an untitled subagent card shows nothing). The test now matches the base.

Observed / Not run

  • Observed: the rbx runs above. Fleet hdm-core-ce95cbb1 passed CmuxHomeCoreTests at the merged head ce95cbb. Fleet hdm-head-ce95cbb1 passed HomeWorkMarkerTests, HomeTimelineOrderTests and HomeTimelinePropertyTests. At the final head 2bb7788e242e, fleet hdm-head-2bb7788e passed HomeDoneMarkerTests (threaded and unthreaded marker), HomeWorkMarkerTests and HomeTimelineOrderTests, and rbx passed done_marker.
  • Not run: a tagged app build or dogfood, and iOS.

Follow-ups, out of scope here: iOS ConversationViewController and the Rust inbox preview in cmux-conversation home.rs do not use shownText.

Changelog

  • Fixed: a Chief's silent turn no longer shows a bubble with only its session name, or adds an empty reply to your message's thread.

risk:normal

🤖 Generated with Claude Code