I2133 — Every mesh input and answer has a bound, and a refused registration learns nothing
Bound the discovery channel, every reply a runtime reads and the candidates it accepts; answer a refused registration with its refusal alone; and give every link retry a floor and jitter.
DONE wave 0 · p1 · implementation profile · runs alone
Objective
Bound the discovery channel, every reply a runtime reads and the candidates it accepts; answer a refused registration with its refusal alone; and give every link retry a floor and jitter.
Why
The provider channel is unbounded (apps/majordomus-cli/src/mesh/manager.rs:425 channel()) and feeds one thread that runs an Ed25519 verify per datagram, with no per-source rate and no drop counter (threat T3). Rendezvous and link replies to the dialer are read with an unbounded read_to_end (apps/majordomus-cli/src/mcp/bridge.rs:84-85) under a per-read timeout only, so a slow trickle holds the worker and the per-runtime round lock (apps/majordomus-cli/src/mesh/cooperation.rs:2383-2387) (T4), and the candidate count received is unbounded. docs/MESH.md:341 lists 'messages (900 KiB)' as a flood bound, which holds only for what the answerer receives (apps/majordomus-cli/src/mesh/cooperation.rs:1769-1779, 2010-2020) and the dialer sends (apps/majordomus-cli/src/mesh/link.rs:883-888). mesh.register answers its own envelope and up to 32 candidates even when the caller's envelope is refused (apps/majordomus-cli/src/mesh/manager.rs:623-636), and the candidates include untrusted nodes of any repository (apps/majordomus-cli/src/mesh/registry.rs:342-357) (T2, T13). An UnknownLink answer is retried with zero delay (apps/majordomus-cli/src/mesh/cooperation.rs:2592-2595), so a peer that welcomes and then refuses sync drives a busy loop, and the link backoff has no jitter (apps/majordomus-cli/src/mesh/cooperation.rs:2611-2614). Baseline audit of 2026-10-09 at master 1fb8d6be44, mesh gaps 5 and 11, threats T2, T3, T4 and T13, drift 5.
Current state
Inputs the answerer receives are bounded; the discovery channel, replies the dialer reads, received candidates and registration answers are not.
Desired state
Providers send through a bounded queue (OBSERVATION_QUEUE, 1024) whose drops are counted as overflow in mesh.status refusals; a refused registration is answered with the refusal alone, and an admitted one with this node and the trusted nodes of the caller's own repositories (MeshRegistry::candidates_for; the unfiltered candidates is gone); an answerer that keeps answering unknown_link is retried no faster than a heartbeat after the first immediate retry. The deferred part, the dialer's reply and candidate bounds, jitter on the link backoff and a test of the unknown_link retry rate, is I2704.
Scope
- apps/majordomus-cli/src/mesh/manager.rs
- apps/majordomus-cli/src/mesh/rendezvous.rs
- apps/majordomus-cli/src/mesh/registry.rs
- apps/majordomus-cli/src/mesh/cooperation.rs
- apps/majordomus-cli/tests/mesh.rs
- apps/majordomus-cli/tests/mesh_cooperation.rs
- docs/MESH.md
Dependencies
None. This issue is a root of the graph.
What waits on this
Acceptance criteria
- Datagrams beyond the channel bound are dropped and counted in mesh status, and the process's memory stays bounded under a flood test
- A registration whose envelope is refused receives no candidate, and no answer carries a candidate of another repository
Validation
- bin/majordomus plan validate
- cargo test --lib mesh
- cargo test --test mesh --test mesh_cooperation
Evidence required
- discovery_flood_bounded_test
- refused_registration_learns_nothing_test
Evidence
| covers | type | command | result | at commit |
|---|---|---|---|---|
| discovery_flood_bounded_test | test | cargo test --locked --manifest-path apps/majordomus-cli/Cargo.toml --test mesh discovery_flood_bounded_test | test result: ok. 8 passed; 0 failed (whole file) (run 2026-10-14 12:00-12:15Z on master 2ca25bb9cf plus this change) | 2ca25bb |
| refused_registration_learns_nothing_test | test | cargo test --locked --manifest-path apps/majordomus-cli/Cargo.toml --test mesh a_registration_learns_only_the_trusted_nodes_of_its_own_repository | test result: ok. 8 passed; 0 failed (whole file) (run 2026-10-14 12:00-12:15Z on master 2ca25bb9cf plus this change) | 2ca25bb |
Timeline
- started
- 2026-10-14T12:15:55Z
- verified
- —
- completed
- 2026-10-14T12:16:35Z
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I2133.yaml. Read it back with majordomus plan show I2133.