Skip to content

fix(meshd): key neighbor map on SocketAddr (loopback smoke regression gate) - #49

Merged
gHashTag merged 2 commits into
feat/w7-m2-fpga-pivot-2026-07-05from
feat/fix-ip-to-id-socketaddr-2026-07-05
Jul 5, 2026
Merged

fix(meshd): key neighbor map on SocketAddr (loopback smoke regression gate)#49
gHashTag merged 2 commits into
feat/w7-m2-fpga-pivot-2026-07-05from
feat/fix-ip-to-id-socketaddr-2026-07-05

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

Fix the sandbox-testability defect discovered while running the M2 loopback
smoke introduced in #48: the neighbor identity map in trios_meshd was keyed
on IpAddr, so three simulated nodes on 127.0.0.1 collided into a single
entry and node-11 lost identity.

Not a hardware M2 blocker. Real P203 Mini boards have unique IPs, so the
bug never surfaces there. This is purely a fix for the CI smoke rig.

Base

This PR is stacked on #48 (feat/w7-m2-fpga-pivot-2026-07-05). Merge #48
first, then this. If you rebase #48 onto main, please rebase this branch too.

Change

src/bin/trios_meshd.rs:

  • HashMap<IpAddr, NodeId>HashMap<SocketAddr, NodeId> (ip_to_id renamed to addr_to_id)
  • Central RX now dispatches on the full SocketAddr returned by recv_from
  • use std::net::IpAddr dropped

Behaviour on real hardware is a strict superset of the previous code (unique
IPs collapse trivially to unique SocketAddrs), so no regression there.

Regression gate

smoke/m2_loopback_smoke.sh now ends with a "triangle convergence gate":
each node's last neighbors log line must list both peers at steady
ETX in the range 1.00–1.09. Any missing peer or non-steady ETX fails the
script with exit code 2. This is the tripwire for anyone who accidentally
regresses the fix.

Verification (sandbox, -sim, 2026-07-05)

$ cargo build --bin trios_meshd --release
    Finished `release` profile [optimized] target(s) in 8.71s

$ cargo test --workspace --release
test result: ok. 137 passed; 0 failed

$ DURATION=10 ./smoke/m2_loopback_smoke.sh
=== triangle convergence gate ===
node 11: PASS — both peers at steady ETX ({ 12=1.00, 13=1.00 })
node 12: PASS — both peers at steady ETX ({ 11=1.00, 13=1.00 })
node 13: PASS — both peers at steady ETX ({ 11=1.00, 12=1.00 })
exit=0

Full context: smoke/M2_LOOPBACK_FIX_RESULTS.md.

Reproduction

cd tri-net
cargo build --bin trios_meshd --release
DURATION=10 ./smoke/m2_loopback_smoke.sh ; echo "exit=$?"

Discipline hooks

  • no-fabricated-metrics: every number cited here came from a real run in
    this sandbox at 2026-07-05 22:2x +07 and is labelled -sim.
  • SHA-advance rule: any approval binds to the SHA the reviewer explicitly
    cites. Advancing the branch requires a fresh
    Re-reviewed at <new_sha>: delta <bullet-list>.
  • no-paste-review rule: this PR body is descriptive; the actual review
    surface is the committed diff.

phi^2 + phi^-2 = 3

Loopback smoke on 127.0.0.1:5011/5012/5013 exposed a HashMap collision:
all three simulated nodes shared 127.0.0.1, so the last insert won and
node-11 lost identity. On real hardware every P203 Mini has a unique
IP, so the defect is sandbox-only, but it makes CI smoke unreliable.

Change:
- HashMap<IpAddr, NodeId> -> HashMap<SocketAddr, NodeId>
  (rename ip_to_id -> addr_to_id)
- Central RX dispatches on full src: SocketAddr from recv_from
- drop unused IpAddr import

Regression gate:
- smoke/m2_loopback_smoke.sh now ends with a strict "triangle
  convergence gate" that fails with exit 2 if any node does not
  see both peers at steady ETX 1.0x.
- smoke/M2_LOOPBACK_FIX_RESULTS.md documents defect, fix, and
  reproduction with actual sandbox output.

Verification (all -sim, this sandbox, 2026-07-05):
- cargo build --bin trios_meshd --release: clean
- cargo test --workspace --release: 137 passed, 0 failed
- DURATION=10 ./smoke/m2_loopback_smoke.sh: all 3 nodes PASS,
  exit 0

Behaviour on real hardware unchanged (unique IPs collapse to
unique SocketAddrs); this is a strict superset.

Ref PR #48 (parent, introduces smoke).

phi^2 + phi^-2 = 3
@gHashTag gHashTag added mesh TRI-NET mesh track documentation Docs labels Jul 5, 2026
The v1 gate ("last neighbors line == 1.0x for both peers") was
non-deterministic under WMEWMA. Reviewer ran the smoke twice
back-to-back on same host, same binary (SHA 43ab3bf), only pkill
between runs:

  run #1: node-11 { 13=2.03 }  -> gate FAIL (coin-flip red)
  run #2: node-11 { 12=1.00, 13=1.00 } -> gate PASS (coin-flip green)

Both are correct measurements. The gate itself was the problem:
WMEWMA with alpha=0.5, HELLO_MS=300, ETX_WINDOW=3 bounces ETX for
3-4 ticks after any single dropped HELLO on any real channel. The
v1 gate tested the algorithm's asymptote (steady 1.0x) instead of
the SocketAddr fix's actual invariant (both peers visible, ETX
finite). Category error.

v2 gate design:
- Grep last N=5 neighbors lines per node.
- Require both peers with a finite decimal ETX in every sample.
- Reject missing peers (pre-fix regression signal).
- Reject inf/nan (persistent link death).
- Accept transient spikes like 2.03 (correct WMEWMA response).

Sandbox verification:
- Positive: 5/5 runs PASS with new gate.
- Negative: synthetic pre-fix log (node-11 with empty neighbors)
  correctly triggers FAIL for node-11.

Also added smoke/m2_loopback_smoke_n_runs.sh: convenience wrapper
that runs the smoke N times (default 5) and requires every run to
exit 0. Encodes the "results-without-repro-check" discipline: a
regression tripwire must be verified deterministic before trusted.

Reference: WMEWMA rationale (Woo, Tong & Culler, SenSys 2003;
Rosati et al., arXiv:1307.6350).

Ref PR #48 (parent), PR #49 (this branch).

phi^2 + phi^-2 = 3
@gHashTag
gHashTag marked this pull request as ready for review July 5, 2026 16:22
@gHashTag
gHashTag merged commit 67edde5 into feat/w7-m2-fpga-pivot-2026-07-05 Jul 5, 2026
2 checks passed
@gHashTag
gHashTag deleted the feat/fix-ip-to-id-socketaddr-2026-07-05 branch July 5, 2026 16:22
gHashTag added a commit that referenced this pull request Jul 5, 2026
* fix(meshd): key neighbor map on SocketAddr, not IpAddr

Loopback smoke on 127.0.0.1:5011/5012/5013 exposed a HashMap collision:
all three simulated nodes shared 127.0.0.1, so the last insert won and
node-11 lost identity. On real hardware every P203 Mini has a unique
IP, so the defect is sandbox-only, but it makes CI smoke unreliable.

Change:
- HashMap<IpAddr, NodeId> -> HashMap<SocketAddr, NodeId>
  (rename ip_to_id -> addr_to_id)
- Central RX dispatches on full src: SocketAddr from recv_from
- drop unused IpAddr import

Regression gate:
- smoke/m2_loopback_smoke.sh now ends with a strict "triangle
  convergence gate" that fails with exit 2 if any node does not
  see both peers at steady ETX 1.0x.
- smoke/M2_LOOPBACK_FIX_RESULTS.md documents defect, fix, and
  reproduction with actual sandbox output.

Verification (all -sim, this sandbox, 2026-07-05):
- cargo build --bin trios_meshd --release: clean
- cargo test --workspace --release: 137 passed, 0 failed
- DURATION=10 ./smoke/m2_loopback_smoke.sh: all 3 nodes PASS,
  exit 0

Behaviour on real hardware unchanged (unique IPs collapse to
unique SocketAddrs); this is a strict superset.

Ref PR #48 (parent, introduces smoke).

phi^2 + phi^-2 = 3

* fix(smoke): gate v2 — finite-ETX visibility across N=5 samples

The v1 gate ("last neighbors line == 1.0x for both peers") was
non-deterministic under WMEWMA. Reviewer ran the smoke twice
back-to-back on same host, same binary (SHA 43ab3bf), only pkill
between runs:

  run #1: node-11 { 13=2.03 }  -> gate FAIL (coin-flip red)
  run #2: node-11 { 12=1.00, 13=1.00 } -> gate PASS (coin-flip green)

Both are correct measurements. The gate itself was the problem:
WMEWMA with alpha=0.5, HELLO_MS=300, ETX_WINDOW=3 bounces ETX for
3-4 ticks after any single dropped HELLO on any real channel. The
v1 gate tested the algorithm's asymptote (steady 1.0x) instead of
the SocketAddr fix's actual invariant (both peers visible, ETX
finite). Category error.

v2 gate design:
- Grep last N=5 neighbors lines per node.
- Require both peers with a finite decimal ETX in every sample.
- Reject missing peers (pre-fix regression signal).
- Reject inf/nan (persistent link death).
- Accept transient spikes like 2.03 (correct WMEWMA response).

Sandbox verification:
- Positive: 5/5 runs PASS with new gate.
- Negative: synthetic pre-fix log (node-11 with empty neighbors)
  correctly triggers FAIL for node-11.

Also added smoke/m2_loopback_smoke_n_runs.sh: convenience wrapper
that runs the smoke N times (default 5) and requires every run to
exit 0. Encodes the "results-without-repro-check" discipline: a
regression tripwire must be verified deterministic before trusted.

Reference: WMEWMA rationale (Woo, Tong & Culler, SenSys 2003;
Rosati et al., arXiv:1307.6350).

Ref PR #48 (parent), PR #49 (this branch).

phi^2 + phi^-2 = 3

---------

Co-authored-by: gHashTag <auaavroo0312@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Docs mesh TRI-NET mesh track

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant