cmux-rd: one typed app line for cmux rd serve|connect, read back through a C line reader (ABI 5; Mac Screen step A)

Merged
LA
1d ago
+849-30

Summary

First Rust move for the tip's swift-logic red (lead order after 18:00Z; the task was offered to Abdulaziz Albahar in STATUS 12204 first). The Mac Screen's cmux rd serve|connect stdout lines had two definitions: json! literals in cmux-rd-host and a hand decoder in Swift (MacScreenRdMessage, MacScreenRdLines). This PR makes Rust the only definition and gives the app a C reader for it. It is step A of the two-step app FFI path: no Swift caller of the new C ABI until the app FFI release that includes it is pinned.

  • cmux-rd-proto app_line (feature serde): AppLine and LinePath, the line shape, and LineSplitter, the stdout byte splitter. Golden vectors: tests/vectors/app_lines.json (every line kind of the old Swift decoder: key, candidate, candidates_done, connected, listening, ended, path with kind and rtt_ms, displays with current, the displays error, plus an unknown line, a non-JSON line and a field of the wrong type).
  • cmux-rd-host serve.rs and connect.rs print AppLine values. Same fields; the key order of a line now follows the struct (no reader depends on key order).
  • cmux-rd-ffi: CmuxRdLineReader (cmux_rd_line_reader_new, _free, _push, _next) and CmuxRdLine, ABI 4 -> 5. No I/O, no threads, panics caught, a panic poisons only that reader.
  • CmuxNextMacScreenTests (new test target, MacScreenRdLineTests): the Mac Screen's current Swift decoder reads every golden vector as its want. That is the behavior-neutral proof: for every line the host prints, the Rust reader gives the Swift code the same values it reads today.

Step B (written and on branch swift-logic/macscreen-rd-lines-b, head 306b582953b2, not in this PR): RemoteRdLineReader (CmuxNextRemoteView, a thin wrapper over cmux_rd_line_reader_*), MacScreenRdProcess reads lines through it, MacScreenRdMessage and MacScreenRdLines are deleted, and MacScreenRdLineTests feeds the vectors through the Rust reader. It opens as its own PR after this PR lands, app-ffi-release.yml publishes the release and the re-pin PR lands. Not in scope: MacScreenRdDocument and MacScreenRdServers (the cmux.rd/1 offer and answer text format). No Rust code owns that format today, so they stay Swift.

Numbers

swift-logic-lines.py, swift_logic_lines (mirror_lines 71,927 everywhere; missing 15, invalid 0):

Revisionswift_logic_lines
base 2d102f877445415,764
this PR, c6450d9fda6c415,764 (step A adds no Swift logic)
step B branch, 306b582953b2 (4 PLATFORM rows included)415,621 (-143)

Step B deletes MacScreenRdMessage (23) and MacScreenRdLines (15). MacScreenRdProcess (105) becomes process plumbing only, and its new row says so with the FFI call (lead rule c). The new wrapper RemoteRdLineReader (80) gets PLATFORM rows like the other RemoteRd* cmux-rd-ffi wrappers. This move alone does not turn swift-logic green: the tip is +546 over 415,218, and step B gives -143.

Changelog

none

Observed / Not run

Observed, fleet steps on c6d9ab7c2af8 or c6450d9fda6c (this head):

  • cmux-ci run --class light --script scripts/ci/feat-parity-check.sh --arg rust-workspace --arg cmux-tui/crates/cmux-rd-ffi at c6d9ab7c2af8: step 402081659a6ef2ef5854918f, green. 57 tests, including the 5 line_reader_tests and header_declares_exactly_the_exported_functions_and_codes (the header and the exports agree, with ABI 5).
  • the same with --arg cmux-tui/crates/cmux-app-ffi at c6d9ab7c2af8: step 06415966171e0394243cf985, green.
  • cmux-ci run --class light --script scripts/ci/run-swift-testing-suites.sh --arg Packages/macOS/CmuxNext --env CMUX_SWIFT_TEST_SUITES=MacScreenRdLineTests at c6d9ab7c2af8: step 7921ed72ed76c99430274f2a, PASS ^CmuxNextMacScreenTests\.MacScreenRdLineTests/ (the old Swift decoder matches every vector).
  • cmux-tui-rust-check.sh --os macos --arg clippy at c6450d9fda6c: step a7e9929aa05ac79a0927f3f1, green. The same at c6d9ab7c2af8 was red, step 8c236eb2cc562486441cfe49 (E0282 in my splitter test), fixed in c6450d9fda6c.
  • cmux-tui-rust-check.sh --os linux --arg fmt at c6d9ab7c2af8: step 92f81d99e2d7676f0d6168ed, red on base files only (cmux-app-manifest tests/customize_example.rs, cmux-tui-core apps/grants.rs and lib.rs, cmux-tui link/sync_cli.rs and store.rs). None of them is in this PR; rustfmt --check of the changed files passes with each crate's edition.
  • cmux-tui-rust-check.sh --os macos --arg rd-host at c6450d9fda6c: step 8d10f3568178258dfea4953d, clippy red on mac/capture.rs:247 displays is never used (this lane builds without the link feature, so serve.rs, the only caller, is out). The same lane on base 2d102f877445 is red the same way: step c9df8dd88354824c7ba7df84. It is a base finding; rd-host tests pass in both.
  • cmux-tui-rust-check.sh --os linux --arg test --arg app_line at c6450d9fda6c: step 1901370296fb198e25d3ee9f, "no tests to run". On Linux nothing in the cmux-tui workspace turns on cmux-rd-proto's serde feature (rd-host is a macOS-only dependency of cmux-tui), so app_line compiles out there, as control.rs does. The same on macOS: step 231d065bdaf96e7553d39927, green, 5 of 5 app_line tests.
  • cmux-ci run --class light --script scripts/cmux-next/build-app-ffi.sh at c6450d9fda6c: step 9a8bb411b755274ed000e890, green (CCmuxAppFFI.xcframework builds with ABI 5).
  • python3 scripts/cmux-next/prepush-gate.py: no new violations.

Not run: no build of the app with the new ABI (step B needs the published release). No GUI run of a Mac Screen session (no line shape changes: the vectors prove the values).


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Makes Rust the single source of the JSON lines cmux rd serve|connect print for the app, and adds a C line reader (CmuxRdLineReader, ABI 4→5) so the app reads them back as typed lines. The line shape was previously defined twice — json! literals in cmux-rd-host and a hand decoder in Swift — and now cmux-rd-proto's app_line owns it; the host prints AppLine and the Swift Mac Screen reads the same values as today. A new Swift test target proves the existing decoder reads every golden vector as its want, so the behavior is unchanged.

  • New app_line module (feature serde): AppLine, LinePath, LineSplitter, and golden vectors for every line kind the Swift decoder knew, plus unknown, non-JSON, and wrong-type lines.
  • New cmux-rd-ffi reader: cmux_rd_line_reader_new/_free/_push/_next, no I/O or threads, panics caught per reader.
  • Host serve.rs/connect.rs print AppLine values; same fields, key order now follows the struct.
  • Step A of two: no Swift caller of the new ABI until the app FFI release is pinned; step B (Swift reads through the reader, MacScreenRdMessage/MacScreenRdLines deleted) lands after the re-pin.