acpmux resolve: a PR footer's agent link finds its session, here or on a peer, with its metadata
Merged
TE
13d ago+820+820+012345678901234567890123456789-2-2-0123456789
Leo, 2026-10-24: "shouldnt the deeplinks and such be able to tell you a decent amount of metadata and be able to find things? likewise, what about beads? linking beads to agents and vice versa?"
This PR is the deeplink half. The beads half comes in a second PR.
What changed
acpmux resolve LINK|ID|NAME (alias find) and the RPC _acpmux/resolve {query}:
- It takes a PR footer's
https://cmux.com/deeplink/agent?harness=ā¦&session=ā¦&host=ā¦(the bare URL or the whole markdown footer line), the nativecmux://agent/<harness>/<session>?ā¦, an acpmux session id, a qualified id, a harness session id,HOST/NAME, a name, or@. - A link's
session=is the harness's own session id, so it is matched againstagentSessionId, plus the family when the session has one. Matches on the host the link names come first, then this daemon's own sessions, then newest first. - It searches this daemon's own sessions and the session lists it already mirrors from its peers (
all_session_summaries). It sends no new request to any peer. - Each match returns: host, peer, sessionId, qualifiedSessionId, agentSessionId, name, harness, family, model, cwd, gitBranch, status, lane, title, pullRequests, lastTurn, lastPrompt, lastMessage, createdAt, updatedAt, tags, peerState, stale, and the session's own
link. - When nothing matches, the error says where it looked: this machine and the names of its peers. It also says if the link names a host that is neither this machine nor a peer, and which peers are not connected right now.
- The link reader is
src/agent_link.rs. Its test runs every vector inschemas/deeplinks/agent-link.json, the same vectors the web page and the app's parser run, so the three readers can't drift apart. The schema's comment now lists this reader as well. - Registered in
rpc.rs, the protocol registry, the committed IR (spec/acpmux-protocol.json), the generated web method list, theinitializeextensions list, and peer_forward's daemon-scoped list. The acpmux guide (section 6) gains one line about it. - No MCP tool. acpmux has no MCP surface for arbitrary sessions: the
cmux-subsessionsserver only covers your own children. Agents use the CLI, which the guide documents.
Tests
- Red on base:
tests/peer_integration.rsan_agent_link_resolves_to_its_session_here_or_on_a_peer, run with this test on the base code, fails with"Method not found: _acpmux/resolve". - Green on this head, run via
cmux-ci test --setup rust:- that peer test passes. It covers a local session from a whole footer line, a peer's session from the native link with
host=branked first, a bare name found on the peer, an unknown link that names a foreign host (the error lists the peers and the host), and a link with no session. cargo test -p acpmux --lib agent_link locate: 25 tests, including the schema vectors.cargo fmt --checkandcargo clippy --all-targets -D warningsare clean.
- that peer test passes. It covers a local session from a whole footer line, a peer's session from the native link with
protocol_ir_is_currentandprotocol_registry_names_every_served_methodalso fail on base (ce5e5c3b9f7: staletitleSourcein the IR, and"_acpmux/unknown"in a server/mod.rs test). Re-blessing the IR on this head changes only thetitleSourcedrift, so the_acpmux/resolveentry matches what the registry emits. Re-running the webviews codegen on this head gives no diff.
Review
Independent Codex review (gpt-6-astra, xhigh, its own read-only checkout).
- Round 1, at c6da1dc: BLOCK with five findings.
- A peer-origin resolve returned unmasked session text: the card lacked
lastSeq, soserver/peer_text.rsdid not see it as a summary. - A session with no family could match a link for a different harness.
- Read-only paired devices are refused
_acpmux/resolve. - The link reader accepted
/deeplink/agenton any host or path. - The CLI printed the last prompt instead of the latest reply.
- A peer-origin resolve returned unmasked session text: the card lacked
- Fixed with tests: 1 (the Origin::Peer integration test
a_peer_resolves_a_sessions_text_maskedwas red at c6da1dc and is green now), 2, 4 and 5. - Not changed: 3. The read-only allowlist is an access-control list, which is the owner's policy; read-only devices still get
_acpmux/sessions. The reviewer agreed it is not a blocker and it is tracked as a follow-up. - Round 2: SHIP, reviewed head d8b5b0ee00fc7491970d72066d9f7b8e842745d2.
- After that, two CI reds were this PR's own, and both are fixed: the crash ratchet (two
.expect(on the regex statics, nowOptionand checked by the vectors test) and tree-key-embeds (the schema was added toscripts/cmux-next/cmux-tui-tree-inputs.txt). - Round 3: SHIP, reviewed head fb82c2c1d013b82f9c15e2d51ba8729b4cd6a2f6.
- The reds left at that head also fail on base: No new SwiftUI and Checks job structure (Swift, base job 121072285982), gallery health (2)/(3) (base run 40160510139), release-notary and Guard status. The visual-evidence check is advisory.
- Fleet results at that head: the whole
tests/peer_integration.rspasses (35 tests); the lib tests for agent_link, locate, cli::resolve, peer_text and pairing pass; fmt and clippy-D warningsare clean.
Stop condition: merged at a head the Codex reviewer said SHIP to. No new timer, observer or loop.
No capture: CLI and RPC only, nothing visible changed.
Agent session: big-red
š¤ Generated with Claude Code