feat(tab-drag): expose index and reveal rules over app FFI
Summary
Moves the pure NEXT tab-drag index conversion and drop-reveal policy into the existing app FFI crate, with no Swift call-site changes. The API accepts caller-owned UInt32 tab ids, preserves Swift clamping and same-pane wire-index rules, and maps every TabDragOutcome explicitly to reveal flags.
This is the prerequisite Rust-only step for the later TabDrag consumer shards. Reverting this PR leaves the existing Swift implementation unchanged.
Validation
- Added Rust unit coverage for same/cross-pane wire indices, clamped pane/group indices, null-array rejection, representative reveal outcomes, and reveal guards.
git diff --checkpassed.- Fleet check at
98f47e48ba366fbf7baf5021903132d2fe914047: run 41759609604, checks job 126345277544 passedcargo fmt --check, Clippy with-D warnings, and all 84 tests in the standalone FFI crate, including four tab-drag tests. No local build was used. - The previous own CI failure was two missing FFI
# Safetysections; both are fixed and the same Clippy command is green at this head.
Performance
| Metric | Before | After | Delta | Harness |
|---|---|---|---|---|
| Migrated rule families covered by Rust tests | 0 | 4 | +4 | cmux-layout-reducer-ffi test target |
No runtime benchmark is claimed: this step only adds pure decision APIs and preserves the current Swift behavior until its consumer shards land.
Changelog
none
Source-only release order
This prerequisite adds four Rust/C entry points and a direct CCmuxAppFFI target dependency. No Swift source imports or calls the new symbols in this PR, so the currently pinned binary continues to build and behave as before.
The release sequence is mandated by docs/ci/app-ffi-release.md: source lands on feat-cmux-next, .github/workflows/app-ffi-release.yml publishes the landed SHA, then its generated app-ffi-repin PR updates the URL and real checksum. That workflow runs only at refs/heads/feat-cmux-next and its protected release environment accepts only that branch. The source-freshness check is expected to report the intermediate drift. This lane owns the release and generated pin through merge; the two Swift consumer shards wait for that pin.
Please evaluate the prior review's pin finding against that documented two-stage publication order; no consumer uses these symbols before the matching binary exists.
🤖 Generated with Codex
Agent session: agent session
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds the NEXT tab-drag index conversion and drop-reveal policy to the app FFI crate, with no Swift call-site changes. The API takes caller-owned UInt32 tab ids, keeps Swift clamping and same-pane wire-index rules, and maps every TabDragOutcome to reveal flags. CmuxNextBridge now links CCmuxAppFFI to reach the new entry points. Reverting this change leaves the existing Swift implementation unchanged.
Validation
- Added Rust unit coverage for same/cross-pane wire indices, clamped pane/group indices, null-array rejection, representative reveal outcomes, and reveal guards.
- Negative index values are preserved against Swift's wider
Int64before clamping, and each non-empty array pointer carries an explicit validity contract.