Repository navigation
Mask secrets in the lane's title, step and error before they leave the daemon - #21794
Conversation
…raw prompt (red) hq#2509 follow-up. The Lanes view shows each lane's prompt, peers' included, so a pasted token shows on screen. acpmux should mask secrets in lane.step before the summary leaves it, and the app should read only lane.step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Lanes view showed each lane's raw prompt, fleet peers' included, so a pasted token showed on screen. acpmux now decides the step itself (lane.step: the running turn's prompt, else the agent's last reply line) and masks secrets in it and in lane.error before the summary reaches a client or a peer. The mask is typed: [github token], [anthropic key], [jwt], [private key], [credentials], [secret]. It is destructive, not a cover: the masked text has no source left to reveal. The detector is its own module (acpmux::secret_scan) so transcripts, notifications and the phone relay can share it. It knows provider key shapes, JWTs, PEM private keys, auth headers, URL credentials, secret NAME=value assignments and long random-looking runs, and leaves git SHAs, UUIDs, paths and data: URI payloads alone. The app and the web view read only lane.step; an acpmux from before it shows no step rather than the raw prompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Receipt for
|
|
Visual preview of 8644306: in the maintainers' private review feed. |
|
Bead |
…ssignment false positives (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
red: web / Web status; do not merge until green; see lane-rules |
|
Unclear: CI failed on
Not re-run automatically: Written by |
|
Agents: |
…nes, cuts before scanning (hq#2509) The lanes view showed the summary's raw title or first prompt and the raw error. acpmux now sends a masked lane.title, both clients read the lane's title and error only, and an older peer's lane without them is decided again here. The step and title scan only the text's head. The assignment rule needs a letter and a digit, so counts and words named token or secret are left alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
A review subagent checked 906e297 (correctness first). It found no leak or panic in the step and error paths. Each finding and what happened to it:
Head 76290ce. On Huge Blue: |
…cut into it (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rompt (hq#2509) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
A second review subagent checked 906e297..76290ce. Nothing in it blocks merge. Each finding and what happened to it:
The reviewer also checked these and found them fine: the peer re-decide with closed or current peers, all Head 7261ea1. On Huge Blue, |
- vp fmt webviews/test/agent-activity-priority.test.ts Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39171945368
|
Found 4 test failures on Blacksmith runners: Failures
|
|
CI on head 8644306: 87 checks pass and 2 fail. 8644306 is cmux-autofix's Prettier reflow of my 7261ea1; the code is unchanged. Both reds are base reds:
Not run: The acpmux Rust tests ( |
|
PR CI doesn't run the acpmux unit tests, so I ran |
|
Shipped in:
|
Review: AgentActivityLane.of lost its title: parameter (#21794), so the test target did not compile. The app reaches the lanes through SidebarRowFeed.laneRowSource, which replaces SidebarBridge's unused CmuxNextActions import, so CmuxNextApp's source line count stays put. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue
…ebug toggle) (#20956) * test(cmux-next): sidebar rows show each agent session's acpmux lane state Leo 2026-10-15 via cg-ui-coord: a sidebar row shows its agent session's live status (working, waiting on you, failed, idle) from the acpmux lane AgentLaneStore already holds, whatever harness runs the chat, behind the Debug toggle sidebar.laneStatus (off by default). Adds the toggle, the shared lookup of a workspace's lanes on this Mac (SidebarLocalLanes) and a pass-through SidebarLaneStatus, so the tests compile and fail until rows merge the lane state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(cmux-next): sidebar rows merge each agent session's acpmux lane state (Debug toggle) With sidebar.laneStatus on, a workspace row's status mark also follows the acpmux lane of each agent chat in it on this Mac, read inside the row's mapping so a lane change maps that row again. Precedence is StatusStack's state rank: failed, then waiting on you, from either the row or a lane; then working; then the row's own done; an idle lane adds nothing; the row's own state wins a tie. Off, no lane is read and rows are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): name the sidebar's section type in the lane status tests SidebarSection is ambiguous between CmuxNextDaemon and CmuxNextSidebar in the app tests; use the bridge's SidebarRowSection. Back to the pass-through SidebarLaneStatus so this commit is the behavioral red; the next one merges the lanes again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(cmux-next): sidebar rows merge each agent session's acpmux lane state (Debug toggle) With sidebar.laneStatus on, a workspace row's status mark also follows the acpmux lane of each agent chat in it on this Mac, read inside the row's mapping so a lane change maps that row again. Precedence is StatusStack's state rank: failed, then waiting on you, from either the row or a lane; then working; then the row's own done; an idle lane adds nothing; the row's own state wins a tie. Off, no lane is read and rows are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at 61b50fb - regenerated schemas/defaults/cmux-next.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38700743401 * chore(next): PR autofix at 8bbe40b - Packages/macOS/CmuxNext/ci-target-graph.json - schemas/defaults/cmux-next.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39367511362 * refactor(cmux-next): row lane status lives in CmuxNextAgentLanes, not the app target The CmuxNextApp size cap was this PR's own red: new code goes in its own target. SidebarLaneStatus and SidebarLocalLanes move to CmuxNextAgentLanes (the acpmux lanes feed, which already depends on AgentActivity, Bridge and Sidebar); the app reads them through AgentLaneStore.sidebarRows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue * fix(cmux-next): lane status tests compile; the app grows no source lines Review: AgentActivityLane.of lost its title: parameter (#21794), so the test target did not compile. The app reaches the lanes through SidebarRowFeed.laneRowSource, which replaces SidebarBridge's unused CmuxNextActions import, so CmuxNextApp's source line count stays put. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c2a-ee5f-7111-b18b-d14161ef8c3c&host=huge-blue --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
The Lanes view showed raw prompt text in each lane's title and step line, so a pasted token appeared on screen and went to every fleet peer. acpmux now masks secrets in the lane before it leaves the daemon, and the clients read only the masked lane. Follow-up to #21727, part of cmuxterm-hq#2509.
What changed
acpmux::secret_scanmodule.findandmaskreplace each secret with its kind:[github token],[anthropic key],[jwt],[private key],[auth token],[credentials],[secret]. It catches provider keys (Anthropic, OpenAI, Stripe, GitHub, Slack, AWS, Google), JWTs, PEM private keys (truncated ones too), auth headers, credentials in URLs,NAME=valuesecrets, and long random runs. The masked text no longer holds the secret, so nothing downstream can reveal it. The module only reads text, so transcripts, notifications and the phone relay can use it later.stepandtitle, andlane.erroris now masked as well.stepis the running prompt or the agent's last reply.titleis the session's title, falling back to its first prompt.title, this daemon decides that lane again, so the peer's lanes come out masked too.lane.title,lane.stepandlane.error. The raw prompt, title and error fallbacks are gone. Against an older daemon, a lane shows the session name and no step.AgentActivityLane.ofno longer takes atitle:, since the one its callers passed could be the raw first prompt.stepandtitle. Re-blessing the IR also picked up two staleLifecycleReceiptdescriptions from the base branch.Left alone on purpose: git SHAs and other hex, UUIDs, paths, branch names, camelCase identifiers,
sk-learn-…package names,data:…;base64,images, and code or config that only names tokens (max_tokens: 100000,crate::secret_scan::mask,token: expired). For an assignment to be masked, its value must contain a letter and a digit. The module doc lists the known misses: short passwords with no recognizable shape, and values containing;,,or spaces.Next: a stacked PR replaces these hand-written patterns with gitleaks' rule set (MIT, pinned to v8.30.1) and adds Nosey Parker's examples as a fixture corpus, keeping the same
find/maskAPI.Question for Leo
The summary still sends these fields raw to clients and peers:
turn.prompt,lastPrompt,lastMessage,previewandtitle. Should the daemon mask them for peers too (remote chats would then show masked text), or stay with only the lane fields the Lanes view uses?Verification
a lane's title and error are the daemon's masked onesfailed (1 of 8). On Huge Blue, the Rust teststhe_lanes_title_is_masked…andordinary_text_is_left_alonefailed, and so dida_lane_from_an_older_peer…once its fixture gainedindicator. That fixture change landed in b3b7f14.cargo test -p acpmux --lib,protocol_ir_is_current,cargo fmt --check, the webview priority and lanes tests, and protocol codegen with no diff.AgentLanesTestschange. That is left to CI.The protocol spec changed (
Lane.step,Lane.title), so this may need a coordinator WINDOW.Changelog
Fixed: The Lanes view masks API keys, tokens and other secrets in each lane's title, step and error, including for fleet peers.
🤖 Generated with Claude Code