Repository navigation
Conversation
…generated Step 6 of the shared network plan (ADR 0037). The membership exchange has run on every node since the previous change; this is how an application turns it on. - `ProtocolConfig.app_publisher_key` (optional, 32 bytes; any other length is refused at construction, so a key meant to be set never silently configures nothing). - `set_app_membership(cert)` and `app_membership_status()` on the engine. - `sign_app_membership(publisher_private_key, address, not_after)`, a pure namespace function for embedded mode. A source guard refuses any log, event, storage or send in its body, so the key cannot reach one of those whatever is added around it. Two review items from #685 land here, because this is the first change that lets an application call the code: - Supplying the same certificate again is a no-op. Before, every call restarted every exchange, so an app that hands the certificate over on each foreground made every neighbour sign and seal again, and a hello burst with no link change is something only a configured node produces. - The hello is not built for a peer with no mesh link. Discovery also reports relay, Nostr and LAN peers, and each one cost a clock tick and an identity signature before the send refused it. Tests for both, for the status, for a certificate from the signing helper being accepted, and for the 512-exchange and 1024-visible bounds. Every binding is regenerated from the one definition: Swift, Kotlin, Python, Ruby, Java, the C dispatcher and the C# generated sources. The C# generator refused the new `sequence<u8>?` config field, as it should; it now has a rule for it (standard base64, the C API's JSON form). The three calls are platform operations on the local API: the certificate binds the one identity every client shares, and the signing helper takes a private key that must never cross a socket.
This was referenced Nov 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 6 of the shared network plan (ADR 0037). First of a stack: steps 7 to 12 are stacked on this branch.
What an application gets
ProtocolConfig.app_publisher_key: optional, 32 bytes. Any other length is refused at construction, so a key that was meant to be set never silently configures nothing.set_app_membership(cert)andapp_membership_status()on the engine. The status reports this node's own configuration only (configured, its certificate'snot_afterwhile current, how many neighbours are visible).sign_app_membership(publisher_private_key, address, not_after): a pure namespace function for embedded mode (decision 6a). A source guard (sign_app_membership_never_lets_the_key_out) refuses any log, event, storage or send in its body. I checked it with a negative control: planting adebug!in the body makes it fail.Nothing is gated yet. Visibility is still read only by tests; the gate is the next PR.
#685 review items folded in
send_to_neighborrefused it. A later mesh link is still greeted at once (tested).Regenerated
The whole set was regenerated from the one definition: Swift, Kotlin, Python, Ruby, Java, the C dispatcher, the C header (no change), the Python local API table, and the C# generated sources.
sequence<u8>?onProtocolConfig, which is what it should do. It now has a rule for that type: standard base64, the C API's JSON form for bytes.ConsumerCheckTest.config()passesnullfor the new field.Tested locally
cargo test -p offline-protocol --lib membership: 29 pass, plus the two signing tests.cargo test -p offline-protocol-uniffi: 318 pass, including the two new FFI tests.capi-dispatch-gen --check: clean.generate_local_api_table.py --check: clean.gen_csharp_local_api.py --check: clean.tests/local_api: 129 pass.cargo clippy --workspaceand--no-default-featuresonoffline-protocolare both clean.-D warnings: clean.Not run locally
Java, Ruby, C#, Swift and Android. CI runs those.
Owed to later PRs in the stack