Skip to content

test(protocol): every neighbour report and every inbound frame passes the membership gate - #691

Closed
bahdotsh wants to merge 1 commit into
feat/sealed-app-idfrom
feat/app-gate-guards
Closed

bahdotsh wants to merge 1 commit into
feat/sealed-app-idfrom
feat/app-gate-guards

Conversation

@bahdotsh

@bahdotsh bahdotsh commented Nov 4, 2026

Copy link
Copy Markdown
Member

Step 8 of the shared-network plan (ADR 0037). Stacked on #690.

The behavioural tests in #688 and #689 drive the core. A host that emits a neighbour report on its own, or a second reader of the transport, would pass every one of them. These two guards make that state impossible to reach unnoticed.

every_neighbour_report_passes_the_core_gate

  • Scans the shipped source of offline-protocol, offline-protocol-uniffi and offline-protocol-web. It skips inline test modules, tests/, telemetry/ and events.rs.
  • Every construction of NeighborDiscovered, NeighborLost or PeerRssi must be handed straight to emit_event or push_event.
  • In the 14 lines before it there must be a gate call: neighbor_reachable, neighbor_unreachable or app_sees_peer, or the core's own release_held_discovery.
  • It finds 12 sites today: 6 in the FFI crate, 5 in the browser crate and the core's release. The count is asserted from below, so a scan that stops seeing the sites fails rather than passing vacuously.

frames_for_this_node_have_one_entry_and_it_is_gated

  • transport_manager.receive() is called in exactly one shipped file, protocol/receive.rs.
  • In that loop, inbound_admitted comes before the Lamport merge, which is the first side effect.
  • This answers open question 2 of the plan. Data-sync announcements, presence, key packages and ACKs from a stranger all go through the same predicate, and none has a list of its own. Service discovery is the one exemption, and step 7c replaces it.

Mutation checks (each restored afterwards)

  • Removing the gate at uniffi/src/lib.rs:3365 fails the first guard and names that line.
  • Removing the gate at web/src/node.rs:417 fails it and names that line.
  • Removing inbound_admitted from receive.rs fails the second guard.

cargo test -p offline-protocol --lib: 2216 passed. cargo clippy --workspace -- -D warnings is clean.

Left as is, on purpose

Subscription renewal and the data-sync kick are not gated. Both act on relations the application itself created (a subscription it made, a document it shares), so the application already knows the peer.

… the membership gate

Two source guards for ADR 0037 step 8. Every construction of
NeighborDiscovered, NeighborLost or PeerRssi in the engine, the FFI crate
and the browser crate is emitted behind a core gate call. Frames for this
node have one entry, and the membership gate runs in it before the first
side effect.
@bahdotsh bahdotsh closed this Nov 4, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant