cmux-next iPhone: Home shows the Mac's Home list, not agent-chat rows

Merged
AZ
17d ago
+1687-452

User direction: "I don't like the fact that there are Home rows for agent chats, it's confusing. Home should be exact information parity with macOS."

What changed

The iPhone's Home now shows the chosen Mac's Home list, the same rows the Mac's Home sidebar draws, and no agent-chat rows.

  • Data comes from the Mac. The phone reads the Mac's home-inbox rows (the Chief home daemon, local owner) over the link's chief channel and draws them as they come (MacHomeFeed). Kind, name, order, pins, unread, unread mark and the Chief's typing are the Mac owner's, so the two lists can't drift. It re-reads on conversation-changed, conversation-typing and conversation-inbox-changed, as the Mac's HomeInboxSource does.

  • Same layout as the Mac. The pinned grid (the owner's pin order, up to 9), then every other conversation newest first. Each row shows its name, a Chief's tag (the Mac's name where the Mac says "This Mac"; "Main · Cloud" on the Cloud Chief), preview, time, unread dot and typing bubble.

  • Same controls. Search (no grid while searching, matching pins first), the Unread toggle (the Mac's only filter), compose. Long-press: Pin / Unpin, Mark as Read / Mark as Unread. These write the person's list state on the Mac's owner (conversation-inbox-op), so the Mac's Home changes too.

  • Agent chats stay in their workspaces (Workspaces tab), as on the Mac.

  • Mac filter. Home doesn't merge several Macs' lists, since that is a list no Mac shows. With more than one Mac, the bar's Mac menu chooses whose Home shows. It's the same setting as the Workspaces filter, and it links that Mac. There is no "All Macs" on Home.

  • cmux-mobile-host chief channel policy (risk: relay policy). It now allows:

    • home-inbox with owners: ["local"] only. The reply is narrowed to rows in the channel's scope: conversations between the owner and agents. Cloud rows never cross the link.
    • conversation-inbox-op with inbox.pin / inbox.mark_unread only. Fields are typed, the conversation must be in scope, and inbox.mute is refused.
    • conversation-inbox-changed events, only for user_local and only for conversations in scope.

    The actor is still the owner's trusted connection (user_local). No command-bearing params are accepted.

Parity table, inventory and stills: cmux-next-ios/verify/home-parity.md.

Phone (left) and the same Mac's Home (right), after Pin on the phone
pinned

Tests

Committed first (b447405053b5), then the fix:

  • Rust: cargo test -p cmux-mobile-host --lib chief_policy on mini-cmux15. home_inbox_and_list_state_stay_in_scope fails on the base (line 799, home-inbox refused) and passes on the head. All 9 chief_policy tests pass.
  • Swift: cmux-next-ios/verify/termqa/cmux_mobile_kit-test-ios.sh CmuxMobileChiefTests CmuxMobileShellTests on mini-cmux15, iOS 26.5 simulator. 71 tests in 24 suites pass, including the new MacHomeListTests and MacHomeFeedTests: order, grid of 9, search, Unread, the fake owner's reads, re-read on events, list-state writes, switching Mac. On the base these don't compile, because MacHomeFeed doesn't exist.

Observed / Not run

  • Observed: a live check over the real link with verify/multimac/home_parity_live.py.
    • Phone: a headless simulator running this branch's Demo build.
    • Mac: the hidden rig Mac on mini-cmux15, running this branch's cmux-mobile-host.
    • Path: WireGuard over TURN.
    • Home lists the Mac's Chief and the Cloud Chief, with no agent rows.
    • Pin, Mark as Unread, Mark as Read and Unpin from the phone each reached the Mac's own home-inbox, read on the Mac. The Mac window's stills show the same changes. PASS.
  • Observed: prepush-gate.py reported no new violations.
  • Not run: the user's phone (no TapKit). Group and DM rows on the phone: the channel scope never admits them.
  • Known gaps (in the parity table): Chief pet pictures show as avatar text on the phone. Mac-only menu items are not on the phone: Usage…, Archive Chief, group actions, Message Requests. The Cloud inbox's DMs and groups aren't shown, because the policy keeps Cloud rows off the link.

No capture: iOS app UI; cmux-ci capture covers the Mac app. The stills are in cmux-next-ios/verify/home-parity/.

Review

Fresh correctness subagent, three passes; findings and their resolution are in the PR comments.

Review (claude-subagent): SHIP at 1b22fe284ceb7138ac40114e9d41598a95fc89f9

Changelog

  • Changed: the iPhone's Home shows the same list as the Mac's Home (Chiefs and conversations, pins, unread) instead of agent-chat rows. Agent chats are in their workspaces.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Home on iPhone now shows the chosen Mac's Home list (its owner's home-inbox rows over the chief channel) instead of agent-chat rows, matching the Mac's Home sidebar exactly. Agent chats stay in their workspaces.

  • Rows are read from the Mac and re-read on conversation, typing, and inbox changes, so pins, unread, and order can't drift.
  • Same layout as the Mac, with review fixes: every pin is a tile (no cap), and the Unread toggle hides the grid.
  • Conversations opened from Home keep their outbox across tab switches and close only when the link or the Mac changes; a new link gives them a new session without a second open being started.
  • The Mac Chief's row is known from the owner's list before its session finds it.
  • Search, compose, Pin/Unpin, and Mark as Read/Unread write list state back to the Mac.
  • With more than one Mac, the Mac menu (same setting as Workspaces) chooses whose Home shows; there's no All Macs.

cmux-mobile-host chief channel policy

  • The channel now allows home-inbox (local rows only, narrowed to scope) and conversation-inbox-op (pin and mark-unread only) via the person's trusted connection, plus in-scope conversation-inbox-changed events.
  • Cloud rows never cross the link, inbox.mute is refused, and no command-bearing params are accepted.

Rust chief_policy tests and Swift MacHomeList/MacHomeFeed tests cover ordering, grid, search, unread, event re-reads, list-state writes, and Mac switching; a live check over WireGuard/TURN confirmed Home parity end to end.