ci(risk): pane host ops and allowlists are high risk
Summary
The risk-tier classifier now grades high the files that decide what an agent pane's web page may make the host do or read. Before this, they all graded normal.
#22646 added the page op chat.asks.pending to AgentPageOps. Its handler, AgentPanePendingAsks.swift, opens its own connection to the local acpmux daemon and reads another chat's permission asks. Until review caught it, the read reached a peer daemon. The fix named the chat local/<id> and refused replies that name a peer. The whole change graded normal by path, so the next such op would have been caught only by a reviewer's judgment, not by the path tiers.
New rule in scripts/ci/risk_tier.py, "agent pane host op or allowlist", placed right after the socket and relay rule:
CmuxNextAgentPane/AgentPageProvider.swift: theAgentPageOpslist and itscalldispatch. Every new op edits this list.CmuxNextAgentPane/AcpmuxPaneMethods*.swift: the_acpmux/*methods a pane may relay and theirknownParams.CmuxNextAgentPane/AgentPaneEnvironmentRequest.swift,AgentPaneReplyRequest.swift: the page-op param tables.CmuxNextAgentPane/AgentPaneTransport+Check.swift: the frame check.CmuxNextAgentPane/AcpmuxPathPolicy.swift: the folder policy.CmuxNextAgentPane/AgentPanePendingAsks.swift: a host op that opens its own daemon connection for a page.CmuxNextAgentPane/AgentPaneTransport+Frames.swift:decide(), the gesture rule that spends a click's ticket (and grants folder roots).CmuxNextAgentPane/AgentPaneGestureIntent.swift: which methods a click's ticket may redeem.CmuxNextAgentPane/AgentPaneUserGestures.swift: the click tickets themselves (reserve,consume,redeem).CmuxNextAgentPane/AgentPaneModel+Actions.swift:connectActions, the app actions a page may run throughaction.run.CmuxNextAgentPane/AgentPaneTransport+RelayedAllow.swift: the decision proof a relayed allow carries, signed with the person key.CmuxNextAgentPane/AgentPaneTransport+PickedFolder.swift: a folder the person picks becomes a root the page's requests pass.CmuxNextAgentPane/AgentPaneTransport+FullAccess.swift: the refusal of a switch into a mode that skips approvals.cmux-tui/crates/cmux-agent-pane-policy/*: the Rust mirror (policy.json, src and Cargo.toml).cmux-tui/crates/acpmux/src/server/remote_guard*: what acpmux allows from a non-local connection.
The rest of CmuxNextAgentPane stays normal (for example AgentPaneView.swift, AgentPageProvider+Scroll.swift, AgentPaneTransportPacer.swift). The policy tests stay low, because the test rule comes first. docs/ci/risk-tiers.md gets a new row under the socket and relay access policy kind, with #22646 as its evidence. There are still six kinds.
This touches risk_tier.py, so this PR is risk:high and needs a person's approval.
Review follow-up (c0695a250b0b)
The independent review of c0b5b4ed passed and named three gatekeepers outside the rule; they are added above, with test cases. Checked with risk_tier.py's classify_path on this head: all three grade high, and AgentPaneView.swift, AgentPaneModel+Composer.swift and AgentPaneTransportPacer.swift stay normal. git merge-tree with #23371 at 0b7d7fed still merges cleanly. Lines touched at f08aa0f3446e: risk_tier.py new 95-111, tests/test_risk_tier.py new 201-238, docs/ci/risk-tiers.md line 30 (all new lines). A second review (of c0695a25) passed and named AgentPaneUserGestures.swift, added in f08aa0f3. The test file was not run on this Mac (a hook refuses it); CI's risk tier tests job runs it.
Base merge and review follow-up (05ee5b880ba7)
Merged feat-cmux-next afaf26df (13fdb5f9; base hadn't touched risk_tier.py). The independent review of 13fdb5f9 passed (SHIP) and named three transport files that also decide what a page may make the host do: +RelayedAllow, +PickedFolder, +FullAccess. Added in 945913d5 (test) and 05ee5b88 (rule and docs row). python3 -I tests/test_risk_tier.py ran on this Mac this time: red at 945913d5 ('normal' != 'high' for exactly those three paths), green at 05ee5b88 (31 tests OK).
Changelog
none
Testing
New tests: test_agent_pane_host_ops_and_allowlists_are_high and test_ordinary_agent_pane_ui_and_policy_tests_stay_below_high in tests/test_risk_tier.py. The risk tier tests workflow runs them on this PR (python3 tests/test_risk_tier.py -v).
Observed / Not run
Observed:
- A hook on this Mac refuses
python3 tests/test_risk_tier.py(heavy work on an interactive Mac). So I got red and green from the sameclassifyfunction the tests call, one path at a time:risk_tier.py classify --files <one path> --json.- On base (red): every new path returned
normal(AgentPageProvider.swift,AcpmuxPaneMethods.swift,AcpmuxPaneMethods+Params.swift,AgentPaneEnvironmentRequest.swift,AgentPaneReplyRequest.swift,AgentPaneTransport+Check.swift,AcpmuxPathPolicy.swift,AgentPanePendingAsks.swift,policy.json,params.rs,remote_guard.rs). - On head (green): each of those returned
high.AgentPaneView.swift,AgentPageProvider+Scroll.swiftandAgentPaneTransportPacer.swiftreturnednormal.cmux-agent-pane-policy/tests/swift.rsandacpmux/tests/remote_guard.rsreturnedlow.
- On base (red): every new path returned
python3 scripts/cmux-next/prepush-gate.py: no new violations.python3 scripts/verify-local.py: 10 of 11 checks passed.localizationfailed on parity in catalogs this PR doesn't touch (base debt).git merge-tree --write-treeagainst #23371's head (0b7d7fed) merges cleanly. The two PRs change different lines of the same three files.
Not run before 05ee5b88: the full tests/test_risk_tier.py suite locally (the hook refused it then). At 05ee5b88 it ran locally: 31 tests OK (see the follow-up section above).
Agent session: cosmic-gray
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
The risk-tier classifier now grades high the files that decide what an agent pane's web page may make the host do or read, so a security slip like #22646's chat.asks.pending (which reached a peer daemon until review caught it) gets caught by path instead of by reviewer judgment.
- Adds a high-risk rule in
scripts/ci/risk_tier.pycovering the page ops list, the relayable_acpmuxmethods and params, the page-op param tables, the frame check, the gesture rule (the click-minted tickets anddecidespending one), the app actions a page may run, the folder policy and the picked-folder roots, the relayed-allow proof, the full-access refusal, the Rust mirror, and acpmux's remote guard. - Ordinary pane UI files stay normal and the policy tests stay low.
- Adds matching tests and a docs row; this PR touches
risk_tier.pyitself, so it grades high and needs a person's approval.