Where Feed data comes from, and where it lives
Feed is a view of agent activity recorded by the Mac. The phone fetches and combines that activity from its connected Macs. Notifications are also a Feed input. The Notifications tab keeps its own read and dismissal surface, while Feed projects the same durable notification records alongside agent activity.
Direct answers
Rows can come from notifications too
Hooks, provider plugins, wrapper telemetry, Codex Teams approvals, and the notification history store feed the timeline. A notification creates a Feed row with its notification UUID as the event identity. [1–4]
Incoming rows are saved on disk
The Mac app keeps a live store and appends incoming items and later mutations to ~/.cmuxterm/workstream.jsonl. Startup collapses repeated JSONL rows to the latest state for each event. [5–7]
A live mirror backed by Mac state
The phone refetches the authoritative rows after restart. Reply text and the Replied marker come back from the Mac because the reply is stored on the event record; local triage remains device-specific. Sign-in and pairing have their own saved state. [9–10]
Follow an event
Choose a path. These controls illustrate the inspected implementation; they do not send commands to an agent.
Structured events
Native hooks, plugins, wrappers, or the Codex Teams app-server bridge.
feed.pushFeedCoordinator + WorkstreamStore
Validate the target, create a row, retain content, and increase the revision.
workstream.jsonlFeed snapshot and UI
Fetch from each capable Mac, combine rows, and route actions to their owner.
feed.list · feed.textnotification.feed.list and its own Mac history store. Agent Feed reads feed.list, which now combines Workstream rows with those durable notification records. Apple push delivery is only a delivery mechanism; the Mac history is authoritative. [3, 8, 11]The phone communicates with the owning Mac over an authenticated connection. The transport chooses its direct or relay route. Authentication, discovery, and push can involve infrastructure; the inspected Feed path does not use a cloud database as its authoritative row store. “Mac-owned data” does not mean every network connection is infrastructure-free.
What can produce a Feed row?
| Producer | What enters Feed | Limit |
|---|---|---|
Agent hooks through cmux hooks feed | Permission, question, plan, tool, prompt, session, and stop events. | Only events the provider integration emits. Installing cmux does not create a complete transcript for every agent. |
| Provider wrappers and plugins | Wrapper telemetry adds session/prompt/stop activity. OpenCode’s plugin sends the same socket protocol; Pi supplies lifecycle/tool telemetry. | The wrapper telemetry send is best effort, with short timeouts and swallowed errors. It has no durable Feed outbox on that path. |
| Codex Teams app-server watcher | Actionable command/file approval requests after Codex asks for user approval. | Regular Codex hook permission events remain nonblocking telemetry. They do not imply this approval bridge is active. |
| Other supported event producers | The local socket accepts validated feed.push events; remote workspace integration can forward them. | Admission and live target checks still apply. Provider parity is not established by a shared wire format. |
| Notification history / Apple push | Notification history is persisted on the Mac, and Feed projects each retained record. | The notification UUID is the Feed event ID. Push delivery can be missed; a later feed.list refresh reads the Mac history. |
Source trace: [1–4]. Provider hook ingestion was checked for Codex, Claude, OpenCode, Pi, Cursor, Grok, and Gemini. This is not proof that every provider supports the same permission/question/plan features.
The phone deliberately hides noise: standalone session starts/ends, user prompts, routine tool calls, and successful tool results. Prompt text can appear as context on another row. Stops, permissions, questions, plans, assistant messages, and failed tool results pass the host filter; the UI further shapes the presentation. [8]
What is persisted?
| Data | Mac | Phone | Consequence |
|---|---|---|---|
| Incoming Feed item and retained message | Disk + memory. JSONL append is asynchronous; write errors are ignored. | In-memory snapshot of bounded previews. | Phone restart needs a Mac fetch. Abrupt Mac exit can lose a queued write; there is no durable-write acknowledgement on this path. |
| Permission/plan/question resolution and expiry | Disk + memory. Each mutation appends the latest WorkstreamItem version, and startup collapses rows by event UUID. | Updated mirror while connected. | Restart restores the latest decision or expiry. Waiting hook decisions remain process-local. |
| Terminal reply text + Replied marker | Text is pasted into the terminal, then stored on the exact WorkstreamItem named by feed_event_id when submission succeeds. The append-only record is replayed on startup. | Rehydrated from the Mac's durable event record; no phone disk cache is needed for correctness. | Every reply is tied to one event UUID, so a refresh or restart cannot move the Replied marker to another row. |
| Done / Needs Input override | No update to authoritative pending state. | Local memory only. | This is personal triage, not an answer to an agent request. |
| Full-text reader contents | Reads the retained item in the current store snapshot. | Loaded into sheet memory, no dedicated persisted cache. | New reads need the owning Mac. Disk history outside the loaded snapshot is not fetched automatically. |
Retention and limits
- Mac startup restores the latest 300 persisted items.
- Live ingestion caps the working store at 2,000 items. The separate Mac history loader can load older pages.
- Mobile
feed.listreturns at most 200 visible items per Mac, fewer if the response-size limit requires it. - The phone combines up to 400 rows. There is no mobile older-history cursor here.
- Full text uses 16 KiB pages with an 8 MiB phone limit.
- The disk log has no automatic retention limit in this implementation; explicit Feed clear removes it.
Storage ownership and privacy
The default log path is scoped to the local OS user. It is not separated by app tag or Stack account, so development instances can restore history from the same file.
The persistence redactor covers tool/permission payloads. It does not generally redact stop response text or conversational context. Treat the retained content as potentially sensitive local data.
These are code findings, not a completed privacy or crash-recovery audit. Retention, account switching, deletion, and shared-file behavior need explicit release decisions. [5–7]
What happens when something disconnects?
Expected behavior inferred from the referenced state and persistence code. The live phone authentication/reconnect gate passed; these restart and loss scenarios have not all been exercised end to end.
Decisions before shipping
The implemented design is a useful live activity surface. A durable, cross-device conversation history would require additional work. The items below are findings and proposed acceptance criteria, not silently added implementation scope.
| Decision / gap | Current evidence | Proposed acceptance criterion |
|---|---|---|
| Durable decisions and replies | Incoming items, resolution mutations, expiry, and terminal reply markers persist on the Mac event record. [6, 9–10] | Restart both apps after a reply/approval. The row must preserve the correct result and cannot offer a duplicate action. Choose the authoritative persisted record. |
| Reliable delivery and deduplication | Best-effort telemetry can be lost. Stop deduplication uses a two-second match on device, workstream, provider, and reason, without the instance tag. [2, 10] | Define stable provider event/turn IDs, retry guarantees, and acknowledgement. Repeated delivery produces one row; distinct rapid turns and sibling tags stay distinct. |
| Meaning of Replied | submitted: true confirms terminal submission. It is not a provider/model acknowledgement. [10] | Either label this as submitted, or add evidence that the targeted agent accepted a new turn. Verify with each supported provider. |
| Failure recovery | The composer closes on Send; failures in the current terminal reply path are logged without a visible retry flow. [14] | Preserve the draft and explain failed delivery. A retry after partial paste must not type the reply twice. |
| History and ownership | No phone disk cache or mobile history paging. Mac log is unbounded and shares its OS-user path. [5–10] | Choose offline reading expectations, retention, cleanup, account/tag separation, and how old unavailable sessions are presented. |
| Transport compatibility | Full-text feature uses the existing feed.v1 capability; an older capable Mac can lack feed.text. [12] | Version or negotiate the new read method, or require coordinated app updates. Older hosts currently produce a read failure rather than full text. |
| Release integration and verification | Full-text checks pass; newer main has conflicts and broader inherited checks are not green. | Reconcile main, run the required checks, and verify real phone replies, deduplication, failure feedback, and restart recovery before merge/release. |
What has been verified this round?
Reading UI
The hosted iPhone test verifies Markdown headings, lists, emphasis, links, and code in row previews and the full-text reader. It also checks inline expansion only for long text, retry, final paragraph, Close, Open, and Feed search. Inspected screenshots use test data.
UI test and attachmentsContent and routing
Focused tests cover full text, Unicode pages, exact Mac ownership, authorization, Feed matching, and valid/deleted workspace or tab targets. Built CLI hook checks preserve complete supplied text for seven providers.
Focused test runCurrent installation
The matching fmdblk apps at 20b38a26d7d are installed and signed in as aziz@manaflow.ai. The phone reconnects using its saved sign-in in 7,088 ms. The nearby simulator is updated and connected.
The spacing screen test catches the original 76-point gap and passes after the fix. The production Feed preview was also inspected on iOS 27. Live physical-phone Feed interaction remains a separate check.
The UI workflow’s separate conventions check remains red on inherited violations. The search coordinator unit run was blocked by an unrelated missing GhosttySurfaceWorkQueue symbol in the terminal test target; the production Feed search UI check passed. Mac download metadata and the older branch’s bundle-ID build setting needed task-local packaging corrections. iOS compiler output was isolated by tag/source after a stale Iroh header cache failed; the retry passed both packages. The existing task simulator was updated without booting another device. Physical-phone installation and a fresh saved-auth reconnect remain pending.
Code references
Links are pinned to the inspected revision. The session inventory tracks accepted scope separately from the proposed shipping work.