acpmux: publish a running turn's activity and plan step masked in the session summary
Summary
acpmux's session summary now publishes a running turn's turn.activity (its latest tool call's title) and turn.planStep masked (secret_scan, masked before the 160-char cut), the same way the sub-session rows already do. A token in a tool call's title, such as curl -H 'x-key: ā¦', no longer reaches any reader of the summary as raw text.
The finding (from the sidebar lane, on cmux#28095):
cmux#28095 (sidebar agent rows). Its opt-in Now line now shows turn.activity / turn.planStep from acpmux's watch summary, which carries them UNMASKED: hub/views.rs:398-399 copies t.doing.activity raw, and only the sub-session summaries get masked copies (hub/activity.rs:99, hub/subsessions.rs:821). The old source, lane.step, was masked (hq#2509), so a tool-call title holding a token could now show in the sidebar. Ask: publish masked copies of activity and planStep in the watch summary, using the existing Doing masker, as the sub-session summaries already do, so every app consumer gets the masked text.
What changed
hub/activity.rs:TurnActivitykeeps only the masked line.activity_ofmasks, then cuts (session::masked_preview). The raw copy, the separatemasked_*fields andmask_intoare gone.- This one path feeds every reader of the summary:
Hub::session_summary(hub/views.rs), which carries the app's sidebar row,_acpmux/watch/session_changed,_acpmux/sessions,acpmux ls --fields turn.activity,session infoand the sub-session rows. It also feeds a turn an adopting daemon rebuilds from the log (hosts.rs,work.doing.note). A peer gets the masked text from the source, andserver/peer_text.rsstill masks those fields again on the way out. subsessions.rs: drops the now-redundantmask_intocall.- Protocol docs:
TurnSummary.activity/planStepnow say "masked". The Rust doc,spec/acpmux-protocol.jsonand the generatedtypes.tschanged together; only the wording changed, no shape.
No reader needs the raw text. I grepped every reader of turn.activity / planStep / doing in cmux-tui, webviews and Packages: the webviews sessionList.ts doing line, subsession_send.rs doing_line, the CLI --fields examples and tests. All of them only display it.
Prior masking: hq#2509 (lane.step / peer text), cmux#23669 (the sub-session rows' masked activity).
Testing
Regression tests, committed before the fix (e66c53774d8):
hub::activity::tests::a_secret_in_a_tool_title_or_plan_step_is_masked: a tool title and a plan step carrying an AWS-key-shaped string are masked. A key straddling the 160-char cut leaves no head.subsessions_delivery: a child's tool title carrying the key is masked in_acpmux/sessionsover a local connection, which is what the app reads, as well as in the sub-session rows.
Command: cmux-ci test -- cargo test -p acpmux --lib hub::activity and --test subsessions_delivery, plus cargo clippy -p acpmux --all-targets -- -D warnings. Results are in a comment below: red at the test commit, green at the head.
Observed / Not run
- Observed: rustfmt
--checkon the changed Rust files is clean. - Not run locally: cargo build/test/clippy (lane VM); they run through
cmux-ci. The production code adds no panic sites; only code was removed.
No capture: no UI change. The daemon masks a text field it already sends; types.ts changed only a doc comment.
Changelog
Fixed: an agent's current tool call or plan step no longer shows a pasted secret in its session summary (sidebar, acpmux ls).
risk: normal (masking a display field; no shape change)
Agent session: agent session
š¤ Generated with Claude Code