# Cost-Based Parent Selection: Hysteresis Stability Test # # Topology (explicit 4-node diamond, symmetric): # # n01 (root) # / \ # wifi wifi # / \ # n02 n03 # \ / # wifi wifi # \ / # n04 (test subject) # # All links are WiFi-like with similar characteristics. Aggressive # netem mutation shifts link qualities every 10-20s, but the changes # stay within the 20% hysteresis band. n04 should pick one parent # and mostly stick with it — flapping indicates insufficient hysteresis. # # Validation: n04 should switch parent at most 5 times. This is now the # max_parent_switches assertion below, scoped to n04. It previously # existed only as this comment and was checked by nothing, so the # scenario could not fail on it. # # The threshold of 5 is the one this comment always named, kept # deliberately rather than re-derived. What the number is worth, from 11 # completed archived runs of this scenario: n04 was 1 or 2 every time and # never reached 3, while the mesh-wide total ranged 3 to 6. Two # consequences worth knowing before trusting a green result here. # # First, 5 is a long way above anything observed, so this catches only # near-pathological reparenting. The daemon's own 30s parent hold-down # caps non-mandatory switches at roughly 6 per 180s run, so the band # where this can fail is narrow. A hysteresis regression that added two # or three switches would pass. # # Second, the count spans the container's whole life, not just the # mutation phase: in the archived runs nearly every n04 switch lands in # the first 100ms during initial tree formation, before the first netem # mutation fires. So this number is dominated by convergence transients # rather than by the hysteresis behaviour the scenario is named for. # # Tightening to 3 would make it a real detector against the observed # distribution. That is a change to the stated criterion rather than a # fix, so it is left as a decision rather than taken here. scenario: name: "cost-stability" seed: 42 duration_secs: 180 topology: algorithm: explicit num_nodes: 4 params: adjacency: - [n01, n02] - [n01, n03] - [n02, n04] - [n03, n04] subnet: "172.20.0.0/24" ip_start: 10 netem: enabled: true default_policy: # WiFi baseline delay_ms: [5, 20] jitter_ms: [2, 5] loss_pct: [1, 3] mutation: interval_secs: {min: 10, max: 20} fraction: 1.0 policies: slightly_better: delay_ms: [3, 8] jitter_ms: [1, 3] loss_pct: [0, 1] slightly_worse: delay_ms: [15, 25] jitter_ms: [3, 8] loss_pct: [2, 4] link_flaps: enabled: false traffic: enabled: true max_concurrent: 2 interval_secs: {min: 15, max: 30} duration_secs: {min: 5, max: 15} parallel_streams: 2 assertions: max_parent_switches: node: n04 max_total: 5 logging: rust_log: "info" output_dir: "./sim-results"