Skip to content

Give tab attention persistent request identity and guarded clearing - #27497

Merged
teamleaderleo merged 5 commits into
feat-cmux-nextfrom
lane/attention-request-identity
Oct 29, 2026
Merged

teamleaderleo merged 5 commits into
feat-cmux-nextfrom
lane/attention-request-identity

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Two identical attention requests can share the same millisecond timestamp. A stale acknowledgement can then clear a replacement mark. Each new mark now carries a persisted, owner-issued opaque request_id, independent of wall time and row lifetime.

tab-attention-request-id-v1 advertises transactional compare-and-clear: tab.update accepts attention:null with the captured attention_request_id. A stale token is a successful no-op returning the current tab. Invalid guards fail validation. The existing unconditional clear remains compatible for legacy callers; new consumers must require the capability and token and never fall back to timestamp matching or unconditional clearing.

Valid pre-token marks acquire an identity once on store open. The JSON addition remains readable by older builds. Risk: upgrading assigns new identities to legacy marks; clients must invalidate cached tokenless actions. No Swift or FFI ABI change is included. Native consumers require the daemon release advertising this capability. The derived app FFI input list excludes all changed paths, so no app FFI release or binary-target repin applies.

Validation at final head f5502f81b211965630e621060a4d741eea02db9d: Linux run 40954356328 passed the workspace/all-targets compile, all 10 attention tests, resource boundary/spec inventory, both Rust adapter clippy and test commands, MCP cancellation, and all 107 release-notary guards. Independent Sol high whole-diff review and primary integration inspection both returned SHIP at that exact head.

The only focused failure is workspace formatting in two unchanged base files (surface_parity.rs and resource/wire_name_tests.rs). Focused baseline 40956888289 runs the same command on base 6fbb57eb3ff3da62aa1f2443db0213782c1e2c88 and reproduces those exact diffs. It also reproduces the hosted No-SwiftUI diagnostics for HomeChatColorsPanel.swift and HomeChatColorsView.swift; the other continuing checks execute. Neither failure comes from this PR. No native UI or FFI artifact changes are included.

Agent session: agent session

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')/
test_live_raw_v12_layout_and_history_contracts_are_exact (test_ir.IrTests.test_live_raw
_v12_layout_and_history_contracts_are_exact) (command='new-pane-right')
View Logs

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

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 2d04c81: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr27497 -f ref=lane/attention-request-identity -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 6fbb57e; does not block

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-yrhzt0 created for this PR by the cmux coordinator.

@teamleaderleo
teamleaderleo marked this pull request as ready for review October 29, 2026 18:54
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

The conformance adapters' --locked base red is fixed on feat-cmux-next by #27517 (merge c9e4f75); both adapter jobs pass there. Re-running those jobs after the next base update clears them.

@teamleaderleo
teamleaderleo merged commit c587e68 into feat-cmux-next Oct 29, 2026
166 of 169 checks passed
@teamleaderleo
teamleaderleo deleted the lane/attention-request-identity branch October 29, 2026 21:30
@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40958340569 at c587e68 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at e3d7290. This pull request is one of 2 merged since: #27524, #27497.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

lawrencecchen added a commit that referenced this pull request Oct 30, 2026
…ine_arg_app sockets get a per-process serial

- transport_path_coverage: tab.update attention_request_id (#27497) is the app's
  guarded clear of a captured mark; the CLI keeps the unconditional clear.
- action_machine_arg_app: parallel tests could read the same clock tick and bind
  one socket path (AddrInUse on Linux CI); a per-process serial keeps them apart.
cmux-bot Bot pushed a commit that referenced this pull request Oct 30, 2026
…nd why (carries #24311) (#27962)

* cmux NEXT: a tab an agent needs you in shows the unread dot, ring and why

tab-attention-v1 (the daemon half is #24286): the tab record's
extra.attention {reason, at_ms} becomes TabModel.attention, and
showsUnread reads it, so the tab's blue dot, the screen bar, the sidebar
tab list and the pane's blue ring all show it with no new drawing. The
workspace row gets its manual dot and shows the reason as its text line.
Going into the pane (a click or a key) or Dismiss Highlight hides the
ring; the dot stays until the agent clears the mark, the page changes or
the tab closes, and a new request rings again. Mark as Read on the tab
also drops the mark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* SidebarMapping: keep newestUnread's doc comment on newestUnread

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* Attention ring: going into a remote marked tab hides its ring too

interacted(_:tabID:) found tabs on this Mac's daemon only, while attentionMarks
rings marked tabs on every machine, so a click or a key in a Cloud or SSH tab
never dismissed its ring. A tab found on another machine now gets the ring's
dismissal, which is this app's own state; its notifications and Mark as Unread
keep their daemon's own paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* Attention ring: resolve a click or key on the window's own machine; reject a bad at_ms

A tab on another machine can share an id with one here (a forked machine keeps its
tab ids). Interactions now find the tab in the workspace the window shows, on the
machine that owns it, and the hidden-ring state lives on the tab's own model, so
one machine's click or Dismiss Highlight never hides another's ring. A mark whose
at_ms is missing, negative, fractional or not a number is no mark.

Leo-ask: ask-12231fbe5e

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* Attention ring: typing in another machine's terminal clears no workspace mark here; tests prove the redraw and the untouched local tab

noteTyping's workspace Mark as Unread clear now runs only for a window that shows
this Mac's workspace (or none), so a key in a remote terminal never clears a local
workspace whose tab shares the id. The ring test checks that hiding the ring wakes
its observers, and the two-machine test checks that a click on the remote tab leaves
the local tab's Mark as Unread alone.

Leo-ask: ask-12231fbe5e

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* TabAttentionTests: the observation flag is nonisolated (onChange is a Sendable closure)

Leo-ask: ask-12231fbe5e

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16037-16c2-7a73-b063-2e37ed40b9c4&host=cosmic-gray

* Test remote attention rings through a delayed strip click

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Keep delayed strip clicks on their originating machine

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Pass the strip fixture readiness condition explicitly

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Test attention ownership through workspace replacement and menu reads

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Bind attention reads to their owner and show clears immediately

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Guard attention clears and ring generations

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Make attention clears conditional and monotonic

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Document revision guarded attention clears

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Persist attention clear revisions across remarks

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* Fix decimal encoding for guarded attention clears

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: import wire decimal parser

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: preflight attention clear capability

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: read nullable attention revision

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: preserve explicit attention targets

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* style: format tab update SDK

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: scope remote highlight dismissal and validate revisions

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* test: read SQLite timestamps as signed integers

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: scope highlight dismissal to its machine and pinned owner

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: serialize machine-scoped highlight debug state

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: provide scheduler in attention test fixtures

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: reject malformed guarded attention timestamps

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: keep attention input ownership lookup indexed

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* test: import attention fixture scheduler module

Agent-Session: https://cmux.com/deeplink/agent?id=aid-493104335f660a57687e

* fix: guard shared attention interactions by owner request identity

Integrate the shared native request-ID contract from 9171431 and cecd056 while retaining machine-scoped dismissal state and client-local attention generation. Clear only the captured owner token and require the capability on the actual sending connection after handoff.

Regressions cover coalesced same-clock replacements, stale native mouse release, and legacy transport refusal. Fleet runtime validation is pending the backend-containing integration tree from #27497; no runtime result is claimed. Static verification: nine checks pass; unchanged localization inputs exceed existing debt. Swift #26809 and structural dogfood holds remain.

* fix(attention): an older daemon's mark hides its ring on entry and Dismiss Highlight

A mark without a request id (a daemon before tab-attention-request-id-v1)
stayed ringed until the agent cleared it: going in and Dismiss Highlight
skipped it. Hiding the ring is this client's view state, keyed by the
client-local attention generation, so it now applies to those marks too.
A press whose mark was replaced since is still dropped: a mark without a
request id compares the generation captured at the press. The owner clear
still needs the id.

Fixes the review BLOCK at c27c81c on #24311.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): a remote workspace or tab menu runs every targeted row on its own machine

Review BLOCK at 23ffe95 on #27962: only Dismiss Highlight and Mark Tab
Unread carried the owner machine, so a remote menu's other rows routed to
the first daemon holding the same id. Every menu row that names the
right-clicked object now carries its machine, and menu validation checks
the row against that machine, as the run does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): a remote workspace menu's rename field renames it on its own machine

Review at 44d1031 on #27962: the menu's rows were scoped to the
workspace's machine but the identity header's rename field built its own
invocation without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): a remote tab's menu rows resolve their pane on the tab's machine

Box review BLOCK at 06e3510 on #27962: with the menu's machine on the
invocation, routing went to the remote daemon but ActionScope.pane and
AppActionContext.paneController still found the first pane holding a
same-id tab on any machine, so Reload Tab could reach this Mac's tab. Both
now look only on the target's machine when the invocation names one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): name the pane in ActionScope's pane lookup closure (compile)

Box review at 8c0b5f5: $0 inside a closure nested in one with a
named parameter does not compile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): Move Tab keeps the remote tab model it was given

Box review BLOCK at 3e011c0 on #27962: movingTabs looked the tab up
again by id across every machine, so with a same-id tab on this Mac shown,
Move Tab to New Workspace or Window could move this Mac's tab. It now
finds the pane of that very tab model on its own machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* Revert "fix(attention): Move Tab keeps the remote tab model it was given"

This reverts commit ad63a5f.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* Revert "fix(attention): name the pane in ActionScope's pane lookup closure (compile)"

This reverts commit 3e011c0.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* Revert "fix(attention): a remote tab's menu rows resolve their pane on the tab's machine"

This reverts commit 8c0b5f5.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* Revert "fix(attention): a remote workspace menu's rename field renames it on its own machine"

This reverts commit a9a4b8b.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* Revert "fix(attention): a remote workspace or tab menu runs every targeted row on its own machine"

This reverts commit 44d1031.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): a machine-scoped menu row validates against its machine

The one part of the reverted 44d1031 that fixed this PR's own code: menu
validation rebuilt the invocation without targetMachineID, so a scoped
row's title and enablement were checked against a same-id object on
another machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* fix(attention): opening a marked tab hides its ring

Sol review BLOCK at 5825e87 on #27962 (P2): jump to unread or a
banner click opens the tab with the .open trigger, which dismissAttention
ignored, so the ring stayed after the person went in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

* refactor(attention): TabInteractionTarget lives in CmuxNextDaemon (app-type guardrail)

The type holds only daemon models (TabModel, DaemonStore) and its mark
check; nested in NotificationCenterService it grew a CmuxNextApp file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8bf8af53d779b9f5acad

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

3 inactive deployments
artifacts — f5502f81 Deployed Oct 29, 2026 by teamleaderleo via add the Windows daemon to the tree #78212
sentry-dsyms — f5502f81 Deployed Oct 29, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #78212
ci-routing-agent — f5502f81 Deployed Oct 29, 2026 by teamleaderleo via cmux-tui tree preflight #78212
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant