Skip to content

enable migration client#3354

Open
insipx wants to merge 3 commits intomainfrom
d14n-migration
Open

enable migration client#3354
insipx wants to merge 3 commits intomainfrom
d14n-migration

Conversation

@insipx
Copy link
Copy Markdown
Contributor

@insipx insipx commented Mar 24, 2026

Enable migration client path across mobile, Node, and WASM bindings

  • Introduces connect_to_backend_exclusive (mobile), connectToApiBackendExclusive (iOS/Android), and is_migration() env variants (Node/WASM) to preserve the pre-migration exclusive connection path while making the default connection migration-capable.
  • The default connect_to_backend on mobile and the BackendBuilder.build on Node/WASM now call builder.build() (migration-capable) instead of builder.build_optional_d14n() when in a migration environment.
  • New MigrationLocal, MigrationStaging, and MigrationProduction env variants are added to Node and WASM bindings to signal migration mode.
  • Existing tests are updated to use the exclusive connection path to preserve their prior behavior.
  • Behavioral Change: the default mobile FFI connect_to_backend now auto-migrates on D14n cutover; callers that need strict exclusive behavior must switch to connect_to_backend_exclusive.

Macroscope summarized c338984.

@insipx insipx requested a review from a team as a code owner March 24, 2026 14:34
@claude
Copy link
Copy Markdown

claude bot commented Mar 24, 2026

Claude finished @insipx's task —— View job


Code Review Complete

Review Date: April 3, 2026, 15:22 UTC

This PR enables migration client functionality across mobile, node, and wasm bindings by introducing migration-aware environment variants and changing default behavior for connect_to_backend to auto-migrate on D14n cutover. Most issues flagged by Macroscope have been resolved. Below is focused feedback on remaining concerns:


Critical Issues

None remaining - the critical syntax error and build/build_optional_d14n issues were already fixed in commits 4601db9 and 5ea7efe.


High Priority

1. Inconsistent WASM behavior doesn't match PR description

bindings/wasm/src/client.rs:313-319: The legacy createClient function still uses build_optional_d14n() instead of migrating based on XmtpEnv. The PR description states "migration-aware XmtpEnv variants...use builder.build() for automatic D14n migration," but the old WASM API doesn't implement this.

  • Impact: WASM users calling createClient (not the new BackendBuilder path) won't get automatic migration even when using MigrationLocal/Staging/Production environments
  • Recommendation: Either update createClient to check for migration environments (like node/mobile), or document this limitation clearly

2. Missing test coverage for migration behavior

No tests verify that:

  • XmtpEnv::MigrationLocal/Staging/Production actually trigger ClientBundle::Migration creation
  • Non-migration environments use the correct backend
  • The exclusive deprecated APIs preserve the old behavior correctly

Recommendation: Add integration tests in bindings/mobile, bindings/node, and bindings/wasm that verify:

// Pseudo-code
assert!(matches!(
    connect_with_migration_env().bundle, 
    ClientBundle::Migration { .. }
));
assert!(matches!(
    connect_to_backend_exclusive().bundle,
    ClientBundle::D14n(_) | ClientBundle::V3(_)
));

Medium Priority

3. Cache key implementation looks correct

Contrary to Macroscope's concern, the cache key implementation in sdks/android/library/src/main/java/org/xmtp/android/library/Client.kt:133 and sdks/ios/Sources/XMTPiOS/Client.swift:134-145 correctly includes the exclusive flag, preventing cache collisions between exclusive and migrating clients. The resolved comment was accurate.

4. Migration environment naming could be clearer

The MigrationLocal/Staging/Production names don't clearly communicate they're temporary transition variants. Consider adding deprecation notices or documentation that these will be removed after cutover.


Low Priority

5. Limited documentation of behavioral change

The PR introduces a breaking behavioral change where connect_to_backend now migrates by default. While the deprecated exclusive APIs preserve old behavior, there's no:

  • CHANGELOG entry documenting this change
  • Migration guide for users who need the old behavior
  • Clear timeline for when exclusive APIs will be removed

6. Node/WASM BackendBuilder pattern is good

The new BackendBuilder pattern in bindings/node/src/client/backend.rs:83-86 and bindings/wasm/src/client/backend.rs:58-64 correctly checks env.is_migration() to determine whether to call build() or build_optional_d14n(). This is the right approach.


Summary

The implementation is mostly sound with proper cache key separation and a clean builder pattern for node/wasm. Main gaps:

  1. Test coverage for migration logic across all bindings
  2. WASM legacy API (createClient) doesn't implement migration-aware behavior
  3. Documentation of breaking behavioral changes

Recommendation: Add tests before merge, update WASM createClient for consistency, and document the migration path.


Tasks

  • Read and analyze changed files
  • Review migration logic and API changes
  • Check test coverage
  • Provide feedback on code quality, bugs, performance, security

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Mar 24, 2026

Approvability

Verdict: Needs human review

This PR enables new migration client functionality that changes how clients connect to backends - new connect_to_backend() calls build() for auto-migration behavior while the old behavior is deprecated to connect_to_backend_exclusive(). This is feature enablement affecting runtime connection/migration behavior across multiple platform bindings, warranting human review despite the author owning all changed files.

You can customize Macroscope's approvability policy. Learn more.

Comment on lines +166 to +168
// switch v3/d14n based on presence of gateway host to preserve
// previous behavior and avoid breaking changes
let client_bundle = client_bundle.build_optional_d14n()?;
let client_bundle = client_bundle.build()?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium src/mls.rs:166

build() returns an error when gateway_host is None, but the surrounding comment explicitly states the intent is to "switch v3/d14n based on presence of gateway host to preserve previous behavior and avoid breaking changes." Since gateway_host is Option<String>, callers passing None (the previous default behavior) will now receive an error instead of a V3 client. This contradicts the documented intent. Consider reverting to build_optional_d14n() or updating the comment to reflect the new requirement.

     // switch v3/d14n based on presence of gateway host to preserve
     // previous behavior and avoid breaking changes
-    let client_bundle = client_bundle.build()?;
+    let client_bundle = client_bundle.build_optional_d14n()?;
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file bindings/mobile/src/mls.rs around lines 166-168:

`build()` returns an error when `gateway_host` is `None`, but the surrounding comment explicitly states the intent is to "switch v3/d14n based on presence of gateway host to preserve previous behavior and avoid breaking changes." Since `gateway_host` is `Option<String>`, callers passing `None` (the previous default behavior) will now receive an error instead of a V3 client. This contradicts the documented intent. Consider reverting to `build_optional_d14n()` or updating the comment to reflect the new requirement.

Evidence trail:
bindings/mobile/src/mls.rs:139-141 (function signature with `gateway_host: Option<String>`), bindings/mobile/src/mls.rs:167-169 (comment and `build()` call), crates/xmtp_api_d14n/src/queries/client_bundle.rs:247-250 (`build()` method calling `inner_build_d14n()`), crates/xmtp_api_d14n/src/queries/client_bundle.rs:170-176 (`inner_build_d14n()` erroring on missing gateway_host), crates/xmtp_api_d14n/src/queries/client_bundle.rs:255-265 (`build_optional_d14n()` method that implements the behavior the comment describes)

@insipx insipx force-pushed the d14n-migration branch 4 times, most recently from 5d679cb to 4601db9 Compare March 30, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant