CI: the Swift app's acpmux methods and the agent pane's param keys are checked against acpmux-protocol.json

Merged
TE
1d ago
+430-0

Leo, 2026-11-05, after a Cloud chat failed on a hand-spelled field name: "You guys keep running into these. These are weird issues that I feel like you should be able to just fix beforehand and check on beforehand."

acpmux's wire contract is cmux-tui/crates/acpmux/spec/acpmux-protocol.json. It is emitted from acpmux's Rust method registry, Rust's protocol_ir_is_current keeps it current, and the webviews generate their client from it. The app's Swift side names acpmux methods and the agent pane's allowed param keys by hand, and nothing checked those names against it. Now CI fails when Swift names a method or param the protocol does not define.

What changes

  • scripts/ci/check-swift-acpmux-protocol.py checks three things against the protocol:
    • Every method-shaped string literal in Packages/macOS/CmuxNext/Sources (_acpmux/, session/, acp., trigger/), skipping comments and joined prefixes. Today that is 144 names. Comments are skipped; multiline and raw strings are read as strings.
    • Every method of the agent pane's frame policy (AcpmuxPaneMethods requests, notifications, knownParams, and the first frame's initialize): 80 methods.
    • Every knownParams key of a method whose params the protocol types as a closed object: 14 methods, 42 keys. An open object (no additionalProperties: false) takes other keys too, so it is not limited.
  • Names that aren't methods go in scripts/ci/swift-acpmux-protocol-allowlist.txt with a reason. Today the only entry is acp.trust.peer-v1, an initialize extension name. A listed name that is no longer used, or that the protocol now defines, fails too, so the list only shrinks.
  • .github/workflows/swift-acpmux-protocol.yml runs the check and its tests on Linux with a sparse checkout, whenever either side changes.
  • tests/test_check_swift_acpmux_protocol.py covers four cases: a drifted method literal, a drifted pane method, a drifted param key, a drifted first-frame method, method names in multiline and raw strings, and a stale allowlist entry. It is also green on the repository.

No drift on today's tree beyond the one extension name. _meta.acpmux keys and the methods with untyped or open params are not checked yet, because the protocol does not close them.

Changelog

none

Verification

  • python3 -I tests/test_check_swift_acpmux_protocol.py: 8 tests OK.
  • python3 -I scripts/ci/check-swift-acpmux-protocol.py: green.
  • actionlint is clean on the new workflow.

Agent session: agent session

šŸ¤– Generated with Claude Code