acpmux workflows: a launch and its end say what a resume names (scriptPath, args, runId)
Leo, 2026-10-24: "lawrence also sent some of this stuff with dynamic workflows claude "trajectories" ... we can use that to help think about how cmux-next/acpmux wants to expose/reveal/render dynamic workflows... we can look at claude code desktop and see how we can do better". Design: manaflow-ai/cmuxterm-hq#3720 and #3734.
Review: Codex (xhigh) blocked the first version, a denylist guard on raw args, because an env map or a base64 blob passes any denylist. It then blocked an unsalted SHA-256 digest, which allows offline guessing of small args. Args now go out only as a daemon-keyed HMAC digest. This is the follow-up to #24789, carrying what was moved out of it to stay under the size cap.
acpmux owner notice. plans/cmux-next/acpmux-audit.md names the acpmux owner as session cmux-4f (PL-acpmux). That session can't be reached from here, so this is the notice. The change is in claude_stdio/workflows.rs, inbound.rs and subagents.rs (two fields passed through), plus doc comments in hub/subagent_transcript.rs.
Risk: normal. A workflow's launch and end updates carry scriptPath, runId and an args digest, never the args.
What changed
A pane's Resume asks the chat for Workflow({scriptPath, resumeFromRunId, args}), but it had no script path to put there. The pane fold (#24818) already keeps what acpmux sends.
- Launch. A workflow's launch update carries
scriptPath, the path Claude Code returned and the only kind it accepts back. - End. The run's last update, its end keyframe, repeats
runIdandscriptPath, so a reader of recent history alone can still resume it. (This was a non-blocking nit from Codex's review of #24789.) - Args are never sent. They can hold anything (an env map, a base64 blob) that no denylist or scanner recognizes, and session updates aren't masked. A launch and the run's end send
argsDigestinstead: the first 16 bytes of an HMAC-SHA-256 of the args' JSON, under a key the daemon draws at random once per process. Two runs with the same args on one daemon match, and nothing outside the daemon can test a guess against it.- The daemon's workflow index (
_acpmux/workflows, #24889) now marks duplicates byargsDigest. - A resume doesn't need args from the pane: the agent that launched the run has them, so a Resume asks it to use the same.
- The daemon's workflow index (
- Doc fix.
hub/subagent_transcript.rs's doc comments saytruncatedalso covers the line-index cap (a nit from Codex's review of #24825).
No capture: a daemon change with no UI.
Testing
cargo test -p acpmux --lib -- claude_stdio subagents hub::subagent_transcript hub::workflow_index capabilities: 98 passed. New and changed tests cover:- a launch names its run, script path and args digest;
- the end repeats them;
- args never go out, whatever they hold (an env map, a base64 blob), only their digest;
- the same args give the same digest, different args a different one, and the digest isn't the plain SHA-256;
- the index marks duplicates by digest.
cargo fmt --checkis clean, andcargo clippy -p acpmux --lib --tests -- -D warningspasses.
Agent session: huge-blue
š¤ Generated with Claude Code